def setUp(self): logging.basicConfig(level=logging.DEBUG) def test_local_upgrade_proposal(self): dirname = os.path.join(sys.prefix, "lib", "python2.5", "site-packages") repo = EasyInstallRepository(location=dirname) installed = dict((key, project.active_package) for key, project in repo.projects.items() if project.active_package != None) available = dict((key, project.packages) for key, project in repo.projects.items()) packages = set([repo.projects["codetools"].packages[0]]) print [package.name for package in packages] upgrades = upgrade(packages, installed, repo) for proposal, reasoning in upgrades: print "Proposal:" for project in proposal: print " Project:", project print "\n".join(reasoning[project]) print print def test_remote_upgrade_proposal(self): dirname = os.path.join(sys.prefix, "lib", "python2.5", "site-packages") repo = EasyInstallRepository(location=dirname) remote_repo = HTMLRepository(location="http://pypi.python.org/simple") installed = dict((key, project.active_package) for key, project in repo.projects.items()
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)