Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,31 @@ func applyCmd() *cli.Command {
}
```

Another `pflag.FlagSet` can be accessed using `*Command.PersistentFlags()`. Contrary to the
basic flags, flags set via the persistent flag set will be passed down to the children of the
command.

```go
func applyCmd() *cli.Command {
cmd := &cli.Command{
Use: "apply",
Short: "apply the changes"
}
force := cmd.PersistentFlags().BoolP("force", "f", false, "skip checks")
childCmd := &cli.Command{
Use: "now"
Short: "do it now"
}
cmd.AddCommand(childCmd)
childCmd.Run = func(cmd *cli.Command, args []string) error {
fmt.Println("applied now", args[0])
if *force {
fmt.Println("The force was with us.")
}
}
}
```

## Aliases

To make the `apply` subcommand also available as `make` and `do`:
Expand Down
11 changes: 10 additions & 1 deletion children.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package cli

import "fmt"
import (
"fmt"

"github.com/spf13/pflag"
)

// AddCommand adds the supplied commands as subcommands.
// Persistent flags are passed down to the child.
// This command is set as the parent of the new children.
func (c *Command) AddCommand(children ...*Command) {
for _, child := range children {
child.parentPtr = c
if c.persistentFlags != nil {
child.persistentFlags = pflag.NewFlagSet(child.Name(), pflag.ContinueOnError)
child.PersistentFlags().AddFlagSet(c.persistentFlags)
}
c.children = append(c.children, child)
}
}
Expand Down
8 changes: 5 additions & 3 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ type Command struct {
Args Arguments

// internal fields
children []*Command
flags *pflag.FlagSet
parentPtr *Command
children []*Command
flags *pflag.FlagSet
persistentFlags *pflag.FlagSet
parentPtr *Command
}

// Execute runs the application. It should be run on the most outer level
Expand Down Expand Up @@ -90,6 +91,7 @@ func (c *Command) execute(args []string) error {
}

// parse flags
c.Flags().AddFlagSet(c.PersistentFlags())
if err := c.Flags().Parse(args); err != nil {
return c.help(err)
}
Expand Down
9 changes: 9 additions & 0 deletions flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ func (c *Command) Flags() *pflag.FlagSet {
return c.flags
}

// PersistentFlags returns the `*pflag.FlagSet` with the persistent flags of this command.
// Persistent flags are passed to subcommands.
func (c *Command) PersistentFlags() *pflag.FlagSet {
if c.persistentFlags == nil {
c.persistentFlags = pflag.NewFlagSet(c.Name(), pflag.ContinueOnError)
}
return c.persistentFlags
}

// stripFlags removes flags from the argument line, leaving only subcommands and
// positional arguments.
func stripFlags(args []string, c *Command) []string {
Expand Down
14 changes: 14 additions & 0 deletions flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,17 @@ func TestStripFlags(t *testing.T) {
}
}
}

func TestPersistentFlags(t *testing.T) {
parent := &Command{}
parent.PersistentFlags().String("persistent", "", "")
parent.Flags().String("non-persistent", "", "")
child := &Command{}
parent.AddCommand(child)
if child.PersistentFlags().Lookup("persistent") == nil {
t.Error("expected persistent flag to be passed to child")
}
if child.Flags().Lookup("non-persistent") != nil {
t.Error("expected non-persistent flag to not be passed to child")
}
}