summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pkg/argocd/git.go66
-rw-r--r--pkg/argocd/git_test.go12
2 files changed, 66 insertions, 12 deletions
diff --git a/pkg/argocd/git.go b/pkg/argocd/git.go
index 8ec2274..7710b98 100644
--- a/pkg/argocd/git.go
+++ b/pkg/argocd/git.go
@@ -4,6 +4,7 @@ import (
"bytes"
"crypto/sha256"
"encoding/hex"
+ "errors"
"fmt"
"os"
"path"
@@ -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"
@@ -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
}
diff --git a/pkg/argocd/git_test.go b/pkg/argocd/git_test.go
index cfd7914..7db7aad 100644
--- a/pkg/argocd/git_test.go
+++ b/pkg/argocd/git_test.go
@@ -271,6 +271,18 @@ func Test_updateKustomizeFile(t *testing.T) {
filter: filter,
},
{
+ name: "indented",
+ content: `images:
+ - name: foo
+ digest: sha12345
+`,
+ wantContent: `images:
+ - name: foo
+ digest: sha23456
+`,
+ filter: filter,
+ },
+ {
name: "no-change",
content: `images:
- name: foo