fix(gomod): auto-append +incompatible for non-module-path major versions#1012
fix(gomod): auto-append +incompatible for non-module-path major versions#1012kartikjoshi21 wants to merge 2 commits intoproject-dalec:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR improves Dalec’s gomod replace handling by normalizing replacement targets that specify a v2+ semantic version on a module path that does not use semantic import versioning (/vN)—automatically appending +incompatible to prevent Go module resolution failures.
Changes:
- Added normalization logic for
GomodReplace.goModEditArg()to append+incompatiblefor v2+ versions when the module path has no major-version suffix. - Introduced targeted unit tests covering the new normalization behavior and key non-rewrite cases.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
spec.go |
Adds normalizeGomodReplaceTarget() and applies it when generating go mod edit -replace arguments. |
generator_gomod_test.go |
Adds/extends tests to validate +incompatible normalization and ensure no rewrites for /vN paths and local replacements. |
Automatically normalize gomod replace targets for v2+ module versions that do not use a /vN module path suffix by appending +incompatible. Adds regression coverage for incompatible-version normalization and ensures existing valid replace forms remain unchanged." Signed-off-by: Kartik Joshi <karikjoshi21@gmail.com>
ebfc7c5 to
b839ee4
Compare
| expectErr: false, | ||
| expectedArg: "github.com/stretchr/testify=github.com/stretchr/testify@v1.8.0", | ||
| }, | ||
| { |
There was a problem hiding this comment.
How difficult would be to implement these as integration tests, so we actually pull some stuff for testing?
There was a problem hiding this comment.
I tried moving this into an integration-style test under test/linux_target_test.go, and CI is definitely exercising it now. The issue I hit is that the public +incompatible fixture I used (github.com/docker/distribution) appears to be flaky/problematic across distro CI, so the failure looks fixture-specific rather than a Dalec integration issue. i think i will open up an issue to handle adding these tests under integration.
There was a problem hiding this comment.
Thanks for looking into it. And did you run IG build with this patch to confirm that generates correct replace?
There was a problem hiding this comment.
kartikjoshi@kartikjoshiwindows:~/dalec-project/dalec$ git diff
diff --git a/test/linux_target_test.go b/test/linux_target_test.go
index 87ae1a0..6dc854f 100644
--- a/test/linux_target_test.go
+++ b/test/linux_target_test.go
@@ -2078,6 +2078,77 @@ Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/boot
})
})
+ t.Run("temp gomod incompatible replace probe", func(t *testing.T) {
+ t.Parallel()
+ ctx := startTestSpan(baseCtx, t)
+
+ spec := &dalec.Spec{
+ Name: "test-gomod-incompatible-probe",
+ Version: "0.0.1",
+ Revision: "1",
+ License: "MIT",
+ Website: "https://github.com/project-dalec/dalec",
+ Vendor: "Dalec",
+ Packager: "Dalec",
+ Description: "Temporary probe for gomod +incompatible replace",
+ Sources: map[string]dalec.Source{
+ "src": {
+ Inline: &dalec.SourceInline{
+ Dir: &dalec.SourceInlineDir{
+ Files: map[string]*dalec.SourceInlineFile{
+ "go.mod": {Contents: "module example.com/test\n\ngo 1.18\n\nrequire github.com/docker/distribution v2.8.3+incompatible\n"},
+ "main.go": {Contents: `package main
+
+import (
+ "fmt"
+ _ "github.com/docker/distribution/version"
+)
+
+func main() {
+ fmt.Println("hello")
+}
+`},
+ },
+ },
+ },
+ Generate: []*dalec.SourceGenerator{
+ {
+ Gomod: &dalec.GeneratorGomod{
+ Edits: &dalec.GomodEdits{
+ Replace: []dalec.GomodReplace{
+ {
+ Original: "github.com/docker/distribution",
+ Update: "github.com/docker/distribution@v2.8.3",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Dependencies: &dalec.PackageDependencies{
+ Build: map[string]dalec.PackageConstraints{
+ testConfig.GetPackage("golang"): {},
+ },
+ },
+ Build: dalec.ArtifactBuild{
+ Steps: []dalec.BuildStep{
+ {Command: "grep -F 'replace github.com/docker/distribution => github.com/docker/distribution v2.8.3+incompatible' ./src/go.mod"},
+ {Command: "cd ./src && go build"},
+ },
+ },
+ }
+
+ testEnv.RunTest(ctx, t, func(ctx context.Context, client gwclient.Client) {
+ req := newSolveRequest(
+ withBuildTarget(testConfig.Target.Package),
+ withSpec(ctx, t, spec),
+ )
+ solveT(ctx, t, client, req)
+ })
+ })
+
ild.go:219:
build.go:219: #86 Build deb package
build.go:219: #86 DONE 0.1s
build.go:219:
build.go:219: #87 Build deb package
build.go:219: #87 DONE 0.1s
build.go:219:
build.go:219: #88 Build deb package
build.go:219: #88 DONE 0.1s
--- PASS: TestBookworm (0.00s)
--- PASS: TestBookworm/temp_gomod_incompatible_replace_probe (643.21s)
PASS
ok github.com/project-dalec/dalec/test 643.390s
@invidian I added this test and things passed locally.
a4de639 to
b839ee4
Compare
Signed-off-by: Kartik Joshi <karikjoshi21@gmail.com>
|
@invidian LGTY? |
Summary
Normalize gomod replacement targets that use a v2+ semver on a module path
without a
/vNsuffix by automatically appending+incompatible.This prevents builds from failing for replace targets such as:
github.com/docker/cli@v29.2.0which should be normalized to:
github.com/docker/cli@v29.2.0+incompatibleWhat changed
GomodReplace.goModEditArg()to normalize replacement targetsWhy
Go module versioning requires
/vNsuffixes for major versions 2 and above.For repositories that do not follow semantic import versioning,
+incompatibleis required. This change makes Dalec handle that case automatically instead of
requiring each spec author to know and write the normalized version manually.
Testing
go test ./... -run TestGomodReplaceGoModEditArg -vgo test --test.short ./...make verify