4
4
"bytes"
5
5
"crypto/sha256"
6
6
"encoding/hex"
7
+ "errors"
7
8
"fmt"
8
9
"os"
9
10
"path"
@@ -12,6 +13,7 @@ import (
12
13
13
14
"sigs.k8s.io/kustomize/api/konfig"
14
15
"sigs.k8s.io/kustomize/api/types"
16
+ "sigs.k8s.io/kustomize/kyaml/kio"
15
17
"sigs.k8s.io/kustomize/kyaml/order"
16
18
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
17
19
@@ -345,43 +347,83 @@ func writeKustomization(app *v1alpha1.Application, wbc *WriteBackConfig, gitC gi
345
347
}
346
348
347
349
// 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.
350
352
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 )
353
355
if err != nil {
354
356
return err , false
355
357
}
356
358
357
- originalData , err := y .String ()
359
+ // Read the yaml document from bytes
360
+ originalYSlice , err := kio .FromBytes (yRaw )
358
361
if err != nil {
359
362
return err , false
360
363
}
361
364
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
+
362
393
// Update the yaml
363
- yCpy := y .Copy ()
364
- if err := yCpy .PipeE (filter ); err != nil {
394
+ if err := newY .PipeE (filter ); err != nil {
365
395
return err , false
366
396
}
367
397
368
398
// Preserve the original order of fields
369
- if err := order .SyncOrder (y , yCpy ); err != nil {
399
+ if err := order .SyncOrder (originalY , newY ); err != nil {
370
400
return err , false
371
401
}
372
402
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 ()
374
415
if err != nil {
375
416
return err , false
376
417
}
377
418
378
- if originalData == override {
419
+ // Compare the updated document with the original document
420
+ if originalData == newData {
379
421
log .Debugf ("target parameter file and marshaled data are the same, skipping commit." )
380
422
return nil , true
381
423
}
382
424
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 {
385
427
return err , false
386
428
}
387
429
0 commit comments