From ccbff00bfd25bbcd44b3818b19e74371facba64c Mon Sep 17 00:00:00 2001 From: mingfu Date: Wed, 18 Oct 2023 09:51:07 +0800 Subject: [PATCH] feat: add common slice helper functions --- .../v1alpha1/zz_generated.deepcopy.go | 30 ++++ apis/meta/v1alpha1/gitoption_types.go | 12 -- apis/meta/v1alpha1/gitrepositories_types.go | 19 +++ apis/meta/v1alpha1/gittag_types.go | 50 +++++++ apis/meta/v1alpha1/gittag_types_test.go | 83 +++++++++++ apis/meta/v1alpha1/zz_generated.deepcopy.go | 107 +++++++++++++- plugin/client/interface.go | 12 ++ secret/mutate_test.go | 3 +- slices/slices.go | 28 ++++ slices/slices_test.go | 134 ++++++++++++++++++ 10 files changed, 460 insertions(+), 18 deletions(-) create mode 100644 apis/meta/v1alpha1/gittag_types.go create mode 100644 apis/meta/v1alpha1/gittag_types_test.go create mode 100644 slices/slices.go create mode 100644 slices/slices_test.go diff --git a/apis/artifacts/v1alpha1/zz_generated.deepcopy.go b/apis/artifacts/v1alpha1/zz_generated.deepcopy.go index 6428fdfa..6e673a65 100644 --- a/apis/artifacts/v1alpha1/zz_generated.deepcopy.go +++ b/apis/artifacts/v1alpha1/zz_generated.deepcopy.go @@ -71,6 +71,21 @@ func (in *AnyFilter) DeepCopy() *AnyFilter { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArtifactTypeBinaryProperties) DeepCopyInto(out *ArtifactTypeBinaryProperties) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArtifactTypeBinaryProperties. +func (in *ArtifactTypeBinaryProperties) DeepCopy() *ArtifactTypeBinaryProperties { + if in == nil { + return nil + } + out := new(ArtifactTypeBinaryProperties) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ArtifactVersion) DeepCopyInto(out *ArtifactVersion) { *out = *in @@ -187,6 +202,21 @@ func (in *EnvFilter) DeepCopy() *EnvFilter { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FileUploadBinaryProperties) DeepCopyInto(out *FileUploadBinaryProperties) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FileUploadBinaryProperties. +func (in *FileUploadBinaryProperties) DeepCopy() *FileUploadBinaryProperties { + if in == nil { + return nil + } + out := new(FileUploadBinaryProperties) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FileUploadParams) DeepCopyInto(out *FileUploadParams) { *out = *in diff --git a/apis/meta/v1alpha1/gitoption_types.go b/apis/meta/v1alpha1/gitoption_types.go index f0019443..588eee84 100644 --- a/apis/meta/v1alpha1/gitoption_types.go +++ b/apis/meta/v1alpha1/gitoption_types.go @@ -57,18 +57,6 @@ type GitPullRequestOption struct { Index int `json:"Index"` } -// GitRepositoryTagOption option for repository tag -type GitRepositoryTagOption struct { - GitRepo - // Tag the name of the tag - Tag string `json:"tag"` -} - -// GitRepositoryTagListOption option for list repository tag -type GitRepositoryTagListOption struct { - GitRepo -} - type PullRequestState string const ( diff --git a/apis/meta/v1alpha1/gitrepositories_types.go b/apis/meta/v1alpha1/gitrepositories_types.go index d14f1618..4263e5ed 100644 --- a/apis/meta/v1alpha1/gitrepositories_types.go +++ b/apis/meta/v1alpha1/gitrepositories_types.go @@ -74,3 +74,22 @@ func GitRepositoryResourceAttributes(verb string) authv1.ResourceAttributes { Verb: verb, } } + +// GitRepositoryVisibility visibility of repository +type GitRepositoryVisibility string + +const ( + // GitRepositoryVisibilityPrivate private repository + GitRepositoryVisibilityPrivate GitRepositoryVisibility = "private" + // GitRepositoryVisibilityPublic public repository + GitRepositoryVisibilityPublic GitRepositoryVisibility = "public" +) + +// CreateGitRepositoryPayload payload for create repository +type CreateGitRepositoryPayload struct { + GitRepo + + DisplayName string `json:"displayName"` + Visibility GitRepositoryVisibility `json:"visibility"` + AutoInit bool `json:"autoInit"` +} diff --git a/apis/meta/v1alpha1/gittag_types.go b/apis/meta/v1alpha1/gittag_types.go new file mode 100644 index 00000000..e482fc0f --- /dev/null +++ b/apis/meta/v1alpha1/gittag_types.go @@ -0,0 +1,50 @@ +/* +Copyright 2023 The Katanomi Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import "errors" + +// GitRepositoryTagOption option for repository tag +// Deprecated: use GitTag instead +type GitRepositoryTagOption struct { + GitRepo + // Tag the name of the tag + Tag string `json:"tag"` +} + +// GitRepositoryTagListOption option for list repository tag +type GitRepositoryTagListOption struct { + GitRepo +} + +// GitTag describe a unique tag +type GitTag struct { + GitRepo + // Tag the name of the tag + Tag string `json:"tag"` +} + +// Validate validate the git repo +func (r *GitTag) Validate() error { + if err := r.GitRepo.Validate(); err != nil { + return err + } + if r.Tag == "" { + return errors.New("tag is empty") + } + return nil +} diff --git a/apis/meta/v1alpha1/gittag_types_test.go b/apis/meta/v1alpha1/gittag_types_test.go new file mode 100644 index 00000000..d0fd2501 --- /dev/null +++ b/apis/meta/v1alpha1/gittag_types_test.go @@ -0,0 +1,83 @@ +/* +Copyright 2023 The Katanomi Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "testing" + + . "github.com/onsi/gomega" +) + +func TestGitTag_Validate(t *testing.T) { + g := NewWithT(t) + testCases := map[string]struct { + gitTag GitTag + wantErr bool + wantErrMsg string + }{ + "project is empty": { + gitTag: GitTag{ + GitRepo: GitRepo{}, + Tag: "", + }, + wantErr: true, + wantErrMsg: "project is empty", + }, + "repository is empty": { + gitTag: GitTag{ + GitRepo: GitRepo{ + Project: "abc", + }, + Tag: "", + }, + wantErr: true, + wantErrMsg: "repository is empty", + }, + "tag is empty": { + gitTag: GitTag{ + GitRepo: GitRepo{ + Project: "abc", + Repository: "abc", + }, + Tag: "", + }, + wantErr: true, + wantErrMsg: "tag is empty", + }, + "valid case": { + gitTag: GitTag{ + GitRepo: GitRepo{ + Project: "abc", + Repository: "abc", + }, + Tag: "v0.0.1", + }, + wantErr: false, + }, + } + for _, testCase := range testCases { + t.Run(testCase.wantErrMsg, func(t *testing.T) { + err := testCase.gitTag.Validate() + if !testCase.wantErr { + g.Expect(err).Should(Succeed()) + } else { + g.Expect(err).Should(HaveOccurred()) + g.Expect(err.Error()).Should(ContainSubstring(testCase.wantErrMsg)) + } + }) + } +} diff --git a/apis/meta/v1alpha1/zz_generated.deepcopy.go b/apis/meta/v1alpha1/zz_generated.deepcopy.go index 2085e214..592d992c 100644 --- a/apis/meta/v1alpha1/zz_generated.deepcopy.go +++ b/apis/meta/v1alpha1/zz_generated.deepcopy.go @@ -1447,6 +1447,22 @@ func (in *CreateCommitStatusPayload) DeepCopy() *CreateCommitStatusPayload { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CreateGitRepositoryPayload) DeepCopyInto(out *CreateGitRepositoryPayload) { + *out = *in + out.GitRepo = in.GitRepo +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CreateGitRepositoryPayload. +func (in *CreateGitRepositoryPayload) DeepCopy() *CreateGitRepositoryPayload { + if in == nil { + return nil + } + out := new(CreateGitRepositoryPayload) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CreatePullRequestCommentParam) DeepCopyInto(out *CreatePullRequestCommentParam) { *out = *in @@ -2770,6 +2786,22 @@ func (in *GitRevisionSpec) DeepCopy() *GitRevisionSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GitTag) DeepCopyInto(out *GitTag) { + *out = *in + out.GitRepo = in.GitRepo +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitTag. +func (in *GitTag) DeepCopy() *GitTag { + if in == nil { + return nil + } + out := new(GitTag) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GitUserBaseInfo) DeepCopyInto(out *GitUserBaseInfo) { *out = *in @@ -3002,6 +3034,7 @@ func (in *ListMeta) DeepCopy() *ListMeta { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ListOptions) DeepCopyInto(out *ListOptions) { *out = *in + in.SubResourcesOptions.DeepCopyInto(&out.SubResourcesOptions) if in.Search != nil { in, out := &in.Search, &out.Search *out = make(url.Values, len(*in)) @@ -3017,11 +3050,6 @@ func (in *ListOptions) DeepCopyInto(out *ListOptions) { (*out)[key] = outVal } } - if in.SubResources != nil { - in, out := &in.SubResources, &out.SubResources - *out = make([]string, len(*in)) - copy(*out, *in) - } if in.Sort != nil { in, out := &in.Sort, &out.Sort *out = make([]SortOptions, len(*in)) @@ -3191,6 +3219,22 @@ func (in *Project) DeepCopy() *Project { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectArtifactOptions) DeepCopyInto(out *ProjectArtifactOptions) { + *out = *in + in.SubResourcesOptions.DeepCopyInto(&out.SubResourcesOptions) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectArtifactOptions. +func (in *ProjectArtifactOptions) DeepCopy() *ProjectArtifactOptions { + if in == nil { + return nil + } + out := new(ProjectArtifactOptions) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProjectList) DeepCopyInto(out *ProjectList) { *out = *in @@ -3467,6 +3511,26 @@ func (in *SortOptions) DeepCopy() *SortOptions { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubResourcesOptions) DeepCopyInto(out *SubResourcesOptions) { + *out = *in + if in.SubResources != nil { + in, out := &in.SubResources, &out.SubResources + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubResourcesOptions. +func (in *SubResourcesOptions) DeepCopy() *SubResourcesOptions { + if in == nil { + return nil + } + out := new(SubResourcesOptions) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TestBuildStatusInfo) DeepCopyInto(out *TestBuildStatusInfo) { *out = *in @@ -3922,6 +3986,39 @@ func (in *TimeCursor) DeepCopy() *TimeCursor { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ToolMeta) DeepCopyInto(out *ToolMeta) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ToolMeta. +func (in *ToolMeta) DeepCopy() *ToolMeta { + if in == nil { + return nil + } + out := new(ToolMeta) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ToolMetaSpec) DeepCopyInto(out *ToolMetaSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ToolMetaSpec. +func (in *ToolMetaSpec) DeepCopy() *ToolMetaSpec { + if in == nil { + return nil + } + out := new(ToolMetaSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TriggeredBy) DeepCopyInto(out *TriggeredBy) { *out = *in diff --git a/plugin/client/interface.go b/plugin/client/interface.go index 7e0ab3b4..4f9ed979 100644 --- a/plugin/client/interface.go +++ b/plugin/client/interface.go @@ -335,6 +335,18 @@ type GitRepoFileCreator interface { CreateGitRepoFile(ctx context.Context, payload metav1alpha1.CreateRepoFilePayload) (metav1alpha1.GitCommit, error) } +// GitRepositoryCreator create a git repository +type GitRepositoryCreator interface { + Interface + CreateGitRepository(ctx context.Context, payload metav1alpha1.CreateGitRepositoryPayload) (metav1alpha1.GitRepository, error) +} + +// GitRepositoryDeleter delete a git repository +type GitRepositoryDeleter interface { + Interface + DeleteGitRepository(ctx context.Context, gitRepo metav1alpha1.GitRepo) error +} + // GitRepositoryLister list git repository type GitRepositoryLister interface { Interface diff --git a/secret/mutate_test.go b/secret/mutate_test.go index 493c90c3..75f51832 100644 --- a/secret/mutate_test.go +++ b/secret/mutate_test.go @@ -19,10 +19,11 @@ package secret import ( "context" "errors" + "testing" + . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "testing" ) // MockMutator is a mock implementation of the Mutator interface for testing. diff --git a/slices/slices.go b/slices/slices.go new file mode 100644 index 00000000..b16775fc --- /dev/null +++ b/slices/slices.go @@ -0,0 +1,28 @@ +/* +Copyright 2023 The Katanomi Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package slices provides some useful functions for slices +package slices + +// InList check if item in list +func InList[T comparable](list []T, item T) bool { + for _, v := range list { + if v == item { + return true + } + } + return false +} diff --git a/slices/slices_test.go b/slices/slices_test.go new file mode 100644 index 00000000..3addbf16 --- /dev/null +++ b/slices/slices_test.go @@ -0,0 +1,134 @@ +/* +Copyright 2023 The Katanomi Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package slices + +import ( + "testing" +) + +type Person struct { + Name string + Age int +} + +func TestInList_struct(t *testing.T) { + tests := []struct { + name string + list []Person + item Person + want bool + }{ + { + name: "struct in list", + list: []Person{{Name: "Alice", Age: 30}, {Name: "Bob", Age: 40}}, + item: Person{Name: "Bob", Age: 40}, + want: true, + }, + { + name: "struct not in list", + list: []Person{{Name: "Alice", Age: 30}, {Name: "Bob", Age: 40}}, + item: Person{Name: "Charlie", Age: 50}, + want: false, + }, + { + name: "empty list", + list: []Person{}, + item: Person{Name: "Charlie", Age: 60}, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := InList(tt.list, tt.item); got != tt.want { + t.Errorf("[struct]InList() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestInList_string(t *testing.T) { + tests := []struct { + name string + list []string + item string + want bool + }{ + { + name: "item in list", + list: []string{"1", "2", "3"}, + item: "2", + want: true, + }, + { + name: "item not in list", + list: []string{"1", "2", "3"}, + item: "4", + want: false, + }, + { + name: "empty list", + list: []string{}, + item: "1", + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := InList(tt.list, tt.item); got != tt.want { + t.Errorf("[string]InList() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestInList_int(t *testing.T) { + tests := []struct { + name string + list []int + item int + want bool + }{ + { + name: "item in list", + list: []int{1, 2, 3}, + item: 2, + want: true, + }, + { + name: "item not in list", + list: []int{1, 2, 3}, + item: 4, + want: false, + }, + { + name: "empty list", + list: []int{}, + item: 1, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := InList(tt.list, tt.item); got != tt.want { + t.Errorf("[int]InList() = %v, want %v", got, tt.want) + } + }) + } +}