From efef6c325440e5afb650f4f470a4addbefc21026 Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Mon, 16 Nov 2020 22:12:18 -0800 Subject: [PATCH 01/14] Start modifying upgrade for injected upgrade support. --- src/pipx/commands/upgrade.py | 93 ++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 37 deletions(-) diff --git a/src/pipx/commands/upgrade.py b/src/pipx/commands/upgrade.py index 309b12ba6e..2737fcda6e 100644 --- a/src/pipx/commands/upgrade.py +++ b/src/pipx/commands/upgrade.py @@ -1,6 +1,6 @@ import logging from pathlib import Path -from typing import List, Sequence +from typing import Dict, List, Sequence from pipx import constants from pipx.colors import bold, red @@ -11,33 +11,7 @@ from pipx.venv import Venv, VenvContainer -def upgrade( - venv_dir: Path, - pip_args: List[str], - verbose: bool, - *, - upgrading_all: bool, - force: bool, -) -> int: - """Returns nonzero if package was upgraded, 0 if version did not change""" - - if not venv_dir.is_dir(): - raise PipxError( - f"Package is not installed. Expected to find {str(venv_dir)}, " - "but it does not exist." - ) - - venv = Venv(venv_dir, verbose=verbose) - package = venv.main_package_name - - if not venv.package_metadata: - print( - f"Not upgrading {red(bold(package))}. It has missing internal pipx metadata.\n" - f" It was likely installed using a pipx version before 0.15.0.0.\n" - f" Please uninstall and install this package, or reinstall-all to fix." - ) - return 0 - +def _upgrade_package(venv, package, pip_args, force): package_metadata = venv.package_metadata[package] if package_metadata.package_or_url is None: @@ -48,9 +22,7 @@ def upgrade( include_apps = package_metadata.include_apps include_dependencies = package_metadata.include_dependencies - # Upgrade shared libraries (pip, setuptools and wheel) - venv.upgrade_packaging_libraries(pip_args) - + # TODO: should we use the original venv_metadata pip_args ? venv.upgrade_package( package, package_or_url, @@ -60,9 +32,6 @@ def upgrade( is_main_package=True, suffix=package_metadata.suffix, ) - # TODO 20191026: upgrade injected packages also (Issue #79) - - package_metadata = venv.package_metadata[package] display_name = f"{package_metadata.package}{package_metadata.suffix}" new_version = package_metadata.package_version @@ -82,18 +51,68 @@ def upgrade( force=force, suffix=package_metadata.suffix, ) + return (display_name, old_version, new_version) - if old_version == new_version: + +def upgrade( + venv_dir: Path, + pip_args: List[str], + verbose: bool, + *, + upgrade_injected: bool = False, + upgrading_all: bool, + force: bool, +) -> int: + """Returns nonzero if package was upgraded, 0 if version did not change""" + + if not venv_dir.is_dir(): + raise PipxError( + f"Package is not installed. Expected to find {str(venv_dir)}, " + "but it does not exist." + ) + + venv = Venv(venv_dir, verbose=verbose) + + # TODO: is this the proper way to check for missing metadata? + if not venv.package_metadata: + print( + f"Not upgrading {red(bold(venv_dir.name))}. It has missing internal pipx metadata.\n" + f" It was likely installed using a pipx version before 0.15.0.0.\n" + f" Please uninstall and install this package to fix." + ) + return 0 + + # Upgrade shared libraries (pip, setuptools and wheel) + venv.upgrade_packaging_libraries(pip_args) + + display_names: Dict[str, str] = {} + old_versions: Dict[str, str] = {} + new_versions: Dict[str, str] = {} + for package_name in venv.package_metadata: + if not upgrade_injected and package_name != venv.main_package_name: + continue + ( + display_names[package_name], + old_versions[package_name], + new_versions[package_name], + ) = _upgrade_package(venv, package_name, pip_args, force) + + # TODO: print report of injected packages upgraded or not + if old_versions[venv.main_package_name] == new_versions[venv.main_package_name]: if upgrading_all: pass else: print( - f"{display_name} is already at latest version {old_version} (location: {str(venv_dir)})" + f"{display_names[venv.main_package_name]} is already at latest version " + f"{old_versions[venv.main_package_name]} " + f"(location: {str(venv_dir)})" ) return 0 else: print( - f"upgraded package {display_name} from {old_version} to {new_version} (location: {str(venv_dir)})" + f"upgraded package {display_names[venv.main_package_name]} from " + f"{old_versions[venv.main_package_name]} to {new_versions[venv.main_package_name]} " + f"(location: {str(venv_dir)})" ) return 1 From e6433add0815f312280e26cacfeea91b4b1054bb Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Sun, 22 Nov 2020 17:00:09 -0800 Subject: [PATCH 02/14] Add include_injected argument, refactor. --- src/pipx/commands/upgrade.py | 96 +++++++++++++++++++++++------------- src/pipx/main.py | 14 +++++- 2 files changed, 75 insertions(+), 35 deletions(-) diff --git a/src/pipx/commands/upgrade.py b/src/pipx/commands/upgrade.py index 60734e1a9d..b72b0abd3e 100644 --- a/src/pipx/commands/upgrade.py +++ b/src/pipx/commands/upgrade.py @@ -12,31 +12,9 @@ from pipx.venv import Venv, VenvContainer -def _upgrade_venv( - venv_dir: Path, - pip_args: List[str], - verbose: bool, - *, - upgrading_all: bool, - force: bool, -) -> int: - """Returns 1 if package version changed, 0 if same version""" - if not venv_dir.is_dir(): - raise PipxError( - f"Package is not installed. Expected to find {str(venv_dir)}, " - "but it does not exist." - ) - - venv = Venv(venv_dir, verbose=verbose) - package = venv.main_package_name - - if not venv.package_metadata: - raise PipxError( - f"Not upgrading {red(bold(package))}. It has missing internal pipx metadata.\n" - f" It was likely installed using a pipx version before 0.15.0.0.\n" - f" Please uninstall and install this package to fix." - ) - +def _upgrade_package( + venv: Venv, package: str, pip_args: List[str], force: bool, upgrading_all: bool +) -> bool: package_metadata = venv.package_metadata[package] if package_metadata.package_or_url is None: @@ -59,7 +37,6 @@ def _upgrade_venv( is_main_package=True, suffix=package_metadata.suffix, ) - # TODO 20191026: upgrade injected packages also (Issue #79) package_metadata = venv.package_metadata[package] @@ -87,29 +64,81 @@ def _upgrade_venv( pass else: print( - f"{display_name} is already at latest version {old_version} (location: {str(venv_dir)})" + f"{display_name} is already at latest version {old_version} " + f"(location: {str(venv.root)})" ) - return 0 + return False else: print( - f"upgraded package {display_name} from {old_version} to {new_version} (location: {str(venv_dir)})" + f"upgraded package {display_name} from {old_version} to {new_version} " + f"(location: {str(venv.root)})" ) - return 1 + return True + + +def _upgrade_venv( + venv_dir: Path, + pip_args: List[str], + verbose: bool, + *, + include_injected: bool, + upgrading_all: bool, + force: bool, +) -> int: + """Returns 1 if package version changed, 0 if same version""" + if not venv_dir.is_dir(): + raise PipxError( + f"Package is not installed. Expected to find {str(venv_dir)}, " + "but it does not exist." + ) + + venv = Venv(venv_dir, verbose=verbose) + + if not venv.package_metadata: + raise PipxError( + f"Not upgrading {red(bold(venv_dir.name))}. It has missing internal pipx metadata.\n" + f" It was likely installed using a pipx version before 0.15.0.0.\n" + f" Please uninstall and install this package to fix." + ) + + # TODO 20191026: upgrade injected packages also (Issue #79) + package = venv.main_package_name + + version_change = _upgrade_package(venv, package, pip_args, force, upgrading_all) + + return 1 if version_change else 0 def upgrade( - venv_dir: Path, pip_args: List[str], verbose: bool, *, force: bool + venv_dir: Path, + pip_args: List[str], + verbose: bool, + *, + include_injected: bool, + force: bool, ) -> ExitCode: """Returns pipx exit code.""" - _ = _upgrade_venv(venv_dir, pip_args, verbose, upgrading_all=False, force=force) + _ = _upgrade_venv( + venv_dir, + pip_args, + verbose, + include_injected=include_injected, + upgrading_all=False, + force=force, + ) # Any error in upgrade will raise PipxError from vevn._run_pip() return EXIT_CODE_OK def upgrade_all( - venv_container: VenvContainer, verbose: bool, *, skip: Sequence[str], force: bool + venv_container: VenvContainer, + verbose: bool, + *, + include_injected: bool, + skip: Sequence[str], + force: bool, ) -> ExitCode: """Returns pipx exit code.""" venv_error = False @@ -126,6 +155,7 @@ def upgrade_all( venv_dir, venv.pipx_metadata.main_package.pip_args, verbose, + include_injected=include_injected, upgrading_all=True, force=force, ) diff --git a/src/pipx/main.py b/src/pipx/main.py index 0b67a406bc..87ec67fabf 100644 --- a/src/pipx/main.py +++ b/src/pipx/main.py @@ -221,10 +221,20 @@ def run_pipx_command(args: argparse.Namespace) -> ExitCode: # noqa: C901 force=args.force, ) elif args.command == "upgrade": - return commands.upgrade(venv_dir, pip_args, verbose, force=args.force) + return commands.upgrade( + venv_dir, + pip_args, + verbose, + include_injected=args.include_injected, + force=args.force, + ) elif args.command == "upgrade-all": return commands.upgrade_all( - venv_container, verbose, skip=skip_list, force=args.force + venv_container, + verbose, + include_injected=args.include_injected, + skip=skip_list, + force=args.force, ) elif args.command == "list": return commands.list_packages(venv_container, args.include_injected) From 6667e44be6d6a1694f087ba45e434d963066f271 Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Sun, 22 Nov 2020 17:01:41 -0800 Subject: [PATCH 03/14] Implement --include-injected for upgrade, upgrade-all. --- src/pipx/main.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/pipx/main.py b/src/pipx/main.py index 87ec67fabf..bb63a5000c 100644 --- a/src/pipx/main.py +++ b/src/pipx/main.py @@ -371,6 +371,11 @@ def _add_upgrade(subparsers, venv_completer) -> None: description="Upgrade a package in a pipx-managed Virtual Environment by running 'pip install --upgrade PACKAGE'", ) p.add_argument("package").completer = venv_completer + p.add_argument( + "--include-injected", + action="store_true", + help="Also upgrade packages injected into the main app's environment", + ) p.add_argument( "--force", "-f", @@ -387,7 +392,11 @@ def _add_upgrade_all(subparsers) -> None: help="Upgrade all packages. Runs `pip install -U ` for each package.", description="Upgrades all packages within their virtual environments by running 'pip install --upgrade PACKAGE'", ) - + p.add_argument( + "--include-injected", + action="store_true", + help="Also upgrade packages injected into the main app's environment", + ) p.add_argument("--skip", nargs="+", default=[], help="skip these packages") p.add_argument( "--force", From f5e235aa1cbab1bf1c3b7e6a3daa07dba64fcbd1 Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Sun, 22 Nov 2020 18:30:20 -0800 Subject: [PATCH 04/14] Functional. --- src/pipx/commands/upgrade.py | 57 +++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/src/pipx/commands/upgrade.py b/src/pipx/commands/upgrade.py index b72b0abd3e..6fd15ff5a3 100644 --- a/src/pipx/commands/upgrade.py +++ b/src/pipx/commands/upgrade.py @@ -13,7 +13,12 @@ def _upgrade_package( - venv: Venv, package: str, pip_args: List[str], force: bool, upgrading_all: bool + venv: Venv, + package: str, + pip_args: List[str], + is_main_package: bool, + force: bool, + upgrading_all: bool, ) -> bool: package_metadata = venv.package_metadata[package] @@ -25,16 +30,13 @@ def _upgrade_package( include_apps = package_metadata.include_apps include_dependencies = package_metadata.include_dependencies - # Upgrade shared libraries (pip, setuptools and wheel) - venv.upgrade_packaging_libraries(pip_args) - venv.upgrade_package( package, package_or_url, pip_args, include_dependencies=include_dependencies, include_apps=include_apps, - is_main_package=True, + is_main_package=is_main_package, suffix=package_metadata.suffix, ) @@ -43,12 +45,13 @@ def _upgrade_package( display_name = f"{package_metadata.package}{package_metadata.suffix}" new_version = package_metadata.package_version - expose_apps_globally( - constants.LOCAL_BIN_DIR, - package_metadata.app_paths, - force=force, - suffix=package_metadata.suffix, - ) + if include_apps: + expose_apps_globally( + constants.LOCAL_BIN_DIR, + package_metadata.app_paths, + force=force, + suffix=package_metadata.suffix, + ) if include_dependencies: for _, app_paths in package_metadata.app_paths_of_dependencies.items(): @@ -94,6 +97,9 @@ def _upgrade_venv( venv = Venv(venv_dir, verbose=verbose) + # Upgrade shared libraries (pip, setuptools and wheel) + venv.upgrade_packaging_libraries(pip_args) + if not venv.package_metadata: raise PipxError( f"Not upgrading {red(bold(venv_dir.name))}. It has missing internal pipx metadata.\n" @@ -101,12 +107,35 @@ def _upgrade_venv( f" Please uninstall and install this package to fix." ) - # TODO 20191026: upgrade injected packages also (Issue #79) + versions_updated = 0 + package = venv.main_package_name + version_change = _upgrade_package( + venv, + package, + pip_args, + is_main_package=True, + force=force, + upgrading_all=upgrading_all, + ) + versions_updated += 1 if version_change else 0 - version_change = _upgrade_package(venv, package, pip_args, force, upgrading_all) + # TODO 20191026: upgrade injected packages also (Issue #79) + if include_injected: + for package in venv.package_metadata: + if package == venv.main_package_name: + continue + version_change = _upgrade_package( + venv, + package, + pip_args, + is_main_package=False, + force=force, + upgrading_all=upgrading_all, + ) + versions_updated += 1 if version_change else 0 - return 1 if version_change else 0 + return versions_updated def upgrade( From 4246016d1deeaa68a1c30f6b23610f1f7b28716f Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Sun, 22 Nov 2020 18:38:10 -0800 Subject: [PATCH 05/14] Remove TODO. --- src/pipx/commands/upgrade.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pipx/commands/upgrade.py b/src/pipx/commands/upgrade.py index 6fd15ff5a3..d29312f06e 100644 --- a/src/pipx/commands/upgrade.py +++ b/src/pipx/commands/upgrade.py @@ -120,7 +120,6 @@ def _upgrade_venv( ) versions_updated += 1 if version_change else 0 - # TODO 20191026: upgrade injected packages also (Issue #79) if include_injected: for package in venv.package_metadata: if package == venv.main_package_name: From 146249b82cb61adc12b54e446c57a283684577e5 Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Sun, 22 Nov 2020 18:40:48 -0800 Subject: [PATCH 06/14] Use int to indicate version change. --- src/pipx/commands/upgrade.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/pipx/commands/upgrade.py b/src/pipx/commands/upgrade.py index d29312f06e..c5f878b8d6 100644 --- a/src/pipx/commands/upgrade.py +++ b/src/pipx/commands/upgrade.py @@ -19,7 +19,8 @@ def _upgrade_package( is_main_package: bool, force: bool, upgrading_all: bool, -) -> bool: +) -> int: + """Returns 1 if updated version changed, 0 otherwise""" package_metadata = venv.package_metadata[package] if package_metadata.package_or_url is None: @@ -70,13 +71,13 @@ def _upgrade_package( f"{display_name} is already at latest version {old_version} " f"(location: {str(venv.root)})" ) - return False + return 0 else: print( f"upgraded package {display_name} from {old_version} to {new_version} " f"(location: {str(venv.root)})" ) - return True + return 1 def _upgrade_venv( @@ -110,7 +111,7 @@ def _upgrade_venv( versions_updated = 0 package = venv.main_package_name - version_change = _upgrade_package( + versions_updated += _upgrade_package( venv, package, pip_args, @@ -118,13 +119,12 @@ def _upgrade_venv( force=force, upgrading_all=upgrading_all, ) - versions_updated += 1 if version_change else 0 if include_injected: for package in venv.package_metadata: if package == venv.main_package_name: continue - version_change = _upgrade_package( + versions_updated += _upgrade_package( venv, package, pip_args, @@ -132,7 +132,6 @@ def _upgrade_venv( force=force, upgrading_all=upgrading_all, ) - versions_updated += 1 if version_change else 0 return versions_updated From 9b86fa8d03064601ce69358e193ac647880aa53c Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Sun, 22 Nov 2020 20:56:54 -0800 Subject: [PATCH 07/14] Fix docstrings. --- src/pipx/commands/upgrade.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pipx/commands/upgrade.py b/src/pipx/commands/upgrade.py index c5f878b8d6..3f26411433 100644 --- a/src/pipx/commands/upgrade.py +++ b/src/pipx/commands/upgrade.py @@ -20,7 +20,7 @@ def _upgrade_package( force: bool, upgrading_all: bool, ) -> int: - """Returns 1 if updated version changed, 0 otherwise""" + """Returns 1 if package version changed, 0 if same version""" package_metadata = venv.package_metadata[package] if package_metadata.package_or_url is None: @@ -89,7 +89,7 @@ def _upgrade_venv( upgrading_all: bool, force: bool, ) -> int: - """Returns 1 if package version changed, 0 if same version""" + """Returns number of packages with changed versions.""" if not venv_dir.is_dir(): raise PipxError( f"Package is not installed. Expected to find {str(venv_dir)}, " From 6633b778e38da0bbba7892ce17674a26b5f0ec7b Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Sun, 22 Nov 2020 21:34:17 -0800 Subject: [PATCH 08/14] Add test. --- src/pipx/commands/upgrade.py | 2 +- tests/test_upgrade.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/pipx/commands/upgrade.py b/src/pipx/commands/upgrade.py index 3f26411433..7607eae612 100644 --- a/src/pipx/commands/upgrade.py +++ b/src/pipx/commands/upgrade.py @@ -155,7 +155,7 @@ def upgrade( force=force, ) - # Any error in upgrade will raise PipxError from vevn._run_pip() + # Any error in upgrade will raise PipxError from venv._run_pip() return EXIT_CODE_OK diff --git a/tests/test_upgrade.py b/tests/test_upgrade.py index 89b7f96eee..f6dc165821 100644 --- a/tests/test_upgrade.py +++ b/tests/test_upgrade.py @@ -55,3 +55,13 @@ def test_upgrade_specifier(pipx_temp_env, capsys): assert not run_pipx_cli(["upgrade", f"{name}"]) captured = capsys.readouterr() assert f"upgraded package {name} from {initial_version} to" in captured.out + + +def test_upgrade_include_injected(pipx_temp_env, capsys): + assert not run_pipx_cli(["install", "pylint==2.5.3"]) + assert not run_pipx_cli(["inject", "pylint", "black==18.9.b0"]) + captured = capsys.readouterr() + assert not run_pipx_cli(["pipx", "upgrade", "--include-injected", "pylint"]) + captured = capsys.readouterr() + assert "upgraded package pylint" in captured.out + assert "upgraded package black" in captured.out From 94d418a416557861eea35aaa5e77ae010692ae60 Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Sun, 22 Nov 2020 21:35:25 -0800 Subject: [PATCH 09/14] Add changelog. --- docs/changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.md b/docs/changelog.md index 610dacae01..ef884a0b59 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -12,6 +12,7 @@ dev - [feature] Autocomplete for venv names is no longer restricted to an exact match to the literal venv name, but will autocomplete any logically-similar python package name (i.e. case does not matter, and `.`, `-`, `_` characters are all equivalent.) - pipx now reinstalls its internal shared libraries when the user executes `reinstall-all`. - Made sure shell exit codes from every pipx command are correct. In the past some (like from `pipx upgrade`) were wrong. The exit code from `pipx runpip` is now the exit code from the `pip` command run. The exit code from `pipx list` will be 1 if one or more venvs have problems that need to be addressed. +- Add `--upgrade-injected` option to `pipx upgrade` and `pipx upgrade-all` to direct pipx to also upgrade injected packages. 0.15.6.0 From f9aa4204edab5eedd92fccc6b2d05771ce8fb0a2 Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Sun, 22 Nov 2020 21:54:54 -0800 Subject: [PATCH 10/14] Fix test goof. --- tests/test_upgrade.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_upgrade.py b/tests/test_upgrade.py index f6dc165821..9adf801a28 100644 --- a/tests/test_upgrade.py +++ b/tests/test_upgrade.py @@ -61,7 +61,7 @@ def test_upgrade_include_injected(pipx_temp_env, capsys): assert not run_pipx_cli(["install", "pylint==2.5.3"]) assert not run_pipx_cli(["inject", "pylint", "black==18.9.b0"]) captured = capsys.readouterr() - assert not run_pipx_cli(["pipx", "upgrade", "--include-injected", "pylint"]) + assert not run_pipx_cli(["upgrade", "--include-injected", "pylint"]) captured = capsys.readouterr() assert "upgraded package pylint" in captured.out assert "upgraded package black" in captured.out From ab334f514e3cc4d4f4c31b5b4eb524f30093738d Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Sun, 22 Nov 2020 22:23:44 -0800 Subject: [PATCH 11/14] Add another test. --- tests/test_upgrade.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_upgrade.py b/tests/test_upgrade.py index 9adf801a28..0be09b6493 100644 --- a/tests/test_upgrade.py +++ b/tests/test_upgrade.py @@ -65,3 +65,13 @@ def test_upgrade_include_injected(pipx_temp_env, capsys): captured = capsys.readouterr() assert "upgraded package pylint" in captured.out assert "upgraded package black" in captured.out + + +def test_upgrade_no_include_injected(pipx_temp_env, capsys): + assert not run_pipx_cli(["install", "pylint==2.5.3"]) + assert not run_pipx_cli(["inject", "pylint", "black==18.9.b0"]) + captured = capsys.readouterr() + assert not run_pipx_cli(["upgrade", "pylint"]) + captured = capsys.readouterr() + assert "upgraded package pylint" in captured.out + assert "upgraded package black" not in captured.out From 599f561755c787783b5ae17c5e74bbdf53dc8352 Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Sun, 22 Nov 2020 23:49:58 -0800 Subject: [PATCH 12/14] Fix changelog. --- docs/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index ef884a0b59..7023a583ee 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -12,7 +12,7 @@ dev - [feature] Autocomplete for venv names is no longer restricted to an exact match to the literal venv name, but will autocomplete any logically-similar python package name (i.e. case does not matter, and `.`, `-`, `_` characters are all equivalent.) - pipx now reinstalls its internal shared libraries when the user executes `reinstall-all`. - Made sure shell exit codes from every pipx command are correct. In the past some (like from `pipx upgrade`) were wrong. The exit code from `pipx runpip` is now the exit code from the `pip` command run. The exit code from `pipx list` will be 1 if one or more venvs have problems that need to be addressed. -- Add `--upgrade-injected` option to `pipx upgrade` and `pipx upgrade-all` to direct pipx to also upgrade injected packages. +- `pipx upgrade` and `pipx upgrade-all` now have a `--upgrade-injected` option which directs pipx to also upgrade injected packages. 0.15.6.0 From 56f4dcf5111b21c4fc9df8ff6cb7948799a841e6 Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Mon, 23 Nov 2020 15:36:22 -0800 Subject: [PATCH 13/14] Only upgrade shared libraries after checking for venv error. --- src/pipx/commands/upgrade.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pipx/commands/upgrade.py b/src/pipx/commands/upgrade.py index 7607eae612..3a0d3b26b5 100644 --- a/src/pipx/commands/upgrade.py +++ b/src/pipx/commands/upgrade.py @@ -98,9 +98,6 @@ def _upgrade_venv( venv = Venv(venv_dir, verbose=verbose) - # Upgrade shared libraries (pip, setuptools and wheel) - venv.upgrade_packaging_libraries(pip_args) - if not venv.package_metadata: raise PipxError( f"Not upgrading {red(bold(venv_dir.name))}. It has missing internal pipx metadata.\n" @@ -108,6 +105,9 @@ def _upgrade_venv( f" Please uninstall and install this package to fix." ) + # Upgrade shared libraries (pip, setuptools and wheel) + venv.upgrade_packaging_libraries(pip_args) + versions_updated = 0 package = venv.main_package_name @@ -155,7 +155,7 @@ def upgrade( force=force, ) - # Any error in upgrade will raise PipxError from venv._run_pip() + # Any error in upgrade will raise PipxError (e.g. from venv._run_pip()) return EXIT_CODE_OK From 51a3c88f0533cfc31526fdc2889e4780f132a559 Mon Sep 17 00:00:00 2001 From: Matthew Clapp Date: Mon, 23 Nov 2020 16:13:29 -0800 Subject: [PATCH 14/14] Always use package_metadata for include_apps, include_dependencies. --- src/pipx/commands/upgrade.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/pipx/commands/upgrade.py b/src/pipx/commands/upgrade.py index 3a0d3b26b5..bc3d3be276 100644 --- a/src/pipx/commands/upgrade.py +++ b/src/pipx/commands/upgrade.py @@ -28,15 +28,13 @@ def _upgrade_package( package_or_url = parse_specifier_for_upgrade(package_metadata.package_or_url) old_version = package_metadata.package_version - include_apps = package_metadata.include_apps - include_dependencies = package_metadata.include_dependencies venv.upgrade_package( package, package_or_url, pip_args, - include_dependencies=include_dependencies, - include_apps=include_apps, + include_dependencies=package_metadata.include_dependencies, + include_apps=package_metadata.include_apps, is_main_package=is_main_package, suffix=package_metadata.suffix, ) @@ -46,7 +44,7 @@ def _upgrade_package( display_name = f"{package_metadata.package}{package_metadata.suffix}" new_version = package_metadata.package_version - if include_apps: + if package_metadata.include_apps: expose_apps_globally( constants.LOCAL_BIN_DIR, package_metadata.app_paths, @@ -54,7 +52,7 @@ def _upgrade_package( suffix=package_metadata.suffix, ) - if include_dependencies: + if package_metadata.include_dependencies: for _, app_paths in package_metadata.app_paths_of_dependencies.items(): expose_apps_globally( constants.LOCAL_BIN_DIR,