Skip to content

Commit

Permalink
Describe valid project name on error
Browse files Browse the repository at this point in the history
PR #261 changed `docker compose` behavior to require normalized project
names as input, instead of normalizing project names automatically. This
landed in compose-spec/compose-go v1.2.5 and docker/compose v2.5.1.

However, the previous error message gave no indication why a name isn't
valid.  This is surprising for users whose previously working project
names no longer work with newer versions of `docker compose`.

As of compose-spec/compose-spec#314, the spec now contains the text:

> Project name MUST contain only lowercase letters, decimal digits,
> dashes, and underscores, and MUST begin with a lowercase letter or
> decimal digit.

This updated error message provides a concise version of this
requirement based on regular expression character range notation.

See also:

- compose-spec/compose-spec#311
- docker/compose#9741

Signed-off-by: Mike Bland <mbland@acm.org>
  • Loading branch information
mbland committed Mar 3, 2023
1 parent 5837d67 commit e2729c4
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 5 deletions.
3 changes: 2 additions & 1 deletion cli/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ func NewProjectOptions(configs []string, opts ...ProjectOptionsFn) (*ProjectOpti
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)
return fmt.Errorf("%q is not a valid project name: it must contain " +
"only characters from [a-z0-9_-] and start with [a-z0-9]", name)
}
o.Name = name
return nil
Expand Down
8 changes: 4 additions & 4 deletions cli/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestProjectName(t *testing.T) {

t.Run("by name start with invalid char '-'", func(t *testing.T) {
_, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("-my_project"))
assert.Error(t, err, `"-my_project" is not a valid project name`)
assert.ErrorContains(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"),
Expand All @@ -67,7 +67,7 @@ func TestProjectName(t *testing.T) {

t.Run("by name start with invalid char '_'", func(t *testing.T) {
_, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("_my_project"))
assert.Error(t, err, `"_my_project" is not a valid project name`)
assert.ErrorContains(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"),
Expand All @@ -80,7 +80,7 @@ func TestProjectName(t *testing.T) {

t.Run("by name contains dots", func(t *testing.T) {
_, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("www.my.project"))
assert.Error(t, err, `"www.my.project" is not a valid project name`)
assert.ErrorContains(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"),
Expand All @@ -93,7 +93,7 @@ func TestProjectName(t *testing.T) {

t.Run("by name uppercase", func(t *testing.T) {
_, err := NewProjectOptions([]string{"testdata/simple/compose.yaml"}, WithName("MY_PROJECT"))
assert.Error(t, err, `"MY_PROJECT" is not a valid project name`)
assert.ErrorContains(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"),
Expand Down

0 comments on commit e2729c4

Please sign in to comment.