5
5
package main
6
6
7
7
import (
8
- "bytes"
9
8
"context"
10
9
"flag"
11
10
"fmt"
@@ -21,6 +20,7 @@ import (
21
20
"github.com/golang/dep/gps"
22
21
"github.com/golang/dep/gps/paths"
23
22
"github.com/golang/dep/gps/pkgtree"
23
+ "github.com/golang/dep/gps/verify"
24
24
"github.com/pkg/errors"
25
25
)
26
26
@@ -184,6 +184,33 @@ func (cmd *ensureCommand) Run(ctx *dep.Ctx, args []string) error {
184
184
return cmd .runVendorOnly (ctx , args , p , sm , params )
185
185
}
186
186
187
+ statchan := make (chan map [string ]verify.VendorStatus )
188
+ var lps []gps.LockedProject
189
+ if p .Lock != nil {
190
+ lps = p .Lock .Projects ()
191
+ }
192
+ go func (vendorDir string , p []gps.LockedProject ) {
193
+ // Make sure vendor dir exists
194
+ err := os .MkdirAll (vendorDir , os .FileMode (0777 ))
195
+ if err != nil {
196
+ ctx .Err .Printf ("Error creating vendor directory: %q" , err .Error ())
197
+ // TODO(sdboyer) handle these better
198
+ os .Exit (1 )
199
+ }
200
+
201
+ sums := make (map [string ]verify.VersionedDigest )
202
+ for _ , lp := range p {
203
+ sums [string (lp .Ident ().ProjectRoot )] = lp .(verify.VerifiableProject ).Digest
204
+ }
205
+
206
+ status , err := verify .VerifyDepTree (vendorDir , sums )
207
+ if err != nil {
208
+ ctx .Err .Printf ("Error while verifying vendor directory: %q" , err .Error ())
209
+ os .Exit (1 )
210
+ }
211
+ statchan <- status
212
+ }(filepath .Join (p .AbsRoot , "vendor" ), lps )
213
+
187
214
params .RootPackageTree , err = p .ParseRootPackageTree ()
188
215
if err != nil {
189
216
return err
@@ -212,11 +239,11 @@ func (cmd *ensureCommand) Run(ctx *dep.Ctx, args []string) error {
212
239
}
213
240
214
241
if cmd .add {
215
- return cmd .runAdd (ctx , args , p , sm , params )
242
+ return cmd .runAdd (ctx , args , p , sm , params , statchan )
216
243
} else if cmd .update {
217
- return cmd .runUpdate (ctx , args , p , sm , params )
244
+ return cmd .runUpdate (ctx , args , p , sm , params , statchan )
218
245
}
219
- return cmd .runDefault (ctx , args , p , sm , params )
246
+ return cmd .runDefault (ctx , args , p , sm , params , statchan )
220
247
}
221
248
222
249
func (cmd * ensureCommand ) validateFlags () error {
@@ -246,7 +273,7 @@ func (cmd *ensureCommand) vendorBehavior() dep.VendorBehavior {
246
273
return dep .VendorOnChanged
247
274
}
248
275
249
- func (cmd * ensureCommand ) runDefault (ctx * dep.Ctx , args []string , p * dep.Project , sm gps.SourceManager , params gps.SolveParameters ) error {
276
+ func (cmd * ensureCommand ) runDefault (ctx * dep.Ctx , args []string , p * dep.Project , sm gps.SourceManager , params gps.SolveParameters , statchan chan map [ string ]verify. VendorStatus ) error {
250
277
// Bare ensure doesn't take any args.
251
278
if len (args ) != 0 {
252
279
return errors .New ("dep ensure only takes spec arguments with -add or -update" )
@@ -256,52 +283,37 @@ func (cmd *ensureCommand) runDefault(ctx *dep.Ctx, args []string, p *dep.Project
256
283
return err
257
284
}
258
285
259
- if lsat , err := p .LockSatisfiesInputs (sm ); err != nil {
260
- return err
261
- } else if ! lsat .Passes () {
262
- if ctx .Verbose {
263
- ctx .Out .Printf ("%s was already in sync with imports and %s\n " , dep .LockName , dep .ManifestName )
264
- }
286
+ lock := p .Lock
287
+ if lock != nil {
288
+ lsat := verify .LockSatisfiesInputs (p .Lock , p .Lock .SolveMeta .InputImports , p .Manifest , params .RootPackageTree )
289
+ if ! lsat .Passed () {
290
+ // TODO(sdboyer) print out what bits are unsatisfied here
291
+ solver , err := gps .Prepare (params , sm )
292
+ if err != nil {
293
+ return errors .Wrap (err , "prepare solver" )
294
+ }
265
295
266
- if cmd .noVendor {
296
+ if cmd .noVendor && cmd .dryRun {
297
+ return errors .New ("Gopkg.lock was not up to date" )
298
+ }
299
+
300
+ solution , err := solver .Solve (context .TODO ())
301
+ if err != nil {
302
+ return handleAllTheFailuresOfTheWorld (err )
303
+ }
304
+ lock = dep .LockFromSolution (solution , p .Manifest .PruneOptions )
305
+ } else if cmd .noVendor {
267
306
// The user said not to touch vendor/, so definitely nothing to do.
268
307
return nil
269
308
}
270
309
271
- sw , err := dep .NewSafeWriter (nil , p .Lock , p .Lock , dep .VendorOnChanged , p .Manifest .PruneOptions )
272
- if err != nil {
273
- return err
274
- }
275
-
276
- if cmd .dryRun {
277
- return sw .PrintPreparedActions (ctx .Out , ctx .Verbose )
278
- }
279
-
280
- var logger * log.Logger
281
- if ctx .Verbose {
282
- logger = ctx .Err
283
- }
284
- return errors .WithMessage (sw .Write (p .AbsRoot , sm , true , logger ), "grouped write of manifest, lock and vendor" )
285
310
}
286
311
287
- solver , err := gps .Prepare (params , sm )
288
- if err != nil {
289
- return errors .Wrap (err , "prepare solver" )
290
- }
291
-
292
- if cmd .noVendor && cmd .dryRun {
293
- return errors .New ("Gopkg.lock was not up to date" )
294
- }
295
-
296
- solution , err := solver .Solve (context .TODO ())
297
- if err != nil {
298
- return handleAllTheFailuresOfTheWorld (err )
299
- }
300
-
301
- sw , err := dep .NewSafeWriter (nil , p .Lock , dep .LockFromSolution (solution ), cmd .vendorBehavior (), p .Manifest .PruneOptions )
312
+ sw , err := dep .NewDeltaWriter (p .Lock , lock , <- statchan , p .Manifest .PruneOptions , filepath .Join (p .AbsRoot , "vendor" ))
302
313
if err != nil {
303
314
return err
304
315
}
316
+
305
317
if cmd .dryRun {
306
318
return sw .PrintPreparedActions (ctx .Out , ctx .Verbose )
307
319
}
@@ -310,7 +322,7 @@ func (cmd *ensureCommand) runDefault(ctx *dep.Ctx, args []string, p *dep.Project
310
322
if ctx .Verbose {
311
323
logger = ctx .Err
312
324
}
313
- return errors .Wrap (sw .Write (p .AbsRoot , sm , false , logger ), "grouped write of manifest, lock and vendor" )
325
+ return errors .WithMessage (sw .Write (p .AbsRoot , sm , true , logger ), "grouped write of manifest, lock and vendor" )
314
326
}
315
327
316
328
func (cmd * ensureCommand ) runVendorOnly (ctx * dep.Ctx , args []string , p * dep.Project , sm gps.SourceManager , params gps.SolveParameters ) error {
@@ -339,7 +351,7 @@ func (cmd *ensureCommand) runVendorOnly(ctx *dep.Ctx, args []string, p *dep.Proj
339
351
return errors .WithMessage (sw .Write (p .AbsRoot , sm , true , logger ), "grouped write of manifest, lock and vendor" )
340
352
}
341
353
342
- func (cmd * ensureCommand ) runUpdate (ctx * dep.Ctx , args []string , p * dep.Project , sm gps.SourceManager , params gps.SolveParameters ) error {
354
+ func (cmd * ensureCommand ) runUpdate (ctx * dep.Ctx , args []string , p * dep.Project , sm gps.SourceManager , params gps.SolveParameters , statchan chan map [ string ]verify. VendorStatus ) error {
343
355
if p .Lock == nil {
344
356
return errors .Errorf ("-update works by updating the versions recorded in %s, but %s does not exist" , dep .LockName , dep .LockName )
345
357
}
@@ -348,14 +360,6 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
348
360
return err
349
361
}
350
362
351
- // We'll need to discard this prepared solver as later work changes params,
352
- // but solver preparation is cheap and worth doing up front in order to
353
- // perform the fastpath check of hash comparison.
354
- solver , err := gps .Prepare (params , sm )
355
- if err != nil {
356
- return errors .Wrap (err , "fastpath solver prepare" )
357
- }
358
-
359
363
// When -update is specified without args, allow every dependency to change
360
364
// versions, regardless of the lock file.
361
365
if len (args ) == 0 {
@@ -367,7 +371,7 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
367
371
}
368
372
369
373
// Re-prepare a solver now that our params are complete.
370
- solver , err = gps .Prepare (params , sm )
374
+ solver , err : = gps .Prepare (params , sm )
371
375
if err != nil {
372
376
return errors .Wrap (err , "fastpath solver prepare" )
373
377
}
@@ -379,7 +383,7 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
379
383
return handleAllTheFailuresOfTheWorld (err )
380
384
}
381
385
382
- sw , err := dep .NewSafeWriter (nil , p .Lock , dep .LockFromSolution (solution ), cmd .vendorBehavior (), p .Manifest .PruneOptions )
386
+ sw , err := dep .NewSafeWriter (nil , p .Lock , dep .LockFromSolution (solution , p . Manifest . PruneOptions ), cmd .vendorBehavior (), p .Manifest .PruneOptions )
383
387
if err != nil {
384
388
return err
385
389
}
@@ -394,7 +398,7 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
394
398
return errors .Wrap (sw .Write (p .AbsRoot , sm , false , logger ), "grouped write of manifest, lock and vendor" )
395
399
}
396
400
397
- func (cmd * ensureCommand ) runAdd (ctx * dep.Ctx , args []string , p * dep.Project , sm gps.SourceManager , params gps.SolveParameters ) error {
401
+ func (cmd * ensureCommand ) runAdd (ctx * dep.Ctx , args []string , p * dep.Project , sm gps.SourceManager , params gps.SolveParameters , statchan chan map [ string ]verify. VendorStatus ) error {
398
402
if len (args ) == 0 {
399
403
return errors .New ("must specify at least one project or package to -add" )
400
404
}
@@ -411,15 +415,6 @@ func (cmd *ensureCommand) runAdd(ctx *dep.Ctx, args []string, p *dep.Project, sm
411
415
return errors .Wrap (err , "fastpath solver prepare" )
412
416
}
413
417
414
- // Compare the hashes. If they're not equal, bail out and ask the user to
415
- // run a straight `dep ensure` before updating. This is handholding the
416
- // user a bit, but the extra effort required is minimal, and it ensures the
417
- // user is isolating variables in the event of solve problems (was it the
418
- // "pending" changes, or the -add that caused the problem?).
419
- if p .Lock != nil && ! bytes .Equal (p .Lock .InputsDigest (), solver .HashInputs ()) {
420
- ctx .Out .Printf ("Warning: %s is out of sync with %s or the project's imports." , dep .LockName , dep .ManifestName )
421
- }
422
-
423
418
rm , _ := params .RootPackageTree .ToReachMap (true , true , false , p .Manifest .IgnoredPackages ())
424
419
425
420
// TODO(sdboyer) re-enable this once we ToReachMap() intelligently filters out normally-excluded (_*, .*), dirs from errmap
@@ -678,7 +673,7 @@ func (cmd *ensureCommand) runAdd(ctx *dep.Ctx, args []string, p *dep.Project, sm
678
673
}
679
674
sort .Strings (reqlist )
680
675
681
- sw , err := dep .NewSafeWriter (nil , p .Lock , dep .LockFromSolution (solution ), dep .VendorOnChanged , p .Manifest .PruneOptions )
676
+ sw , err := dep .NewSafeWriter (nil , p .Lock , dep .LockFromSolution (solution , p . Manifest . PruneOptions ), dep .VendorOnChanged , p .Manifest .PruneOptions )
682
677
if err != nil {
683
678
return err
684
679
}
0 commit comments