Skip to content

Commit bacbcb4

Browse files
committed
Test mergeReplaceDirectives with duplicate module
1 parent 2edc6c8 commit bacbcb4

File tree

10 files changed

+119
-7
lines changed

10 files changed

+119
-7
lines changed

pkg/commands/internal/builder.go

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ func (b Builder) addReplaceDirective(ctx context.Context, plugin *Plugin) error
168168
return nil
169169
}
170170

171+
type goModReplace struct {
172+
Replace []struct {
173+
Old struct{ Path, Version string }
174+
New struct{ Path, Version string }
175+
}
176+
}
177+
171178
func (b Builder) mergeReplaceDirectives(ctx context.Context, pluginPath string) error {
172179
cmd := exec.CommandContext(ctx, "go", "mod", "edit", "-json")
173180
cmd.Dir = pluginPath
@@ -179,18 +186,36 @@ func (b Builder) mergeReplaceDirectives(ctx context.Context, pluginPath string)
179186
return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err)
180187
}
181188

182-
var goMod struct {
183-
Replace []struct {
184-
Old struct{ Path, Version string }
185-
New struct{ Path, Version string }
186-
}
189+
var pluginGoMod goModReplace
190+
err = json.Unmarshal(output, &pluginGoMod)
191+
if err != nil {
192+
return fmt.Errorf("unmarshal go mod json: %w", err)
193+
}
194+
195+
cmd = exec.CommandContext(ctx, "go", "mod", "edit", "-json")
196+
cmd.Dir = b.repo
197+
output, err = cmd.CombinedOutput()
198+
if err != nil {
199+
b.log.Warnf("%s", string(output))
200+
201+
return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err)
187202
}
188-
err = json.Unmarshal(output, &goMod)
203+
204+
var rootGoMod goModReplace
205+
err = json.Unmarshal(output, &rootGoMod)
189206
if err != nil {
190207
return fmt.Errorf("unmarshal go mod json: %w", err)
191208
}
192209

193-
for _, r := range goMod.Replace {
210+
for _, r := range pluginGoMod.Replace {
211+
for _, rr := range rootGoMod.Replace {
212+
if r.Old.Path == rr.Old.Path && r.Old.Version == rr.Old.Version {
213+
return fmt.Errorf("duplicate replace directive for %s@%s", r.Old.Path, r.Old.Version)
214+
}
215+
}
216+
}
217+
218+
for _, r := range pluginGoMod.Replace {
194219
abs, err := filepath.Abs(filepath.Join(pluginPath, r.New.Path))
195220
if err != nil {
196221
return fmt.Errorf("get absolute path: %w", err)

pkg/commands/internal/builder_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,62 @@ go 1.24.0
104104
require.Len(t, goMod.Replace, 1)
105105
assert.Contains(t, goMod.Replace[0].New.Path, "testdata/plugin/target")
106106
}
107+
108+
func TestMergeReplaceDirectives_DuplicateReplace(t *testing.T) {
109+
t.Parallel()
110+
111+
tmp := t.TempDir()
112+
require.NoError(t, os.WriteFile(filepath.Join(tmp, "go.mod"), []byte(`
113+
module github.com/golangci/golangci-lint/v2
114+
go 1.24.0
115+
`), 0o644))
116+
require.NoError(t, os.Mkdir(filepath.Join(tmp, "golangci-lint"), 0o755))
117+
118+
// Both plugins define a replace directive for example.com/target.
119+
b := NewBuilder(nil, &Configuration{Plugins: []*Plugin{
120+
{Module: "example.com/plugin", Path: "testdata/plugin"},
121+
{Module: "example.com/plugin2", Path: "testdata/plugin2"},
122+
}}, tmp)
123+
124+
err := b.mergeReplaceDirectives(t.Context(), filepath.Join("testdata", "plugin"))
125+
require.NoError(t, err)
126+
127+
err = b.mergeReplaceDirectives(t.Context(), filepath.Join("testdata", "plugin2"))
128+
assert.ErrorContains(t, err, "duplicate replace directive for example.com/target")
129+
}
130+
131+
func TestMergeReplaceDirectives_DuplicateButDifferentVersion(t *testing.T) {
132+
t.Parallel()
133+
134+
tmp := t.TempDir()
135+
require.NoError(t, os.WriteFile(filepath.Join(tmp, "go.mod"), []byte(`
136+
module github.com/golangci/golangci-lint/v2
137+
go 1.24.0
138+
`), 0o644))
139+
require.NoError(t, os.Mkdir(filepath.Join(tmp, "golangci-lint"), 0o755))
140+
141+
// Both plugins define a replace directive for example.com/target.
142+
b := NewBuilder(nil, &Configuration{Plugins: []*Plugin{
143+
{Module: "example.com/plugin", Path: "testdata/plugin"},
144+
{Module: "example.com/plugin3", Path: "testdata/plugin3"},
145+
}}, tmp)
146+
147+
err := b.mergeReplaceDirectives(t.Context(), filepath.Join("testdata", "plugin"))
148+
require.NoError(t, err)
149+
150+
err = b.mergeReplaceDirectives(t.Context(), filepath.Join("testdata", "plugin3"))
151+
require.NoError(t, err)
152+
153+
cmd := exec.CommandContext(t.Context(), "go", "mod", "edit", "-json")
154+
cmd.Dir = b.repo
155+
output, err := cmd.CombinedOutput()
156+
require.NoError(t, err)
157+
158+
var goMod struct {
159+
Replace []struct{ New struct{ Path string } }
160+
}
161+
err = json.Unmarshal(output, &goMod)
162+
require.NoError(t, err)
163+
164+
assert.Len(t, goMod.Replace, 2)
165+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module example.com/plugin2
2+
3+
go 1.24.0
4+
5+
require example.com/target v0.0.0
6+
7+
replace example.com/target => ./target
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package plugin
2+
3+
import _ "example.com/target"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module example.com/target
2+
3+
go 1.24.0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package target
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module example.com/plugin2
2+
3+
go 1.24.0
4+
5+
require example.com/target v1.0.0
6+
7+
replace example.com/[email protected] => ./target
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package plugin
2+
3+
import _ "example.com/target"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module example.com/target
2+
3+
go 1.24.0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package target

0 commit comments

Comments
 (0)