dallow 0.2.1
dallow: ^0.2.1 copied to clipboard
Codebase intelligence for Dart and Flutter. Finds unreachable dead code, dependency drift, circular imports, duplicate blocks, and complexity hot spots.
Changelog #
0.2.1 - 2026-06-25 #
- Packaging: add an
example/(CLI usage walkthrough) and a.pubignorethat drops thetest/andtool/trees from the published archive — the test fixtures deliberately import undeclared packages to exercise the deps check, which pub flagged as packaging warnings. - Metadata: broaden the package description to name the duplication and
complexity checks, add pub.dev
topics, and declareissue_tracker.
0.2.0 - 2026-06-25 #
-
Complexity: added a resolved-AST cyclomatic-complexity check for functions, methods, constructors, and closures, plus a
complexitysubcommand and--max-complexitythreshold. Findings above the threshold are warnings; findings at least twice the threshold are errors. -
Health score:
analyze/complexitynow emit an info-level project-health finding with a deterministic 0–100 score derived from complexity excess and non-complexity finding density. -
PR gate: inline
dallow-ignoresuppression. A// dallow-ignorecomment on a finding's line — or the line directly above it — removes that finding before the gate, so it neither prints nor affects the exit code. Scope it to one check with// dallow-ignore: <check-kind>(a comma-separated list, plus an optional trailing reason). Comments are read from the analyzer's token stream rather than by scanning text, and suppression composes with--changed-sinceand--baseline(applied first, against the raw findings).--report-unused-ignoressurfaces stale directives that matched nothing as info-levelunused-ignorefindings. -
SARIF output:
--format sarifemits a SARIF 2.1.0 log for code-scanning platforms (e.g. GitHub Advanced Security). The singlerunadvertises one rule per check kind (tool.driver.rules, with ashortDescriptionand adefaultConfiguration.levelmapped from severity —error/warning/note), and oneresultper finding (ruleId= check kind, mappedlevel, message, and aphysicalLocationwith a relative POSIX URI +region.startLineonly when the finding has both a file and a line). Whole-package andpubspec.yaml-level findings (a file but no line) are emitted as valid results without aphysicalLocation, since GitHub code-scanning needsregion.startLineand would otherwise pin a region-less location to line 1. Wired through--formaton every subcommand. -
PR gate:
--changed-since <ref>filters findings to files changed since a git ref (merge-base<ref>...HEAD); whole-package andpubspec.yamlfindings are always kept, and a non-git tree or bad ref exits64with a clear message instead of crashing. -
PR gate:
--baseline <file>suppresses findings recorded in a JSON baseline, and--write-baseline <file>captures the current findings as one (exit0), so a team can adopt the gate on a dirty codebase and fail only on new findings. Baseline entries are matched by a line-independent fingerprint (kind + file + symbol + normalised message), so they survive line shifts. The filters compose and apply to every subcommand. -
Duplication: added a token-level duplicate-code check,
duplicationsubcommand,analyzewiring, and--min-block-sizethreshold. -
Dead code: now reports unused class members (methods, getters/setters, fields), not just top-level symbols, on the resolved element graph. A member is flagged when it is private (or belongs to a non-public-API
lib/srcclass) and unreachable from any entrypoint. Members reached through inheritance — an@override, an interface implementation, or a member overridden by a subtype — are kept (they may be dispatched dynamically), as are public members of public-API classes and fields initialised through athis.xconstructor parameter. Member findings carry a qualifiedEnclosingType.membersymbol. -
Monorepos: new
-r, --recursiveflag onanalyze(and every sub-command) discovers and analyses all member packages in one run, instead of the single-package default. Packages are found from amelos.yamlpackages:globs list (honouringignore:), a pub-workspaceworkspace:member list, or, failing both, every nestedpubspec.yaml; build/tooling/symlink dirs are skipped. Findings are attributed to their package (console/markdown prefix, JSONpackagefield) and--fail-onis evaluated across all packages. -
Dead code: register Dart 3
extension typedeclarations, so a dead one is flagged (labelled "extension type") instead of silently skipped. -
Circular imports:
--max-cycle-sizenow rejects values below the smallest possible cycle (2) with a usage error, instead of silently disabling the check. -
Docs: README exit-codes section now documents
64(usage) and69(no SDK) alongside0/1. -
Build:
tool/build.shaborts loudly if no platform binary was produced, rather than packaging a binary-less zip. -
Deps: federated plugin implementations (
<base>_web,<base>_android,<base>_platform_interface, …) are no longer flagged as unused when their base plugin is a declared dependency. -
Circular imports: long cycle membership is truncated in the message with an "(+N more)" suffix, and a new
--max-cycle-sizeflag skips cycles above a given size (e.g. a known barrel mega-cycle) while still catching small ones. -
Dead code: skip synthetic elements at registration, so an explicit getter's synthetic backing variable is no longer reported as a phantom dead symbol.
-
Dead code: seed each public library's export namespace as a reachability root, so
lib/src/symbols surfaced through a barrel re-export are no longer false-flagged. -
Dead code: track references made inside
typedefdeclarations; symbols used only through a typedef are no longer false-flagged. -
Dead code: derive the symbol-kind label from the resolved element type rather than
runtimeType.toString(). -
Deps: anchor the
package:scan toimport/exportdirective lines so mentions in comments or strings no longer count as usage. -
Circular imports: reworded to "Dependency cycle among N files" (the graph includes export edges; members are listed, not a traversal path).
-
Extracted the exit-code gate into
exitCodeForfor direct testing. -
Tests: re-export and typedef regressions, misplaced-dependency, reporters, and exit-code gating.
0.1.0 #
Initial release.
dead-code: reachability-based dead-code detection over the resolvedanalyzerelement graph.deps: dependency hygiene againstpubspec.yaml(unused, missing, and misplaced dependencies).circular: import-cycle detection via strongly-connected components.analyze: runs every check.console,json, andmarkdownoutput formats with--fail-onexit-code gating.