From ee16b7550be057b6bbf6d6954a8a4097267963fb Mon Sep 17 00:00:00 2001 From: Quan Zhang Date: Fri, 30 Sep 2022 15:54:56 -0400 Subject: [PATCH] [TEP-0115] Git-based Versioning Validation Prior to this change, the Catlin validation only supports directory-based catalog path validation (i.e. ./////.yaml). The git-based versioning catalog is proposed in TEP-0115: https://github.com/tektoncd/community/blob/main/teps/0115-tekton-catalog-git-based-versioning.md. with a new file path layout (i.e. .////.yaml). This commit introduces a new flag `versioning` to the `catlin validate` command, indicating the versioning type of the catalog to validate. The value can be set to either `directory` or `git`. The default value is `directory`. --- .../maven-git-versioning.yaml | 24 +++++++++++++++ .../npm-git-versioning.yaml | 28 +++++++++++++++++ pkg/cmd/validate/validate.go | 30 ++++++++++++++----- pkg/cmd/validate/validate_test.go | 30 +++++++++++++++++++ pkg/validator/file_validator.go | 25 ++++++++++++---- 5 files changed, 125 insertions(+), 12 deletions(-) create mode 100644 pkg/cmd/validate/testdata/task/maven-git-versioning/maven-git-versioning.yaml create mode 100644 pkg/cmd/validate/testdata/task/npm-git-versioning/npm-git-versioning.yaml diff --git a/pkg/cmd/validate/testdata/task/maven-git-versioning/maven-git-versioning.yaml b/pkg/cmd/validate/testdata/task/maven-git-versioning/maven-git-versioning.yaml new file mode 100644 index 00000000..98e3ff5a --- /dev/null +++ b/pkg/cmd/validate/testdata/task/maven-git-versioning/maven-git-versioning.yaml @@ -0,0 +1,24 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: maven-git-versioning + labels: + app.kubernetes.io/version: "0.1" + annotations: + tekton.dev/pipelines.minVersion: "0.12.1" + tekton.dev/tags: build-automation + tekton.dev/categories: Build Tools + tekton.dev/displayName: "maven" +spec: + description: >- + This Task can be used to run a Maven build. + params: + - name: GOALS + type: array + steps: + - name: execute-goals + image: gcr.io/cloud-builders/mvn:3.6.8@sha256:57523fc43394d6d9d2414ee8d1c85ed7a13460cbb268c3cd16d28cfb3859e641 + command: + - mvn + args: + - $(params.GOALS) diff --git a/pkg/cmd/validate/testdata/task/npm-git-versioning/npm-git-versioning.yaml b/pkg/cmd/validate/testdata/task/npm-git-versioning/npm-git-versioning.yaml new file mode 100644 index 00000000..affb9bc1 --- /dev/null +++ b/pkg/cmd/validate/testdata/task/npm-git-versioning/npm-git-versioning.yaml @@ -0,0 +1,28 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: npm-git-versioning + labels: + app.kubernetes.io/version: "0.1" + annotations: + tekton.dev/pipelines.minVersion: "0.17.0" + tekton.dev/tags: build-automation + tekton.dev/categories: Build Tools + tekton.dev/displayName: "npm" +spec: + description: >- + This task can be used to run npm goals on a project. + + This task can be used to run npm goals on a project + where package.json is present and has some pre-defined + npm scripts. + params: + - name: GOALS + type: array + steps: + - name: execute-goals + image: docker.io/library/node:12-alpine@sha256:12048cdfd75d944df35f3144132d9bdeee78015fbd6df765edad1be46599b110 + command: + - npm + args: + - $(params.GOALS) diff --git a/pkg/cmd/validate/validate.go b/pkg/cmd/validate/validate.go index e1c6dd88..303c5400 100644 --- a/pkg/cmd/validate/validate.go +++ b/pkg/cmd/validate/validate.go @@ -81,18 +81,34 @@ func validResourcePath() cobra.PositionalArgs { } } +func validateFlags(cmd *cobra.Command, args []string, versioning string) error { + if versioning != validator.DirectoryBasedVersioning && versioning != validator.GitBasedVersioning { + return fmt.Errorf("invalid versioning: %s, expecting git or directory", versioning) + } + + return nil +} + func Command(cli app.CLI) *cobra.Command { - return &cobra.Command{ + var versioning string + cmd := &cobra.Command{ Use: "validate", Aliases: []string{"verify"}, Args: validResourcePath(), + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + return validateFlags(cmd, args, versioning) + }, RunE: func(cmd *cobra.Command, args []string) error { - return validateResources(cli, args) + return validateResources(cli, args, versioning) }, } + + cmd.PersistentFlags().StringVar(&versioning, "versioning", "directory", "Versioning type of catalog (directory/git)") + + return cmd } -func validateResources(cli app.CLI, args []string) error { +func validateResources(cli app.CLI, args []string, versioning string) error { out := cli.Stream().Out for _, filePath := range args { @@ -113,7 +129,7 @@ func validateResources(cli app.CLI, args []string) error { fileWithPath = fileWithPath + "/" + file.Name() } fmt.Fprintf(out, "FILE: %s\n", fileWithPath) - err = validate(cli, fileWithPath) + err = validate(cli, fileWithPath, versioning) if err != nil { return err } @@ -121,7 +137,7 @@ func validateResources(cli app.CLI, args []string) error { } } else if filepath.Ext(filePath) == ".yaml" { fmt.Fprintf(out, "FILE: %s\n", filePath) - err := validate(cli, filePath) + err := validate(cli, filePath, versioning) if err != nil { return err } @@ -130,7 +146,7 @@ func validateResources(cli app.CLI, args []string) error { return nil } -func validate(cli app.CLI, path string) error { +func validate(cli app.CLI, path, versioning string) error { r, err := os.Open(path) if err != nil { @@ -154,7 +170,7 @@ func validate(cli app.CLI, path string) error { // run validators validators := []validator.Validator{ - validator.NewPathValidator(res, path), + validator.NewPathValidator(res, path, versioning), validator.NewContentValidator(res, cat), validator.ForKind(res), } diff --git a/pkg/cmd/validate/validate_test.go b/pkg/cmd/validate/validate_test.go index 23338722..dafcc681 100644 --- a/pkg/cmd/validate/validate_test.go +++ b/pkg/cmd/validate/validate_test.go @@ -35,12 +35,30 @@ func TestValidate(t *testing.T) { wantError: false, want: "", }, + { + name: "single filepath - with directory versioning flag", + args: []string{"./testdata/task/maven/0.1", "--versioning", "directory"}, + wantError: false, + want: "", + }, + { + name: "single filepath git versioning", + args: []string{"./testdata/task/maven-git-versioning", "--versioning", "git"}, + wantError: false, + want: "", + }, { name: "multiple filepath", args: []string{"./testdata/task/maven/0.1", "./testdata/task/npm/0.1"}, wantError: false, want: "", }, + { + name: "multiple filepath git versioning", + args: []string{"./testdata/task/maven-git-versioning", "./testdata/task/npm-git-versioning", "--versioning", "git"}, + wantError: false, + want: "", + }, } for _, tp := range testParams { @@ -72,6 +90,18 @@ func TestValidateError(t *testing.T) { wantError: true, want: "Error: ./testdata/task/black/0.1/black.yaml failed validation\n", }, + { + name: "versioning mismatch - git versioning", + args: []string{"./testdata/task/maven/0.1", "--versioning", "git"}, + wantError: true, + want: "Error: ./testdata/task/maven/0.1/maven.yaml failed validation\n", + }, + { + name: "versioning mismatch - directory versioning", + args: []string{"./testdata/task/maven-git-versioning", "--versioning", "directory"}, + wantError: true, + want: "Error: ./testdata/task/maven-git-versioning/maven-git-versioning.yaml failed validation\n", + }, } for _, tp := range testParams { diff --git a/pkg/validator/file_validator.go b/pkg/validator/file_validator.go index cd25d124..489ba32c 100644 --- a/pkg/validator/file_validator.go +++ b/pkg/validator/file_validator.go @@ -21,15 +21,21 @@ import ( "github.com/tektoncd/catlin/pkg/parser" ) +const ( + GitBasedVersioning = "git" + DirectoryBasedVersioning = "directory" +) + type PathValidator struct { - path string - res *parser.Resource + path string + versioning string + res *parser.Resource } var _ Validator = (*PathValidator)(nil) -func NewPathValidator(r *parser.Resource, path string) *PathValidator { - return &PathValidator{path: path, res: r} +func NewPathValidator(r *parser.Resource, path, versioning string) *PathValidator { + return &PathValidator{path: path, versioning: versioning, res: r} } func (v *PathValidator) Validate() Result { @@ -46,7 +52,16 @@ func (v *PathValidator) Validate() Result { return result } - expectedPath := filepath.Join(kind, name, version, name+".yaml") + var expectedPath string + switch v.versioning { + case GitBasedVersioning: + expectedPath = filepath.Join(kind, name, name+".yaml") + case DirectoryBasedVersioning: + expectedPath = filepath.Join(kind, name, version, name+".yaml") + default: + result.Error("invalid versioning, expecting git or directory, but got: %s", v.versioning) + return result + } if !strings.HasSuffix(absPath, expectedPath) { result.Error("Resource path is invalid; expected path: %s", expectedPath)