Skip to content

deps: remove fanal framework, call Trivy parsers directly#2476

Merged
kotakanbe merged 42 commits intomasterfrom
diet-trivy-dispatch
Mar 27, 2026
Merged

deps: remove fanal framework, call Trivy parsers directly#2476
kotakanbe merged 42 commits intomasterfrom
diet-trivy-dispatch

Conversation

@kotakanbe
Copy link
Copy Markdown
Member

@kotakanbe kotakanbe commented Mar 17, 2026

Summary

  • Remove the Trivy fanal analyzer framework and call dependency parsers directly
  • Eliminates IaC/misconf package tree that was pulled in transitively via fanal/analyzer -> misconf -> all IaC scanners
  • Scanner-only binary: 106.6 MB → 34.1 MB (-68%)
  • Full binary: 139.1 MB → 136.0 MB (-2%)

What changed

  • Rewrite AnalyzeLibrary() to use detectParserType() + direct parser calls
  • Remove all fanal blank imports (25+ analyzer registrations)
  • Simplify JAR parser to standalone function, removing fanal PostAnalyzer interface
  • Remove DummyFileInfo (no longer needed)
  • Add detectParserType() with table-driven tests covering all edge cases
  • Add composer-vendor (installed.json) support to detectParserType — fanal registered this analyzer but the old dispatch table missed it
  • Error handling: parse errors collected in l.errs (appear in ScanResult.Errors), remaining lockfiles continue scanning

Metrics

Build flags: goreleaser equivalent (CGO_ENABLED=0 GOEXPERIMENT=jsonv2 go build -a -trimpath -ldflags "-s -w")

Metric Before (master) After Change
Full binary size 139.1 MB 136.0 MB -2%
Scanner-only binary size 106.6 MB 34.1 MB -68%
Scanner-only build time (cached) 7.8s 3.2s -59%
Trivy package deps 352 144 -59%
misconf packages 1 0 -100%

Why the full binary size reduction is only -2%

The full binary (go build ./cmd/vuls/) still imports the Trivy vulnerability detection layer through two paths, both outside the scope of this PR:

  1. subcmds/report.go imports trivy/pkg/cache — this transitively pulls in 254 IaC packages (terraform parser, cloudformation parser, trivy-checks, etc.)
  2. detector/library.go imports trivy/pkg/db — this transitively pulls in 90 IaC packages

These imports exist because Trivy's internal package structure couples its DB/cache layer with IaC scanning types. Even though Vuls never uses IaC scanning, the Go linker must include these packages.

The scanner-only binary (go build -tags scanner ./cmd/scanner/) excludes both detector/ and subcmds/report.go via the !scanner build tag, which is why it benefits dramatically (-68%).

Fully decoupling the full binary from IaC packages would require either upstream changes to Trivy's package structure or replacing the trivy/pkg/cache and trivy/pkg/db imports — a separate, larger effort. (The trivy/pkg/cache removal is addressed in #2478.)

What is NOT changed

  • detector/library.go (vulnerability detection) -- unchanged, !scanner build tag
  • detector/javadb/ (Java DB download and SHA1 lookup) -- unchanged, !scanner build tag. Java DB is only used in the detect phase (vuls report), not in the scan phase where this PR's changes apply.
  • go.mod -- trivy dependency remains (used by detector in full build)
  • Parser output -- identical to before for 16/17 ecosystems (see regression testing section)

New files and directories

scanner/testdata/ — Golden test fixtures

35 lockfile fixtures and their expected JSON outputs for all supported ecosystems. Each fixture is a real-world lockfile (npm, yarn, pnpm, pip, pipenv, poetry, uv, bundler, cargo, composer, go.mod, pom.xml, gradle, nuget, dotnet-deps, conan, pub, mix, cocoapods, swift, jar, war, gobinary, rustbinary).

  • scanner/testdata/fixtures/ — Input lockfiles/binaries
  • scanner/testdata/golden/ — Expected JSON output (*.golden.json)

These are used by scanner/analyze_golden_test.go to verify that AnalyzeLibrary() produces exactly the expected output. Run go test ./scanner/ -update to regenerate golden files after intentional changes.

scripts/ — A/B regression comparison tool

  • scripts/compare-lockfile.go — Downloads real-world lockfiles from popular OSS projects (GitHub, Maven Central), creates a git worktree for the base ref, and runs AnalyzeLibrary() on both refs to diff the JSON output. This catches regressions that golden tests might miss (e.g., behavior differences with large real-world files).
  • scripts/lockfile-fixtures.json — 129 fixture definitions (10 per ecosystem, pinned tags for reproducibility).
  • scripts/README.md — Usage documentation.

GNUmakefile — New compare-lockfile target

make compare-lockfile              # fetch fixtures and compare against master
make compare-lockfile BASE=v0.27.0 # compare against specific ref
make compare-lockfile FETCH=0      # skip download, reuse cached fixtures

No regression in both build modes

AnalyzeLibrary() is the shared code path used by both the full binary and the scanner-only binary. This PR rewrites that function, and both golden tests and make compare-lockfile exercise it directly. Since AnalyzeLibrary() is common to both builds, verifying it once covers both:

  • Full build (go build ./cmd/vuls/): compiles and all tests pass. The additional code in this build is detector/library.go (vulnerability detection via Trivy DB), which is excluded from this PR's changes by the !scanner build tag.
  • Scanner-only build (go build -tags scanner ./cmd/scanner/): compiles and all tests pass. This is where the binary size reduction is most significant (-68%).

Regression testing

Golden tests (go test ./scanner/...)

35 lockfile fixtures with exact JSON output comparison. Covers all parser types including the newly added composer-vendor (installed.json).

pom.xml online mode (TestAnalyzeLibrary_PomOnline)

pom.xml is the only parser that behaves differently in online vs offline mode — online mode resolves transitive dependencies from Maven Central. A dedicated test verifies this:

  • Calls AnalyzeLibrary() with isOffline=false and compares output against pom.xml.online.golden.json
  • Verifies online mode returns more dependencies than offline (offline: 2 libs, online: 3 libs — transitive log4j-api is resolved)
  • Manually verified to produce identical results to master (both online and offline)
  • Skipped with go test -short since it requires network access

Note: JAR/WAR parsing does not use the online/offline flag — it only reads META-INF/MANIFEST.MF and pom.properties from inside the archive. Java DB (trivy-java-db) is used only in the detect phase (detector/javadb/), not in the scan phase.

Real-world comparison (make compare-lockfile)

scripts/compare-lockfile.go runs AnalyzeLibrary() on both the current branch and the base ref (master) using real-world lockfiles fetched from popular OSS projects, then diffs the JSON output.

129 fixtures tested across 13 ecosystems (10 projects each + jar/gobinary/rustbinary):

Ecosystem Fixtures Result
npm 10 10 IDENTICAL
yarn 10 10 IDENTICAL
pnpm 10 7 IDENTICAL, 3 DIFFERENT (dev flag only, see below)
pip 10 10 IDENTICAL
pipenv 10 10 IDENTICAL
poetry 10 10 IDENTICAL
bundler 10 10 IDENTICAL
cargo 10 10 IDENTICAL
composer 10 10 IDENTICAL
gomod 10 10 IDENTICAL
pom 10 10 IDENTICAL
mix 10 10 IDENTICAL
swift 10 10 IDENTICAL
jar 2 2 IDENTICAL
gobinary 1 1 IDENTICAL
rustbinary 1 1 IDENTICAL
Total 129 126 IDENTICAL, 3 DIFFERENT

pnpm difference explained

The 3 pnpm differences (vitejs/vite, withastro/astro, pnpm/pnpm) all show the same pattern: "dev": true flags being added or corrected. This is a pre-existing bug in master, not a regression introduced by this PR.

Root cause: In master, the fanal analyzer framework wraps the pnpm parser in a way that loses the dev flag information. By calling the Trivy pnpm parser directly in this PR, the parser's correct behavior is now exposed — dev dependencies are properly marked with "dev": true.

All library names, versions, and PURLs are identical across all 129 fixtures. The only differences are dev flag corrections in pnpm.

Test plan

  • Golden tests: 35 lockfile fixtures, output matches exactly (go test ./scanner/...)
  • Dispatch tests: all file-to-parser mappings verified (table-driven, dispatch_test.go)
  • pom.xml online mode: transitive dependency resolution via Maven Central verified, identical to master (TestAnalyzeLibrary_PomOnline)
  • make compare-lockfile: 129 real-world fixtures across 13 ecosystems — 126/129 identical with master (3 diffs are pre-existing pnpm dev-flag bug, not a regression)
  • go build ./cmd/vuls/ (full build OK)
  • go build -tags scanner ./cmd/scanner/ (scanner-only build OK)
  • go test ./... all packages PASS
  • GOEXPERIMENT=jsonv2 golangci-lint run ./... PASS

🤖 Generated with Claude Code

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the scanner’s library analysis to bypass Trivy’s fanal analyzer framework and instead dispatch directly to Trivy dependency parsers, primarily to reduce transitive dependencies (notably IaC/misconf) and shrink the scanner-only binary.

Changes:

  • Replaced AnalyzeLibrary()’s fanal-based analysis with detectParserType() + direct Trivy parser calls.
  • Extracted JAR/WAR/EAR/PAR parsing into a standalone ParseJAR function (removing fanal post-analyzer wiring).
  • Added dispatch + golden-style tests and a set of golden JSON fixtures for many lockfile/artifact types.

Reviewed changes

Copilot reviewed 36 out of 39 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scanner/base.go Replaces fanal analyzer group usage with direct parser dispatch and helper parse wrappers.
scanner/dispatch.go Adds file path/filemode → parser-type detection logic.
scanner/dispatch_test.go Table-driven tests for parser dispatch mapping (including exclusions and exec-bit detection).
scanner/trivy/jar/jar.go Reworks JAR parsing into a direct ParseJAR entrypoint.
scanner/analyze_golden_test.go Adds golden tests comparing AnalyzeLibrary() output against committed golden JSON outputs.
scanner/testdata/golden/Cargo.lock.golden.json Golden fixture for Cargo.lock parsing output.
scanner/testdata/golden/Directory.Packages.props.golden.json Golden fixture for NuGet central package management props parsing output.
scanner/testdata/golden/Gemfile.lock.golden.json Golden fixture for Bundler parsing output.
scanner/testdata/golden/Package.resolved.golden.json Golden fixture for Swift Package Manager parsing output.
scanner/testdata/golden/Pipfile.lock.golden.json Golden fixture for Pipenv parsing output.
scanner/testdata/golden/Podfile.lock.golden.json Golden fixture for CocoaPods parsing output.
scanner/testdata/golden/bun.lock.golden.json Golden fixture for Bun lock parsing output.
scanner/testdata/golden/composer.lock.golden.json Golden fixture for Composer parsing output.
scanner/testdata/golden/conan-v1_conan.lock.golden.json Golden fixture for Conan v1 lock parsing output.
scanner/testdata/golden/conan-v2_conan.lock.golden.json Golden fixture for Conan v2 lock parsing output.
scanner/testdata/golden/datacollector.deps.json.golden.json Golden fixture for .NET deps.json parsing output.
scanner/testdata/golden/go.mod.golden.json Golden fixture for Go module parsing output.
scanner/testdata/golden/go.sum.golden.json Golden fixture verifying go.sum alone yields no output.
scanner/testdata/golden/gobinary.golden.json Golden fixture for Go binary dependency extraction output.
scanner/testdata/golden/gradle.lockfile.golden.json Golden fixture for Gradle lockfile parsing output.
scanner/testdata/golden/hello-rust.golden.json Golden fixture for Rust binary dependency extraction output.
scanner/testdata/golden/juddiv3-war-3.3.5.war.golden.json Golden fixture for WAR/JAR family parsing output with embedded libs.
scanner/testdata/golden/log4j-core-2.13.0.jar.golden.json Golden fixture for JAR parsing output.
scanner/testdata/golden/mix.lock.golden.json Golden fixture for Elixir mix.lock parsing output.
scanner/testdata/golden/npm-v1_package-lock.json.golden.json Golden fixture for npm v1 package-lock parsing output.
scanner/testdata/golden/npm-v2_package-lock.json.golden.json Golden fixture for npm v2 package-lock parsing output.
scanner/testdata/golden/npm-v3_package-lock.json.golden.json Golden fixture for npm v3 package-lock parsing output.
scanner/testdata/golden/packages.config.golden.json Golden fixture for NuGet packages.config parsing output.
scanner/testdata/golden/packages.lock.json.golden.json Golden fixture for NuGet packages.lock.json parsing output.
scanner/testdata/golden/pnpm-v9_pnpm-lock.yaml.golden.json Golden fixture for pnpm v9 lock parsing output.
scanner/testdata/golden/pnpm_pnpm-lock.yaml.golden.json Golden fixture verifying pnpm lock can yield empty output for fixture.
scanner/testdata/golden/poetry-v1_poetry.lock.golden.json Golden fixture for Poetry v1 lock parsing output.
scanner/testdata/golden/poetry-v2_poetry.lock.golden.json Golden fixture for Poetry v2 lock parsing output.
scanner/testdata/golden/pom.xml.golden.json Golden fixture for Maven pom.xml parsing output.
scanner/testdata/golden/pubspec.lock.golden.json Golden fixture for Dart pubspec.lock parsing output.
scanner/testdata/golden/requirements.txt.golden.json Golden fixture for requirements.txt parsing output.
scanner/testdata/golden/uv.lock.golden.json Golden fixture for uv.lock parsing output.
scanner/testdata/golden/wrong-name-log4j-core.jar.golden.json Golden fixture for JAR name edge case parsing output.
scanner/testdata/golden/yarn.lock.golden.json Golden fixture for yarn.lock parsing output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@kotakanbe
Copy link
Copy Markdown
Member Author

End-to-end comparison: master vs this PR

Methodology

Ran AnalyzeLibrary() against all 34 lockfile fixtures on both master (fanal framework) and this PR branch (direct parser calls), then compared the JSON output byte-for-byte.

Steps

1. Create a master worktree

git worktree add /tmp/vuls-master master

2. Write a comparison harness

Created a Go program that calls scanner.AnalyzeLibrary() on every lockfile in integration/data/lockfile/, normalizes the output (sort by name+version to eliminate ordering differences), and writes one JSON file per lockfile.

On master, AnalyzeLibrary() goes through the fanal analyzer framework with blank imports. On this PR branch, it calls Trivy dependency parsers directly. The comparison proves both paths produce identical output.

Target files (34 total):

npm (v1,v2,v3), yarn, pnpm (v8,v9), bun,
pip, pipenv, poetry (v1,v2), uv,
bundler, cargo, rust-binary,
composer, go.mod, go.sum, go-binary,
pom.xml, gradle, JAR (log4j, wrong-name, WAR),
nuget-lock, nuget-config, deps.json, packages.props,
conan (v1,v2), pubspec, mix, cocoapods, swift

3. Run on master

cd /tmp/vuls-master
go run run_analyze.go integration/data/lockfile /tmp/result-master

Output:

OK npm-v1/package-lock.json (242 libs)
OK npm-v2/package-lock.json (324 libs)
OK npm-v3/package-lock.json (1327 libs)
OK yarn.lock (836 libs)
OK pnpm/pnpm-lock.yaml (0 libs)
OK pnpm-v9/pnpm-lock.yaml (536 libs)
OK bun.lock (6 libs)
OK requirements.txt (1 libs)
OK Pipfile.lock (19 libs)
OK poetry-v1/poetry.lock (62 libs)
OK poetry-v2/poetry.lock (15 libs)
OK uv.lock (105 libs)
OK Gemfile.lock (111 libs)
OK Cargo.lock (399 libs)
OK hello-rust (6 libs)
OK composer.lock (107 libs)
OK go.mod (19 libs)
OK go.sum (0 libs)
OK gobinary (3 libs)
OK pom.xml (2 libs)
OK gradle.lockfile (1 libs)
OK log4j-core-2.13.0.jar (1 libs)
OK wrong-name-log4j-core.jar (2 libs)
OK juddiv3-war-3.3.5.war (79 libs)
OK packages.lock.json (1 libs)
OK packages.config (1 libs)
OK datacollector.deps.json (2 libs)
OK Directory.Packages.props (2 libs)
OK conan-v1/conan.lock (7 libs)
OK conan-v2/conan.lock (2 libs)
OK pubspec.lock (50 libs)
OK mix.lock (4 libs)
OK Podfile.lock (6 libs)
OK Package.resolved (4 libs)

4. Run on this PR branch

cd /home/kota/go/src/github.com/future-architect/vuls  # diet-trivy-dispatch branch
go run run_analyze.go integration/data/lockfile /tmp/result-new

Output is identical to master (same library counts for every file).

5. Diff JSON output

diff_count=0
total=0
for f in /tmp/result-master/*.json; do
  name=$(basename "$f")
  total=$((total + 1))
  if ! diff -q "$f" "/tmp/result-new/$name" > /dev/null 2>&1; then
    echo "DIFF: $name"
    diff "$f" "/tmp/result-new/$name"
    diff_count=$((diff_count + 1))
  fi
done
echo "Total: $total files compared"
echo "Identical: $((total - diff_count))"
echo "Different: $diff_count"

Result

Total: 34 files compared
Identical: 34
Different: 0

All 34 lockfile outputs are byte-for-byte identical between master and this PR. A total of 4,883 library detections match exactly between the fanal-based implementation (master) and the direct parser calls (this PR).

@kotakanbe
Copy link
Copy Markdown
Member Author

Test fixture strategy: CI compatibility

Problem

The golden tests originally read lockfile fixtures from integration/data/lockfile/, which is a git submodule (vulsio/integration). CI uses actions/checkout without submodules: true, so the integration directory is not available in CI. This means the golden tests would be silently skipped in CI, defeating the purpose of regression protection.

Options considered

Option Pros Cons
A. Copy text fixtures to scanner/testdata/fixtures/ Self-contained, works in CI without config changes File duplication (~2.3 MB)
B. Add submodules: true to CI workflow Full coverage (34/34) +81 MB clone per PR run; submodule updates can break golden tests; CI workflow change is out of scope for this PR
C. Keep as skip-in-CI No extra files CI provides zero regression protection

Decision: Option A

Copied 29 text-based lockfile fixtures (2.3 MB) to scanner/testdata/fixtures/. Binary fixtures (JAR, WAR, Go/Rust binaries — 35 MB total) remain in the integration submodule only.

CI behavior

Verified by temporarily hiding the integration submodule (mv integration integration.bak) and running tests:

29 PASS  — text fixtures from testdata/fixtures/ (always available)
 5 SKIP  — binary fixtures: hello-rust, gobinary, log4j-core-2.13.0.jar,
           wrong-name-log4j-core.jar, juddiv3-war-3.3.5.war
           (requires: git submodule update --init)

Local behavior (with submodule)

34 PASS  — all fixtures available
 0 SKIP

Test code changes

  • Text fixtures: read from testdata/fixtures/ (committed, always available)
  • Binary fixtures: read from ../integration/data/lockfile/ (submodule, t.Skip if missing)
  • t.Fatalf for missing text fixtures (these should never be missing in CI)
  • t.Skipf for missing binary fixtures (with instructions to init submodule)

kotakanbe added a commit that referenced this pull request Mar 18, 2026
- Return parse errors from AnalyzeLibrary instead of silently swallowing
  them. Caller (scanLibraries) logs warning and continues to next file.
- Use io.SeekEnd/io.SeekStart instead of magic numbers in JAR parser.
- Golden test treats parse errors as empty result (matches production
  behavior where scanLibraries warns and continues).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kotakanbe kotakanbe requested a review from Copilot March 18, 2026 00:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the scanner-side dependency analysis to bypass Trivy’s fanal analyzer framework and invoke Trivy dependency parsers directly, primarily to reduce transitive dependencies (notably IaC/misconf) and dramatically shrink the scanner-only binary.

Changes:

  • Rewrites AnalyzeLibrary() to dispatch by filename/mode and call Trivy parsers directly (plus a dedicated JAR parsing entrypoint).
  • Adds parser dispatch unit tests and broad golden tests with many new fixtures/golden outputs.
  • Updates module dependencies to reflect removed direct usage (golang.org/x/sync becomes indirect).

Reviewed changes

Copilot reviewed 46 out of 69 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
scanner/base.go Replaces fanal-based analysis with direct parser dispatch; changes error handling to warn-and-continue on per-file failures.
scanner/dispatch.go Adds detectParserType() dispatch logic for lockfiles/artifacts and executable detection.
scanner/dispatch_test.go Adds table-driven tests validating dispatch decisions and exclusions.
scanner/trivy/jar/jar.go Converts JAR analyzer into a standalone ParseJAR function callable directly.
scanner/analyze_golden_test.go Adds golden test harness covering many ecosystems and artifact types (with optional integration-submodule fixtures).
go.mod Removes direct golang.org/x/sync requirement and retains it indirectly.
scanner/testdata/fixtures/requirements.txt Adds pip requirements fixture for golden tests.
scanner/testdata/fixtures/pubspec.lock Adds Dart pub lock fixture.
scanner/testdata/fixtures/pom.xml Adds Maven POM fixture.
scanner/testdata/fixtures/poetry-v2/poetry.lock Adds Poetry v2 fixture.
scanner/testdata/fixtures/packages.lock.json Adds NuGet lock fixture.
scanner/testdata/fixtures/packages.config Adds NuGet packages.config fixture.
scanner/testdata/fixtures/mix.lock Adds Elixir mix lock fixture.
scanner/testdata/fixtures/gradle.lockfile Adds Gradle lockfile fixture.
scanner/testdata/fixtures/go.mod Adds Go module fixture.
scanner/testdata/fixtures/datacollector.deps.json Adds .NET deps.json fixture.
scanner/testdata/fixtures/conan-v2/conan.lock Adds Conan v2 lock fixture.
scanner/testdata/fixtures/conan-v1/conan.lock Adds Conan v1 lock fixture.
scanner/testdata/fixtures/bun.lock Adds Bun lock fixture.
scanner/testdata/fixtures/Podfile.lock Adds CocoaPods lock fixture.
scanner/testdata/fixtures/Package.resolved Adds Swift Package.resolved fixture.
scanner/testdata/fixtures/Gemfile.lock Adds Bundler lock fixture.
scanner/testdata/fixtures/Directory.Packages.props Adds NuGet Directory.Packages.props fixture.
scanner/testdata/golden/wrong-name-log4j-core.jar.golden.json Golden output for JAR parsing scenario.
scanner/testdata/golden/uv.lock.golden.json Golden output for uv.lock parsing.
scanner/testdata/golden/requirements.txt.golden.json Golden output for requirements.txt parsing.
scanner/testdata/golden/pubspec.lock.golden.json Golden output for pubspec.lock parsing.
scanner/testdata/golden/pom.xml.golden.json Golden output for pom.xml parsing.
scanner/testdata/golden/poetry-v2_poetry.lock.golden.json Golden output for Poetry v2 parsing.
scanner/testdata/golden/poetry-v1_poetry.lock.golden.json Golden output for Poetry v1 parsing.
scanner/testdata/golden/pnpm_pnpm-lock.yaml.golden.json Golden output for pnpm lock parsing (empty case).
scanner/testdata/golden/packages.lock.json.golden.json Golden output for NuGet packages.lock.json parsing.
scanner/testdata/golden/packages.config.golden.json Golden output for NuGet packages.config parsing.
scanner/testdata/golden/mix.lock.golden.json Golden output for mix.lock parsing.
scanner/testdata/golden/log4j-core-2.13.0.jar.golden.json Golden output for JAR parsing scenario.
scanner/testdata/golden/juddiv3-war-3.3.5.war.golden.json Golden output for WAR parsing scenario.
scanner/testdata/golden/hello-rust.golden.json Golden output for executable (Rust) parsing path.
scanner/testdata/golden/gradle.lockfile.golden.json Golden output for Gradle lockfile parsing.
scanner/testdata/golden/gobinary.golden.json Golden output for executable (Go) parsing path.
scanner/testdata/golden/go.sum.golden.json Golden output for go.sum-only behavior (empty case).
scanner/testdata/golden/go.mod.golden.json Golden output for go.mod parsing.
scanner/testdata/golden/datacollector.deps.json.golden.json Golden output for .NET deps.json parsing.
scanner/testdata/golden/conan-v2_conan.lock.golden.json Golden output for Conan v2 parsing.
scanner/testdata/golden/conan-v1_conan.lock.golden.json Golden output for Conan v1 parsing.
scanner/testdata/golden/composer.lock.golden.json Golden output for composer.lock parsing.
scanner/testdata/golden/bun.lock.golden.json Golden output for bun.lock parsing.
scanner/testdata/golden/Podfile.lock.golden.json Golden output for Podfile.lock parsing.
scanner/testdata/golden/Pipfile.lock.golden.json Golden output for Pipfile.lock parsing.
scanner/testdata/golden/Package.resolved.golden.json Golden output for Package.resolved parsing.
scanner/testdata/golden/Gemfile.lock.golden.json Golden output for Gemfile.lock parsing.
scanner/testdata/golden/Directory.Packages.props.golden.json Golden output for Directory.Packages.props parsing.
Files not reviewed (1)
  • scanner/testdata/fixtures/npm-v1/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

kotakanbe added a commit that referenced this pull request Mar 18, 2026
- Remove unused parserRustBinary constant (dispatch returns parserGoBinary
  for all executables, language determined at parse time)
- Make suffix-based dispatch case-insensitive (.deps.json, gradle.lockfile)
  for cross-platform compatibility
- Aggregate parse errors into l.warns so they surface in scan results
- Remove unused fanal blank imports from golden test file

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kotakanbe kotakanbe requested a review from Copilot March 18, 2026 00:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the scanner-side dependency analysis to bypass Trivy’s fanal analyzer framework and invoke Trivy dependency parsers directly, primarily to reduce transitive dependencies (notably misconf/IaC scanners) and shrink the scanner-only binary.

Changes:

  • Reworks AnalyzeLibrary() to dispatch by filename/mode (detectParserType) and call Trivy parsers directly (including a standalone JAR parser entrypoint).
  • Adds dispatch tests and extensive golden fixtures/tests for lockfile parsing output stability.
  • Updates/expands scanner test fixtures and golden outputs for multiple ecosystems (Node, Python, Java, .NET, etc).

Reviewed changes

Copilot reviewed 46 out of 69 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scanner/trivy/jar/jar.go Replaces fanal post-analyzer registration with a standalone ParseJAR function.
scanner/dispatch.go Adds parserType and detectParserType() dispatch logic (including exclusions and filemode executable detection).
scanner/dispatch_test.go Adds table-driven tests validating file-to-parser dispatch behavior.
scanner/base.go Rewrites AnalyzeLibrary() to call Trivy parsers directly; adjusts lockfile scan error handling to warn-and-continue.
scanner/analyze_golden_test.go Adds golden tests that run AnalyzeLibrary() across a suite of fixtures and compare normalized JSON outputs.
scanner/testdata/fixtures/requirements.txt Adds pip requirements fixture for golden testing.
scanner/testdata/fixtures/pubspec.lock Adds Dart/pub fixture for golden testing.
scanner/testdata/fixtures/pom.xml Adds Maven pom fixture for golden testing.
scanner/testdata/fixtures/poetry-v2/poetry.lock Adds Poetry v2 fixture for golden testing.
scanner/testdata/fixtures/packages.lock.json Adds NuGet lock fixture for golden testing.
scanner/testdata/fixtures/packages.config Adds NuGet packages.config fixture for golden testing.
scanner/testdata/fixtures/mix.lock Adds Elixir mix.lock fixture for golden testing.
scanner/testdata/fixtures/gradle.lockfile Adds Gradle lockfile fixture for golden testing.
scanner/testdata/fixtures/go.mod Adds Go module fixture for golden testing.
scanner/testdata/fixtures/datacollector.deps.json Adds .NET deps.json fixture for golden testing.
scanner/testdata/fixtures/conan-v2/conan.lock Adds Conan v2 fixture for golden testing.
scanner/testdata/fixtures/conan-v1/conan.lock Adds Conan v1 fixture for golden testing.
scanner/testdata/fixtures/bun.lock Adds Bun lock fixture for golden testing.
scanner/testdata/fixtures/Podfile.lock Adds CocoaPods fixture for golden testing.
scanner/testdata/fixtures/Package.resolved Adds Swift Package.resolved fixture for golden testing.
scanner/testdata/fixtures/Gemfile.lock Adds Bundler fixture for golden testing.
scanner/testdata/fixtures/Directory.Packages.props Adds .NET central packages props fixture for golden testing.
scanner/testdata/golden/wrong-name-log4j-core.jar.golden.json Adds golden output for a JAR edge-case fixture.
scanner/testdata/golden/uv.lock.golden.json Adds golden output for uv.lock parsing.
scanner/testdata/golden/requirements.txt.golden.json Adds golden output for requirements.txt parsing.
scanner/testdata/golden/pubspec.lock.golden.json Adds golden output for pubspec.lock parsing.
scanner/testdata/golden/pom.xml.golden.json Adds golden output for pom.xml parsing.
scanner/testdata/golden/poetry-v2_poetry.lock.golden.json Adds golden output for Poetry v2 lock parsing.
scanner/testdata/golden/poetry-v1_poetry.lock.golden.json Adds golden output for Poetry v1 lock parsing.
scanner/testdata/golden/pnpm_pnpm-lock.yaml.golden.json Adds golden output for pnpm-lock.yaml parsing.
scanner/testdata/golden/packages.lock.json.golden.json Adds golden output for packages.lock.json parsing.
scanner/testdata/golden/packages.config.golden.json Adds golden output for packages.config parsing.
scanner/testdata/golden/mix.lock.golden.json Adds golden output for mix.lock parsing.
scanner/testdata/golden/log4j-core-2.13.0.jar.golden.json Adds golden output for JAR parsing.
scanner/testdata/golden/juddiv3-war-3.3.5.war.golden.json Adds golden output for WAR parsing.
scanner/testdata/golden/hello-rust.golden.json Adds golden output for executable (rust) parsing.
scanner/testdata/golden/gradle.lockfile.golden.json Adds golden output for gradle.lockfile parsing.
scanner/testdata/golden/gobinary.golden.json Adds golden output for Go binary parsing.
scanner/testdata/golden/go.sum.golden.json Adds golden output for go.sum (empty) behavior.
scanner/testdata/golden/go.mod.golden.json Adds golden output for go.mod parsing.
scanner/testdata/golden/datacollector.deps.json.golden.json Adds golden output for .deps.json parsing.
scanner/testdata/golden/conan-v2_conan.lock.golden.json Adds golden output for Conan v2 parsing.
scanner/testdata/golden/conan-v1_conan.lock.golden.json Adds golden output for Conan v1 parsing.
scanner/testdata/golden/composer.lock.golden.json Adds golden output for composer.lock parsing.
scanner/testdata/golden/bun.lock.golden.json Adds golden output for bun.lock parsing.
scanner/testdata/golden/Podfile.lock.golden.json Adds golden output for Podfile.lock parsing.
scanner/testdata/golden/Pipfile.lock.golden.json Adds golden output for Pipfile.lock parsing.
scanner/testdata/golden/Package.resolved.golden.json Adds golden output for Package.resolved parsing.
scanner/testdata/golden/Gemfile.lock.golden.json Adds golden output for Gemfile.lock parsing.
scanner/testdata/golden/Directory.Packages.props.golden.json Adds golden output for Directory.Packages.props parsing.
go.mod Updates dependency graph (moves golang.org/x/sync to indirect).
Files not reviewed (1)
  • scanner/testdata/fixtures/npm-v1/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@kotakanbe kotakanbe requested a review from Copilot March 18, 2026 21:25
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the scanner-side library analysis to bypass Trivy’s fanal analyzer framework and invoke Trivy dependency parsers directly, significantly reducing transitive dependencies (notably IaC/misconf) and shrinking the scanner-only binary.

Changes:

  • Rewires AnalyzeLibrary() to dispatch via detectParserType() and call Trivy parsers directly (including a standalone JAR parser).
  • Adds dispatch + golden tests and new fixtures/golden outputs to validate parser mapping and output stability.
  • Adds a make diff-lockfile helper and scripts to compare AnalyzeLibrary() outputs across Git refs using real-world fixtures.

Reviewed changes

Copilot reviewed 50 out of 74 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
scripts/lockfile-fixtures.json Adds a pinned list of real-world lockfile/binary fixtures for comparison runs.
scripts/compare-lockfile.go New dev script to fetch fixtures and compare AnalyzeLibrary() outputs between current ref and a base ref.
scripts/README.md Documents the new lockfile diff/regression workflow and fixtures list.
scanner/trivy/jar/jar.go Replaces fanal post-analyzer registration with a direct ParseJAR helper.
scanner/testdata/golden/wrong-name-log4j-core.jar.golden.json Adds/updates golden output for a JAR parsing case.
scanner/testdata/golden/uv.lock.golden.json Adds golden output for uv.lock parsing.
scanner/testdata/golden/requirements.txt.golden.json Adds golden output for requirements.txt parsing.
scanner/testdata/golden/pubspec.lock.golden.json Adds golden output for Dart pubspec.lock parsing.
scanner/testdata/golden/pom.xml.golden.json Adds golden output for Maven pom.xml parsing.
scanner/testdata/golden/poetry-v2_poetry.lock.golden.json Adds golden output for Poetry v2 lock parsing.
scanner/testdata/golden/poetry-v1_poetry.lock.golden.json Adds golden output for Poetry v1 lock parsing.
scanner/testdata/golden/pnpm_pnpm-lock.yaml.golden.json Adds golden output for pnpm (including an expected-empty/error case).
scanner/testdata/golden/packages.lock.json.golden.json Adds golden output for NuGet packages.lock.json.
scanner/testdata/golden/packages.config.golden.json Adds golden output for NuGet packages.config.
scanner/testdata/golden/mix.lock.golden.json Adds golden output for Elixir mix.lock.
scanner/testdata/golden/log4j-core-2.13.0.jar.golden.json Adds golden output for JAR parsing.
scanner/testdata/golden/hello-rust.golden.json Adds golden output for Rust binary parsing.
scanner/testdata/golden/gradle.lockfile.golden.json Adds golden output for Gradle lockfile parsing.
scanner/testdata/golden/gobinary.golden.json Adds golden output for Go binary parsing.
scanner/testdata/golden/go.sum.golden.json Adds golden output for standalone go.sum behavior (empty).
scanner/testdata/golden/go.mod.golden.json Adds golden output for go.mod parsing.
scanner/testdata/golden/datacollector.deps.json.golden.json Adds golden output for .deps.json parsing.
scanner/testdata/golden/conan-v2_conan.lock.golden.json Adds golden output for Conan v2 lock parsing.
scanner/testdata/golden/conan-v1_conan.lock.golden.json Adds golden output for Conan v1 lock parsing.
scanner/testdata/golden/composer.lock.golden.json Adds golden output for Composer lock parsing.
scanner/testdata/golden/bun.lock.golden.json Adds golden output for Bun lock parsing.
scanner/testdata/golden/Podfile.lock.golden.json Adds golden output for CocoaPods lock parsing.
scanner/testdata/golden/Pipfile.lock.golden.json Adds golden output for Pipenv lock parsing.
scanner/testdata/golden/Package.resolved.golden.json Adds golden output for Swift Package.resolved parsing.
scanner/testdata/golden/Gemfile.lock.golden.json Adds golden output for Bundler lock parsing.
scanner/testdata/golden/Directory.Packages.props.golden.json Adds golden output for Directory.Packages.props parsing.
scanner/testdata/fixtures/requirements.txt Adds a minimal pip requirements fixture.
scanner/testdata/fixtures/pubspec.lock Adds a Dart pub lock fixture.
scanner/testdata/fixtures/pom.xml Adds a minimal Maven POM fixture.
scanner/testdata/fixtures/poetry-v2/poetry.lock Adds a Poetry v2 lock fixture.
scanner/testdata/fixtures/packages.lock.json Adds a NuGet lock fixture.
scanner/testdata/fixtures/packages.config Adds a NuGet config fixture.
scanner/testdata/fixtures/mix.lock Adds an Elixir lock fixture.
scanner/testdata/fixtures/gradle.lockfile Adds a Gradle lockfile fixture.
scanner/testdata/fixtures/go.mod Adds a Go module fixture.
scanner/testdata/fixtures/datacollector.deps.json Adds a .NET deps fixture.
scanner/testdata/fixtures/conan-v2/conan.lock Adds a Conan v2 fixture.
scanner/testdata/fixtures/conan-v1/conan.lock Adds a Conan v1 fixture.
scanner/testdata/fixtures/bun.lock Adds a Bun lock fixture.
scanner/testdata/fixtures/Podfile.lock Adds a CocoaPods fixture.
scanner/testdata/fixtures/Package.resolved Adds a Swift resolved fixture.
scanner/testdata/fixtures/Gemfile.lock Adds a Bundler lock fixture.
scanner/testdata/fixtures/Directory.Packages.props Adds a Directory.Packages.props fixture.
scanner/dispatch_test.go Adds table-driven tests for parser dispatch behavior (paths, exclusions, case-insensitivity, executable mode).
scanner/dispatch.go Introduces detectParserType() and helpers to map files to parsers without fanal registrations.
scanner/base.go Rewrites AnalyzeLibrary() to call Trivy parsers directly; adjusts error handling in scanLibraries().
scanner/analyze_golden_test.go Adds golden tests covering many lockfile types and behavior parity checks.
go.mod Moves golang.org/x/sync from direct to indirect requirement due to removed usage.
GNUmakefile Adds diff-lockfile target to run the new comparison script.
.gitignore Ignores a potential scripts/compare-lockfile artifact/binary.
Files not reviewed (1)
  • scanner/testdata/fixtures/npm-v1/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

kotakanbe added a commit that referenced this pull request Mar 18, 2026
  scanner/base.go:
  - Add Rust binary error types (ErrUnrecognizedExe, ErrNonRustBinary)
    to parseBinary suppression list
  - Wrap parse errors with file path context in l.errs

  scripts/compare-lockfile.go:
  - Fix file header (compare-analyze.go -> compare-lockfile.go)
  - Add HTTP client timeout (5 min)
  - Remove dead code in base runner safe variable

  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kotakanbe kotakanbe requested a review from Copilot March 18, 2026 22:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the scanner’s library analysis flow to bypass Trivy’s fanal analyzer framework and instead dispatch directly to Trivy dependency parsers, reducing transitive dependencies (notably misconf/IaC) and shrinking the scanner-only binary. It also adds regression tooling and golden/dispatch tests to ensure parser output remains unchanged.

Changes:

  • Replaced fanal-based AnalyzeLibrary() with direct parser dispatch via detectParserType() and parser-specific helpers.
  • Simplified the JAR analyzer into a standalone ParseJAR() function and updated scanning loops to collect parse errors and continue.
  • Added regression tooling (make diff-lockfile) plus dispatch and golden tests with new fixtures/golden outputs.

Reviewed changes

Copilot reviewed 52 out of 76 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
scripts/lockfile-fixtures.json Defines real-world fixtures used by the A/B comparison tool.
scripts/compare-lockfile.go Adds a Git-ref comparison tool for AnalyzeLibrary() output across fixtures.
scripts/README.md Documents diff-lockfile usage and fixture maintenance.
scanner/windows.go Changes library scan behavior to collect parse errors and continue.
scanner/trivy/jar/jar.go Replaces fanal post-analyzer integration with standalone ParseJAR().
scanner/pseudo.go Changes library scan behavior to collect parse errors and continue.
scanner/dispatch_test.go Adds table-driven tests for file-to-parser dispatch logic.
scanner/dispatch.go Introduces parserType and detectParserType() dispatch logic.
scanner/base.go Rewrites AnalyzeLibrary() to call Trivy parsers directly; updates error handling to continue scanning.
scanner/analyze_golden_test.go Adds golden tests for AnalyzeLibrary() output across many lockfile types/artifacts.
scanner/testdata/golden/wrong-name-log4j-core.jar.golden.json Golden output for JAR parsing edge case.
scanner/testdata/golden/uv.lock.golden.json Golden output for uv lock parsing.
scanner/testdata/golden/requirements.txt.golden.json Golden output for pip requirements parsing.
scanner/testdata/golden/pubspec.lock.golden.json Golden output for Dart pub lock parsing.
scanner/testdata/golden/pom.xml.golden.json Golden output for Maven pom parsing.
scanner/testdata/golden/poetry-v2_poetry.lock.golden.json Golden output for Poetry v2 lock parsing.
scanner/testdata/golden/poetry-v1_poetry.lock.golden.json Golden output for Poetry v1 lock parsing.
scanner/testdata/golden/pnpm_pnpm-lock.yaml.golden.json Golden output for pnpm fixture (empty on parse error).
scanner/testdata/golden/packages.lock.json.golden.json Golden output for NuGet packages.lock.json parsing.
scanner/testdata/golden/packages.config.golden.json Golden output for NuGet packages.config parsing.
scanner/testdata/golden/mix.lock.golden.json Golden output for Elixir mix.lock parsing.
scanner/testdata/golden/log4j-core-2.13.0.jar.golden.json Golden output for JAR parsing.
scanner/testdata/golden/hello-rust.golden.json Golden output for Rust binary parsing.
scanner/testdata/golden/gradle.lockfile.golden.json Golden output for Gradle lockfile parsing.
scanner/testdata/golden/gobinary.golden.json Golden output for Go binary parsing.
scanner/testdata/golden/go.sum.golden.json Golden output for go.sum (expected empty).
scanner/testdata/golden/go.mod.golden.json Golden output for go.mod parsing.
scanner/testdata/golden/datacollector.deps.json.golden.json Golden output for .NET deps.json parsing.
scanner/testdata/golden/conan-v2_conan.lock.golden.json Golden output for Conan v2 lock parsing.
scanner/testdata/golden/conan-v1_conan.lock.golden.json Golden output for Conan v1 lock parsing.
scanner/testdata/golden/composer.lock.golden.json Golden output for Composer lock parsing.
scanner/testdata/golden/bun.lock.golden.json Golden output for Bun lock parsing.
scanner/testdata/golden/Podfile.lock.golden.json Golden output for CocoaPods lock parsing.
scanner/testdata/golden/Pipfile.lock.golden.json Golden output for Pipenv lock parsing.
scanner/testdata/golden/Package.resolved.golden.json Golden output for Swift Package.resolved parsing.
scanner/testdata/golden/Gemfile.lock.golden.json Golden output for Bundler lock parsing.
scanner/testdata/golden/Directory.Packages.props.golden.json Golden output for .NET Directory.Packages.props parsing.
scanner/testdata/fixtures/requirements.txt Adds pip requirements fixture for golden tests.
scanner/testdata/fixtures/pubspec.lock Adds Dart pubspec.lock fixture for golden tests.
scanner/testdata/fixtures/pom.xml Adds Maven pom.xml fixture for golden tests.
scanner/testdata/fixtures/poetry-v2/poetry.lock Adds Poetry v2 fixture for golden tests.
scanner/testdata/fixtures/packages.lock.json Adds NuGet packages.lock.json fixture for golden tests.
scanner/testdata/fixtures/packages.config Adds NuGet packages.config fixture for golden tests.
scanner/testdata/fixtures/mix.lock Adds mix.lock fixture for golden tests.
scanner/testdata/fixtures/gradle.lockfile Adds Gradle lockfile fixture for golden tests.
scanner/testdata/fixtures/go.mod Adds go.mod fixture for golden tests.
scanner/testdata/fixtures/datacollector.deps.json Adds .NET deps.json fixture for golden tests.
scanner/testdata/fixtures/conan-v2/conan.lock Adds Conan v2 fixture for golden tests.
scanner/testdata/fixtures/conan-v1/conan.lock Adds Conan v1 fixture for golden tests.
scanner/testdata/fixtures/bun.lock Adds Bun lock fixture for golden tests.
scanner/testdata/fixtures/Podfile.lock Adds CocoaPods lock fixture for golden tests.
scanner/testdata/fixtures/Package.resolved Adds Swift Package.resolved fixture for golden tests.
scanner/testdata/fixtures/Gemfile.lock Adds Bundler lock fixture for golden tests.
scanner/testdata/fixtures/Directory.Packages.props Adds Directory.Packages.props fixture for golden tests.
go.mod Updates module requirements to reflect removal of fanal/errgroup usage.
GNUmakefile Adds diff-lockfile target to run the comparison tool.
.gitignore Ignores the optional built comparison binary output under scripts/.
Files not reviewed (1)
  • scanner/testdata/fixtures/npm-v1/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@kotakanbe kotakanbe requested a review from Copilot March 18, 2026 22:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the scanner’s library analysis to bypass Trivy’s fanal analyzer framework and invoke Trivy dependency parsers directly, primarily to reduce transitive dependencies (notably IaC/misconf) and shrink the scanner-only binary.

Changes:

  • Rewires AnalyzeLibrary() to dispatch via detectParserType() and call Trivy parsers directly (including a standalone JAR parser).
  • Adds dispatch and golden tests to validate parser selection and output stability across many lockfile formats.
  • Introduces a diff-lockfile developer workflow (fixtures + compare script + README) to A/B compare results between Git refs using real-world lockfiles.

Reviewed changes

Copilot reviewed 52 out of 76 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scanner/base.go Replaces fanal-based analysis with direct Trivy parser calls and continues scanning on per-lockfile parse errors.
scanner/dispatch.go Adds file-to-parser dispatch logic (detectParserType) used by the new direct parsing flow.
scanner/dispatch_test.go Adds table-driven tests for dispatch behavior and exclusion rules.
scanner/trivy/jar/jar.go Converts JAR parsing into a standalone function callable without fanal post-analyzers.
scanner/analyze_golden_test.go Adds golden tests covering many lockfile formats (skipping binary fixtures if the integration submodule isn’t present).
scanner/{windows.go,pseudo.go} Changes library scan behavior to collect parse errors and continue scanning remaining lockfiles.
scanner/testdata/** Adds/updates fixtures and golden outputs for the new parsing path.
scripts/compare-lockfile.go Adds a comparison utility to diff AnalyzeLibrary() output between current ref and a base ref using fetched fixtures.
scripts/lockfile-fixtures.json Defines the real-world fixture list (URLs, filemodes, archive paths).
scripts/README.md Documents diff-lockfile usage and fixture format.
GNUmakefile Adds make diff-lockfile target.
go.mod Updates dependency classification after removing fanal/errgroup usage.
.gitignore Ignores a local scripts/compare-lockfile artifact.
Files not reviewed (1)
  • scanner/testdata/fixtures/npm-v1/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@kotakanbe kotakanbe requested a review from Copilot March 19, 2026 00:11
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes reliance on Trivy’s fanal analyzer framework for library/lockfile analysis and instead dispatches directly to Trivy dependency parsers, primarily to reduce transitive dependencies (notably misconf/IaC scanners) and shrink the scanner-only binary.

Changes:

  • Reworked AnalyzeLibrary() to use a new detectParserType() dispatcher and call Trivy parsers directly (including a standalone JAR parser entrypoint).
  • Changed library scanning to collect parse errors and continue scanning remaining lockfiles, surfacing errors via ScanResult.Errors.
  • Added regression tooling and fixtures (make diff-lockfile, comparison script, fixture list) plus extensive golden/dispatch tests and fixture updates.

Reviewed changes

Copilot reviewed 52 out of 76 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
scripts/lockfile-fixtures.json Defines real-world fixtures for A/B comparison runs.
scripts/compare-lockfile.go Adds a Git-ref comparison tool for AnalyzeLibrary() output.
scripts/README.md Documents diff-lockfile workflow and fixture management.
scanner/windows.go Continues scanning on lockfile parse errors and records errors.
scanner/trivy/jar/jar.go Replaces fanal post-analyzer registration with a standalone ParseJAR function.
scanner/testdata/golden/wrong-name-log4j-core.jar.golden.json Golden output for JAR edge case fixture.
scanner/testdata/golden/uv.lock.golden.json Golden output for uv lockfile fixture.
scanner/testdata/golden/requirements.txt.golden.json Golden output for pip requirements fixture.
scanner/testdata/golden/pubspec.lock.golden.json Golden output for Dart pubspec lock fixture.
scanner/testdata/golden/pom.xml.golden.json Golden output for Maven pom fixture.
scanner/testdata/golden/poetry-v2_poetry.lock.golden.json Golden output for Poetry v2 fixture.
scanner/testdata/golden/poetry-v1_poetry.lock.golden.json Golden output for Poetry v1 fixture.
scanner/testdata/golden/pnpm_pnpm-lock.yaml.golden.json Golden output for pnpm fixture (expected empty/parse-error behavior).
scanner/testdata/golden/packages.lock.json.golden.json Golden output for NuGet lock fixture.
scanner/testdata/golden/packages.config.golden.json Golden output for NuGet packages.config fixture.
scanner/testdata/golden/mix.lock.golden.json Golden output for Elixir mix.lock fixture.
scanner/testdata/golden/log4j-core-2.13.0.jar.golden.json Golden output for log4j-core JAR fixture.
scanner/testdata/golden/hello-rust.golden.json Golden output for Rust binary fixture.
scanner/testdata/golden/gradle.lockfile.golden.json Golden output for Gradle lockfile fixture.
scanner/testdata/golden/gobinary.golden.json Golden output for Go binary fixture.
scanner/testdata/golden/go.sum.golden.json Golden output for go.sum fixture (expected empty behavior).
scanner/testdata/golden/go.mod.golden.json Golden output for go.mod fixture.
scanner/testdata/golden/datacollector.deps.json.golden.json Golden output for .deps.json fixture.
scanner/testdata/golden/conan-v2_conan.lock.golden.json Golden output for Conan v2 fixture.
scanner/testdata/golden/conan-v1_conan.lock.golden.json Golden output for Conan v1 fixture.
scanner/testdata/golden/composer.lock.golden.json Golden output for composer.lock fixture.
scanner/testdata/golden/bun.lock.golden.json Golden output for bun.lock fixture.
scanner/testdata/golden/Podfile.lock.golden.json Golden output for CocoaPods lock fixture.
scanner/testdata/golden/Pipfile.lock.golden.json Golden output for Pipenv fixture.
scanner/testdata/golden/Package.resolved.golden.json Golden output for Swift resolved fixture.
scanner/testdata/golden/Gemfile.lock.golden.json Golden output for Bundler fixture.
scanner/testdata/golden/Directory.Packages.props.golden.json Golden output for Directory.Packages.props fixture.
scanner/testdata/fixtures/requirements.txt Adds minimal pip requirements fixture.
scanner/testdata/fixtures/pubspec.lock Adds Dart pubspec.lock fixture.
scanner/testdata/fixtures/pom.xml Adds minimal Maven pom fixture.
scanner/testdata/fixtures/poetry-v2/poetry.lock Adds Poetry v2 fixture.
scanner/testdata/fixtures/packages.lock.json Adds NuGet lock fixture.
scanner/testdata/fixtures/packages.config Adds NuGet packages.config fixture.
scanner/testdata/fixtures/mix.lock Adds Elixir mix.lock fixture.
scanner/testdata/fixtures/gradle.lockfile Adds Gradle lockfile fixture.
scanner/testdata/fixtures/go.mod Adds Go module fixture.
scanner/testdata/fixtures/datacollector.deps.json Adds .NET deps.json fixture.
scanner/testdata/fixtures/conan-v2/conan.lock Adds Conan v2 lock fixture.
scanner/testdata/fixtures/conan-v1/conan.lock Adds Conan v1 lock fixture.
scanner/testdata/fixtures/bun.lock Adds Bun lock fixture.
scanner/testdata/fixtures/Podfile.lock Adds CocoaPods lock fixture.
scanner/testdata/fixtures/Package.resolved Adds Swift Package.resolved fixture.
scanner/testdata/fixtures/Gemfile.lock Adds Bundler lock fixture.
scanner/testdata/fixtures/Directory.Packages.props Adds Directory.Packages.props fixture.
scanner/pseudo.go Continues scanning on lockfile parse errors and records errors (pseudo mode).
scanner/dispatch_test.go Adds table-driven tests for file→parser dispatch logic.
scanner/dispatch.go Introduces detectParserType() dispatch logic for direct parser calls.
scanner/base.go Core refactor: direct Trivy parser calls, new dispatch/parse helpers, error-collection behavior.
scanner/analyze_golden_test.go Adds golden tests covering many parser types and edge cases (skipping integration submodule binaries when absent).
go.mod Adjusts dependency graph after removing fanal usage (x/sync becomes indirect).
GNUmakefile Adds diff-lockfile make target for regression comparisons.
.gitignore Ignores an optional built scripts/compare-lockfile binary.
Files not reviewed (1)
  • scanner/testdata/fixtures/npm-v1/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@kotakanbe kotakanbe requested a review from Copilot March 19, 2026 00:24
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the Trivy fanal analyzer framework from the scanner path and switches AnalyzeLibrary() to dispatch directly to Trivy dependency parsers, aiming to reduce transitive dependencies (notably IaC/misconf) and shrink the scanner-only binary size.

Changes:

  • Rewires AnalyzeLibrary() to use detectParserType() + direct Trivy parser calls (including a standalone JAR parser).
  • Updates library-scanning flows to collect per-lockfile parse errors while continuing to scan remaining files.
  • Adds regression tooling: table-driven dispatch tests, AnalyzeLibrary golden tests + fixtures, and a make diff-lockfile comparison script with real-world fixtures.

Reviewed changes

Copilot reviewed 52 out of 76 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
scripts/lockfile-fixtures.json Defines real-world fixtures (URLs + metadata) for lockfile comparison runs.
scripts/compare-lockfile.go Adds a dev-only tool to compare AnalyzeLibrary() output across Git refs using downloaded fixtures.
scripts/README.md Documents the diff-lockfile workflow and how to add fixtures.
scanner/windows.go Changes lockfile parse failures to be collected and scanning to continue.
scanner/trivy/jar/jar.go Refactors JAR parsing into a standalone ParseJAR function (no fanal registration).
scanner/pseudo.go Changes lockfile parse failures to be collected and scanning to continue (pseudo mode).
scanner/dispatch_test.go Adds table-driven tests for file-to-parser dispatch behavior.
scanner/dispatch.go Introduces detectParserType() and helper logic for dispatching files to parsers.
scanner/base.go Replaces fanal-based library analysis with direct Trivy parser calls; adds helper parsing functions.
scanner/analyze_golden_test.go Adds golden tests to ensure parser output remains stable across supported lockfile types.
go.mod Removes direct dependency on golang.org/x/sync (now indirect) due to fanal removal.
GNUmakefile Adds diff-lockfile make target to run the comparison tool.
.gitignore Ignores a locally built scripts/compare-lockfile binary.
scanner/testdata/golden/wrong-name-log4j-core.jar.golden.json Golden output for “wrong-name-log4j-core.jar”.
scanner/testdata/golden/uv.lock.golden.json Golden output for uv.lock.
scanner/testdata/golden/requirements.txt.golden.json Golden output for requirements.txt.
scanner/testdata/golden/pubspec.lock.golden.json Golden output for pubspec.lock.
scanner/testdata/golden/pom.xml.golden.json Golden output for pom.xml.
scanner/testdata/golden/poetry-v2_poetry.lock.golden.json Golden output for poetry-v2/poetry.lock.
scanner/testdata/golden/poetry-v1_poetry.lock.golden.json Golden output for poetry-v1/poetry.lock.
scanner/testdata/golden/pnpm_pnpm-lock.yaml.golden.json Golden output for pnpm v8 fixture (expected empty due to known parse error).
scanner/testdata/golden/packages.lock.json.golden.json Golden output for packages.lock.json.
scanner/testdata/golden/packages.config.golden.json Golden output for packages.config.
scanner/testdata/golden/mix.lock.golden.json Golden output for mix.lock.
scanner/testdata/golden/log4j-core-2.13.0.jar.golden.json Golden output for log4j-core-2.13.0.jar.
scanner/testdata/golden/hello-rust.golden.json Golden output for hello-rust binary fixture.
scanner/testdata/golden/gradle.lockfile.golden.json Golden output for gradle.lockfile.
scanner/testdata/golden/gobinary.golden.json Golden output for Go binary fixture.
scanner/testdata/golden/go.sum.golden.json Golden output for standalone go.sum behavior (empty).
scanner/testdata/golden/go.mod.golden.json Golden output for go.mod.
scanner/testdata/golden/datacollector.deps.json.golden.json Golden output for .deps.json fixture.
scanner/testdata/golden/conan-v2_conan.lock.golden.json Golden output for Conan v2 lock fixture.
scanner/testdata/golden/conan-v1_conan.lock.golden.json Golden output for Conan v1 lock fixture.
scanner/testdata/golden/composer.lock.golden.json Golden output for composer.lock.
scanner/testdata/golden/bun.lock.golden.json Golden output for bun.lock.
scanner/testdata/golden/Podfile.lock.golden.json Golden output for Podfile.lock.
scanner/testdata/golden/Pipfile.lock.golden.json Golden output for Pipfile.lock.
scanner/testdata/golden/Package.resolved.golden.json Golden output for Package.resolved.
scanner/testdata/golden/Gemfile.lock.golden.json Golden output for Gemfile.lock.
scanner/testdata/golden/Directory.Packages.props.golden.json Golden output for Directory.Packages.props.
scanner/testdata/fixtures/requirements.txt Adds committed fixture for pip requirements parsing.
scanner/testdata/fixtures/pubspec.lock Adds committed fixture for Dart pub lock parsing.
scanner/testdata/fixtures/pom.xml Adds committed fixture for Maven POM parsing.
scanner/testdata/fixtures/poetry-v2/poetry.lock Adds committed fixture for Poetry v2 parsing.
scanner/testdata/fixtures/packages.lock.json Adds committed fixture for NuGet lock parsing.
scanner/testdata/fixtures/packages.config Adds committed fixture for NuGet packages.config parsing.
scanner/testdata/fixtures/mix.lock Adds committed fixture for Elixir mix.lock parsing.
scanner/testdata/fixtures/gradle.lockfile Adds committed fixture for Gradle lockfile parsing.
scanner/testdata/fixtures/go.mod Adds committed fixture for Go module parsing.
scanner/testdata/fixtures/datacollector.deps.json Adds committed fixture for .NET deps parsing.
scanner/testdata/fixtures/conan-v2/conan.lock Adds committed fixture for Conan v2 parsing.
scanner/testdata/fixtures/conan-v1/conan.lock Adds committed fixture for Conan v1 parsing.
scanner/testdata/fixtures/bun.lock Adds committed fixture for Bun lock parsing.
scanner/testdata/fixtures/Podfile.lock Adds committed fixture for CocoaPods lock parsing.
scanner/testdata/fixtures/Package.resolved Adds committed fixture for SwiftPM resolved parsing.
scanner/testdata/fixtures/Gemfile.lock Adds committed fixture for Bundler lock parsing.
scanner/testdata/fixtures/Directory.Packages.props Adds committed fixture for .NET packages props parsing.
Files not reviewed (1)
  • scanner/testdata/fixtures/npm-v1/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@kotakanbe kotakanbe requested a review from Copilot March 19, 2026 00:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the Trivy fanal analyzer framework from the scanner-only path and instead dispatches directly to Trivy’s dependency parsers, significantly reducing the scanner binary size and transitive dependency footprint (notably eliminating IaC/misconf-related packages).

Changes:

  • Rewrites AnalyzeLibrary() to use detectParserType() + direct Trivy parser calls (including a standalone JAR parser entrypoint).
  • Changes library scanning to collect per-lockfile parse errors and continue scanning remaining lockfiles (errors surfaced via ScanResult.Errors).
  • Adds regression tooling and tests: dispatch unit tests, extensive golden fixtures, and a make diff-lockfile A/B comparison script.

Reviewed changes

Copilot reviewed 52 out of 76 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
scripts/lockfile-fixtures.json Defines real-world lockfile/binary fixtures used for cross-ref comparisons.
scripts/compare-lockfile.go Adds an A/B comparison tool to diff AnalyzeLibrary() output between Git refs.
scripts/README.md Documents the new diff-lockfile workflow and fixture format.
scanner/base.go Replaces fanal-based analysis with direct Trivy parser calls; adds parse dispatch helpers.
scanner/dispatch.go Introduces detectParserType() to map files to parsers (mirrors fanal Required logic).
scanner/dispatch_test.go Adds table-driven tests covering file-to-parser dispatch edge cases.
scanner/trivy/jar/jar.go Refactors JAR parsing into a standalone ParseJAR() function callable directly.
scanner/windows.go Changes lockfile scan flow to continue on parse errors and record them in errs.
scanner/pseudo.go Changes lockfile scan flow to continue on parse errors and record them in errs.
scanner/analyze_golden_test.go Adds golden tests for AnalyzeLibrary() across many lockfile types and binaries (with submodule-aware skips).
scanner/testdata/golden/wrong-name-log4j-core.jar.golden.json Adds golden output for a JAR edge case fixture.
scanner/testdata/golden/uv.lock.golden.json Adds golden output for uv.lock parsing.
scanner/testdata/golden/requirements.txt.golden.json Adds golden output for pip requirements parsing.
scanner/testdata/golden/pubspec.lock.golden.json Adds golden output for Dart pub lock parsing.
scanner/testdata/golden/pom.xml.golden.json Adds golden output for Maven POM parsing.
scanner/testdata/golden/poetry-v2_poetry.lock.golden.json Adds golden output for Poetry v2 lock parsing.
scanner/testdata/golden/poetry-v1_poetry.lock.golden.json Adds golden output for Poetry v1 lock parsing.
scanner/testdata/golden/pnpm_pnpm-lock.yaml.golden.json Adds golden output for pnpm fixture (notably empty for known parse-error case).
scanner/testdata/golden/packages.lock.json.golden.json Adds golden output for NuGet packages.lock.json parsing.
scanner/testdata/golden/packages.config.golden.json Adds golden output for NuGet packages.config parsing.
scanner/testdata/golden/mix.lock.golden.json Adds golden output for Elixir mix lock parsing.
scanner/testdata/golden/log4j-core-2.13.0.jar.golden.json Adds golden output for log4j-core JAR parsing.
scanner/testdata/golden/hello-rust.golden.json Adds golden output for Rust binary fixture parsing.
scanner/testdata/golden/gradle.lockfile.golden.json Adds golden output for Gradle lockfile parsing.
scanner/testdata/golden/gobinary.golden.json Adds golden output for Go binary fixture parsing.
scanner/testdata/golden/go.sum.golden.json Adds golden output for go.sum behavior (empty when standalone).
scanner/testdata/golden/go.mod.golden.json Adds golden output for go.mod parsing.
scanner/testdata/golden/datacollector.deps.json.golden.json Adds golden output for .NET deps.json parsing.
scanner/testdata/golden/conan-v2_conan.lock.golden.json Adds golden output for Conan v2 lock parsing.
scanner/testdata/golden/conan-v1_conan.lock.golden.json Adds golden output for Conan v1 lock parsing.
scanner/testdata/golden/composer.lock.golden.json Adds golden output for Composer lock parsing.
scanner/testdata/golden/bun.lock.golden.json Adds golden output for Bun lock parsing.
scanner/testdata/golden/Directory.Packages.props.golden.json Adds golden output for NuGet Directory.Packages.props parsing.
scanner/testdata/fixtures/requirements.txt Adds a pip requirements fixture.
scanner/testdata/fixtures/pubspec.lock Adds a Dart pubspec.lock fixture.
scanner/testdata/fixtures/pom.xml Adds a Maven POM fixture.
scanner/testdata/fixtures/poetry-v2/poetry.lock Adds a Poetry v2 lock fixture.
scanner/testdata/fixtures/packages.lock.json Adds a NuGet packages.lock.json fixture.
scanner/testdata/fixtures/packages.config Adds a NuGet packages.config fixture.
scanner/testdata/fixtures/mix.lock Adds an Elixir mix.lock fixture.
scanner/testdata/fixtures/gradle.lockfile Adds a Gradle lockfile fixture.
scanner/testdata/fixtures/go.mod Adds a Go module fixture.
scanner/testdata/fixtures/datacollector.deps.json Adds a .NET deps.json fixture.
scanner/testdata/fixtures/conan-v2/conan.lock Adds a Conan v2 lock fixture.
scanner/testdata/fixtures/conan-v1/conan.lock Adds a Conan v1 lock fixture.
scanner/testdata/fixtures/bun.lock Adds a Bun lock fixture.
scanner/testdata/fixtures/Podfile.lock Adds a CocoaPods lock fixture.
scanner/testdata/fixtures/Package.resolved Adds a Swift Package.resolved fixture.
scanner/testdata/fixtures/Gemfile.lock Adds a Bundler Gemfile.lock fixture.
scanner/testdata/fixtures/Directory.Packages.props Adds a Directory.Packages.props fixture.
GNUmakefile Adds a diff-lockfile make target to run the comparison tool.
.gitignore Ignores a potential built scripts/compare-lockfile artifact.
go.mod Adjusts module requirements after removing direct fanal usage (moves x/sync to indirect).
Files not reviewed (1)
  • scanner/testdata/fixtures/npm-v1/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@kotakanbe kotakanbe requested a review from Copilot March 19, 2026 00:55
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the scanner’s language/library analysis to bypass Trivy’s fanal analyzer framework and call Trivy dependency parsers directly, significantly reducing transitive dependencies and scanner-only binary size. It also adds regression tooling and expanded golden/dispatch tests to ensure parser behavior remains consistent.

Changes:

  • Rewrite AnalyzeLibrary() to dispatch via detectParserType() and call Trivy parsers directly (including a standalone JAR parser).
  • Change library scanning to collect parse errors and continue scanning remaining lockfiles, surfacing errors in ScanResult.Errors.
  • Add make diff-lockfile tooling plus fixtures and expanded golden tests for parser regression coverage.

Reviewed changes

Copilot reviewed 52 out of 76 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scripts/lockfile-fixtures.json Defines real-world fixtures for A/B regression comparisons.
scripts/compare-lockfile.go Adds a git-ref comparison tool to validate AnalyzeLibrary() output across refs.
scripts/README.md Documents the diff-lockfile workflow and fixture management.
scanner/windows.go Continues scanning on lockfile parse errors; collects errors into scan result.
scanner/trivy/jar/jar.go Replaces fanal post-analyzer with direct ParseJAR function.
scanner/pseudo.go Continues scanning on lockfile parse errors; collects errors into scan result.
scanner/dispatch_test.go Adds table-driven tests for file-to-parser dispatch behavior.
scanner/dispatch.go Introduces parserType + detectParserType() dispatch logic.
scanner/base.go Refactors AnalyzeLibrary() to call Trivy parsers directly and removes fanal wiring/registrations.
scanner/analyze_golden_test.go Adds/updates golden tests for AnalyzeLibrary() across many fixture types (skips binary fixtures if submodule absent).
go.mod Adjusts module requirements after removing direct fanal usage.
GNUmakefile Adds diff-lockfile target for regression comparisons.
.gitignore Ignores the scripts/compare-lockfile output artifact.
scanner/testdata/golden/wrong-name-log4j-core.jar.golden.json Golden output for JAR “wrong name” edge case.
scanner/testdata/golden/uv.lock.golden.json Golden output for uv.lock.
scanner/testdata/golden/requirements.txt.golden.json Golden output for requirements.txt.
scanner/testdata/golden/pubspec.lock.golden.json Golden output for pubspec.lock.
scanner/testdata/golden/pom.xml.golden.json Golden output for pom.xml.
scanner/testdata/golden/poetry-v2_poetry.lock.golden.json Golden output for Poetry v2 lockfile fixture.
scanner/testdata/golden/poetry-v1_poetry.lock.golden.json Golden output for Poetry v1 lockfile fixture.
scanner/testdata/golden/pnpm_pnpm-lock.yaml.golden.json Golden output covering known pnpm parse-error behavior (empty result).
scanner/testdata/golden/packages.lock.json.golden.json Golden output for NuGet packages.lock.json.
scanner/testdata/golden/packages.config.golden.json Golden output for NuGet packages.config.
scanner/testdata/golden/mix.lock.golden.json Golden output for Elixir mix.lock.
scanner/testdata/golden/log4j-core-2.13.0.jar.golden.json Golden output for JAR parsing.
scanner/testdata/golden/hello-rust.golden.json Golden output for Rust binary parsing.
scanner/testdata/golden/gradle.lockfile.golden.json Golden output for Gradle lockfile parsing.
scanner/testdata/golden/gobinary.golden.json Golden output for Go binary parsing.
scanner/testdata/golden/go.sum.golden.json Golden output for go.sum behavior (no results standalone).
scanner/testdata/golden/go.mod.golden.json Golden output for Go module parsing.
scanner/testdata/golden/datacollector.deps.json.golden.json Golden output for .NET deps JSON parsing.
scanner/testdata/golden/conan-v2_conan.lock.golden.json Golden output for Conan v2 lockfile parsing.
scanner/testdata/golden/conan-v1_conan.lock.golden.json Golden output for Conan v1 lockfile parsing.
scanner/testdata/golden/composer.lock.golden.json Golden output for Composer lockfile parsing.
scanner/testdata/golden/bun.lock.golden.json Golden output for Bun lockfile parsing.
scanner/testdata/golden/Podfile.lock.golden.json Golden output for CocoaPods lockfile parsing.
scanner/testdata/golden/Pipfile.lock.golden.json Golden output for Pipenv lockfile parsing.
scanner/testdata/golden/Package.resolved.golden.json Golden output for Swift Package.resolved parsing.
scanner/testdata/golden/Gemfile.lock.golden.json Golden output for Bundler Gemfile.lock parsing.
scanner/testdata/golden/Directory.Packages.props.golden.json Golden output for NuGet Directory.Packages.props parsing.
scanner/testdata/fixtures/requirements.txt Adds requirements.txt fixture.
scanner/testdata/fixtures/pubspec.lock Adds pubspec.lock fixture.
scanner/testdata/fixtures/pom.xml Adds pom.xml fixture.
scanner/testdata/fixtures/poetry-v2/poetry.lock Adds Poetry v2 lockfile fixture.
scanner/testdata/fixtures/packages.lock.json Adds NuGet lockfile fixture.
scanner/testdata/fixtures/packages.config Adds NuGet config fixture.
scanner/testdata/fixtures/mix.lock Adds Elixir lockfile fixture.
scanner/testdata/fixtures/gradle.lockfile Adds Gradle lockfile fixture.
scanner/testdata/fixtures/go.mod Adds Go module fixture.
scanner/testdata/fixtures/datacollector.deps.json Adds .NET deps JSON fixture.
scanner/testdata/fixtures/conan-v2/conan.lock Adds Conan v2 fixture.
scanner/testdata/fixtures/conan-v1/conan.lock Adds Conan v1 fixture.
scanner/testdata/fixtures/bun.lock Adds Bun lockfile fixture.
scanner/testdata/fixtures/Podfile.lock Adds CocoaPods fixture.
scanner/testdata/fixtures/Package.resolved Adds Swift Package.resolved fixture.
scanner/testdata/fixtures/Gemfile.lock Adds Bundler fixture.
scanner/testdata/fixtures/Directory.Packages.props Adds NuGet Directory.Packages.props fixture.
Files not reviewed (1)
  • scanner/testdata/fixtures/npm-v1/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@kotakanbe kotakanbe requested a review from Copilot March 19, 2026 01:08
@kotakanbe
Copy link
Copy Markdown
Member Author

Response to Copilot review (review-3994608680)

scanner/analyze_golden_test.go — unmarshal array into single struct
Already fixed in 3c8a234. The test now unmarshals into []goldenLibraryScanner and sums lib counts across elements.

scripts/README.md — fixture count mismatch (134 vs 129)
Updated the PR description to use the correct count (129). The original 134 was from an earlier iteration that included additional ecosystems (gradle, nuget, conan, pub, cocoapods) which were later consolidated. Thanks for catching the inconsistency.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 56 out of 80 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • scanner/testdata/fixtures/npm-v1/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kotakanbe kotakanbe requested a review from shino March 23, 2026 21:14
@shino
Copy link
Copy Markdown
Collaborator

shino commented Mar 24, 2026

make compare-lockfile shows two patterns for pnpm dev flags, one is added and another is removed. Is this known pattern?

% cat /tmp/diet-compare/comparison.log
[snip]
DIFFERENT  pnpm         withastro/astro
--- /tmp/diet-compare/result-base/withastro_astro__pnpm-lock.yaml.result.json   2026-03-24 18:28:22.515640602 +0900
+++ /tmp/diet-compare/result-current/withastro_astro__pnpm-lock.yaml.result.json        2026-03-24 18:28:11.119634294 +0900
@@ -1634,13 +1634,13 @@
       {
         "name": "@types/alpinejs",
         "version": "3.13.10",
-        "purl": "pkg:npm/%40types/alpinejs@3.13.10"
+        "purl": "pkg:npm/%40types/alpinejs@3.13.10",
+        "dev": true
       },
[snip]
DIFFERENT  pnpm         pnpm/pnpm
--- /tmp/diet-compare/result-base/pnpm_pnpm__pnpm-lock.yaml.result.json 2026-03-24 18:28:22.583640772 +0900
+++ /tmp/diet-compare/result-current/pnpm_pnpm__pnpm-lock.yaml.result.json      2026-03-24 18:28:11.179634268 +0900
@@ -1377,8 +1377,7 @@
       {
         "name": "@pnpm/fs.packlist",
         "version": "2.0.0",
-        "purl": "pkg:npm/%40pnpm/fs.packlist@2.0.0",
-        "dev": true
+        "purl": "pkg:npm/%40pnpm/fs.packlist@2.0.0"
       },
       {
         "name": "@pnpm/git-utils",
[snip]

shino
shino previously approved these changes Mar 24, 2026
Copy link
Copy Markdown
Collaborator

@shino shino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside one tiny nitpick comment, this PR is GREAT!! Can't thank you enough!

@kotakanbe
Copy link
Copy Markdown
Member Author

@shino Good catch — the PR description's characterization ("dev: true being added or corrected, pre-existing bug in master") was inaccurate. The bidirectional changes you spotted (dev added in one package, removed in another) reveal a real issue.

Root cause: non-determinism in Trivy's pnpm v9 parser

This is caused by Go map iteration non-determinism in Trivy's parseV9().

In trivy/pkg/dependency/parser/nodejs/pnpm/parse.go L170:

for _, importer := range lockFile.Importers {   // map iteration = non-deterministic
    for n, v := range importer.DevDependencies {
        devDeps[n] = v.Version                   // last write wins
    }
    for n, v := range importer.Dependencies {
        deps[n] = v.Version                      // last write wins
    }
}

In monorepo lockfiles (like pnpm/pnpm), the same package can be referenced from multiple importers with different version specifiers. For example, @pnpm/fs.packlist in the pnpm/pnpm lockfile:

# fetching/git-fetcher — registry version
dependencies:
  '@pnpm/fs.packlist':
    version: 2.0.0

# fetching/directory-fetcher — workspace link
dependencies:
  '@pnpm/fs.packlist':
    version: link:../../fs/packlist

Whichever importer is iterated last overwrites deps["@pnpm/fs.packlist"]. Then when the parser checks:

if v, ok := deps[name]; ok && p.trimPeerDeps(v, lockVer) == ver {
    dev = false
}
  • If deps ends up as "2.0.0" → matches @pnpm/fs.packlist@2.0.0dev = false
  • If deps ends up as "link:../../fs/packlist" → no match → dev stays true

This is a Trivy upstream bug, not introduced by this PR. Both the fanal path (master) and direct parser call (this PR) use the same pnpm.NewParser(), but compare-lockfile runs two separate processes (one per git worktree), so each gets different map iteration order — producing the bidirectional diffs you observed. Running compare-lockfile multiple times would likely produce varying results.

This only affects monorepo-style lockfiles where the same package has both workspace links and registry versions across different importers.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 56 out of 80 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • scanner/testdata/fixtures/npm-v1/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Rename golden files: .golden.json → .json (redundant under testdata/golden/)
- Use cmp.Or for sort comparators in normalizeResult
- Switch on langType in parseBinary to isolate sentinel errors per language
- Wrap parseExecutableBinary errors with language name, symmetrize structure
- Simplify dispatch.go: inline filepath.Base in switch, use slices.Contains
- Extract base-runner.go from compare-lockfile.go via //go:embed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kotakanbe kotakanbe requested review from MaineK00n and shino March 27, 2026 03:23
Copy link
Copy Markdown
Collaborator

@shino shino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏋️

@kotakanbe kotakanbe merged commit 652294a into master Mar 27, 2026
8 checks passed
@kotakanbe kotakanbe deleted the diet-trivy-dispatch branch March 27, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants