Expand engine (directory scan, NDJSON/CSV, severity filters), docs, tests, and CI#2
Open
cognis-digital wants to merge 1 commit into
Open
Expand engine (directory scan, NDJSON/CSV, severity filters), docs, tests, and CI#2cognis-digital wants to merge 1 commit into
cognis-digital wants to merge 1 commit into
Conversation
Additive production-grade improvements across four areas. No existing entry points, APIs, or output shapes are removed. Features: - Directory & recursive scanning via new yararun/scanfs.iter_targets: include/exclude fnmatch globs, per-file --max-bytes ceiling, symlink policy, de-dup, stable order, and WalkStats counters. `scan` now accepts directories in addition to files and stdin. - Two new output formats: ndjson (one compact object per file) and csv (RFC-4180, one row per matched string) via core.to_ndjson / core.to_csv. - --min-severity display filter (ScanResult.filtered) and severity helpers (severity_rank / severity_at_least). - New scan flags: -R/--recursive, --no-recursive, --include, --exclude, --max-bytes, --follow-symlinks, --stats. Tests & CI: - New tests/test_expansion.py (29 tests) covering severity helpers, the filtered() narrowing, ndjson/csv exporters, iter_targets walking, and the new CLI surface. Full suite: 131 passing. - CI now runs a pytest matrix on Python 3.10-3.13 plus a ruff lint job (blocking on real defects E9/F63/F7/F82, full report non-blocking). Docs: - README overhauled: overview, features, install, per-subcommand usage, output-format and configuration reference, Python API, and FAQ (keeps the huntkit pointer). - New docs/USAGE.md (full CLI + rule-language reference); refreshed docs/ARCHITECTURE.md and ROADMAP.md to match the actual modules. Refactor: - New modules are fully typed and documented; json import added to core for the exporters; version bumped to 2.1.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
yararunis a dependency-free, pure-stdlib YARA-subset rule engine and triagetoolkit. Its own tagline is "run rules over a directory", yet the CLI could
only scan individual files, and machine consumers were limited to JSON/SARIF.
This PR closes that gap and levels the repo up across four areas — features,
tests/CI, docs, and internal structure — without removing a single existing
entry point, API, or output shape. Everything is additive and the core stays
standard-library only.
What changed
Features / depth
yararun/scanfs.pywithiter_targets()expands a mix of files, directories, and-(stdin) into ade-duplicated, stably-ordered stream of file paths. It honours:
-R/--recursive,--no-recursive),fnmatch--include/--excludeglobs (matched against basename andthe path relative to the walked root; exclude wins),
--max-bytesceiling so a recursive scan can't be derailed by amulti-GB artifact,
--follow-symlinks,WalkStatscounter surfaced via--stats(files/dirs/skips to stderr).scannow accepts directories in addition to files/stdin.--format ndjson— one compact, key-sorted JSON object per file, one perline (streaming/log-pipeline friendly) via
core.to_ndjson.--format csv— RFC-4180 CSV, one row per matched string, with a summaryrow even for clean files, via
core.to_csv(stableCSV_COLUMNS).--min-severitydisplay filter backed by the pure,non-mutating
ScanResult.filtered(), plusseverity_rank()/severity_at_least()helpers incore.Tests & CI
tests/test_expansion.py(29 tests) with real assertions on realbehaviour: severity helpers and their
mediumfallback,filtered()narrowing + non-mutation + intel preservation, NDJSON/CSV exporter shape and
RFC-4180 quoting, the full
iter_targetsmatrix (recursion, include/excludeprecedence, size cap, dedup, stdin passthrough, missing paths, stats), and the
new CLI surface (directory scans,
--no-recursive, include glob, ndjson/csv,--min-severity,--max-bytes,--stats, single-file back-compat)..github/workflows/ci.yml): pytest matrix on Python3.10-3.13 with
PYTHONUTF8=1, plus a ruff lint job — a byte-compilesyntax gate and a blocking
ruff check --select E9,F63,F7,F82(real defectsonly: syntax errors, undefined names, broken f-strings, bad comparisons), with
a full non-blocking ruff report.
ruff>=0.6added to thedevextra.Docs
feature list, install (incl. extras), quick start, per-subcommand usage
tables, output-format table, rule-writing, architecture diagram, Python API,
configuration + exit-code reference, and a FAQ. The huntkit pointer is kept.
docs/USAGE.md— complete CLI reference, the supported rule-languagegrammar, exit codes, and recipes.
docs/ARCHITECTURE.md(accurate module/data-flow map) andROADMAP.md(principles, shipped/near/mid/long-term, non-goals).Refactor
jsonimport added tocorefor the exporters; new public names exported fromyararun/__init__.core.TOOL_VERSION,pyproject,VERSION).Test results
New usage examples
Backward compatibility
Additive only. No files deleted, no public API or CLI flag removed, no
output shape changed. A single explicit file target still yields a JSON object
(array only for multiple/expanded targets);
-/stdin,--fail-on, and everyexisting subcommand behave exactly as before. A missing top-level target still
exits
2; the core/CLI remain standard-library only.Checklist
PYTHONUTF8=1pip install -e .works; console script runs