import (
"bytes"
- "cmd/go/internal/base"
- "cmd/go/internal/cache"
- "cmd/go/internal/cfg"
- "cmd/go/internal/load"
- "cmd/go/internal/str"
"encoding/json"
"errors"
"fmt"
"strings"
"sync"
"time"
+
+ "cmd/go/internal/base"
+ "cmd/go/internal/cache"
+ "cmd/go/internal/cfg"
+ "cmd/go/internal/load"
+ "cmd/go/internal/str"
)
// actionList returns the list of actions in the dag rooted at root
return nil
}
+ if err := allowInstall(a); err != nil {
+ return err
+ }
+
// make target directory
dir, _ := filepath.Split(a.Target)
if dir != "" {
return err
}
+ if err := allowInstall(a); err != nil {
+ return err
+ }
+
// make target directory
dir, _ := filepath.Split(a.Target)
if dir != "" {
}
func (b *Builder) installShlibname(a *Action) error {
+ if err := allowInstall(a); err != nil {
+ return err
+ }
+
// TODO: BuildN
a1 := a.Deps[0]
err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666)
}
defer b.flushOutput(a)
+ if err := allowInstall(a); err != nil {
+ return err
+ }
+
if err := b.Mkdir(a.Objdir); err != nil {
return err
}
// advertise it by touching the mtimes (usually the libraries are up
// to date).
if !a.buggyInstall && !b.IsCmdList {
- now := time.Now()
- os.Chtimes(a.Target, now, now)
+ if cfg.BuildN {
+ b.Showcmd("", "touch %s", a.Target)
+ } else if err := allowInstall(a); err == nil {
+ now := time.Now()
+ os.Chtimes(a.Target, now, now)
+ }
}
return nil
}
a.built = a1.built
return nil
}
+ if err := allowInstall(a); err != nil {
+ return err
+ }
if err := b.Mkdir(a.Objdir); err != nil {
return err
return b.moveOrCopyFile(a.Target, a1.built, perm, false)
}
+// allowInstall returns a non-nil error if this invocation of the go command is
+// allowed to install a.Target.
+//
+// (The build of cmd/go running under its own test is forbidden from installing
+// to its original GOROOT.)
+var allowInstall = func(*Action) error { return nil }
+
// cleanup removes a's object dir to keep the amount of
// on-disk garbage down in a large build. On an operating system
// with aggressive buffering, cleaning incrementally like
return nil
}
+ if err := allowInstall(a); err != nil {
+ return err
+ }
+
dir, _ := filepath.Split(a.Target)
if dir != "" {
if err := b.Mkdir(dir); err != nil {
package work
-import "os"
+import (
+ "cmd/go/internal/cfg"
+ "cmd/go/internal/search"
+ "fmt"
+ "os"
+ "path/filepath"
+ "runtime"
+)
func init() {
if v := os.Getenv("TESTGO_VERSION"); v != "" {
runtimeVersion = v
}
+
+ if testGOROOT := os.Getenv("TESTGO_GOROOT"); testGOROOT != "" {
+ // Disallow installs to the GOROOT from which testgo was built.
+ // Installs to other GOROOTs — such as one set explicitly within a test — are ok.
+ allowInstall = func(a *Action) error {
+ if cfg.BuildN {
+ return nil
+ }
+
+ rel := search.InDir(a.Target, testGOROOT)
+ if rel == "" {
+ return nil
+ }
+
+ callerPos := ""
+ if _, file, line, ok := runtime.Caller(1); ok {
+ if shortFile := search.InDir(file, filepath.Join(testGOROOT, "src")); shortFile != "" {
+ file = shortFile
+ }
+ callerPos = fmt.Sprintf("%s:%d: ", file, line)
+ }
+ return fmt.Errorf("%stestgo must not write to GOROOT (installing to %s)", callerPos, filepath.Join("GOROOT", rel))
+ }
+ }
}