diff --git a/internal/app/cmd/validate.go b/internal/app/cmd/validate.go index 474ff56f..564922cc 100644 --- a/internal/app/cmd/validate.go +++ b/internal/app/cmd/validate.go @@ -50,12 +50,13 @@ func validate(dir, path string, isWorkflow, isAction bool) error { kind = "action" } if err != nil { - fmt.Printf("%s %s schema validation failed:\n%s\n", shortPath, kind, err.Error()) + err = fmt.Errorf("%s %s schema validation failed:\n%s", shortPath, kind, err.Error()) + fmt.Printf("%s\n", err.Error()) } else { fmt.Printf("%s %s schema validation OK\n", shortPath, kind) } - return nil + return err } func validatePath(validateArgs *validateArgs) error { @@ -65,8 +66,17 @@ func validatePath(validateArgs *validateArgs) error { return validate("", validateArgs.path, validateArgs.workflow, validateArgs.action) } -func validateHasYamlSuffix(s, suffix string) bool { - return strings.HasSuffix(s, suffix+".yml") || strings.HasSuffix(s, suffix+".yaml") +func validatePathMatch(existing, search string) bool { + if !validateHasYamlSuffix(existing) { + return false + } + existing = strings.TrimSuffix(existing, ".yml") + existing = strings.TrimSuffix(existing, ".yaml") + return existing == search || strings.HasSuffix(existing, "/"+search) +} + +func validateHasYamlSuffix(s string) bool { + return strings.HasSuffix(s, ".yml") || strings.HasSuffix(s, ".yaml") } func validateRepository(validateArgs *validateArgs) error { @@ -106,15 +116,17 @@ func validateRepository(validateArgs *validateArgs) error { } } + var validationErrors error + if err := filepath.Walk(clonedir, func(path string, fi fs.FileInfo, err error) error { - if validateHasYamlSuffix(path, "/.forgejo/workflows/action") { + if validatePathMatch(path, ".forgejo/workflows/action") { return nil } isWorkflow := false isAction := true - if validateHasYamlSuffix(path, "/action") { + if validatePathMatch(path, "action") { if err := validate(clonedir, path, isWorkflow, isAction); err != nil { - return err + validationErrors = errors.Join(validationErrors, err) } } return nil @@ -132,9 +144,9 @@ func validateRepository(validateArgs *validateArgs) error { if err := filepath.Walk(workflowdir, func(path string, fi fs.FileInfo, err error) error { isWorkflow := true isAction := false - if validateHasYamlSuffix(path, "") { + if validateHasYamlSuffix(path) { if err := validate(clonedir, path, isWorkflow, isAction); err != nil { - return err + validationErrors = errors.Join(validationErrors, err) } } return nil @@ -143,7 +155,7 @@ func validateRepository(validateArgs *validateArgs) error { } } - return nil + return validationErrors } func processDirectory(validateArgs *validateArgs) { diff --git a/internal/app/cmd/validate_test.go b/internal/app/cmd/validate_test.go index 8a7c6c71..9b132d9f 100644 --- a/internal/app/cmd/validate_test.go +++ b/internal/app/cmd/validate_test.go @@ -10,6 +10,15 @@ import ( "github.com/stretchr/testify/assert" ) +func Test_validatePathMatch(t *testing.T) { + assert.False(t, validatePathMatch("nosuffix", "nosuffix")) + assert.True(t, validatePathMatch("something.yml", "something")) + assert.True(t, validatePathMatch("something.yaml", "something")) + assert.False(t, validatePathMatch("entire_something.yaml", "something")) + assert.True(t, validatePathMatch("nested/in/directory/something.yaml", "something")) + assert.False(t, validatePathMatch("nested/in/directory/entire_something.yaml", "something")) +} + func Test_validateCmd(t *testing.T) { ctx := context.Background() for _, testCase := range []struct { @@ -47,9 +56,10 @@ func Test_validateCmd(t *testing.T) { stdOut: "schema validation OK", }, { - name: "PathActionNOK", - args: []string{"--action", "--path", "testdata/validate/bad-action.yml"}, - stdOut: "Expected a mapping got scalar", + name: "PathActionNOK", + args: []string{"--action", "--path", "testdata/validate/bad-action.yml"}, + stdOut: "Expected a mapping got scalar", + message: "testdata/validate/bad-action.yml action schema validation failed", }, { name: "PathWorkflowOK", @@ -57,9 +67,10 @@ func Test_validateCmd(t *testing.T) { stdOut: "schema validation OK", }, { - name: "PathWorkflowNOK", - args: []string{"--workflow", "--path", "testdata/validate/bad-workflow.yml"}, - stdOut: "Unknown Property ruins-on", + name: "PathWorkflowNOK", + args: []string{"--workflow", "--path", "testdata/validate/bad-workflow.yml"}, + stdOut: "Unknown Property ruins-on", + message: "testdata/validate/bad-workflow.yml workflow schema validation failed", }, { name: "DirectoryOK", @@ -67,14 +78,16 @@ func Test_validateCmd(t *testing.T) { stdOut: "action.yml action schema validation OK\nsubaction/action.yaml action schema validation OK\n.forgejo/workflows/action.yml workflow schema validation OK\n.forgejo/workflows/workflow1.yml workflow schema validation OK\n.forgejo/workflows/workflow2.yaml workflow schema validation OK", }, { - name: "DirectoryActionNOK", - args: []string{"--directory", "testdata/validate/bad-directory"}, - stdOut: "action.yml action schema validation failed", + name: "DirectoryActionNOK", + args: []string{"--directory", "testdata/validate/bad-directory"}, + stdOut: "action.yml action schema validation failed", + message: "action.yml action schema validation failed", }, { - name: "DirectoryWorkflowNOK", - args: []string{"--directory", "testdata/validate/bad-directory"}, - stdOut: ".forgejo/workflows/workflow1.yml workflow schema validation failed", + name: "DirectoryWorkflowNOK", + args: []string{"--directory", "testdata/validate/bad-directory"}, + stdOut: ".forgejo/workflows/workflow1.yml workflow schema validation failed", + message: ".forgejo/workflows/workflow1.yml workflow schema validation failed", }, { name: "RepositoryOK", @@ -82,14 +95,16 @@ func Test_validateCmd(t *testing.T) { stdOut: "action.yml action schema validation OK\nsubaction/action.yaml action schema validation OK\n.forgejo/workflows/action.yml workflow schema validation OK\n.forgejo/workflows/workflow1.yml workflow schema validation OK\n.forgejo/workflows/workflow2.yaml workflow schema validation OK", }, { - name: "RepositoryActionNOK", - args: []string{"--repository", "testdata/validate/bad-repository"}, - stdOut: "action.yml action schema validation failed", + name: "RepositoryActionNOK", + args: []string{"--repository", "testdata/validate/bad-repository"}, + stdOut: "action.yml action schema validation failed", + message: "action.yml action schema validation failed", }, { - name: "RepositoryWorkflowNOK", - args: []string{"--repository", "testdata/validate/bad-repository"}, - stdOut: ".forgejo/workflows/workflow1.yml workflow schema validation failed", + name: "RepositoryWorkflowNOK", + args: []string{"--repository", "testdata/validate/bad-repository"}, + stdOut: ".forgejo/workflows/workflow1.yml workflow schema validation failed", + message: ".forgejo/workflows/workflow1.yml workflow schema validation failed", }, } { t.Run(testCase.name, func(t *testing.T) {