Source code for meta_package_manager.managers.pacman

# Copyright Kevin Deldycke <kevin@deldycke.com> and contributors.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

from __future__ import annotations

import re
from typing import Iterator

from extra_platforms import UNIX_WITHOUT_MACOS

from meta_package_manager.base import Package, PackageManager
from meta_package_manager.capabilities import (
    search_capabilities,
    version_not_implemented,
)


[docs] class Pacman(PackageManager): """See command equivalences at: https://wiki.archlinux.org/title/Pacman/Rosetta.""" homepage_url = "https://wiki.archlinux.org/title/pacman" platforms = UNIX_WITHOUT_MACOS requirement = "5.0.0" pre_args = ("--noconfirm",) version_regex = r".*Pacman\s+v(?P<version>\S+)" r"""Search version right after the ``Pacman `` string. .. code-block:: shell-session ► pacman --version .--. Pacman v6.0.1 - libalpm v13.0.1 / _.-' .-. .-. .-. Copyright (C) 2006-2021 Pacman Development Team \ '-. '-' '-' '-' Copyright (C) 2002-2006 Judd Vinet '--' This program may be freely redistributed under the terms of the GNU General Public License. """ @property def installed(self) -> Iterator[Package]: """Fetch installed packages. .. code-block:: shell-session ► pacman --noconfirm --query a52dec 0.7.4-11 aalib 1.4rc5-14 abseil-cpp 20211102.0-2 accountsservice 22.08.8-2 acl 2.3.1-2 acme.sh 3.0.2-1 acpi 1.7-3 acpid 2.0.33-1 """ output = self.run_cli("--query") regexp = re.compile(r"(\S+) (\S+)") for package in output.splitlines(): match = regexp.match(package) if match: package_id, installed_version = match.groups() yield self.package(id=package_id, installed_version=installed_version) @property def outdated(self) -> Iterator[Package]: """Fetch outdated packages. .. code-block:: shell-session ► pacman --noconfirm --query --upgrades linux 4.19.1.arch1-1 -> 4.19.2.arch1-1 linux-headers 4.19.1.arch1-1 -> 4.19.2.arch1-1 """ output = self.run_cli("--query", "--upgrades") regexp = re.compile(r"(\S+) (\S+) -> (\S+)") for package in output.splitlines(): match = regexp.match(package) if match: package_id, installed_version, latest_version = match.groups() yield self.package( id=package_id, latest_version=latest_version, installed_version=installed_version, )
[docs] @search_capabilities(extended_support=False) def search(self, query: str, extended: bool, exact: bool) -> Iterator[Package]: """Fetch matching packages. .. caution:: Search does not supports extended matching. .. code-block:: shell-session ► pacman --noconfirm --sync --search fire extra/dump_syms 0.0.7-1 Symbol dumper for Firefox extra/firefox 99.0-1 Standalone web browser from mozilla.org extra/firefox-i18n-ach 99.0-1 Acholi language pack for Firefox extra/firefox-i18n-af 99.0-1 Afrikaans language pack for Firefox extra/firefox-i18n-an 99.0-1 Aragonese language pack for Firefox extra/firefox-i18n-ar 99.0-1 Arabic language pack for Firefox extra/firefox-i18n-ast 99.0-1 Asturian language pack for Firefox """ if exact: query = f"^{query}$" output = self.run_cli("--sync", "--search", query) regexp = re.compile( r"(?P<repo_id>\S+?)/(?P<package_id>\S+)\s+(?P<version>\S+).*\n\s+(?P<description>.+)", re.MULTILINE | re.VERBOSE, ) for _repo_id, package_id, version, description in regexp.findall(output): yield self.package( id=package_id, description=description, latest_version=version, )
@version_not_implemented def install(self, package_id: str, version: str | None = None) -> str: """Install one package. .. code-block:: shell-session ► sudo pacman --noconfirm --sync firefox """ return self.run_cli("--sync", package_id, sudo=True)
[docs] def upgrade_all_cli(self) -> tuple[str, ...]: """Generates the CLI to upgrade the package provided as parameter. .. code-block:: shell-session ► sudo pacman --noconfirm --sync --refresh --sysupgrade """ return self.build_cli("--sync", "--refresh", "--sysupgrade", sudo=True)
@version_not_implemented def upgrade_one_cli( self, package_id: str, version: str | None = None, ) -> tuple[str, ...]: """Generates the CLI to upgrade the package provided as parameter. .. code-block:: shell-session ► sudo pacman --noconfirm --sync firefox """ return self.build_cli("--sync", package_id, sudo=True)
[docs] def remove(self, package_id: str) -> str: """Removes a package. .. code-block:: shell-session ► sudo pacman --noconfirm --remove firefox """ return self.run_cli("--remove", package_id, sudo=True)
[docs] def sync(self) -> None: """Sync package metadata. .. code-block:: shell-session ► pacman --noconfirm --sync --refresh """ self.run_cli("--sync", "--refresh")
[docs] def cleanup(self) -> None: """Removes things we don't need anymore. .. code-block:: shell-session ► sudo pacman --noconfirm --sync --clean --clean """ self.run_cli("--sync", "--clean", "--clean", sudo=True)
[docs] class Pacaur(Pacman): """``Pacaur`` wraps ``pacman`` and shadows its options.""" homepage_url = "https://github.com/E5ten/pacaur" requirement = "4.0.0" version_regex = r"pacaur\s+(?P<version>\S+)" r"""Search version right after the ``pacaur`` string. .. code-block:: shell-session ► pacaur --version pacaur 4.8.6 """
[docs] class Paru(Pacman): """``paru`` wraps ``pacman`` and shadows its options.""" homepage_url = "https://github.com/Morganamilo/paru" # v1.9.3 is the first version implementing the --sysupgrade option. requirement = "1.9.3" version_regex = r"paru\s+v(?P<version>\S+)" r"""Search version right after the ``paru`` string. .. code-block:: shell-session ► paru --version paru v1.10.0 - libalpm v13.0.1 """
[docs] class Yay(Pacman): """``yay`` wraps ``pacman`` and shadows its options.""" homepage_url = "https://github.com/Jguer/yay" requirement = "11.0.0" version_regex = r"yay\s+v(?P<version>\S+)" r"""Search version right after the ``yay`` string. .. code-block:: shell-session ► yay --version yay v11.1.2 - libalpm v13.0.1 """