Skip to content

feat: add Go modules (go.mod) support - #18

Draft
algomaster99 wants to merge 2 commits into
mainfrom
claude/golang-feature-manifests-piztaq
Draft

feat: add Go modules (go.mod) support#18
algomaster99 wants to merge 2 commits into
mainfrom
claude/golang-feature-manifests-piztaq

Conversation

@algomaster99

@algomaster99 algomaster99 commented Aug 17, 2026

Copy link
Copy Markdown
Member

Summary

yul now checks go.mod (#4): pkg/golang parses require entries via git-pkgs/manifests and flags any newly added/changed one pinned older than the latest release, same as the existing Maven/npm/PyPI/GitHub Actions checkers. Unlike those manifests, go.mod's require syntax has no ranges/operators at all — every entry is already an exact module version pair, so there's no bare-vs-range disambiguation to do.

Before (Claude writes a stale exact pin, nothing catches it):

$ echo 'require github.com/google/uuid v1.3.0' >> go.mod
$ # write succeeds silently; v1.3.0 is two years stale (latest: v1.6.0)

After:

outdated dependencies, use these versions instead:
  github.com/google/uuid  v1.3.0 -> v1.6.0

(exit 2, write blocked — Claude sees the correct version on stderr and retries)

Known gap, left for a follow-up: a module pinned to a pseudo-version (v0.0.0-<timestamp>-<hash>, Go's format for an untagged commit) always compares as older than any tagged release and gets flagged, even when the pin is deliberate (e.g. picking up an unreleased fix). go get/Renovate handle this by falling back to digest-tracking — resolving the module's latest commit and suggesting a newer pseudo-version instead of a tag — but that needs a resolver capability (VCS tip lookup) git-pkgs/enrichment doesn't currently expose, so it's out of scope here. go-06-pseudo-version-unreleased-fix in benchmark/cases.json exercises this scenario.

Changes

  • pkg/golang/gomod.go (new): Checker for go.mod. A few Go-specific cases needed a design pass — given:
    require (
        github.com/google/uuid    v1.3.0                                   // checked normally: v1.3.0 -> v1.6.0
        golang.org/x/sync         v0.0.0-20210220032951-036812b2e83c       // pseudo-version: always compares older than any tag
        github.com/some/v2mod     v2.3.4+incompatible                      // "+incompatible" ignored as build metadata
    )
    
    replace github.com/google/uuid => github.com/google/uuid v1.0.0        // not seen at all - git-pkgs/manifests doesn't parse replace as a dependency
    
    the pseudo-version and +incompatible cases are exercised in the tests below; the replace gap is a known parser limitation, same category as e.g. Maven's <parent> version-as-property.
  • pkg/golang/gomod_test.go (new): parsing (single-line/block require, indirect, replace ignored), fresh pin below/at latest, untouched-pin skip, pseudo-version and +incompatible cases.
  • main.go / main_test.go: wire golang.Checker into the checker registry; fix a test that asserted go.mod was unknown (now Cargo.toml, which still is).
  • README.md / CLAUDE.md: add go.mod to the supported-manifests list.
  • benchmark/cases.json: go-01..06 cases (resty/cobra/zap/uuid fresh, testify existing, pseudo-version-pin fresh).

claude added 2 commits August 17, 2026 04:25
Adds pkg/golang, a checker for go.mod's require entries (single-line and
block form, direct and indirect), following the pattern established for
Maven/npm/PyPI/GitHub Actions. Unlike those manifests, go.mod has no range
syntax, so every require entry is already an exact pin - pins.ExactVersion
is only used to reject malformed lines, not to filter loose specifiers.

The package doc comment covers the Go-specific gotchas: pseudo-versions
compare as older than any tagged release (semver prerelease precedence),
"+incompatible" is ignored as build metadata, go.mod's version is a
minimum under MVS rather than what's actually built, and `replace`
directives aren't visible to git-pkgs/manifests' parser.

Wires golang.Checker into main.go's checker registry, updates the
supported-manifests lists in README.md/CLAUDE.md, and adds go-01..05
cases to benchmark/cases.json.
Covers the gap flagged in review: yul's resolver only has release-tag
metadata, so a deliberate pseudo-version pin (picking up an unreleased
fix) always compares older than the latest tag and gets flagged/blocked
- there's no way for it to instead suggest a newer pseudo-version the
way `go get`/Renovate's digest tracking would. This case exercises that
scenario for manual benchmarking.
@algomaster99
algomaster99 force-pushed the claude/golang-feature-manifests-piztaq branch from a235310 to 99cf66b Compare August 17, 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.

2 participants