@@ -110,8 +110,8 @@ def _hash_flags_dict(self, flags):
110110 h ^= hash (pair )
111111 return h
112112
113- def solve (self , top_core , flags ):
114- return self ._solve (top_core , flags )
113+ def solve (self , top_core , flags , added_cores ):
114+ return self ._solve (top_core , flags , added_cores )
115115
116116 def _get_conflict_map (self ):
117117 """Return a map of cores to their conflicts
@@ -142,7 +142,7 @@ def _get_conflict_map(self):
142142 conflict_set .remove (real_pkg )
143143 return conflict_map
144144
145- def _solve (self , top_core , flags = {}, only_matching_vlnv = False ):
145+ def _solve (self , top_core , flags = {}, added_cores = (), only_matching_vlnv = False ):
146146 def eq_vln (this , that ):
147147 return (
148148 this .vendor == that .vendor
@@ -151,7 +151,12 @@ def eq_vln(this, that):
151151 )
152152
153153 # Try to return a cached result
154- solver_cache_key = (top_core , self ._hash_flags_dict (flags ), only_matching_vlnv )
154+ requested_cores = frozenset (added_cores + (top_core ,))
155+ solver_cache_key = (
156+ requested_cores ,
157+ self ._hash_flags_dict (flags ),
158+ only_matching_vlnv ,
159+ )
155160 cached_solution = self ._solver_cache_lookup (solver_cache_key )
156161 if cached_solution :
157162 return cached_solution
@@ -206,12 +211,13 @@ def eq_vln(this, that):
206211 repo .add_package (package )
207212
208213 request = Request ()
209- _top_dep = "{} {} {}" .format (
210- self ._package_name (top_core ),
211- top_core .relation ,
212- self ._package_version (top_core ),
213- )
214- request .install (Requirement ._from_string (_top_dep ))
214+ for requested_core in requested_cores :
215+ dep = "{} {} {}" .format (
216+ self ._package_name (requested_core ),
217+ requested_core .relation ,
218+ self ._package_version (requested_core ),
219+ )
220+ request .install (Requirement ._from_string (dep ))
215221
216222 installed_repository = Repository ()
217223 pool = Pool ([repo ])
@@ -249,11 +255,12 @@ def eq_vln(this, that):
249255 ]
250256 # Print a warning for all virtual selections that has no concrete requirement selection
251257 for virtual in virtual_selection .values ():
252- logger .warning (
253- "Non-deterministic selection of virtual core {} selected {}" .format (
254- virtual [1 ], virtual [0 ]
258+ if virtual [0 ] not in requested_cores :
259+ logger .warning (
260+ "Non-deterministic selection of virtual core {} selected {}" .format (
261+ virtual [1 ], virtual [0 ]
262+ )
255263 )
256- )
257264
258265 result = [op .package .core for op in transaction .operations ]
259266
@@ -402,13 +409,16 @@ def get_libraries(self):
402409 """Get all registered libraries"""
403410 return self ._lm .get_libraries ()
404411
405- def get_depends (self , core , flags ):
412+ def get_depends (self , core , flags , added_cores ):
406413 """Get an ordered list of all dependencies of a core
407414
408415 All direct and indirect dependencies are resolved into a dependency
409416 tree, the tree is flattened, and an ordered list of dependencies is
410417 created.
411418
419+ The list is augmented by any added_cores required by the call, which can
420+ deterministically satisfy virtual VLNV dependencies.
421+
412422 The first element in the list is a leaf dependency, the last element
413423 is the core at the root of the dependency tree.
414424 """
@@ -417,8 +427,11 @@ def get_depends(self, core, flags):
417427 core .relation , str (core ), str (flags )
418428 )
419429 )
430+ logger .debug (
431+ " User added cores to request: " + ", " .join ([str (c ) for c in added_cores ])
432+ )
420433 resolved_core = self .db .find (core )
421- deps = self .db .solve (resolved_core .name , flags )
434+ deps = self .db .solve (resolved_core .name , flags , added_cores )
422435 logger .debug (" Resolved core to {}" .format (str (resolved_core .name )))
423436 logger .debug (" with dependencies " + ", " .join ([str (c .name ) for c in deps ]))
424437 return deps
0 commit comments