mwdd_mediawiki.go 16.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*Package cmd is used for command line.

Copyright © 2020 Addshore

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cmd

import (
	"fmt"
22
	"os"
23
24
25
26
	"os/user"
	"path/filepath"
	"strings"
	"time"
Addshore's avatar
Addshore committed
27
28

	"gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/exec"
29
	"gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/mediawiki"
Addshore's avatar
Addshore committed
30
	"gerrit.wikimedia.org/r/mediawiki/tools/cli/internal/mwdd"
31
	"github.com/briandowns/spinner"
32
	"github.com/manifoldco/promptui"
33
34
35
36
	"github.com/spf13/cobra"
)

var mwddMediawikiCmd = &cobra.Command{
37
38
39
40
	Use:     "mediawiki",
	Short:   "MediaWiki service",
	Aliases: []string{"mw"},
	RunE:    nil,
41
42
43
44
	PersistentPreRun: func(cmd *cobra.Command, args []string) {
		cmd.Parent().Parent().PersistentPreRun(cmd, args)
		mwdd := mwdd.DefaultForUser()
		mwdd.EnsureReady()
45
46
47
48

		usr, _ := user.Current()
		usrDir := usr.HomeDir

Addshore's avatar
Addshore committed
49
		if mwdd.Env().Missing("MEDIAWIKI_VOLUMES_CODE") {
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

			// Try to autodetect if we are in a MediaWiki directory at all
			suggestedMwDir, err := os.Getwd()
			if err != nil {
				panic(err)
			}
			for {
				_, checkError := mediawiki.ForDirectory(suggestedMwDir)
				if checkError == nil {
					break
				}
				suggestedMwDir = filepath.Dir(suggestedMwDir)
				if suggestedMwDir == "/" {
					suggestedMwDir = "~/dev/git/gerrit/mediawiki/core"
					break
				}
			}

			// Prompt the user for a directory or confirmation
69
			dirPrompt := promptui.Prompt{
Addshore's avatar
Addshore committed
70
				Label:   "What directory would you like to store MediaWiki source code in?",
71
				Default: suggestedMwDir,
72
73
74
75
76
77
78
79
80
81
82
83
84
85
			}
			value, err := dirPrompt.Run()

			// Deal with people entering ~/ paths and them not be handled
			if value == "~" {
				// In case of "~", which won't be caught by the "else if"
				value = usrDir
			} else if strings.HasPrefix(value, "~/") {
				// Use strings.HasPrefix so we don't match paths like
				// "/something/~/something/"
				value = filepath.Join(usrDir, value[2:])
			}

			if err == nil {
Addshore's avatar
Addshore committed
86
				mwdd.Env().Set("MEDIAWIKI_VOLUMES_CODE", value)
87
88
89
90
			} else {
				fmt.Println("Can't continue without a MediaWiki code directory")
				os.Exit(1)
			}
91
92
93
94

		}

		// Default the mediawiki container to a .composer directory in the running users home dir
Addshore's avatar
Addshore committed
95
		if !mwdd.Env().Has("MEDIAWIKI_VOLUMES_DOT_COMPOSER") {
96
97
98
99
100
101
102
103
			usrComposerDirectory := usrDir + "/.composer"
			if _, err := os.Stat(usrComposerDirectory); os.IsNotExist(err) {
				err := os.Mkdir(usrComposerDirectory, 0755)
				if err != nil {
					fmt.Println("Failed to create directory needed for a composer cache")
					os.Exit(1)
				}
			}
104
			mwdd.Env().Set("MEDIAWIKI_VOLUMES_DOT_COMPOSER", usrDir+"/.composer")
105
106
107
108
109
110
111
112
		}

		setupOpts := mediawiki.CloneSetupOpts{}
		mediawiki, _ := mediawiki.ForDirectory(mwdd.Env().Get("MEDIAWIKI_VOLUMES_CODE"))

		// TODO ask a question about what remotes you want to end up using? https vs ssh!
		// TODO ask if they want to get any more skins and extensions?
		// TODO async cloning of repos for speed!
Addshore's avatar
Addshore committed
113
		if !mediawiki.MediaWikiIsPresent() {
114
115
116
117
118
119
120
			cloneMwPrompt := promptui.Prompt{
				Label:     "MediaWiki code not detected in " + mwdd.Env().Get("MEDIAWIKI_VOLUMES_CODE") + ". Do you want to clone it now?",
				IsConfirm: true,
			}
			_, err := cloneMwPrompt.Run()
			setupOpts.GetMediaWiki = err == nil
		}
Addshore's avatar
Addshore committed
121
		if !mediawiki.VectorIsPresent() {
122
123
124
125
126
127
128
			cloneMwPrompt := promptui.Prompt{
				Label:     "Vector skin is not detected in " + mwdd.Env().Get("MEDIAWIKI_VOLUMES_CODE") + ". Do you want to clone it from Gerrit?",
				IsConfirm: true,
			}
			_, err := cloneMwPrompt.Run()
			setupOpts.GetVector = err == nil
		}
Addshore's avatar
Addshore committed
129
		if setupOpts.GetMediaWiki || setupOpts.GetVector {
130
			cloneFromGithubPrompt := promptui.Prompt{
131
132
133
				Label:     "Do you want to clone from Github for extra speed? (your git remotes will be switched to Gerrit after download)",
				IsConfirm: true,
			}
134
			_, err := cloneFromGithubPrompt.Run()
135
			setupOpts.UseGithub = err == nil
136
137

			cloneShallowPrompt := promptui.Prompt{
138
139
140
				Label:     "Do you want to use shallow clones for extra speed? (You can fetch all history later using `git fetch --unshallow`)",
				IsConfirm: true,
			}
141
			_, err = cloneShallowPrompt.Run()
142
143
			setupOpts.UseShallow = err == nil

144
			finalRemoteTypePrompt := promptui.Prompt{
Addshore's avatar
Addshore committed
145
				Label:   "How do you want to interact with Gerrit for the cloned repositores? (http or ssh)",
146
147
148
				Default: "ssh",
			}
			remoteType, err := finalRemoteTypePrompt.Run()
Addshore's avatar
Addshore committed
149
			if err != nil || (remoteType != "ssh" && remoteType != "http") {
150
151
152
153
				fmt.Println("Invalid Gerrit interaction type chosen.")
				os.Exit(1)
			}
			setupOpts.GerritInteractionType = remoteType
Addshore's avatar
Addshore committed
154
			if remoteType == "ssh" {
155
				gerritUsernamePrompt := promptui.Prompt{
Addshore's avatar
Addshore committed
156
					Label: "What is your Gerrit username?",
157
158
				}
				gerritUsername, err := gerritUsernamePrompt.Run()
Addshore's avatar
Addshore committed
159
				if err != nil || len(gerritUsername) < 1 {
160
161
162
163
164
165
					fmt.Println("Gerrit username required for ssh interaction type.")
					os.Exit(1)
				}
				setupOpts.GerritUsername = gerritUsername
			}
			setupOpts.UseShallow = err == nil
166
167
		}

Addshore's avatar
Addshore committed
168
		if setupOpts.GetMediaWiki || setupOpts.GetVector {
169
170
171
172
173
174
175
176
177
178
179
			// Clone various things in multiple stages
			Spinner := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
			Spinner.Prefix = "Performing step"
			Spinner.FinalMSG = Spinner.Prefix + "(done)\n"
			setupOpts.Options = exec.HandlerOptions{
				Spinner: Spinner,
			}

			mediawiki.CloneSetup(setupOpts)

			// Check that the needed things seem to have happened
Addshore's avatar
Addshore committed
180
			if setupOpts.GetMediaWiki && !mediawiki.MediaWikiIsPresent() {
181
				fmt.Println("Something went wrong cloning MediaWiki")
Addshore's avatar
Addshore committed
182
				os.Exit(1)
183
			}
Addshore's avatar
Addshore committed
184
			if setupOpts.GetVector && !mediawiki.VectorIsPresent() {
185
				fmt.Println("Something went wrong cloning Vector")
Addshore's avatar
Addshore committed
186
				os.Exit(1)
187
			}
188
189
		}
	},
190
191
}

192
/*DbType used by the install command*/
Addshore's avatar
Addshore committed
193
194
var DbType string

195
/*DbName used by the install command*/
Addshore's avatar
Addshore committed
196
var DbName string
197

Addshore's avatar
Addshore committed
198
var mwddMediawikiInstallCmd = &cobra.Command{
199
200
201
	Use:     "install",
	Short:   "Installs a new MediaWiki site using install.php",
	Aliases: []string{"i"},
Addshore's avatar
Addshore committed
202
	Run: func(cmd *cobra.Command, args []string) {
203
204
205
206
207
208
209
210
		// Make it harder for people to fall over https://phabricator.wikimedia.org/T287654 for now
		if DbType != "sqlite" && DbType != "mysql" && DbType != "postgres" {
			fmt.Println("You must specify a valid dbtype (mysql, postgres, sqlite)")
			os.Exit(1)
		}

		// TODO check that the required DB services is running? OR start it up?

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
		mediawiki, _ := mediawiki.ForDirectory(mwdd.DefaultForUser().Env().Get("MEDIAWIKI_VOLUMES_CODE"))
		if !mediawiki.LocalSettingsIsPresent() {
			prompt := promptui.Prompt{
				IsConfirm: true,
				Label:     "No LocalSettings.php detected. Do you want to create the default mwdd file?",
			}
			_, err := prompt.Run()
			if err == nil {
				lsPath := mediawiki.Path("LocalSettings.php")

				f, err := os.Create(lsPath)
				if err != nil {
					fmt.Println(err)
					return
				}
226
				settingsStringToWrite := "<?php\n//require_once \"$IP/includes/PlatformSettings.php\";\nrequire_once '/mwdd/MwddSettings.php';\n"
Addshore's avatar
Addshore committed
227
				if mediawiki.VectorIsPresent() {
228
229
230
					settingsStringToWrite += "\nwfLoadSkin('Vector');\n"
				}
				_, err = f.WriteString(settingsStringToWrite)
231
232
233
234
235
236
237
238
239
240
241
242
243
244
				if err != nil {
					fmt.Println(err)
					f.Close()
					return
				}
				err = f.Close()
				if err != nil {
					fmt.Println(err)
					return
				}
			} else {
				fmt.Println("Can't install without the expected LocalSettings.php file")
				return
			}
245
		}
246

Addshore's avatar
Addshore committed
247
		if !mediawiki.LocalSettingsContains("/mwdd/MwddSettings.php") {
248
			fmt.Println("LocalSettings.php file exists, but doesn't look right (missing mwcli mwdd shim)")
Addshore's avatar
Addshore committed
249
			return
250
		}
Addshore's avatar
Addshore committed
251

252
		// TODO make sure of composer caches
Addshore's avatar
Addshore committed
253
		composerErr := mwdd.DefaultForUser().ExecNoOutput("mediawiki", []string{
254
			"php", "/var/www/html/w/maintenance/checkComposerLockUpToDate.php",
255
		},
Addshore's avatar
Addshore committed
256
257
258
			exec.HandlerOptions{}, User)
		if composerErr != nil {
			fmt.Println("Composer check failed:", composerErr)
259
260
261
262
263
264
265
266
			prompt := promptui.Prompt{
				IsConfirm: true,
				Label:     "Composer dependencies are not up to date, do you want to composer install?",
			}
			_, err := prompt.Run()
			if err == nil {
				mwdd.DefaultForUser().DockerExec(mwdd.DockerExecCommand{
					DockerComposeService: "mediawiki",
267
268
					Command:              []string{"composer", "install", "--ignore-platform-reqs", "--no-interaction"},
					User:                 User,
Addshore's avatar
Addshore committed
269
				})
270
271
272
273
274
			} else {
				fmt.Println("Can't install without up to date composer dependencies")
				os.Exit(1)
			}
		}
275

276
		// Fix some permissions
Addshore's avatar
Addshore committed
277
278
		mwdd.DefaultForUser().Exec("mediawiki", []string{"chown", "-R", "nobody", "/var/www/html/w/data"}, exec.HandlerOptions{}, "root")
		mwdd.DefaultForUser().Exec("mediawiki", []string{"chown", "-R", "nobody", "/var/log/mediawiki"}, exec.HandlerOptions{}, "root")
279

280
281
282
283
284
285
286
287
288
		// Copy current local settings "somewhere safe", incase someone needs to restore it
		currentTime := time.Now()
		currentTimeString := currentTime.Format("20060102150405")
		mwdd.DefaultForUser().Exec("mediawiki", []string{
			"cp",
			"/var/www/html/w/LocalSettings.php",
			"/var/www/html/w/LocalSettings.php.mwdd.bak." + currentTimeString,
		}, exec.HandlerOptions{}, User)

Addshore's avatar
Addshore committed
289
		// Move custom LocalSetting.php so the install doesn't overwrite it
Addshore's avatar
Addshore committed
290
		mwdd.DefaultForUser().Exec("mediawiki", []string{
Addshore's avatar
Addshore committed
291
292
			"mv",
			"/var/www/html/w/LocalSettings.php",
293
			"/var/www/html/w/LocalSettings.php.mwdd.tmp",
Addshore's avatar
Addshore committed
294
		}, exec.HandlerOptions{}, "root")
Addshore's avatar
Addshore committed
295

296
297
298
299
		var serverLink string = "http://" + DbName + ".mediawiki.mwdd.localhost:" + mwdd.DefaultForUser().Env().Get("PORT")
		const adminUser string = "admin"
		const adminPass string = "mwddpassword"

300
301
		// Do a DB type dependant install, writing the output LocalSettings.php to /tmp
		if DbType == "sqlite" {
Addshore's avatar
Addshore committed
302
			mwdd.DefaultForUser().Exec("mediawiki", []string{
303
304
				"php",
				"/var/www/html/w/maintenance/install.php",
305
				"--confpath", "/tmp",
306
				"--server", serverLink,
307
308
				"--dbtype", DbType,
				"--dbname", DbName,
309
				"--lang", "en",
310
				"--pass", adminPass,
311
				"docker-" + DbName,
312
				adminUser,
Addshore's avatar
Addshore committed
313
			}, exec.HandlerOptions{}, "nobody")
314
		}
315
		if DbType == "mysql" {
Addshore's avatar
Addshore committed
316
			mwdd.DefaultForUser().Exec("mediawiki", []string{
317
318
				"/wait-for-it.sh",
				"mysql:3306",
Addshore's avatar
Addshore committed
319
			}, exec.HandlerOptions{}, "nobody")
Addshore's avatar
Addshore committed
320
321
		}
		if DbType == "postgres" {
Addshore's avatar
Addshore committed
322
			mwdd.DefaultForUser().Exec("mediawiki", []string{
Addshore's avatar
Addshore committed
323
324
				"/wait-for-it.sh",
				"postgres:5432",
Addshore's avatar
Addshore committed
325
			}, exec.HandlerOptions{}, "nobody")
Addshore's avatar
Addshore committed
326
327
		}
		if DbType == "mysql" || DbType == "postgres" {
Addshore's avatar
Addshore committed
328
			mwdd.DefaultForUser().Exec("mediawiki", []string{
329
330
				"php",
				"/var/www/html/w/maintenance/install.php",
331
				"--confpath", "/tmp",
332
				"--server", serverLink,
333
				"--dbtype", DbType,
334
335
				"--dbuser", "root",
				"--dbpass", "toor",
336
				"--dbname", DbName,
Addshore's avatar
Addshore committed
337
				"--dbserver", DbType,
338
				"--lang", "en",
339
				"--pass", adminPass,
340
				"docker-" + DbName,
341
				adminUser,
Addshore's avatar
Addshore committed
342
			}, exec.HandlerOptions{}, "nobody")
343
		}
Addshore's avatar
Addshore committed
344
345

		// Move the custom one back
Addshore's avatar
Addshore committed
346
		mwdd.DefaultForUser().Exec("mediawiki", []string{
Addshore's avatar
Addshore committed
347
			"mv",
348
			"/var/www/html/w/LocalSettings.php.mwdd.tmp",
Addshore's avatar
Addshore committed
349
			"/var/www/html/w/LocalSettings.php",
Addshore's avatar
Addshore committed
350
		}, exec.HandlerOptions{}, "root")
Addshore's avatar
Addshore committed
351
352

		// Run update.php once too
Addshore's avatar
Addshore committed
353
		mwdd.DefaultForUser().Exec("mediawiki", []string{
Addshore's avatar
Addshore committed
354
355
			"php",
			"/var/www/html/w/maintenance/update.php",
356
			"--wiki", DbName,
Addshore's avatar
Addshore committed
357
			"--quick",
Addshore's avatar
Addshore committed
358
		}, exec.HandlerOptions{}, "nobody")
359
360
361
362
363
364
365
366

		fmt.Println("")
		fmt.Println("***************************************")
		fmt.Println("Installation successfull 🎉")
		fmt.Println("User: " + adminUser)
		fmt.Println("Pass: " + adminPass)
		fmt.Println("Link: " + serverLink)
		fmt.Println("***************************************")
367
368
369
370
371

		// TODO remove once https://phabricator.wikimedia.org/T287654 is solved
		if DbType == "sqlite" {
			fmt.Println("WARNING: The sqlite development environemtn currently suffers an issue, https://phabricator.wikimedia.org/T287654")
		}
Addshore's avatar
Addshore committed
372
373
374
375
	},
}

var mwddMediawikiComposerCmd = &cobra.Command{
Addshore's avatar
Addshore committed
376
377
378
	Use:     "composer",
	Short:   "Runs composer in a container in the context of MediaWiki",
	Example: "  composer info\n  composer install -- --ignore-platform-reqs",
Addshore's avatar
Addshore committed
379
	Run: func(cmd *cobra.Command, args []string) {
380
		mwdd.DefaultForUser().EnsureReady()
381
		mwdd.DefaultForUser().DockerExec(applyRelevantWorkingDirectory(mwdd.DockerExecCommand{
382
			DockerComposeService: "mediawiki",
Addshore's avatar
Addshore committed
383
384
			Command:              append([]string{"composer"}, args...),
			User:                 User,
385
		}))
Addshore's avatar
Addshore committed
386
387
388
	},
}

389
390
391
392
var mwddMediawikiCreateCmd = &cobra.Command{
	Use:   "create",
	Short: "Create the Mediawiki containers",
	Run: func(cmd *cobra.Command, args []string) {
Addshore's avatar
Addshore committed
393
394
		mwdd.DefaultForUser().EnsureReady()
		options := exec.HandlerOptions{
Addshore's avatar
Addshore committed
395
			Verbosity: Verbosity,
Addshore's avatar
Addshore committed
396
397
		}
		// TODO mediawiki should come from some default definition set?
Addshore's avatar
Addshore committed
398
		mwdd.DefaultForUser().UpDetached([]string{"mediawiki", "mediawiki-web"}, options)
Addshore's avatar
Addshore committed
399
400
		// TODO add functionality for writing to the hosts file...
		//mwdd.DefaultForUser().EnsureHostsFile()
401
402
403
404
405
406
407
	},
}

var mwddMediawikiDestroyCmd = &cobra.Command{
	Use:   "destroy",
	Short: "Destroy the Mediawiki containers",
	Run: func(cmd *cobra.Command, args []string) {
Addshore's avatar
Addshore committed
408
409
		mwdd.DefaultForUser().EnsureReady()
		options := exec.HandlerOptions{
Addshore's avatar
Addshore committed
410
			Verbosity: Verbosity,
Addshore's avatar
Addshore committed
411
		}
Addshore's avatar
Addshore committed
412
413
		mwdd.DefaultForUser().Rm([]string{"mediawiki", "mediawiki-web"}, options)
		mwdd.DefaultForUser().RmVolumes([]string{"mediawiki-data", "mediawiki-images", "mediawiki-logs", "mediawiki-dot-composer"}, options)
414
	},
415
416
417
418
419
420
}

var mwddMediawikiSuspendCmd = &cobra.Command{
	Use:   "suspend",
	Short: "Suspend the Mediawiki containers",
	Run: func(cmd *cobra.Command, args []string) {
421
422
		mwdd.DefaultForUser().EnsureReady()
		options := exec.HandlerOptions{
Addshore's avatar
Addshore committed
423
			Verbosity: Verbosity,
424
		}
Addshore's avatar
Addshore committed
425
		mwdd.DefaultForUser().Stop([]string{"mediawiki", "mediawiki-web"}, options)
426
427
428
429
430
431
432
	},
}

var mwddMediawikiResumeCmd = &cobra.Command{
	Use:   "resume",
	Short: "Resume the Mediawiki containers",
	Run: func(cmd *cobra.Command, args []string) {
433
434
		mwdd.DefaultForUser().EnsureReady()
		options := exec.HandlerOptions{
Addshore's avatar
Addshore committed
435
			Verbosity: Verbosity,
436
		}
Addshore's avatar
Addshore committed
437
		mwdd.DefaultForUser().Start([]string{"mediawiki", "mediawiki-web"}, options)
438
439
440
	},
}

Addshore's avatar
Addshore committed
441
442
443
444
445
var mwddMediawikiPhpunitCmd = &cobra.Command{
	Use:   "phpunit",
	Short: "Runs MediaWiki phpunit in the MediaWiki container",
	Run: func(cmd *cobra.Command, args []string) {
		mwdd.DefaultForUser().EnsureReady()
446
		mwdd.DefaultForUser().DockerExec(applyRelevantWorkingDirectory(mwdd.DockerExecCommand{
Addshore's avatar
Addshore committed
447
			DockerComposeService: "mediawiki",
Addshore's avatar
Addshore committed
448
449
			Command:              append([]string{"php", "/var/www/html/w/tests/phpunit/phpunit.php"}, args...),
			User:                 User,
450
		}))
Addshore's avatar
Addshore committed
451
452
453
	},
}

Addshore's avatar
Addshore committed
454
var mwddMediawikiExecCmd = &cobra.Command{
Addshore's avatar
Addshore committed
455
456
457
	Use:     "exec [flags] [command...]",
	Example: "  exec bash\n  exec -- bash --help\n  exec --user root bash\n  exec --user root -- bash --help",
	Short:   "Executes a command in the MediaWiki container",
Addshore's avatar
Addshore committed
458
459
460
461
	Run: func(cmd *cobra.Command, args []string) {
		mwdd.DefaultForUser().EnsureReady()
		mwdd.DefaultForUser().DockerExec(mwdd.DockerExecCommand{
			DockerComposeService: "mediawiki",
Addshore's avatar
Addshore committed
462
463
			Command:              args,
			User:                 User,
Addshore's avatar
Addshore committed
464
465
466
		})
	},
}
Addshore's avatar
Addshore committed
467

Addshore's avatar
Addshore committed
468
var applyRelevantWorkingDirectory = func(dockerExecCommand mwdd.DockerExecCommand) mwdd.DockerExecCommand {
469
470
471
	currentWorkingDirectory, _ := os.Getwd()
	mountedMwDirectory := mwdd.DefaultForUser().Env().Get("MEDIAWIKI_VOLUMES_CODE")
	// For paths inside the mediawiki path
Addshore's avatar
Addshore committed
472
	if strings.HasPrefix(currentWorkingDirectory, mountedMwDirectory) {
473
474
475
476
477
478
479
480
		dockerExecCommand.WorkingDir = strings.Replace(currentWorkingDirectory, mountedMwDirectory, "/var/www/html/w", 1)
	} else {
		fmt.Println("This command is not supported outside of the MediaWiki core directory: " + mountedMwDirectory)
		os.Exit(1)
	}
	return dockerExecCommand
}

481
482
483
484
485
486
func init() {
	mwddCmd.AddCommand(mwddMediawikiCmd)
	mwddMediawikiCmd.AddCommand(mwddMediawikiCreateCmd)
	mwddMediawikiCmd.AddCommand(mwddMediawikiDestroyCmd)
	mwddMediawikiCmd.AddCommand(mwddMediawikiSuspendCmd)
	mwddMediawikiCmd.AddCommand(mwddMediawikiResumeCmd)
Addshore's avatar
Addshore committed
487
	mwddMediawikiCmd.AddCommand(mwddMediawikiInstallCmd)
488
	mwddMediawikiInstallCmd.Flags().StringVarP(&DbName, "dbname", "", "default", "Name of the database to install (must be accepted by MediaWiki, stick to letters and numbers)")
489
	mwddMediawikiInstallCmd.Flags().StringVarP(&DbType, "dbtype", "", "", "Type of database to install (mysql, postgres, sqlite)")
Addshore's avatar
Addshore committed
490
	mwddMediawikiCmd.AddCommand(mwddMediawikiComposerCmd)
491
	mwddMediawikiComposerCmd.Flags().StringVarP(&User, "user", "u", mwdd.UserAndGroupForDockerExecution(), "User to run as, defaults to current OS user uid:gid")
Addshore's avatar
Addshore committed
492
	mwddMediawikiCmd.AddCommand(mwddMediawikiPhpunitCmd)
493
	mwddMediawikiPhpunitCmd.Flags().StringVarP(&User, "user", "u", mwdd.UserAndGroupForDockerExecution(), "User to run as, defaults to current OS user uid:gid")
Addshore's avatar
Addshore committed
494
	mwddMediawikiCmd.AddCommand(mwddMediawikiExecCmd)
495
496
	mwddMediawikiExecCmd.Flags().StringVarP(&User, "user", "u", mwdd.UserAndGroupForDockerExecution(), "User to run as, defaults to current OS user uid:gid")

497
}