Cli: Combine flags from other package

Created on 15 Aug 2015  路  11Comments  路  Source: urfave/cli

Hi

Is there any solutaion for combining flags from other package. For example, glog package requires flag.Parse for using his flags but when i put the flag.Parse(), his flag overrided whole my cli flags. What should i do if i want to use both glog flags and my cli flags ?

help wanted statustale statutriage

Most helpful comment

Managed to get it going in the v1 branch without vendoring (though it's certainly pretty janky):

func glogFlagShim(fakeVals map[string]string) {
    flag.VisitAll(func(fl *flag.Flag) {
        if val, ok := fakeVals[fl.Name]; ok {
            fl.Value.Set(val)
        }
    })
}

func glogGangstaShim(c *cli.Context) {
    _ = flag.CommandLine.Parse([]string{})
    glogFlagShim(map[string]string{
        "v":                fmt.Sprint(c.Int("v")),
        "logtostderr":      fmt.Sprint(c.Bool("logtostderr")),
        "stderrthreshold":  fmt.Sprint(c.Int("stderrthreshold")),
        "alsologtostderr":  fmt.Sprint(c.Bool("alsologtostderr")),
        "vmodule":          c.String("vmodule"),
        "log_dir":          c.String("log_dir"),
        "log_backtrace_at": c.String("log_backtrace_at"),
    })
}

var glogGangstaFlags = []cli.Flag{
    cli.IntFlag{
        Name: "v", Value: 0, Usage: "log level for V logs",
    },
    cli.BoolFlag{
        Name: "logtostderr", Usage: "log to standard error instead of files",
    },
    cli.IntFlag{
        Name:  "stderrthreshold",
        Usage: "logs at or above this threshold go to stderr",
    },
    cli.BoolFlag{
        Name: "alsologtostderr", Usage: "log to standard error as well as files",
    },
    cli.StringFlag{
        Name:  "vmodule",
        Usage: "comma-separated list of pattern=N settings for file-filtered logging",
    },
    cli.StringFlag{
        Name: "log_dir", Usage: "If non-empty, write log files in this directory",
    },
    cli.StringFlag{
        Name:  "log_backtrace_at",
        Usage: "when logging hits line file:N, emit a stack trace",
        Value: ":0",
    },
}

func main() {
    cli.VersionFlag = cli.BoolFlag{
        Name:  "version",
        Usage: "print the version",
    }
    app := cli.NewApp()
    app.Flags = []cli.Flag{
        cli.StringFlag{Name: "config", Value: "config.json"},
    }
    app.Flags = append(app.Flags, glogGangstaFlags...)

    app.Action = func(c *cli.Context) error {
        glogGangstaShim(c)
        return nil
    }
    app.Run(os.Args)
}

All 11 comments

+1

I needed this and the following seems to be work. I of course had to vendor the cli package and add the following file

package cli
import (
    "flag"
    "fmt"
)

type FlagsFlag struct {
    *flag.Flag
}

func (f FlagsFlag) Apply(flag *flag.FlagSet) {
    flag.Var(f.Flag.Value, f.Name, f.Usage)
}

func (f FlagsFlag) getName() string {
    return f.Name
}

func (f FlagsFlag) String() string {
    return fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Flag.Name), f.Flag.Value, f.Flag.Usage)
}

and then add the following to my app

func addDefault(app *cli.App) {
    app.HideVersion=true
    flag.CommandLine.VisitAll(func(f *flag.Flag) {
        app.Flags = append(app.Flags, cli.FlagsFlag{f})
    })
}

Seems to print the logs, not clean but unblock for now.

+1

That workaround doesn't work for the v2 branch

Managed to get it going in the v1 branch without vendoring (though it's certainly pretty janky):

func glogFlagShim(fakeVals map[string]string) {
    flag.VisitAll(func(fl *flag.Flag) {
        if val, ok := fakeVals[fl.Name]; ok {
            fl.Value.Set(val)
        }
    })
}

func glogGangstaShim(c *cli.Context) {
    _ = flag.CommandLine.Parse([]string{})
    glogFlagShim(map[string]string{
        "v":                fmt.Sprint(c.Int("v")),
        "logtostderr":      fmt.Sprint(c.Bool("logtostderr")),
        "stderrthreshold":  fmt.Sprint(c.Int("stderrthreshold")),
        "alsologtostderr":  fmt.Sprint(c.Bool("alsologtostderr")),
        "vmodule":          c.String("vmodule"),
        "log_dir":          c.String("log_dir"),
        "log_backtrace_at": c.String("log_backtrace_at"),
    })
}

var glogGangstaFlags = []cli.Flag{
    cli.IntFlag{
        Name: "v", Value: 0, Usage: "log level for V logs",
    },
    cli.BoolFlag{
        Name: "logtostderr", Usage: "log to standard error instead of files",
    },
    cli.IntFlag{
        Name:  "stderrthreshold",
        Usage: "logs at or above this threshold go to stderr",
    },
    cli.BoolFlag{
        Name: "alsologtostderr", Usage: "log to standard error as well as files",
    },
    cli.StringFlag{
        Name:  "vmodule",
        Usage: "comma-separated list of pattern=N settings for file-filtered logging",
    },
    cli.StringFlag{
        Name: "log_dir", Usage: "If non-empty, write log files in this directory",
    },
    cli.StringFlag{
        Name:  "log_backtrace_at",
        Usage: "when logging hits line file:N, emit a stack trace",
        Value: ":0",
    },
}

func main() {
    cli.VersionFlag = cli.BoolFlag{
        Name:  "version",
        Usage: "print the version",
    }
    app := cli.NewApp()
    app.Flags = []cli.Flag{
        cli.StringFlag{Name: "config", Value: "config.json"},
    }
    app.Flags = append(app.Flags, glogGangstaFlags...)

    app.Action = func(c *cli.Context) error {
        glogGangstaShim(c)
        return nil
    }
    app.Run(os.Args)
}

+1, consider solving the problem in this tool?

I'm not 100% sure what the request is here - as far as I can tell @carlverge has a solution above? Given that, I think I'm gonna close this. Let me know if it should be re-opened, though!

Created a stand-alone feature request for this => https://github.com/urfave/cli/issues/948. I'm going to close this one as a duplicate now

re-opening this b/c there wasn't any movement on https://github.com/urfave/cli/issues/948, anyone that's available please do pick up the work here

This issue or PR has been automatically marked as stale because it has not had recent activity. Please add a comment bumping this if you're still interested in it's resolution! Thanks for your help, please let us know if you need anything else.

Closing this as it has become stale.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

errashe picture errashe  路  3Comments

LeonB picture LeonB  路  5Comments

millken picture millken  路  5Comments

blackrez picture blackrez  路  5Comments

renzhengeek picture renzhengeek  路  5Comments