]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: 'go get' no longer builds or installs packages
authorJay Conrod <jayconrod@google.com>
Tue, 14 Sep 2021 23:23:10 +0000 (16:23 -0700)
committerJay Conrod <jayconrod@google.com>
Tue, 28 Sep 2021 17:18:36 +0000 (17:18 +0000)
As part of #40267, 'go install' is now fully responsible for building
and installing executables. 'go get' will only be used to change
versions in go.mod. The -d flag no longer has any effect; its behavior
is the default.

When 'go get' is invoked inside a module on a main package outside of
the main module, it no longer prints any warning. In 1.16-1.17, we
suggested using -d in this situation, but we want
'go get example.com/cmd' to be able to upgrade a tool dependency
without needing -d to suppress the warning.

For #43684

Change-Id: I9daf29c123a5a0e382aa326d62721cb26fc26c19
Reviewed-on: https://go-review.googlesource.com/c/go/+/349997
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>
src/cmd/go/alldocs.go
src/cmd/go/internal/modget/get.go
src/cmd/go/testdata/script/build_trimpath.txt
src/cmd/go/testdata/script/mod_download_svn.txt [moved from src/cmd/go/testdata/script/mod_get_svn.txt with 61% similarity]
src/cmd/go/testdata/script/mod_get_cmd.txt [deleted file]
src/cmd/go/testdata/script/mod_get_commit.txt
src/cmd/go/testdata/script/mod_get_deprecate_install.txt
src/cmd/go/testdata/script/mod_get_errors.txt
src/cmd/go/testdata/script/mod_get_tags.txt
src/cmd/go/testdata/script/mod_outside.txt

index 7be673b290f7525ce0092f9719f62a1063840510..8a2109619d975ec6170f3d56c631486a171bc1e2 100644 (file)
 //
 // Usage:
 //
-//     go get [-d] [-t] [-u] [-v] [build flags] [packages]
+//     go get [-t] [-u] [-v] [build flags] [packages]
 //
 // Get resolves its command-line arguments to packages at specific module versions,
-// updates go.mod to require those versions, downloads source code into the
-// module cache, then builds and installs the named packages.
+// updates go.mod to require those versions, and downloads source code into the
+// module cache.
 //
 // To add a dependency for a package or upgrade it to its latest version:
 //
 //
 // See https://golang.org/ref/mod#go-get for details.
 //
-// The 'go install' command may be used to build and install packages. When a
-// version is specified, 'go install' runs in module-aware mode and ignores
-// the go.mod file in the current directory. For example:
+// In earlier versions of Go, 'go get' was used to build and install packages.
+// Now, 'go get' is dedicated to adjusting dependencies in go.mod. 'go install'
+// may be used to build and install commands instead. When a version is specified,
+// 'go install' runs in module-aware mode and ignores the go.mod file in the
+// current directory. For example:
 //
 //     go install example.com/pkg@v1.2.3
 //     go install example.com/pkg@latest
 // When the -t and -u flags are used together, get will update
 // test dependencies as well.
 //
-// The -d flag instructs get not to build or install packages. get will only
-// update go.mod and download source code needed to build packages.
-//
-// Building and installing packages with get is deprecated. In a future release,
-// the -d flag will be enabled by default, and 'go get' will be only be used to
-// adjust dependencies of the current module. To install a package using
-// dependencies from the current module, use 'go install'. To install a package
-// ignoring the current module, use 'go install' with an @version suffix like
-// "@latest" after each argument.
-//
 // For more about modules, see https://golang.org/ref/mod.
 //
 // For more about specifying packages, see 'go help packages'.
index 20734bdd2369c1883a1ecf72facf361178d94a7a..674ee1c2670da73975303cba228aca632a0bcace 100644 (file)
@@ -37,7 +37,6 @@ import (
 
        "cmd/go/internal/base"
        "cmd/go/internal/imports"
-       "cmd/go/internal/load"
        "cmd/go/internal/modfetch"
        "cmd/go/internal/modload"
        "cmd/go/internal/par"
@@ -50,14 +49,14 @@ import (
 )
 
 var CmdGet = &base.Command{
-       // Note: -d -u are listed explicitly because they are the most common get flags.
+       // Note: flags below are listed explicitly because they're the most common.
        // Do not send CLs removing them because they're covered by [get flags].
-       UsageLine: "go get [-d] [-t] [-u] [-v] [build flags] [packages]",
+       UsageLine: "go get [-t] [-u] [-v] [build flags] [packages]",
        Short:     "add dependencies to current module and install them",
        Long: `
 Get resolves its command-line arguments to packages at specific module versions,
-updates go.mod to require those versions, downloads source code into the
-module cache, then builds and installs the named packages.
+updates go.mod to require those versions, and downloads source code into the
+module cache.
 
 To add a dependency for a package or upgrade it to its latest version:
 
@@ -73,9 +72,11 @@ To remove a dependency on a module and downgrade modules that require it:
 
 See https://golang.org/ref/mod#go-get for details.
 
-The 'go install' command may be used to build and install packages. When a
-version is specified, 'go install' runs in module-aware mode and ignores
-the go.mod file in the current directory. For example:
+In earlier versions of Go, 'go get' was used to build and install packages.
+Now, 'go get' is dedicated to adjusting dependencies in go.mod. 'go install'
+may be used to build and install commands instead. When a version is specified,
+'go install' runs in module-aware mode and ignores the go.mod file in the
+current directory. For example:
 
        go install example.com/pkg@v1.2.3
        go install example.com/pkg@latest
@@ -98,16 +99,6 @@ but changes the default to select patch releases.
 When the -t and -u flags are used together, get will update
 test dependencies as well.
 
-The -d flag instructs get not to build or install packages. get will only
-update go.mod and download source code needed to build packages.
-
-Building and installing packages with get is deprecated. In a future release,
-the -d flag will be enabled by default, and 'go get' will be only be used to
-adjust dependencies of the current module. To install a package using
-dependencies from the current module, use 'go install'. To install a package
-ignoring the current module, use 'go install' with an @version suffix like
-"@latest" after each argument.
-
 For more about modules, see https://golang.org/ref/mod.
 
 For more about specifying packages, see 'go help packages'.
@@ -218,7 +209,7 @@ variable for future go command invocations.
 }
 
 var (
-       getD        = CmdGet.Flag.Bool("d", false, "")
+       getD        = CmdGet.Flag.Bool("d", true, "")
        getF        = CmdGet.Flag.Bool("f", false, "")
        getFix      = CmdGet.Flag.Bool("fix", false, "")
        getM        = CmdGet.Flag.Bool("m", false, "")
@@ -265,6 +256,10 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
        default:
                base.Fatalf("go: unknown upgrade flag -u=%s", getU.rawVersion)
        }
+       // TODO(#43684): in the future (Go 1.20), warn that -d is a no-op.
+       if !*getD {
+               base.Fatalf("go: -d flag may not be disabled")
+       }
        if *getF {
                fmt.Fprintf(os.Stderr, "go: -f flag is a no-op when using modules\n")
        }
@@ -272,7 +267,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
                fmt.Fprintf(os.Stderr, "go: -fix flag is a no-op when using modules\n")
        }
        if *getM {
-               base.Fatalf("go: -m flag is no longer supported; consider -d to skip building packages")
+               base.Fatalf("go: -m flag is no longer supported")
        }
        if *getInsecure {
                base.Fatalf("go: -insecure flag is no longer supported; use GOINSECURE instead")
@@ -356,66 +351,6 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
        }
        r.checkPackageProblems(ctx, pkgPatterns)
 
-       // We've already downloaded modules (and identified direct and indirect
-       // dependencies) by loading packages in findAndUpgradeImports.
-       // So if -d is set, we're done after the module work.
-       //
-       // Otherwise, we need to build and install the packages matched by
-       // command line arguments.
-       // Note that 'go get -u' without arguments is equivalent to
-       // 'go get -u .', so we'll typically build the package in the current
-       // directory.
-       if !*getD && len(pkgPatterns) > 0 {
-               work.BuildInit()
-
-               pkgOpts := load.PackageOpts{ModResolveTests: *getT}
-               var pkgs []*load.Package
-               for _, pkg := range load.PackagesAndErrors(ctx, pkgOpts, pkgPatterns) {
-                       if pkg.Error != nil {
-                               var noGo *load.NoGoError
-                               if errors.As(pkg.Error.Err, &noGo) {
-                                       if m := modload.PackageModule(pkg.ImportPath); m.Path == pkg.ImportPath {
-                                               // pkg is at the root of a module, and doesn't exist with the current
-                                               // build tags. Probably the user just wanted to change the version of
-                                               // that module — not also build the package — so suppress the error.
-                                               // (See https://golang.org/issue/33526.)
-                                               continue
-                                       }
-                               }
-                       }
-                       pkgs = append(pkgs, pkg)
-               }
-               load.CheckPackageErrors(pkgs)
-
-               haveExternalExe := false
-               for _, pkg := range pkgs {
-                       if pkg.Name == "main" && pkg.Module != nil {
-                               if !modload.MainModules.Contains(pkg.Module.Path) {
-                                       haveExternalExe = true
-                                       break
-                               }
-                       }
-               }
-               if haveExternalExe {
-                       fmt.Fprint(os.Stderr, "go: installing executables with 'go get' in module mode is deprecated.")
-                       var altMsg string
-                       if modload.HasModRoot() {
-                               altMsg = `
-       To adjust and download dependencies of the current module, use 'go get -d'.
-       To install using requirements of the current module, use 'go install'.
-       To install ignoring the current module, use 'go install' with a version,
-       like 'go install example.com/cmd@latest'.
-`
-                       } else {
-                               altMsg = "\n\tUse 'go install pkg@version' instead.\n"
-                       }
-                       fmt.Fprint(os.Stderr, altMsg)
-                       fmt.Fprintf(os.Stderr, "\tFor more information, see https://golang.org/doc/go-get-install-deprecation\n\tor run 'go help get' or 'go help install'.\n")
-               }
-
-               work.InstallPackages(ctx, pkgPatterns, pkgs)
-       }
-
        if !modload.HasModRoot() {
                return
        }
index 2c3bee8fdc7a925bb9bd9bdcee078a36b0ed9581..f36b1237dc09413f8cf95fea76a278ed48b187f6 100644 (file)
@@ -32,7 +32,8 @@ stdout 'binary contains GOROOT: false'
 
 # A binary from an external module built with -trimpath should not contain
 # the current workspace or GOROOT.
-go get -trimpath rsc.io/fortune
+go get rsc.io/fortune
+go install -trimpath rsc.io/fortune
 exec $WORK/paths-a.exe $GOPATH/bin/fortune$GOEXE
 stdout 'binary contains module root: false'
 stdout 'binary contains GOROOT: false'
similarity index 61%
rename from src/cmd/go/testdata/script/mod_get_svn.txt
rename to src/cmd/go/testdata/script/mod_download_svn.txt
index 4d6b94ae5b04a870c61b006b4d3327b6764b979e..79e00dc9706c9fd80ba7f7a37eec2e076678817b 100644 (file)
@@ -1,7 +1,7 @@
 [!net] skip
 [!exec:svn] skip
 
-# 'go get' will fall back to svn+ssh once svn fails over protocols like https.
+# 'go mod download' will fall back to svn+ssh once svn fails over protocols like https.
 # If vcs-test.golang.org isn't in the user's known_hosts file, this will result
 # in an ssh prompt, which will stop 'go test' entirely
 #
@@ -19,18 +19,11 @@ env GOPROXY=direct
 env GOSUMDB=off
 
 # Attempting to get a module zip using svn should succeed.
-go get vcs-test.golang.org/svn/hello.svn@000000000001
+go mod download vcs-test.golang.org/svn/hello.svn@000000000001
 exists $GOPATH/pkg/mod/cache/download/vcs-test.golang.org/svn/hello.svn/@v/v0.0.0-20170922011245-000000000001.zip
-exists $GOPATH/bin/hello.svn$GOEXE
 
 # Attempting to get a nonexistent module using svn should fail with a
 # reasonable message instead of a panic.
-! go get -d vcs-test.golang.org/svn/nonexistent.svn
+! go mod download vcs-test.golang.org/svn/nonexistent.svn@latest
 ! stderr panic
-stderr 'go: vcs-test.golang.org/svn/nonexistent.svn: no matching versions for query "upgrade"'
-
--- go.mod --
-module golang/go/issues/28943/main
--- go.sum --
-vcs-test.golang.org/svn/hello.svn v0.0.0-20170922011245-000000000001 h1:rZjvboXMfQICKXdhx/QHqJ2Y/AQsJVrXnwGqwcTxQiw=
-vcs-test.golang.org/svn/hello.svn v0.0.0-20170922011245-000000000001/go.mod h1:0memnh/BRLuxiK2zF4rvUgz6ts/fhhB28l3ULFWPusc=
+stderr 'go: module vcs-test.golang.org/svn/nonexistent.svn: no matching versions for query "latest"$'
diff --git a/src/cmd/go/testdata/script/mod_get_cmd.txt b/src/cmd/go/testdata/script/mod_get_cmd.txt
deleted file mode 100644 (file)
index d31cee1..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-env GO111MODULE=on
-[short] skip
-
-# Test that when 'go get' is run from $GOBIN, it does not delete binaries
-# after it installs them. Verifies golang.org/issue/32766.
-
-go get example.com/tools/cmd/hello
-
-# 'go get' should not delete the command when run from $GOPATH/bin
-cd $GOPATH/bin
-exists hello$GOEXE
-go get example.com/tools/cmd/hello
-exists hello$GOEXE
-
-# 'go get' should not delete the command when run from a different $GOBIN
-mkdir $WORK/bin
-cd $WORK/bin
-env GOBIN=$WORK/bin
-go get example.com/tools/cmd/hello
-exists hello$GOEXE
index 0cf94ae1821e6602d77a6ea87ddc9c3416cafa1c..ff7185f59a187370db1def687aad0b4d15ad306d 100644 (file)
@@ -16,7 +16,7 @@ go get -d golang.org/x/text@14c0d48
 
 env GOCACHE=$WORK/gocache  # Looking for compile commands, so need a clean cache.
 
-go get -x golang.org/x/text/language@14c0d48
+go build -x golang.org/x/text/language
 stderr 'compile|cp|gccgo .*language\.a$'
 
 # BUG: after the build, the package should not be stale, as 'go install' would
@@ -24,12 +24,13 @@ stderr 'compile|cp|gccgo .*language\.a$'
 go list -f '{{.Stale}}' golang.org/x/text/language
 stdout ^true
 
-# install after get should not run the compiler again.
+# install after build should not run the compiler again.
 go install -x golang.org/x/text/language
 ! stderr 'compile|cp|gccgo .*language\.a$'
 
-# even with -d, we should see an error for unknown packages.
-! go get -d -x golang.org/x/text/foo@14c0d48
+# we should see an error for unknown packages.
+! go get -x golang.org/x/text/foo@14c0d48
+stderr '^go: module golang.org/x/text@14c0d48 found \(v0.3.0\), but does not contain package golang.org/x/text/foo$'
 
 # get pseudo-version should record that version
 go get -d rsc.io/quote@v0.0.0-20180214005840-23179ee8a569
index e8142afee9283d58404d08706941ad6007238b45..ab1d6a43f7432346a930dcda52f460b33996a64f 100644 (file)
@@ -2,10 +2,7 @@
 
 env GO111MODULE=on
 
-# 'go get' outside a module with an executable prints a deprecation message.
-go get example.com/cmd/a
-stderr '^go: installing executables with ''go get'' in module mode is deprecated.$'
-stderr 'Use ''go install pkg@version'' instead.'
+# TODO(#43684): test message outside module.
 
 cp go.mod.orig go.mod
 
@@ -13,13 +10,16 @@ cp go.mod.orig go.mod
 # This will stop building in the future, but it's the command we want to use.
 go get rsc.io/quote
 ! stderr deprecated
+! stderr 'no longer installs'
 cp go.mod.orig go.mod
 
-# 'go get' inside a module with an executable prints a different
-# deprecation message.
+# 'go get' inside a module with an executable does not print a message.
+# In 1.16 and 1.17, 'go get' did print a message in this case suggesting the
+# use of -d. In 1.18, -d is a no-op, and we'd like to begin discouraging
+# its use.
 go get example.com/cmd/a
-stderr '^go: installing executables with ''go get'' in module mode is deprecated.$'
-stderr 'To adjust and download dependencies of the current module, use ''go get -d'''
+! stderr deprecated
+! stderr 'no longer installs'
 cp go.mod.orig go.mod
 
 # 'go get' should not print a warning for a main package inside the main module.
index 5c37058d1c1b9508e8a77ce8fb3de85eabf34eaf..7cb03ce2f1e6b5b4f5b5efd63110653c0a172740 100644 (file)
@@ -1,35 +1,23 @@
 cp go.mod go.mod.orig
 
 
-# Both 'go get' and 'go get -d' should fail, without updating go.mod,
-# if the transitive dependencies of the requested package (by default,
-# the package in the current directory) cannot be resolved.
+# 'go get' should fail, without updating go.mod, if the transitive dependencies
+# of the requested package (by default, the package in the current directory)
+# cannot be resolved.
 
 ! go get
 stderr '^example.com/m imports\n\texample.com/badimport imports\n\texample.net/oops: cannot find module providing package example.net/oops$'
 cmp go.mod.orig go.mod
 
-! go get -d
-stderr '^example.com/m imports\n\texample.com/badimport imports\n\texample.net/oops: cannot find module providing package example.net/oops$'
-cmp go.mod.orig go.mod
-
 cd importsyntax
 
 
-# If 'go get' fails due to a compile error (such as a syntax error),
-# it should not update the go.mod file.
-
-! go get
-stderr '^..[/\\]badimport[/\\]syntaxerror[/\\]syntaxerror.go:1:1: expected ''package'', found pack$'  # TODO: An import stack would be nice.
-cmp ../go.mod.orig ../go.mod
-
-
 # A syntax error in a dependency prevents the compiler from needing that
-# dependency's imports, so 'go get -d' should not report an error when those
+# dependency's imports, so 'go get' should not report an error when those
 # imports cannot be resolved: it has all of the dependencies that the compiler
 # needs, and the user did not request to run the compiler.
 
-go get -d
+go get
 cmp ../go.mod.syntax-d ../go.mod
 
 
index e9869e3f0230b3ab6f6bdbb1f756071a2c624a1c..e4fb6c4326b46f52a14b4d8316896a9e18e0d5ce 100644 (file)
@@ -1,25 +1,14 @@
 env GO111MODULE=on
 
-[short] skip
-
 # get should add modules needed to build packages, even if those
 # dependencies are in sources excluded by build tags.
 # All build tags are considered true except "ignore".
 go mod init m
-go get -d .
+go get .
 go list -m all
 stdout 'example.com/version v1.1.0'
 stdout 'rsc.io/quote v1.5.2'
 
-[short] skip
-
-# Packages that are only imported in excluded files should not be built.
-env GOCACHE=$WORK/gocache  # Looking for compile commands, so need a clean cache.
-go get -n -x .
-stderr 'compile.* -p m '
-! stderr 'compile.* -p example.com/version '
-! stderr 'compile.* -p rsc.io/quote '
-
 -- empty.go --
 package m
 
index 6da6314b79990e295711b6afa243ab23232ba9cb..e5318ee13deb4050150e66b52bbcc090fdac14e5 100644 (file)
@@ -223,30 +223,6 @@ go fmt needmod/needmod.go
 
 # The remainder of the test checks dependencies by linking and running binaries.
 
-# 'go get' of a binary without a go.mod should install the requested version,
-# resolving outside dependencies to the latest available versions.
-go get example.com/printversion@v0.1.0
-exec ../bin/printversion
-stdout 'path is example.com/printversion'
-stdout 'main is example.com/printversion v0.1.0'
-stdout 'using example.com/version v1.1.0'
-
-# 'go get' of a versioned binary should build and install the latest version
-# using its minimal required modules, ignoring replacements and exclusions.
-go get example.com/printversion
-exec ../bin/printversion
-stdout 'path is example.com/printversion'
-stdout 'main is example.com/printversion v1.0.0'
-stdout 'using example.com/version v1.0.0'
-
-# 'go get -u=patch' should patch dependencies before installing,
-# again ignoring replacements and exclusions.
-go get -u=patch example.com/printversion@v1.0.0
-exec ../bin/printversion
-stdout 'path is example.com/printversion'
-stdout 'main is example.com/printversion v1.0.0'
-stdout 'using example.com/version v1.0.1'
-
 # 'go run' should work with file arguments if they don't import anything
 # outside std.
 go run ./stdonly/stdonly.go