@@ -22,13 +22,48 @@ const (
22
22
indexIgnoreFilename = ".indexignore"
23
23
)
24
24
25
+ type WalkMetasFunc func (path string , meta * Meta , err error ) error
26
+
27
+ func WalkMetasFS (root fs.FS , walkFn WalkMetasFunc ) error {
28
+ return walkFiles (root , func (root fs.FS , path string , err error ) error {
29
+ if err != nil {
30
+ return walkFn (path , nil , err )
31
+ }
32
+
33
+ f , err := root .Open (path )
34
+ if err != nil {
35
+ return walkFn (path , nil , err )
36
+ }
37
+ defer f .Close ()
38
+
39
+ return walkMetasReader (f , func (meta * Meta ) error {
40
+ return walkFn (path , meta , nil )
41
+ })
42
+ })
43
+ }
44
+
25
45
type WalkFunc func (path string , cfg * DeclarativeConfig , err error ) error
26
46
27
47
// WalkFS walks root using a gitignore-style filename matcher to skip files
28
48
// that match patterns found in .indexignore files found throughout the filesystem.
29
49
// It calls walkFn for each declarative config file it finds. If WalkFS encounters
30
50
// an error loading or parsing any file, the error will be immediately returned.
31
51
func WalkFS (root fs.FS , walkFn WalkFunc ) error {
52
+ return walkFiles (root , func (root fs.FS , path string , err error ) error {
53
+ if err != nil {
54
+ return walkFn (path , nil , err )
55
+ }
56
+
57
+ cfg , err := LoadFile (root , path )
58
+ if err != nil {
59
+ return walkFn (path , cfg , err )
60
+ }
61
+
62
+ return walkFn (path , cfg , nil )
63
+ })
64
+ }
65
+
66
+ func walkFiles (root fs.FS , fn func (root fs.FS , path string , err error ) error ) error {
32
67
if root == nil {
33
68
return fmt .Errorf ("no declarative config filesystem provided" )
34
69
}
@@ -40,20 +75,15 @@ func WalkFS(root fs.FS, walkFn WalkFunc) error {
40
75
41
76
return fs .WalkDir (root , "." , func (path string , info fs.DirEntry , err error ) error {
42
77
if err != nil {
43
- return walkFn ( path , nil , err )
78
+ return fn ( root , path , err )
44
79
}
45
80
// avoid validating a directory, an .indexignore file, or any file that matches
46
81
// an ignore pattern outlined in a .indexignore file.
47
82
if info .IsDir () || info .Name () == indexIgnoreFilename || matcher .Match (path , false ) {
48
83
return nil
49
84
}
50
85
51
- cfg , err := LoadFile (root , path )
52
- if err != nil {
53
- return walkFn (path , cfg , err )
54
- }
55
-
56
- return walkFn (path , cfg , err )
86
+ return fn (root , path , nil )
57
87
})
58
88
}
59
89
@@ -123,46 +153,35 @@ func extractCSV(objs []string) string {
123
153
// Path references will not be de-referenced so callers are responsible for de-referencing if necessary.
124
154
func LoadReader (r io.Reader ) (* DeclarativeConfig , error ) {
125
155
cfg := & DeclarativeConfig {}
126
- dec := yaml .NewYAMLOrJSONDecoder (r , 4096 )
127
- for {
128
- doc := json.RawMessage {}
129
- if err := dec .Decode (& doc ); err != nil {
130
- if errors .Is (err , io .EOF ) {
131
- break
132
- }
133
- return nil , err
134
- }
135
- doc = []byte (strings .NewReplacer (`\u003c` , "<" , `\u003e` , ">" , `\u0026` , "&" ).Replace (string (doc )))
136
-
137
- var in Meta
138
- if err := json .Unmarshal (doc , & in ); err != nil {
139
- return nil , fmt .Errorf ("unmarshal error: %s" , resolveUnmarshalErr (doc , err ))
140
- }
141
156
157
+ if err := walkMetasReader (r , func (in * Meta ) error {
142
158
switch in .Schema {
143
159
case SchemaPackage :
144
160
var p Package
145
- if err := json .Unmarshal (doc , & p ); err != nil {
146
- return nil , fmt .Errorf ("parse package: %v" , err )
161
+ if err := json .Unmarshal (in . Blob , & p ); err != nil {
162
+ return fmt .Errorf ("parse package: %v" , err )
147
163
}
148
164
cfg .Packages = append (cfg .Packages , p )
149
165
case SchemaChannel :
150
166
var c Channel
151
- if err := json .Unmarshal (doc , & c ); err != nil {
152
- return nil , fmt .Errorf ("parse channel: %v" , err )
167
+ if err := json .Unmarshal (in . Blob , & c ); err != nil {
168
+ return fmt .Errorf ("parse channel: %v" , err )
153
169
}
154
170
cfg .Channels = append (cfg .Channels , c )
155
171
case SchemaBundle :
156
172
var b Bundle
157
- if err := json .Unmarshal (doc , & b ); err != nil {
158
- return nil , fmt .Errorf ("parse bundle: %v" , err )
173
+ if err := json .Unmarshal (in . Blob , & b ); err != nil {
174
+ return fmt .Errorf ("parse bundle: %v" , err )
159
175
}
160
176
cfg .Bundles = append (cfg .Bundles , b )
161
177
case "" :
162
- return nil , fmt .Errorf ("object '%s' is missing root schema field" , string (doc ))
178
+ return fmt .Errorf ("object '%s' is missing root schema field" , string (in . Blob ))
163
179
default :
164
- cfg .Others = append (cfg .Others , in )
180
+ cfg .Others = append (cfg .Others , * in )
165
181
}
182
+ return nil
183
+ }); err != nil {
184
+ return nil , err
166
185
}
167
186
return cfg , nil
168
187
}
@@ -188,6 +207,30 @@ func LoadFile(root fs.FS, path string) (*DeclarativeConfig, error) {
188
207
return cfg , nil
189
208
}
190
209
210
+ func walkMetasReader (r io.Reader , fn func (* Meta ) error ) error {
211
+ dec := yaml .NewYAMLOrJSONDecoder (r , 4096 )
212
+ for {
213
+ doc := json.RawMessage {}
214
+ if err := dec .Decode (& doc ); err != nil {
215
+ if errors .Is (err , io .EOF ) {
216
+ break
217
+ }
218
+ return err
219
+ }
220
+ doc = []byte (strings .NewReplacer (`\u003c` , "<" , `\u003e` , ">" , `\u0026` , "&" ).Replace (string (doc )))
221
+
222
+ var in Meta
223
+ if err := json .Unmarshal (doc , & in ); err != nil {
224
+ return fmt .Errorf ("unmarshal error: %s" , resolveUnmarshalErr (doc , err ))
225
+ }
226
+
227
+ if err := fn (& in ); err != nil {
228
+ return err
229
+ }
230
+ }
231
+ return nil
232
+ }
233
+
191
234
func resolveUnmarshalErr (data []byte , err error ) string {
192
235
var te * json.UnmarshalTypeError
193
236
if errors .As (err , & te ) {
@@ -213,10 +256,10 @@ func formatUnmarshallErrorString(data []byte, errmsg string, offset int64) strin
213
256
var pOffset , origOffset int64
214
257
origOffset = 0
215
258
for origOffset = 0 ; origOffset < offset ; {
216
- pOffset ++
217
259
if pString [pOffset ] != '\n' && pString [pOffset ] != ' ' {
218
260
origOffset ++
219
261
}
262
+ pOffset ++
220
263
}
221
264
_ , _ = sb .WriteString (pString [:pOffset ])
222
265
_ , _ = sb .WriteString (" <== " )
0 commit comments