Skip to content

Commit 7a8d157

Browse files
convert: do not escape $ into $$ when using the --no-interpolate option (#9703)
Signed-off-by: Lucas Berg <root.lucasberg@gmail.com> Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com> Co-authored-by: Ulysses Souza <ulyssessouza@gmail.com>
1 parent 88df5ed commit 7a8d157

File tree

4 files changed

+44
-21
lines changed

4 files changed

+44
-21
lines changed

cmd/compose/convert.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package compose
1818

1919
import (
2020
"bufio"
21+
"bytes"
2122
"context"
2223
"fmt"
2324
"io"
@@ -112,7 +113,7 @@ func convertCommand(p *projectOptions, backend api.Service) *cobra.Command {
112113
}
113114

114115
func runConvert(ctx context.Context, backend api.Service, opts convertOptions, services []string) error {
115-
var json []byte
116+
var content []byte
116117
project, err := opts.toProject(services,
117118
cli.WithInterpolation(!opts.noInterpolate),
118119
cli.WithResolvedPaths(true),
@@ -136,27 +137,31 @@ func runConvert(ctx context.Context, backend api.Service, opts convertOptions, s
136137
}
137138
}
138139

139-
json, err = backend.Convert(ctx, project, api.ConvertOptions{
140+
content, err = backend.Convert(ctx, project, api.ConvertOptions{
140141
Format: opts.Format,
141142
Output: opts.Output,
142143
})
143144
if err != nil {
144145
return err
145146
}
146147

148+
if !opts.noInterpolate {
149+
content = escapeDollarSign(content)
150+
}
151+
147152
if opts.quiet {
148153
return nil
149154
}
150155

151156
var out io.Writer = os.Stdout
152-
if opts.Output != "" && len(json) > 0 {
157+
if opts.Output != "" && len(content) > 0 {
153158
file, err := os.Create(opts.Output)
154159
if err != nil {
155160
return err
156161
}
157162
out = bufio.NewWriter(file)
158163
}
159-
_, err = fmt.Fprint(out, string(json))
164+
_, err = fmt.Fprint(out, string(content))
160165
return err
161166
}
162167

@@ -237,3 +242,9 @@ func runConfigImages(opts convertOptions, services []string) error {
237242
}
238243
return nil
239244
}
245+
246+
func escapeDollarSign(marshal []byte) []byte {
247+
dollar := []byte{'$'}
248+
escDollar := []byte{'$', '$'}
249+
return bytes.ReplaceAll(marshal, dollar, escDollar)
250+
}

pkg/compose/compose.go

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package compose
1818

1919
import (
20-
"bytes"
2120
"context"
2221
"encoding/json"
2322
"fmt"
@@ -95,28 +94,14 @@ func getContainerNameWithoutProject(c moby.Container) string {
9594
func (s *composeService) Convert(ctx context.Context, project *types.Project, options api.ConvertOptions) ([]byte, error) {
9695
switch options.Format {
9796
case "json":
98-
marshal, err := json.MarshalIndent(project, "", " ")
99-
if err != nil {
100-
return nil, err
101-
}
102-
return escapeDollarSign(marshal), nil
97+
return json.MarshalIndent(project, "", " ")
10398
case "yaml":
104-
marshal, err := yaml.Marshal(project)
105-
if err != nil {
106-
return nil, err
107-
}
108-
return escapeDollarSign(marshal), nil
99+
return yaml.Marshal(project)
109100
default:
110101
return nil, fmt.Errorf("unsupported format %q", options)
111102
}
112103
}
113104

114-
func escapeDollarSign(marshal []byte) []byte {
115-
dollar := []byte{'$'}
116-
escDollar := []byte{'$', '$'}
117-
return bytes.ReplaceAll(marshal, dollar, escDollar)
118-
}
119-
120105
// projectFromName builds a types.Project based on actual resources with compose labels set
121106
func (s *composeService) projectFromName(containers Containers, projectName string, services ...string) (*types.Project, error) {
122107
project := &types.Project{

pkg/e2e/compose_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,25 @@ networks:
234234
name: compose-e2e-convert_default`, filepath.Join(wd, "fixtures", "simple-build-test", "nginx-build")), ExitCode: 0})
235235
})
236236
}
237+
238+
func TestConvertInterpolate(t *testing.T) {
239+
const projectName = "compose-e2e-convert-interpolate"
240+
c := NewParallelCLI(t)
241+
242+
wd, err := os.Getwd()
243+
assert.NilError(t, err)
244+
245+
t.Run("convert", func(t *testing.T) {
246+
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/simple-build-test/compose-interpolate.yaml", "-p", projectName, "convert", "--no-interpolate")
247+
res.Assert(t, icmd.Expected{Out: fmt.Sprintf(`services:
248+
nginx:
249+
build:
250+
context: %s
251+
dockerfile: ${MYVAR}
252+
networks:
253+
default: null
254+
networks:
255+
default:
256+
name: compose-e2e-convert-interpolate_default`, filepath.Join(wd, "fixtures", "simple-build-test", "nginx-build")), ExitCode: 0})
257+
})
258+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
services:
2+
nginx:
3+
build:
4+
context: nginx-build
5+
dockerfile: ${MYVAR}

0 commit comments

Comments
 (0)