mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-21 07:55:00 +00:00
package: Add functions for removing packages
Functions needed to spot and remove installed conflicting packages before installation of apps. - Remove all packages in a single operation as this way apt can search for solutions to conflicts more easily. - Use type hints rather than a lot of type checking. Type hints shall later be enforced using offline checking (with mypy) or at runtime (with enforce, etc.). Signed-off-by: Fioddor Superconcentrado <fioddor@gmail.com> [sunil: Run single remove operation on all packages] [sunil: Use type hints instead of extensive type checking] [sunil: Trim down the test case as it would only succeed after install] Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org> package
This commit is contained in:
parent
cb539cf1e8
commit
24f7ffe3cf
@ -48,6 +48,11 @@ def parse_arguments():
|
||||
'module', help='name of module for which package is being installed')
|
||||
subparser.add_argument('packages', nargs='+',
|
||||
help='list of packages to install')
|
||||
|
||||
subparser = subparsers.add_parser('remove', help='remove the package(s)')
|
||||
subparser.add_argument('--packages', required=True,
|
||||
help='List of packages to remove', nargs='+')
|
||||
|
||||
subparsers.add_parser('is-package-manager-busy',
|
||||
help='Return whether package manager is busy')
|
||||
subparser = subparsers.add_parser(
|
||||
@ -100,6 +105,11 @@ def subcommand_install(arguments):
|
||||
sys.exit(returncode)
|
||||
|
||||
|
||||
def subcommand_remove(arguments):
|
||||
"""Remove apt package(s)."""
|
||||
sys.exit(run_apt_command(['remove'] + arguments.packages))
|
||||
|
||||
|
||||
def _assert_managed_packages(module, packages):
|
||||
"""Check that list of packages are in fact managed by module."""
|
||||
cfg.read()
|
||||
@ -116,7 +126,8 @@ def _assert_managed_packages(module, packages):
|
||||
def subcommand_is_package_manager_busy(_):
|
||||
"""Check whether package manager is busy.
|
||||
|
||||
An exit code of zero indicates that package manager is busy."""
|
||||
An exit code of zero indicates that package manager is busy.
|
||||
"""
|
||||
if not is_package_manager_busy():
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
@ -7,11 +7,14 @@ import json
|
||||
import logging
|
||||
import subprocess
|
||||
import threading
|
||||
from typing import Union
|
||||
|
||||
import apt.cache
|
||||
from django.utils.translation import gettext as _
|
||||
from django.utils.translation import gettext_lazy
|
||||
|
||||
from plinth import actions
|
||||
from plinth.errors import ActionError, PlinthError
|
||||
from plinth.utils import format_lazy
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -195,3 +198,30 @@ def filter_conffile_prompt_packages(packages):
|
||||
'packages',
|
||||
['filter-conffile-packages', '--packages'] + list(packages))
|
||||
return json.loads(response)
|
||||
|
||||
|
||||
def packages_installed(candidates: Union[list, tuple]) -> list:
|
||||
"""Check which candidates are installed on the system.
|
||||
|
||||
:param candidates: A list of package names.
|
||||
:return: A list of installed Debian package names.
|
||||
"""
|
||||
cache = apt.cache.Cache()
|
||||
installed_packages = []
|
||||
for package_name in candidates:
|
||||
try:
|
||||
package = cache[package_name]
|
||||
if package.is_installed:
|
||||
installed_packages.append(package_name)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
return installed_packages
|
||||
|
||||
|
||||
def remove(packages: Union[list, tuple]) -> None:
|
||||
"""Remove packages."""
|
||||
try:
|
||||
actions.superuser_run('packages', ['remove', '--packages'] + packages)
|
||||
except ActionError:
|
||||
pass
|
||||
|
||||
35
plinth/tests/test_package.py
Normal file
35
plinth/tests/test_package.py
Normal file
@ -0,0 +1,35 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""
|
||||
Test module for package module.
|
||||
"""
|
||||
|
||||
from unittest.mock import call, patch
|
||||
|
||||
from plinth.errors import ActionError
|
||||
from plinth.package import packages_installed, remove
|
||||
|
||||
|
||||
def test_packages_installed():
|
||||
"""Test packages_installed()."""
|
||||
# list as input
|
||||
assert len(packages_installed([])) == 0
|
||||
assert len(packages_installed(['unknown-package'])) == 0
|
||||
assert len(packages_installed(['python3'])) == 1
|
||||
# tuples as input
|
||||
assert len(packages_installed(())) == 0
|
||||
assert len(packages_installed(('unknown-package', ))) == 0
|
||||
assert len(packages_installed(('python3', ))) == 1
|
||||
|
||||
|
||||
@patch('plinth.actions.superuser_run')
|
||||
def test_remove(run):
|
||||
"""Test removing packages."""
|
||||
remove(['package1', 'package2'])
|
||||
run.assert_has_calls(
|
||||
[call('packages', ['remove', '--packages', 'package1', 'package2'])])
|
||||
|
||||
run.reset_mock()
|
||||
run.side_effect = ActionError()
|
||||
remove(['package1'])
|
||||
run.assert_has_calls(
|
||||
[call('packages', ['remove', '--packages', 'package1'])])
|
||||
Loading…
x
Reference in New Issue
Block a user