From 487736177e2bdc9f3de0ec57e8e3b98d3d414673 Mon Sep 17 00:00:00 2001 From: mbomb007 <22807401+mbomb007@users.noreply.github.com> Date: Wed, 17 Jul 2024 19:45:47 -0500 Subject: [PATCH] feat: Replace underscores with hyphens in project-name, fixes #6206 (#6210) Co-authored-by: Randy Fay Co-authored-by: Stanislav Zhuk --- cmd/ddev/cmd/config.go | 2 +- pkg/ddevapp/config.go | 7 +++--- pkg/ddevapp/config_test.go | 43 ++++++++++++++++++++++++++++++++++++- pkg/ddevapp/ddevapp.go | 5 +++++ pkg/ddevapp/ddevapp_test.go | 4 +--- 5 files changed, 52 insertions(+), 9 deletions(-) diff --git a/cmd/ddev/cmd/config.go b/cmd/ddev/cmd/config.go index 145247bf8c1..affa7e9c773 100644 --- a/cmd/ddev/cmd/config.go +++ b/cmd/ddev/cmd/config.go @@ -381,7 +381,7 @@ func handleMainConfigArgs(cmd *cobra.Command, _ []string, app *ddevapp.DdevApp) } else { // No siteNameArg passed, c.Name not set: use c.Name from the directory pwd, err := os.Getwd() util.CheckErr(err) - app.Name = filepath.Base(pwd) + app.Name = ddevapp.NormalizeProjectName(filepath.Base(pwd)) } err = app.CheckExistingAppInApproot() diff --git a/pkg/ddevapp/config.go b/pkg/ddevapp/config.go index f1c8cc49e01..0b85f95b97d 100644 --- a/pkg/ddevapp/config.go +++ b/pkg/ddevapp/config.go @@ -102,7 +102,7 @@ func NewApp(appRoot string, includeOverrides bool) (*DdevApp, error) { app.FailOnHookFailGlobal = globalconfig.DdevGlobalConfig.FailOnHookFailGlobal // Provide a default app name based on directory name - app.Name = filepath.Base(app.AppRoot) + app.Name = NormalizeProjectName(filepath.Base(app.AppRoot)) // Gather containers to omit, adding ddev-router for gitpod/codespaces app.OmitContainersGlobal = globalconfig.DdevGlobalConfig.OmitContainersGlobal @@ -1283,9 +1283,8 @@ func WriteImageDockerfile(fullpath string, contents []byte) error { func (app *DdevApp) promptForName() error { if app.Name == "" { dir, err := os.Getwd() - // If working directory name is invalid for hostnames, we shouldn't suggest it - if err == nil && hostRegex.MatchString(filepath.Base(dir)) { - app.Name = filepath.Base(dir) + if err == nil && hostRegex.MatchString(NormalizeProjectName(filepath.Base(dir))) { + app.Name = NormalizeProjectName(filepath.Base(dir)) } } diff --git a/pkg/ddevapp/config_test.go b/pkg/ddevapp/config_test.go index 263f6097442..6304ded75af 100644 --- a/pkg/ddevapp/config_test.go +++ b/pkg/ddevapp/config_test.go @@ -230,7 +230,7 @@ func TestConfigCommand(t *testing.T) { testMatrix := map[string][]string{ "magentophpversion": {nodeps.AppTypeMagento, nodeps.PHPDefault}, "drupal7phpversion": {nodeps.AppTypeDrupal7, nodeps.PHP82}, - "drupalphpversion": {nodeps.AppTypeDrupal, nodeps.PHPDefault}, + "Drupalphpversion": {nodeps.AppTypeDrupal, nodeps.PHPDefault}, } for testName, testValues := range testMatrix { @@ -298,6 +298,47 @@ func TestConfigCommand(t *testing.T) { } } +// TestConfigCommandProjectNormalization tests behavior when normalizing project names. +// For example, a directory like "some_dir" should result in project name "some-dir" +func TestConfigCommandProjectNormalization(t *testing.T) { + assert := asrt.New(t) + origDir, _ := os.Getwd() + + testMatrix := []struct { + name string + expectation string + }{ + {"normalname", "normalname"}, + {"with-hyphen", "with-hyphen"}, + {"with_underscore", "with-underscore"}, + {"with.dot", "with.dot"}, + } + + for _, tc := range testMatrix { + t.Run(tc.name, func(t *testing.T) { + + baseTestDir := t.TempDir() + testDir := filepath.Join(baseTestDir, tc.name) + err := os.Mkdir(testDir, 0755) + require.NoError(t, err) + + // Create the app we'll use for testing. + app, err := ddevapp.NewApp(testDir, false) + require.NoError(t, err) + + require.Equal(t, tc.expectation, app.Name) + + t.Cleanup(func() { + _ = app.Stop(true, false) + _ = os.Chdir(origDir) + }) + + err = ddevapp.PrepDdevDirectory(app) + assert.NoError(err) + }) + } +} + // TestConfigCommandDocrootDetection asserts the default docroot is detected. func TestConfigCommandDocrootDetection(t *testing.T) { // Set up tests and give ourselves a working directory. diff --git a/pkg/ddevapp/ddevapp.go b/pkg/ddevapp/ddevapp.go index 5fef07d2b02..e78eb50b1cc 100644 --- a/pkg/ddevapp/ddevapp.go +++ b/pkg/ddevapp/ddevapp.go @@ -2870,6 +2870,11 @@ func GetActiveApp(siteName string) (*DdevApp, error) { return app, nil } +// NormalizeProjectName replaces underscores in the site name with hyphens. +func NormalizeProjectName(siteName string) string { + return strings.ReplaceAll(siteName, "_", "-") +} + // restoreApp recreates an AppConfig's Name and returns an error // if it cannot restore them. func restoreApp(app *DdevApp, siteName string) error { diff --git a/pkg/ddevapp/ddevapp_test.go b/pkg/ddevapp/ddevapp_test.go index 97e9ae3fca5..1a9f6901b7e 100644 --- a/pkg/ddevapp/ddevapp_test.go +++ b/pkg/ddevapp/ddevapp_test.go @@ -3219,9 +3219,7 @@ func TestRouterPortsCheck(t *testing.T) { } app, err = ddevapp.GetActiveApp(site.Name) - if err != nil { - t.Fatalf("Failed to GetActiveApp(%s), err:%v", site.Name, err) - } + require.NoError(t, err, "Failed to GetActiveApp(%s), err:%v", site.Name, err) startErr = app.StartAndWait(5) //nolint: errcheck defer app.Stop(true, false)