Skip to content

Commit 2a51251

Browse files
committed
builder: Add merge dirs test
Signed-off-by: Stefan Prodan <[email protected]>
1 parent b18386b commit 2a51251

File tree

2 files changed

+87
-4
lines changed

2 files changed

+87
-4
lines changed

docs/spec/v1beta1/artifactgenerators.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,8 @@ Each copy operation specifies how to copy files from sources into the generated
268268
the root of the generated artifact and `path` is the relative path to a file or directory.
269269
- `exclude` (optional): A list of glob patterns to filter out from the source selection.
270270
Any file matched by `from` that also matches an exclude pattern will be ignored.
271-
- `strategy` (optional): Can be `Overwrite` (default) or `Merge`. The `Merge` strategy
272-
only works for YAML files and merges using the same logic as Helm for `values.yaml` files.
271+
- `strategy` (optional): Defines how to handle existing files at the destination,
272+
either `Overwrite` (default) or `Merge` (for YAML files only).
273273

274274
Copy operations use `cp`-like semantics:
275275

@@ -304,6 +304,14 @@ Examples of copy operations:
304304
- "**/testdata/**" # Excludes all files under any testdata/ dir
305305
```
306306
307+
#### Copy Strategies
308+
309+
By default, copy operations use the `Overwrite` strategy, where later copies
310+
overwrite files from earlier ones.
311+
312+
When copying YAML files, the `Merge` strategy can be used to merge the contents
313+
from the source file into the destination file.
314+
307315
Example of copy with `Merge` strategy:
308316

309317
```yaml
@@ -316,8 +324,8 @@ Example of copy with `Merge` strategy:
316324
strategy: Merge
317325
```
318326
319-
**Note** that the merge strategy will replace _arrays_ entirely,
320-
the behavior is the same as Helm's `values.yaml` merging.
327+
**Note** that the merge strategy will replace _arrays_ entirely, the behavior is
328+
identical to how Helm merges `values.yaml` files when using multiple `--values` flags.
321329

322330
## Working with ArtifactGenerators
323331

internal/builder/merge_test.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,81 @@ env: production
165165
a: override
166166
c:
167167
d: e
168+
`))
169+
},
170+
},
171+
{
172+
name: "merge YAML in dirs successfully",
173+
setupFunc: func(t *testing.T) (*swapi.OutputArtifact, map[string]string, string) {
174+
tmpDir := t.TempDir()
175+
source1Dir := filepath.Join(tmpDir, "source1")
176+
source2Dir := filepath.Join(tmpDir, "source2")
177+
workspaceDir := filepath.Join(tmpDir, "workspace")
178+
179+
setupDirs(t, source1Dir, source2Dir, workspaceDir)
180+
181+
// Create first source with base config
182+
createFile(t, source1Dir, "config1.yaml", `
183+
env: dev
184+
region: us-west-1
185+
`)
186+
createFile(t, source1Dir, "config2.yaml", `
187+
version: 1.0.0
188+
image: my-app:latest
189+
`)
190+
191+
// Create second source with overlay config
192+
createFile(t, source2Dir, "config1.yaml", "env: prod") // This should overwrite the env
193+
createFile(t, source2Dir, "config2.yaml", "replicas: 5") // This should add a new field
194+
195+
spec := &swapi.OutputArtifact{
196+
Name: "yaml-to-yaml-dir-merge",
197+
Copy: []swapi.CopyOperation{
198+
{
199+
From: "@source1/**",
200+
To: "@artifact/",
201+
Strategy: swapi.OverwriteStrategy,
202+
},
203+
{
204+
From: "@source2/**",
205+
To: "@artifact/",
206+
Strategy: swapi.MergeStrategy,
207+
},
208+
},
209+
}
210+
211+
sources := map[string]string{
212+
"source1": source1Dir,
213+
"source2": source2Dir,
214+
}
215+
return spec, sources, workspaceDir
216+
},
217+
validateFunc: func(t *testing.T, artifact *gotkmeta.Artifact, workspaceDir string) {
218+
g := NewWithT(t)
219+
g.Expect(artifact).ToNot(BeNil())
220+
221+
// Read the merged config from staging directory
222+
stagingDir := filepath.Join(workspaceDir, "yaml-to-yaml-dir-merge")
223+
config1Path := filepath.Join(stagingDir, "config1.yaml")
224+
config2Path := filepath.Join(stagingDir, "config2.yaml")
225+
226+
config1Content, err := os.ReadFile(config1Path)
227+
g.Expect(err).ToNot(HaveOccurred())
228+
g.Expect(config1Content).ToNot(BeEmpty())
229+
230+
config2Content, err := os.ReadFile(config2Path)
231+
g.Expect(err).ToNot(HaveOccurred())
232+
g.Expect(config2Content).ToNot(BeEmpty())
233+
234+
// Verify the merged YAML contains expected content
235+
g.Expect(config1Content).To(MatchYAML(`
236+
env: prod
237+
region: us-west-1
238+
`))
239+
g.Expect(config2Content).To(MatchYAML(`
240+
image: my-app:latest
241+
replicas: 5
242+
version: 1.0.0
168243
`))
169244
},
170245
},

0 commit comments

Comments
 (0)