...
1
2
3
4 package kio
5
6 import (
7 "encoding/json"
8 "io"
9 "path/filepath"
10
11 "sigs.k8s.io/kustomize/kyaml/errors"
12 "sigs.k8s.io/kustomize/kyaml/kio/kioutil"
13 "sigs.k8s.io/kustomize/kyaml/yaml"
14 )
15
16
17
18
19
20 type ByteWriter struct {
21
22 Writer io.Writer
23
24
25
26 KeepReaderAnnotations bool
27
28
29 ClearAnnotations []string
30
31
32 Style yaml.Style
33
34
35
36 FunctionConfig *yaml.RNode
37
38 Results *yaml.RNode
39
40
41
42
43 WrappingKind string
44
45
46 WrappingAPIVersion string
47
48
49 Sort bool
50 }
51
52 var _ Writer = ByteWriter{}
53
54 func (w ByteWriter) Write(inputNodes []*yaml.RNode) error {
55
56 nodes := copyRNodes(inputNodes)
57 if w.Sort {
58 if err := kioutil.SortNodes(nodes); err != nil {
59 return errors.Wrap(err)
60 }
61 }
62
63
64 jsonEncodeSingleBareNode := w.shouldJSONEncodeSingleBareNode(nodes)
65
66
67 var seqIndentsForNodes []string
68 for i := range nodes {
69 seqIndentsForNodes = append(seqIndentsForNodes, nodes[i].GetAnnotations()[kioutil.SeqIndentAnnotation])
70 }
71
72 for i := range nodes {
73
74 if !w.KeepReaderAnnotations {
75 _, err := nodes[i].Pipe(yaml.ClearAnnotation(kioutil.IndexAnnotation))
76 if err != nil {
77 return errors.Wrap(err)
78 }
79 _, err = nodes[i].Pipe(yaml.ClearAnnotation(kioutil.LegacyIndexAnnotation))
80 if err != nil {
81 return errors.Wrap(err)
82 }
83
84 _, err = nodes[i].Pipe(yaml.ClearAnnotation(kioutil.SeqIndentAnnotation))
85 if err != nil {
86 return errors.Wrap(err)
87 }
88 }
89 for _, a := range w.ClearAnnotations {
90 _, err := nodes[i].Pipe(yaml.ClearAnnotation(a))
91 if err != nil {
92 return errors.Wrap(err)
93 }
94 }
95
96 if err := yaml.ClearEmptyAnnotations(nodes[i]); err != nil {
97 return err
98 }
99
100 if w.Style != 0 {
101 nodes[i].YNode().Style = w.Style
102 }
103 }
104
105 if jsonEncodeSingleBareNode {
106 encoder := json.NewEncoder(w.Writer)
107 encoder.SetIndent("", " ")
108 return errors.Wrap(encoder.Encode(nodes[0]))
109 }
110
111 encoder := yaml.NewEncoder(w.Writer)
112 defer encoder.Close()
113
114 if w.WrappingKind == "" {
115 for i := range nodes {
116 if seqIndentsForNodes[i] == string(yaml.WideSequenceStyle) {
117 encoder.DefaultSeqIndent()
118 } else {
119 encoder.CompactSeqIndent()
120 }
121 if err := encoder.Encode(upWrapBareSequenceNode(nodes[i].Document())); err != nil {
122 return errors.Wrap(err)
123 }
124 }
125 return nil
126 }
127
128 items := &yaml.Node{Kind: yaml.SequenceNode}
129 list := &yaml.Node{
130 Kind: yaml.MappingNode,
131 Style: w.Style,
132 Content: []*yaml.Node{
133 {Kind: yaml.ScalarNode, Value: "apiVersion"},
134 {Kind: yaml.ScalarNode, Value: w.WrappingAPIVersion},
135 {Kind: yaml.ScalarNode, Value: "kind"},
136 {Kind: yaml.ScalarNode, Value: w.WrappingKind},
137 {Kind: yaml.ScalarNode, Value: "items"}, items,
138 }}
139 if w.FunctionConfig != nil {
140 list.Content = append(list.Content,
141 &yaml.Node{Kind: yaml.ScalarNode, Value: "functionConfig"},
142 w.FunctionConfig.YNode())
143 }
144 if w.Results != nil {
145 list.Content = append(list.Content,
146 &yaml.Node{Kind: yaml.ScalarNode, Value: "results"},
147 w.Results.YNode())
148 }
149 doc := &yaml.Node{
150 Kind: yaml.DocumentNode,
151 Content: []*yaml.Node{list}}
152 for i := range nodes {
153 items.Content = append(items.Content, nodes[i].YNode())
154 }
155 return encoder.Encode(doc)
156 }
157
158 func copyRNodes(in []*yaml.RNode) []*yaml.RNode {
159 out := make([]*yaml.RNode, len(in))
160 for i := range in {
161 out[i] = in[i].Copy()
162 }
163 return out
164 }
165
166
167
168
169
170
171
172
173
174
175
176 func (w ByteWriter) shouldJSONEncodeSingleBareNode(nodes []*yaml.RNode) bool {
177 if w.WrappingKind == "" && len(nodes) == 1 {
178 if path, _, _ := kioutil.GetFileAnnotations(nodes[0]); path != "" {
179 filename := filepath.Base(path)
180 for _, glob := range JSONMatch {
181 if match, _ := filepath.Match(glob, filename); match {
182 return true
183 }
184 }
185 }
186 }
187 return false
188 }
189
190
191 func upWrapBareSequenceNode(node *yaml.Node) *yaml.Node {
192 rNode := yaml.NewRNode(node)
193 seqNode, err := rNode.Pipe(yaml.Lookup(yaml.BareSeqNodeWrappingKey))
194 if err == nil && !seqNode.IsNilOrEmpty() {
195 return seqNode.YNode()
196 }
197 return node
198 }
199
View as plain text