From 385e77cb93f8365efb625c67c27606199b552dbc Mon Sep 17 00:00:00 2001 From: slush Date: Tue, 17 Sep 2024 13:12:41 -0500 Subject: [PATCH] fix: makes uninstall work when using the long name displayed in ape pm list (#2287) Co-authored-by: slush Co-authored-by: antazoey --- docs/userguides/dependencies.md | 6 +++++- src/ape_pm/_cli.py | 11 +++++++---- tests/functional/test_dependencies.py | 13 ++++++++----- tests/integration/cli/test_pm.py | 14 ++++++++++++++ 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/docs/userguides/dependencies.md b/docs/userguides/dependencies.md index 9e6a8170b2..adee75f67b 100644 --- a/docs/userguides/dependencies.md +++ b/docs/userguides/dependencies.md @@ -179,12 +179,16 @@ project.dependencies.install( ### uninstall -Remove previously installed packages using the `uninstall` command: +Remove previously installed packages using the `uninstall` command, providing it either the dependency's name or package_id: ```shell ape pm uninstall OpenZeppelin ``` +```shell +ape pm uninstall OpenZeppelin/openzeppelin-contracts +``` + If there is a single version installed, the command will remove the single version. If multiple versions are installed, pass additional arguments specifying the version(s) to be removed: diff --git a/src/ape_pm/_cli.py b/src/ape_pm/_cli.py index cde4a65512..f3eeba547a 100644 --- a/src/ape_pm/_cli.py +++ b/src/ape_pm/_cli.py @@ -201,9 +201,9 @@ def uninstall(cli_ctx, name, versions, yes): versions to remove. You can also choose to remove all versions of the package. Examples:\n - - Remove specific versions: ape pm remove "1.0.0" "2.0.0"\n - - Prompt to choose versions: ape pm remove \n - - Remove all versions: ape pm remove -y + - Remove specific versions: ape pm uninstall "1.0.0" "2.0.0"\n + - Prompt to choose versions: ape pm uninstall \n + - Remove all versions: ape pm uninstall -y """ pm = cli_ctx.local_project @@ -233,7 +233,10 @@ def uninstall(cli_ctx, name, versions, yes): else: deps_to_remove = { - d for d in installed if d.name == name and (d.version in versions if versions else True) + d + for d in installed + if (d.name == name or d.package_id == name) + and (d.version in versions if versions else True) } for dependency in deps_to_remove: did_find = True diff --git a/tests/functional/test_dependencies.py b/tests/functional/test_dependencies.py index fca79885d9..1686c40c1c 100644 --- a/tests/functional/test_dependencies.py +++ b/tests/functional/test_dependencies.py @@ -137,9 +137,10 @@ def test_decode_dependency_with_config_override(project): def test_uri_map(project_with_dependency_config): actual = project_with_dependency_config.dependencies.uri_map here = Path(__file__).parent - expected = f"file://{here}/data/projects/LongContractsFolder" + # Wrap in Path to handle Windows. + expected = Path(f"file://{here}/data/projects/LongContractsFolder") assert "testdependency" in actual - assert str(actual["testdependency"]) == expected + assert Path(str(actual["testdependency"])) == expected def test_get_dependency_by_package_id(project_with_downloaded_dependencies): @@ -254,13 +255,15 @@ def test_install_dependencies_of_dependencies(project, with_dependencies_project # deps_of_deps = [x for x in actual.project.dependencies.specified] -def test_uninstall(project_with_downloaded_dependencies): - name = "openzeppelin" +@pytest.mark.parametrize("name", ("openzeppelin", "OpenZeppelin/openzeppelin-contracts")) +def test_uninstall(name, project_with_downloaded_dependencies): version = "4.4.2" dm = project_with_downloaded_dependencies.dependencies dependency = dm.get_dependency(name, version) dependency.uninstall() - assert not any(d.name == name and d.version == version for d in dm.installed) + assert not any( + (d.name == name or d.package_id == name) and d.version == version for d in dm.installed + ) def test_unpack(project_with_downloaded_dependencies): diff --git a/tests/integration/cli/test_pm.py b/tests/integration/cli/test_pm.py index 6ecf906582..5ad62e7908 100644 --- a/tests/integration/cli/test_pm.py +++ b/tests/integration/cli/test_pm.py @@ -206,6 +206,20 @@ def test_uninstall(pm_runner, integ_project): assert expected_message in result.output or result._completed_process.stderr +@skip_projects_except("only-dependencies") +def test_uninstall_by_long_name(pm_runner, integ_project): + pm_runner.project = integ_project + package_name = "dependency-in-project-only" + package_long_name = integ_project.dependencies.get_dependency(package_name, "local").package_id + + # Install packages + pm_runner.invoke("install", ".", "--force") + result = pm_runner.invoke("uninstall", package_long_name, "--yes") + expected_message = f"Uninstalled '{package_name}=local'." + assert result.exit_code == 0, result.output or result._completed_process.stderr + assert expected_message in result.output or result._completed_process.stderr + + @skip_projects_except("only-dependencies") def test_uninstall_not_exists(pm_runner, integ_project): pm_runner.project = integ_project