@@ -68,89 +68,66 @@ type testEnv struct {
6868 goModPath string
6969}
7070
71- // setupTestEnv sets up the test environment with all necessary files and directories .
71+ // setupTestEnvFromTestdata sets up the test environment by copying testdata and tool source .
7272// It returns a testEnv struct with all the paths needed for the test.
73- func setupTestEnv (t * testing.T , yamlContent , goModContent string ) * testEnv {
73+ func setupTestEnvFromTestdata (t * testing.T , testdataDir string ) * testEnv {
7474 t .Helper ()
7575
76- tmpDir := t .TempDir ()
77- scriptDir := filepath .Join (tmpDir , "tools" , "generate-module-dependencies" )
78- if err := os .MkdirAll (scriptDir , 0755 ); err != nil {
79- t .Fatalf ("Failed to create script directory: %v" , err )
80- }
81-
82- projectRoot := tmpDir
83-
84- // Create dependency-replacements.yaml
85- yamlPath := filepath .Join (projectRoot , "dependency-replacements.yaml" )
86- if err := os .WriteFile (yamlPath , []byte (yamlContent ), 0644 ); err != nil {
87- t .Fatalf ("Failed to write dependency-replacements.yaml: %v" , err )
88- }
89-
90- // Create replaces-mod.tpl template
91- templateContent := `// BEGIN GENERATED REPLACES - DO NOT EDIT
92- // Generated by go generate - DO NOT EDIT MANUALLY
93- {{- range . }}
94- {{- if .Comment }}
95- // {{ .Comment }}
96- {{- end }}
97- replace {{ .Dependency }} => {{ .Replacement }}
98- {{ end -}}
99- // END GENERATED REPLACES
100-
101- `
102- templatePath := filepath .Join (scriptDir , "replaces-mod.tpl" )
103- if err := os .WriteFile (templatePath , []byte (templateContent ), 0644 ); err != nil {
104- t .Fatalf ("Failed to write replaces-mod.tpl: %v" , err )
105- }
106-
107- // Create go.mod file (this is the target file we'll modify)
108- goModPath := filepath .Join (projectRoot , "go.mod" )
109- if err := os .WriteFile (goModPath , []byte (goModContent ), 0644 ); err != nil {
110- t .Fatalf ("Failed to write go.mod: %v" , err )
111- }
112-
113- // Get the original working directory before changing
11476 originalWd , err := os .Getwd ()
11577 if err != nil {
11678 t .Fatalf ("Failed to get current working directory: %v" , err )
11779 }
11880
119- // Copy go.mod and go.sum to the test script directory so go generate can resolve dependencies
120- originalGoMod := filepath .Join (originalWd , "go.mod" )
121- originalGoSum := filepath .Join (originalWd , "go.sum" )
81+ // Get the testdata directory path
82+ testdataPath := filepath .Join (originalWd , "testdata" , testdataDir )
83+ if _ , err := os .Stat (testdataPath ); os .IsNotExist (err ) {
84+ t .Fatalf ("Testdata directory not found: %s" , testdataPath )
85+ }
12286
123- testGoMod := filepath .Join (scriptDir , "go.mod" )
124- testGoSum := filepath .Join (scriptDir , "go.sum" )
87+ tmpDir := t .TempDir ()
88+ projectRoot := tmpDir
89+ scriptDir := filepath .Join (tmpDir , "tools" , "generate-module-dependencies" )
12590
126- // Copy go.mod and go.sum
127- goModData , err := os .ReadFile (originalGoMod )
128- if err != nil {
129- t .Fatalf ("Failed to read original go.mod: %v" , err )
130- }
131- if err := os .WriteFile (testGoMod , goModData , 0644 ); err != nil {
132- t .Fatalf ("Failed to copy go.mod to test directory: %v" , err )
91+ // Copy testdata files to project root
92+ testdataYaml := filepath .Join (testdataPath , "dependency-replacements.yaml" )
93+ projectYaml := filepath .Join (projectRoot , "dependency-replacements.yaml" )
94+ if err := copyFile (testdataYaml , projectYaml ); err != nil {
95+ t .Fatalf ("Failed to copy dependency-replacements.yaml: %v" , err )
13396 }
13497
135- if goSumData , err := os . ReadFile ( originalGoSum ); err == nil {
136- if err := os . WriteFile ( testGoSum , goSumData , 0644 ); err != nil {
137- t . Fatalf ( "Failed to copy go.sum to test directory: %v" , err )
138- }
98+ testdataGoMod := filepath . Join ( testdataPath , "go.mod" )
99+ goModPath := filepath . Join ( projectRoot , "go.mod" )
100+ if err := copyFile ( testdataGoMod , goModPath ); err != nil {
101+ t . Fatalf ( "Failed to copy go.mod: %v" , err )
139102 }
140103
141- // Copy the internal directory structure so imports can be resolved
142- originalInternal := filepath .Join (originalWd , "internal" )
143- testInternal := filepath .Join (scriptDir , "internal" )
104+ // Copy tool source code to script directory
105+ if err := os .MkdirAll (scriptDir , 0755 ); err != nil {
106+ t .Fatalf ("Failed to create script directory: %v" , err )
107+ }
144108
145- if err := copyDir (originalInternal , testInternal ); err != nil {
146- t .Fatalf ("Failed to copy internal directory: %v" , err )
109+ // Copy all necessary tool files
110+ toolFiles := []string {"replaces-mod.tpl" , "main.go" , "generate.go" , "go.mod" , "go.sum" }
111+ for _ , file := range toolFiles {
112+ src := filepath .Join (originalWd , file )
113+ dst := filepath .Join (scriptDir , file )
114+ if _ , err := os .Stat (src ); err == nil {
115+ if err := copyFile (src , dst ); err != nil {
116+ t .Fatalf ("Failed to copy %s: %v" , file , err )
117+ }
118+ }
147119 }
148120
149- // Copy generate.go
150- originalGenerateGo := filepath .Join (originalWd , "generate.go" )
151- testGenerateGo := filepath .Join (scriptDir , "generate.go" )
152- if err := copyFile (originalGenerateGo , testGenerateGo ); err != nil {
153- t .Fatalf ("Failed to copy generate.go: %v" , err )
121+ // Copy tool directories
122+ toolDirs := []string {"internal" , "cmd" }
123+ for _ , dir := range toolDirs {
124+ src := filepath .Join (originalWd , dir )
125+ dst := filepath .Join (scriptDir , dir )
126+ if _ , err := os .Stat (src ); err == nil {
127+ if err := copyDir (src , dst ); err != nil {
128+ t .Fatalf ("Failed to copy %s directory: %v" , dir , err )
129+ }
130+ }
154131 }
155132
156133 return & testEnv {
@@ -159,8 +136,8 @@ replace {{ .Dependency }} => {{ .Replacement }}
159136 }
160137}
161138
162- // runGoGenerate runs `go generate` in the test environment
163- func runGoGenerate (t * testing.T , env * testEnv ) {
139+ // runCommand runs the generate command in the test environment
140+ func runCommand (t * testing.T , env * testEnv ) {
164141 t .Helper ()
165142
166143 // Change to script directory to simulate running from there
@@ -174,59 +151,67 @@ func runGoGenerate(t *testing.T, env *testEnv) {
174151 t .Fatalf ("Failed to change to script directory: %v" , err )
175152 }
176153
177- // Run go generate
178- cmd := exec .Command ("go" , "generate" )
154+ // Calculate the project root relative to scriptDir
155+ // scriptDir is tmpDir/tools/generate-module-dependencies
156+ // project root should be tmpDir (two levels up)
157+ projectRoot := filepath .Join (env .scriptDir , ".." , ".." )
158+ projectRoot , err = filepath .Abs (projectRoot )
159+ if err != nil {
160+ t .Fatalf ("Failed to resolve project root: %v" , err )
161+ }
162+
163+ // Calculate the yaml path relative to scriptDir
164+ // dependency-replacements.yaml is at projectRoot/dependency-replacements.yaml
165+ yamlPath := filepath .Join (projectRoot , "dependency-replacements.yaml" )
166+ relYamlPath , err := filepath .Rel (env .scriptDir , yamlPath )
167+ if err != nil {
168+ t .Fatalf ("Failed to calculate relative yaml path: %v" , err )
169+ }
170+
171+ // Calculate relative project root path
172+ relProjectRoot , err := filepath .Rel (env .scriptDir , projectRoot )
173+ if err != nil {
174+ t .Fatalf ("Failed to calculate relative project root: %v" , err )
175+ }
176+
177+ // Run the command directly
178+ cmd := exec .Command ("go" , "run" , "main.go" , "generate" ,
179+ "--dependency-yaml" , relYamlPath ,
180+ "--project-root" , relProjectRoot )
179181 cmd .Dir = env .scriptDir
180182 output , err := cmd .CombinedOutput ()
181183 if err != nil {
182- t .Logf ("go generate output: %s" , string (output ))
183- t .Fatalf ("Failed to run go generate : %v" , err )
184+ t .Logf ("Command output: %s" , string (output ))
185+ t .Fatalf ("Failed to run command : %v" , err )
184186 }
185187}
186188
187189// ##################################################################################
188190// ################################### E2E TESTS ####################################
189191// ##################################################################################
190192
191- // TestE2E tests the full pipeline: generating replaces from YAML and applying them to go.mod
192- func TestE2E (t * testing.T ) {
193+ // TestE2E_Basic tests the full pipeline: generating replaces from YAML and applying them to go.mod
194+ // This test uses the testdata/basic directory which contains a simple example project.
195+ func TestE2E_Basic (t * testing.T ) {
193196 originalWd , err := os .Getwd ()
194197 if err != nil {
195198 t .Fatalf ("Failed to get current working directory: %v" , err )
196199 }
197200 defer os .Chdir (originalWd )
198201
199- // Test-specific setup: YAML and go.mod content
200- yamlContent := `modules:
201- - name: test-module
202- path: go.mod
203- file_type: mod
204-
205- replaces:
206- - comment: Test replace for example.com/package
207- dependency: example.com/package
208- replacement: example.com/fork v1.0.0
209-
210- - comment: Another test replace
211- dependency: github.com/test/dependency
212- replacement: github.com/test/fork v1.0.0
213- `
214-
215- goModContent := `module test.example.com
202+ // Set up test environment from testdata
203+ env := setupTestEnvFromTestdata (t , "basic" )
216204
217- go 1.21
205+ // Run the generate command
206+ runCommand (t , env )
218207
219- require (
220- example.com/package v0.1.0
221- github.com/test/dependency v1.0.0
222- )
223- `
224-
225- // Set up test environment
226- env := setupTestEnv (t , yamlContent , goModContent )
227-
228- // Run go generate
229- runGoGenerate (t , env )
208+ // Read expected output from testdata
209+ expectedPath := filepath .Join ("testdata" , "basic" , "go.mod.expected" )
210+ expectedContent , err := os .ReadFile (expectedPath )
211+ if err != nil {
212+ t .Fatalf ("Failed to read expected go.mod: %v" , err )
213+ }
214+ expectedGoMod := strings .TrimSpace (string (expectedContent ))
230215
231216 // Verify go.mod was updated
232217 updatedGoModContent , err := os .ReadFile (env .goModPath )
@@ -236,69 +221,34 @@ require (
236221
237222 actualGoMod := strings .TrimSpace (string (updatedGoModContent ))
238223
239- // Define expected go.mod content
240- // Note: go mod tidy removes unused dependencies, so the require block is removed
241- expectedGoMod := `module test.example.com
242-
243- go 1.21
244-
245- // BEGIN GENERATED REPLACES - DO NOT EDIT
246- // Generated by go generate - DO NOT EDIT MANUALLY
247- // Test replace for example.com/package
248- replace example.com/package => example.com/fork v1.0.0
249-
250- // Another test replace
251- replace github.com/test/dependency => github.com/test/fork v1.0.0
252-
253- // END GENERATED REPLACES`
254-
255- expectedGoMod = strings .TrimSpace (expectedGoMod )
256-
257224 if actualGoMod != expectedGoMod {
258225 t .Errorf ("go.mod content mismatch.\n Expected:\n %s\n \n Actual:\n %s" , expectedGoMod , actualGoMod )
259226 }
260227}
261228
262- // TestE2E_UpdateExisting tests updating an existing generated block
229+ // TestE2E_UpdateExisting tests updating an existing generated block.
230+ // This test uses the testdata/update-existing directory which contains a go.mod
231+ // with an existing generated block that should be updated.
263232func TestE2E_UpdateExisting (t * testing.T ) {
264233 originalWd , err := os .Getwd ()
265234 if err != nil {
266235 t .Fatalf ("Failed to get current working directory: %v" , err )
267236 }
268237 defer os .Chdir (originalWd )
269238
270- // Test-specific setup: YAML and go.mod content with existing generated block
271- yamlContent := `modules:
272- - name: test-module
273- path: go.mod
274- file_type: mod
275-
276- replaces:
277- - comment: Updated replace
278- dependency: example.com/package
279- replacement: example.com/fork v1.1.0
280- `
281-
282- goModContent := `module test.example.com
283-
284- go 1.21
285-
286- require (
287- example.com/package v0.1.0
288- )
289-
290- // BEGIN GENERATED REPLACES - DO NOT EDIT
291- // Generated by go generate - DO NOT EDIT MANUALLY
292- // Old comment
293- replace example.com/package => example.com/fork v1.0.0
294- // END GENERATED REPLACES
295- `
239+ // Set up test environment from testdata
240+ env := setupTestEnvFromTestdata (t , "update-existing" )
296241
297- // Set up test environment
298- env := setupTestEnv (t , yamlContent , goModContent )
242+ // Run the generate command
243+ runCommand (t , env )
299244
300- // Run go generate
301- runGoGenerate (t , env )
245+ // Read expected output from testdata
246+ expectedPath := filepath .Join ("testdata" , "update-existing" , "go.mod.expected" )
247+ expectedContent , err := os .ReadFile (expectedPath )
248+ if err != nil {
249+ t .Fatalf ("Failed to read expected go.mod: %v" , err )
250+ }
251+ expectedGoMod := strings .TrimSpace (string (expectedContent ))
302252
303253 // Verify go.mod was updated
304254 updatedGoModContent , err := os .ReadFile (env .goModPath )
@@ -308,22 +258,6 @@ replace example.com/package => example.com/fork v1.0.0
308258
309259 actualGoMod := strings .TrimSpace (string (updatedGoModContent ))
310260
311- // Define expected go.mod content
312- // Note: go mod tidy removes unused dependencies, so the require block is removed
313- // The old replace should be replaced with the new one
314- expectedGoMod := `module test.example.com
315-
316- go 1.21
317-
318- // BEGIN GENERATED REPLACES - DO NOT EDIT
319- // Generated by go generate - DO NOT EDIT MANUALLY
320- // Updated replace
321- replace example.com/package => example.com/fork v1.1.0
322-
323- // END GENERATED REPLACES`
324-
325- expectedGoMod = strings .TrimSpace (expectedGoMod )
326-
327261 if actualGoMod != expectedGoMod {
328262 t .Errorf ("go.mod content mismatch.\n Expected:\n %s\n \n Actual:\n %s" , expectedGoMod , actualGoMod )
329263 }
0 commit comments