@@ -458,6 +458,7 @@ func getBuildRoots(emitDiagnostics bool) (goWorkspaces []GoWorkspace, totalModul
458458 }
459459
460460 goModDirs := util .GetParentDirs (goModPaths )
461+ newGoModDirs := []string {}
461462 straySourceFiles := util .GoFilesOutsideDirs ("." , goModDirs ... )
462463 if len (straySourceFiles ) > 0 {
463464 if emitDiagnostics {
@@ -474,6 +475,27 @@ func getBuildRoots(emitDiagnostics bool) (goWorkspaces []GoWorkspace, totalModul
474475 for _ , component := range components {
475476 path = filepath .Join (path , component )
476477
478+ // If this path is already covered by a new `go.mod` file we will initialise,
479+ // then we don't need a more deeply-nested one. Keeping a separate list of
480+ // `go.mod` files we are initialising in `newGoModDirs` allows us to descend as
481+ // deep as we need to into the directory structure to place new `go.mod` files
482+ // that don't conflict with pre-existing ones, but means we won't descend past
483+ // the ones we are initialising ourselves. E.g. consider the following layout:
484+ //
485+ // - pre-existing/go.mod
486+ // - no-go-mod/main.go
487+ // - no-go-mod/sub-dir/foo.go
488+ //
489+ // Here, we want to initialise a `go.mod` in `no-go-mod/` only. This works fine
490+ // without the `newGoModDirs` check below. However, if we added `no-go-mod/` to
491+ // `goModDirs`, we would recurse all the way into `no-go-mod/sub-dir/` and
492+ // initialise another `go.mod` file there, which we do not want. If we were to
493+ // add an `else` branch to the `goModDirs` check, then we wouldn't be able to
494+ // descend into `no-go-mod/` for the `go.mod` file we want.
495+ if startsWithAnyOf (path , newGoModDirs ) {
496+ break
497+ }
498+
477499 // Try to initialize a `go.mod` file automatically for the stray source files if
478500 // doing so would not place it in a parent directory of an existing `go.mod` file.
479501 if ! startsWithAnyOf (path , goModDirs ) {
@@ -482,7 +504,7 @@ func getBuildRoots(emitDiagnostics bool) (goWorkspaces []GoWorkspace, totalModul
482504 DepMode : GoGetNoModules ,
483505 ModMode : ModUnset ,
484506 })
485- goModDirs = append (goModDirs , path )
507+ newGoModDirs = append (newGoModDirs , path )
486508 break
487509 }
488510 }
0 commit comments