Skip to content

Commit 97d37a3

Browse files
committed
Implement first pass of preferred versions
Fixes golang#16.
1 parent 165a4cc commit 97d37a3

File tree

1 file changed

+64
-5
lines changed

1 file changed

+64
-5
lines changed

solver.go

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ func (s *solver) selectRoot() error {
431431
s.sel.pushDep(dependency{depender: pa, dep: dep})
432432
// Add all to unselected queue
433433
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})
435435
}
436436

437437
return nil
@@ -616,9 +616,40 @@ func (s *solver) createVersionQueue(bmi bimodalIdentifier) (*versionQueue, error
616616

617617
var prefv Version
618618
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?
619640
// If this bmi came from the root, then we want to search the unselected
620641
// queue to see if anything *else* wants this ident, in which case we
621642
// 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+
622653
} else {
623654
// Otherwise, just use the preferred version expressed in the bmi
624655
prefv = bmi.prefv
@@ -887,8 +918,6 @@ func (s *solver) unselectedComparator(i, j int) bool {
887918
// isn't locked by the root. And, because being locked by root is the only
888919
// way avoid that call when making a version queue, we know we're gonna have
889920
// to pay that cost anyway.
890-
//
891-
// TODO ...at least, 'til we allow 'preferred' versions via non-root locks
892921

893922
// We can safely ignore an err from ListVersions here because, if there is
894923
// an actual problem, it'll be noted and handled somewhere else saner in the
@@ -949,6 +978,14 @@ func (s *solver) selectAtomWithPackages(a atomWithPackages) {
949978
panic(fmt.Sprintf("canary - shouldn't be possible %s", err))
950979
}
951980

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+
952989
for _, dep := range deps {
953990
s.sel.pushDep(dependency{depender: a.a, dep: dep})
954991
// Go through all the packages introduced on this dep, selecting only
@@ -963,7 +1000,14 @@ func (s *solver) selectAtomWithPackages(a atomWithPackages) {
9631000
}
9641001

9651002
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)
9671011
}
9681012

9691013
if s.sel.depperCount(dep.Ident) == 1 {
@@ -993,6 +1037,14 @@ func (s *solver) selectPackages(a atomWithPackages) {
9931037
panic(fmt.Sprintf("canary - shouldn't be possible %s", err))
9941038
}
9951039

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+
9961048
for _, dep := range deps {
9971049
s.sel.pushDep(dependency{depender: a.a, dep: dep})
9981050
// Go through all the packages introduced on this dep, selecting only
@@ -1007,7 +1059,14 @@ func (s *solver) selectPackages(a atomWithPackages) {
10071059
}
10081060

10091061
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)
10111070
}
10121071

10131072
if s.sel.depperCount(dep.Ident) == 1 {

0 commit comments

Comments
 (0)