Skip to content

Commit 692a917

Browse files
committed
Add project validations
Signed-off-by: Maysun J Faisal <[email protected]>
1 parent 62a0445 commit 692a917

File tree

4 files changed

+209
-14
lines changed

4 files changed

+209
-14
lines changed

pkg/validation/commands.go

-14
Original file line numberDiff line numberDiff line change
@@ -187,20 +187,6 @@ func validateCompositeCommand(command *v1alpha2.Command, parentCommands map[stri
187187
if err != nil {
188188
return err
189189
}
190-
191-
// if subCommand.Composite != nil {
192-
// // Recursively validate the composite subcommand
193-
// err := validateCompositeCommand(&subCommand, parentCommands, devfileCommands, components)
194-
// if err != nil {
195-
// // Don't wrap the error message here to make the error message more readable to the user
196-
// return err
197-
// }
198-
// } else {
199-
// err := validateCommandComponent(subCommand, components)
200-
// if err != nil {
201-
// return err
202-
// }
203-
// }
204190
}
205191
return nil
206192
}

pkg/validation/projects.go

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package validation
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
7+
)
8+
9+
// ValidateStarterProjects validates the starter projects
10+
func ValidateStarterProjects(starterProject v1alpha2.StarterProject) (err error) {
11+
12+
var gitSource v1alpha2.GitLikeProjectSource
13+
if starterProject.Git != nil {
14+
gitSource = starterProject.Git.GitLikeProjectSource
15+
} else if starterProject.Github != nil {
16+
gitSource = starterProject.Github.GitLikeProjectSource
17+
} else {
18+
return
19+
}
20+
21+
if len(gitSource.Remotes) != 1 {
22+
return fmt.Errorf("starterProject can have only one remote")
23+
} else if gitSource.CheckoutFrom.Remote != "" {
24+
return validateRemoteMap(gitSource.Remotes, gitSource.CheckoutFrom.Remote)
25+
}
26+
27+
return
28+
}
29+
30+
// ValidateProjects validates the projects
31+
func ValidateProjects(project v1alpha2.Project) (err error) {
32+
33+
var gitSource v1alpha2.GitLikeProjectSource
34+
if project.Git != nil {
35+
gitSource = project.Git.GitLikeProjectSource
36+
} else if project.Github != nil {
37+
gitSource = project.Github.GitLikeProjectSource
38+
} else {
39+
return
40+
}
41+
42+
if len(gitSource.Remotes) > 1 || gitSource.CheckoutFrom.Remote != "" {
43+
return validateRemoteMap(gitSource.Remotes, gitSource.CheckoutFrom.Remote)
44+
}
45+
46+
return
47+
}
48+
49+
// validateRemoteMap checks if the checkout remote is present in the project remote map
50+
func validateRemoteMap(remotes map[string]string, checkoutRemote string) (err error) {
51+
52+
if _, ok := remotes[checkoutRemote]; !ok {
53+
return fmt.Errorf("unable to find the checkout remote in project remotes map")
54+
}
55+
56+
return
57+
}

pkg/validation/projects_test.go

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package validation
2+
3+
import (
4+
"testing"
5+
6+
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
7+
)
8+
9+
func generateDummyGitStarterProject(name, checkoutRemote string, remotes map[string]string) v1alpha2.StarterProject {
10+
return v1alpha2.StarterProject{
11+
Name: name,
12+
ProjectSource: v1alpha2.ProjectSource{
13+
Git: &v1alpha2.GitProjectSource{
14+
GitLikeProjectSource: v1alpha2.GitLikeProjectSource{
15+
Remotes: remotes,
16+
CheckoutFrom: &v1alpha2.CheckoutFrom{
17+
Remote: checkoutRemote,
18+
},
19+
},
20+
},
21+
},
22+
}
23+
}
24+
25+
func generateDummyGithubStarterProject(name, checkoutRemote string, remotes map[string]string) v1alpha2.StarterProject {
26+
return v1alpha2.StarterProject{
27+
Name: name,
28+
ProjectSource: v1alpha2.ProjectSource{
29+
Github: &v1alpha2.GithubProjectSource{
30+
GitLikeProjectSource: v1alpha2.GitLikeProjectSource{
31+
Remotes: remotes,
32+
CheckoutFrom: &v1alpha2.CheckoutFrom{
33+
Remote: checkoutRemote,
34+
},
35+
},
36+
},
37+
},
38+
}
39+
}
40+
41+
func generateDummyGitProject(name, checkoutRemote string, remotes map[string]string) v1alpha2.Project {
42+
return v1alpha2.Project{
43+
Name: name,
44+
ProjectSource: v1alpha2.ProjectSource{
45+
Git: &v1alpha2.GitProjectSource{
46+
GitLikeProjectSource: v1alpha2.GitLikeProjectSource{
47+
Remotes: remotes,
48+
CheckoutFrom: &v1alpha2.CheckoutFrom{
49+
Remote: checkoutRemote,
50+
},
51+
},
52+
},
53+
},
54+
}
55+
}
56+
57+
func generateDummyGithubProject(name, checkoutRemote string, remotes map[string]string) v1alpha2.Project {
58+
return v1alpha2.Project{
59+
Name: name,
60+
ProjectSource: v1alpha2.ProjectSource{
61+
Github: &v1alpha2.GithubProjectSource{
62+
GitLikeProjectSource: v1alpha2.GitLikeProjectSource{
63+
Remotes: remotes,
64+
CheckoutFrom: &v1alpha2.CheckoutFrom{
65+
Remote: checkoutRemote,
66+
},
67+
},
68+
},
69+
},
70+
}
71+
}
72+
73+
func TestValidateStarterProjects(t *testing.T) {
74+
75+
tests := []struct {
76+
name string
77+
starterProject v1alpha2.StarterProject
78+
wantErr bool
79+
}{
80+
{
81+
name: "Case 1: Valid Starter Project",
82+
starterProject: generateDummyGitStarterProject("project1", "origin", map[string]string{"origin": "originremote"}),
83+
wantErr: false,
84+
},
85+
{
86+
name: "Case 2: Invalid Starter Project",
87+
starterProject: generateDummyGithubStarterProject("project1", "origin", map[string]string{"origin": "originremote", "test": "testremote"}),
88+
wantErr: true,
89+
},
90+
{
91+
name: "Case 3: Invalid Starter Project with wrong checkout",
92+
starterProject: generateDummyGithubStarterProject("project1", "origin", map[string]string{"test": "testremote"}),
93+
wantErr: true,
94+
},
95+
{
96+
name: "Case 4: Valid Starter Project with empty checkout remote",
97+
starterProject: generateDummyGitStarterProject("project1", "", map[string]string{"origin": "originremote"}),
98+
wantErr: false,
99+
},
100+
}
101+
for _, tt := range tests {
102+
t.Run(tt.name, func(t *testing.T) {
103+
err := ValidateStarterProjects(tt.starterProject)
104+
if !tt.wantErr == (err != nil) {
105+
t.Errorf("TestValidateStarterProjects unexpected error: %v", err)
106+
}
107+
})
108+
}
109+
}
110+
111+
func TestValidateProjects(t *testing.T) {
112+
113+
tests := []struct {
114+
name string
115+
project v1alpha2.Project
116+
wantErr bool
117+
}{
118+
{
119+
name: "Case 1: Valid Project",
120+
project: generateDummyGitProject("project1", "origin", map[string]string{"origin": "originremote"}),
121+
wantErr: false,
122+
},
123+
{
124+
name: "Case 2: Invalid Project with multiple remote and empty checkout remote",
125+
project: generateDummyGithubProject("project1", "", map[string]string{"origin": "originremote", "test": "testremote"}),
126+
wantErr: true,
127+
},
128+
{
129+
name: "Case 3: Invalid Project with wrong checkout",
130+
project: generateDummyGithubProject("project1", "invalidorigin", map[string]string{"origin": "originremote", "test": "testremote"}),
131+
wantErr: true,
132+
},
133+
{
134+
name: "Case 4: Valid Project with empty checkout remote",
135+
project: generateDummyGitProject("project1", "", map[string]string{"origin": "originremote"}),
136+
wantErr: false,
137+
},
138+
}
139+
for _, tt := range tests {
140+
t.Run(tt.name, func(t *testing.T) {
141+
err := ValidateProjects(tt.project)
142+
if !tt.wantErr == (err != nil) {
143+
t.Errorf("TestValidateProjects unexpected error: %v", err)
144+
}
145+
})
146+
}
147+
}

pkg/validation/validation-rule.md

+5
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,8 @@ Common rules for all components types:
5656

5757
### starterProjects:
5858
- Starter project entries cannot have more than one remote defined
59+
- if checkout remote is mentioned, validate it against the starter project remote configured map
60+
61+
### projects
62+
- if more than one remote map is configured, a checkout remote is mandatory
63+
- if checkout remote is mentioned, validate it against the starter project remote configured map

0 commit comments

Comments
 (0)