Skip to content

Commit

Permalink
Keep yaml sequence indentation when writing back to Git to a kustomiz…
Browse files Browse the repository at this point in the history
…e file (#1002)

Signed-off-by: Alessandro Zanatta <[email protected]>
  • Loading branch information
AlessandroZanatta authored Jan 14, 2025
1 parent b155506 commit 154f51a
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 12 deletions.
66 changes: 54 additions & 12 deletions pkg/argocd/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"os"
"path"
Expand All @@ -12,6 +13,7 @@ import (

"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/order"
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"

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

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

originalData, err := y.String()
// Read the yaml document from bytes
originalYSlice, err := kio.FromBytes(yRaw)
if err != nil {
return err, false
}

// Check that we are dealing with a single document
if len(originalYSlice) != 1 {
return errors.New("target parameter file should contain a single YAML document"), false
}
originalY := originalYSlice[0]

// Get the (parsed) original document
originalData, err := originalY.String()
if err != nil {
return err, false
}

// Create a reader, preserving indentation of sequences
var out bytes.Buffer
rw := &kio.ByteReadWriter{
Reader: bytes.NewBuffer(yRaw),
Writer: &out,
PreserveSeqIndent: true,
}

// Read from input buffer
newYSlice, err := rw.Read()
if err != nil {
return err, false
}
// We can safely assume we have a single document from the previous check
newY := newYSlice[0]

// Update the yaml
yCpy := y.Copy()
if err := yCpy.PipeE(filter); err != nil {
if err := newY.PipeE(filter); err != nil {
return err, false
}

// Preserve the original order of fields
if err := order.SyncOrder(y, yCpy); err != nil {
if err := order.SyncOrder(originalY, newY); err != nil {
return err, false
}

override, err := yCpy.String()
// Write the yaml document to the output buffer
if err = rw.Write([]*kyaml.RNode{newY}); err != nil {
return err, false
}

// newY contains metadata used by kio to preserve sequence indentation,
// hence we need to parse the output buffer instead
newParsedY, err := kyaml.Parse(out.String())
if err != nil {
return err, false
}
newData, err := newParsedY.String()
if err != nil {
return err, false
}

if originalData == override {
// Compare the updated document with the original document
if originalData == newData {
log.Debugf("target parameter file and marshaled data are the same, skipping commit.")
return nil, true
}

// Write the yaml
if err := os.WriteFile(path, []byte(override), 0600); err != nil {
// Write to file the changes
if err := os.WriteFile(path, out.Bytes(), 0600); err != nil {
return err, false
}

Expand Down
12 changes: 12 additions & 0 deletions pkg/argocd/git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,18 @@ func Test_updateKustomizeFile(t *testing.T) {
wantContent: `images:
- name: foo
digest: sha23456
`,
filter: filter,
},
{
name: "indented",
content: `images:
- name: foo
digest: sha12345
`,
wantContent: `images:
- name: foo
digest: sha23456
`,
filter: filter,
},
Expand Down

0 comments on commit 154f51a

Please sign in to comment.