You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Yul currently checks Maven (pom.xml), npm (package.json), and PyPI (requirements.txt, pyproject.toml) via #2/#3, using git-pkgs/manifests for parsing, git-pkgs/vers for exact-pin detection and comparison, and git-pkgs/enrichment for latest-release lookups.
git-pkgs/manifests parses 40+ ecosystems (manifests.Ecosystems() returns cargo, gem, composer, golang, nuget, hex, bazel, cocoapods, swift, conda, cran, elm, julia, hackage, pub, and more). Yul only wires up three of them. This issue tracks adding the rest, one ecosystem at a time, following the pattern established in #2 — each section below is independent and can be picked up separately.
Shared per-ecosystem steps, for reference (spelled out per-section below too):
Confirm the git-pkgs/vers scheme name and exact-pin semantics (bare-literal-is-exact or not) against real manifest examples.
Add a pkg/<ecosystem>/ package with a Checker implementing manifestchecker.ManifestChecker, built on manifests.Parse + pins.Diff, following pkg/npm/package.go as the template.
Wire the checker into newCheckers in main.go.
Unit tests: fresh exact pin below latest, fresh exact pin at latest, non-exact range/wildcard (ignored), an edit that doesn't touch the dependency (ignored), and the ecosystem's own "not actually exact" gotcha.
Spot-check that git-pkgs/enrichment's ecosyste.ms-backed resolver returns LatestVersion for that ecosystem's PURL type (smaller registries may have sparser coverage than npm/PyPI/Maven).
Add 5 cases to benchmark/cases.json (4 "fresh" + 1 "existing", matching the existing HTTP-client/JSON/logging/domain-4th-pick archetypes).
[ ] Cargo (Cargo.toml, pkg:cargo)
Confirm exact-pin semantics: a bare version in Cargo.toml (e.g. serde = "1.2.3") is an implicit caret range (^1.2.3), not an exact pin — same gotcha as Poetry's pyproject.toml tables, which is why pins.ExactVersion already takes a requireOperator flag. Reuse that path (requireOperator: true) rather than npm's bare-is-exact assumption.
pkg/cargo/ checker + wiring in main.go
Unit tests (including the implicit-caret case explicitly)
Confirm exact-pin semantics: Gemfile pins are usually written with ~>; a bare version (no operator) is exact, closer to npm's behavior than Cargo/Poetry's.
Confirmed via manifests.Identify("Podfile") → eco=cocoapods, kind=manifest (plain basename match, same shape as existing checkers). Podfile.lock also resolves as kind=lockfile — not relevant here since the hook only inspects manifest edits.
Confirmed via manifests.Identify: MODULE.bazel matches (bzlmod), but WORKSPACE, WORKSPACE.bazel, BUILD, and BUILD.bazel do not — git-pkgs/manifests only understands the newer bzlmod dependency format, not legacy WORKSPACE-based http_archive/git_repository rules. Scope is MODULE.bazel only; legacy WORKSPACE repos are out of scope until upstream adds that parser.
[ ] Go modules (go.mod, pkg:golang) — needs a design note first
Write a short design note resolving how "outdated" applies here: go.mod has no range syntax — every require line is already an exact pseudo-version or tag, and minimum version selection changes what "exact pin" even means. This likely needs its own comparison path rather than reusing pins.ExactVersion's operator-detection logic. (pkg/golang/ already exists as an empty placeholder package.)
pkg/golang/ checker + wiring in main.go
Unit tests
Confirm enrichment resolves pkg:golang purls
benchmark/cases.json: go-01..04 + go-05-*-existing, manifest go.mod, cases reflecting the pseudo-version/MVS difference rather than the plain "pin below latest" framing
[ ] GitHub Actions (.github/workflows/*.yml/*.yaml, pkg:githubactions) — needs a design note first
Write a short design note covering two open questions:
Dispatch mechanism. Every other ecosystem is identified by a fixed basename (pom.xml, Cargo.toml, Podfile, MODULE.bazel, ...), which is what manifestchecker.ManifestChecker.Filename() and checkerFor's filepath.Base() lookup in main.go assume. Workflow files have arbitrary basenames (ci.yml, release.yml, ...) and are only identifiable by directory — confirmed via manifests.Identify(".github/workflows/ci.yaml") matching but manifests.Identify("action.yml") (a composite action's own manifest) not matching. Adding this ecosystem means either widening ManifestChecker to match a full relative path/glob, or special-casing the .github/workflows/ directory in checkerFor.
Tag vs. SHA pins.uses: pins are usually a tag (@v4, mutable) or a full commit SHA (immutable, the security-recommended practice). "Outdated" doesn't cleanly reduce to the semver-comparison model the other ecosystems use.
pkg/githubactions/ checker + wiring in main.go (or dispatch change, per the design note)
benchmark/cases.json: ghactions-01..04 + ghactions-05-*-existing, manifest e.g. .github/workflows/ci.yml, prompts framed around adding a uses: owner/repo@ref step rather than a library dependency
[ ] Backlog (not blocking this issue's closure)
Everything else git-pkgs/manifests supports — Swift, Conda, Hex, Pub, Hackage, CRAN, Elm, Julia, etc. — considered opportunistically after the ecosystems above land, since they're lower-traffic for this hook's likely users.
Yul currently checks Maven (
pom.xml), npm (package.json), and PyPI (requirements.txt,pyproject.toml) via #2/#3, usinggit-pkgs/manifestsfor parsing,git-pkgs/versfor exact-pin detection and comparison, andgit-pkgs/enrichmentfor latest-release lookups.git-pkgs/manifestsparses 40+ ecosystems (manifests.Ecosystems()returns cargo, gem, composer, golang, nuget, hex, bazel, cocoapods, swift, conda, cran, elm, julia, hackage, pub, and more). Yul only wires up three of them. This issue tracks adding the rest, one ecosystem at a time, following the pattern established in #2 — each section below is independent and can be picked up separately.Shared per-ecosystem steps, for reference (spelled out per-section below too):
git-pkgs/versscheme name and exact-pin semantics (bare-literal-is-exact or not) against real manifest examples.pkg/<ecosystem>/package with aCheckerimplementingmanifestchecker.ManifestChecker, built onmanifests.Parse+pins.Diff, followingpkg/npm/package.goas the template.newCheckersinmain.go.git-pkgs/enrichment's ecosyste.ms-backed resolver returnsLatestVersionfor that ecosystem's PURL type (smaller registries may have sparser coverage than npm/PyPI/Maven).benchmark/cases.json(4"fresh"+ 1"existing", matching the existing HTTP-client/JSON/logging/domain-4th-pick archetypes).[ ] Cargo (
Cargo.toml,pkg:cargo)Cargo.toml(e.g.serde = "1.2.3") is an implicit caret range (^1.2.3), not an exact pin — same gotcha as Poetry'spyproject.tomltables, which is whypins.ExactVersionalready takes arequireOperatorflag. Reuse that path (requireOperator: true) rather than npm's bare-is-exact assumption.pkg/cargo/checker + wiring inmain.gopkg:cargopurlsbenchmark/cases.json:cargo-01..04(fresh) +cargo-05-*-existing, manifestCargo.toml[ ] RubyGems (
Gemfile,pkg:gem)~>; a bare version (no operator) is exact, closer to npm's behavior than Cargo/Poetry's.pkg/gem/checker + wiring inmain.gopkg:gempurlsbenchmark/cases.json:gem-01..04+gem-05-*-existing, manifestGemfile[ ] Composer (
composer.json,pkg:composer)pkg/composer/checker + wiring inmain.gopkg:composerpurlsbenchmark/cases.json:composer-01..04+composer-05-*-existing, manifestcomposer.json[ ] NuGet (
.csproj/packages.config,pkg:nuget)PackageReferenceversions are exact by default unless a bracket range ([1.0,2.0)) is used.pkg/nuget/checker + wiring inmain.gopkg:nugetpurlsbenchmark/cases.json:nuget-01..04+nuget-05-*-existing, manifest*.csproj(orpackages.config)[ ] CocoaPods (
Podfile,pkg:cocoapods)manifests.Identify("Podfile")→eco=cocoapods, kind=manifest(plain basename match, same shape as existing checkers).Podfile.lockalso resolves askind=lockfile— not relevant here since the hook only inspects manifest edits.pkg/cocoapods/checker + wiring inmain.gopkg:cocoapodspurlsbenchmark/cases.json:cocoapods-01..04+cocoapods-05-*-existing, manifestPodfile[ ] Bazel (
MODULE.bazelonly,pkg:bazel)manifests.Identify:MODULE.bazelmatches (bzlmod), butWORKSPACE,WORKSPACE.bazel,BUILD, andBUILD.bazeldo not —git-pkgs/manifestsonly understands the newer bzlmod dependency format, not legacyWORKSPACE-basedhttp_archive/git_repositoryrules. Scope isMODULE.bazelonly; legacy WORKSPACE repos are out of scope until upstream adds that parser.pkg/bazel/checker + wiring inmain.gopkg:bazelpurlsbenchmark/cases.json:bazel-01..04+bazel-05-*-existing, manifestMODULE.bazel, prompts framed aroundbazel_dep(...)entries[ ] Go modules (
go.mod,pkg:golang) — needs a design note firstgo.modhas no range syntax — everyrequireline is already an exact pseudo-version or tag, and minimum version selection changes what "exact pin" even means. This likely needs its own comparison path rather than reusingpins.ExactVersion's operator-detection logic. (pkg/golang/already exists as an empty placeholder package.)pkg/golang/checker + wiring inmain.gopkg:golangpurlsbenchmark/cases.json:go-01..04+go-05-*-existing, manifestgo.mod, cases reflecting the pseudo-version/MVS difference rather than the plain "pin below latest" framing[ ] GitHub Actions (
.github/workflows/*.yml/*.yaml,pkg:githubactions) — needs a design note firstpom.xml,Cargo.toml,Podfile,MODULE.bazel, ...), which is whatmanifestchecker.ManifestChecker.Filename()andcheckerFor'sfilepath.Base()lookup inmain.goassume. Workflow files have arbitrary basenames (ci.yml,release.yml, ...) and are only identifiable by directory — confirmed viamanifests.Identify(".github/workflows/ci.yaml")matching butmanifests.Identify("action.yml")(a composite action's own manifest) not matching. Adding this ecosystem means either wideningManifestCheckerto match a full relative path/glob, or special-casing the.github/workflows/directory incheckerFor.uses:pins are usually a tag (@v4, mutable) or a full commit SHA (immutable, the security-recommended practice). "Outdated" doesn't cleanly reduce to the semver-comparison model the other ecosystems use.pkg/githubactions/checker + wiring inmain.go(or dispatch change, per the design note)pkg:githubactionspurlsbenchmark/cases.json:ghactions-01..04+ghactions-05-*-existing, manifest e.g..github/workflows/ci.yml, prompts framed around adding auses: owner/repo@refstep rather than a library dependency[ ] Backlog (not blocking this issue's closure)
Everything else
git-pkgs/manifestssupports — Swift, Conda, Hex, Pub, Hackage, CRAN, Elm, Julia, etc. — considered opportunistically after the ecosystems above land, since they're lower-traffic for this hook's likely users.