diff --git a/CHANGELOG.md b/CHANGELOG.md index 3392ae7..07a796e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +- (cli) [#6](https://github.com/MalteHerrmann/ginkgo-parser/6) Use Cobra for CLI implementation. - (ci) [#5](https://github.com/MalteHerrmann/ginkgo-parser/5) Add linter to CI. ## [v0.1.0](https://github.com/MalteHerrmann/ginkgo-parser/releases/tag/v0.1.0) - 2023-08-24 diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..0210268 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,64 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/MalteHerrmann/ginkgo-parser/report" + "github.com/spf13/cobra" +) + +const ( + ExportTypeMD = "md" + ExportTypeHTML = "html" +) + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "ginkgo-parser REPORT_PATH EXPORT_PATH [flags]", + Short: "Parses the generated JSON report from a Ginkgo run and exports the test information to Markdown or HTML.", + Long: `This tool parses the JSON reports, that can be generated using the Ginkgo BDD +testing binary. + +By default, the tool generates a Markdown document, that lists the ran +specs in a nested and sorted way. + +Optionally, an HTML document can be generated.`, + Args: cobra.ExactArgs(2), + RunE: func(_ *cobra.Command, args []string) error { + jsonFile := args[0] + if _, err := os.Stat(jsonFile); os.IsNotExist(err) { + return fmt.Errorf("file not found: %s", jsonFile) + } + + exportPath := os.Args[1] + switch exportType { + case ExportTypeMD: + return report.ConvertGinkgoReportToMarkdown(jsonFile, exportPath) + default: + return fmt.Errorf("unsupported export type: %s", exportType) + } + }, +} + +// exportType defines which type of output should be generated with this tool. +var exportType string + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + err := rootCmd.Execute() + if err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func init() { + rootCmd.Flags().StringVar( + &exportType, + "type", + ExportTypeMD, + fmt.Sprintf("The type of the exported file. Can be %q or %q.", ExportTypeMD, ExportTypeHTML), + ) +} diff --git a/example-report/example_test.go b/example-report/example_test.go index f939fe0..ee4229b 100644 --- a/example-report/example_test.go +++ b/example-report/example_test.go @@ -5,7 +5,9 @@ package example_test import ( "testing" + //nolint:revive // Okay to use dot imports for Ginkgo . "github.com/onsi/ginkgo/v2" + //nolint:revive // Okay to use dot imports for Ginkgo . "github.com/onsi/gomega" ) diff --git a/go.mod b/go.mod index fa432a8..d0701c7 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,9 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect diff --git a/go.sum b/go.sum index d43c6ce..c92df76 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -7,11 +8,18 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= diff --git a/main.go b/main.go index 850fe7a..f47a16c 100644 --- a/main.go +++ b/main.go @@ -4,42 +4,13 @@ // It converts the specification into a markdown file, which list all run specs // in a nested and human readable format. // -// Usage: -// -// go run github.com/MalteHerrmann/ginkgo-parser GINKGO_REPORT [EXPORT_PATH] +// Optionally, an HTML file can be generated. package main import ( - "fmt" - "os" - - "github.com/MalteHerrmann/ginkgo-parser/report" + "github.com/MalteHerrmann/ginkgo-parser/cmd" ) -// defaultExportName defines the default name of the export file. -const defaultExportName = "parsed_ginkgo_suite.md" - func main() { - // TODO: use cobra CLI library - if len(os.Args) < 2 || len(os.Args) > 3 { - fmt.Println("Usage: ginkgo-parser GINKGO_REPORT [EXPORT_PATH]") - return - } - - jsonFile := os.Args[1] - if _, err := os.Stat(jsonFile); os.IsNotExist(err) { - fmt.Printf("File '%s' not found.\n", jsonFile) - return - } - - exportPath := defaultExportName - if len(os.Args) == 3 { - exportPath = os.Args[2] - } - - err := report.ConvertGinkgoReportToMarkdown(jsonFile, exportPath) - if err != nil { - fmt.Printf("Error: %s\n", err) - return - } + cmd.Execute() } diff --git a/report/markdown.go b/report/markdown.go index 0118e7e..9c0ac1f 100644 --- a/report/markdown.go +++ b/report/markdown.go @@ -15,18 +15,18 @@ const spacesPerIndentation = " " func ConvertGinkgoReportToMarkdown(jsonFile, markdownFile string) error { reports, err := GetReportsFromJSON(jsonFile) if err != nil { - return fmt.Errorf("error parsing JSON: %w\n", err) + return fmt.Errorf("error parsing JSON: %w", err) } spec, err := buildSpecMap(reports) if err != nil { - return fmt.Errorf("Error building spec map: %w\n", err) + return fmt.Errorf("error building spec map: %w", err) } markdownContents := buildMarkdown(spec, 0) - err = os.WriteFile(markdownFile, []byte(markdownContents), 0o644) + err = os.WriteFile(markdownFile, []byte(markdownContents), 0o600) if err != nil { - return fmt.Errorf("Error writing file: %w\n", err) + return fmt.Errorf("error writing file: %w", err) } fmt.Printf("Markdown file '%s' generated successfully.\n", markdownFile) @@ -49,7 +49,7 @@ func buildSpecMap(reports []ginkgotypes.Report) (map[string]interface{}, error) case ginkgotypes.NodeTypeIt: leafNodeTypeStr = "it" default: - panic(fmt.Sprintf("Unknown leaf node type: %d", leafNodeType)) + return nil, fmt.Errorf("unknown leaf node type: %d", leafNodeType) } leafNodeText := specReport.LeafNodeText diff --git a/report/report.go b/report/report.go index 8f334f3..7e3553c 100644 --- a/report/report.go +++ b/report/report.go @@ -15,12 +15,12 @@ import ( func GetReportsFromJSON(jsonFile string) ([]ginkgotypes.Report, error) { reportBytes, err := os.ReadFile(jsonFile) if err != nil { - return nil, fmt.Errorf("error reading file: %w\n", err) + return nil, fmt.Errorf("error reading file: %w", err) } var reports []ginkgotypes.Report if err := json.Unmarshal(reportBytes, &reports); err != nil { - return nil, fmt.Errorf("error parsing JSON: %w\n", err) + return nil, fmt.Errorf("error parsing JSON: %w", err) } return reports, nil diff --git a/report/report_test.go b/report/report_test.go index 1f53dab..1b0df9d 100644 --- a/report/report_test.go +++ b/report/report_test.go @@ -3,7 +3,9 @@ package report_test import ( "testing" + //nolint:revive // Okay to use dot imports for Ginkgo . "github.com/onsi/ginkgo/v2" + //nolint:revive // Okay to use dot imports for Ginkgo . "github.com/onsi/gomega" "github.com/MalteHerrmann/ginkgo-parser/report"