diff --git a/README.md b/README.md index 52e3263..23727db 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ Cli-X is a command line library for Go, inspired by [`spf13/cobra`](https://github.com/spf13/cobra). -- :package: **`struct` based API**: Similar to `cobra`, `clix` features a `struct` based +- :package: **`struct` based API**: Similar to `cobra`, `go-clix/cli` features a `struct` based API for easy composition and discovery of available options. -- :children_crossing: [**Subcommands**](#subcommands): `clix.Command` can be nested for a `git` +- :children_crossing: [**Subcommands**](#subcommands): `cli.Command` can be nested for a `git` like experience. - :pushpin: [**Flags**](#flags): Every command has it's own set of flags. POSIX compliant using `spf13/pflag`. @@ -34,12 +34,12 @@ import ( func main() { // create the root command - rootCmd := clix.Command{ + rootCmd := cli.Command{ Use: "greet", Short: "print a message", - Run: func(cmd *clix.Command, args []string) error { + Run: func(cmd *cli.Command, args []string) error { fmt.Println("Hello from Cli-X!") - } + }, } // run and check for errors @@ -57,19 +57,21 @@ Every command may have children: ```go // use a func to return a Command instead of // a global variable and `init()` -func applyCmd() *clix.Command { - cmd := &clix.Command{ +func applyCmd() *cli.Command { + cmd := &cli.Command{ Use: "apply", Short: "apply the changes" } - cmd.Run = func(cmd *clix.Command, args []string) error { + cmd.Run = func(cmd *cli.Command, args []string) error { fmt.Println("applied", args[0]) } + + return cmd } func main() { - rootCmd := &clix.Comand{ + rootCmd := &cli.Comand{ Use: "kubectl", Short: "Kubernetes management tool", } @@ -95,20 +97,21 @@ func main() { A `pflag.FlagSet` can be accessed per command using `*Command.Flags()`: ```go -func applyCmd() *clix.Command { - cmd := &clix.Command{ +func applyCmd() *cli.Command { + cmd := &cli.Command{ Use: "apply", Short: "apply the changes" } force := cmd.Flags().BoolP("force", "f", false, "skip checks") - cmd.Run = func(cmd *clix.Command, args []string) error { + cmd.Run = func(cmd *cli.Command, args []string) error { fmt.Println("applied", args[0]) if *force { fmt.Println("The force was with us.") } } + return cmd } ``` @@ -117,8 +120,8 @@ func applyCmd() *clix.Command { To make the `apply` subcommand also available as `make` and `do`: ```go -func applyCmd() *clix.Command { - cmd := &clix.Command{ +func applyCmd() *cli.Command { + cmd := &cli.Command{ Use: "apply", Aliases: []string{"make", "do"}, Short: "apply the changes" @@ -161,12 +164,12 @@ import ( "github.com/go-clix/cli" ) -func logsCmd() *clix.Command { - cmd := &clix.Command{ +func logsCmd() *cli.Command { + cmd := &cli.Command{ Use: "logs", Short: "show logs of a pod", Predictors: map[string]complete.Predictor{ - "output": clix.PredictSet("lines", "json", "logfmt"), + "output": cli.PredictSet("lines", "json", "logfmt"), }, } @@ -200,12 +203,12 @@ import ( "github.com/go-clix/cli" ) -func applyCmd() *clix.Command { - cmd := &clix.Command{ +func applyCmd() *cli.Command { + cmd := &cli.Command{ Use: "logs", Short: "show logs of a pod", // we expect one argument which can be anything - Args: clix.ArgsExact(1), + Args: cli.ArgsExact(1), } } ``` diff --git a/_examples/aliases/main.go b/_examples/aliases/main.go new file mode 100644 index 0000000..a47d494 --- /dev/null +++ b/_examples/aliases/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "fmt" + "os" + + "github.com/go-clix/cli" +) + +// Keep in mind that in `--help` outputs the command will still be called `apply`. + + +func applyCmd() *cli.Command { + return &cli.Command{ + Use: "apply", + Aliases: []string{"make", "do"}, + Short: "apply the changes", + } +} + +func main() { + rootCmd := &cli.Command{ + Use: "aliases", + Short: "Subcommand has aliases.", + } + rootCmd.AddCommand(applyCmd()) + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/_examples/basic/main.go b/_examples/basic/main.go new file mode 100644 index 0000000..7dd2684 --- /dev/null +++ b/_examples/basic/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "fmt" + "os" + + "github.com/go-clix/cli" +) + +func main(){ + // create the root command + rootCmd := cli.Command{ + Use: "greet", + Short: "print a message", + Run: func(cmd *cli.Command, args []string) error { + fmt.Println("Hello from Cli-X!") + return nil + }, + } + + // run and check for errors + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/_examples/flags/main.go b/_examples/flags/main.go new file mode 100644 index 0000000..e7205f8 --- /dev/null +++ b/_examples/flags/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "os" + + "github.com/go-clix/cli" +) + +// A `pflag.FlagSet` can be accessed per command using `*Command.Flags()`: + +func applyCmd() *cli.Command { + cmd := &cli.Command{ + Use: "apply", + Short: "apply the changes", + } + + force := cmd.Flags().BoolP("force", "f", false, "skip checks") + + cmd.Run = func(cmd *cli.Command, args []string) error { + fmt.Println("applied", args[0]) + if *force { + fmt.Println("The force was with us.") + } + return nil + } + return cmd +} + + +func main() { + rootCmd := &cli.Command{ + Use: "kubectl", + Short: "Kubernetes management tool", + } + + // add the child command + rootCmd.AddCommand( + applyCmd(), + ) + + // run and check for errors + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/_examples/subcommands/main.go b/_examples/subcommands/main.go new file mode 100644 index 0000000..ab44efa --- /dev/null +++ b/_examples/subcommands/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" + "os" + + "github.com/go-clix/cli" +) + +// use a func to return a Command instead of +// a global variable and `init()` +func applyCmd() *cli.Command { + cmd := &cli.Command{ + Use: "apply", + Short: "apply the changes", + } + + cmd.Run = func(cmd *cli.Command, args []string) error { + fmt.Println("applied", args[0]) + return nil + } + + return cmd +} + +func main() { + rootCmd := &cli.Command{ + Use: "subcommands", + Short: "This command has sub commands.", + } + rootCmd.AddCommand(applyCmd()) + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/childs.go b/children.go similarity index 94% rename from childs.go rename to children.go index f028f80..e5faf21 100644 --- a/childs.go +++ b/children.go @@ -4,8 +4,8 @@ import "fmt" // AddCommand adds the supplied commands as subcommands. // This command is set as the parent of the new children. -func (c *Command) AddCommand(childs ...*Command) { - for _, child := range childs { +func (c *Command) AddCommand(children ...*Command) { + for _, child := range children { child.parentPtr = c c.children = append(c.children, child) } diff --git a/flags_test.go b/flags_test.go index 241683b..2377c0c 100644 --- a/flags_test.go +++ b/flags_test.go @@ -1,9 +1,8 @@ package cli import ( + "reflect" "testing" - - "github.com/stretchr/testify/assert" ) func TestStripFlags(t *testing.T) { @@ -73,6 +72,8 @@ func TestStripFlags(t *testing.T) { for _, test := range tests { got := stripFlags(test.input, c) - assert.Equal(t, test.output, got) + if !reflect.DeepEqual(test.output, got) { + t.Fatalf("want %+v but got %+v", got, test.output) + } } } diff --git a/go.mod b/go.mod index 7643fcf..7c2db67 100644 --- a/go.mod +++ b/go.mod @@ -5,5 +5,4 @@ go 1.14 require ( github.com/posener/complete v1.2.3 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.4.0 )