aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/work/build.go
diff options
context:
space:
mode:
authorJay Conrod <jayconrod@google.com>2021-04-15 11:36:23 -0400
committerJay Conrod <jayconrod@google.com>2021-04-16 14:15:49 +0000
commit0613c748e8919536c360cfc9be4e63a0b55d4286 (patch)
treed06fd9e8098aedf7d1d031140177d44657f0d945 /src/cmd/go/internal/work/build.go
parentdc76c4756599ac4bd9644e407aa2af9f9c8a3bdc (diff)
downloadgo-0613c748e8919536c360cfc9be4e63a0b55d4286.tar.gz
go-0613c748e8919536c360cfc9be4e63a0b55d4286.zip
cmd/go: move 'go install cmd@version' code into internal/load
'go run cmd@version' will use the same code. This changes error messages a bit. For #42088 Change-Id: Iaed3997a3d27f9fc0e868013ab765f1fb638a0b5 Reviewed-on: https://go-review.googlesource.com/c/go/+/310410 Trust: Jay Conrod <jayconrod@google.com> Run-TryBot: Jay Conrod <jayconrod@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src/cmd/go/internal/work/build.go')
-rw-r--r--src/cmd/go/internal/work/build.go144
1 files changed, 10 insertions, 134 deletions
diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go
index dcb9e3785c..a75ace7d4e 100644
--- a/src/cmd/go/internal/work/build.go
+++ b/src/cmd/go/internal/work/build.go
@@ -10,9 +10,7 @@ import (
"fmt"
"go/build"
exec "internal/execabs"
- "internal/goroot"
"os"
- "path"
"path/filepath"
"runtime"
"strings"
@@ -21,13 +19,9 @@ import (
"cmd/go/internal/cfg"
"cmd/go/internal/fsys"
"cmd/go/internal/load"
- "cmd/go/internal/modfetch"
"cmd/go/internal/modload"
"cmd/go/internal/search"
"cmd/go/internal/trace"
-
- "golang.org/x/mod/modfile"
- "golang.org/x/mod/module"
)
var CmdBuild = &base.Command{
@@ -762,145 +756,27 @@ func installOutsideModule(ctx context.Context, args []string) {
modload.RootMode = modload.NoRoot
modload.AllowMissingModuleImports()
modload.Init()
-
- // Check that the arguments satisfy syntactic constraints.
- var version string
- for _, arg := range args {
- if i := strings.Index(arg, "@"); i >= 0 {
- version = arg[i+1:]
- if version == "" {
- base.Fatalf("go install %s: version must not be empty", arg)
- }
- break
- }
- }
- patterns := make([]string, len(args))
- for i, arg := range args {
- if !strings.HasSuffix(arg, "@"+version) {
- base.Errorf("go install %s: all arguments must have the same version (@%s)", arg, version)
- continue
- }
- p := arg[:len(arg)-len(version)-1]
- switch {
- case build.IsLocalImport(p):
- base.Errorf("go install %s: argument must be a package path, not a relative path", arg)
- case filepath.IsAbs(p):
- base.Errorf("go install %s: argument must be a package path, not an absolute path", arg)
- case search.IsMetaPackage(p):
- base.Errorf("go install %s: argument must be a package path, not a meta-package", arg)
- case path.Clean(p) != p:
- base.Errorf("go install %s: argument must be a clean package path", arg)
- case !strings.Contains(p, "...") && search.IsStandardImportPath(p) && goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, p):
- base.Errorf("go install %s: argument must not be a package in the standard library", arg)
- default:
- patterns[i] = p
- }
- }
- base.ExitIfErrors()
BuildInit()
- // Query the module providing the first argument, load its go.mod file, and
- // check that it doesn't contain directives that would cause it to be
- // interpreted differently if it were the main module.
- //
- // If multiple modules match the first argument, accept the longest match
- // (first result). It's possible this module won't provide packages named by
- // later arguments, and other modules would. Let's not try to be too
- // magical though.
- allowed := modload.CheckAllowed
- if modload.IsRevisionQuery(version) {
- // Don't check for retractions if a specific revision is requested.
- allowed = nil
- }
- noneSelected := func(path string) (version string) { return "none" }
- qrs, err := modload.QueryPackages(ctx, patterns[0], version, noneSelected, allowed)
- if err != nil {
- base.Fatalf("go install %s: %v", args[0], err)
- }
- installMod := qrs[0].Mod
- data, err := modfetch.GoMod(installMod.Path, installMod.Version)
- if err != nil {
- base.Fatalf("go install %s: %v", args[0], err)
- }
- f, err := modfile.Parse("go.mod", data, nil)
- if err != nil {
- base.Fatalf("go install %s: %s: %v", args[0], installMod, err)
- }
- directiveFmt := "go install %s: %s\n" +
- "\tThe go.mod file for the module providing named packages contains one or\n" +
- "\tmore %s directives. It must not contain directives that would cause\n" +
- "\tit to be interpreted differently than if it were the main module."
- if len(f.Replace) > 0 {
- base.Fatalf(directiveFmt, args[0], installMod, "replace")
- }
- if len(f.Exclude) > 0 {
- base.Fatalf(directiveFmt, args[0], installMod, "exclude")
- }
-
- // Since we are in NoRoot mode, the build list initially contains only
- // the dummy command-line-arguments module. Add a requirement on the
- // module that provides the packages named on the command line.
- if _, err := modload.EditBuildList(ctx, nil, []module.Version{installMod}); err != nil {
- base.Fatalf("go install %s: %v", args[0], err)
- }
-
- // Load packages for all arguments. Ignore non-main packages.
+ // Load packages. Ignore non-main packages.
// Print a warning if an argument contains "..." and matches no main packages.
// PackagesAndErrors already prints warnings for patterns that don't match any
// packages, so be careful not to double print.
- matchers := make([]func(string) bool, len(patterns))
- for i, p := range patterns {
- if strings.Contains(p, "...") {
- matchers[i] = search.MatchPattern(p)
- }
- }
-
// TODO(golang.org/issue/40276): don't report errors loading non-main packages
// matched by a pattern.
- pkgs := load.PackagesAndErrors(ctx, load.PackageOpts{}, patterns)
- load.CheckPackageErrors(pkgs)
- mainPkgs := make([]*load.Package, 0, len(pkgs))
- mainCount := make([]int, len(patterns))
- nonMainCount := make([]int, len(patterns))
- for _, pkg := range pkgs {
- if pkg.Name == "main" {
- mainPkgs = append(mainPkgs, pkg)
- for i := range patterns {
- if matchers[i] != nil && matchers[i](pkg.ImportPath) {
- mainCount[i]++
- }
- }
- } else {
- for i := range patterns {
- if matchers[i] == nil && patterns[i] == pkg.ImportPath {
- base.Errorf("go install: package %s is not a main package", pkg.ImportPath)
- } else if matchers[i] != nil && matchers[i](pkg.ImportPath) {
- nonMainCount[i]++
- }
- }
- }
- }
- base.ExitIfErrors()
- for i, p := range patterns {
- if matchers[i] != nil && mainCount[i] == 0 && nonMainCount[i] > 0 {
- fmt.Fprintf(os.Stderr, "go: warning: %q matched no main packages\n", p)
- }
+ pkgOpts := load.PackageOpts{MainOnly: true}
+ pkgs, err := load.PackagesAndErrorsOutsideModule(ctx, pkgOpts, args)
+ if err != nil {
+ base.Fatalf("go install: %v", err)
}
-
- // Check that named packages are all provided by the same module.
- for _, pkg := range mainPkgs {
- if pkg.Module == nil {
- // Packages in std, cmd, and their vendored dependencies
- // don't have this field set.
- base.Errorf("go install: package %s not provided by module %s", pkg.ImportPath, installMod)
- } else if pkg.Module.Path != installMod.Path || pkg.Module.Version != installMod.Version {
- base.Errorf("go install: package %s provided by module %s@%s\n\tAll packages must be provided by the same module (%s).", pkg.ImportPath, pkg.Module.Path, pkg.Module.Version, installMod)
- }
+ load.CheckPackageErrors(pkgs)
+ patterns := make([]string, len(args))
+ for i, arg := range args {
+ patterns[i] = arg[:strings.Index(arg, "@")]
}
- base.ExitIfErrors()
// Build and install the packages.
- InstallPackages(ctx, patterns, mainPkgs)
+ InstallPackages(ctx, patterns, pkgs)
}
// ExecCmd is the command to use to run user binaries.