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