Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support json output format on argo lint Fixes #14035 #14041

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/argo/commands/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func NewLintCommand() *cobra.Command {
strict bool
lintKinds []string
output = common.EnumFlagValue{
AllowedValues: []string{"pretty", "simple"},
AllowedValues: []string{"pretty", "simple", "json"},
Value: "pretty",
}
offline bool
Expand Down
56 changes: 56 additions & 0 deletions cmd/argo/lint/formatter_json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package lint

import (
"encoding/json"
"fmt"
)

// JsonLintResult is the intermediate struct to convert result to json
type JsonLintResult struct {
File string `json:"file"`
ErrsStr []string `json:"errors"`
Linted bool `json:"linted"`
}

// JsonLintResults is the intermediate struct to convert results to json
type JsonLintResults struct {
Results []*JsonLintResult `json:"results"`
Success bool `json:"success"`
AnythingLinted bool `json:"anything_linted"`
}

type formatterJson struct{}

func (f formatterJson) Format(l *LintResult) string {
return ""
}

func (f formatterJson) Summarize(l *LintResults) string {
b, err := json.Marshal(toJsonResultStruct(l))
if err != nil {
return fmt.Sprintf("Failed to marshal results to JSON: %e", err)
}
return string(b)
}

func toJsonResultStruct(l *LintResults) *JsonLintResults {
jsonLintResults := &JsonLintResults{
Results: make([]*JsonLintResult, len(l.Results)),
Success: l.Success,
AnythingLinted: l.anythingLinted,
}

for i, lr := range l.Results {
errStrs := make([]string, len(lr.Errs))
for j, err := range lr.Errs {
errStrs[j] = err.Error()
}
jsonLintResults.Results[i] = &JsonLintResult{
File: lr.File,
Linted: lr.Linted,
ErrsStr: errStrs,
}
}

return jsonLintResults
}
50 changes: 50 additions & 0 deletions cmd/argo/lint/formatter_json_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package lint

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
)

func TestJsonSummarize(t *testing.T) {
t.Run("Success", func(t *testing.T) {
msg := formatterJson{}.Summarize(&LintResults{
Success: true,
Results: []*LintResult{
{
File: "test1",
Errs: []error{
fmt.Errorf("some error"),
},
Linted: true,
},
},
})
expected := "{\"results\":[{\"file\":\"test1\",\"errors\":[\"some error\"],\"linted\":true}],\"success\":true,\"anything_linted\":false}"
assert.Equal(t, expected, msg)
})
t.Run("Nothing linted", func(t *testing.T) {
msg := formatterJson{}.Summarize(&LintResults{
anythingLinted: false,
Success: false,
})
expected := "{\"results\":[],\"success\":false,\"anything_linted\":false}"
assert.Equal(t, expected, msg)
})
}

func TestJsonFormat(t *testing.T) {
t.Run("Error Exists", func(t *testing.T) {
msg := formatterJson{}.Format(&LintResult{
File: "test1",
Errs: []error{
fmt.Errorf("some error"),
fmt.Errorf("some error2"),
},
Linted: true,
})
expected := ""
assert.Equal(t, expected, msg)
})
}
1 change: 1 addition & 0 deletions cmd/argo/lint/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ var (
formatters = map[string]Formatter{
"pretty": formatterPretty{},
"simple": formatterSimple{},
"json": formatterJson{},
}
)

Expand Down
5 changes: 5 additions & 0 deletions cmd/argo/lint/lint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ func TestGetFormatter(t *testing.T) {
expectedErr: nil,
expectedOutput: (&LintResults{fmtr: formatterSimple{}}).buildMsg(),
},
"json": {
formatterName: "json",
expectedErr: nil,
expectedOutput: (&LintResults{fmtr: formatterJson{}}).buildMsg(),
},
"unknown name": {
formatterName: "foo",
expectedErr: fmt.Errorf("unknown formatter: foo"),
Expand Down
2 changes: 1 addition & 1 deletion docs/cli/argo_lint.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ argo lint FILE... [flags]
--kinds strings Which kinds will be linted. Can be: workflows|workflowtemplates|cronworkflows|clusterworkflowtemplates (default [all])
--no-color Disable colorized output
--offline perform offline linting. For resources referencing other resources, the references will be resolved from the provided args
-o, --output string Linting results output format. One of: pretty|simple (default "pretty")
-o, --output string Linting results output format. One of: pretty|simple|json (default "pretty")
--strict Perform strict workflow validation (default true)
```

Expand Down
Loading