From 05684c3dc12bb5c5c89541758b2d7471fdcf46f2 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sun, 22 Apr 2018 20:16:51 -0700 Subject: [PATCH] make.go: validate that make.go is run in GOPATH It used to be a feature of make.go that it could run from anywhere and users could ignore GOPATH. We would still like that, but the shenanigans we did before to mirror the perkeep source tree to a temp directory and set GOPATH to that temp directory were annoying. And fortunately GOPATH is slowly dying, so we won't need to deal with this forever. As of Go 1.8, there is always now a default GOPATH (https://golang.org/doc/go1.8#gopath), so at least people don't need to set environment variables. And in Go 1.12-ish, we'll probably ditch GOPATH entirely. So, for now require that users build in their GOPATH, which might be the implicit GOPATH if they haven't set one. This only affects developers. Regular users can use release binaries. Change-Id: Ib4e3f05fa987baeaba5aa51349887e6c243f0092 --- make.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/make.go b/make.go index 42b5a8abc..2b84ee64e 100644 --- a/make.go +++ b/make.go @@ -696,6 +696,7 @@ func verifyPerkeepRoot() { if _, err := os.Stat(testFile); err != nil { log.Fatalf("make.go must be run from the Perkeep src root directory (where make.go is). Current working directory is %s", pkRoot) } + validateDirInGOPATH(pkRoot) cmd := exec.Command("go", "list", "-f", "{{.Target}}", "perkeep.org/cmd/pk") cmd.Stderr = os.Stderr @@ -706,6 +707,43 @@ func verifyPerkeepRoot() { binDir = filepath.Dir(strings.TrimSpace(string(out))) } +func validateDirInGOPATH(dir string) { + fi, err := os.Lstat(dir) + if err != nil { + log.Fatal(err) + } + + gopathEnv, err := exec.Command("go", "env", "GOPATH").Output() + if err != nil { + log.Fatalf("error finding GOPATH: %v", err) + } + gopaths := filepath.SplitList(strings.TrimSpace(string(gopathEnv))) + if len(gopaths) == 0 { + log.Fatalf("failed to find your GOPATH: go env GOPATH returned nothing") + } + var validOpts []string + for _, gopath := range gopaths { + validDir := filepath.Join(gopath, "src", "perkeep.org") + validOpts = append(validOpts, validDir) + fi2, err := os.Lstat(validDir) + if os.IsNotExist(err) { + continue + } + if err != nil { + log.Fatal(err) + } + if os.SameFile(fi, fi2) { + // In a valid directory. + return + } + } + if len(validOpts) == 1 { + log.Fatalf("make.go cannot be run from %s; it must be in a valid GOPATH. Move the directory containing make.go to %s", dir, validOpts[0]) + } else { + log.Fatalf("make.go cannot be run from %s; it must be in a valid GOPATH. Move the directory containing make.go to one of %q", dir, validOpts) + } +} + const ( goVersionMinor = 10 gopherJSGoMinor = 10