Skip to content

Commit

Permalink
Added generate-ignorefile command to generate an ignorefile.yaml from…
Browse files Browse the repository at this point in the history
… a lint report.json file
  • Loading branch information
Calvin Lobo authored and daveshanley committed Jan 2, 2025
1 parent dc29a0b commit 9e67e6c
Show file tree
Hide file tree
Showing 4 changed files with 481 additions and 0 deletions.
120 changes: 120 additions & 0 deletions cmd/generate_ignorefile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright 2022 Dave Shanley / Quobix
// SPDX-License-Identifier: MIT

package cmd

import (
"encoding/json"
"errors"
"fmt"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"io"
"log"
"os"
)

func GetGenerateIgnoreFileCommand() *cobra.Command {

// LintResult represents a single linting result
type LintResult struct {
Path string `json:"path"`
RuleID string `json:"ruleId"`
}

type LintReport struct {
ResultSet struct {
Results []LintResult `json:"results"`
} `json:"resultSet"`
}

// RulePathsMap is the structure for YAML output
type RulePathsMap map[string][]string

cmd := &cobra.Command{
SilenceUsage: true,
SilenceErrors: true,
Use: "generate-ignorefile",
Short: "Generate an ignorefile from a lint report",
Long: "Generate an ignorefile from a lint report. An ignorefile is used to ignore specific errors from the lint results.",
Example: "vacuum generate-ignorefile <report-file-name.json> <output-ignore-file-name.yaml>",
RunE: func(cmd *cobra.Command, args []string) error {

PrintBanner()

// check for report file args
if len(args) < 1 {
errText := "please supply the lint report file"
pterm.Error.Println(errText)
pterm.Println()
return errors.New(errText)
}

lintReportPath := args[0]
_, err := os.Stat(lintReportPath)
if os.IsNotExist(err) {
errText := fmt.Sprintf("cannot find lint report file at '%s'", lintReportPath)
pterm.Error.Println(errText)
pterm.Println()
return errors.New(errText)
}

outputFile := "ignorefile.yaml"
if len(args) == 2 {
outputFile = args[1]
}

pterm.Info.Printf("Generating Ignorefile from lint errors in: %s", lintReportPath)
pterm.Println()

// Read JSON file
jsonFile, err := os.Open(lintReportPath)
if err != nil {
log.Fatalf("Failed to open JSON file: %v", err)
}
defer jsonFile.Close()

byteValue, err := io.ReadAll(jsonFile)
if err != nil {
log.Fatalf("Failed to read JSON file: %v", err)
}

// Parse JSON into a slice of LintResult
var lintReport LintReport
if err := json.Unmarshal(byteValue, &lintReport); err != nil {
log.Fatalf("Failed to parse JSON: %v", err)
}

// Organize paths by rule ID
rulePaths := make(RulePathsMap)
for _, result := range lintReport.ResultSet.Results {
rulePaths[result.RuleID] = append(rulePaths[result.RuleID], result.Path)
}

// Convert to YAML format
yamlData, err := yaml.Marshal(rulePaths)
if err != nil {
log.Fatalf("Failed to convert to YAML: %v", err)
}

outFile, err := os.Create(outputFile)
if err != nil {
log.Fatalf("Failed to open write file: %v", err)
}
defer outFile.Close()

// Write YAML data to file
_, err = outFile.Write(yamlData)
if err != nil {
log.Fatalf("Failed to write YAML file: %v", err)
}

pterm.Success.Printf("Ingorefile generated at '%s'\n", outputFile)
pterm.Println()

return nil
},
}
return cmd
}
57 changes: 57 additions & 0 deletions cmd/generate_ignorefile_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package cmd

import (
"bytes"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"io"
"os"
"testing"
)

func TestGenerateIgnoreFileCommand(t *testing.T) {
outputFile := "/tmp/ignorefile.yaml"

cmd := GetGenerateIgnoreFileCommand()
b := bytes.NewBufferString("")
cmd.SetOut(b)
cmd.SetArgs([]string{
"./test_data/vacuum-report.json",
outputFile,
})
cmdErr := cmd.Execute()
outBytes, err := io.ReadAll(b)

assert.NoError(t, cmdErr)
assert.NoError(t, err)
assert.NotNil(t, outBytes)

defer os.Remove(outputFile)

ignoreFileBytes, err := os.ReadFile(outputFile)
assert.NoError(t, err)

ignorefileValues := map[string][]string{}
err = yaml.Unmarshal(ignoreFileBytes, &ignorefileValues)
assert.NoError(t, err)

expectedIgnorefileValues := map[string][]string{
"oas3-missing-example": {
"$.components.schemas['Error']",
"$.components.schemas['Burger']",
"$.components.schemas['Fries']",
"$.components.schemas['Fries'].properties['seasoning']",
"$.components.schemas['Dressing']",
"$.components.schemas['Drink']",
},
"oas3-unused-component": {
"$.components.schemas['Error']",
"$.components.schemas['Burger']",
"$.components.schemas['Fries']",
"$.components.schemas['Dressing']",
"$.components.schemas['Drink']",
},
}
assert.Equal(t, expectedIgnorefileValues, ignorefileValues)

}
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func GetRootCommand() *cobra.Command {
rootCmd.AddCommand(GetHTMLReportCommand())
rootCmd.AddCommand(GetDashboardCommand())
rootCmd.AddCommand(GetGenerateRulesetCommand())
rootCmd.AddCommand(GetGenerateIgnoreFileCommand())
rootCmd.AddCommand(GetGenerateVersionCommand())
rootCmd.AddCommand(GetLanguageServerCommand())
rootCmd.AddCommand(GetBundleCommand())
Expand Down
Loading

0 comments on commit 9e67e6c

Please sign in to comment.