-
-
Notifications
You must be signed in to change notification settings - Fork 580
/
start.go
163 lines (139 loc) · 4.97 KB
/
start.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package cmd
import (
"os"
"path"
"strings"
"github.com/ddev/ddev/pkg/amplitude"
"github.com/ddev/ddev/pkg/config/remoteconfig"
"github.com/ddev/ddev/pkg/config/state/storage/yaml"
"github.com/ddev/ddev/pkg/ddevapp"
"github.com/ddev/ddev/pkg/dockerutil"
"github.com/ddev/ddev/pkg/globalconfig"
"github.com/ddev/ddev/pkg/output"
"github.com/ddev/ddev/pkg/util"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
)
var startAll bool
// StartCmd provides the ddev start command
var StartCmd = &cobra.Command{
ValidArgsFunction: ddevapp.GetProjectNamesFunc("inactive", 0),
Use: "start [projectname ...]",
Aliases: []string{"add"},
Short: "Start a DDEV project.",
Long: `Start initializes and configures the web server and database containers
to provide a local development environment. You can run 'ddev start' from a
project directory to start that project, or you can start stopped projects in
any directory by running 'ddev start projectname [projectname ...]'`,
Example: `ddev start
ddev start <project1> <project2>
ddev start --all`,
PreRun: func(_ *cobra.Command, _ []string) {
dockerutil.EnsureDdevNetwork()
},
Run: func(cmd *cobra.Command, args []string) {
// Create a global state to be injected later.
state := yaml.NewState(path.Join(globalconfig.GetGlobalDdevDir(), ".state.yaml"))
// TODO: For the time being this triggers the download from GitHub but
// should be realized with a clean bootstrap as soon as it exists. The
// download does not hurt here as it's done in a asynchronous call but it's
// important to start it as early as possible to have an up to date
// remote config at the end of the command execution.
remoteconfig.InitGlobal(
remoteconfig.Config{
Local: remoteconfig.Local{
Path: globalconfig.GetGlobalDdevDir(),
},
Remote: remoteconfig.Remote{
Owner: globalconfig.DdevGlobalConfig.RemoteConfig.Remote.Owner,
Repo: globalconfig.DdevGlobalConfig.RemoteConfig.Remote.Repo,
Ref: globalconfig.DdevGlobalConfig.RemoteConfig.Remote.Ref,
Filepath: globalconfig.DdevGlobalConfig.RemoteConfig.Remote.Filepath,
},
UpdateInterval: globalconfig.DdevGlobalConfig.RemoteConfig.UpdateInterval,
TickerInterval: globalconfig.DdevGlobalConfig.Messages.TickerInterval,
},
state,
globalconfig.IsInternetActive,
)
remoteconfig.GetGlobal().ShowTicker()
remoteconfig.GetGlobal().ShowNotifications()
skip, err := cmd.Flags().GetBool("skip-confirmation")
if err != nil {
util.Failed(err.Error())
}
// Look for version change and opt-in to instrumentation if it has changed.
err = checkDdevVersionAndOptInInstrumentation(skip)
if err != nil {
util.Failed(err.Error())
}
selectFlag, err := cmd.Flags().GetBool("select")
if err != nil {
util.Failed(err.Error())
}
if selectFlag {
inactiveProjects, err := ddevapp.GetInactiveProjects()
if err != nil {
util.Failed(err.Error())
}
if len(inactiveProjects) == 0 {
util.Warning("No project to start available")
os.Exit(0)
}
inactiveProjectNames := ddevapp.ExtractProjectNames(inactiveProjects)
prompt := promptui.Select{
Label: "Projects",
Items: inactiveProjectNames,
Templates: &promptui.SelectTemplates{
Label: "{{ . | cyan }}:",
},
StartInSearchMode: true,
Searcher: func(input string, idx int) bool {
return strings.Contains(inactiveProjectNames[idx], input)
},
}
_, projectName, err := prompt.Run()
if err != nil {
util.Failed(err.Error())
}
args = append(args, projectName)
}
projects, err := getRequestedProjects(args, startAll)
if err != nil {
util.Failed("Failed to start project(s): %v", err)
}
if len(projects) > 0 {
instrumentationApp = projects[0]
}
for _, project := range projects {
if err := ddevapp.CheckForMissingProjectFiles(project); err != nil {
util.Failed("Failed to start %s: %v", project.GetName(), err)
}
output.UserOut.Printf("Starting %s...", project.GetName())
if err := project.Start(); err != nil {
util.Failed("Failed to start %s: %v", project.GetName(), err)
}
util.Success("Successfully started %s", project.GetName())
httpURLs, httpsURLs, _ := project.GetAllURLs()
if project.CanUseHTTPOnly() {
httpsURLs = httpURLs
}
util.Success("Project can be reached at %s", strings.Join(httpsURLs, " "))
}
amplitude.CheckSetUp()
},
}
func init() {
StartCmd.Flags().BoolVarP(&startAll, "all", "a", false, "Start all projects")
StartCmd.Flags().BoolP("skip-confirmation", "y", false, "Skip any confirmation steps")
StartCmd.Flags().BoolP("select", "s", false, "Interactively select a project to start")
err := StartCmd.Flags().MarkHidden("select")
if err != nil {
util.Warning("Unexpected error marking flag as hidden: %v", err)
}
err = StartCmd.Flags().MarkDeprecated("select", "Use tabbed autocompletion instead.")
if err != nil {
util.Warning("Unexpected error marking flag as deprecated: %v", err)
}
RootCmd.AddCommand(StartCmd)
}