def _valid_virtuals_and_externals(self, spec): """Returns a list of candidate virtual dep providers and external packages that coiuld be used to concretize a spec. Preferred specs come first in the list. """ # First construct a list of concrete candidates to replace spec with. candidates = [spec] pref_key = lambda spec: 0 # no-op pref key if spec.virtual: candidates = spack.repo.providers_for(spec) if not candidates: raise UnsatisfiableProviderSpecError(candidates[0], spec) # Find nearest spec in the DAG (up then down) that has prefs. spec_w_prefs = find_spec( spec, lambda p: PackagePrefs.has_preferred_providers( p.name, spec.name), spec) # default to spec itself. # Create a key to sort candidates by the prefs we found pref_key = PackagePrefs(spec_w_prefs.name, 'providers', spec.name) # For each candidate package, if it has externals, add those # to the usable list. if it's not buildable, then *only* add # the externals. # # Use an OrderedDict to avoid duplicates (use it like a set) usable = OrderedDict() for cspec in candidates: if is_spec_buildable(cspec): usable[cspec] = True externals = spec_externals(cspec) for ext in externals: if ext.satisfies(spec): usable[ext] = True # If nothing is in the usable list now, it's because we aren't # allowed to build anything. if not usable: raise NoBuildError(spec) # Use a sort key to order the results return sorted( usable, key=lambda spec: ( not spec.external, # prefer externals pref_key(spec), # respect prefs spec.name, # group by name reverse_order(spec.versions), # latest version spec # natural order ))
def _valid_virtuals_and_externals(self, spec): """Returns a list of candidate virtual dep providers and external packages that coiuld be used to concretize a spec. Preferred specs come first in the list. """ # First construct a list of concrete candidates to replace spec with. candidates = [spec] pref_key = lambda spec: 0 # no-op pref key if spec.virtual: candidates = spack.repo.providers_for(spec) if not candidates: raise UnsatisfiableProviderSpecError(candidates[0], spec) # Find nearest spec in the DAG (up then down) that has prefs. spec_w_prefs = find_spec( spec, lambda p: PackagePrefs.has_preferred_providers( p.name, spec.name), spec) # default to spec itself. # Create a key to sort candidates by the prefs we found pref_key = PackagePrefs(spec_w_prefs.name, 'providers', spec.name) # For each candidate package, if it has externals, add those # to the usable list. if it's not buildable, then *only* add # the externals. # # Use an OrderedDict to avoid duplicates (use it like a set) usable = OrderedDict() for cspec in candidates: if is_spec_buildable(cspec): usable[cspec] = True externals = spec_externals(cspec) for ext in externals: if ext.satisfies(spec): usable[ext] = True # If nothing is in the usable list now, it's because we aren't # allowed to build anything. if not usable: raise NoBuildError(spec) # Use a sort key to order the results return sorted(usable, key=lambda spec: ( not spec.external, # prefer externals pref_key(spec), # respect prefs spec.name, # group by name reverse_order(spec.versions), # latest version spec # natural order ))