Skip to content

Commit 154f51a

Browse files
Keep yaml sequence indentation when writing back to Git to a kustomize file (#1002)
Signed-off-by: Alessandro Zanatta <[email protected]>
1 parent b155506 commit 154f51a

File tree

2 files changed

+66
-12
lines changed

2 files changed

+66
-12
lines changed

pkg/argocd/git.go

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"crypto/sha256"
66
"encoding/hex"
7+
"errors"
78
"fmt"
89
"os"
910
"path"
@@ -12,6 +13,7 @@ import (
1213

1314
"sigs.k8s.io/kustomize/api/konfig"
1415
"sigs.k8s.io/kustomize/api/types"
16+
"sigs.k8s.io/kustomize/kyaml/kio"
1517
"sigs.k8s.io/kustomize/kyaml/order"
1618
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
1719

@@ -345,43 +347,83 @@ func writeKustomization(app *v1alpha1.Application, wbc *WriteBackConfig, gitC gi
345347
}
346348

347349
// updateKustomizeFile reads the kustomization file at path, applies the filter to it, and writes the result back
348-
// to the file. This is the same behavior as kyaml.UpdateFile, but it preserves the original order
349-
// of YAML fields to minimize git diffs.
350+
// to the file. This is the same behavior as kyaml.UpdateFile, but it preserves the original order of YAML fields
351+
// and indentation of YAML sequences to minimize git diffs.
350352
func updateKustomizeFile(filter kyaml.Filter, path string) (error, bool) {
351-
// Read the yaml
352-
y, err := kyaml.ReadFile(path)
353+
// Open the input file for read
354+
yRaw, err := os.ReadFile(path)
353355
if err != nil {
354356
return err, false
355357
}
356358

357-
originalData, err := y.String()
359+
// Read the yaml document from bytes
360+
originalYSlice, err := kio.FromBytes(yRaw)
358361
if err != nil {
359362
return err, false
360363
}
361364

365+
// Check that we are dealing with a single document
366+
if len(originalYSlice) != 1 {
367+
return errors.New("target parameter file should contain a single YAML document"), false
368+
}
369+
originalY := originalYSlice[0]
370+
371+
// Get the (parsed) original document
372+
originalData, err := originalY.String()
373+
if err != nil {
374+
return err, false
375+
}
376+
377+
// Create a reader, preserving indentation of sequences
378+
var out bytes.Buffer
379+
rw := &kio.ByteReadWriter{
380+
Reader: bytes.NewBuffer(yRaw),
381+
Writer: &out,
382+
PreserveSeqIndent: true,
383+
}
384+
385+
// Read from input buffer
386+
newYSlice, err := rw.Read()
387+
if err != nil {
388+
return err, false
389+
}
390+
// We can safely assume we have a single document from the previous check
391+
newY := newYSlice[0]
392+
362393
// Update the yaml
363-
yCpy := y.Copy()
364-
if err := yCpy.PipeE(filter); err != nil {
394+
if err := newY.PipeE(filter); err != nil {
365395
return err, false
366396
}
367397

368398
// Preserve the original order of fields
369-
if err := order.SyncOrder(y, yCpy); err != nil {
399+
if err := order.SyncOrder(originalY, newY); err != nil {
370400
return err, false
371401
}
372402

373-
override, err := yCpy.String()
403+
// Write the yaml document to the output buffer
404+
if err = rw.Write([]*kyaml.RNode{newY}); err != nil {
405+
return err, false
406+
}
407+
408+
// newY contains metadata used by kio to preserve sequence indentation,
409+
// hence we need to parse the output buffer instead
410+
newParsedY, err := kyaml.Parse(out.String())
411+
if err != nil {
412+
return err, false
413+
}
414+
newData, err := newParsedY.String()
374415
if err != nil {
375416
return err, false
376417
}
377418

378-
if originalData == override {
419+
// Compare the updated document with the original document
420+
if originalData == newData {
379421
log.Debugf("target parameter file and marshaled data are the same, skipping commit.")
380422
return nil, true
381423
}
382424

383-
// Write the yaml
384-
if err := os.WriteFile(path, []byte(override), 0600); err != nil {
425+
// Write to file the changes
426+
if err := os.WriteFile(path, out.Bytes(), 0600); err != nil {
385427
return err, false
386428
}
387429

pkg/argocd/git_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,18 @@ func Test_updateKustomizeFile(t *testing.T) {
267267
wantContent: `images:
268268
- name: foo
269269
digest: sha23456
270+
`,
271+
filter: filter,
272+
},
273+
{
274+
name: "indented",
275+
content: `images:
276+
- name: foo
277+
digest: sha12345
278+
`,
279+
wantContent: `images:
280+
- name: foo
281+
digest: sha23456
270282
`,
271283
filter: filter,
272284
},

0 commit comments

Comments
 (0)