mirror of
https://github.com/golang/go
synced 2024-11-26 17:36:56 -07:00
cmd/go: add a '-e' flag to 'mod tidy' and 'mod vendor'
This flag, like the -e flag to 'go list', instructs the command to make a best effort to continue in spite of errors for specific packages. Fixes #26603 Change-Id: I5ee2f50c71870ae8ef3f9b3e5b045474adcca525 Reviewed-on: https://go-review.googlesource.com/c/go/+/255960 Trust: Bryan C. Mills <bcmills@google.com> Trust: Jay Conrod <jayconrod@google.com> Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Matloob <matloob@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
This commit is contained in:
parent
4e1d812afc
commit
3aa09489ab
@ -66,6 +66,13 @@ Do not send CLs removing the interior tags from such phrases.
|
|||||||
TODO: write and link to tutorial or blog post
|
TODO: write and link to tutorial or blog post
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p><!-- golang.org/issue/26603 -->
|
||||||
|
The <code>go</code> <code>mod</code> <code>vendor</code>
|
||||||
|
and <code>go</code> <code>mod</code> <code>tidy</code> subcommands now accept
|
||||||
|
the <code>-e</code> flag, which instructs them to proceed despite errors in
|
||||||
|
resolving missing packages.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h4 id="go-test"><code>go</code> <code>test</code></h4>
|
<h4 id="go-test"><code>go</code> <code>test</code></h4>
|
||||||
|
|
||||||
<p><!-- golang.org/issue/29062 -->
|
<p><!-- golang.org/issue/29062 -->
|
||||||
|
@ -1231,7 +1231,7 @@
|
|||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
//
|
//
|
||||||
// go mod tidy [-v]
|
// go mod tidy [-e] [-v]
|
||||||
//
|
//
|
||||||
// Tidy makes sure go.mod matches the source code in the module.
|
// Tidy makes sure go.mod matches the source code in the module.
|
||||||
// It adds any missing modules necessary to build the current module's
|
// It adds any missing modules necessary to build the current module's
|
||||||
@ -1242,12 +1242,15 @@
|
|||||||
// The -v flag causes tidy to print information about removed modules
|
// The -v flag causes tidy to print information about removed modules
|
||||||
// to standard error.
|
// to standard error.
|
||||||
//
|
//
|
||||||
|
// The -e flag causes tidy to attempt to proceed despite errors
|
||||||
|
// encountered while loading packages.
|
||||||
|
//
|
||||||
//
|
//
|
||||||
// Make vendored copy of dependencies
|
// Make vendored copy of dependencies
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
//
|
//
|
||||||
// go mod vendor [-v]
|
// go mod vendor [-e] [-v]
|
||||||
//
|
//
|
||||||
// Vendor resets the main module's vendor directory to include all packages
|
// Vendor resets the main module's vendor directory to include all packages
|
||||||
// needed to build and test all the main module's packages.
|
// needed to build and test all the main module's packages.
|
||||||
@ -1256,6 +1259,9 @@
|
|||||||
// The -v flag causes vendor to print the names of vendored
|
// The -v flag causes vendor to print the names of vendored
|
||||||
// modules and packages to standard error.
|
// modules and packages to standard error.
|
||||||
//
|
//
|
||||||
|
// The -e flag causes vendor to attempt to proceed despite errors
|
||||||
|
// encountered while loading packages.
|
||||||
|
//
|
||||||
//
|
//
|
||||||
// Verify dependencies have expected content
|
// Verify dependencies have expected content
|
||||||
//
|
//
|
||||||
|
@ -2164,7 +2164,7 @@ func PackagesAndErrors(ctx context.Context, patterns []string) []*Package {
|
|||||||
loadOpts := modload.PackageOpts{
|
loadOpts := modload.PackageOpts{
|
||||||
ResolveMissingImports: true,
|
ResolveMissingImports: true,
|
||||||
LoadTests: ModResolveTests,
|
LoadTests: ModResolveTests,
|
||||||
AllowErrors: true,
|
SilenceErrors: true,
|
||||||
}
|
}
|
||||||
matches, _ = modload.LoadPackages(ctx, loadOpts, patterns...)
|
matches, _ = modload.LoadPackages(ctx, loadOpts, patterns...)
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var cmdTidy = &base.Command{
|
var cmdTidy = &base.Command{
|
||||||
UsageLine: "go mod tidy [-v]",
|
UsageLine: "go mod tidy [-e] [-v]",
|
||||||
Short: "add missing and remove unused modules",
|
Short: "add missing and remove unused modules",
|
||||||
Long: `
|
Long: `
|
||||||
Tidy makes sure go.mod matches the source code in the module.
|
Tidy makes sure go.mod matches the source code in the module.
|
||||||
@ -26,12 +26,18 @@ to go.sum and removes any unnecessary ones.
|
|||||||
|
|
||||||
The -v flag causes tidy to print information about removed modules
|
The -v flag causes tidy to print information about removed modules
|
||||||
to standard error.
|
to standard error.
|
||||||
|
|
||||||
|
The -e flag causes tidy to attempt to proceed despite errors
|
||||||
|
encountered while loading packages.
|
||||||
`,
|
`,
|
||||||
|
Run: runTidy,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tidyE bool // if true, report errors but proceed anyway.
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cmdTidy.Run = runTidy // break init cycle
|
|
||||||
cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "")
|
cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "")
|
||||||
|
cmdTidy.Flag.BoolVar(&tidyE, "e", false, "")
|
||||||
base.AddModCommonFlags(&cmdTidy.Flag)
|
base.AddModCommonFlags(&cmdTidy.Flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +63,9 @@ func runTidy(ctx context.Context, cmd *base.Command, args []string) {
|
|||||||
Tags: imports.AnyTags(),
|
Tags: imports.AnyTags(),
|
||||||
ResolveMissingImports: true,
|
ResolveMissingImports: true,
|
||||||
LoadTests: true,
|
LoadTests: true,
|
||||||
AllowErrors: false, // TODO(#26603): Make this a flag.
|
AllowErrors: tidyE,
|
||||||
}, "all")
|
}, "all")
|
||||||
|
|
||||||
modload.TidyBuildList()
|
modload.TidyBuildList()
|
||||||
modload.TrimGoSum()
|
modload.TrimGoSum()
|
||||||
modload.WriteGoMod()
|
modload.WriteGoMod()
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var cmdVendor = &base.Command{
|
var cmdVendor = &base.Command{
|
||||||
UsageLine: "go mod vendor [-v]",
|
UsageLine: "go mod vendor [-e] [-v]",
|
||||||
Short: "make vendored copy of dependencies",
|
Short: "make vendored copy of dependencies",
|
||||||
Long: `
|
Long: `
|
||||||
Vendor resets the main module's vendor directory to include all packages
|
Vendor resets the main module's vendor directory to include all packages
|
||||||
@ -34,12 +34,18 @@ It does not include test code for vendored packages.
|
|||||||
|
|
||||||
The -v flag causes vendor to print the names of vendored
|
The -v flag causes vendor to print the names of vendored
|
||||||
modules and packages to standard error.
|
modules and packages to standard error.
|
||||||
|
|
||||||
|
The -e flag causes vendor to attempt to proceed despite errors
|
||||||
|
encountered while loading packages.
|
||||||
`,
|
`,
|
||||||
Run: runVendor,
|
Run: runVendor,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var vendorE bool // if true, report errors but proceed anyway
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cmdVendor.Flag.BoolVar(&cfg.BuildV, "v", false, "")
|
cmdVendor.Flag.BoolVar(&cfg.BuildV, "v", false, "")
|
||||||
|
cmdVendor.Flag.BoolVar(&vendorE, "e", false, "")
|
||||||
base.AddModCommonFlags(&cmdVendor.Flag)
|
base.AddModCommonFlags(&cmdVendor.Flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +60,7 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) {
|
|||||||
Tags: imports.AnyTags(),
|
Tags: imports.AnyTags(),
|
||||||
ResolveMissingImports: true,
|
ResolveMissingImports: true,
|
||||||
UseVendorAll: true,
|
UseVendorAll: true,
|
||||||
|
AllowErrors: vendorE,
|
||||||
}
|
}
|
||||||
_, pkgs := modload.LoadPackages(ctx, loadOpts, "all")
|
_, pkgs := modload.LoadPackages(ctx, loadOpts, "all")
|
||||||
|
|
||||||
|
@ -66,10 +66,10 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) {
|
|||||||
modload.RootMode = modload.NeedRoot
|
modload.RootMode = modload.NeedRoot
|
||||||
|
|
||||||
loadOpts := modload.PackageOpts{
|
loadOpts := modload.PackageOpts{
|
||||||
Tags: imports.AnyTags(),
|
Tags: imports.AnyTags(),
|
||||||
LoadTests: !*whyVendor,
|
LoadTests: !*whyVendor,
|
||||||
AllowErrors: true,
|
SilenceErrors: true,
|
||||||
UseVendorAll: *whyVendor,
|
UseVendorAll: *whyVendor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if *whyM {
|
if *whyM {
|
||||||
|
@ -406,7 +406,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
|
|||||||
Tags: imports.AnyTags(),
|
Tags: imports.AnyTags(),
|
||||||
ResolveMissingImports: true, // dubious; see https://golang.org/issue/32567
|
ResolveMissingImports: true, // dubious; see https://golang.org/issue/32567
|
||||||
LoadTests: *getT,
|
LoadTests: *getT,
|
||||||
AllowErrors: true, // Errors may be fixed by subsequent upgrades or downgrades.
|
SilenceErrors: true, // Errors may be fixed by subsequent upgrades or downgrades.
|
||||||
SilenceUnmatchedWarnings: true, // We will warn after iterating below.
|
SilenceUnmatchedWarnings: true, // We will warn after iterating below.
|
||||||
}
|
}
|
||||||
matches, _ = modload.LoadPackages(ctx, loadOpts, pkgPatterns...)
|
matches, _ = modload.LoadPackages(ctx, loadOpts, pkgPatterns...)
|
||||||
|
@ -151,11 +151,14 @@ type PackageOpts struct {
|
|||||||
// declare 'go 1.16' or higher.
|
// declare 'go 1.16' or higher.
|
||||||
UseVendorAll bool
|
UseVendorAll bool
|
||||||
|
|
||||||
// AllowErrors indicates that LoadPackages should not log errors in resolving
|
// AllowErrors indicates that LoadPackages should not terminate the process if
|
||||||
// patterns or imports, and should not terminate the process if such an error
|
// an error occurs.
|
||||||
// occurs.
|
|
||||||
AllowErrors bool
|
AllowErrors bool
|
||||||
|
|
||||||
|
// SilenceErrors indicates that LoadPackages should not print errors
|
||||||
|
// that occur while loading packages. SilenceErrors implies AllowErrors.
|
||||||
|
SilenceErrors bool
|
||||||
|
|
||||||
// SilenceUnmatchedWarnings suppresses the warnings normally emitted for
|
// SilenceUnmatchedWarnings suppresses the warnings normally emitted for
|
||||||
// patterns that did not match any packages.
|
// patterns that did not match any packages.
|
||||||
SilenceUnmatchedWarnings bool
|
SilenceUnmatchedWarnings bool
|
||||||
@ -263,23 +266,31 @@ func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (ma
|
|||||||
|
|
||||||
// One last pass to finalize wildcards.
|
// One last pass to finalize wildcards.
|
||||||
updateMatches(loaded)
|
updateMatches(loaded)
|
||||||
checkMultiplePaths()
|
|
||||||
WriteGoMod()
|
|
||||||
|
|
||||||
|
// Report errors, if any.
|
||||||
|
checkMultiplePaths()
|
||||||
for _, pkg := range loaded.pkgs {
|
for _, pkg := range loaded.pkgs {
|
||||||
if pkg.err != nil && !opts.AllowErrors {
|
if pkg.err != nil && !opts.SilenceErrors {
|
||||||
base.Errorf("%s: %v", pkg.stackText(), pkg.err)
|
if opts.AllowErrors {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s: %v\n", pkg.stackText(), pkg.err)
|
||||||
|
} else {
|
||||||
|
base.Errorf("%s: %v", pkg.stackText(), pkg.err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !pkg.isTest() {
|
if !pkg.isTest() {
|
||||||
loadedPackages = append(loadedPackages, pkg.path)
|
loadedPackages = append(loadedPackages, pkg.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !opts.AllowErrors {
|
if !opts.SilenceErrors {
|
||||||
// Also list errors in matching patterns (such as directory permission
|
// Also list errors in matching patterns (such as directory permission
|
||||||
// errors for wildcard patterns).
|
// errors for wildcard patterns).
|
||||||
for _, match := range matches {
|
for _, match := range matches {
|
||||||
for _, err := range match.Errs {
|
for _, err := range match.Errs {
|
||||||
base.Errorf("%v", err)
|
if opts.AllowErrors {
|
||||||
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
} else {
|
||||||
|
base.Errorf("%v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,6 +300,8 @@ func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (ma
|
|||||||
search.WarnUnmatched(matches)
|
search.WarnUnmatched(matches)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Success! Update go.mod (if needed) and return the results.
|
||||||
|
WriteGoMod()
|
||||||
sort.Strings(loadedPackages)
|
sort.Strings(loadedPackages)
|
||||||
return matches, loadedPackages
|
return matches, loadedPackages
|
||||||
}
|
}
|
||||||
|
89
src/cmd/go/testdata/script/mod_e.txt
vendored
Normal file
89
src/cmd/go/testdata/script/mod_e.txt
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
cp go.mod go.mod.orig
|
||||||
|
|
||||||
|
|
||||||
|
# If a dependency cannot be resolved, 'go mod tidy' fails with an error message
|
||||||
|
# explaining the problem and does not update the go.mod file.
|
||||||
|
# TODO(bcmills): Ideally, with less redundancy than these error messages!
|
||||||
|
|
||||||
|
! go mod tidy
|
||||||
|
|
||||||
|
stderr '^example.com/untidy imports\n\texample.net/directnotfound: cannot find module providing package example.net/directnotfound: module example.net/directnotfound: reading http://.*: 404 Not Found$'
|
||||||
|
|
||||||
|
stderr '^example.com/untidy imports\n\texample.net/m imports\n\texample.net/indirectnotfound: cannot find module providing package example.net/indirectnotfound: module example.net/indirectnotfound: reading http://.*: 404 Not Found$'
|
||||||
|
|
||||||
|
stderr '^example.com/untidy tested by\n\texample.com/untidy.test imports\n\texample.net/directtestnotfound: cannot find module providing package example.net/directtestnotfound: module example.net/directtestnotfound: reading http://.*: 404 Not Found$'
|
||||||
|
|
||||||
|
stderr '^example.com/untidy imports\n\texample.net/m tested by\n\texample.net/m.test imports\n\texample.net/indirecttestnotfound: cannot find module providing package example.net/indirecttestnotfound: module example.net/indirecttestnotfound: reading http://.*: 404 Not Found$'
|
||||||
|
|
||||||
|
cmp go.mod.orig go.mod
|
||||||
|
|
||||||
|
|
||||||
|
# If a dependency cannot be resolved, 'go mod vendor' fails with an error message
|
||||||
|
# explaining the problem, does not update the go.mod file, and does not create
|
||||||
|
# the vendor directory.
|
||||||
|
|
||||||
|
! go mod vendor
|
||||||
|
|
||||||
|
stderr '^example.com/untidy imports\n\texample.net/directnotfound: cannot find module providing package example.net/directnotfound: module example.net/directnotfound: reading http://.*: 404 Not Found$'
|
||||||
|
|
||||||
|
stderr '^example.com/untidy imports\n\texample.net/m imports\n\texample.net/indirectnotfound: cannot find module providing package example.net/indirectnotfound: module example.net/indirectnotfound: reading http://.*: 404 Not Found$'
|
||||||
|
|
||||||
|
stderr '^example.com/untidy tested by\n\texample.com/untidy.test imports\n\texample.net/directtestnotfound: cannot find module providing package example.net/directtestnotfound: module example.net/directtestnotfound: reading http://.*: 404 Not Found$'
|
||||||
|
|
||||||
|
! stderr 'indirecttestnotfound' # Vendor prunes test dependencies.
|
||||||
|
|
||||||
|
cmp go.mod.orig go.mod
|
||||||
|
! exists vendor
|
||||||
|
|
||||||
|
|
||||||
|
# 'go mod tidy' still logs the errors, but succeeds and updates go.mod.
|
||||||
|
|
||||||
|
go mod tidy -e
|
||||||
|
stderr -count=4 'cannot find module providing package'
|
||||||
|
cmp go.mod.final go.mod
|
||||||
|
|
||||||
|
|
||||||
|
# 'go mod vendor -e' still logs the errors, but succeeds and updates go.mod.
|
||||||
|
|
||||||
|
cp go.mod.orig go.mod
|
||||||
|
go mod vendor -e
|
||||||
|
stderr -count=3 'cannot find module providing package'
|
||||||
|
cmp go.mod.final go.mod
|
||||||
|
exists vendor/modules.txt
|
||||||
|
exists vendor/example.net/m/m.go
|
||||||
|
|
||||||
|
|
||||||
|
-- go.mod --
|
||||||
|
module example.com/untidy
|
||||||
|
go 1.16
|
||||||
|
replace example.net/m v0.1.0 => ./m
|
||||||
|
-- go.mod.final --
|
||||||
|
module example.com/untidy
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
replace example.net/m v0.1.0 => ./m
|
||||||
|
|
||||||
|
require example.net/m v0.1.0
|
||||||
|
-- untidy.go --
|
||||||
|
package untidy
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "example.net/m"
|
||||||
|
_ "example.net/directnotfound"
|
||||||
|
)
|
||||||
|
-- untidy_test.go --
|
||||||
|
package untidy_test
|
||||||
|
|
||||||
|
import _ "example.net/directtestnotfound"
|
||||||
|
-- m/go.mod --
|
||||||
|
module example.net/m
|
||||||
|
go 1.16
|
||||||
|
-- m/m.go --
|
||||||
|
package m
|
||||||
|
|
||||||
|
import _ "example.net/indirectnotfound"
|
||||||
|
-- m/m_test.go --
|
||||||
|
package m_test
|
||||||
|
|
||||||
|
import _ "example.net/indirecttestnotfound"
|
Loading…
Reference in New Issue
Block a user