Skip to content

Add NuGet package analyzer (redundant & conflicting references) with :analyze packages CLI#423

Open
ChrisonSimtian wants to merge 4 commits into
Fallout-build:mainfrom
ChrisonSimtian:feature/nuget-package-analyzer
Open

Add NuGet package analyzer (redundant & conflicting references) with :analyze packages CLI#423
ChrisonSimtian wants to merge 4 commits into
Fallout-build:mainfrom
ChrisonSimtian:feature/nuget-package-analyzer

Conversation

@ChrisonSimtian

Copy link
Copy Markdown
Collaborator

Implements #421.

What this adds

A NuGet dependency analyzer — a "snitch" done on top of machinery Fallout already owns, available as a CLI command and built so a build target can consume it later.

Fallout.NuGet.Analysis reads the post-restore project.assets.json (the resolved dependency graph) and detects:

  1. Redundant via project reference — a direct PackageReference already provided by a referenced project.
  2. Redundant via package — a direct PackageReference already pulled in transitively by another package you reference.
  3. Version conflict — the same package resolved at different versions across projects (computed per target framework, so a multi-targeted project pinning different versions across its own TFMs is not a false positive).

Detections 1 & 2 are one reachability check over the resolved graph: a direct package X is redundant when reachable through some other direct dependency (project or package).

CLI

dotnet fallout :analyze packages [<path>] [--tfm <moniker>] [--severity none|trace|normal|warning|error] [--format table|flat] [--conflicts] [--verbose] [--exclude <id>[,<id>...]]
  • <path> — a .csproj, a directory, or a .sln/.slnx (parsed via Fallout.Solutions.ReadSolution() for real project membership). Defaults to the working directory.
  • Default output is a per-project tree of redundant references (the actionable cleanup list). Version conflicts are hidden unless --conflicts (compact counts; --verbose for project lists).
  • --severity controls the log level findings emit at and whether the command exits non-zero (error → CI gating). --format flat keeps plain log lines.

:analyze is introduced as a command namespace so future analyzers slot in alongside.

Guardrails

  • Excludes autoReferenced (SDK-implicit) and PrivateAssets=all (suppressParent) refs — can't / shouldn't be removed.
  • Distinguishes remove (resolved version unchanged) from review (removal could downgrade the resolved version).
  • Central Package Management aware (versions come from the resolved graph).
  • Clear messaging when a project isn't restored.

Design notes

  • Reads project.assets.json directly — the post-restore truth that already encodes direct-ref intent (autoReferenced/suppressParent) and the resolved transitive graph with versions. No MSBuild evaluation needed; scales with file-read speed (markedly faster than snitch's per-project design-time builds). Requires a restore to have run.
  • Core library is free of CLI/build coupling so both can consume it (Fallout.NuGet.Analysis → CLI today, a build target next).
  • Library targets net10.0 for now (matches the CLI); multi-target when build integration lands.

Layout

  • src/Fallout.NuGet.Analysis/ — core analyzer (assets reader + detections + result model).
  • src/Fallout.Cli/Program.Analyze.cs — the :analyze packages command + table/flat rendering.
  • tests/Fallout.NuGet.Analysis.Tests/ — 6 unit tests over synthetic assets files (transitive redundancy safe + might-downgrade, auto-referenced/private-assets exclusion, --exclude, project-reference redundancy, cross-project version conflicts).

Dogfooded

  • Against this repo's src/ and against a large real-world solution (MyFoodBag) — surfaces genuine project-reference and package-transitive redundancies and cross-project version drift.

Follow-ups (not in this PR)

  • A build target consuming the analyzer with a configurable LogLevel + optional fail-on-finding.
  • MSBuild-eval file attribution (point removal advice at the exact csproj vs Directory.Build.props).
  • Pre-release flagging, dependency-graph export, richer alignment in the tree.

ChrisonSimtian and others added 3 commits June 25, 2026 11:13
…`:analyze packages` CLI

Introduces Fallout.NuGet.Analysis, a dependency analyzer that reads the
post-restore project.assets.json resolved graph and flags:

- direct package references already provided by a referenced project
- direct package references already pulled in transitively by another package
- the same package resolving to different versions across projects

The core library is free of CLI/build coupling so it can be consumed by both.
Wires it up as `dotnet fallout :analyze packages [<path>] [--tfm] [--severity] [--exclude]`,
emitting findings at a configurable log level and returning a severity-driven exit code.

Implements Fallout-build#421.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Targeting a solution now reads real project membership through
Fallout.Solutions.ReadSolution() instead of globbing the directory.
Adds a `--format table|flat` option (table is the default) rendering
findings as Spectre tables; flat keeps the log-line output.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…onflicts behind --conflicts

Table view now renders redundant references as a per-project tree (the
actionable cleanup list) and hides version conflicts unless --conflicts is
passed (then a compact counts view, or --verbose for the project lists).

Version-conflict detection is now done per target framework, so a
multi-targeted project that legitimately pins different versions across its
own frameworks is no longer reported as a conflict. Conflict data is exposed
structurally via Finding.ConflictVersions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisonSimtian ChrisonSimtian requested a review from a team as a code owner June 25, 2026 01:36
@ChrisonSimtian ChrisonSimtian added enhancement New feature or request target/2026 Targets the 2026 calendar-version line (current). See ADR-0004. labels Jun 25, 2026
…rojects

Adds Fallout.NuGet.Analysis + Fallout.NuGet.Analysis.Tests to the generated
strongly-typed solution view (and picks up the pre-existing Components.Tests
entry the snapshot was missing).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisonSimtian

Copy link
Copy Markdown
Collaborator Author

needs rebase onto #394 (stacked) or wait until that PR lands. But it would be cool to have an onboard dependency analyzer. We already walk the dependency path with our topo stuff, might as well spit this out (and keen to get this into a vs code extension as well)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request target/2026 Targets the 2026 calendar-version line (current). See ADR-0004.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant