Skip to content

Commit

Permalink
do not use go list to find go.mod file (#56)
Browse files Browse the repository at this point in the history
The go list command fails if the go.mod file isn't well formed (like for
example one of the replace directives refers to a non-existent target).
This can be a problem, so find the go.mod file by looking directly for
it instead.
  • Loading branch information
rogpeppe authored Sep 16, 2019
1 parent c30549a commit 0e0a004
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 17 deletions.
37 changes: 22 additions & 15 deletions gomodcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"io"
"io/ioutil"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -56,29 +57,35 @@ func listModules(modules ...string) (mods map[string]*listModule, err error) {
return mods, nil
}

func goModInfo() (*modfile.File, error) {
// Get info on the current module so that we can find the
// path to the current go.mod file.
mods, err := listModules()
// goModInfo returns the main module's root directory
// and the parsed contents of the go.mod file.
func goModInfo() (string, *modfile.File, error) {
goModPath, err := findGoMod(cwd)
if err != nil {
return nil, errors.Wrap(err)
}
if len(mods) != 1 {
return nil, errors.Newf("unexpected module list count (want 1 got %d)", len(mods))
}
var goModPath string
for _, m := range mods {
goModPath = m.GoMod
return "", nil, errors.Notef(err, nil, "cannot find main module")
}
rootDir := filepath.Dir(goModPath)
data, err := ioutil.ReadFile(goModPath)
if err != nil {
return nil, errors.Notef(err, nil, "cannot read current go.mod file")
return "", nil, errors.Notef(err, nil, "cannot read main go.mod file")
}
modf, err := modfile.Parse(goModPath, data, nil)
if err != nil {
return nil, errors.Wrap(err)
return "", nil, errors.Wrap(err)
}
return rootDir, modf, nil
}

func findGoMod(dir string) (string, error) {
out, err := runCmd(dir, "go", "env", "GOMOD")
if err != nil {
return "", err
}
out = strings.TrimSpace(out)
if out == "" {
return "", errors.New("no go.mod file found in any parent directory")
}
return modf, nil
return strings.TrimSpace(out), nil
}

func writeModFile(modf *modfile.File) error {
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func main1() int {
return 2
}

if mf, err := goModInfo(); err == nil {
if _, mf, err := goModInfo(); err == nil {
mainModFile = mf
} else {
return errorf("cannot determine main module: %v", err)
Expand Down
5 changes: 4 additions & 1 deletion script_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ func TestScripts(t *testing.T) {
p := testscript.Params{
Dir: "testdata",
Setup: func(e *testscript.Env) error {
e.Vars = append(e.Vars, "GOPROXY="+proxyURL)
e.Vars = append(e.Vars,
"GOPROXY="+proxyURL,
"GONOSUMDB=*",
)
return nil
},
}
Expand Down
2 changes: 2 additions & 0 deletions testdata/get-no-main-mod.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
! gohack get nothing
stderr 'cannot find main module: no go.mod file found in any parent directory'
29 changes: 29 additions & 0 deletions testdata/undo-not-existent.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
cd repo
go get rsc.io/[email protected]
env GOHACK=$WORK/gohack
gohack get rsc.io/quote
stdout '^rsc.io/quote => .*/gohack/rsc.io/quote$'
! stderr .+

exists $GOHACK/rsc.io/quote
rm $GOHACK/rsc.io/quote

gohack undo
stdout '^dropped rsc\.io/quote$'
! stderr .+

-- repo/main.go --
package main
import (
"fmt"
"rsc.io/quote"
"rsc.io/sampler"
)

func main() {
sampler.DefaultUserPrefs()
fmt.Println(quote.Glass())
}

-- repo/go.mod --
module example.com/repo

0 comments on commit 0e0a004

Please sign in to comment.