@@ -131,44 +131,58 @@ func (*Optic) WithOverride(ctx context.Context, override *config.Linter) (linter
131
131
// output by Optic CI. Returns an error when lint fails configured rules.
132
132
func (o * Optic ) Run (ctx context.Context , paths ... string ) error {
133
133
var errs error
134
+ var comparisons []comparison
135
+ var dockerArgs []string
134
136
for i := range paths {
135
- err := o .runCompare ( ctx , paths [i ])
137
+ comparison , volumeArgs , err := o .newComparison ( paths [i ])
136
138
if err != nil {
137
139
errs = multierr .Append (errs , err )
140
+ } else {
141
+ comparisons = append (comparisons , comparison )
142
+ dockerArgs = append (dockerArgs , volumeArgs ... )
138
143
}
139
144
}
145
+ err := o .bulkCompare (ctx , comparisons , dockerArgs )
146
+ errs = multierr .Append (errs , err )
140
147
return errs
141
148
}
142
149
143
- var opticOutputRE = regexp .MustCompile (`/(from|to)` )
150
+ type comparison struct {
151
+ From string `json:"from"`
152
+ To string `json:"to"`
153
+ Context Context `json:"context"`
154
+ }
155
+
156
+ type bulkCompareInput struct {
157
+ Comparisons []comparison `json:"comparisons"`
158
+ }
144
159
145
- func (o * Optic ) runCompare ( ctx context. Context , path string ) error {
160
+ func (o * Optic ) newComparison ( path string ) ( comparison , [] string , error ) {
146
161
cwd , err := os .Getwd ()
147
162
if err != nil {
148
- return err
163
+ return comparison {}, nil , err
149
164
}
150
- var compareArgs , volumeArgs []string
165
+ var volumeArgs []string
151
166
152
167
// TODO: This assumes the file being linted is a resource version spec
153
168
// file, and not a compiled one. We don't yet have rules that support
154
169
// diffing _compiled_ specs; that will require a different context and rule
155
170
// set for Vervet Underground integration.
156
171
opticCtx , err := o .contextFromPath (path )
157
172
if err != nil {
158
- return fmt .Errorf ("failed to get context from path %q: %w" , path , err )
173
+ return comparison {}, nil , fmt .Errorf ("failed to get context from path %q: %w" , path , err )
159
174
}
160
- opticCtxJson , err := json . Marshal ( & opticCtx )
161
- if err != nil {
162
- return err
175
+
176
+ cmp := comparison {
177
+ Context : * opticCtx ,
163
178
}
164
- compareArgs = append (compareArgs , "--context" , string (opticCtxJson ))
165
179
166
180
fromFile , err := o .fromSource .Fetch (path )
167
181
if err != nil {
168
- return err
182
+ return comparison {}, nil , err
169
183
}
170
184
if fromFile != "" {
171
- compareArgs = append ( compareArgs , "--from" , " /from/"+ path )
185
+ cmp . From = " /from/" + path
172
186
volumeArgs = append (volumeArgs ,
173
187
"-v" , cwd + ":/from" ,
174
188
"-v" , fromFile + ":/from/" + path ,
@@ -177,21 +191,42 @@ func (o *Optic) runCompare(ctx context.Context, path string) error {
177
191
178
192
toFile , err := o .toSource .Fetch (path )
179
193
if err != nil {
180
- return err
194
+ return comparison {}, nil , err
181
195
}
182
196
if toFile != "" {
183
- compareArgs = append ( compareArgs , "--to" , " /to/"+ path )
197
+ cmp . To = " /to/" + path
184
198
volumeArgs = append (volumeArgs ,
185
199
"-v" , cwd + ":/to" ,
186
200
"-v" , toFile + ":/to/" + path ,
187
201
)
188
202
}
189
203
190
- // TODO: provide context JSON object in --context
204
+ return cmp , volumeArgs , nil
205
+ }
206
+
207
+ var opticFromOutputRE = regexp .MustCompile (`/from/` )
208
+ var opticToOutputRE = regexp .MustCompile (`/to/` )
209
+
210
+ func (o * Optic ) bulkCompare (ctx context.Context , comparisons []comparison , dockerArgs []string ) error {
211
+ input := & bulkCompareInput {
212
+ Comparisons : comparisons ,
213
+ }
214
+ inputFile , err := ioutil .TempFile ("" , "*-input.json" )
215
+ if err != nil {
216
+ return err
217
+ }
218
+ defer inputFile .Close ()
219
+ err = json .NewEncoder (inputFile ).Encode (& input )
220
+ if err != nil {
221
+ return err
222
+ }
223
+ if err := inputFile .Sync (); err != nil {
224
+ return err
225
+ }
226
+
191
227
// TODO: link to command line arguments for optic-ci when available.
192
- cmdline := append ([]string {"run" , "--rm" }, volumeArgs ... )
193
- cmdline = append (cmdline , o .image , "compare" )
194
- cmdline = append (cmdline , compareArgs ... )
228
+ cmdline := append ([]string {"run" , "--rm" , "-v" , inputFile .Name () + ":/input.json" }, dockerArgs ... )
229
+ cmdline = append (cmdline , o .image , "bulk-compare" , "--input" , "/input.json" )
195
230
log .Println (cmdline )
196
231
cmd := exec .CommandContext (ctx , "docker" , cmdline ... )
197
232
@@ -216,7 +251,10 @@ func (o *Optic) runCompare(ctx context.Context, path string) error {
216
251
defer pipeReader .Close ()
217
252
sc := bufio .NewScanner (pipeReader )
218
253
for sc .Scan () {
219
- fmt .Println (opticOutputRE .ReplaceAllLiteralString (sc .Text (), cwd ))
254
+ line := sc .Text ()
255
+ line = opticFromOutputRE .ReplaceAllString (line , "(" + o .fromSource .Name ()+ "):" )
256
+ line = opticToOutputRE .ReplaceAllString (line , "(" + o .toSource .Name ()+ "):" )
257
+ fmt .Println (line )
220
258
}
221
259
if err := sc .Err (); err != nil {
222
260
fmt .Fprintf (os .Stderr , "error reading stdout: %v" , err )
@@ -228,7 +266,7 @@ func (o *Optic) runCompare(ctx context.Context, path string) error {
228
266
cmd .Stderr = os .Stderr
229
267
err = o .runner .run (cmd )
230
268
if err != nil {
231
- return fmt .Errorf ("lint %q failed: %w" , path , err )
269
+ return fmt .Errorf ("lint failed: %w" , err )
232
270
}
233
271
return nil
234
272
}
0 commit comments