diff --git a/azure/backend.go b/azure/backend.go index 20406cf59..3b9c3933b 100644 --- a/azure/backend.go +++ b/azure/backend.go @@ -26,6 +26,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" "github.com/Azure/go-autorest/autorest/to" + "github.com/compose-spec/compose-go/cli" "github.com/compose-spec/compose-go/types" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -167,28 +168,26 @@ func (cs *aciContainerService) Run(ctx context.Context, r containers.ContainerCo return err } - project := compose.Project{ + project := types.Project{ Name: r.ID, - Config: types.Config{ - Services: []types.ServiceConfig{ - { - Name: singleContainerName, - Image: r.Image, - Ports: ports, - Labels: r.Labels, - Volumes: serviceConfigVolumes, - Deploy: &types.DeployConfig{ - Resources: types.Resources{ - Limits: &types.Resource{ - NanoCPUs: fmt.Sprintf("%f", r.CPULimit), - MemoryBytes: types.UnitBytes(r.MemLimit.Value()), - }, + Services: []types.ServiceConfig{ + { + Name: singleContainerName, + Image: r.Image, + Ports: ports, + Labels: r.Labels, + Volumes: serviceConfigVolumes, + Deploy: &types.DeployConfig{ + Resources: types.Resources{ + Limits: &types.Resource{ + NanoCPUs: fmt.Sprintf("%f", r.CPULimit), + MemoryBytes: types.UnitBytes(r.MemLimit.Value()), }, }, }, }, - Volumes: projectVolumes, }, + Volumes: projectVolumes, } logrus.Debugf("Running container %q with name %q\n", r.Image, r.ID) @@ -301,8 +300,8 @@ type aciComposeService struct { ctx store.AciContext } -func (cs *aciComposeService) Up(ctx context.Context, opts compose.ProjectOptions) error { - project, err := compose.ProjectFromOptions(&opts) +func (cs *aciComposeService) Up(ctx context.Context, opts cli.ProjectOptions) error { + project, err := cli.ProjectFromOptions(&opts) if err != nil { return err } @@ -315,8 +314,8 @@ func (cs *aciComposeService) Up(ctx context.Context, opts compose.ProjectOptions return createOrUpdateACIContainers(ctx, cs.ctx, groupDefinition) } -func (cs *aciComposeService) Down(ctx context.Context, opts compose.ProjectOptions) error { - project, err := compose.ProjectFromOptions(&opts) +func (cs *aciComposeService) Down(ctx context.Context, opts cli.ProjectOptions) error { + project, err := cli.ProjectFromOptions(&opts) if err != nil { return err } diff --git a/azure/convert/convert.go b/azure/convert/convert.go index 7653feae5..c4953a3f9 100644 --- a/azure/convert/convert.go +++ b/azure/convert/convert.go @@ -29,7 +29,6 @@ import ( "github.com/Azure/go-autorest/autorest/to" "github.com/compose-spec/compose-go/types" - "github.com/docker/api/compose" "github.com/docker/api/containers" "github.com/docker/api/context/store" ) @@ -47,7 +46,7 @@ const ( ) // ToContainerGroup converts a compose project into a ACI container group -func ToContainerGroup(aciContext store.AciContext, p compose.Project) (containerinstance.ContainerGroup, error) { +func ToContainerGroup(aciContext store.AciContext, p types.Project) (containerinstance.ContainerGroup, error) { project := projectAciHelper(p) containerGroupName := strings.ToLower(project.Name) volumesCache, volumesSlice, err := project.getAciFileVolumes() @@ -154,7 +153,7 @@ func getDNSSidecar(containers []containerinstance.Container) containerinstance.C return dnsSideCar } -type projectAciHelper compose.Project +type projectAciHelper types.Project func (p projectAciHelper) getAciSecretVolumes() ([]containerinstance.Volume, error) { var secretVolumes []containerinstance.Volume diff --git a/azure/convert/convert_test.go b/azure/convert/convert_test.go index 69fa33a95..72841d888 100644 --- a/azure/convert/convert_test.go +++ b/azure/convert/convert_test.go @@ -23,7 +23,6 @@ import ( "github.com/Azure/go-autorest/autorest/to" "github.com/compose-spec/compose-go/types" - "github.com/docker/api/compose" "github.com/docker/api/containers" "github.com/docker/api/context/store" @@ -46,7 +45,7 @@ func (suite *ConvertTestSuite) BeforeTest(suiteName, testName string) { } func (suite *ConvertTestSuite) TestProjectName() { - project := compose.Project{ + project := types.Project{ Name: "TEST", } containerGroup, err := ToContainerGroup(suite.ctx, project) @@ -110,18 +109,15 @@ func (suite *ConvertTestSuite) TestContainerGroupToContainer() { } func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerWithDnsSideCarSide() { - project := compose.Project{ - Name: "", - Config: types.Config{ - Services: []types.ServiceConfig{ - { - Name: "service1", - Image: "image1", - }, - { - Name: "service2", - Image: "image2", - }, + project := types.Project{ + Services: []types.ServiceConfig{ + { + Name: "service1", + Image: "image1", + }, + { + Name: "service2", + Image: "image2", }, }, } @@ -142,14 +138,11 @@ func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerWithDnsSideCa } func (suite *ConvertTestSuite) TestComposeSingleContainerGroupToContainerNoDnsSideCarSide() { - project := compose.Project{ - Name: "", - Config: types.Config{ - Services: []types.ServiceConfig{ - { - Name: "service1", - Image: "image1", - }, + project := types.Project{ + Services: []types.ServiceConfig{ + { + Name: "service1", + Image: "image1", }, }, } @@ -163,28 +156,25 @@ func (suite *ConvertTestSuite) TestComposeSingleContainerGroupToContainerNoDnsSi } func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerMultiplePorts() { - project := compose.Project{ - Name: "", - Config: types.Config{ - Services: []types.ServiceConfig{ - { - Name: "service1", - Image: "image1", - Ports: []types.ServicePortConfig{ - { - Published: 80, - Target: 80, - }, + project := types.Project{ + Services: []types.ServiceConfig{ + { + Name: "service1", + Image: "image1", + Ports: []types.ServicePortConfig{ + { + Published: 80, + Target: 80, }, }, - { - Name: "service2", - Image: "image2", - Ports: []types.ServicePortConfig{ - { - Published: 8080, - Target: 8080, - }, + }, + { + Name: "service2", + Image: "image2", + Ports: []types.ServicePortConfig{ + { + Published: 8080, + Target: 8080, }, }, }, @@ -215,19 +205,16 @@ func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerMultiplePorts func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerResourceLimits() { _0_1Gb := 0.1 * 1024 * 1024 * 1024 - project := compose.Project{ - Name: "", - Config: types.Config{ - Services: []types.ServiceConfig{ - { - Name: "service1", - Image: "image1", - Deploy: &types.DeployConfig{ - Resources: types.Resources{ - Limits: &types.Resource{ - NanoCPUs: "0.1", - MemoryBytes: types.UnitBytes(_0_1Gb), - }, + project := types.Project{ + Services: []types.ServiceConfig{ + { + Name: "service1", + Image: "image1", + Deploy: &types.DeployConfig{ + Resources: types.Resources{ + Limits: &types.Resource{ + NanoCPUs: "0.1", + MemoryBytes: types.UnitBytes(_0_1Gb), }, }, }, @@ -245,19 +232,16 @@ func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerResourceLimit } func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerResourceLimitsDefaults() { - project := compose.Project{ - Name: "", - Config: types.Config{ - Services: []types.ServiceConfig{ - { - Name: "service1", - Image: "image1", - Deploy: &types.DeployConfig{ - Resources: types.Resources{ - Limits: &types.Resource{ - NanoCPUs: "", - MemoryBytes: 0, - }, + project := types.Project{ + Services: []types.ServiceConfig{ + { + Name: "service1", + Image: "image1", + Deploy: &types.DeployConfig{ + Resources: types.Resources{ + Limits: &types.Resource{ + NanoCPUs: "", + MemoryBytes: 0, }, }, }, diff --git a/azure/convert/registrycredentials.go b/azure/convert/registrycredentials.go index e4f548ca7..5b666e93b 100644 --- a/azure/convert/registrycredentials.go +++ b/azure/convert/registrycredentials.go @@ -23,11 +23,10 @@ import ( "github.com/Azure/azure-sdk-for-go/profiles/latest/containerinstance/mgmt/containerinstance" "github.com/Azure/go-autorest/autorest/to" + compose "github.com/compose-spec/compose-go/types" "github.com/docker/cli/cli/config" "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/types" - - "github.com/docker/api/compose" ) // Specific username from ACR docs : https://github.com/Azure/acr/blob/master/docs/AAD-OAuth.md#getting-credentials-programatically diff --git a/azure/convert/registrycredentials_test.go b/azure/convert/registrycredentials_test.go index b56d41e0f..5b975bc24 100644 --- a/azure/convert/registrycredentials_test.go +++ b/azure/convert/registrycredentials_test.go @@ -24,8 +24,6 @@ import ( "github.com/compose-spec/compose-go/types" cliconfigtypes "github.com/docker/cli/cli/config/types" - "github.com/docker/api/compose" - "github.com/Azure/azure-sdk-for-go/profiles/latest/containerinstance/mgmt/containerinstance" . "github.com/onsi/gomega" @@ -173,7 +171,7 @@ func (suite *RegistryConvertTestSuite) TestHubAndSeveralACRRegistries() { })) } -func composeServices(images ...string) compose.Project { +func composeServices(images ...string) types.Project { var services []types.ServiceConfig for index, name := range images { service := types.ServiceConfig{ @@ -182,10 +180,8 @@ func composeServices(images ...string) compose.Project { } services = append(services, service) } - return compose.Project{ - Config: types.Config{ - Services: services, - }, + return types.Project{ + Services: services, } } diff --git a/cli/cmd/compose/down.go b/cli/cmd/compose/down.go index 56e449c3c..20544358b 100644 --- a/cli/cmd/compose/down.go +++ b/cli/cmd/compose/down.go @@ -20,14 +20,14 @@ import ( "context" "errors" + "github.com/compose-spec/compose-go/cli" "github.com/spf13/cobra" "github.com/docker/api/client" - "github.com/docker/api/compose" ) func downCommand() *cobra.Command { - opts := compose.ProjectOptions{} + opts := cli.ProjectOptions{} downCmd := &cobra.Command{ Use: "down", RunE: func(cmd *cobra.Command, args []string) error { @@ -35,13 +35,13 @@ func downCommand() *cobra.Command { }, } downCmd.Flags().StringVarP(&opts.Name, "project-name", "p", "", "Project name") - downCmd.Flags().StringVar(&opts.WorkDir, "workdir", ".", "Work dir") + downCmd.Flags().StringVar(&opts.WorkingDir, "workdir", ".", "Work dir") downCmd.Flags().StringArrayVarP(&opts.ConfigPaths, "file", "f", []string{}, "Compose configuration files") return downCmd } -func runDown(ctx context.Context, opts compose.ProjectOptions) error { +func runDown(ctx context.Context, opts cli.ProjectOptions) error { c, err := client.New(ctx) if err != nil { return err diff --git a/cli/cmd/compose/up.go b/cli/cmd/compose/up.go index a16c0bacd..4ac19a433 100644 --- a/cli/cmd/compose/up.go +++ b/cli/cmd/compose/up.go @@ -20,15 +20,15 @@ import ( "context" "errors" + "github.com/compose-spec/compose-go/cli" "github.com/spf13/cobra" "github.com/docker/api/client" - "github.com/docker/api/compose" "github.com/docker/api/progress" ) func upCommand() *cobra.Command { - opts := compose.ProjectOptions{} + opts := cli.ProjectOptions{} upCmd := &cobra.Command{ Use: "up", RunE: func(cmd *cobra.Command, args []string) error { @@ -36,7 +36,7 @@ func upCommand() *cobra.Command { }, } upCmd.Flags().StringVarP(&opts.Name, "project-name", "p", "", "Project name") - upCmd.Flags().StringVar(&opts.WorkDir, "workdir", ".", "Work dir") + upCmd.Flags().StringVar(&opts.WorkingDir, "workdir", ".", "Work dir") upCmd.Flags().StringArrayVarP(&opts.ConfigPaths, "file", "f", []string{}, "Compose configuration files") upCmd.Flags().StringArrayVarP(&opts.Environment, "environment", "e", []string{}, "Environment variables") upCmd.Flags().BoolP("detach", "d", true, " Detached mode: Run containers in the background") @@ -44,7 +44,7 @@ func upCommand() *cobra.Command { return upCmd } -func runUp(ctx context.Context, opts compose.ProjectOptions) error { +func runUp(ctx context.Context, opts cli.ProjectOptions) error { c, err := client.New(ctx) if err != nil { return err diff --git a/compose/api.go b/compose/api.go index bf12111d5..b08384ec9 100644 --- a/compose/api.go +++ b/compose/api.go @@ -18,12 +18,14 @@ package compose import ( "context" + + "github.com/compose-spec/compose-go/cli" ) // Service manages a compose project type Service interface { // Up executes the equivalent to a `compose up` - Up(ctx context.Context, opts ProjectOptions) error + Up(ctx context.Context, opts cli.ProjectOptions) error // Down executes the equivalent to a `compose down` - Down(ctx context.Context, opts ProjectOptions) error + Down(ctx context.Context, opts cli.ProjectOptions) error } diff --git a/compose/project.go b/compose/project.go deleted file mode 100644 index 4a8cb77cc..000000000 --- a/compose/project.go +++ /dev/null @@ -1,172 +0,0 @@ -/* - Copyright 2020 Docker, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package compose - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "regexp" - "strings" - - "github.com/compose-spec/compose-go/loader" - "github.com/compose-spec/compose-go/types" - "github.com/sirupsen/logrus" -) - -var supportedFilenames = []string{ - "compose.yml", - "compose.yaml", - "docker-compose.yml", - "docker-compose.yaml", -} - -// ProjectOptions configures a compose project -type ProjectOptions struct { - Name string - WorkDir string - ConfigPaths []string - Environment []string -} - -// Project represents a compose project with a name -type Project struct { - types.Config - projectDir string - Name string `yaml:"-" json:"-"` -} - -// ProjectFromOptions load a compose project based on given options -func ProjectFromOptions(options *ProjectOptions) (*Project, error) { - configPath, err := getConfigPathFromOptions(options) - if err != nil { - return nil, err - } - - configs, err := parseConfigs(configPath) - if err != nil { - return nil, err - } - - name := options.Name - if name == "" { - r := regexp.MustCompile(`[^a-z0-9\\-_]+`) - absPath, err := filepath.Abs(options.WorkDir) - if err != nil { - return nil, err - } - name = r.ReplaceAllString(strings.ToLower(filepath.Base(absPath)), "") - } - - return newProject(types.ConfigDetails{ - WorkingDir: options.WorkDir, - ConfigFiles: configs, - Environment: getAsEqualsMap(options.Environment), - }, name) -} - -func newProject(config types.ConfigDetails, name string) (*Project, error) { - model, err := loader.Load(config) - if err != nil { - return nil, err - } - - p := Project{ - Config: *model, - projectDir: config.WorkingDir, - Name: name, - } - return &p, nil -} - -func getConfigPathFromOptions(options *ProjectOptions) ([]string, error) { - var paths []string - pwd := options.WorkDir - - if len(options.ConfigPaths) != 0 { - for _, f := range options.ConfigPaths { - if f == "-" { - paths = append(paths, f) - continue - } - if !filepath.IsAbs(f) { - f = filepath.Join(pwd, f) - } - if _, err := os.Stat(f); err != nil { - return nil, err - } - paths = append(paths, f) - } - return paths, nil - } - - for { - var candidates []string - for _, n := range supportedFilenames { - f := filepath.Join(pwd, n) - if _, err := os.Stat(f); err == nil { - candidates = append(candidates, f) - } - } - if len(candidates) > 0 { - winner := candidates[0] - if len(candidates) > 1 { - logrus.Warnf("Found multiple config files with supported names: %s", strings.Join(candidates, ", ")) - logrus.Warnf("Using %s\n", winner) - } - return []string{winner}, nil - } - parent := filepath.Dir(pwd) - if parent == pwd { - return nil, fmt.Errorf("can't find a suitable configuration file in this directory or any parent. Is %q the right directory?", pwd) - } - pwd = parent - } -} - -func parseConfigs(configPaths []string) ([]types.ConfigFile, error) { - var files []types.ConfigFile - for _, f := range configPaths { - var b []byte - var err error - if f == "-" { - b, err = ioutil.ReadAll(os.Stdin) - } else { - b, err = ioutil.ReadFile(f) - } - if err != nil { - return nil, err - } - config, err := loader.ParseYAML(b) - if err != nil { - return nil, err - } - files = append(files, types.ConfigFile{Filename: f, Config: config}) - } - return files, nil -} - -// getAsEqualsMap split key=value formatted strings into a key : value map -func getAsEqualsMap(em []string) map[string]string { - m := make(map[string]string) - for _, v := range em { - kv := strings.SplitN(v, "=", 2) - m[kv[0]] = kv[1] - } - return m -} diff --git a/compose/project_test.go b/compose/project_test.go deleted file mode 100644 index ff3069d99..000000000 --- a/compose/project_test.go +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright 2020 Docker, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package compose - -import ( - "os" - "testing" - - . "github.com/onsi/gomega" - "github.com/stretchr/testify/suite" -) - -type ComposeTest struct { - suite.Suite -} - -func (suite *ComposeTest) TestParseComposeFile() { - files := []string{"../tests/composefiles/aci-demo/aci_demo_port.yaml"} - config, err := parseConfigs(files) - Expect(err).To(BeNil()) - services := config[0].Config["services"].(map[string]interface{}) - Expect(len(services)).To(Equal(3)) -} - -func (suite *ComposeTest) TestParseComposeStdin() { - files := []string{"-"} - f, err := os.Open("../tests/composefiles/aci-demo/aci_demo_port.yaml") - Expect(err).To(BeNil()) - defer func() { - err := f.Close() - Expect(err).To(BeNil()) - }() - oldStdin := os.Stdin - defer func() { os.Stdin = oldStdin }() // Restore original Stdin - - os.Stdin = f - config, err := parseConfigs(files) - Expect(err).To(BeNil()) - services := config[0].Config["services"].(map[string]interface{}) - Expect(len(services)).To(Equal(3)) -} - -func TestComposeProject(t *testing.T) { - RegisterTestingT(t) - suite.Run(t, new(ComposeTest)) -} diff --git a/example/backend.go b/example/backend.go index deea71dff..076b4087f 100644 --- a/example/backend.go +++ b/example/backend.go @@ -22,6 +22,7 @@ import ( "context" "errors" "fmt" + "github.com/compose-spec/compose-go/cli" "io" "github.com/docker/api/context/cloud" @@ -109,8 +110,8 @@ func (cs *containerService) Delete(ctx context.Context, id string, force bool) e type composeService struct{} -func (cs *composeService) Up(ctx context.Context, opts compose.ProjectOptions) error { - prj, err := compose.ProjectFromOptions(&opts) +func (cs *composeService) Up(ctx context.Context, opts cli.ProjectOptions) error { + prj, err := cli.ProjectFromOptions(&opts) if err != nil { return err } @@ -118,8 +119,8 @@ func (cs *composeService) Up(ctx context.Context, opts compose.ProjectOptions) e return nil } -func (cs *composeService) Down(ctx context.Context, opts compose.ProjectOptions) error { - prj, err := compose.ProjectFromOptions(&opts) +func (cs *composeService) Down(ctx context.Context, opts cli.ProjectOptions) error { + prj, err := cli.ProjectFromOptions(&opts) if err != nil { return err } diff --git a/go.mod b/go.mod index 5c29b7e86..73a191621 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 github.com/Microsoft/hcsshim v0.8.9 // indirect github.com/buger/goterm v0.0.0-20200322175922-2f3e71b85129 - github.com/compose-spec/compose-go v0.0.0-20200423124427-63dcf8c22cae + github.com/compose-spec/compose-go v0.0.0-20200629133725-59b25574fd55 github.com/containerd/console v1.0.0 github.com/containerd/containerd v1.3.5 // indirect github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb // indirect diff --git a/go.sum b/go.sum index e255df7ce..9d1eaadd8 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,8 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/compose-spec/compose-go v0.0.0-20200423124427-63dcf8c22cae h1:5zRbbF5Gbkl7ZEJrKwYha2JMWgnfpPjSmv8+jCmkeSA= -github.com/compose-spec/compose-go v0.0.0-20200423124427-63dcf8c22cae/go.mod h1:1PUpzRF1O/65VOqXZuwpCuYY7pJxbIq1jbAvAf62FGM= +github.com/compose-spec/compose-go v0.0.0-20200629133725-59b25574fd55 h1:vX1uiHKgVnFBPBLxz6P28n+TKGt3jGThvDr2vkSP8D0= +github.com/compose-spec/compose-go v0.0.0-20200629133725-59b25574fd55/go.mod h1:ArodJ6gsEB7iWKrbV3fSHZ08LlBvSVB0Oqg04fX86t4= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= @@ -179,6 +179,8 @@ github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= @@ -214,8 +216,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4= -github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= +github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/term v0.0.0-20200611042045-63b9a826fb74 h1:kvRIeqJNICemq2UFLx8q/Pj+1IRNZS0XPTaMFkuNsvg= github.com/moby/term v0.0.0-20200611042045-63b9a826fb74/go.mod h1:pJ0Ot5YGdTcMdxnPMyGCfAr6fKXe0g9cDlz16MuFEBE= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= @@ -272,7 +274,6 @@ github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvH github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=