@@ -3,12 +3,14 @@ package project
33import (
44 "log"
55 "os"
6+ "os/exec"
67 "path/filepath"
78 "regexp"
89 "sort"
910 "strings"
1011
1112 "github.com/github/codeql-go/extractor/diagnostics"
13+ "github.com/github/codeql-go/extractor/toolchain"
1214 "github.com/github/codeql-go/extractor/util"
1315 "golang.org/x/mod/modfile"
1416 "golang.org/x/mod/semver"
@@ -52,6 +54,31 @@ func checkDirsNested(inputDirs []string) (string, bool) {
5254 return dirs [0 ], true
5355}
5456
57+ // Try to initialize a go.mod file for projects that do not already have one.
58+ func initGoModForLegacyProject (path string ) {
59+ log .Printf ("Project appears to be a legacy Go project, attempting to initialize go.mod" )
60+
61+ modInit := exec .Command ("go" , "mod" , "init" , "codeql/auto-project" )
62+ modInit .Dir = path
63+
64+ if ! util .RunCmd (modInit ) {
65+ log .Printf ("Failed to initialize go.mod file for this project." )
66+ return
67+ }
68+
69+ modTidy := toolchain .TidyModule (path )
70+ out , err := modTidy .CombinedOutput ()
71+ log .Println (string (out ))
72+
73+ if err != nil {
74+ log .Printf ("Failed to determine module requirements for this project." )
75+
76+ if strings .Contains (string (out ), "is relative, but relative import paths are not supported in module mode" ) {
77+ diagnostics .EmitRelativeImportPaths ()
78+ }
79+ }
80+ }
81+
5582// Find all go.work files in the working directory and its subdirectories
5683func findGoWorkFiles () []string {
5784 return util .FindAllFilesWithName ("." , "go.work" , "vendor" )
@@ -195,11 +222,13 @@ func getBuildRoot(emitDiagnostics bool) (baseDirs []string, useGoMod bool) {
195222 totalModuleFiles += len (goWorkspace .Modules )
196223 }
197224
198- // If there are no `go.mod` files at all, try to build the project without Go modules.
225+ // If there are no `go.mod` files at all, create one in line with https://go.dev/blog/migrating-to-go-modules
199226 if totalModuleFiles == 0 {
200- log .Println ("Found no go.mod files, not using Go modules." )
227+ // If we have no `go.mod` files, then the project appears to be a legacy project without
228+ // a `go.mod` file. Try to initialize one automatically.
229+ initGoModForLegacyProject ("." )
201230 baseDirs = []string {"." }
202- useGoMod = false
231+ useGoMod = true
203232 return
204233 }
205234
0 commit comments