Skip to content

Commit

Permalink
Check an explicit project name is valid
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
  • Loading branch information
ndeloof committed May 17, 2022
1 parent 771cf87 commit 79a1c00
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 19 deletions.
3 changes: 3 additions & 0 deletions cli/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ func NewProjectOptions(configs []string, opts ...ProjectOptionsFn) (*ProjectOpti
// WithName defines ProjectOptions' name
func WithName(name string) ProjectOptionsFn {
return func(o *ProjectOptions) error {
if name != loader.NormalizeProjectName(name) {
return fmt.Errorf("%q is not a valid project name", name)
}
o.Name = name
return nil
}
Expand Down
36 changes: 20 additions & 16 deletions cli/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,47 +52,51 @@ func TestProjectName(t *testing.T) {
})

t.Run("by name start with invalid char '-'", func(t *testing.T) {
opts, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("-my_project"))
assert.NilError(t, err)
p, err := ProjectFromOptions(opts)
assert.NilError(t, err)
assert.Equal(t, p.Name, "my_project")
_, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("-my_project"))
assert.Error(t, err, `"-my_project" is not a valid project name`)

opts, err = NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithEnv([]string{
opts, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithEnv([]string{
fmt.Sprintf("%s=%s", consts.ComposeProjectName, "-my_project"),
}))
assert.NilError(t, err)
p, err = ProjectFromOptions(opts)
p, err := ProjectFromOptions(opts)
assert.NilError(t, err)
assert.Equal(t, p.Name, "my_project")
})

t.Run("by name start with invalid char '_'", func(t *testing.T) {
opts, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("_my_project"))
assert.NilError(t, err)
p, err := ProjectFromOptions(opts)
assert.NilError(t, err)
assert.Equal(t, p.Name, "my_project")
_, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("_my_project"))
assert.Error(t, err, `"_my_project" is not a valid project name`)

opts, err = NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithEnv([]string{
opts, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithEnv([]string{
fmt.Sprintf("%s=%s", consts.ComposeProjectName, "_my_project"),
}))
assert.NilError(t, err)
p, err = ProjectFromOptions(opts)
p, err := ProjectFromOptions(opts)
assert.NilError(t, err)
assert.Equal(t, p.Name, "my_project")
})

t.Run("by name contains dots", func(t *testing.T) {
opts, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("www.my.project"))
_, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("www.my.project"))
assert.Error(t, err, `"www.my.project" is not a valid project name`)

opts, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithEnv([]string{
fmt.Sprintf("%s=%s", consts.ComposeProjectName, "www.my.project"),
}))
assert.NilError(t, err)
p, err := ProjectFromOptions(opts)
assert.NilError(t, err)
assert.Equal(t, p.Name, "wwwmyproject")
})

t.Run("by name uppercase", func(t *testing.T) {
opts, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("MY_PROJECT"))
_, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("MY_PROJECT"))
assert.Error(t, err, `"MY_PROJECT" is not a valid project name`)

opts, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithEnv([]string{
fmt.Sprintf("%s=%s", consts.ComposeProjectName, "_my_project"),
}))
assert.NilError(t, err)
p, err := ProjectFromOptions(opts)
assert.NilError(t, err)
Expand Down
6 changes: 3 additions & 3 deletions loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ type Options struct {
}

func (o *Options) SetProjectName(name string, imperativelySet bool) {
o.projectName = normalizeProjectName(name)
o.projectName = NormalizeProjectName(name)
o.projectNameImperativelySet = imperativelySet
}

Expand Down Expand Up @@ -208,7 +208,7 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.
}

projectName, projectNameImperativelySet := opts.GetProjectName()
model.Name = normalizeProjectName(model.Name)
model.Name = NormalizeProjectName(model.Name)
if !projectNameImperativelySet && model.Name != "" {
projectName = model.Name
}
Expand Down Expand Up @@ -245,7 +245,7 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.
return project, nil
}

func normalizeProjectName(s string) string {
func NormalizeProjectName(s string) string {
r := regexp.MustCompile("[a-z0-9_-]")
s = strings.ToLower(s)
s = strings.Join(r.FindAllString(s, -1), "")
Expand Down

0 comments on commit 79a1c00

Please sign in to comment.