diff --git a/pipsi/__init__.py b/pipsi/__init__.py index 470ce58..696c64f 100644 --- a/pipsi/__init__.py +++ b/pipsi/__init__.py @@ -423,6 +423,17 @@ def upgrade(self, package, editable=False): return True + def upgrade_all(self, packages, editable=False): + if not packages: + if os.path.isdir(self.home): + all_installed_packages = os.listdir(self.home) + packages = all_installed_packages + + for package in packages: + self.upgrade(package, editable) + + return True + def list_everything(self, versions=False): venvs = {} python = '/Scripts/python.exe' if IS_WIN else '/bin/python' @@ -491,14 +502,14 @@ def install(repo, package, python, editable, system_site_packages): @cli.command() -@click.argument('package') +@click.argument('packages', required=False, nargs=-1) @click.option('--editable', '-e', is_flag=True, help='Enable editable installation. This only works for ' 'locally installed packages.') @click.pass_obj -def upgrade(repo, package, editable): - """Upgrades an already installed package.""" - if repo.upgrade(package, editable): +def upgrade(repo, packages, editable): + """Upgrades the specifiled (or all) already installed packages.""" + if repo.upgrade_all(packages, editable): click.echo('Done.') else: sys.exit(1) diff --git a/testing/test_repo.py b/testing/test_repo.py index 90e17cf..9349bf0 100644 --- a/testing/test_repo.py +++ b/testing/test_repo.py @@ -1,8 +1,10 @@ import os import sys +import subprocess import pytest import click -from pipsi import Repo, find_scripts +from click.testing import CliRunner +from pipsi import Repo, find_scripts, cli @pytest.fixture @@ -60,6 +62,43 @@ def test_simple_install(repo, home, bin, package, glob): assert repo.upgrade(package) +def test_upgrade_all(repo, home, bin): + def installed_version(package): + pip_freeze = ['%s/%s/bin/pip' % (home.strpath, package), 'freeze'] + frozen_requirements = subprocess.check_output(pip_freeze, stderr=subprocess.STDOUT) + frozen_requirements = frozen_requirements.strip() + for requirement in frozen_requirements.split('\n'): + name, version = requirement.split('==', 2) + if name == bytes(package): + version_as_tuple = tuple([int(i) for i in version.split('.')]) + return version_as_tuple + + arbitrary_packages = [ + ('grin', (1, 2)), + ('curlish', (1, 17)), + ] + + # Install packages and assert given versions were installed: + for name, version_tuple in arbitrary_packages: + package = '%s==%s' % (name, '.'.join([str(i) for i in version_tuple])) + assert repo.install(package) + assert installed_version(name) == version_tuple + + # Run upgrade command with no packages as arguments: + runner = CliRunner() + args = ['--home', str(home), + '--bin-dir', str(bin), + 'upgrade', + # Note: no packages are given as arguments! + ] + result = runner.invoke(cli, args) + assert result.exit_code == 0 + + # Assert versions have increased: + for name, version_tuple in arbitrary_packages: + assert installed_version(name) > version_tuple + + @pytest.mark.xfail( sys.version_info[0] != 3, reason='attic is python3 only', run=False)