Source code for meta_package_manager.managers.deb_get
# 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 extra_platforms import LINUX_LIKE
from ..capabilities import search_capabilities, version_not_implemented
from ..manager import PackageManager
TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Iterator
from ..package import Package
[docs]
class Deb_Get(PackageManager):
"""`deb-get` installs third-party software on Debian and Ubuntu via `.deb`
packages sourced from GitHub releases, direct URLs, and PPAs.
```{note}
`deb-get` wraps `apt` under the hood for actual package installation
and removal, so all operations that modify the system require `sudo`.
```
```{caution}
`deb-get list --installed` prints bare package names with no versions,
so the installed inventory carries no version. `search` is likewise
version-less and offers no exact or extended mode, so mpm refilters its
results.
```
```{note}
There is no read-only `outdated`: detection runs `deb-get update`,
which also refreshes the package index, so the probe escalates through
`sudo` like a sync.
```
"""
name = "deb-get"
homepage_url = "https://github.com/wimpysworld/deb-get"
logo = "debian"
platforms = LINUX_LIKE
default_sudo = True
version_cli_options = ("version",)
"""
```{code-block} shell-session
$ deb-get version
0.4.5
```
"""
version_regexes = (r"(?P<version>\d+\.\d+\.\d+)",)
_OUTDATED_REGEXP = re.compile(
r"\[\+\] (?P<package_id>\S+)"
r" \((?P<installed_version>\S+)\)"
r" has an update pending\."
r" (?P<latest_version>\S+) is available\.",
)
@property
def installed(self) -> Iterator[Package]:
"""Fetch installed packages.
```{code-block} shell-session
$ deb-get list --installed
activitywatch
anydesk
bitwarden
deb-get
freeplane
google-chrome-stable
ipscan
protonvpn
zoom
```
```{note}
`deb-get list --installed` only outputs bare package names without
version information.
```
"""
output = self.run_cli("list", "--installed")
for line in output.splitlines():
package_id = line.strip()
if package_id:
yield self.package(id=package_id)
@property
def outdated(self) -> Iterator[Package]:
"""Fetch outdated packages.
```{code-block} shell-session
$ sudo deb-get update
Checking for updates to deb-get installed packages
[+] ipscan (3.9.2) has an update pending. 3.9.3 is available.
```
```{note}
Outdated detection piggybacks on `deb-get update` which also
refreshes the package index.
```
"""
output = self.run_cli("update", sudo=True)
yield from self.parse_regex_lines(self._OUTDATED_REGEXP, output)
[docs]
@search_capabilities(extended_support=False, exact_support=False)
def search(self, query: str, extended: bool, exact: bool) -> Iterator[Package]:
"""Fetch matching packages.
```{caution}
Search does not support extended or exact matching, and does not
provide version information. Returns the best subset of results and
lets
{meth}`meta_package_manager.manager.PackageManager.refiltered_search`
refine them.
```
```{code-block} shell-session
$ deb-get search zoom
zoom
```
"""
output = self.run_cli("search", query)
for line in output.splitlines():
package_id = line.strip()
if package_id:
yield self.package(id=package_id)
[docs]
@version_not_implemented
def install(self, package_id: str, version: str | None = None) -> str:
"""Install one package.
```{code-block} shell-session
$ sudo deb-get install ipscan
```
"""
return self.run_cli("install", package_id, sudo=True)
[docs]
def upgrade_all_cli(self) -> tuple[str, ...]:
"""Generates the CLI to upgrade all packages.
```{code-block} shell-session
$ sudo deb-get upgrade
```
"""
return self.build_cli("upgrade", sudo=True)
[docs]
@version_not_implemented
def upgrade_one_cli(
self,
package_id: str,
version: str | None = None,
) -> tuple[str, ...]:
"""Generates the CLI to upgrade one package by reinstalling it.
```{code-block} shell-session
$ sudo deb-get install ipscan
```
"""
return self.build_cli("install", package_id, sudo=True)
[docs]
def remove(self, package_id: str) -> str:
"""Remove one package.
```{code-block} shell-session
$ sudo deb-get remove ipscan
```
"""
return self.run_cli("remove", package_id, sudo=True)
[docs]
def sync(self) -> None:
"""Sync package metadata.
```{code-block} shell-session
$ sudo deb-get update
```
"""
self.run_cli("update", sudo=True)
[docs]
def cleanup_cache(self) -> None:
"""Remove cached downloads.
```{code-block} shell-session
$ sudo deb-get clean
```
"""
self.run_cli("clean", sudo=True)