@@ -138,17 +138,17 @@ func (cmd *ensureCommand) Run(ctx *dep.Ctx, args []string) error {
138
138
return errors .New ("cannot pass both -add and -update" )
139
139
}
140
140
141
- if cmd .update && cmd . vendorOnly {
142
- return errors . New ( "-vendor-only makes - update a no-op; cannot pass them together" )
143
- }
144
-
145
- if cmd .add && cmd . vendorOnly {
146
- return errors .New ("-vendor-only makes -add a no-op; cannot pass them together" )
147
- }
148
-
149
- if cmd . vendorOnly && cmd . noVendor {
150
- // TODO(sdboyer) can't think of anything not snarky right now
151
- return errors . New ( "really?" )
141
+ if cmd .vendorOnly {
142
+ if cmd . update {
143
+ return errors . New ( "-vendor-only makes -update a no-op; cannot pass them together" )
144
+ }
145
+ if cmd .add {
146
+ return errors .New ("-vendor-only makes -add a no-op; cannot pass them together" )
147
+ }
148
+ if cmd . noVendor {
149
+ // TODO(sdboyer) can't think of anything not snarky right now
150
+ return errors . New ( "really?" )
151
+ }
152
152
}
153
153
154
154
p , err := ctx .LoadProject ("" )
@@ -263,7 +263,6 @@ func (cmd *ensureCommand) runDefault(ctx *dep.Ctx, args []string, p *dep.Project
263
263
// that "verification" is supposed to look like (#121); in the meantime,
264
264
// we unconditionally write out vendor/ so that `dep ensure`'s behavior
265
265
// is maximally compatible with what it will eventually become.
266
- // vendor doesn't exist at all; be helpful and write it.
267
266
err := sw .Prepare (nil , p .Lock , p .Lock , dep .VendorAlways )
268
267
if err != nil {
269
268
return err
@@ -308,7 +307,8 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
308
307
// run a straight `dep ensure` before updating. This is handholding the
309
308
// user a bit, but the extra effort required is minimal, and it ensures the
310
309
// user is isolating variables in the event of solve problems (was it the
311
- // existing changes, or the -update that caused the problem?).
310
+ // "pending" changes, or the -update that caused the problem?).
311
+ // TODO(sdboyer) reduce this to a warning?
312
312
if bytes .Equal (p .Lock .InputHash (), solver .HashInputs ()) {
313
313
return errors .Errorf ("%s and %s are out of sync. run a plain `dep ensure` to resync them before attempting an -update." , dep .ManifestName , dep .LockName )
314
314
}
@@ -328,15 +328,18 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
328
328
pc , err := getProjectConstraint (arg , sm )
329
329
if err != nil {
330
330
// TODO(sdboyer) return all errors, not just the first one we encounter
331
- // TODO(sdboyer) ensure these errors are contextualized in a
332
- // sensible way for -update
331
+ // TODO(sdboyer) ensure these errors are contextualized in a sensible way for -update
333
332
return err
334
333
}
335
334
336
335
if ! p .Lock .HasProjectWithRoot (pc .Ident .ProjectRoot ) {
337
336
return errors .Errorf ("%s is not present in %s, cannot -update it" , pc .Ident .ProjectRoot , dep .LockName )
338
337
}
339
338
339
+ if p .Ident .Source != "" {
340
+ return errors .Errorf ("cannot specify alternate sources on -update (%s)" )
341
+ }
342
+
340
343
if ! gps .IsAny (pc .Constraint ) {
341
344
// TODO(sdboyer) constraints should be allowed to allow solves that
342
345
// target particular versions while remaining within declared constraints
@@ -370,6 +373,61 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project,
370
373
}
371
374
372
375
func (cmd * ensureCommand ) runAdd (ctx * dep.Ctx , args []string , p * dep.Project , sm gps.SourceManager , params gps.SolveParameters ) error {
376
+ if len (args ) == 0 {
377
+ return errors .New ("must specify at least one project or package to add" )
378
+ }
379
+
380
+ // Compare the hashes. If they're not equal, bail out and ask the user to
381
+ // run a straight `dep ensure` before updating. This is handholding the
382
+ // user a bit, but the extra effort required is minimal, and it ensures the
383
+ // user is isolating variables in the event of solve problems (was it the
384
+ // "pending" changes, or the -add that caused the problem?).
385
+ // TODO(sdboyer) reduce this to a warning?
386
+ if bytes .Equal (p .Lock .InputHash (), solver .HashInputs ()) {
387
+ return errors .Errorf ("%s and %s are out of sync. run a plain `dep ensure` to resync them before attempting an -add." , dep .ManifestName , dep .LockName )
388
+ }
389
+
390
+ rm , errmap := params .RootPackageTree .ToReachMap (true , true , false , p .Manifest .IgnoredPackages ())
391
+ // Having some problematic internal packages isn't cause for termination,
392
+ // but the user needs to be warned.
393
+ for fail := range errmap {
394
+ internal .Logf ("Warning: %s" , fail )
395
+ }
396
+
397
+ exmap := make (map [string ]bool )
398
+ exrmap := make (map [gps.ProjectRoot ]bool )
399
+ for _ , ex := range append (rm .Flatten (false ), p .Manifest .RequiredPackages ()... ) {
400
+ exmap [ex ] = true
401
+ root , err := sm .DeduceProjectRoot (ex )
402
+ if err != nil {
403
+ // This should be essentially impossible to hit, as it entails that
404
+ // we couldn't deduce the root for an import, but that some previous
405
+ // solve run WAS able to deduce the root.
406
+ return errors .Wrap (err , "could not deduce project root" )
407
+ }
408
+ exrmap [root ] = true
409
+ }
410
+
411
+ for _ , arg := range args {
412
+ // TODO(sdboyer) return all errors, not just the first one we encounter
413
+ // TODO(sdboyer) do these concurrently
414
+ pc , err := getProjectConstraint (arg , sm )
415
+ if err != nil {
416
+ // TODO(sdboyer) ensure these errors are contextualized in a sensible way for -add
417
+ return err
418
+ }
419
+
420
+ inManifest := p .Manifest .HasConstraintsOn (pc .Ident .ProjectRoot )
421
+ inImports := exrmap [pc .Ident .ProjectRoot ]
422
+ if inManifest && inImports {
423
+ return errors .Errorf ("%s is already in %s and the project's direct imports, nothing to add" , pc .Ident .ProjectRoot , dep .ManifestName )
424
+ }
425
+
426
+ err = sm .SyncSourceFor (pc .Ident )
427
+ if err != nil {
428
+ return errors .Wrap (err , "failed to fetch source for %s" , pc .Ident .ProjectRoot )
429
+ }
430
+ }
373
431
}
374
432
375
433
func applyEnsureArgs (args []string , overrides stringSlice , p * dep.Project , sm * gps.SourceMgr , params * gps.SolveParameters ) error {
0 commit comments