urfave / cli

A simple, fast, and fun package for building command line apps in Go
https://cli.urfave.org
MIT License
21.91k stars 1.69k forks source link

PersistentFlags support #1820

Closed chirino closed 7 months ago

chirino commented 7 months ago

Something similar to cobra's PersistentFlag would be a nice addition to save configuration to files.

A persistent flag is a flag defined in a parent command, that can be use in any of the sub commands without having to repeat the flag in the sub command. These a really useful for common flags like --verbose that all sub commands will implement.

See: https://stackoverflow.com/questions/63495992/what-is-the-difference-between-go-cobra-persistentflags-and-flags for other explanations.

chirino commented 7 months ago

This is basically reopening #692 since that was closed due to folks not understanding what persistent flags are. They are NOT about "saving a flag that was set in the previous invocation of the cli".

chirino commented 7 months ago

Some might think you can just use common flags on the root command and sub commands to get this to work, but sadly it does not. The following test currently fails:

package test

import (
    "github.com/urfave/cli/v2"
    "testing"
)

func TestCommonFlags(t *testing.T) {

    commonFlags := []cli.Flag{
        &cli.StringFlag{
            Name: "result",
        },
    }

    result := ""
    app := &cli.App{
        Name:  "root",
        Flags: commonFlags,
        Commands: []*cli.Command{
            {
                Name:  "sub",
                Flags: commonFlags,
                Action: func(ctx *cli.Context) error {
                    result = ctx.String("result")
                    return nil
                },
            },
        },
    }

    if err := app.Run([]string{"root", "sub", "--result", "after"}); err != nil {
        t.Fatal(err)
    }
    if result != "after" {
        t.Fatalf("result is not after")
    }

    if err := app.Run([]string{"root", "--result", "before", "sub"}); err != nil {
        t.Fatal(err)
    }
    if result != "before" {
        t.Fatalf("result is not before")
    }

}
dearchap commented 7 months ago

@chirino Support for persistent flags was added in v3. Please try with that. You can mark a flag explicitly as persistent in which case it will be allowed in subcommands as well.

dearchap commented 7 months ago

@chirino I am closing this for now. If you see any problems with persistent flags in v3 we can create a new issue

chirino commented 7 months ago

Thanks! I Tested v3 out and it's working nice.

chirino commented 7 months ago

Well mostly working.. found this bug: https://github.com/urfave/cli/issues/1826