Tags: #go #guide
Most information is copied verbatim from https://pace.dev/blog/2020/02/12/why-you-shouldnt-use-func-main-in-golang-by-mat-ryer.html
Also consider:
Call a run
function from main
to decouple the two and to enable easier testing:
const (
// exitFail is the exit code if the program
// fails.
exitFail = 1
)
func main() {
if err := run(os.Args, os.Stdout); err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(exitFail)
}
}
func run(args []string, stdout io.Writer) error {
if len(args) < 2 {
return errors.New("no names")
}
for _, name := range args[1:] {
fmt.Fprintf(stdout, "Hi %s", name)
}
return nil
}
We can use flags inside the run function using the flag.NewFlagSet function and avoid using global flags altogether:
flags := flag.NewFlagSet(args[0], flag.ExitOnError)
var (
verbose = flags.Bool("v", false, "verbose logging")
format = flags.String("f", "Hi %s", "greeting format")
)
if err := flags.Parse(args[1:]); err != nil {
return err
}
Test code can set any flags they like when calling run
by passing in different args:
err := run([]string{"program", "-v", "-debug=true", "-another=2"})
This allows you to write tests covering different flag usage too.