From 5f136fda0752e2fe256af7449cbd5a49a3281804 Mon Sep 17 00:00:00 2001 From: Marques Johansson Date: Fri, 28 Aug 2020 13:00:16 -0400 Subject: [PATCH 1/2] add "tink docs" command for markdown and man page generation Signed-off-by: Marques Johansson --- cmd/tink-cli/cmd/completion.go | 7 +++--- cmd/tink-cli/cmd/docs.go | 46 ++++++++++++++++++++++++++++++++++ cmd/tink-cli/cmd/root.go | 1 + go.sum | 3 +++ 4 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 cmd/tink-cli/cmd/docs.go diff --git a/cmd/tink-cli/cmd/completion.go b/cmd/tink-cli/cmd/completion.go index 78acafcaa..3cf73649b 100644 --- a/cmd/tink-cli/cmd/completion.go +++ b/cmd/tink-cli/cmd/completion.go @@ -32,10 +32,9 @@ func completionCmd(name string) *cobra.Command { # To load completions for each session, execute once: $ tink-cli completion fish > ~/.config/fish/completions/tink-cli.fish `, - DisableFlagsInUseLine: true, - Hidden: true, - ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, - Args: cobra.ExactValidArgs(1), + Hidden: true, + ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, + Args: cobra.ExactValidArgs(1), RunE: func(cmd *cobra.Command, args []string) error { switch args[0] { case "bash": diff --git a/cmd/tink-cli/cmd/docs.go b/cmd/tink-cli/cmd/docs.go new file mode 100644 index 000000000..e3a6de25a --- /dev/null +++ b/cmd/tink-cli/cmd/docs.go @@ -0,0 +1,46 @@ +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" +) + +var ( + docsPath string +) + +// docsCmd returns the generate command that, when run, generates +// documentation +func docsCmd(name string) *cobra.Command { + return &cobra.Command{ + Use: "docs [markdown|man]", + Short: "Generate documentation", + Hidden: true, + ValidArgs: []string{"markdown", "man"}, + Args: cobra.ExactValidArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + format := args[0] + + switch format { + case "markdown": + return doc.GenMarkdownTree(cmd.Parent(), docsPath) + case "man": + header := &doc.GenManHeader{Title: name} + return doc.GenManTree(cmd.Parent(), header, docsPath) + } + // ValidArgs make this error response dead-code + return fmt.Errorf("unknown format: %q", format) + }, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + return nil + }, + } +} + +func init() { + docsCmd := docsCmd(rootCmd.CalledAs()) + docsCmd.Flags().StringVarP(&docsPath, "path", "p", "", "Path where documentation will be generated") + rootCmd.AddCommand(docsCmd) +} diff --git a/cmd/tink-cli/cmd/root.go b/cmd/tink-cli/cmd/root.go index 7562eb015..418dbc0e1 100644 --- a/cmd/tink-cli/cmd/root.go +++ b/cmd/tink-cli/cmd/root.go @@ -15,6 +15,7 @@ var rootCmd = &cobra.Command{ Use: "tink", Short: "tinkerbell CLI", PersistentPreRunE: setupClient, + DisableAutoGenTag: true, } func init() { diff --git a/go.sum b/go.sum index acc6534e2..828aaadbf 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,7 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -184,9 +185,11 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rollbar/rollbar-go v1.0.2 h1:uA3+z0jq6ka9WUUt9VX/xuiQZXZyWRoeKvkhVvLO9Jc= github.com/rollbar/rollbar-go v1.0.2/go.mod h1:AcFs5f0I+c71bpHlXNNDbOWJiKwjFDtISeXco0L5PKQ= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= From f0596c42f737e7b0ec373c09f1f0ce5869b04ce0 Mon Sep 17 00:00:00 2001 From: Marques Johansson Date: Fri, 28 Aug 2020 20:25:01 -0400 Subject: [PATCH 2/2] add tests for tink-cli docs command Signed-off-by: Marques Johansson --- cmd/tink-cli/cmd/docs.go | 6 +- cmd/tink-cli/cmd/docs_test.go | 143 ++++++++++++++++++++++++++++++++++ go.mod | 1 + 3 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 cmd/tink-cli/cmd/docs_test.go diff --git a/cmd/tink-cli/cmd/docs.go b/cmd/tink-cli/cmd/docs.go index e3a6de25a..cd5adb0b5 100644 --- a/cmd/tink-cli/cmd/docs.go +++ b/cmd/tink-cli/cmd/docs.go @@ -14,7 +14,7 @@ var ( // docsCmd returns the generate command that, when run, generates // documentation func docsCmd(name string) *cobra.Command { - return &cobra.Command{ + cmd := &cobra.Command{ Use: "docs [markdown|man]", Short: "Generate documentation", Hidden: true, @@ -37,10 +37,12 @@ func docsCmd(name string) *cobra.Command { return nil }, } + cmd.Flags().StringVarP(&docsPath, "path", "p", "", "Path where documentation will be generated") + return cmd } func init() { docsCmd := docsCmd(rootCmd.CalledAs()) - docsCmd.Flags().StringVarP(&docsPath, "path", "p", "", "Path where documentation will be generated") + rootCmd.AddCommand(docsCmd) } diff --git a/cmd/tink-cli/cmd/docs_test.go b/cmd/tink-cli/cmd/docs_test.go new file mode 100644 index 000000000..e055486dc --- /dev/null +++ b/cmd/tink-cli/cmd/docs_test.go @@ -0,0 +1,143 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "os" + "path" + "strings" + "testing" + + "github.com/spf13/cobra" +) + +const ( + testCommand = "tink-cli" +) + +func Test_docsCmd(t *testing.T) { + type args struct { + name string + } + tests := []struct { + name string + args args + want *cobra.Command + cmdFunc func(*testing.T, *cobra.Command) + }{ + { + name: "NoArgs", + args: args{name: testCommand}, + want: &cobra.Command{}, + cmdFunc: func(t *testing.T, c *cobra.Command) { + root := c.Root() + root.SetArgs([]string{"docs"}) + if err := root.Execute(); err == nil { + t.Error("expected an error") + } + }, + }, + { + name: "Help", + args: args{name: testCommand}, + want: &cobra.Command{}, + cmdFunc: func(t *testing.T, c *cobra.Command) { + root := c.Root() + out := &bytes.Buffer{} + root.SetArgs([]string{"docs", "--help"}) + root.SetOutput(out) + if err := root.Execute(); err != nil { + t.Error(err) + } + if !strings.Contains(out.String(), "markdown") { + t.Error("expected help to include markdown") + } + }, + }, + { + name: "Markdown", + args: args{name: testCommand}, + want: &cobra.Command{}, + cmdFunc: func(t *testing.T, c *cobra.Command) { + dir, err := ioutil.TempDir("", "tink-test-*") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + root := c.Root() + root.SetArgs([]string{"docs", "markdown", "--path", dir}) + + if err := root.Execute(); err != nil { + t.Error(err) + } + + expectFile := testCommand + ".md" + _, err = os.Stat(path.Join(dir, expectFile)) + + if os.IsNotExist(err) { + t.Errorf("expected to create %s: %s", expectFile, err) + } + + if err != nil { + t.Error(err) + } + }, + }, + { + name: "Man", + args: args{name: testCommand}, + want: &cobra.Command{}, + cmdFunc: func(t *testing.T, c *cobra.Command) { + dir, err := ioutil.TempDir("", "tink-test-*") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + root := c.Root() + root.SetArgs([]string{"docs", "man", "--path", dir}) + + if err := root.Execute(); err != nil { + t.Error(err) + } + + expectFile := testCommand + ".1" + _, err = os.Stat(path.Join(dir, expectFile)) + + if os.IsNotExist(err) { + t.Errorf("expected to create %s: %s", expectFile, err) + } + + if err != nil { + t.Error(err) + } + }, + }, + { + name: "BadFormat", + args: args{name: testCommand}, + want: &cobra.Command{}, + cmdFunc: func(t *testing.T, c *cobra.Command) { + root := c.Root() + root.SetArgs([]string{"docs", "invalid"}) + if err := root.Execute(); err == nil { + t.Error("expected error") + } + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rootCmd := &cobra.Command{ + Use: testCommand, + Run: func(_ *cobra.Command, _ []string) {}, + Version: "test", + } + cmd := docsCmd(tt.args.name) + rootCmd.AddCommand(cmd) + tt.cmdFunc(t, cmd) + }) + } +} diff --git a/go.mod b/go.mod index 90e9266b2..b468999e8 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/rollbar/rollbar-go v1.0.2 // indirect github.com/satori/go.uuid v1.2.0 github.com/sirupsen/logrus v1.4.1 + github.com/spf13/afero v1.1.2 github.com/spf13/cobra v1.0.0 github.com/spf13/viper v1.4.0 github.com/stretchr/testify v1.3.0