Skip to content

Commit

Permalink
Revert parent config search, prevent directory destruction, hopefully f…
Browse files Browse the repository at this point in the history
…ixes #1574 (#1576)

* Revert "Look in parent directories for an existing .ddev/config.yaml, fixes #1158 (#1275)"

This reverts commit 7c8310e.

* Remove the behavior of ddev composer create --no-interaction that allows full deletion without confirmation

* Add error check to make sure they don't run it in homedir

* Warn user of ddev config if a parent directory has .ddev/config.yaml in it

* Add tests to make sure subdir and homedir config behaves properly

* Clean up ~/.ddev/config.yaml that might exist
  • Loading branch information
rfay committed May 10, 2019
1 parent 9b6fcad commit 16f109e
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 40 deletions.
8 changes: 3 additions & 5 deletions cmd/ddev/cmd/composer-create.go
Expand Up @@ -71,11 +71,9 @@ project root will be deleted when creating a project.`,
}

// Make the user confirm that existing contents will be deleted
util.Warning("Warning: Any existing contents of the project root (%s) will be removed", app.AppRoot)
if !noInteractionArg {
if !util.Confirm("Would you like to continue?") {
util.Failed("create-project cancelled")
}
util.Warning("Warning: ALL EXISTING CONTENT of the project root (%s) will be deleted", app.AppRoot)
if !util.Confirm("Would you like to continue?") {
util.Failed("create-project cancelled")
}

// Remove any contents of project root
Expand Down
23 changes: 13 additions & 10 deletions cmd/ddev/cmd/config.go
Expand Up @@ -2,7 +2,9 @@ package cmd

import (
"fmt"
"github.com/drud/ddev/pkg/globalconfig"
"github.com/drud/ddev/pkg/version"
"github.com/mitchellh/go-homedir"
"os"
"strings"

Expand Down Expand Up @@ -142,6 +144,11 @@ func handleConfigRun(cmd *cobra.Command, args []string) {
util.Failed(err.Error())
}

homeDir, _ := homedir.Dir()
if app.AppRoot == filepath.Dir(globalconfig.GetGlobalDdevDir()) || app.AppRoot == homeDir {
util.Failed("Please do not use `ddev config` in your home directory")
}

if cmd.Flags().NFlag() == 0 {
err = app.PromptForConfig()
if err != nil {
Expand Down Expand Up @@ -258,24 +265,20 @@ func init() {

// getConfigApp() does the basic setup of the app (with provider) and returns it.
func getConfigApp(providerName string) (*ddevapp.DdevApp, error) {
// Find app root
cd, err := os.Getwd()
appRoot, err := os.Getwd()
if err != nil {
return nil, err
return nil, fmt.Errorf("could not determine current working directory: %v", err)
}

// Check for an existing config in this or a parent dir
appRoot, err := ddevapp.CheckForConf(cd)
if err != nil {
// An error indicates no config file was found, use current directory
appRoot = cd
// Check for an existing config in a parent dir
otherRoot, _ := ddevapp.CheckForConf(appRoot)
if otherRoot != "" && otherRoot != appRoot {
util.Error("Is it possible you wanted to `ddev config` in parent directory %s?", otherRoot)
}

app, err := ddevapp.NewApp(appRoot, false, providerName)
if err != nil {
return nil, fmt.Errorf("could not create new config: %v", err)
}

return app, nil
}

Expand Down
53 changes: 28 additions & 25 deletions cmd/ddev/cmd/config_test.go
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"github.com/drud/ddev/pkg/fileutil"
"github.com/drud/ddev/pkg/version"
"github.com/mitchellh/go-homedir"
"testing"

"os"
Expand Down Expand Up @@ -306,45 +307,47 @@ func TestConfigInvalidProjectname(t *testing.T) {
assert.NotContains(out, "You may now run 'ddev start'")
_ = os.Remove(filepath.Join(tmpdir, ".ddev", "config.yaml"))
}

}

// TestConfigSubdir ensures an existing config can be found from subdirectories
func TestConfigSubdir(t *testing.T) {
// TestCmdDisasterConfig tests to make sure we can't accidentally
// config in homedir, and that config in a subdir is handled correctly
func TestCmdDisasterConfig(t *testing.T) {
var err error
assert := asrt.New(t)

testDir, _ := os.Getwd()
// Make sure we're not allowed to config in home directory.
home, _ := homedir.Dir()
err = os.Chdir(home)
assert.NoError(err)
out, err := exec.RunCommand(DdevBin, []string{"config", "--project-type=php"})
assert.Error(err)
_ = out

err = os.Chdir(testDir)
assert.NoError(err)

// Create a temporary directory and switch to it.
tmpdir := testcommon.CreateTmpDir(t.Name())
defer testcommon.CleanupDir(tmpdir)
defer testcommon.Chdir(tmpdir)()

// Create a simple config.
args := []string{
"config",
"--project-type",
"php",
}

out, err := exec.RunCommand(DdevBin, args)
out, err = exec.RunCommand(DdevBin, []string{"config", "--project-type=php"})
assert.NoError(err)
assert.Contains(out, "You may now run 'ddev start'")

// Create a subdirectory and switch to it.
subdir := filepath.Join(tmpdir, "some", "sub", "dir")
err = os.MkdirAll(subdir, 0755)
subdir := filepath.Join(tmpdir, "junk")
err = os.Mkdir(subdir, 0777)
assert.NoError(err)
defer testcommon.Chdir(subdir)()

// Confirm that the detected config location is in the original dir.
args = []string{
"config",
"--show-config-location",
}
err = os.Chdir(subdir)
assert.NoError(err)
assert.NotContains(out, "possible you wanted to")

// Ensure the existing config can be found
out, err = exec.RunCommand(DdevBin, args)
// Make sure that ddev config in subdir gives a warning
out, err = exec.RunCommand(DdevBin, []string{"config", "--project-type=php"})
assert.NoError(err)
assert.Contains(out, filepath.Join(tmpdir, ".ddev", "config.yaml"))
assert.Contains(out, "possible you wanted to")
assert.Contains(out, fmt.Sprintf("parent directory %s?", tmpdir))
assert.FileExists(filepath.Join(subdir, ".ddev/config.yaml"))
}

/**
Expand Down
6 changes: 6 additions & 0 deletions pkg/ddevapp/config.go
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/Masterminds/sprig"
"github.com/drud/ddev/pkg/dockerutil"
"github.com/drud/ddev/pkg/nodeps"
"github.com/mitchellh/go-homedir"
"html/template"
"io/ioutil"
"os"
Expand Down Expand Up @@ -68,6 +69,11 @@ func NewApp(AppRoot string, includeOverrides bool, provider string) (*DdevApp, e
// Set defaults.
app := &DdevApp{}

homeDir, _ := homedir.Dir()
if AppRoot == filepath.Dir(globalconfig.GetGlobalDdevDir()) || app.AppRoot == homeDir {
return nil, fmt.Errorf("ddev config is not useful in home directory (%s)", homeDir)
}

if !fileutil.FileExists(AppRoot) {
return app, fmt.Errorf("project root %s does not exist", AppRoot)
}
Expand Down
41 changes: 41 additions & 0 deletions pkg/ddevapp/config_test.go
Expand Up @@ -3,6 +3,7 @@ package ddevapp_test
import (
"bufio"
"fmt"
"github.com/mitchellh/go-homedir"
"github.com/stretchr/testify/require"
"io/ioutil"
"os"
Expand Down Expand Up @@ -55,6 +56,46 @@ func TestNewConfig(t *testing.T) {

}

// TestDisasterConfig tests for disaster opportunities (configing wrong directory, home dir, etc).
func TestDisasterConfig(t *testing.T) {
assert := asrt.New(t)

testDir, _ := os.Getwd()

// Make sure we're not allowed to config in home directory.
tmpDir, _ := homedir.Dir()
_, err := NewApp(tmpDir, false, ProviderDefault)
assert.Error(err)
assert.Contains(err.Error(), "ddev config is not useful in home directory")
_ = os.Chdir(testDir)

// Create a temporary directory and change to it for the duration of this test.
tmpDir = testcommon.CreateTmpDir("TestDisasterConfig")

defer testcommon.CleanupDir(tmpDir)
defer testcommon.Chdir(tmpDir)()

// Load a new Config
app, err := NewApp(tmpDir, false, ProviderDefault)
assert.NoError(err)

// WriteConfig the app.
err = app.WriteConfig()
assert.NoError(err)
_, err = os.Stat(app.ConfigPath)
assert.NoError(err)

subdir := filepath.Join(app.AppRoot, "subdir")
err = os.Mkdir(subdir, 0777)
assert.NoError(err)
err = os.Chdir(subdir)
assert.NoError(err)
subdirApp, err := NewApp(subdir, false, ProviderDefault)
assert.NoError(err)
_ = subdirApp

}

// TestAllowedAppType tests the IsAllowedAppType function.
func TestAllowedAppTypes(t *testing.T) {
assert := asrt.New(t)
Expand Down
5 changes: 5 additions & 0 deletions pkg/globalconfig/global_config.go
Expand Up @@ -143,6 +143,11 @@ func GetGlobalDdevDir() string {
logrus.Fatalf("Failed to create required directory %s, err: %v", ddevDir, err)
}
}
// config.yaml is not allowed in ~/.ddev, can only result in disaster
globalConfigYaml := filepath.Join(ddevDir, "config.yaml")
if _, err := os.Stat(globalConfigYaml); err == nil {
_ = os.Remove(filepath.Join(globalConfigYaml))
}
return ddevDir
}

Expand Down

0 comments on commit 16f109e

Please sign in to comment.