77 "strings"
88
99 "github.com/Masterminds/semver/v3"
10+ "golang.org/x/mod/modfile"
1011)
1112
1213// Module describes a Go module upgrade candidate
@@ -31,25 +32,53 @@ type goListModule struct {
3132 } `json:"Update"`
3233}
3334
34- // ListAllModulePaths returns all module paths in the current context
35+ // ListAllModulePaths returns all direct (non-indirect) module paths declared in go.mod
3536func ListAllModulePaths () ([]string , error ) {
36- cmd := exec .Command ("go" , "list" , "-m" , "-f" , "{{.Path}}" , "all" )
37- cmd .Env = append (os .Environ (), "GOWORK=off" )
38- out , err := cmd .Output ()
37+ gomodPath , err := getGoModPath ()
38+ if err != nil {
39+ return nil , err
40+ }
41+
42+ data , err := os .ReadFile (gomodPath )
43+ if err != nil {
44+ return nil , err
45+ }
46+
47+ f , err := modfile .Parse (gomodPath , data , nil )
3948 if err != nil {
4049 return nil , err
4150 }
42- lines := strings .Split (strings .TrimSpace (string (out )), "\n " )
43- var paths []string
44- for _ , l := range lines {
45- l = strings .TrimSpace (l )
46- if l != "" {
47- paths = append (paths , l )
51+
52+ paths := make ([]string , 0 , len (f .Require ))
53+ seen := make (map [string ]struct {})
54+ for _ , req := range f .Require {
55+ if req == nil || req .Mod .Path == "" || req .Indirect {
56+ continue
57+ }
58+ if _ , ok := seen [req .Mod .Path ]; ok {
59+ continue
4860 }
61+ paths = append (paths , req .Mod .Path )
62+ seen [req .Mod .Path ] = struct {}{}
4963 }
64+
5065 return paths , nil
5166}
5267
68+ func getGoModPath () (string , error ) {
69+ cmd := exec .Command ("go" , "env" , "GOMOD" )
70+ cmd .Env = append (os .Environ (), "GOWORK=off" )
71+ out , err := cmd .Output ()
72+ if err != nil {
73+ return "" , err
74+ }
75+ path := strings .TrimSpace (string (out ))
76+ if path == "" || path == os .DevNull {
77+ return "go.mod" , nil
78+ }
79+ return path , nil
80+ }
81+
5382func GetModuleInfo (path string ) (Module , error ) {
5483 cmd := exec .Command ("go" , "list" , "-m" , "-u" , "-json" , path )
5584 cmd .Env = append (os .Environ (), "GOWORK=off" )
0 commit comments