@@ -273,7 +273,16 @@ func (cmd *statusCommand) Run(ctx *dep.Ctx, args []string) error {
273
273
return errors .Errorf ("no Gopkg.lock found. Run `dep ensure` to generate lock file" )
274
274
}
275
275
276
- hasMissingPkgs , errCount , err := runStatusAll (ctx , out , p , sm , cmd )
276
+ // Choose function based on command options
277
+ var hasMissingPkgs bool
278
+ var errCount int
279
+ switch {
280
+ case cmd .old :
281
+ hasMissingPkgs , errCount , err = runOld (ctx , out , p , sm )
282
+ default :
283
+ hasMissingPkgs , errCount , err = runStatusAll (ctx , out , p , sm )
284
+ }
285
+
277
286
if err != nil {
278
287
switch err {
279
288
case errFailedUpdate :
@@ -340,15 +349,6 @@ func (cmd *statusCommand) validateFlags() error {
340
349
return nil
341
350
}
342
351
343
- // OldStatus contains information about all the out of date packages in a project.
344
- type OldStatus struct {
345
- ProjectRoot string
346
- Constraint gps.Constraint
347
- Version gps.UnpairedVersion
348
- Revision gps.Revision
349
- Latest gps.Version
350
- }
351
-
352
352
type rawStatus struct {
353
353
ProjectRoot string
354
354
Constraint string
@@ -432,7 +432,7 @@ type MissingStatus struct {
432
432
MissingPackages []string
433
433
}
434
434
435
- func runStatusAll (ctx * dep.Ctx , out outputter , p * dep.Project , sm gps.SourceManager , cmd * statusCommand ) (hasMissingPkgs bool , errCount int , err error ) {
435
+ func runStatusAll (ctx * dep.Ctx , out outputter , p * dep.Project , sm gps.SourceManager ) (hasMissingPkgs bool , errCount int , err error ) {
436
436
// While the network churns on ListVersions() requests, statically analyze
437
437
// code from the current project.
438
438
ptree , err := p .ParseRootPackageTree ()
@@ -465,17 +465,6 @@ func runStatusAll(ctx *dep.Ctx, out outputter, p *dep.Project, sm gps.SourceMana
465
465
return false , 0 , errors .Wrapf (err , "could not set up solver for input hashing" )
466
466
}
467
467
468
- // We only care about solution in the -old flag case
469
- var solution gps.Solution
470
- if cmd .old {
471
- params .ChangeAll = true
472
- var err error
473
- solution , err = s .Solve (context .TODO ())
474
- if err != nil {
475
- return false , 0 , err
476
- }
477
- }
478
-
479
468
// Errors while collecting constraints should not fail the whole status run.
480
469
// It should count the error and tell the user about incomplete results.
481
470
cm , ccerrs := collectConstraints (ctx , p , sm )
@@ -662,15 +651,6 @@ func runStatusAll(ctx *dep.Ctx, out outputter, p *dep.Project, sm gps.SourceMana
662
651
for _ , proj := range slp {
663
652
pr := proj .Ident ().ProjectRoot
664
653
665
- // If -old flag, only display the lines where the solver mismatches
666
- if cmd .old {
667
- if matches , err := projUpToDate (proj , solution ); matches {
668
- continue
669
- } else if err != nil {
670
- return false , 0 , err
671
- }
672
- }
673
-
674
654
if err := out .BasicLine (bsMap [string (pr )]); err != nil {
675
655
return false , 0 , err
676
656
}
@@ -752,9 +732,223 @@ outer:
752
732
return hasMissingPkgs , 0 , errInputDigestMismatch
753
733
}
754
734
735
+ func runOld (ctx * dep.Ctx , out outputter , p * dep.Project , sm gps.SourceManager ) (hasMissingPkgs bool , errCount int , err error ) {
736
+ ptree , err := p .ParseRootPackageTree ()
737
+ if err != nil {
738
+ return false , 0 , err
739
+ }
740
+
741
+ // Solve the dependencies so we can check if the current dependencies are old
742
+ params := gps.SolveParameters {
743
+ ProjectAnalyzer : dep.Analyzer {},
744
+ RootDir : p .AbsRoot ,
745
+ RootPackageTree : ptree ,
746
+ Manifest : p .Manifest ,
747
+ ChangeAll : true ,
748
+ }
749
+ s , err := gps .Prepare (params , sm )
750
+ if err != nil {
751
+ return false , 0 , errors .Wrapf (err , "could not set up solver for input hashing" )
752
+ }
753
+
754
+ if err := out .BasicHeader (); err != nil {
755
+ return false , 0 , err
756
+ }
757
+
758
+ // Errors while collecting constraints should not fail the whole status run.
759
+ // It should count the error and tell the user about incomplete results.
760
+ cm , ccerrs := collectConstraints (ctx , p , sm )
761
+ if len (ccerrs ) > 0 {
762
+ errCount += len (ccerrs )
763
+ }
764
+
765
+ bsMap := make (map [string ]* BasicStatus )
766
+
767
+ slp := p .Lock .Projects ()
768
+
769
+ if ! bytes .Equal (s .HashInputs (), p .Lock .SolveMeta .InputsDigest ) {
770
+ // Hash digest mismatch may indicate that some deps are no longer
771
+ // needed, some are missing, or that some constraints or source
772
+ // locations have changed.
773
+ //
774
+ // It's possible for digests to not match, but still have a correct
775
+ // lock.
776
+ rm , _ := ptree .ToReachMap (true , true , false , p .Manifest .IgnoredPackages ())
777
+
778
+ external := rm .FlattenFn (paths .IsStandardImportPath )
779
+ roots := make (map [gps.ProjectRoot ][]string , len (external ))
780
+
781
+ type fail struct {
782
+ ex string
783
+ err error
784
+ }
785
+ var errs []fail
786
+ for _ , e := range external {
787
+ root , err := sm .DeduceProjectRoot (e )
788
+ if err != nil {
789
+ errs = append (errs , fail {
790
+ ex : e ,
791
+ err : err ,
792
+ })
793
+ continue
794
+ }
795
+
796
+ roots [root ] = append (roots [root ], e )
797
+ }
798
+
799
+ if len (errs ) != 0 {
800
+ // TODO this is just a fix quick so staticcheck doesn't complain.
801
+ // Visually reconciling failure to deduce project roots with the rest of
802
+ // the mismatch output is a larger problem.
803
+ ctx .Err .Printf ("Failed to deduce project roots for import paths:\n " )
804
+ for _ , fail := range errs {
805
+ ctx .Err .Printf ("\t %s: %s\n " , fail .ex , fail .err .Error ())
806
+ }
807
+
808
+ return false , 0 , errors .New ("address issues with undeducible import paths to get more status information" )
809
+ }
810
+
811
+ if err = out .MissingHeader (); err != nil {
812
+ return false , 0 , err
813
+ }
814
+
815
+ outer2:
816
+ for root , pkgs := range roots {
817
+ // TODO also handle the case where the project is present, but there
818
+ // are items missing from just the package list
819
+ for _ , lp := range slp {
820
+ if lp .Ident ().ProjectRoot == root {
821
+ continue outer2
822
+ }
823
+ }
824
+
825
+ hasMissingPkgs = true
826
+ err := out .MissingLine (& MissingStatus {ProjectRoot : string (root ), MissingPackages : pkgs })
827
+ if err != nil {
828
+ return false , 0 , err
829
+ }
830
+ }
831
+ if err = out .MissingFooter (); err != nil {
832
+ return false , 0 , err
833
+ }
834
+
835
+ // We are here because of an input-digest mismatch. Return error.
836
+ return hasMissingPkgs , 0 , errInputDigestMismatch
837
+ }
838
+
839
+ solution , err := s .Solve (context .TODO ())
840
+ if err != nil {
841
+ return false , 0 , err
842
+ }
843
+
844
+ for _ , proj := range slp {
845
+ if matches , err := projUpToDate (proj , solution .Projects ()); matches {
846
+ continue
847
+ } else if err != nil {
848
+ return false , 0 , err
849
+ }
850
+
851
+ bs := BasicStatus {
852
+ ProjectRoot : string (proj .Ident ().ProjectRoot ),
853
+ PackageCount : len (proj .Packages ()),
854
+ }
855
+ switch out .(type ) {
856
+ case * dotOutput :
857
+ ptr , err := sm .ListPackages (proj .Ident (), proj .Version ())
858
+
859
+ if err != nil {
860
+ bs .hasError = true
861
+ return false , 0 , err
862
+ }
863
+
864
+ prm , _ := ptr .ToReachMap (true , true , false , p .Manifest .IgnoredPackages ())
865
+ bs .Children = prm .FlattenFn (paths .IsStandardImportPath )
866
+ }
867
+ // Split apart the version from the lock into its constituent parts.
868
+ switch tv := proj .Version ().(type ) {
869
+ case gps.UnpairedVersion :
870
+ bs .Version = tv
871
+ case gps.Revision :
872
+ bs .Revision = tv
873
+ case gps.PairedVersion :
874
+ bs .Version = tv .Unpair ()
875
+ bs .Revision = tv .Revision ()
876
+ }
877
+ // Check if the manifest has an override for this project. If so,
878
+ // set that as the constraint.
879
+ if pp , has := p .Manifest .Ovr [proj .Ident ().ProjectRoot ]; has && pp .Constraint != nil {
880
+ bs .hasOverride = true
881
+ bs .Constraint = pp .Constraint
882
+ } else if pp , has := p .Manifest .Constraints [proj .Ident ().ProjectRoot ]; has && pp .Constraint != nil {
883
+ // If the manifest has a constraint then set that as the constraint.
884
+ bs .Constraint = pp .Constraint
885
+ } else {
886
+ bs .Constraint = gps .Any ()
887
+ for _ , c := range cm [bs .ProjectRoot ] {
888
+ bs .Constraint = c .Constraint .Intersect (bs .Constraint )
889
+ }
890
+ }
891
+
892
+ // Only if we have a non-rev and non-plain version do/can we display
893
+ // anything wrt the version's updateability.
894
+ if bs .Version != nil && bs .Version .Type () != gps .IsVersion {
895
+ c , has := p .Manifest .Constraints [proj .Ident ().ProjectRoot ]
896
+ if ! has {
897
+ // Get constraint for locked project
898
+ for _ , lockedP := range p .Lock .P {
899
+ if lockedP .Ident ().ProjectRoot == proj .Ident ().ProjectRoot {
900
+ // Use the unpaired version as the constraint for checking updates.
901
+ c .Constraint = bs .Version
902
+ }
903
+ }
904
+ }
905
+ // TODO: This constraint is only the constraint imposed by the
906
+ // current project, not by any transitive deps. As a result,
907
+ // transitive project deps will always show "any" here.
908
+ bs .Constraint = c .Constraint
909
+
910
+ vl , err := sm .ListVersions (proj .Ident ())
911
+ if err == nil {
912
+ gps .SortPairedForUpgrade (vl )
913
+
914
+ for _ , v := range vl {
915
+ // Because we've sorted the version list for
916
+ // upgrade, the first version we encounter that
917
+ // matches our constraint will be what we want.
918
+ if c .Constraint .Matches (v ) {
919
+ // Latest should be of the same type as the Version.
920
+ if bs .Version .Type () == gps .IsSemver {
921
+ bs .Latest = v
922
+ } else {
923
+ bs .Latest = v .Revision ()
924
+ }
925
+ break
926
+ }
927
+ }
928
+ } else {
929
+ // Failed to fetch version list (could happen due to
930
+ // network issue).
931
+ bs .hasError = true
932
+ return false , 0 , err
933
+ }
934
+ }
935
+
936
+ bsMap [bs .ProjectRoot ] = & bs
937
+ }
938
+
939
+ for k := range bsMap {
940
+ if err := out .BasicLine (bsMap [k ]); err != nil {
941
+ return false , 0 , err
942
+ }
943
+ }
944
+ if footerErr := out .BasicFooter (); footerErr != nil {
945
+ return false , 0 , footerErr
946
+ }
947
+ return false , errCount , err
948
+ }
949
+
755
950
// projUpToDate returns true if the project p, is at the same revision as what the solution indicates
756
- func projUpToDate (p gps.LockedProject , s gps.Solution ) (bool , error ) {
757
- solutionProjects := s .Projects ()
951
+ func projUpToDate (p gps.LockedProject , solutionProjects []gps.LockedProject ) (bool , error ) {
758
952
for i := range solutionProjects {
759
953
if solutionProjects [i ].Ident ().ProjectRoot == p .Ident ().ProjectRoot {
760
954
spr , _ , _ := gps .VersionComponentStrings (solutionProjects [i ].Version ())
0 commit comments