Skip to content

Commit

Permalink
Speed up ddev commands including ddev list, fixes ddev#1881 (ddev#2445)
Browse files Browse the repository at this point in the history
  • Loading branch information
rfay authored Aug 14, 2020
1 parent 2b3fcd8 commit 9551eb7
Show file tree
Hide file tree
Showing 204 changed files with 422 additions and 52,394 deletions.
2 changes: 1 addition & 1 deletion cmd/ddev/cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func addCustomCommands(rootCmd *cobra.Command) error {

// If command has already been added, we won't work with it again.
if _, ok := commandsAdded[commandName]; ok {
util.Warning("not adding custom command %s because it was already added", onHostFullPath)
util.Warning("not adding command %s (%s) because it was already added to project %s", commandName, onHostFullPath, app.Name)
continue
}

Expand Down
5 changes: 4 additions & 1 deletion cmd/ddev/cmd/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ func TestCustomCommands(t *testing.T) {
assert.FileExists(filepath.Join(globalCommandsDir, f))
}

// Make sure we haven't accidentally created anything inappropriate in ~/.ddev
assert.False(fileutil.FileExists(filepath.Join(tmpHome, ".ddev", ".globalcommands")))
assert.False(fileutil.FileExists(filepath.Join(origHome, ".ddev", ".globalcommands")))
}

// TestLaunchCommand tests that the launch command behaves all the ways it should behave
Expand Down Expand Up @@ -141,7 +144,7 @@ func TestLaunchCommand(t *testing.T) {
err = app.Start()
assert.NoError(err)

desc, _ := app.Describe()
desc, _ := app.Describe(false)
cases := map[string]string{
"": app.GetPrimaryURL(),
"-p": desc["phpmyadmin_https_url"].(string),
Expand Down
10 changes: 6 additions & 4 deletions cmd/ddev/cmd/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ func TestCmdDisasterConfig(t *testing.T) {
assert.NoError(err)
out, err := exec.RunCommand(DdevBin, []string{"config", "--project-type=php"})
assert.Error(err)
assert.Contains(out, "not useful in")
_ = out

err = os.Chdir(testDir)
Expand All @@ -387,16 +388,17 @@ func TestCmdDisasterConfig(t *testing.T) {
defer testcommon.CleanupDir(tmpdir)
defer testcommon.Chdir(tmpdir)()

out, err = exec.RunCommand(DdevBin, []string{"config", "--project-type=php"})
// Create a project
_, err = exec.RunCommand(DdevBin, []string{"config", "--project-type=php"})
assert.NoError(err)
subdir := filepath.Join(tmpdir, "junk")
subdirName := t.Name() + fileutil.RandomFilenameBase()
subdir := filepath.Join(tmpdir, subdirName)
err = os.Mkdir(subdir, 0777)
assert.NoError(err)
err = os.Chdir(subdir)
assert.NoError(err)
assert.NotContains(out, "possible you wanted to")

// Make sure that ddev config in subdir gives a warning
// Make sure that ddev config in a subdir gives a warning
out, err = exec.RunCommand(DdevBin, []string{"config", "--project-type=php"})
assert.NoError(err)
assert.Contains(out, "possible you wanted to")
Expand Down
1 change: 1 addition & 0 deletions cmd/ddev/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ ddev delete --all`,
if err != nil {
util.Failed("Failed to get project(s): %v", err)
}
instrumentationApp = projects[0]

// Iterate through the list of projects built above, removing each one.
for _, project := range projects {
Expand Down
2 changes: 1 addition & 1 deletion cmd/ddev/cmd/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ running 'ddev describe <projectname>.`,
util.Failed("Failed to describe %s: %v", project.Name, err)
}

desc, err := project.Describe()
desc, err := project.Describe(false)
if err != nil {
util.Failed("Failed to describe project %s: %v", project.Name, err)
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/ddev/cmd/describe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func TestCmdDescribeAppFunction(t *testing.T) {
app, err := ddevapp.GetActiveApp("")
assert.NoError(err)

desc, err := app.Describe()
desc, err := app.Describe(false)
assert.NoError(err)
assert.EqualValues(ddevapp.SiteRunning, desc["status"])
assert.EqualValues(app.GetName(), desc["name"])
Expand All @@ -133,7 +133,7 @@ func TestCmdDescribeAppFunction(t *testing.T) {
// Stop the router using docker and then check the describe
_, err = exec.RunCommand("docker", []string{"stop", "ddev-router"})
assert.NoError(err)
desc, err = app.Describe()
desc, err = app.Describe(false)
assert.NoError(err)
assert.Equal("exited", desc["router_status"])
_, err = exec.RunCommand("docker", []string{"start", "ddev-router"})
Expand All @@ -158,7 +158,7 @@ func TestCmdDescribeAppUsingSitename(t *testing.T) {
for _, v := range TestSites {
app, err := ddevapp.GetActiveApp(v.Name)
assert.NoError(err)
desc, err := app.Describe()
desc, err := app.Describe(false)
assert.NoError(err)
assert.EqualValues(desc["status"], ddevapp.SiteRunning)
assert.EqualValues(app.GetName(), desc["name"])
Expand Down
33 changes: 1 addition & 32 deletions cmd/ddev/cmd/list.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package cmd

import (
"time"

"github.com/drud/ddev/pkg/ddevapp"
"github.com/drud/ddev/pkg/output"
"github.com/drud/ddev/pkg/util"
"github.com/spf13/cobra"
)

Expand All @@ -27,34 +23,7 @@ var ListCmd = &cobra.Command{
ddev list --active-only
ddev list -A`,
Run: func(cmd *cobra.Command, args []string) {
for {
apps, err := ddevapp.GetProjects(activeOnly)
if err != nil {
util.Failed("failed getting GetProjects: %v", err)
}
appDescs := make([]map[string]interface{}, 0)

if len(apps) < 1 {
output.UserOut.WithField("raw", appDescs).Println("No ddev projects were found.")
} else {
table := ddevapp.CreateAppTable()
for _, app := range apps {
desc, err := app.Describe()
if err != nil {
util.Error("Failed to describe project %s: %v", app.GetName(), err)
}
appDescs = append(appDescs, desc)
ddevapp.RenderAppRow(table, desc)
}
output.UserOut.WithField("raw", appDescs).Print(table.String() + "\n" + ddevapp.RenderRouterStatus())
}

if !continuous {
break
}

time.Sleep(time.Duration(continuousSleepTime) * time.Second)
}
ddevapp.List(activeOnly, continuous, continuousSleepTime)
},
}

Expand Down
8 changes: 4 additions & 4 deletions cmd/ddev/cmd/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,11 @@ func TestCmdListContinuous(t *testing.T) {

reader := bufio.NewReader(stdout)

blob := make([]byte, 8192)
blob := make([]byte, 16000)
byteCount, err := reader.Read(blob)
assert.NoError(err)
blob = blob[:byteCount-1]
require.True(t, byteCount > 1000)
require.True(t, byteCount > 300, "byteCount should have been >300 and was %v", byteCount)

f, err := unmarshalJSONLogs(string(blob))
if err != nil {
Expand All @@ -171,11 +171,11 @@ func TestCmdListContinuous(t *testing.T) {
time.Sleep(time.Millisecond * 1500)

// Now read more from the pipe after resetting blob
blob = make([]byte, 8192)
blob = make([]byte, 16000)
byteCount, err = reader.Read(blob)
assert.NoError(err)
blob = blob[:byteCount-1]
require.True(t, byteCount > 1000)
require.True(t, byteCount > 300)
f, err = unmarshalJSONLogs(string(blob))
require.NoError(t, err)
if len(f) > 1 {
Expand Down
1 change: 1 addition & 0 deletions cmd/ddev/cmd/pause.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ in any directory by running 'ddev pause projectname [projectname ...]' or pause
if err != nil {
util.Failed("Unable to get project(s): %v", err)
}
instrumentationApp = projects[0]

for _, project := range projects {
if err := ddevapp.CheckForMissingProjectFiles(project); err != nil {
Expand Down
1 change: 1 addition & 0 deletions cmd/ddev/cmd/restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ddev restart --all`,
if err != nil {
util.Failed("Failed to get project(s): %v", err)
}
instrumentationApp = projects[0]

for _, app := range projects {

Expand Down
41 changes: 31 additions & 10 deletions cmd/ddev/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gopkg.in/segmentio/analytics-go.v3"
"os"
"path/filepath"
"strings"
"time"
)

var (
updateInterval = time.Hour * 24 * 7 // One week interval between updates
serviceType string
updateDocURL = "https://ddev.readthedocs.io/en/stable/#installation"
updateInterval = time.Hour * 24 * 7 // One week interval between updates
serviceType string
updateDocURL = "https://ddev.readthedocs.io/en/stable/#installation"
instrumentationApp *ddevapp.DdevApp
)

// RootCmd represents the base command when called without any subcommands
Expand All @@ -33,18 +35,15 @@ Docs: https://ddev.readthedocs.io
Support: https://ddev.readthedocs.io/en/stable/#support`,
Version: version.DdevVersion,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
ignores := []string{"version", "config", "hostname", "help", "auth", "import-files"}
command := strings.Join(os.Args[1:], " ")

// LogSetup() has already been done, but now needs to be done
// again *after* --json flag is parsed.
output.LogSetUp()

// Skip docker validation for any command listed in "ignores"
for _, k := range ignores {
if strings.Contains(command, k) {
return
}
// Skip docker and other validation for most commands
if command != "start" && command != "restart" {
return
}

err := dockerutil.CheckDockerVersion(version.DockerVersionConstraint)
Expand Down Expand Up @@ -99,7 +98,7 @@ Support: https://ddev.readthedocs.io/en/stable/#support`,
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
// Do not report these comamnds
ignores := map[string]bool{"list": true, "version": true, "help": true, "auth": true, "hostname": true}
ignores := map[string]bool{"auth": true, "exec": true, "help": true, "hostname": true, "list": true, "ssh": true, "version": true}
if _, ok := ignores[cmd.CalledAs()]; ok {
return
}
Expand All @@ -126,8 +125,21 @@ Support: https://ddev.readthedocs.io/en/stable/#support`,
}

if globalconfig.DdevGlobalConfig.InstrumentationOptIn && version.SegmentKey != "" && globalconfig.IsInternetActive() && len(fullCommand) > 1 {
runTime := util.TimeTrack(time.Now(), "Instrumentation")
// Try to get default instrumentationApp from current directory if not already set
if instrumentationApp == nil {
app, err := ddevapp.NewApp("", false, "")
if err == nil {
instrumentationApp = app
}
}
// If it has been set, provide the tags, otherwise no app tags
if instrumentationApp != nil {
instrumentationApp.SetInstrumentationAppTags()
}
ddevapp.SetInstrumentationBaseTags()
ddevapp.SendInstrumentationEvents(event)
runTime()
}
},
}
Expand Down Expand Up @@ -179,6 +191,15 @@ func checkDdevVersionAndOptInInstrumentation() error {
allowStats := util.Confirm("It looks like you have a new ddev release.\nMay we send anonymous ddev usage statistics and errors?\nTo know what we will see please take a look at\nhttps://ddev.readthedocs.io/en/stable/users/cli-usage/#opt-in-usage-information\nPermission to beam up?")
if allowStats {
globalconfig.DdevGlobalConfig.InstrumentationOptIn = true
client := analytics.New(version.SegmentKey)
defer func() {
_ = client.Close()
}()

err := ddevapp.SegmentUser(client, ddevapp.GetInstrumentationUser())
if err != nil {
output.UserOut.Debugf("error in SegmentUser: %v", err)
}
}
globalconfig.DdevGlobalConfig.LastStartedVersion = version.VERSION
err := globalconfig.WriteGlobalConfig(globalconfig.DdevGlobalConfig)
Expand Down
28 changes: 17 additions & 11 deletions cmd/ddev/cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,33 +148,39 @@ func TestCreateGlobalDdevDir(t *testing.T) {
assert := asrt.New(t)

tmpDir := testcommon.CreateTmpDir("globalDdevCheck")
switchDir := TestSites[0].Chdir()

origHome := os.Getenv("HOME")

t.Cleanup(
func() {
switchDir()
err := os.RemoveAll(tmpDir)
assert.NoError(err)

err = os.Setenv("HOME", origHome)
assert.NoError(err)
})

// Make sure that the tmpDir/.ddev and tmpDir/.ddev/.update don't exist before we run ddev.
_, err := os.Stat(filepath.Join(tmpDir, ".ddev"))
assert.Error(err)
assert.True(os.IsNotExist(err))

_, err = os.Stat(filepath.Join(tmpDir, ".ddev", ".update"))
tmpUpdateFilePath := filepath.Join(tmpDir, ".ddev", ".update")
_, err = os.Stat(tmpUpdateFilePath)
assert.Error(err)
assert.True(os.IsNotExist(err))

// Change the homedir temporarily
err = os.Setenv("HOME", tmpDir)
assert.NoError(err)

args := []string{"list"}
_, err = exec.RunCommand(DdevBin, args)
assert.NoError(err)

_, err = os.Stat(filepath.Join(tmpDir, ".ddev", ".update"))
assert.NoError(err)

// Cleanup our tmp homedir
err = os.RemoveAll(tmpDir)
// The .update file is only created by ddev start
_, err = exec.RunCommand(DdevBin, []string{"start"})
assert.NoError(err)

err = os.Setenv("HOME", origHome)
_, err = os.Stat(tmpUpdateFilePath)
assert.NoError(err)
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/ddev/cmd/sequelpro.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ var dummyDevSequelproCmd = &cobra.Command{
func init() {
switch {
case detectSequelpro():
app, err := ddevapp.GetActiveApp("")
app, err := ddevapp.NewApp("", false, "")
if err == nil && app != nil && !nodeps.ArrayContainsString(app.GetOmittedContainers(), "db") {
RootCmd.AddCommand(DdevSequelproCmd)
}
Expand Down
1 change: 1 addition & 0 deletions cmd/ddev/cmd/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ ddev snapshot --all`,
if err != nil {
util.Failed("Unable to get project(s) %v: %v", args, err)
}
instrumentationApp = apps[0]

for _, app := range apps {
if snapshotNameOutput, err := app.Snapshot(snapshotName); err != nil {
Expand Down
1 change: 1 addition & 0 deletions cmd/ddev/cmd/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ddev ssh -d /var/www/html`,
util.Failed("Failed to ddev ssh: %v", err)
}
app := projects[0]
instrumentationApp = app

if strings.Contains(app.SiteStatus(), ddevapp.SiteStopped) {
util.Failed("Project is not currently running. Try 'ddev start'.")
Expand Down
1 change: 1 addition & 0 deletions cmd/ddev/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ ddev start --all`,
if err != nil {
util.Failed("Failed to get project(s): %v", err)
}
instrumentationApp = projects[0]

for _, project := range projects {
if err := ddevapp.CheckForMissingProjectFiles(project); err != nil {
Expand Down
1 change: 1 addition & 0 deletions cmd/ddev/cmd/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ ddev stop --remove-data`,
if err != nil {
util.Failed("Failed to get project(s): %v", err)
}
instrumentationApp = projects[0]

// Iterate through the list of projects built above, removing each one.
for _, project := range projects {
Expand Down
5 changes: 5 additions & 0 deletions cmd/ddev/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ package main
import (
"github.com/drud/ddev/cmd/ddev/cmd"
"github.com/drud/ddev/pkg/output"
"github.com/drud/ddev/pkg/util"
"os"
"time"
)

func main() {
runTime := util.TimeTrack(time.Now(), "main()")
defer runTime()

// Prevent running as root for most cases
// We really don't want ~/.ddev to have root ownership, breaks things.
if os.Geteuid() == 0 && len(os.Args) > 1 && os.Args[1] != "hostname" {
Expand Down
Loading

0 comments on commit 9551eb7

Please sign in to comment.