diff --git a/news/6209.bugfix.rst b/news/6209.bugfix.rst new file mode 100644 index 0000000000..28ca2b5343 --- /dev/null +++ b/news/6209.bugfix.rst @@ -0,0 +1 @@ +Fix regression introduced with the "smarter uninstall" PR. Uninstall ``--all`` should not clear the Pipfile entries. diff --git a/pipenv/routines/uninstall.py b/pipenv/routines/uninstall.py index 27e65cf7d2..81b3d0f4ff 100644 --- a/pipenv/routines/uninstall.py +++ b/pipenv/routines/uninstall.py @@ -15,6 +15,7 @@ from pipenv.utils.resolver import venv_resolve_deps from pipenv.utils.shell import cmd_list_to_shell, project_python from pipenv.vendor import click +from pipenv.vendor.importlib_metadata.compat.py39 import normalized_name def _uninstall_from_environment(project, package, system=False): @@ -82,22 +83,29 @@ def do_uninstall( if all: click.secho( click.style( - "Un-installing all {}...".format(click.style("[packages]", fg="yellow")), + "Un-installing all packages...", bold=True, ) ) - # Uninstall all dev-packages from environment - for package in project.get_pipfile_section("packages"): - _uninstall_from_environment(project, package, system=system) - # Remove the package from the Pipfile - if project.reset_category_in_pipfile(category="packages"): - click.echo("Removed [packages] from Pipfile.") + # Uninstall all packages from all groups + for category in project.get_package_categories(): + if category in ["source", "requires"]: + continue + for package in project.get_pipfile_section(category): + _uninstall_from_environment(project, package, system=system) + + # Clear all categories in the lockfile + for category in list(lockfile_content.keys()): + if category != "_meta": + lockfile_content[category] = {} - # Finalize changes to lockfile - lockfile_content["default"] = {} lockfile_content.update({"_meta": project.get_lockfile_meta()}) project.write_lockfile(lockfile_content) + # Call do_purge to remove all packages from the environment + do_purge(project, bare=False, downloads=False, allow_global=system) + return + package_args = list(packages) + [f"-e {pkg}" for pkg in editable_packages] # Determine packages and their dependencies for removal @@ -177,8 +185,7 @@ def do_purge(project, bare=False, downloads=False, allow_global=False): # Remove comments from the output, if any. installed = { - pep423_name(pkg.project_name) - for pkg in project.environment.get_installed_packages() + normalized_name(pkg) for pkg in project.environment.get_installed_packages() } bad_pkgs = {pep423_name(pkg) for pkg in BAD_PACKAGES} # Remove setuptools, pip, etc from targets for removal diff --git a/pipenv/utils/virtualenv.py b/pipenv/utils/virtualenv.py index 27c129a0db..1f378ec8f5 100644 --- a/pipenv/utils/virtualenv.py +++ b/pipenv/utils/virtualenv.py @@ -185,7 +185,7 @@ def ensure_virtualenv(project, python=None, site_packages=None, pypi_mirror=None def cleanup_virtualenv(project, bare=True): """Removes the virtualenv directory from the system.""" if not bare: - console.pritn("[red]Environment creation aborted.[/red]") + console.print("[red]Environment creation aborted.[/red]") try: # Delete the virtualenv. shutil.rmtree(project.virtualenv_location) diff --git a/tests/integration/test_uninstall.py b/tests/integration/test_uninstall.py index e8a6bf539f..68a50b2f96 100644 --- a/tests/integration/test_uninstall.py +++ b/tests/integration/test_uninstall.py @@ -90,8 +90,11 @@ def test_uninstall_all_local_files(pipenv_instance_private_pypi, testsroot): c = p.pipenv(f"install {file_uri}") assert c.returncode == 0 c = p.pipenv("uninstall --all") - assert "tablib" not in p.pipfile["packages"] - assert "tablib" not in p.lockfile["default"] + assert c.returncode == 0 + assert "tablib" in c.stdout + # Uninstall --all is not supposed to remove things from the pipfile + # Note that it didn't before, but that instead local filenames showed as hashes + assert "tablib" in p.pipfile["packages"] @pytest.mark.install