mirror of
https://github.com/golang/go
synced 2024-09-29 16:24:28 -06:00
cmd/go: add -C flag
The -C flag is like tar -C or make -C: it changes to the named directory early in command startup, before anything else happens. Fixes #50332. Change-Id: I8e4546f69044cb3a028d4d26dfba482b08cb845d Reviewed-on: https://go-review.googlesource.com/c/go/+/421436 Reviewed-by: Bryan Mills <bcmills@google.com> Auto-Submit: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
fb4f7fdb26
commit
2af48cbb7d
@ -57,12 +57,13 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
unexported bool // -u flag
|
||||
matchCase bool // -c flag
|
||||
showAll bool // -all flag
|
||||
showCmd bool // -cmd flag
|
||||
showSrc bool // -src flag
|
||||
short bool // -short flag
|
||||
unexported bool // -u flag
|
||||
matchCase bool // -c flag
|
||||
chdir string // -C flag
|
||||
showAll bool // -all flag
|
||||
showCmd bool // -cmd flag
|
||||
showSrc bool // -src flag
|
||||
short bool // -short flag
|
||||
)
|
||||
|
||||
// usage is a replacement usage function for the flags package.
|
||||
@ -96,6 +97,7 @@ func do(writer io.Writer, flagSet *flag.FlagSet, args []string) (err error) {
|
||||
flagSet.Usage = usage
|
||||
unexported = false
|
||||
matchCase = false
|
||||
flagSet.StringVar(&chdir, "C", "", "change to `dir` before running command")
|
||||
flagSet.BoolVar(&unexported, "u", false, "show unexported symbols as well as exported")
|
||||
flagSet.BoolVar(&matchCase, "c", false, "symbol matching honors case (paths not affected)")
|
||||
flagSet.BoolVar(&showAll, "all", false, "show all documentation for package")
|
||||
@ -103,6 +105,11 @@ func do(writer io.Writer, flagSet *flag.FlagSet, args []string) (err error) {
|
||||
flagSet.BoolVar(&showSrc, "src", false, "show source code for symbol")
|
||||
flagSet.BoolVar(&short, "short", false, "one-line representation for each symbol")
|
||||
flagSet.Parse(args)
|
||||
if chdir != "" {
|
||||
if err := os.Chdir(chdir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
var paths []string
|
||||
var symbol, method string
|
||||
// Loop until something is printed.
|
||||
|
@ -100,6 +100,10 @@
|
||||
// The build flags are shared by the build, clean, get, install, list, run,
|
||||
// and test commands:
|
||||
//
|
||||
// -C dir
|
||||
// Change to dir before running the command.
|
||||
// Any files named on the command line are interpreted after
|
||||
// changing directories.
|
||||
// -a
|
||||
// force rebuilding of packages that are already up-to-date.
|
||||
// -n
|
||||
@ -1233,6 +1237,8 @@
|
||||
// referred to indirectly. For the full set of modules available to a build,
|
||||
// use 'go list -m -json all'.
|
||||
//
|
||||
// Edit also provides the -C, -n, and -x build flags.
|
||||
//
|
||||
// See https://golang.org/ref/mod#go-mod-edit for more about 'go mod edit'.
|
||||
//
|
||||
// # Print module requirement graph
|
||||
@ -1797,7 +1803,7 @@
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]
|
||||
// go vet [-C dir] [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]
|
||||
//
|
||||
// Vet runs the Go vet command on the packages named by the import paths.
|
||||
//
|
||||
@ -1806,6 +1812,7 @@
|
||||
// For a list of checkers and their flags, see 'go tool vet help'.
|
||||
// For details of a specific checker such as 'printf', see 'go tool vet help printf'.
|
||||
//
|
||||
// The -C flag changes to dir before running the 'go vet' command.
|
||||
// The -n flag prints commands that would be executed.
|
||||
// The -x flag prints commands as they are executed.
|
||||
//
|
||||
|
49
src/cmd/go/chdir_test.go
Normal file
49
src/cmd/go/chdir_test.go
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmd/go/internal/base"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestChdir(t *testing.T) {
|
||||
// We want -C to apply to every go subcommand.
|
||||
// Test that every command either has a -C flag registered
|
||||
// or has CustomFlags set. In the latter case, the command
|
||||
// must be explicitly tested in TestScript/chdir.
|
||||
script, err := os.ReadFile("testdata/script/chdir.txt")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var walk func(string, *base.Command)
|
||||
walk = func(name string, cmd *base.Command) {
|
||||
if len(cmd.Commands) > 0 {
|
||||
for _, sub := range cmd.Commands {
|
||||
walk(name+" "+sub.Name(), sub)
|
||||
}
|
||||
return
|
||||
}
|
||||
if !cmd.Runnable() {
|
||||
return
|
||||
}
|
||||
if cmd.CustomFlags {
|
||||
if !strings.Contains(string(script), "# "+name+"\n") {
|
||||
t.Errorf("%s has custom flags, not tested in testdata/script/chdir.txt", name)
|
||||
}
|
||||
return
|
||||
}
|
||||
f := cmd.Flag.Lookup("C")
|
||||
if f == nil {
|
||||
t.Errorf("%s has no -C flag", name)
|
||||
} else if f.Usage != "AddChdirFlag" {
|
||||
t.Errorf("%s has -C flag but not from AddChdirFlag", name)
|
||||
}
|
||||
}
|
||||
walk("go", base.Go)
|
||||
}
|
@ -6,6 +6,7 @@ package base
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/fsys"
|
||||
@ -57,6 +58,13 @@ func AddBuildFlagsNX(flags *flag.FlagSet) {
|
||||
flags.BoolVar(&cfg.BuildX, "x", false, "")
|
||||
}
|
||||
|
||||
// AddChdirFlag adds the -C flag to the flag set.
|
||||
func AddChdirFlag(flags *flag.FlagSet) {
|
||||
// The usage message is never printed, but it's used in chdir_test.go
|
||||
// to identify that the -C flag is from AddChdirFlag.
|
||||
flags.Func("C", "AddChdirFlag", os.Chdir)
|
||||
}
|
||||
|
||||
// AddModFlag adds the -mod build flag to the flag set.
|
||||
func AddModFlag(flags *flag.FlagSet) {
|
||||
flags.Var(explicitStringFlag{value: &cfg.BuildMod, explicit: &cfg.BuildModExplicit}, "mod", "")
|
||||
|
@ -37,6 +37,7 @@ The report includes useful system information.
|
||||
|
||||
func init() {
|
||||
CmdBug.Flag.BoolVar(&cfg.BuildV, "v", false, "")
|
||||
base.AddChdirFlag(&CmdBug.Flag)
|
||||
}
|
||||
|
||||
func runBug(ctx context.Context, cmd *base.Command, args []string) {
|
||||
|
@ -57,6 +57,7 @@ For more about environment variables, see 'go help environment'.
|
||||
|
||||
func init() {
|
||||
CmdEnv.Run = runEnv // break init cycle
|
||||
base.AddChdirFlag(&CmdEnv.Flag)
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
|
||||
func init() {
|
||||
base.AddBuildFlagsNX(&CmdFmt.Flag)
|
||||
base.AddChdirFlag(&CmdFmt.Flag)
|
||||
base.AddModFlag(&CmdFmt.Flag)
|
||||
base.AddModCommonFlags(&CmdFmt.Flag)
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ func init() {
|
||||
|
||||
// TODO(jayconrod): https://golang.org/issue/35849 Apply -x to other 'go mod' commands.
|
||||
cmdDownload.Flag.BoolVar(&cfg.BuildX, "x", false, "")
|
||||
base.AddChdirFlag(&cmdDownload.Flag)
|
||||
base.AddModCommonFlags(&cmdDownload.Flag)
|
||||
}
|
||||
|
||||
|
@ -127,6 +127,8 @@ Note that this only describes the go.mod file itself, not other modules
|
||||
referred to indirectly. For the full set of modules available to a build,
|
||||
use 'go list -m -json all'.
|
||||
|
||||
Edit also provides the -C, -n, and -x build flags.
|
||||
|
||||
See https://golang.org/ref/mod#go-mod-edit for more about 'go mod edit'.
|
||||
`,
|
||||
}
|
||||
@ -157,8 +159,9 @@ func init() {
|
||||
cmdEdit.Flag.Var(flagFunc(flagRetract), "retract", "")
|
||||
cmdEdit.Flag.Var(flagFunc(flagDropRetract), "dropretract", "")
|
||||
|
||||
base.AddModCommonFlags(&cmdEdit.Flag)
|
||||
base.AddBuildFlagsNX(&cmdEdit.Flag)
|
||||
base.AddChdirFlag(&cmdEdit.Flag)
|
||||
base.AddModCommonFlags(&cmdEdit.Flag)
|
||||
}
|
||||
|
||||
func runEdit(ctx context.Context, cmd *base.Command, args []string) {
|
||||
|
@ -41,6 +41,7 @@ var (
|
||||
|
||||
func init() {
|
||||
cmdGraph.Flag.Var(&graphGo, "go", "")
|
||||
base.AddChdirFlag(&cmdGraph.Flag)
|
||||
base.AddModCommonFlags(&cmdGraph.Flag)
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ See https://golang.org/ref/mod#go-mod-init for more about 'go mod init'.
|
||||
}
|
||||
|
||||
func init() {
|
||||
base.AddChdirFlag(&cmdInit.Flag)
|
||||
base.AddModCommonFlags(&cmdInit.Flag)
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,7 @@ func init() {
|
||||
cmdTidy.Flag.BoolVar(&tidyE, "e", false, "")
|
||||
cmdTidy.Flag.Var(&tidyGo, "go", "")
|
||||
cmdTidy.Flag.Var(&tidyCompat, "compat", "")
|
||||
base.AddChdirFlag(&cmdTidy.Flag)
|
||||
base.AddModCommonFlags(&cmdTidy.Flag)
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,7 @@ func init() {
|
||||
cmdVendor.Flag.BoolVar(&cfg.BuildV, "v", false, "")
|
||||
cmdVendor.Flag.BoolVar(&vendorE, "e", false, "")
|
||||
cmdVendor.Flag.StringVar(&vendorO, "o", "", "")
|
||||
base.AddChdirFlag(&cmdVendor.Flag)
|
||||
base.AddModCommonFlags(&cmdVendor.Flag)
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ See https://golang.org/ref/mod#go-mod-verify for more about 'go mod verify'.
|
||||
}
|
||||
|
||||
func init() {
|
||||
base.AddChdirFlag(&cmdVerify.Flag)
|
||||
base.AddModCommonFlags(&cmdVerify.Flag)
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ var (
|
||||
|
||||
func init() {
|
||||
cmdWhy.Run = runWhy // break init cycle
|
||||
base.AddChdirFlag(&cmdWhy.Flag)
|
||||
base.AddModCommonFlags(&cmdWhy.Flag)
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ func isGccgoTool(tool string) bool {
|
||||
}
|
||||
|
||||
func init() {
|
||||
base.AddChdirFlag(&CmdTool.Flag)
|
||||
CmdTool.Flag.BoolVar(&toolN, "n", false, "")
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ See also: go doc runtime/debug.BuildInfo.
|
||||
}
|
||||
|
||||
func init() {
|
||||
base.AddChdirFlag(&CmdVersion.Flag)
|
||||
CmdVersion.Run = runVersion // break init cycle
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ func init() {
|
||||
|
||||
var CmdVet = &base.Command{
|
||||
CustomFlags: true,
|
||||
UsageLine: "go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]",
|
||||
UsageLine: "go vet [-C dir] [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]",
|
||||
Short: "report likely mistakes in packages",
|
||||
Long: `
|
||||
Vet runs the Go vet command on the packages named by the import paths.
|
||||
@ -35,6 +35,7 @@ For more about specifying packages, see 'go help packages'.
|
||||
For a list of checkers and their flags, see 'go tool vet help'.
|
||||
For details of a specific checker such as 'printf', see 'go tool vet help printf'.
|
||||
|
||||
The -C flag changes to dir before running the 'go vet' command.
|
||||
The -n flag prints commands that would be executed.
|
||||
The -x flag prints commands as they are executed.
|
||||
|
||||
|
@ -58,6 +58,10 @@ will be written to that directory.
|
||||
The build flags are shared by the build, clean, get, install, list, run,
|
||||
and test commands:
|
||||
|
||||
-C dir
|
||||
Change to dir before running the command.
|
||||
Any files named on the command line are interpreted after
|
||||
changing directories.
|
||||
-a
|
||||
force rebuilding of packages that are already up-to-date.
|
||||
-n
|
||||
@ -282,6 +286,7 @@ const (
|
||||
// install, list, run, and test commands.
|
||||
func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) {
|
||||
base.AddBuildFlagsNX(&cmd.Flag)
|
||||
base.AddChdirFlag(&cmd.Flag)
|
||||
cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "")
|
||||
cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "")
|
||||
if mask&OmitVFlag == 0 {
|
||||
|
@ -109,6 +109,7 @@ func init() {
|
||||
cmdEdit.Flag.Var(flagFunc(flagEditworkDropUse), "dropuse", "")
|
||||
cmdEdit.Flag.Var(flagFunc(flagEditworkReplace), "replace", "")
|
||||
cmdEdit.Flag.Var(flagFunc(flagEditworkDropReplace), "dropreplace", "")
|
||||
base.AddChdirFlag(&cmdEdit.Flag)
|
||||
}
|
||||
|
||||
func runEditwork(ctx context.Context, cmd *base.Command, args []string) {
|
||||
|
@ -34,6 +34,7 @@ for more information.
|
||||
}
|
||||
|
||||
func init() {
|
||||
base.AddChdirFlag(&cmdInit.Flag)
|
||||
base.AddModCommonFlags(&cmdInit.Flag)
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ for more information.
|
||||
}
|
||||
|
||||
func init() {
|
||||
base.AddChdirFlag(&cmdSync.Flag)
|
||||
base.AddModCommonFlags(&cmdSync.Flag)
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ var useR = cmdUse.Flag.Bool("r", false, "")
|
||||
func init() {
|
||||
cmdUse.Run = runUse // break init cycle
|
||||
|
||||
base.AddChdirFlag(&cmdUse.Flag)
|
||||
base.AddModCommonFlags(&cmdUse.Flag)
|
||||
}
|
||||
|
||||
|
31
src/cmd/go/testdata/script/chdir.txt
vendored
Normal file
31
src/cmd/go/testdata/script/chdir.txt
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
env OLD=$PWD
|
||||
|
||||
# basic -C functionality
|
||||
cd $GOROOT/src/math
|
||||
go list -C ../strings
|
||||
stdout strings
|
||||
! go list -C ../nonexist
|
||||
stderr 'chdir.*nonexist'
|
||||
|
||||
# check for -C in subcommands with custom flag parsing
|
||||
# cmd/go/chdir_test.go handles the normal ones more directly.
|
||||
|
||||
# go doc
|
||||
go doc -C ../strings HasPrefix
|
||||
|
||||
# go env
|
||||
go env -C $OLD/custom GOMOD
|
||||
stdout 'custom[\\/]go.mod'
|
||||
! go env -C ../nonexist
|
||||
stderr '^invalid value "../nonexist" for flag -C: chdir ../nonexist:.*$'
|
||||
|
||||
# go test
|
||||
go test -n -C ../strings
|
||||
stderr 'strings\.test'
|
||||
|
||||
# go vet
|
||||
go vet -n -C ../strings
|
||||
stderr strings_test
|
||||
|
||||
-- custom/go.mod --
|
||||
module m
|
Loading…
Reference in New Issue
Block a user