mirror of
https://github.com/kiviktnm/decman.git
synced 2026-09-19 12:08:28 +00:00
Add source config
Config manages: - Packages - Systemd units
This commit is contained in:
@@ -1,3 +1,40 @@
|
||||
"""
|
||||
Module for writing system configurations for decman.
|
||||
"""
|
||||
|
||||
import typing
|
||||
|
||||
|
||||
class UserPackage:
|
||||
"""
|
||||
Defines a custom package.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
pkgname: str,
|
||||
version: str,
|
||||
dependencies: list[str],
|
||||
git_url: str,
|
||||
pkgbase: typing.Optional[str] = None,
|
||||
provides: typing.Optional[list[str]] = None,
|
||||
make_dependencies: typing.Optional[list[str]] = None,
|
||||
check_dependencies: typing.Optional[list[str]] = None,
|
||||
):
|
||||
if pkgbase is None:
|
||||
pkgbase = pkgname
|
||||
if provides is None:
|
||||
provides = []
|
||||
if make_dependencies is None:
|
||||
make_dependencies = []
|
||||
if check_dependencies is None:
|
||||
check_dependencies = []
|
||||
|
||||
self.pkgname = pkgname
|
||||
self.pkgbase = pkgbase
|
||||
self.version = version
|
||||
self.provides = provides
|
||||
self.dependencies = dependencies
|
||||
self.make_dependencies = make_dependencies
|
||||
self.check_dependencies = check_dependencies
|
||||
self.git_url = git_url
|
||||
|
||||
@@ -8,6 +8,7 @@ import json
|
||||
import os
|
||||
import typing
|
||||
import decman.config as conf
|
||||
import decman
|
||||
|
||||
_DECMAN_MSG_TAG = "[\033[1;35mDECMAN\033[m]"
|
||||
_RED_PREFIX = "\033[91m"
|
||||
@@ -220,6 +221,112 @@ class UserFacingError(Exception):
|
||||
self.user_facing_msg = user_facing_msg
|
||||
|
||||
|
||||
class Source:
|
||||
"""
|
||||
Configuration that describes a system.
|
||||
"""
|
||||
|
||||
def __init__(self, pacman_packages: list[str], aur_packages: list[str],
|
||||
user_packages: list[decman.UserPackage],
|
||||
ignored_packages: list[str], systemd_units: list[str],
|
||||
systemd_user_units: dict[str, list[str]]):
|
||||
self.pacman_packages = pacman_packages
|
||||
self.aur_packages = aur_packages
|
||||
self.user_packages = user_packages
|
||||
self.ignored_packages = ignored_packages
|
||||
self.systemd_units = systemd_units
|
||||
self.systemd_user_units = systemd_user_units
|
||||
|
||||
def units_to_enable(self, store: Store) -> list[str]:
|
||||
"""
|
||||
Returns all systemd units that should be enabled.
|
||||
"""
|
||||
result = []
|
||||
for unit in self.systemd_units:
|
||||
if unit not in store.enabled_systemd_units:
|
||||
result.append(unit)
|
||||
return result
|
||||
|
||||
def units_to_disable(self, store: Store) -> list[str]:
|
||||
"""
|
||||
Returns all systemd units that should be disabled.
|
||||
"""
|
||||
result = []
|
||||
for unit in store.enabled_systemd_units:
|
||||
if unit not in self.systemd_units:
|
||||
result.append(unit)
|
||||
return result
|
||||
|
||||
def user_units_to_enable(self, store: Store) -> dict[str, list[str]]:
|
||||
"""
|
||||
Returns all user systemd units that should be enabled.
|
||||
"""
|
||||
result = {}
|
||||
for user, units in self.systemd_user_units.items():
|
||||
for unit in units:
|
||||
stored = f"{user}: {unit}"
|
||||
if stored not in store.enabled_user_systemd_units:
|
||||
entry = result.get(user, [])
|
||||
entry.append(unit)
|
||||
result[user] = entry
|
||||
return result
|
||||
|
||||
def user_units_to_disable(self, store: Store) -> dict[str, list[str]]:
|
||||
"""
|
||||
Returns all user systemd units that should be disabled.
|
||||
"""
|
||||
result = {}
|
||||
for stored in store.enabled_user_systemd_units:
|
||||
s = stored.split(": ")
|
||||
user = s[0]
|
||||
unit = s[1]
|
||||
|
||||
if unit not in self.systemd_user_units.get(user, []):
|
||||
entry = result.get(user, [])
|
||||
entry.append(unit)
|
||||
result[user] = entry
|
||||
return result
|
||||
|
||||
def packages_to_remove(
|
||||
self, currently_installed_packages: list[str]) -> list[str]:
|
||||
"""
|
||||
Returns all packages that should be removed. This includes pacman, aur and user packages.
|
||||
"""
|
||||
result = []
|
||||
all_pkgs = self.pacman_packages + self.aur_packages + list(
|
||||
map(lambda p: p.pkgname, self.user_packages))
|
||||
for pkg in currently_installed_packages:
|
||||
if pkg not in all_pkgs and pkg not in self.ignored_packages:
|
||||
result.append(pkg)
|
||||
return result
|
||||
|
||||
def pacman_packages_to_install(
|
||||
self, currently_installed_packages: list[str]) -> list[str]:
|
||||
"""
|
||||
Returns all pacman packages that should be installed.
|
||||
"""
|
||||
result = []
|
||||
for pkg in self.pacman_packages:
|
||||
if pkg not in currently_installed_packages and pkg not in self.ignored_packages:
|
||||
result.append(pkg)
|
||||
return result
|
||||
|
||||
def foreign_packages_to_install(
|
||||
self, currently_installed_packages: list[str]) -> list[str]:
|
||||
"""
|
||||
Returns all aur and user packages that should be installed.
|
||||
"""
|
||||
result = []
|
||||
for pkg in self.aur_packages:
|
||||
if pkg not in currently_installed_packages and pkg not in self.ignored_packages:
|
||||
result.append(pkg)
|
||||
|
||||
for pkg in self.user_packages:
|
||||
if pkg.pkgname not in currently_installed_packages and pkg.pkgname not in self.ignored_packages:
|
||||
result.append(pkg.pkgname)
|
||||
return result
|
||||
|
||||
|
||||
class Pacman:
|
||||
"""
|
||||
Interface for interacting with pacman.
|
||||
|
||||
+29
-1
@@ -19,6 +19,7 @@ import typing
|
||||
|
||||
import requests
|
||||
|
||||
import decman
|
||||
import decman.config as conf
|
||||
import decman.lib as l
|
||||
|
||||
@@ -100,6 +101,24 @@ class PackageInfo:
|
||||
"""
|
||||
return f"{self.pkgname}-{self.version}"
|
||||
|
||||
@staticmethod
|
||||
def from_user_package(user_package: decman.UserPackage,
|
||||
pacman: l.Pacman) -> "PackageInfo":
|
||||
"""
|
||||
Converts a UserPackage to PackageInfo
|
||||
"""
|
||||
return PackageInfo(
|
||||
pkgname=user_package.pkgname,
|
||||
pkgbase=user_package.pkgbase,
|
||||
version=user_package.version,
|
||||
provides=user_package.provides,
|
||||
dependencies=user_package.dependencies,
|
||||
make_dependencies=user_package.make_dependencies,
|
||||
check_dependencies=user_package.check_dependencies,
|
||||
git_url=user_package.git_url,
|
||||
pacman=pacman,
|
||||
)
|
||||
|
||||
|
||||
class ForeignPackage:
|
||||
"""
|
||||
@@ -521,10 +540,16 @@ class ForeignPackageManager:
|
||||
self._pacman = pacman
|
||||
self._search = search
|
||||
|
||||
def upgrade(self, upgrade_devel: bool = False, force: bool = False):
|
||||
def upgrade(self,
|
||||
upgrade_devel: bool = False,
|
||||
force: bool = False,
|
||||
ignored_pkgs: typing.Optional[list[str]] = None):
|
||||
"""
|
||||
Upgrades all foreign packages.
|
||||
"""
|
||||
if ignored_pkgs is None:
|
||||
ignored_pkgs = []
|
||||
|
||||
l.print_summary("Determining packages to upgrade.")
|
||||
|
||||
all_foreign_pkgs = self._pacman.get_versioned_foreign_packages()
|
||||
@@ -538,6 +563,9 @@ class ForeignPackageManager:
|
||||
as_explicit = []
|
||||
as_deps = []
|
||||
for pkg, ver in all_foreign_pkgs:
|
||||
if pkg in ignored_pkgs:
|
||||
continue
|
||||
|
||||
info = self._search.get_package_info(pkg)
|
||||
if info is None:
|
||||
raise l.UserFacingError(f"Failed to find package: {pkg}.")
|
||||
|
||||
@@ -5,9 +5,9 @@ from decman.lib import UserFacingError, Pacman, Store
|
||||
from decman.lib.aur import ForeignPackageManager, DepGraph, ForeignPackage, ExtendedPackageSearch
|
||||
|
||||
|
||||
class TestAUR(unittest.TestCase):
|
||||
class TestVersionComparisons(unittest.TestCase):
|
||||
|
||||
def setUp(self) -> None:
|
||||
def setUp(self):
|
||||
pacman = Pacman()
|
||||
self.aur = ForeignPackageManager(Store(), pacman,
|
||||
ExtendedPackageSearch(pacman))
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
|
||||
|
||||
import unittest
|
||||
from decman.lib import Source, Store
|
||||
from decman import UserPackage
|
||||
|
||||
|
||||
class TestSource(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
source = Source(
|
||||
pacman_packages=["p1", "p2", "p3"],
|
||||
aur_packages=["A1", "A2", "A3"],
|
||||
user_packages=[
|
||||
UserPackage(
|
||||
pkgname="U1",
|
||||
version="1",
|
||||
dependencies=["d1"],
|
||||
git_url="/am/url/yes",
|
||||
),
|
||||
UserPackage(
|
||||
pkgname="U2",
|
||||
version="1",
|
||||
dependencies=["d2"],
|
||||
git_url="/am/url/yes",
|
||||
)
|
||||
],
|
||||
ignored_packages=["i1", "i2"],
|
||||
systemd_units=["1.service", "2.timer"],
|
||||
systemd_user_units={"user": ["u1.service", "u2.timer"]},
|
||||
)
|
||||
|
||||
store = Store()
|
||||
store.enabled_systemd_units.extend(["1.service", "3.service"])
|
||||
store.enabled_user_systemd_units.extend(
|
||||
["user: u1.service", "user: u3.service"])
|
||||
|
||||
currently_installed_packages = [
|
||||
"p1",
|
||||
"p2",
|
||||
"p4",
|
||||
"A2",
|
||||
"A3",
|
||||
"A4",
|
||||
"U1",
|
||||
"i1",
|
||||
]
|
||||
|
||||
self.source = source
|
||||
self.store = store
|
||||
self.currently_installed_packages = currently_installed_packages
|
||||
|
||||
def test_units_to_enable(self):
|
||||
self.assertCountEqual(
|
||||
self.source.units_to_enable(self.store),
|
||||
["2.timer"],
|
||||
)
|
||||
|
||||
def test_units_to_disable(self):
|
||||
self.assertCountEqual(
|
||||
self.source.units_to_disable(self.store),
|
||||
["3.service"],
|
||||
)
|
||||
|
||||
def test_user_units_to_enable(self):
|
||||
self.assertDictEqual(
|
||||
self.source.user_units_to_enable(self.store),
|
||||
{"user": ["u2.timer"]},
|
||||
)
|
||||
|
||||
def test_user_units_to_disable(self):
|
||||
self.assertDictEqual(
|
||||
self.source.user_units_to_disable(self.store),
|
||||
{"user": ["u3.service"]},
|
||||
)
|
||||
|
||||
def test_pacman_packages_to_install(self):
|
||||
self.assertCountEqual(
|
||||
self.source.pacman_packages_to_install(
|
||||
self.currently_installed_packages),
|
||||
["p3"],
|
||||
)
|
||||
|
||||
def test_foreign_packages_to_install(self):
|
||||
self.assertCountEqual(
|
||||
self.source.foreign_packages_to_install(
|
||||
self.currently_installed_packages),
|
||||
["A1", "U2"],
|
||||
)
|
||||
|
||||
def test_packages_to_remove(self):
|
||||
self.assertCountEqual(
|
||||
self.source.packages_to_remove(self.currently_installed_packages),
|
||||
["p4", "A4"],
|
||||
)
|
||||
Reference in New Issue
Block a user