mirror of
https://github.com/open-mmlab/mim.git
synced 2025-06-03 14:59:11 +08:00
[Refactor] refactor mim uninstall (#135)
* refactor(commands/uninstall.py): refactor mim uninstall * reload pip._vendor.pkg_resources before uninstall * update(commands/uninstall.py): use subprocess call_command instead of create_command * remove --root-user-action option * update(commands/uninstall.py): use subprocess call_command instead of create_command * update(commands/uninstall.py): support unknown options pass to pip uninstall * tests(tests/test_uninstall.py): add test case for mim uninstall * update(commands/uninstall.py): use the pip official recommend way to invoke pip uninstall * refine(commands/uninstall.py): use isinstance instead of 'type is' make mypy happy * combine commits: for ci debug * combine commits: for ci debug * Apply suggestions from code review Co-authored-by: Zaida Zhou <58739961+zhouzaida@users.noreply.github.com> Co-authored-by: Zaida Zhou <58739961+zhouzaida@users.noreply.github.com>
This commit is contained in:
parent
90d97cd2f7
commit
eb0b8270a7
@ -1,39 +1,83 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import sys
|
||||
from typing import Any, List, Tuple, Union
|
||||
|
||||
import click
|
||||
|
||||
from mim.click import argument, get_installed_package, param2lowercase
|
||||
from mim.utils import call_command
|
||||
|
||||
|
||||
@click.command('uninstall')
|
||||
@click.command(
|
||||
'uninstall',
|
||||
context_settings=dict(ignore_unknown_options=True),
|
||||
)
|
||||
@argument(
|
||||
'package', autocompletion=get_installed_package, callback=param2lowercase)
|
||||
'args',
|
||||
autocompletion=get_installed_package,
|
||||
callback=param2lowercase,
|
||||
nargs=-1,
|
||||
type=click.UNPROCESSED)
|
||||
@click.option(
|
||||
'-y',
|
||||
'--yes',
|
||||
'confirm_yes',
|
||||
is_flag=True,
|
||||
help='Don’t ask for confirmation of uninstall deletions.')
|
||||
def cli(package: str, confirm_yes: bool) -> None:
|
||||
@click.option(
|
||||
'-r',
|
||||
'--requirement',
|
||||
'requirements',
|
||||
multiple=True,
|
||||
help='Uninstall all the packages listed in the given requirements '
|
||||
'file. This option can be used multiple times.')
|
||||
def cli(args: Tuple,
|
||||
confirm_yes: bool = False,
|
||||
requirements: Tuple = ()) -> None:
|
||||
"""Uninstall package.
|
||||
|
||||
Same as `pip uninstall`.
|
||||
|
||||
\b
|
||||
Example:
|
||||
|
||||
> mim uninstall mmcv-full
|
||||
> mim uninstall -y mmcv-full
|
||||
> mim uninstall mmdet mmcls
|
||||
|
||||
Here we list several commonly used options.
|
||||
|
||||
For more options, please refer to `pip uninstall --help`.
|
||||
"""
|
||||
uninstall(package, confirm_yes)
|
||||
exit_code = uninstall(list(args), confirm_yes, requirements)
|
||||
exit(exit_code)
|
||||
|
||||
|
||||
def uninstall(package: str, confirm_yes=False) -> None:
|
||||
def uninstall(uninstall_args: Union[str, List],
|
||||
confirm_yes: bool = True,
|
||||
requirements: Tuple = ()) -> Any:
|
||||
"""Uninstall package.
|
||||
|
||||
Args:
|
||||
package (str): The name of uninstalled package, such as mmcv-full.
|
||||
uninstall_args (str or list): A package name or a list of package names
|
||||
to uninstalled. You can also put some `pip uninstal` options here.
|
||||
confirm_yes (bool): Don’t ask for confirmation of uninstall deletions.
|
||||
Default: True.
|
||||
"""
|
||||
uninstall_cmd = ['python', '-m', 'pip', 'uninstall', package]
|
||||
if confirm_yes:
|
||||
uninstall_cmd.append('-y')
|
||||
requirements (tuple): A tuple of requirements files to uninstalled.
|
||||
|
||||
call_command(uninstall_cmd)
|
||||
Returns:
|
||||
The status code returned by `pip uninstall`.
|
||||
"""
|
||||
if isinstance(uninstall_args, str):
|
||||
uninstall_args = [uninstall_args]
|
||||
|
||||
if confirm_yes:
|
||||
uninstall_args.append('-y')
|
||||
|
||||
for requirement_file in requirements:
|
||||
uninstall_args += ['-r', requirement_file]
|
||||
|
||||
# Use the pip official recommend way to invoke `pip uninstall`:
|
||||
# https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program
|
||||
pip_uninstall_cmd = [sys.executable, '-m', 'pip', 'uninstall']
|
||||
return call_command(pip_uninstall_cmd + uninstall_args) # type: ignore
|
||||
|
69
tests/test_uninstall.py
Normal file
69
tests/test_uninstall.py
Normal file
@ -0,0 +1,69 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
from click.testing import CliRunner
|
||||
|
||||
from mim.commands.install import cli as install
|
||||
from mim.commands.list import list_package
|
||||
from mim.commands.uninstall import cli as uninstall
|
||||
|
||||
|
||||
def setup_module():
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(uninstall, ['mmcv-full', '--yes'])
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(uninstall, ['mmcls', '--yes'])
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(uninstall, ['mmsegmentation', '--yes'])
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
||||
def test_uninstall():
|
||||
runner = CliRunner()
|
||||
|
||||
# mim install mmsegmentation --yes
|
||||
result = runner.invoke(install, ['mmsegmentation', '--yes'])
|
||||
# Use importlib reload module in the same process may cause `isinstance`
|
||||
# invalidation.
|
||||
# A known issue: `METADATA not found in /tmp/xxx/xxx.whel` will be warning
|
||||
# in pip 21.3.1, and mmcv-full could not install success as expected.
|
||||
# So here we install mmsegmentation twice as an ugly workaround.
|
||||
# TODO: find a better way to deal with this issues.
|
||||
result = runner.invoke(install, ['mmsegmentation', '--yes'])
|
||||
assert result.exit_code == 0
|
||||
|
||||
# check if install success
|
||||
result = list_package()
|
||||
installed_packages = [item[0] for item in result]
|
||||
assert 'mmsegmentation' in installed_packages
|
||||
assert 'mmcv-full' in installed_packages
|
||||
# `mim install mmsegmentation` will install mim extra requirements (via
|
||||
# mminstall.txt) automatically since PR#132, so we got installed mmcls here. # noqa: E501
|
||||
assert 'mmcls' in installed_packages
|
||||
|
||||
# mim uninstall mmsegmentation --yes
|
||||
result = runner.invoke(uninstall, ['mmsegmentation', '--yes'])
|
||||
assert result.exit_code == 0
|
||||
|
||||
# check if uninstall success
|
||||
result = list_package()
|
||||
installed_packages = [item[0] for item in result]
|
||||
assert 'mmsegmentation' not in installed_packages
|
||||
|
||||
# mim uninstall mmcls mmcv-full --yes
|
||||
result = runner.invoke(uninstall, ['mmcls', 'mmcv-full', '--yes'])
|
||||
assert result.exit_code == 0
|
||||
|
||||
# check if uninstall success
|
||||
result = list_package()
|
||||
installed_packages = [item[0] for item in result]
|
||||
assert 'mmcls' not in installed_packages
|
||||
assert 'mmcv-full' not in installed_packages
|
||||
|
||||
|
||||
def teardown_module():
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(uninstall, ['mmcv-full', '--yes'])
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(uninstall, ['mmcls', '--yes'])
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(uninstall, ['mmsegmentation', '--yes'])
|
||||
assert result.exit_code == 0
|
Loading…
x
Reference in New Issue
Block a user