diff --git a/utils.go b/utils.go index 62d23ce..1aafd27 100644 --- a/utils.go +++ b/utils.go @@ -2,57 +2,29 @@ package musttag import ( "encoding/json" - "errors" "fmt" - "io" - "os" "os/exec" "strings" ) -var ( - getwd = os.Getwd - commandOutput = func(name string, args ...string) (string, error) { - output, err := exec.Command(name, args...).Output() - return string(output), err - } -) - func getMainModule() (string, error) { - args := []string{"go", "list", "-m", "-json"} + args := [...]string{"go", "mod", "edit", "-json"} - output, err := commandOutput(args[0], args[1:]...) + out, err := exec.Command(args[0], args[1:]...).Output() if err != nil { - return "", fmt.Errorf("running `%s`: %w", strings.Join(args, " "), err) + return "", fmt.Errorf("running %q: %w", strings.Join(args[:], " "), err) } - cwd, err := getwd() - if err != nil { - return "", fmt.Errorf("getting wd: %w", err) + var info struct { + Module struct { + Path string `json:"Path"` + } `json:"Module"` } - - decoder := json.NewDecoder(strings.NewReader(output)) - - for { - // multiple JSON objects will be returned when using Go workspaces; see #63 for details. - var module struct { - Path string `json:"Path"` - Main bool `json:"Main"` - Dir string `json:"Dir"` - GoMod string `json:"GoMod"` - GoVersion string `json:"GoVersion"` - } - if err := decoder.Decode(&module); err != nil { - if errors.Is(err, io.EOF) { - return "", fmt.Errorf("main module not found\n%s", output) - } - return "", fmt.Errorf("decoding json: %w\n%s", err, output) - } - - if module.Main && strings.HasPrefix(cwd, module.Dir) { - return module.Path, nil - } + if err := json.Unmarshal(out, &info); err != nil { + return "", fmt.Errorf("decoding module info: %w\n%s", err, out) } + + return info.Module.Path, nil } // based on golang.org/x/tools/imports.VendorlessPath diff --git a/utils_test.go b/utils_test.go index 1e59151..b7824e9 100644 --- a/utils_test.go +++ b/utils_test.go @@ -7,42 +7,6 @@ import ( . "go-simpler.org/assert/EF" ) -func Test_getMainModule(t *testing.T) { - tests := map[string]struct { - want, output string - }{ - "single module": { - want: "module1", - output: ` -{"Path": "module1", "Main": true, "Dir": "/path/to/module1"}`, - }, - "multiple modules": { - want: "module1", - output: ` -{"Path": "module1", "Main": true, "Dir": "/path/to/module1"} -{"Path": "module2", "Main": true, "Dir": "/path/to/module2"}`, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - gwd, co := getwd, commandOutput - defer func() { getwd, commandOutput = gwd, co }() - - getwd = func() (string, error) { - return "/path/to/module1/pkg", nil - } - commandOutput = func(string, ...string) (string, error) { - return test.output, nil - } - - got, err := getMainModule() - assert.NoErr[F](t, err) - assert.Equal[E](t, got, test.want) - }) - } -} - func Test_cutVendor(t *testing.T) { tests := []struct { path, want string