@@ -409,6 +409,9 @@ func (cmd *ensureCommand) runAdd(ctx *dep.Ctx, args []string, p *dep.Project, sm
409
409
exrmap [root ] = true
410
410
}
411
411
412
+ var reqlist []string
413
+ //pclist := make(map[gps.ProjectRoot]gps.ProjectConstraint)
414
+
412
415
for _ , arg := range args {
413
416
// TODO(sdboyer) return all errors, not just the first one we encounter
414
417
// TODO(sdboyer) do these concurrently
@@ -421,14 +424,84 @@ func (cmd *ensureCommand) runAdd(ctx *dep.Ctx, args []string, p *dep.Project, sm
421
424
inManifest := p .Manifest .HasConstraintsOn (pc .Ident .ProjectRoot )
422
425
inImports := exrmap [pc .Ident .ProjectRoot ]
423
426
if inManifest && inImports {
424
- return errors .Errorf ("%s is already in %s and the project's direct imports, nothing to add" , pc .Ident .ProjectRoot , dep .ManifestName )
427
+ return errors .Errorf ("%s is already in %s and the project's direct imports or required list; nothing to add" , pc .Ident .ProjectRoot , dep .ManifestName )
425
428
}
426
429
427
430
err = sm .SyncSourceFor (pc .Ident )
428
431
if err != nil {
429
432
return errors .Wrap (err , "failed to fetch source for %s" , pc .Ident .ProjectRoot )
430
433
}
434
+
435
+ someConstraint = pc .Constraint != nil || pc .Ident .Source != ""
436
+ if inManifest {
437
+ if someConstraint {
438
+ return errors .Errorf ("%s already contains constraints for %s, cannot specify a version constraint or alternate source" , arg , dep .ManifestName )
439
+ }
440
+
441
+ reqlist = append (reqlist , arg )
442
+ p .Manifest .Required = append (p .Manifest .Required , arg )
443
+ } else if inImports {
444
+ if ! someConstraint {
445
+ if exmap [arg ] {
446
+ return errors .Errorf ("%s is already imported or required; -add must specify a constraint, but none were provided" , arg )
447
+ }
448
+
449
+ // TODO(sdboyer) this case seems like it's getting overly
450
+ // specific and risks muddying the water more than it helps
451
+ // No constraints, but the package isn't imported; require it.
452
+ reqlist = append (reqlist , arg )
453
+ p .Manifest .Required = append (p .Manifest .Required , arg )
454
+ } else {
455
+ p .Manifest .Dependencies [pc .Ident .ProjectRoot ] = gps.ProjectProperties {
456
+ Source : pc .Ident .Source ,
457
+ Constraint : pc .Constraint ,
458
+ }
459
+
460
+ // Don't require on this branch if the arg was a ProjectRoot;
461
+ // most common here will be the user adding constraints to
462
+ // something they already imported, and if they specify the
463
+ // root, there's a good chance they don't actually want to
464
+ // require the project's root package, but are just trying to
465
+ // indicate which project should receive the constraints.
466
+ if ! exmap [arg ] && string (pc .Ident .ProjectRoot ) != arg {
467
+ reqlist = append (reqlist , arg )
468
+ p .Manifest .Required = append (p .Manifest .Required , arg )
469
+ }
470
+ }
471
+ } else {
472
+ p .Manifest .Dependencies [pc .Ident .ProjectRoot ] = gps.ProjectProperties {
473
+ Source : pc .Ident .Source ,
474
+ Constraint : pc .Constraint ,
475
+ }
476
+
477
+ reqlist = append (reqlist , arg )
478
+ p .Manifest .Required = append (p .Manifest .Required , arg )
479
+ }
431
480
}
481
+
482
+ // Re-prepare a solver now that our params are complete.
483
+ solver , err = gps .Prepare (params , sm )
484
+ if err != nil {
485
+ return errors .Wrap (err , "fastpath solver prepare" )
486
+ }
487
+ solution , err := solver .Solve ()
488
+ if err != nil {
489
+ // TODO(sdboyer) detect if the failure was specifically about some of
490
+ // the -add arguments
491
+ handleAllTheFailuresOfTheWorld (err )
492
+ return errors .Wrap (err , "ensure Solve()" )
493
+ }
494
+
495
+ var sw dep.SafeWriter
496
+ sw .Prepare (nil , p .Lock , dep .LockFromInterface (solution ), dep .VendorOnChanged )
497
+ // TODO(sdboyer) special handling for warning cases as described in spec -
498
+ // e.g., named projects did not upgrade even though newer versions were
499
+ // available.
500
+ if cmd .dryRun {
501
+ return sw .PrintPreparedActions ()
502
+ }
503
+
504
+ return errors .Wrap (sw .Write (p .AbsRoot , sm , true ), "grouped write of manifest, lock and vendor" )
432
505
}
433
506
434
507
func applyEnsureArgs (args []string , overrides stringSlice , p * dep.Project , sm gps.SourceManager , params * gps.SolveParameters ) error {
0 commit comments