I can't seem to be able to access the bool flags from within a subcommand. Is this a regression?

When I run go run main.go --xts, it works, but when I run go run main.go encrypt --xts, it returns

Is this specific to bool commands only for you? In an example I mocked up they don't pass through for any flags that are at the global level. Additionally I don't see any output for global flags in the help template for sub commands.
Did this work in the past for you and are you using v1 or v2?
I have a fork of this I am maintaining and I added basic support for this. Support can be added in a nicer way and presented better but will take a bit more work. It would be nice to do this by separating the global flags so we can print them out in the same way that the parent level help command does. Right now I don't see that being possible while also letting people access the flags how they are accustomed to unless we duplicate them just for the purpose of outputting them. I however also added category support for flags in my branch so you can do something like this for your global commands and get a decent looking output.
app := cli.NewApp()
app.Name = "collins"
app.Version = "0.0.1"
app.Usage = "Interface with http://tumblr.github.io/collins/"
app.Flags = []cli.Flag{
cli.IntFlag{
Name: "timeout",
Usage: "Timeout in seconds (0 == forever)",
Category: "Global setting",
},
cli.StringFlag{
Name: "C, config",
Usage: "Use specific Collins config yaml for client",
Category: "Global setting",
},
}
This then renders like so in a sub command.
NAME:
collins-go-cli query - Search for assets in Collins
USAGE:
collins-go-cli query [command options] [arguments...]
OPTIONS:
Global setting
--timeout value Timeout in seconds (0 == forever) (default: 0)
-C value, --config value Use specific Collins config yaml for client
Query options
-t value, --tag value Assets with tag[s] value[,...]
-Z, --remote-lookup Query remote datacenters for asset
-T value, --type value Only show asset with type value
-n value, --nodeclass value Assets in nodeclass value[,...]
-p value, --pool value Assets in pool value[,...]
-s value, --size value Number of assets to return per page (default: 100)
--limit value Limit total results of assets (default: 0)
-r value, --role value Assets in primary role
-R value, --secondary-role value Assets in secondary role
-i value, --ip-address value Assets with IP address[es]
-S value, --status value Asset status (and optional state after :)
-a value, --attribute value Arbitrary attributes and values to match in query. : between key and value
Robot formatting
-l, --link Output link to assets found in web UI
-j, --json Output results in JSON
-y, --yaml Output results in YAML
Table formatting
-H, --show-header Show header fields in output
-c value, --columns value Attributes to output as columns, comma separated (default: "tag,hostname,nodeclass,status,pool,primary_role,secondary_role")
-x value, --extra-columns value Show these columns in addition to the default columns, comma separated
-f value, --field-separator value Separator between columns in output
If you are using go.mod you can use my patch via the following.
replace github.com/urfave/cli => github.com/michaeljs1990/cli global-flag-subcommand-passthrough
I also have global flags (database access details) that I need for my subcommands. Would love to see this implemented in this library.
[EDIT]
Well, I'm doing this now, which is fine for me:
dbFlags := []cli.Flag{
cli.StringFlag{
Name: "psql-host",
Value: "localhost",
Usage: "The postgres host",
},
cli.IntFlag{
Name: "psql-port",
Value: 5432,
Usage: "The postgres port",
},
cli.StringFlag{
Name: "psql-user",
Value: "user",
Usage: "The postgres user",
},
cli.StringFlag{
Name: "psql-pass",
Value: "secret",
Usage: "The postgres pasword",
},
cli.StringFlag{
Name: "psql-db",
Value: "dbname",
Usage: "The postgres dbname",
},
}
app.Flags = dbFlags
app.Commands = []cli.Command{
{
Name: "up",
Aliases: []string{"u"},
Usage: "Execute new migrations.",
Action: up,
Flags: dbFlags,
},
{
Name: "down",
Aliases: []string{"d"},
Usage: "Revert migrations.",
Action: down,
Flags: dbFlags,
},
}
Reading through the issue - it sounds like there's something we can do here! But I'm not quite sure what that is 馃攳 I think it would be helpful if someone wanted to followup here.
@lynncyrin to state this issue more succinctly:
app.Flags should be queryable alongside subcommand-specific flags within the cli.Context that's passed into cli.Command.Action's func.
I was stuck with the same problem and got the solution from @erikh:
You can query the global flags in app.Flags from a subcommand with c.GlobalBool, so instead of c.Bool("xts") it's c.GlobalBool("xts").
You also need to specify the global flags before the subcommand, so this should work:
go run main.go --xts encrypt
I'm actually going to remove the help wanted here, because I think https://github.com/urfave/cli/pull/892/ will fix this issue. I'll keep this issue open until someone can confirm, though
I can confirm that this is not an issue anymore.
package main
import (
"fmt"
"github.com/urfave/cli/v2"
"log"
"os"
)
func main() {
app := &cli.App{}
app.Name = "myprogramname"
app.Commands = cli.Commands{
{
Name: "foo",
Action: func(c *cli.Context) error {
name := c.String("name")
age := c.Int("age")
eligible := c.Bool("eligible")
fmt.Printf("Name: %s\nAge: %s\nIs Eligible: %v\n", name, age, eligible)
return nil
},
},
}
app.Flags = []cli.Flag{
&cli.StringFlag{
Name: "name",
Aliases: []string{"n"},
},
&cli.IntFlag{
Name: "age",
Aliases: []string{"a"},
},
&cli.BoolFlag{
Name: "eligible",
Aliases: []string{"e"},
},
}
app.Action = func(c *cli.Context) error {
name := c.String("name")
age := c.Int("age")
eligible := c.Bool("eligible")
fmt.Printf("Name: %s\nAge: %s\nIs Eligible: %v\n", name, age, eligible)
return nil
}
log.Fatal(app.Run(os.Args))
}
I tried to execute with this code on the v2 branch with the following commands:
go run main.go --name Ajitem --age 30 --eligible
go run main.go --name Ajitem --age 30 --eligible foo
go run main.go -n Ajitem -a 30 -e
go run main.go -n Ajitem -a 30 -e foo
I was able to access the values of the flags in the subcommands without any problem
Most helpful comment
I have a fork of this I am maintaining and I added basic support for this. Support can be added in a nicer way and presented better but will take a bit more work. It would be nice to do this by separating the global flags so we can print them out in the same way that the parent level help command does. Right now I don't see that being possible while also letting people access the flags how they are accustomed to unless we duplicate them just for the purpose of outputting them. I however also added category support for flags in my branch so you can do something like this for your global commands and get a decent looking output.
This then renders like so in a sub command.
If you are using go.mod you can use my patch via the following.