@@ -431,7 +431,7 @@ func (s *solver) selectRoot() error {
431
431
s .sel .pushDep (dependency {depender : pa , dep : dep })
432
432
// Add all to unselected queue
433
433
s .names [dep .Ident .LocalName ] = dep .Ident .netName ()
434
- heap .Push (s .unsel , bimodalIdentifier {id : dep .Ident , pl : dep .pl })
434
+ heap .Push (s .unsel , bimodalIdentifier {id : dep .Ident , pl : dep .pl , fromRoot : true })
435
435
}
436
436
437
437
return nil
@@ -616,9 +616,40 @@ func (s *solver) createVersionQueue(bmi bimodalIdentifier) (*versionQueue, error
616
616
617
617
var prefv Version
618
618
if bmi .fromRoot {
619
+ // If this bmi came from the root, then we want to search through things
620
+ // with a dependency on it in order to see if any have a lock that might
621
+ // express a prefv
622
+ //
623
+ // TODO nested loop; prime candidate for a cache somewhere
624
+ for _ , dep := range s .sel .getDependenciesOn (bmi .id ) {
625
+ _ , l , err := s .b .getProjectInfo (dep .depender )
626
+ if err != nil {
627
+ // This really shouldn't be possible, but just skip if it if it
628
+ // does happen somehow
629
+ continue
630
+ }
631
+
632
+ for _ , lp := range l .Projects () {
633
+ if lp .Ident ().eq (bmi .id ) {
634
+ prefv = lp .Version ()
635
+ }
636
+ }
637
+ }
638
+
639
+ // OTHER APPROACH, WRONG, BUT MAYBE USEFUL FOR REFERENCE?
619
640
// If this bmi came from the root, then we want to search the unselected
620
641
// queue to see if anything *else* wants this ident, in which case we
621
642
// pick up that prefv
643
+ //for _, bmi2 := range s.unsel.sl {
644
+ //// Take the first thing from the queue that's for the same ident,
645
+ //// and has a non-nil prefv
646
+ //if bmi.id.eq(bmi2.id) {
647
+ //if bmi2.prefv != nil {
648
+ //prefv = bmi2.prefv
649
+ //}
650
+ //}
651
+ //}
652
+
622
653
} else {
623
654
// Otherwise, just use the preferred version expressed in the bmi
624
655
prefv = bmi .prefv
@@ -887,8 +918,6 @@ func (s *solver) unselectedComparator(i, j int) bool {
887
918
// isn't locked by the root. And, because being locked by root is the only
888
919
// way avoid that call when making a version queue, we know we're gonna have
889
920
// to pay that cost anyway.
890
- //
891
- // TODO ...at least, 'til we allow 'preferred' versions via non-root locks
892
921
893
922
// We can safely ignore an err from ListVersions here because, if there is
894
923
// an actual problem, it'll be noted and handled somewhere else saner in the
@@ -949,6 +978,14 @@ func (s *solver) selectAtomWithPackages(a atomWithPackages) {
949
978
panic (fmt .Sprintf ("canary - shouldn't be possible %s" , err ))
950
979
}
951
980
981
+ // If this atom has a lock, pull it out so that we can potentially inject
982
+ // preferred versions into any bmis we enqueue
983
+ _ , l , err := s .b .getProjectInfo (a .a )
984
+ lmap := make (map [ProjectIdentifier ]Version )
985
+ for _ , lp := range l .Projects () {
986
+ lmap [lp .Ident ()] = lp .Version ()
987
+ }
988
+
952
989
for _ , dep := range deps {
953
990
s .sel .pushDep (dependency {depender : a .a , dep : dep })
954
991
// Go through all the packages introduced on this dep, selecting only
@@ -963,7 +1000,14 @@ func (s *solver) selectAtomWithPackages(a atomWithPackages) {
963
1000
}
964
1001
965
1002
if len (newp ) > 0 {
966
- heap .Push (s .unsel , bimodalIdentifier {id : dep .Ident , pl : newp })
1003
+ bmi := bimodalIdentifier {
1004
+ id : dep .Ident ,
1005
+ pl : newp ,
1006
+ // This puts in a preferred version if one's in the map, else
1007
+ // drops in the zero value (nil)
1008
+ prefv : lmap [dep .Ident ],
1009
+ }
1010
+ heap .Push (s .unsel , bmi )
967
1011
}
968
1012
969
1013
if s .sel .depperCount (dep .Ident ) == 1 {
@@ -993,6 +1037,14 @@ func (s *solver) selectPackages(a atomWithPackages) {
993
1037
panic (fmt .Sprintf ("canary - shouldn't be possible %s" , err ))
994
1038
}
995
1039
1040
+ // If this atom has a lock, pull it out so that we can potentially inject
1041
+ // preferred versions into any bmis we enqueue
1042
+ _ , l , err := s .b .getProjectInfo (a .a )
1043
+ lmap := make (map [ProjectIdentifier ]Version )
1044
+ for _ , lp := range l .Projects () {
1045
+ lmap [lp .Ident ()] = lp .Version ()
1046
+ }
1047
+
996
1048
for _ , dep := range deps {
997
1049
s .sel .pushDep (dependency {depender : a .a , dep : dep })
998
1050
// Go through all the packages introduced on this dep, selecting only
@@ -1007,7 +1059,14 @@ func (s *solver) selectPackages(a atomWithPackages) {
1007
1059
}
1008
1060
1009
1061
if len (newp ) > 0 {
1010
- heap .Push (s .unsel , bimodalIdentifier {id : dep .Ident , pl : newp })
1062
+ bmi := bimodalIdentifier {
1063
+ id : dep .Ident ,
1064
+ pl : newp ,
1065
+ // This puts in a preferred version if one's in the map, else
1066
+ // drops in the zero value (nil)
1067
+ prefv : lmap [dep .Ident ],
1068
+ }
1069
+ heap .Push (s .unsel , bmi )
1011
1070
}
1012
1071
1013
1072
if s .sel .depperCount (dep .Ident ) == 1 {
0 commit comments