Commit d5c57887 authored by Jeena Huneidi's avatar Jeena Huneidi
Browse files

Merge branch 'gitlab-ci' into 'master'

CI: Add initial gitlab CI

See merge request releng/cli!1
parents e1fd6968 e91fbf09
image: docker:19.03.12
variables:
# When you use the dind service, you must instruct Docker to talk with
# the daemon started inside of the service. The daemon is available
# with a network connection instead of the default
# /var/run/docker.sock socket. Docker 19.03 does this automatically
# by setting the DOCKER_HOST in
# https://github.com/docker-library/docker/blob/d45051476babc297257df490d22cbd806f1b11e4/19.03/docker-entrypoint.sh#L23-L29
#
# The 'docker' hostname is the alias of the service container as described at
# https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services.
#
# Specify to Docker where to create the certificates. Docker
# creates them automatically on boot, and creates
# `/certs/client` to share between the service and job
# container, thanks to volume mount from config.toml
DOCKER_TLS_CERTDIR: "/certs"
stages:
- build
- test
- integration
- build-release
# The plan would be for this cache to be reused by all jobs.
# Caches curently end up cached per runner, per job concurrency level and per md5 of path?
# So there are potentially 12 caches that end up needing to be populated right now?
# https://forum.gitlab.com/t/confusion-around-ci-docker-cache-volumes-and-sharing-across-jobs-concurrency/56793
# Docker cache volumes look like this runner-<short-token>-project-<id>-concurrent-<concurrency-id>-cache-<md5-of-path>
cache:
- key: mediawiki
paths:
- mediawiki
services:
- name: docker:19.03.12-dind
# Use a registry mirror to avoid hitting docker hub too much as there is a rate limit of 100 pulls per 6 hours
command: ["--registry-mirror", "https://mirror.gcr.io"]
build:
stage: build
needs: []
cache: {}
image: docker-registry.wikimedia.org/golang:1.13-3
artifacts:
paths:
- bin/
script:
- make
build-release:
stage: build-release
needs: []
cache: {}
image: docker-registry.wikimedia.org/golang:1.13-3
artifacts:
paths:
- _release/
script:
# Ideally make would not be needed, only release? But it is needed to install deps currently?
- make
- make release
test:
stage: test
needs: []
cache: {}
image: docker-registry.wikimedia.org/golang:1.13-3
script:
- go get -u golang.org/x/lint/golint
- make test
integration:
stage: integration
needs: [build]
dependencies:
- build
parallel:
matrix:
- TEST: docker-mw-extra-commands.sh
- TEST: docker-mw-install-all-the-dbs.sh
- TEST: docker-mw-mysql-suspend-resume-destroy.sh
before_script:
# libc6-compat needed because https://stackoverflow.com/questions/36279253/go-compiled-binary-wont-run-in-an-alpine-docker-container-on-ubuntu-host
- apk add --no-cache libc6-compat bash docker-compose curl
- ./tests/cache-mediawiki.sh
- ./tests/setup.sh
script:
- ./tests/$TEST
......@@ -45,7 +45,7 @@ var mwddMediawikiCmd = &cobra.Command{
usr, _ := user.Current()
usrDir := usr.HomeDir
if(mwdd.Env().Missing("MEDIAWIKI_VOLUMES_CODE")){
if mwdd.Env().Missing("MEDIAWIKI_VOLUMES_CODE") {
// Try to autodetect if we are in a MediaWiki directory at all
suggestedMwDir, err := os.Getwd()
......@@ -66,7 +66,7 @@ var mwddMediawikiCmd = &cobra.Command{
// Prompt the user for a directory or confirmation
dirPrompt := promptui.Prompt{
Label: "What directory would you like to store MediaWiki source code in?",
Label: "What directory would you like to store MediaWiki source code in?",
Default: suggestedMwDir,
}
value, err := dirPrompt.Run()
......@@ -82,7 +82,7 @@ var mwddMediawikiCmd = &cobra.Command{
}
if err == nil {
mwdd.Env().Set("MEDIAWIKI_VOLUMES_CODE",value)
mwdd.Env().Set("MEDIAWIKI_VOLUMES_CODE", value)
} else {
fmt.Println("Can't continue without a MediaWiki code directory")
os.Exit(1)
......@@ -91,7 +91,7 @@ var mwddMediawikiCmd = &cobra.Command{
}
// Default the mediawiki container to a .composer directory in the running users home dir
if(!mwdd.Env().Has("MEDIAWIKI_VOLUMES_DOT_COMPOSER")) {
if !mwdd.Env().Has("MEDIAWIKI_VOLUMES_DOT_COMPOSER") {
mwdd.Env().Set("MEDIAWIKI_VOLUMES_DOT_COMPOSER", usrDir+"/.composer")
}
......@@ -101,7 +101,7 @@ var mwddMediawikiCmd = &cobra.Command{
// 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!
if(!mediawiki.MediaWikiIsPresent()) {
if !mediawiki.MediaWikiIsPresent() {
cloneMwPrompt := promptui.Prompt{
Label: "MediaWiki code not detected in " + mwdd.Env().Get("MEDIAWIKI_VOLUMES_CODE") + ". Do you want to clone it now?",
IsConfirm: true,
......@@ -109,7 +109,7 @@ var mwddMediawikiCmd = &cobra.Command{
_, err := cloneMwPrompt.Run()
setupOpts.GetMediaWiki = err == nil
}
if(!mediawiki.VectorIsPresent()) {
if !mediawiki.VectorIsPresent() {
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,
......@@ -117,7 +117,7 @@ var mwddMediawikiCmd = &cobra.Command{
_, err := cloneMwPrompt.Run()
setupOpts.GetVector = err == nil
}
if(setupOpts.GetMediaWiki || setupOpts.GetVector) {
if setupOpts.GetMediaWiki || setupOpts.GetVector {
cloneFromGithubPrompt := promptui.Prompt{
Label: "Do you want to clone from Github for extra speed? (your git remotes will be switched to Gerrit after download)",
IsConfirm: true,
......@@ -133,21 +133,21 @@ var mwddMediawikiCmd = &cobra.Command{
setupOpts.UseShallow = err == nil
finalRemoteTypePrompt := promptui.Prompt{
Label: "How do you want to interact with Gerrit for the cloned repositores? (http or ssh)",
Label: "How do you want to interact with Gerrit for the cloned repositores? (http or ssh)",
Default: "ssh",
}
remoteType, err := finalRemoteTypePrompt.Run()
if(err != nil || ( remoteType != "ssh" && remoteType != "http" )) {
if err != nil || (remoteType != "ssh" && remoteType != "http") {
fmt.Println("Invalid Gerrit interaction type chosen.")
os.Exit(1)
}
setupOpts.GerritInteractionType = remoteType
if(remoteType == "ssh") {
if remoteType == "ssh" {
gerritUsernamePrompt := promptui.Prompt{
Label: "What is your Gerrit username?",
Label: "What is your Gerrit username?",
}
gerritUsername, err := gerritUsernamePrompt.Run()
if(err != nil || len(gerritUsername) < 1 ) {
if err != nil || len(gerritUsername) < 1 {
fmt.Println("Gerrit username required for ssh interaction type.")
os.Exit(1)
}
......@@ -156,7 +156,7 @@ var mwddMediawikiCmd = &cobra.Command{
setupOpts.UseShallow = err == nil
}
if(setupOpts.GetMediaWiki || setupOpts.GetVector) {
if setupOpts.GetMediaWiki || setupOpts.GetVector {
// Clone various things in multiple stages
Spinner := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
Spinner.Prefix = "Performing step"
......@@ -168,22 +168,23 @@ var mwddMediawikiCmd = &cobra.Command{
mediawiki.CloneSetup(setupOpts)
// Check that the needed things seem to have happened
if(setupOpts.GetMediaWiki && !mediawiki.MediaWikiIsPresent()) {
if setupOpts.GetMediaWiki && !mediawiki.MediaWikiIsPresent() {
fmt.Println("Something went wrong cloning MediaWiki")
os.Exit(1);
os.Exit(1)
}
if(setupOpts.GetVector && !mediawiki.VectorIsPresent()) {
if setupOpts.GetVector && !mediawiki.VectorIsPresent() {
fmt.Println("Something went wrong cloning Vector")
os.Exit(1);
os.Exit(1)
}
}
},
}
/*DbType used by the install command*/
var DbType string;
var DbType string
/*DbName used by the install command*/
var DbName string;
var DbName string
var mwddMediawikiInstallCmd = &cobra.Command{
Use: "install",
......@@ -205,7 +206,7 @@ var mwddMediawikiInstallCmd = &cobra.Command{
return
}
settingsStringToWrite := "<?php\n//require_once \"$IP/includes/PlatformSettings.php\";\nrequire_once '/mwdd/MwddSettings.php';\n"
if(mediawiki.VectorIsPresent()){
if mediawiki.VectorIsPresent() {
settingsStringToWrite += "\nwfLoadSkin('Vector');\n"
}
_, err = f.WriteString(settingsStringToWrite)
......@@ -225,17 +226,18 @@ var mwddMediawikiInstallCmd = &cobra.Command{
}
}
if(!mediawiki.LocalSettingsContains("/mwdd/MwddSettings.php")) {
if !mediawiki.LocalSettingsContains("/mwdd/MwddSettings.php") {
fmt.Println("LocalSettings.php file exists, but doesn't look right (missing mwcli mwdd shim)")
return;
return
}
// TODO make sure of composer caches
composerErr := mwdd.DefaultForUser().ExecNoOutput("mediawiki",[]string{
composerErr := mwdd.DefaultForUser().ExecNoOutput("mediawiki", []string{
"php", "/var/www/html/w/maintenance/checkComposerLockUpToDate.php",
},
exec.HandlerOptions{})
if(composerErr != nil) {
exec.HandlerOptions{}, User)
if composerErr != nil {
fmt.Println("Composer check failed:", composerErr)
prompt := promptui.Prompt{
IsConfirm: true,
Label: "Composer dependencies are not up to date, do you want to composer install?",
......@@ -245,9 +247,9 @@ var mwddMediawikiInstallCmd = &cobra.Command{
mwdd.DefaultForUser().DockerExec(mwdd.DockerExecCommand{
DockerComposeService: "mediawiki",
// --ignore-platform-reqs is currently used as only PHP7.2 is provided and some things need higher
Command: []string{"composer","install","--ignore-platform-reqs","--no-interaction"},
User: User,
},)
Command: []string{"composer", "install", "--ignore-platform-reqs", "--no-interaction"},
User: User,
})
} else {
fmt.Println("Can't install without up to date composer dependencies")
os.Exit(1)
......@@ -255,19 +257,19 @@ var mwddMediawikiInstallCmd = &cobra.Command{
}
// Fix some permissions
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")
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")
// Move custom LocalSetting.php so the install doesn't overwrite it
mwdd.DefaultForUser().Exec("mediawiki",[]string{
mwdd.DefaultForUser().Exec("mediawiki", []string{
"mv",
"/var/www/html/w/LocalSettings.php",
"/var/www/html/w/LocalSettings.php.mwdd.tmp",
}, exec.HandlerOptions{}, "root")
}, exec.HandlerOptions{}, "root")
// Do a DB type dependant install, writing the output LocalSettings.php to /tmp
if DbType == "sqlite" {
mwdd.DefaultForUser().Exec("mediawiki",[]string{
mwdd.DefaultForUser().Exec("mediawiki", []string{
"php",
"/var/www/html/w/maintenance/install.php",
"--confpath", "/tmp",
......@@ -278,22 +280,22 @@ var mwddMediawikiInstallCmd = &cobra.Command{
"--pass", "mwddpassword",
"docker-" + DbName,
"admin",
}, exec.HandlerOptions{}, "nobody")
}, exec.HandlerOptions{}, "nobody")
}
if DbType == "mysql" {
mwdd.DefaultForUser().Exec("mediawiki",[]string{
mwdd.DefaultForUser().Exec("mediawiki", []string{
"/wait-for-it.sh",
"mysql:3306",
}, exec.HandlerOptions{}, "nobody")
}, exec.HandlerOptions{}, "nobody")
}
if DbType == "postgres" {
mwdd.DefaultForUser().Exec("mediawiki",[]string{
mwdd.DefaultForUser().Exec("mediawiki", []string{
"/wait-for-it.sh",
"postgres:5432",
}, exec.HandlerOptions{}, "nobody")
}, exec.HandlerOptions{}, "nobody")
}
if DbType == "mysql" || DbType == "postgres" {
mwdd.DefaultForUser().Exec("mediawiki",[]string{
mwdd.DefaultForUser().Exec("mediawiki", []string{
"php",
"/var/www/html/w/maintenance/install.php",
"--confpath", "/tmp",
......@@ -307,36 +309,36 @@ var mwddMediawikiInstallCmd = &cobra.Command{
"--pass", "mwddpassword",
"docker-" + DbName,
"admin",
}, exec.HandlerOptions{}, "nobody")
}, exec.HandlerOptions{}, "nobody")
}
// Move the custom one back
mwdd.DefaultForUser().Exec("mediawiki",[]string{
mwdd.DefaultForUser().Exec("mediawiki", []string{
"mv",
"/var/www/html/w/LocalSettings.php.mwdd.tmp",
"/var/www/html/w/LocalSettings.php",
}, exec.HandlerOptions{}, "root")
}, exec.HandlerOptions{}, "root")
// Run update.php once too
mwdd.DefaultForUser().Exec("mediawiki",[]string{
mwdd.DefaultForUser().Exec("mediawiki", []string{
"php",
"/var/www/html/w/maintenance/update.php",
"--wiki", DbName,
"--quick",
}, exec.HandlerOptions{}, "nobody")
}, exec.HandlerOptions{}, "nobody")
},
}
var mwddMediawikiComposerCmd = &cobra.Command{
Use: "composer",
Short: "Runs composer in a container in the context of MediaWiki",
Example: " composer info\n composer install -- --ignore-platform-reqs",
Use: "composer",
Short: "Runs composer in a container in the context of MediaWiki",
Example: " composer info\n composer install -- --ignore-platform-reqs",
Run: func(cmd *cobra.Command, args []string) {
mwdd.DefaultForUser().EnsureReady()
mwdd.DefaultForUser().DockerExec(applyRelevantWorkingDirectory(mwdd.DockerExecCommand{
DockerComposeService: "mediawiki",
Command: append([]string{"composer"},args...),
User: User,
Command: append([]string{"composer"}, args...),
User: User,
}))
},
}
......@@ -347,10 +349,10 @@ var mwddMediawikiCreateCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
mwdd.DefaultForUser().EnsureReady()
options := exec.HandlerOptions{
Verbosity: Verbosity,
Verbosity: Verbosity,
}
// TODO mediawiki should come from some default definition set?
mwdd.DefaultForUser().UpDetached( []string{"mediawiki","mediawiki-web"}, options )
mwdd.DefaultForUser().UpDetached([]string{"mediawiki", "mediawiki-web"}, options)
// TODO add functionality for writing to the hosts file...
//mwdd.DefaultForUser().EnsureHostsFile()
},
......@@ -362,10 +364,10 @@ var mwddMediawikiDestroyCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
mwdd.DefaultForUser().EnsureReady()
options := exec.HandlerOptions{
Verbosity: Verbosity,
Verbosity: Verbosity,
}
mwdd.DefaultForUser().Rm( []string{"mediawiki","mediawiki-web"},options)
mwdd.DefaultForUser().RmVolumes( []string{"mediawiki-data","mediawiki-images","mediawiki-logs","mediawiki-dot-composer"},options)
mwdd.DefaultForUser().Rm([]string{"mediawiki", "mediawiki-web"}, options)
mwdd.DefaultForUser().RmVolumes([]string{"mediawiki-data", "mediawiki-images", "mediawiki-logs", "mediawiki-dot-composer"}, options)
},
}
......@@ -375,9 +377,9 @@ var mwddMediawikiSuspendCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
mwdd.DefaultForUser().EnsureReady()
options := exec.HandlerOptions{
Verbosity: Verbosity,
Verbosity: Verbosity,
}
mwdd.DefaultForUser().Stop( []string{"mediawiki","mediawiki-web"},options)
mwdd.DefaultForUser().Stop([]string{"mediawiki", "mediawiki-web"}, options)
},
}
......@@ -387,9 +389,9 @@ var mwddMediawikiResumeCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
mwdd.DefaultForUser().EnsureReady()
options := exec.HandlerOptions{
Verbosity: Verbosity,
Verbosity: Verbosity,
}
mwdd.DefaultForUser().Start( []string{"mediawiki","mediawiki-web"},options)
mwdd.DefaultForUser().Start([]string{"mediawiki", "mediawiki-web"}, options)
},
}
......@@ -400,31 +402,31 @@ var mwddMediawikiPhpunitCmd = &cobra.Command{
mwdd.DefaultForUser().EnsureReady()
mwdd.DefaultForUser().DockerExec(applyRelevantWorkingDirectory(mwdd.DockerExecCommand{
DockerComposeService: "mediawiki",
Command: append([]string{"php", "/var/www/html/w/tests/phpunit/phpunit.php"},args...),
User: User,
Command: append([]string{"php", "/var/www/html/w/tests/phpunit/phpunit.php"}, args...),
User: User,
}))
},
}
var mwddMediawikiExecCmd = &cobra.Command{
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",
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",
Run: func(cmd *cobra.Command, args []string) {
mwdd.DefaultForUser().EnsureReady()
mwdd.DefaultForUser().DockerExec(mwdd.DockerExecCommand{
DockerComposeService: "mediawiki",
Command: args,
User: User,
Command: args,
User: User,
})
},
}
var applyRelevantWorkingDirectory = func( dockerExecCommand mwdd.DockerExecCommand ) mwdd.DockerExecCommand {
var applyRelevantWorkingDirectory = func(dockerExecCommand mwdd.DockerExecCommand) mwdd.DockerExecCommand {
currentWorkingDirectory, _ := os.Getwd()
mountedMwDirectory := mwdd.DefaultForUser().Env().Get("MEDIAWIKI_VOLUMES_CODE")
// For paths inside the mediawiki path
if( strings.HasPrefix( currentWorkingDirectory,mountedMwDirectory ) ) {
if strings.HasPrefix(currentWorkingDirectory, mountedMwDirectory) {
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)
......
/*Package env for interacting with a .env file
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 env
import (
"fmt"
"os"
"sort"
"strings"
)
// Copy of godotenv.Write with modifications to never quote
// https://github.com/joho/godotenv/issues/50#issuecomment-364873528
// https://github.com/moby/moby/issues/12997
func writeOverride(envMap map[string]string, filename string) error {
content, error := marshelOverride(envMap)
if error != nil {
return error
}
file, error := os.Create(filename)
if error != nil {
return error
}
_, err := file.WriteString(content)
return err
}
// Copy of godotenv.Marshel with modifications to never quote
// https://github.com/joho/godotenv/issues/50#issuecomment-364873528
// https://github.com/moby/moby/issues/12997
func marshelOverride(envMap map[string]string) (string, error) {
lines := make([]string, 0, len(envMap))
for k, v := range envMap {
lines = append(lines, fmt.Sprintf(`%s=%s`, k, doubleQuoteEscape(v)))
}
sort.Strings(lines)
return strings.Join(lines, "\n"), nil
}
const doubleQuoteSpecialChars = "\\\n\r\"!$`"
func doubleQuoteEscape(line string) string {
for _, c := range doubleQuoteSpecialChars {
toReplace := "\\" + string(c)
if c == '\n' {
toReplace = `\n`
}
if c == '\r' {
toReplace = `\r`
}
line = strings.Replace(line, string(c), toReplace, -1)
}
return line
}
......@@ -59,7 +59,11 @@ func (f DotFile) read() map[string]string {
}
func (f DotFile) write(envMap map[string]string) {
godotenv.Write(envMap,f.Path())
// Override the regular gotdotenv Write method to avoid adding quotes
// https://github.com/joho/godotenv/issues/50#issuecomment-364873528
// https://github.com/moby/moby/issues/12997
//godotenv.Write(envMap, f.Path())
writeOverride(envMap, f.Path())
}
/*Delete a value from the env*/
......@@ -97,4 +101,4 @@ func (f DotFile) Missing(name string) bool {
/*List all values from the env*/
func (f DotFile) List() map[string]string {
return f.read()
}
\ No newline at end of file
}
......@@ -30,13 +30,21 @@ import (
/*MWDD representation of a mwdd v2 setup*/
type MWDD string
/*DefaultForUser returns the default mwdd working directory for the user*/
func DefaultForUser() (MWDD) {
func DefaultForUser() MWDD {
return MWDD(mwddUserDirectory() + string(os.PathSeparator) + "default")
}
func mwddUserDirectory() string {
// user home dir can not be used in Gitlab CI, must use the project dir instead!
// https://medium.com/@patrick.winters/mounting-volumes-in-sibling-containers-with-gitlab-ci-534e5edc4035
// TODO maybe this should be pushed further up and the whole mwcli dir should be moved?!
_, inGitlabCi := os.LookupEnv("GITLAB_CI")
if inGitlabCi {
ciDir, _ := os.LookupEnv("CI_PROJECT_DIR")
return ciDir + ".mwcli/mwdd"
}
currentUser, _ := user.Current()
projectDirectory := currentUser.HomeDir + string(os.PathSeparator) + ".mwcli/mwdd"
return projectDirectory
......@@ -70,17 +78,17 @@ func (m MWDD) EnsureHostsFile() {
// DockerComposeCommand results in something like: `docker-compose <automatic project stuff> <command> <commandArguments>`
type DockerComposeCommand struct {
Command string
CommandArguments []string
HandlerOptions exec.HandlerOptions
Command string
CommandArguments []string
HandlerOptions exec.HandlerOptions
}
/*DockerCompose runs any docker-compose command for the mwdd project with the correct project settings and all files loaded*/
func (m MWDD) DockerCompose( command DockerComposeCommand ) error {
func (m MWDD) DockerCompose(command DockerComposeCommand) error {
context := exec.ComposeCommandContext{
ProjectDirectory: m.Directory(),
ProjectName: m.DockerComposeProjectName(),
Files: files.ListRawDcYamlFilesInContextOfProjectDirectory(m.Directory()),
ProjectName: m.DockerComposeProjectName(),
Files: files.ListRawDcYamlFilesInContextOfProjectDirectory(m.Directory()),
}
return exec.RunCommand(
......@@ -88,17 +96,17 @@ func (m MWDD) DockerCompose( command DockerComposeCommand ) error {
exec.ComposeCommand(
context,
command.Command,
command.CommandArguments...
command.CommandArguments...,
),
)
}
/*DockerComposeTTY runs any docker-compose command for the mwdd project with the correct project settings and all files loaded in a TTY*/
func (m MWDD) DockerComposeTTY( command DockerComposeCommand ) {
func (m MWDD) DockerComposeTTY(command DockerComposeCommand) {
context := exec.ComposeCommandContext{
ProjectDirectory: m.Directory(),
ProjectName: m.DockerComposeProjectName(),
Files: files.ListRawDcYamlFilesInContextOfProjectDirectory(m.Directory()),
ProjectName: m.DockerComposeProjectName(),
Files: files.ListRawDcYamlFilesInContextOfProjectDirectory(m.Directory()),
}
exec.RunTTYCommand(
......@@ -106,100 +114,100 @@ func (m MWDD) DockerComposeTTY( command DockerComposeCommand ) {
exec.ComposeCommand(
context,
command.Command,
command.CommandArguments...
command.CommandArguments...,
),
)
}
/*Exec runs `docker-compose exec -T <service> <commandAndArgs>`*/
func (m MWDD) Exec( service string, commandAndArgs []string, options exec.HandlerOptions, user string ) {
func (m MWDD) Exec(service string, commandAndArgs []string, options exec.HandlerOptions, user string) {