def _check_conflict(self, p1, p2): # Does p1 conflict with p2 for conflict in p1.conflicts: cq = Query(conflict) if cq.matches(p2) and not self._does_bridge_after(p1, p2): return (p1, p2) # Does p2 conflict with p1 for conflict in p2.conflicts: cq = Query(conflict) if cq.matches(p1) and not self._does_bridge_after(p2, p1): return p2, p1
def _does_bridge(self, local_repo, targets, p1, p2): # Do we have a bridge already installed? installed_bridges = local_repo.find_bridges(p1, p2) if installed_bridges: return True # Do any of the packages we are about to install offer to bridge this? for package in targets: for bridge in package.bridges: b1 = Query(bridge[0]) b2 = Query(bridge[1]) if b1.matches(p1) and b2.matches(p2): return True elif b2.matches(p1) and b1.matches(p2): return True return False
def _find_conflicts(self, targets, local_repo): # Find conflicts inside targets conflicts = set() for t in targets: for conflict in t.conflicts: cq = Query(conflict) for tc in targets: # Packages don't conflict with themselves if t == tc: continue if (cq.matches(tc) and not self._does_bridge(local_repo, targets, t, tc)): conflicts.add((t, tc)) local_packages = local_repo.get_all_packages() # Find conflicts from targets to local_repo for t in targets: for conflict in t.conflicts: cq = Query(conflict) for lp in local_packages: # Packages don't conflict with themselves if t == lp: continue if (cq.matches(lp) and not self._does_bridge(local_repo, targets, t, lp)): conflicts.add((t, lp)) # Find conflicts from local_repo to targets for lp in local_packages: for conflict in lp.conflicts: cq = Query(conflict) for tc in targets: # Packages don't conflict with themselves if lp == tc: continue if (cq.matches(tc) and not self._does_bridge( local_repo, targets, lp, tc)): # NOQA conflicts.add((lp, tc)) return conflicts
def expand(self): # If theres no targets, expand to all local packages if not self.targets: self.targets = self.local_repo.get_all_packages() upgrades = self._find_upgrade_required(self.targets) self.removes = [u[0] for u in upgrades] self.installs = [u[1] for u in upgrades] self.targets = [ u[1] for u in upgrades if u[0].reason == InstallReason.REQ ] # So the dependencies might have changed. I don't think we want to # remove unused dependencies, but we do want to pull in new ones. We # might also stop providing something, which could invalidate some # other part of the local database. # Basically we will want to do the following: # - Check if all dependencies are filled # - Fill new ones (maybe asking?) # - Check that all the people depending on us still have their # dependencies filled after the transaction # During all of these steps we need to make sure that we aren't # matching packages that this transaction is going to remove, but # include packages we are about to install. # Find all packages touched by something we are removing new_missing = set() for package in self.removes: dependants = self.local_repo.find_dependants(package) for dependant in dependants: # If the dependant is queued for removal we don't really care # if we are going to break dependencies if dependant in self.removes: continue for dep_str in dependant.dependecies: q = Query(dep_str) # If it didn't match before then we don't care # This is important because we don't want to pop up and # error now if the user purposefully broke some # dependencies at some point, but if we are breaking # something we want to report that if not q.matches(package): continue # Are we going to install something that fixes it? dep_sat = super()._find_satisfier_in_set(self.installs, q) if dep_sat is not None: continue # Do we have something else that fixes it? dep_sat = self.local_repo.find_package( q, exclude=self.removes) if dep_sat is not None: continue # This upgrade is going to be a problem # @COMPLETE We should dump the package here as well. new_missing.add((dependant, q)) if len(new_missing) > 0: raise MissingDependencyError(new_missing) # @HACK: Reset removes, since the add transaction finds all packages # that are actually upgrades self.removes = [] self.targets = self.installs super().expand()