Skip to content
This repository has been archived by the owner on Jun 13, 2021. It is now read-only.

Commit

Permalink
Add warnings for env_file entries not copied
Browse files Browse the repository at this point in the history
As 'env_file' entries are not taken in account,
we warn the user to copy that and fix it's
compose file.

Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
  • Loading branch information
ulyssessouza committed Sep 13, 2019
1 parent 83f43bd commit 70a508f
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 14 deletions.
50 changes: 50 additions & 0 deletions e2e/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,56 @@ func TestRenderFormatters(t *testing.T) {
golden.Assert(t, result.Stdout(), "expected-yaml-render.golden")
}

func checkFileWarning(t *testing.T, goldenFile, composeData string) {
cmd, cleanup := dockerCli.createTestCmd()
defer cleanup()

tmpDir := fs.NewDir(t, "app_input",
fs.WithFile(internal.ComposeFileName, composeData),
)
defer tmpDir.Remove()

cmd.Dir = tmpDir.Path()
cmd.Command = dockerCli.Command("app", "init", "app-test",
"--compose-file", tmpDir.Join(internal.ComposeFileName))
stdOut := icmd.RunCmd(cmd).Assert(t, icmd.Success).Combined()
golden.Assert(t, stdOut, goldenFile)
}

func TestInitWarningEnvFiles(t *testing.T) {
testCases := []struct {
name string
golden string
compose string
}{
{
name: "initWarningMultipleEnvFilesTest",
golden: "init-output-warning-single-envfile.golden",
compose: `version: "3.2"
services:
nginx:
image: nginx:latest
env_file: myenv1.env`,
},
{
name: "initWarningMultipleEnvFilesTest",
golden: "init-output-warning-multiple-envfiles.golden",
compose: `version: "3.2"
services:
nginx:
image: nginx:latest
env_file:
- myenv1.env
- myenv2.env`,
},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
checkFileWarning(t, test.golden, test.compose)
})
}
}

func TestInit(t *testing.T) {
cmd, cleanup := dockerCli.createTestCmd()
defer cleanup()
Expand Down
3 changes: 3 additions & 0 deletions e2e/testdata/init-output-warning-multiple-envfiles.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"env_file: myenv1.env" entry of service "nginx" will NOT be copied automatically! Please, copy the file inside the application folder and update your compose file referring to it.
"env_file: myenv2.env" entry of service "nginx" will NOT be copied automatically! Please, copy the file inside the application folder and update your compose file referring to it.
Created "app-test.dockerapp"
2 changes: 2 additions & 0 deletions e2e/testdata/init-output-warning-single-envfile.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"env_file: myenv1.env" entry of service "nginx" will NOT be copied automatically! Please, copy the file inside the application folder and update your compose file referring to it.
Created "app-test.dockerapp"
83 changes: 69 additions & 14 deletions internal/packager/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,22 +123,51 @@ func checkComposeFileVersion(compose map[string]interface{}) error {
return schema.Validate(compose, fmt.Sprintf("%v", version))
}

func initFromComposeFile(name string, composeFile string) error {
logrus.Debugf("Initializing from compose file %s", composeFile)

dirName := internal.DirNameFromAppName(name)

composeRaw, err := ioutil.ReadFile(composeFile)
if err != nil {
return errors.Wrap(err, "failed to read compose file")
func getEnvFiles(svcName string, envFileEntry interface{}) ([]string, error) {
var envFiles []string
switch envFileEntry.(type) {
case string:
envFiles = append(envFiles, envFileEntry.(string))
case []interface{}:
for _, env := range envFileEntry.([]interface{}) {
envFiles = append(envFiles, env.(string))
}
default:
return nil, fmt.Errorf("unknown entries in 'env_file' for service %s -> %v",
svcName, envFileEntry)
}
cfgMap, err := composeloader.ParseYAML(composeRaw)
if err != nil {
return errors.Wrap(err, "failed to parse compose file")
return envFiles, nil
}

func checkEnvFiles(cfgMap map[string]interface{}) error {
services := cfgMap["services"]
servicesMap, ok := services.(map[string]interface{})
if !ok {
return fmt.Errorf("could not process the yaml file 1")
}
if err := checkComposeFileVersion(cfgMap); err != nil {
return err
for svcName, svc := range servicesMap {
svcContent, ok := svc.(map[string]interface{})
if !ok {
return fmt.Errorf("could not process the yaml file 2")
}
envFileEntry, ok := svcContent["env_file"]
if !ok {
continue
}
envFiles, err := getEnvFiles(svcName, envFileEntry)
if err != nil {
return errors.Wrap(err, "could not process the yaml file 4")
}
for _, envFilePath := range envFiles {
fmt.Printf("\"env_file: %s\" entry of service %q will NOT be copied automatically! "+
"Please, copy the file inside the application folder and update your compose file "+
"referring to it.\n", envFilePath, svcName)
}
}
return nil
}

func getParamsFromDefaultEnvFile(composeFile string, composeRaw []byte) (map[string]string, bool, error) {
params := make(map[string]string)
envs, err := opts.ParseEnvFile(filepath.Join(filepath.Dir(composeFile), ".env"))
if err == nil {
Expand All @@ -151,7 +180,7 @@ func initFromComposeFile(name string, composeFile string) error {
}
vars, err := compose.ExtractVariables(composeRaw, compose.ExtrapolationPattern)
if err != nil {
return errors.Wrap(err, "failed to parse compose file")
return nil, false, errors.Wrap(err, "failed to parse compose file")
}
needsFilling := false
for k, v := range vars {
Expand All @@ -164,6 +193,32 @@ func initFromComposeFile(name string, composeFile string) error {
}
}
}
return params, needsFilling, nil
}

func initFromComposeFile(name string, composeFile string) error {
logrus.Debugf("Initializing from compose file %s", composeFile)

dirName := internal.DirNameFromAppName(name)

composeRaw, err := ioutil.ReadFile(composeFile)
if err != nil {
return errors.Wrap(err, "failed to read compose file")
}
cfgMap, err := composeloader.ParseYAML(composeRaw)
if err != nil {
return errors.Wrap(err, "failed to parse compose file")
}
if err := checkComposeFileVersion(cfgMap); err != nil {
return err
}
if err := checkEnvFiles(cfgMap); err != nil {
return err
}
params, needsFilling, err := getParamsFromDefaultEnvFile(composeFile, composeRaw)
if err != nil {
return err
}
expandedParams, err := parameters.FromFlatten(params)
if err != nil {
return errors.Wrap(err, "failed to expand parameters")
Expand Down

0 comments on commit 70a508f

Please sign in to comment.