Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: The go test command cannot parse custom args with flag.Parse() #39206

Closed
the1mills opened this issue May 21, 2020 · 6 comments
Closed

Bug: The go test command cannot parse custom args with flag.Parse() #39206

the1mills opened this issue May 21, 2020 · 6 comments
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.

Comments

@the1mills
Copy link

the1mills commented May 21, 2020

What version of Go are you using (go version)?

go version go1.14 darwin/amd64

Does this issue reproduce with the latest release?

yes 1.14

What operating system and processor architecture are you using (go env)?

go env Output
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/alex/Library/Caches/go-build"
GOENV="/Users/alex/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/alex/go"
GOPRIVATE=""
GOPROXY="direct"
GOROOT="/usr/local/Cellar/go/1.14/libexec"
GOSUMDB="off"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.14/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/alex/go/src/github.com/channelmeter/cp-go-api/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/qh/l8tr6tfd3gv7fmdg0b5z0p340000gn/T/go-build971392475=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I ran:

go test -v github.com/cm/some-pkg -- --env=local

What did you expect to see?

I expected flag.Parse() to capture the flag

What did you see instead?

the --env flag is not captured, even though it appears in the args list when I use:

  fmt.Println(len(os.Args), os.Args)

I see:

[/var/folders/qh/l8tr6tfd3gv7fmdg0b5z0p340000gn/T/go-build589736069/b001/roles.test -test.timeout=10m0s -test.v=true  -- --env=local]

I put the Q on SO first:
https://stackoverflow.com/questions/61944527/how-to-pass-custom-flags-to-go-test?noredirect=1#comment109560255_61944527

@paulgriffiths
Copy link

This is not a bug. From the documentation for package flag:

Flag parsing stops just before the first non-flag argument ("-" is a non-flag argument) or after the terminator "--".

and your --env flag appears after the terminator "--", so it's correctly not being parsed.

@ianlancetaylor ianlancetaylor added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label May 22, 2020
@as
Copy link
Contributor

as commented May 22, 2020

This is a common idiom you will see in many command line tools, not just Go.

-- terminates the argument parser explicitly, because sometimes you have arguments, such as file names, that start with - which you want to capture as a value instead of a flag.

@ORESoftware
Copy link

well then you know what i am trying to do. so what is the solution?

@pschultz
Copy link

Flags in tests are really no different than in any other program, except that you don't get to call flag.Parse() yourself:

package main

import (
	"flag"
	"log"
	"os"
	"testing"
)

var x = flag.Bool("env", false, "")

// run with `go test --env`
func TestFlags(t *testing.T) {
	log.Println(os.Args)     // /tmp/go-build197321626/b001/tmp.lW3vriEIbp.test -test.timeout=10m0s --env
	log.Println(flag.Args()) // []
	log.Println(*x)          // true
}

To treat arguments as flags create a dedicated FlagSet:

// run with `go test -- --env`
func TestArgs(t *testing.T) {
	fs := flag.NewFlagSet("my-test", flag.ContinueOnError)
	y := fs.Bool("env", false, "")

	log.Println(os.Args)     // [/tmp/go-build483180072/b001/tmp.lW3vriEIbp.test -test.timeout=10m0s -- --env]
	log.Println(flag.Args()) // [--env]

	if err := fs.Parse(flag.Args()); err != nil {
		t.Fatal(err)
	}

	log.Println(*y) // true
}

@mvdan
Copy link
Member

mvdan commented May 22, 2020

The docs for the interaction between testing and flag.Parse were a bit ambiguous, so I made them clearer a couple of weeks ago in #38952.

If anything is still confusing, please suggest doc improvements. Aside from that, I agree that the current behavior seems to be correct.

@gopherbot
Copy link

Timed out in state WaitingForInfo. Closing.

(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)

@golang golang locked and limited conversation to collaborators Jun 22, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

8 participants