diff options
author | Jay Conrod <jayconrod@google.com> | 2021-04-15 11:36:23 -0400 |
---|---|---|
committer | Jay Conrod <jayconrod@google.com> | 2021-04-16 14:15:49 +0000 |
commit | 0613c748e8919536c360cfc9be4e63a0b55d4286 (patch) | |
tree | d06fd9e8098aedf7d1d031140177d44657f0d945 /src/cmd/go/internal/work/build.go | |
parent | dc76c4756599ac4bd9644e407aa2af9f9c8a3bdc (diff) | |
download | go-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.go | 144 |
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. |