def remove_requirement(requirements, repos=None, interactive=False, dry_run=False): """ Remove all installed packages which match the requirements """ if repos is None: repos = get_local_repos() for requirement in requirements: removed = False for repo in repos: if requirement.key not in repo.projects: continue for package in repo.projects[requirement.key].packages: if package.distribution in requirement: removed = True if interactive: for dep in sorted(package.full_dependent_packages, key=lambda x: x.name): print "Package %s depends on %s" % (dep.name, package.name) response = query_user("Remove '%s' from %s (y/n)? " % (package.name, package.repository.location), default="y") if not response: continue package.remove(dry_run=dry_run) if not removed: warning("Found no requirement which matches %s" % requirement)
def deactivate_requirement(requirements, repos=None, interactive=False, dry_run=False): if repos is None: repos = get_local_repos() for requirement in requirements: deactivated = False for repo in repos: for package in repo.active_packages: if package.distribution in requirement: deactivated = True if interactive: response = query_user("Deactivate '%s' from %s (y/n)? " % (package.name, package.repository.location), default="y") if not response: continue package.deactivate(dry_run=dry_run) if not deactivated: warning("Found no requirement which matches %s" % requirement)
def install_requirement(requirements, target_repo=None, local_repos=None, remote_repos=None, interactive=True, dry_run=False, verbose=False, term_width=0): """ Find and install packages which match the requirements. This may either upgrade or downgrade packages when needed. """ if target_repo is None: target_repo = get_site_packages() if remote_repos is None: remote_repos = [HTMLRepository("http://pypi.python.org/simple")] if local_repos is None: local_repos = get_local_repos() # FIXME: DMP why did we not use the specified set of local repos? # Commenting out for now. #local = RepositoryUnion(get_local_repos()) local = RepositoryUnion(local_repos) available = RepositoryUnion(local_repos+remote_repos) # Generate proposals installed = dict((key, project.active_package) for key, project in local.projects.items() if project.active_package is not None) to_install = [] for requirement in requirements: # Ensure we can find at least one distribution matching the # requirement. try: packages = [package for package in available.projects[requirement.key].packages if package.distribution in requirement] except KeyError: if verbose: print "Could not find suitable distribution for %s" % \ requirement # FIXME: Should we really return here? I guess we're trying to say # we couldn't find ANY match for ALL requirements by doing so? return if not packages: warning("Could not find a package which matches requirement: " "%s" % requirement) continue # If we're running in interactive mode, let the user pick a # distribution if there is more than one to pick from. Otherwise, # we just go with the first one. if interactive and len(packages) > 1: selection = user_select(["version", "active", "location"], [pkg.metadata for pkg in packages], "Select package: ", max_width=term_width) #selection = user_select(["Package '%s' at %s%s" % (pkg.name, # pkg.location, " (Active)" if pkg.active else "") # for pkg in packages], "Select package: ") if selection == None: if verbose: info("User selected no package for requirement %s" % requirement) continue package = packages[selection] else: package = packages[0] # If the selected distribution is already active, we have nothing to # install. if package.active: if verbose: info("Package %s satisfies %s and is already active" % (package.name, requirement)) else: to_install.append(package) if not to_install: return upgrades = upgrade(to_install, installed, available) try: proposal, reasoning = upgrades.next() except StopIteration: info("Unable to create a consistent installation plan.") return if interactive: response = False while not response: print print "Proposal:" for project, package in proposal.items(): if package.active: continue for repo in local_repos: if project in repo and repo[project].active: active_project = repo[project] break else: active_project = None if active_project is None: print (" Install %s from %s" % (package.name, package.location))[:term_width] else: print (" Upgrade %s from %s to %s from %s" % ( active_project.name, active_project.active_package.version, package.version, package.location))[:term_width] response = query_user("Accept proposed installation plan (y/n)? ", default="y") if not response: try: proposal, reasoning = upgrades.next() except StopIteration: info("No proposed installation plan was acceptable " "to the user.") return # first activate any local packages active_environments = set() for key, package in proposal.items(): if isinstance(package, EasyInstallPackage): package.activate(save=False, dry_run=dry_run) active_environments.add(package.repository.active) for env in active_environments: if not dry_run: env.save() else: print "Saving .pth file." for key, package in proposal.items(): if isinstance(package, RemotePackage): package.install(target_repo, dry_run=dry_run)