Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access flags outside of main package?

Tags:

flags

go

We parse flags in main.go which is in main package, of course. Then we have another package where we want to read some flag's value.

flags.Args() work fine, it will return all non-flag values.

But I cannot figure out to how read already parsed value for a flag in a package other than main.

Is it possible?

Thanks

Amer

like image 554
Amer Avatar asked Oct 23 '14 21:10

Amer


2 Answers

I had the same requirement recently and I wanted a solution that avoided calling flag.Parse repeatedly in init functions.

Perusing the flag package I found Lookup(name string) which returns a Flag which has a Value. Every built in Value implements the flag.Getter interface. The call chain looks like this:

flag.Lookup("httplog").Value.(flag.Getter).Get().(bool)

If you mistype the flag name or use the wrong type you get a runtime error. I wrapped the lookup in a function that I call directly where needed since the lookup and get methods are fast and the function is not called often. So the main package declares the flag.

// main.go
package main

import "flag"

var httplog = flag.Bool("httplog", false, "Log every HTTP request and response.")

func main() {
    flag.Parse()
    // ...
}

And the utility package, which is decoupled from main except for the flag name, reads the flag value.

// httpdiag.go
package utility

import "flag"

func logging() bool {
    return flag.Lookup("httplog").Value.(flag.Getter).Get().(bool)
}
like image 192
Andrew Dobrowolski Avatar answered Nov 15 '22 07:11

Andrew Dobrowolski


You can define the var storing the flag in the separate package, as an exported variable, then call the flag parsing in the main package to use that variable, like this:

mypackage/const.go

var (
    MyExportedVar string
)

mainpackage/main.go

func init() {
    flag.StringVar(&mypackage.MyExportedVar, "flagName", "defaultValue", "usage")

    flag.Parse()
}

This way, everybody can access that flag, including that package itself.

Note: this only works for exported variables.

like image 20
marcusljx Avatar answered Nov 15 '22 08:11

marcusljx