Consider, my application uses a third party library. I want my application to accept only the flags defined in my application and not the flags defined in imported packages.
package main
import (
"flag"
"fmt"
log "github.com/golang/glog"
)
var myFlag int
func init() {
flag.IntVar(&myFlag, "my_flag", 0, "need only my flags")
confDir := "/Users/foo/test/logs" //assume this is read from configuration file
flag.Set("log_dir", confDir)
flag.Parse()
}
func main() {
flag.Parse()
log.Errorln("flag", myFlag)
log.V(0).Infoln("flag", myFlag)
fmt.Println("test", myFlag)
}
In above code sample, log package has many flags. After compiling when I execute following command, all flags including "my_flag" and flags from log package are displayed. But, I want to set the values for log package flags from my code with values obtained from configuration file.
-alsologtostderr
log to standard error as well as files
-log_backtrace_at value
when logging hits line file:N, emit a stack trace
-log_dir string
If non-empty, write log files in this directory
-logtostderr
log to standard error instead of files
-my_flag int
need only my flags
-stderrthreshold value
logs at or above this threshold go to stderr
-v value
log level for V logs
-vmodule value
comma-separated list of pattern=N settings for file-filtered logging
How to restrict my application executable from accepting other flags?
If you want to discard the flags of other packages, then you can use a new flagset instead of the default one.
package main
import (
"flag"
"fmt"
"os"
)
var myFlag int
func main() {
f := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
f.IntVar(&myFlag, "my_flag", 0, "need only my flags")
confDir := "/Users/foo/test/logs" //assume this is read from configuration file
f.Set("log_dir", confDir)
f.Parse(os.Args[1:])
fmt.Println("test", myFlag)
}
flag
functions that aren't methods use the exported package variable CommandLine
. You could use
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
to reset the exported package variable CommandLine
in flag
. Here's a runnable example of that:
package main
import(
"flag"
"fmt"
"os"
)
func main() {
flag.Int("u", 1, "We don't want this flag")
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
GoodInt := flag.Int("g", 100, "This is a flag we want!")
flag.Parse()
fmt.Println(*GoodInt)
}
Usage example:
$ go run program.go -h
Usage of /tmp/.../program:
-g int
This is a flag we want! (default 100)
exit status 2
If you prefer to avoid modifying the package variable, you can do so by creating a new FlagSet
, which the answer that got in just before me demonstrates. In that case, make sure you call only methods on the new FlagSet
, and avoid the flag
functions that operate on CommandLine
.