diff --git a/cmd/cmd.go b/cmd/cmd.go index ef384b7..9da47b3 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -3,7 +3,10 @@ package cmd import ( "fmt" "io" + "log" "os" + "slices" + "strings" "github.com/chaoss/ai-detection-action/detection" "github.com/chaoss/ai-detection-action/detection/coauthor" @@ -13,6 +16,7 @@ import ( "github.com/chaoss/ai-detection-action/output" "github.com/chaoss/ai-detection-action/scan" "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" ) var Version = "dev" @@ -49,6 +53,7 @@ func Run(args []string, stdout, stderr io.Writer) int { rootCmd.AddCommand(scanCommand(stdout, stderr, &exitCode)) rootCmd.AddCommand(textCommand(stdout, stderr, &exitCode)) rootCmd.AddCommand(versionCommand(stdout, &exitCode)) + rootCmd.AddCommand(generateDocs(&exitCode)) rootCmd.SetArgs(args) if err := rootCmd.Execute(); err != nil { @@ -229,3 +234,75 @@ func filterReport(report scan.Report, minConf detection.Confidence) scan.Report return filtered } + +func generateDocs(exitCode *int) *cobra.Command { + var outputDir string + var formatFlag string + + defaultOutputDir := "./docs/cli" + supportedFormats := []string{"markdown", "manpages", "rest"} + cmd := &cobra.Command{ + Use: "docs", + Short: fmt.Sprintf("Build docs in %s formats", strings.Join(supportedFormats, ", ")), + Example: fmt.Sprintf(` # simply build markdown docs at default output dir (%s) + ai-detection-action docs + + # build rest docs at default output dir + ai-detection-action docs --format rest + + # build manpages docs at a specific 'documentation' dir + ai-detection-action docs --format manpages --out ./documentation`, defaultOutputDir), + Args: cobra.MaximumNArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + prepareError := func(err error) error { + log.Println(err) + *exitCode = ExitError + return err + } + + var docDir string + var err error + + root := cmd.Root() + // as per cobra docs: disable autogen tag for + // stable, reproducible files (no timestamp footer) + root.DisableAutoGenTag = true + + // create required dir for docs inside output dir + if slices.Contains(supportedFormats, formatFlag) { + docDir = fmt.Sprintf("%s/%s", outputDir, formatFlag) + err = os.MkdirAll(docDir, 0o755) + } else { + err = fmt.Errorf("unknown format: %s\n", formatFlag) + } + if err != nil { + return prepareError(err) + } + + // gen docs as per specified flag + switch formatFlag { + case "markdown": + log.Println("Building docs in Markdown format.") + err = doc.GenMarkdownTree(root, docDir) + case "manpages": + log.Println("Building docs in Manpages format.") + hdr := &doc.GenManHeader{Title: strings.ToUpper(root.Name()), Section: "1"} + err = doc.GenManTree(root, hdr, docDir) + case "rest": + log.Println("Building docs in ReST (reStructuredText) format.") + err = doc.GenReSTTree(root, docDir) + } + + if err != nil { + return prepareError(err) + } + log.Printf("Docs built successfully at %s\n", docDir) + return nil + }, + } + + cmd.Flags().StringVar(&outputDir, "out", defaultOutputDir, "output directory") + cmd.Flags().StringVar(&formatFlag, "format", "markdown", strings.Join(supportedFormats, "|")) + + return cmd +} diff --git a/go.mod b/go.mod index a084afd..f43e559 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/cloudflare/circl v1.6.1 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect @@ -21,10 +22,12 @@ require ( github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/pjbgf/sha1cd v0.3.2 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.3.1 // indirect github.com/spf13/pflag v1.0.9 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.45.0 // indirect golang.org/x/net v0.47.0 // indirect golang.org/x/sys v0.38.0 // indirect diff --git a/go.sum b/go.sum index 1e4e0cf..6b323de 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,7 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= @@ -58,6 +59,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= @@ -75,6 +77,7 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=