diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 80ec025..f5a3350 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -31,4 +31,4 @@ jobs: run: make snapshot - name: check binary - run: ./dist/mdtoc-amd64-linux -version + run: ./dist/mdtoc-amd64-linux -v diff --git a/.golangci.yml b/.golangci.yml index 9d48484..874d3b4 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -114,6 +114,11 @@ linters: # - varnamelen # - wsl linters-settings: + gci: + sections: + - standard + - default + - localmodule cyclop: max-complexity: 15 godox: diff --git a/go.mod b/go.mod index ffebc88..fbd475c 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22 require ( github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0 github.com/mmarkdown/mmark v2.0.40+incompatible + github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 sigs.k8s.io/release-utils v0.8.3 ) @@ -15,7 +16,6 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/mdtoc.go b/mdtoc.go index fce25b5..f1c6416 100644 --- a/mdtoc.go +++ b/mdtoc.go @@ -18,15 +18,24 @@ package main import ( "errors" - "flag" "fmt" "log" "os" - "sigs.k8s.io/mdtoc/pkg/mdtoc" + "github.com/spf13/cobra" "sigs.k8s.io/release-utils/version" + + "sigs.k8s.io/mdtoc/pkg/mdtoc" ) +var cmd = &cobra.Command{ + Use: os.Args[0] + " [FILE]...", + Long: "Generate a table of contents for a markdown file (GitHub flavor).\n\n" + + "TOC may be wrapped in a pair of tags to allow in-place updates:\n" + + "", + RunE: run, +} + type utilityOptions struct { mdtoc.Options Inplace bool @@ -35,23 +44,20 @@ type utilityOptions struct { var defaultOptions utilityOptions func init() { - flag.BoolVar(&defaultOptions.Dryrun, "dryrun", false, "Whether to check for changes to TOC, rather than overwriting. Requires --inplace flag.") - flag.BoolVar(&defaultOptions.Inplace, "inplace", false, "Whether to edit the file in-place, or output to STDOUT. Requires toc tags to be present.") - flag.BoolVar(&defaultOptions.SkipPrefix, "skip-prefix", true, "Whether to ignore any headers before the opening toc tag.") - flag.IntVar(&defaultOptions.MaxDepth, "max-depth", mdtoc.MaxHeaderDepth, "Limit the depth of headers that will be included in the TOC.") - flag.BoolVar(&defaultOptions.Version, "version", false, "Show MDTOC version.") - - flag.Usage = func() { - fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [OPTIONS] [FILE]...\n", os.Args[0]) - fmt.Fprintf(flag.CommandLine.Output(), "Generate a table of contents for a markdown file (github flavor).\n") - fmt.Fprintf(flag.CommandLine.Output(), "TOC may be wrapped in a pair of tags to allow in-place updates: \n") - flag.PrintDefaults() - } + cmd.PersistentFlags().BoolVarP(&defaultOptions.Dryrun, "dryrun", "d", false, "Whether to check for changes to TOC, rather than overwriting. Requires --inplace flag.") + cmd.PersistentFlags().BoolVarP(&defaultOptions.Inplace, "inplace", "i", false, "Whether to edit the file in-place, or output to STDOUT. Requires toc tags to be present.") + cmd.PersistentFlags().BoolVarP(&defaultOptions.SkipPrefix, "skip-prefix", "s", true, "Whether to ignore any headers before the opening toc tag.") + cmd.PersistentFlags().IntVarP(&defaultOptions.MaxDepth, "max-depth", "m", mdtoc.MaxHeaderDepth, "Limit the depth of headers that will be included in the TOC.") + cmd.PersistentFlags().BoolVarP(&defaultOptions.Version, "version", "v", false, "Show MDTOC version.") } func main() { - flag.Parse() + if err := cmd.Execute(); err != nil { + log.Fatal(err) + } +} +func run(_ *cobra.Command, args []string) error { if defaultOptions.Version { v := version.GetVersionInfo() v.Name = "mdtoc" @@ -59,35 +65,30 @@ func main() { v.ASCIIName = "true" v.FontName = "banner" fmt.Fprintln(os.Stdout, v.String()) - os.Exit(0) + return nil } - if err := validateArgs(defaultOptions, flag.Args()); err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - flag.Usage() - os.Exit(1) + if err := validateArgs(defaultOptions, args); err != nil { + return fmt.Errorf("validate args: %w", err) } - switch defaultOptions.Inplace { - case true: - hadError := false - for _, file := range flag.Args() { - err := mdtoc.WriteTOC(file, defaultOptions.Options) - if err != nil { - log.Printf("%s: %v", file, err) - hadError = true + if defaultOptions.Inplace { + var retErr error + for _, file := range args { + if err := mdtoc.WriteTOC(file, defaultOptions.Options); err != nil { + retErr = errors.Join(retErr, fmt.Errorf("%s: %w", file, err)) } } - if hadError { - os.Exit(1) - } - case false: - toc, err := mdtoc.GetTOC(flag.Args()[0], defaultOptions.Options) - if err != nil { - os.Exit(1) - } - fmt.Println(toc) + return retErr } + + toc, err := mdtoc.GetTOC(args[0], defaultOptions.Options) + if err != nil { + return fmt.Errorf("get toc: %w", err) + } + fmt.Println(toc) + + return nil } func validateArgs(opts utilityOptions, args []string) error { diff --git a/mdtoc_test.go b/mdtoc_test.go index 0859a46..f9b6a2b 100644 --- a/mdtoc_test.go +++ b/mdtoc_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "sigs.k8s.io/mdtoc/pkg/mdtoc" )