diff --git a/e2e/commands_test.go b/e2e/commands_test.go index a3521c4c7..3005ea07f 100644 --- a/e2e/commands_test.go +++ b/e2e/commands_test.go @@ -82,6 +82,17 @@ func testRenderApp(appPath string, env ...string) func(*testing.T) { } } +func TestRenderParametersWithSpecialChars(t *testing.T) { + cmd, cleanup := dockerCli.createTestCmd() + defer cleanup() + dir := fs.NewDir(t, "") + defer dir.Remove() + + appPath := filepath.Join("testdata", "parameters-with-special-chars") + cmd.Command = dockerCli.Command("app", "render", filepath.Join(appPath, "my.dockerapp")) + result := icmd.RunCmd(cmd).Assert(t, icmd.Success) + golden.Assert(t, result.Stdout(), filepath.Join("parameters-with-special-chars", "expected.golden")) +} func TestRenderFormatters(t *testing.T) { cmd, cleanup := dockerCli.createTestCmd() defer cleanup() diff --git a/e2e/testdata/parameters-with-special-chars/expected.golden b/e2e/testdata/parameters-with-special-chars/expected.golden new file mode 100644 index 000000000..09f1850b4 --- /dev/null +++ b/e2e/testdata/parameters-with-special-chars/expected.golden @@ -0,0 +1,9 @@ +version: "3.0" +services: + test: + command: + - echo + - brave + - gnu + - world + image: alpine:latest diff --git a/e2e/testdata/parameters-with-special-chars/my.dockerapp b/e2e/testdata/parameters-with-special-chars/my.dockerapp new file mode 100644 index 000000000..ebb10d421 --- /dev/null +++ b/e2e/testdata/parameters-with-special-chars/my.dockerapp @@ -0,0 +1,16 @@ +version: 0.1.0 +name: myapp +maintainers: + - name: dev + email: dev@example.com +--- +version: "3.0" +services: + test: + image: alpine:latest + command: echo ${texts.first} ${texts.second-1} ${texts.second-2} +--- +texts: + first: "brave" + second-1: "gnu" + second-2: "world" \ No newline at end of file diff --git a/internal/compose/compose.go b/internal/compose/compose.go index 8b16c26bc..db9565454 100644 --- a/internal/compose/compose.go +++ b/internal/compose/compose.go @@ -12,8 +12,9 @@ import ( ) const ( - delimiter = "\\$" - substitution = "[_a-z][._a-z0-9]*(?::?[-?][^}]*)?" + delimiter = "\\$" + substitution = "[_a-z][._a-z0-9-]*" + composeSubstitution = "[_a-z][._a-z0-9]*(?::?[-?][^}]*)?" ) var ( @@ -21,8 +22,15 @@ var ( "%s(?i:(?P%s)|(?P%s)|{(?P%s)}|(?P))", delimiter, delimiter, substitution, substitution, ) + composePatternString = fmt.Sprintf( + "%s(?i:(?P%s)|(?P%s)|{(?P%s)}|(?P))", + delimiter, delimiter, composeSubstitution, composeSubstitution, + ) // ExtrapolationPattern is the variable regexp pattern used to interpolate or extract variables when rendering ExtrapolationPattern = regexp.MustCompile(patternString) + // ComposeExtrapolationPattern is the compose original variable regexp pattern used to interpolate or extract + // variables when rendering. This pattern is only used when a docherapp file is initialized from a compose file + ComposeExtrapolationPattern = regexp.MustCompile(composePatternString) ) // Load applies the specified function when loading a slice of compose data diff --git a/internal/packager/init.go b/internal/packager/init.go index 180d45c23..0df322110 100644 --- a/internal/packager/init.go +++ b/internal/packager/init.go @@ -148,7 +148,7 @@ func initFromComposeFile(name string, composeFile string) error { } } } - vars, err := compose.ExtractVariables(composeRaw, compose.ExtrapolationPattern) + vars, err := compose.ExtractVariables(composeRaw, compose.ComposeExtrapolationPattern) if err != nil { return errors.Wrap(err, "failed to parse compose file") } diff --git a/internal/packager/init_test.go b/internal/packager/init_test.go index 7e03f8f08..339956063 100644 --- a/internal/packager/init_test.go +++ b/internal/packager/init_test.go @@ -52,7 +52,6 @@ services: image: image1 ports: - ${ports.service1:-9001} - service2: image: image2 ports: