mirror of
https://github.com/kiviktnm/decman.git
synced 2026-09-19 20:18:28 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a566adf546 | ||
|
|
616efa9629 | ||
|
|
409146cf14 | ||
|
|
70306ce2ac | ||
|
|
2378f49676 | ||
|
|
a54fad6570 | ||
|
|
6ae8c78959 | ||
|
|
69bcaadf90 | ||
|
|
7ea1ef2d81 | ||
|
|
d765eea3f4 | ||
|
|
37e85a0814 | ||
|
|
7320c88940 | ||
|
|
613beaa917 | ||
|
|
515a27cb7d | ||
|
|
dbeed0b7d8 | ||
|
|
9ce42ccf3e | ||
|
|
0ecd835090 | ||
|
|
27a8c279c4 | ||
|
|
401233a352 |
@@ -4,3 +4,4 @@ build/
|
|||||||
*.egg-info/
|
*.egg-info/
|
||||||
|
|
||||||
venv/
|
venv/
|
||||||
|
dist/
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
# Decman
|
# Decman
|
||||||
|
|
||||||
> 🎉 Decman now has a AUR package! 🎉
|
> 🎉 Early support for Flatpaks was just added! 🎉
|
||||||
>
|
> By default flatpak management is disabled. Support is in early stages so expect bugs.
|
||||||
> To start using the AUR package simply add `decman` to `decman.aur_packages`. To ensure a smooth change, add decman-git to ignored_packages during the conversion.
|
|
||||||
>
|
|
||||||
> ```py
|
> ```py
|
||||||
> import decman
|
> import decman
|
||||||
> decman.aur_packages += ["decman"]
|
> import decman.config
|
||||||
> decman.ignored_packages += ["decman-git"]
|
> decman.config.enable_flatpak = True
|
||||||
|
> # You can add system wide packages as well as user packages
|
||||||
|
> decman.flatpak_packages += ["org.signal.Signal"]
|
||||||
|
> decman.flatpak_user_packages["user"] = decman.flatpak_user_packages.get("user", [])
|
||||||
|
> decman.flatpak_user_packages["user"].append("dev.zed.Zed")
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
Decman is a declarative package & configuration manager for Arch Linux. It allows you to manage installed packages, your dotfiles, enabled systemd units, and run commands automatically. Your system is configured using python so your configuration can be very adaptive.
|
Decman is a declarative package & configuration manager for Arch Linux. It allows you to manage installed packages, your dotfiles, enabled systemd units, and run commands automatically. Your system is configured using python so your configuration can be very adaptive.
|
||||||
@@ -168,7 +171,7 @@ decman.user_packages.append(
|
|||||||
decman.UserPackage(
|
decman.UserPackage(
|
||||||
pkgname="decman-git",
|
pkgname="decman-git",
|
||||||
provides=["decman"],
|
provides=["decman"],
|
||||||
version="0.3.4",
|
version="0.4.1",
|
||||||
dependencies=["python", "python-requests", "devtools", "pacman", "systemd", "git"],
|
dependencies=["python", "python-requests", "devtools", "pacman", "systemd", "git"],
|
||||||
make_dependencies=[
|
make_dependencies=[
|
||||||
"python-setuptools", "python-build", "python-installer", "python-wheel"
|
"python-setuptools", "python-build", "python-installer", "python-wheel"
|
||||||
@@ -300,7 +303,7 @@ user_packages = [{
|
|||||||
# Also, this example may be out of date
|
# Also, this example may be out of date
|
||||||
pkgname="decman-git",
|
pkgname="decman-git",
|
||||||
provides=["decman"],
|
provides=["decman"],
|
||||||
version="0.3.4",
|
version="0.4.1",
|
||||||
dependencies=["python", "python-requests", "devtools", "pacman", "systemd", "git"],
|
dependencies=["python", "python-requests", "devtools", "pacman", "systemd", "git"],
|
||||||
make_dependencies=[
|
make_dependencies=[
|
||||||
"python-setuptools", "python-build", "python-installer", "python-wheel"
|
"python-setuptools", "python-build", "python-installer", "python-wheel"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# from import is ok for importing classes and functions
|
# from import is ok for importing classes and functions
|
||||||
# just remember to not import variables this way
|
# just remember to not import variables this way
|
||||||
from decman import Module, File, Directory, UserPackage, sh, prg
|
|
||||||
|
from decman import Directory, File, Module, UserPackage, prg, sh
|
||||||
|
|
||||||
|
|
||||||
class MyModule(Module):
|
class MyModule(Module):
|
||||||
@@ -88,7 +89,7 @@ class MyModule(Module):
|
|||||||
return [
|
return [
|
||||||
UserPackage(
|
UserPackage(
|
||||||
pkgname="decman-git",
|
pkgname="decman-git",
|
||||||
version="0.3.4",
|
version="0.4.1",
|
||||||
provides=["decman"],
|
provides=["decman"],
|
||||||
dependencies=[
|
dependencies=[
|
||||||
"python",
|
"python",
|
||||||
@@ -112,6 +113,12 @@ class MyModule(Module):
|
|||||||
def aur_packages(self) -> list[str]:
|
def aur_packages(self) -> list[str]:
|
||||||
return ["protonvpn"]
|
return ["protonvpn"]
|
||||||
|
|
||||||
|
def flatpak_packages(self) -> list[str]:
|
||||||
|
return ["org.mozilla.firefox"]
|
||||||
|
|
||||||
|
def flatpak_user_packages(self) -> dict[str, list[str]]:
|
||||||
|
return {"username": ["io.github.kolunmi.Bazaar"]}
|
||||||
|
|
||||||
def systemd_units(self) -> list[str]:
|
def systemd_units(self) -> list[str]:
|
||||||
return ["reflector.timer"]
|
return ["reflector.timer"]
|
||||||
|
|
||||||
|
|||||||
+18
-3
@@ -1,8 +1,8 @@
|
|||||||
# This example covers all decman features and many useful ways of configuring a system.
|
# This example covers all decman features and many useful ways of configuring a system.
|
||||||
# Configuration can be as simple or as complex as is needed.
|
# Configuration can be as simple or as complex as is needed.
|
||||||
|
|
||||||
import socket
|
|
||||||
import os
|
import os
|
||||||
|
import socket
|
||||||
|
|
||||||
# Note: Do NOT use from imports for global variables
|
# Note: Do NOT use from imports for global variables
|
||||||
# BAD: from decman import packages/modules/etc
|
# BAD: from decman import packages/modules/etc
|
||||||
@@ -10,7 +10,10 @@ import decman
|
|||||||
import decman.config
|
import decman.config
|
||||||
|
|
||||||
# This is fine since the thing being imported is a class and not a global variable.
|
# This is fine since the thing being imported is a class and not a global variable.
|
||||||
from decman import UserPackage, File, Directory, UserRaisedError
|
from decman import Directory, File, UserPackage, UserRaisedError
|
||||||
|
|
||||||
|
# Flatpaks are disabled by default. This way no already installed flatpaks will get suddenly deleted.
|
||||||
|
decman.config.enable_flatpak = True
|
||||||
|
|
||||||
# Configuring what packages are installed is easy.
|
# Configuring what packages are installed is easy.
|
||||||
# Duplicates are OK, so if you have multiple modules that want to ensure a package is installed,
|
# Duplicates are OK, so if you have multiple modules that want to ensure a package is installed,
|
||||||
@@ -28,6 +31,18 @@ decman.ignored_packages += ["rustup", "yay"]
|
|||||||
# Installing AUR packages is easy.
|
# Installing AUR packages is easy.
|
||||||
decman.aur_packages += ["decman", "protonvpn"]
|
decman.aur_packages += ["decman", "protonvpn"]
|
||||||
|
|
||||||
|
# Flatpaks work the same way as all other packages.
|
||||||
|
decman.flatpak_packages += ["dev.qwery.AddWater"]
|
||||||
|
|
||||||
|
# They too can be ignored of course
|
||||||
|
decman.ignored_flatpak_packages += ["org.signal.Signal"]
|
||||||
|
|
||||||
|
# You can also install them to your user installation instead of the system installation
|
||||||
|
# Ensure that previous user installed flatpak declarations aren't overwritten and they are initialized.
|
||||||
|
decman.flatpak_user_packages["kk"] = decman.flatpak_user_packages.get("kk", [])
|
||||||
|
# Now add the package.
|
||||||
|
decman.flatpak_user_packages["kk"].append("dev.zed.Zed")
|
||||||
|
|
||||||
# To import GPG keys, set the GNUPGHOME environment variable.
|
# To import GPG keys, set the GNUPGHOME environment variable.
|
||||||
# It can easily be done with python as well.
|
# It can easily be done with python as well.
|
||||||
os.environ["GNUPGHOME"] = "/home/kk/.gnupg/"
|
os.environ["GNUPGHOME"] = "/home/kk/.gnupg/"
|
||||||
@@ -42,7 +57,7 @@ decman.config.makepkg_user = "kk"
|
|||||||
decman.user_packages.append(
|
decman.user_packages.append(
|
||||||
UserPackage(
|
UserPackage(
|
||||||
pkgname="decman-git",
|
pkgname="decman-git",
|
||||||
version="0.3.4",
|
version="0.4.1",
|
||||||
provides=["decman"],
|
provides=["decman"],
|
||||||
dependencies=[
|
dependencies=[
|
||||||
"python",
|
"python",
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "decman"
|
name = "decman"
|
||||||
version = "0.3.4"
|
version = "0.4.1"
|
||||||
description = "Declarative package & configuration manager for Arch Linux."
|
description = "Declarative package & configuration manager for Arch Linux."
|
||||||
license = {file = "LICENSE"}
|
license = {file = "LICENSE"}
|
||||||
authors = [
|
authors = [
|
||||||
|
|||||||
@@ -380,6 +380,20 @@ class Module:
|
|||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def flatpak_packages(self) -> list[str]:
|
||||||
|
"""
|
||||||
|
Override this method to return flatpak packages that should be installed to the system installation as a part of this
|
||||||
|
Module.
|
||||||
|
"""
|
||||||
|
return []
|
||||||
|
|
||||||
|
def flatpak_user_packages(self) -> dict[str, list[str]]:
|
||||||
|
"""
|
||||||
|
Override this method to return flatpak packages that should be installed to the user installation as a part of this
|
||||||
|
Module.
|
||||||
|
"""
|
||||||
|
return {}
|
||||||
|
|
||||||
def systemd_units(self) -> list[str]:
|
def systemd_units(self) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Override this method to return systemd units that should be enabled as a part of this
|
Override this method to return systemd units that should be enabled as a part of this
|
||||||
@@ -412,3 +426,6 @@ enabled_systemd_user_units: dict[str, list[str]] = {}
|
|||||||
files: dict[str, File] = {}
|
files: dict[str, File] = {}
|
||||||
directories: dict[str, Directory] = {}
|
directories: dict[str, Directory] = {}
|
||||||
modules: list[Module] = []
|
modules: list[Module] = []
|
||||||
|
flatpak_packages: list[str] = []
|
||||||
|
flatpak_user_packages: dict[str, list[str]] = {}
|
||||||
|
ignored_flatpak_packages: list[str] = []
|
||||||
|
|||||||
+157
-13
@@ -1,9 +1,12 @@
|
|||||||
|
# pyright: reportUnusedCallResult=false
|
||||||
"""
|
"""
|
||||||
Module containing the CLI Application.
|
Module containing the CLI Application.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
import pwd
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
@@ -52,6 +55,12 @@ def main():
|
|||||||
default=False,
|
default=False,
|
||||||
help="don't upgrade foreign packages",
|
help="don't upgrade foreign packages",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--no-flatpaks",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="don't upgrade flatpak packages",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--no-files", action="store_true", default=False, help="don't install any files"
|
"--no-files", action="store_true", default=False, help="don't install any files"
|
||||||
)
|
)
|
||||||
@@ -177,6 +186,7 @@ def _set_up(store: l.Store, args):
|
|||||||
args.print,
|
args.print,
|
||||||
not args.no_packages,
|
not args.no_packages,
|
||||||
not args.no_foreign_packages,
|
not args.no_foreign_packages,
|
||||||
|
not args.no_flatpaks,
|
||||||
not args.no_files,
|
not args.no_files,
|
||||||
not args.no_systemd_units,
|
not args.no_systemd_units,
|
||||||
not args.no_commands,
|
not args.no_commands,
|
||||||
@@ -195,6 +205,7 @@ class Core:
|
|||||||
self.only_print,
|
self.only_print,
|
||||||
self.update_packages,
|
self.update_packages,
|
||||||
self.update_foreign_packages,
|
self.update_foreign_packages,
|
||||||
|
self.update_flatpaks,
|
||||||
self.update_files,
|
self.update_files,
|
||||||
self.update_units,
|
self.update_units,
|
||||||
self.run_commands,
|
self.run_commands,
|
||||||
@@ -202,9 +213,16 @@ class Core:
|
|||||||
self.force_build,
|
self.force_build,
|
||||||
) = opts
|
) = opts
|
||||||
|
|
||||||
|
if conf.enable_flatpak and not shutil.which("flatpak"):
|
||||||
|
l.print_error(
|
||||||
|
"Flatpaks have been enabled in the source file, but the flatpak command could not be found. Either disable flatpaks or make sure that flatpak is installed and can be accessed by decman. Exiting."
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
self.store = store
|
self.store = store
|
||||||
self.source = _resolve_source()
|
self.source = _resolve_source()
|
||||||
self.pacman = l.Pacman()
|
self.pacman = l.Pacman()
|
||||||
|
self.flatpak = l.Flatpak()
|
||||||
self.systemctl = l.Systemd(store)
|
self.systemctl = l.Systemd(store)
|
||||||
self.fpkg_search = fpm.ExtendedPackageSearch(self.pacman)
|
self.fpkg_search = fpm.ExtendedPackageSearch(self.pacman)
|
||||||
|
|
||||||
@@ -219,6 +237,7 @@ class Core:
|
|||||||
"""
|
"""
|
||||||
Run the main logic of decman.
|
Run the main logic of decman.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.update_units:
|
if self.update_units:
|
||||||
self._disable_units()
|
self._disable_units()
|
||||||
|
|
||||||
@@ -257,36 +276,154 @@ class Core:
|
|||||||
self.systemctl.disable_user_units(units, user)
|
self.systemctl.disable_user_units(units, user)
|
||||||
|
|
||||||
def _remove_pkgs(self):
|
def _remove_pkgs(self):
|
||||||
|
"""
|
||||||
|
Remove pacman and flatpak packages
|
||||||
|
"""
|
||||||
|
# pacman
|
||||||
currently_installed = self.pacman.get_installed()
|
currently_installed = self.pacman.get_installed()
|
||||||
to_remove = self.source.packages_to_remove(currently_installed)
|
to_remove = self.source.packages_to_remove(currently_installed)
|
||||||
l.print_list("Removing packages:", to_remove)
|
|
||||||
if not self.only_print:
|
currently_installed_flatpak = self.flatpak.get_installed()
|
||||||
self.pacman.remove(to_remove)
|
to_remove_flatpak = self.source.flatpak_packages_to_remove(
|
||||||
|
currently_installed_flatpak
|
||||||
|
)
|
||||||
|
|
||||||
|
l.print_list("Removing pacman packages:", to_remove)
|
||||||
|
|
||||||
|
if conf.enable_flatpak and self.update_flatpaks:
|
||||||
|
l.print_list("Removing flatpak packages:", to_remove_flatpak)
|
||||||
|
self._remove_user_flatpaks(only_print=True)
|
||||||
|
|
||||||
|
if self.only_print:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.pacman.remove(to_remove)
|
||||||
|
|
||||||
|
# flatpak
|
||||||
|
if conf.enable_flatpak and self.update_flatpaks:
|
||||||
|
self.flatpak.remove(to_remove_flatpak)
|
||||||
|
self._remove_user_flatpaks()
|
||||||
|
|
||||||
|
def _remove_user_flatpaks(self, only_print: bool = False):
|
||||||
|
# Get all non system users (users that have uid >= 1000), also ignore nobody
|
||||||
|
users = [
|
||||||
|
u.pw_name
|
||||||
|
for u in pwd.getpwall()
|
||||||
|
if u.pw_uid >= 1000 and u.pw_name not in ("nobody",)
|
||||||
|
]
|
||||||
|
# Add root to users
|
||||||
|
users.append("root")
|
||||||
|
for user in users:
|
||||||
|
currently_installed_flatpak = self.flatpak.get_installed(
|
||||||
|
as_user=True, which_user=user
|
||||||
|
)
|
||||||
|
to_remove_flatpak = self.source.flatpak_packages_to_remove(
|
||||||
|
currently_installed_flatpak, as_user=True, which_user=user
|
||||||
|
)
|
||||||
|
l.print_list(
|
||||||
|
f"Removing flatpak packages from user installation for user {user}",
|
||||||
|
to_remove_flatpak,
|
||||||
|
)
|
||||||
|
|
||||||
|
if only_print:
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.flatpak.remove(to_remove_flatpak, True, user)
|
||||||
|
|
||||||
def _upgrade_pkgs(self):
|
def _upgrade_pkgs(self):
|
||||||
|
"""
|
||||||
|
Upgrade pacman, fpm and flatpak packages
|
||||||
|
"""
|
||||||
|
# flatpak + fpm
|
||||||
l.print_summary("Upgrading packages.")
|
l.print_summary("Upgrading packages.")
|
||||||
if not self.only_print:
|
if self.only_print:
|
||||||
self.pacman.upgrade()
|
return
|
||||||
if conf.enable_fpm and self.update_foreign_packages:
|
|
||||||
self.fpm.upgrade(
|
self.pacman.upgrade()
|
||||||
self.upgrade_devel, self.force_build, self.source.ignored_packages
|
if conf.enable_fpm and self.update_foreign_packages:
|
||||||
)
|
self.fpm.upgrade(
|
||||||
|
self.upgrade_devel, self.force_build, self.source.ignored_packages
|
||||||
|
)
|
||||||
|
|
||||||
|
# flatpak
|
||||||
|
if conf.enable_flatpak and self.update_flatpaks:
|
||||||
|
l.print_summary("Upgrading flatpak packages.")
|
||||||
|
self.flatpak.upgrade()
|
||||||
|
users = [
|
||||||
|
u.pw_name
|
||||||
|
for u in pwd.getpwall()
|
||||||
|
if u.pw_uid >= 1000 and u.pw_name not in ("nobody",)
|
||||||
|
]
|
||||||
|
# Add root to users
|
||||||
|
users.append("root")
|
||||||
|
for user in users:
|
||||||
|
l.print_summary(f"Upgrading flatpak packages for {user}.")
|
||||||
|
self.flatpak.upgrade(True, user)
|
||||||
|
|
||||||
def _install_pkgs(self):
|
def _install_pkgs(self):
|
||||||
|
"""
|
||||||
|
Installs all pacman, fpm, and flatpak packages.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# pacman + fpm
|
||||||
currently_installed = self.pacman.get_installed()
|
currently_installed = self.pacman.get_installed()
|
||||||
to_install_pacman = self.source.pacman_packages_to_install(currently_installed)
|
to_install_pacman = self.source.pacman_packages_to_install(currently_installed)
|
||||||
to_install_fpm = self.source.foreign_packages_to_install(currently_installed)
|
to_install_fpm = self.source.foreign_packages_to_install(currently_installed)
|
||||||
|
|
||||||
|
# flatpak
|
||||||
|
currently_installed_flatpak = self.flatpak.get_installed()
|
||||||
|
to_install_flatpak = self.source.flatpak_packages_to_install(
|
||||||
|
currently_installed_flatpak
|
||||||
|
)
|
||||||
|
|
||||||
l.print_list("Installing pacman packages:", to_install_pacman)
|
l.print_list("Installing pacman packages:", to_install_pacman)
|
||||||
|
|
||||||
# fpm prints a summary so no need to print it twice
|
# fpm prints a summary so no need to print it twice
|
||||||
if self.only_print:
|
if self.only_print:
|
||||||
l.print_list("Installing foreign packages:", to_install_fpm)
|
l.print_list("Installing foreign packages:", to_install_fpm)
|
||||||
|
|
||||||
if not self.only_print:
|
if conf.enable_flatpak and self.update_flatpaks:
|
||||||
self.pacman.install(to_install_pacman)
|
l.print_list("Installing flatpak packages:", to_install_flatpak)
|
||||||
if conf.enable_fpm and self.update_foreign_packages:
|
|
||||||
self.fpm.install(to_install_fpm, force=self.force_build)
|
if self.only_print:
|
||||||
|
self._install_user_flatpaks(only_print=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.pacman.install(to_install_pacman)
|
||||||
|
if conf.enable_fpm and self.update_foreign_packages:
|
||||||
|
self.fpm.install(to_install_fpm, force=self.force_build)
|
||||||
|
|
||||||
|
if conf.enable_flatpak and self.update_flatpaks:
|
||||||
|
self.flatpak.install(to_install_flatpak)
|
||||||
|
# Print summary before the action
|
||||||
|
self._install_user_flatpaks(only_print=True)
|
||||||
|
self._install_user_flatpaks()
|
||||||
|
|
||||||
|
def _install_user_flatpaks(self, only_print: bool = False):
|
||||||
|
# Get all non system users (users that have uid >= 1000), also ignore nobody
|
||||||
|
users = [
|
||||||
|
u.pw_name
|
||||||
|
for u in pwd.getpwall()
|
||||||
|
if u.pw_uid >= 1000 and u.pw_name not in ("nobody",)
|
||||||
|
]
|
||||||
|
# Add root to users
|
||||||
|
users.append("root")
|
||||||
|
for user in users:
|
||||||
|
currently_installed_flatpak = self.flatpak.get_installed(
|
||||||
|
as_user=True, which_user=user
|
||||||
|
)
|
||||||
|
to_install_flatpak = self.source.flatpak_packages_to_install(
|
||||||
|
currently_installed_flatpak, as_user=True, which_user=user
|
||||||
|
)
|
||||||
|
|
||||||
|
if only_print:
|
||||||
|
l.print_list(
|
||||||
|
f"Installing flatpak packages to user installation for user {user}",
|
||||||
|
to_install_flatpak,
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.flatpak.install(to_install_flatpak, True, user)
|
||||||
|
|
||||||
def _create_and_remove_files(self):
|
def _create_and_remove_files(self):
|
||||||
l.print_summary("Installing files.")
|
l.print_summary("Installing files.")
|
||||||
@@ -346,6 +483,10 @@ def _resolve_source() -> l.Source:
|
|||||||
for user, units in decman.enabled_systemd_user_units.items():
|
for user, units in decman.enabled_systemd_user_units.items():
|
||||||
enabled_systemd_user_units[user] = set(units)
|
enabled_systemd_user_units[user] = set(units)
|
||||||
|
|
||||||
|
flatpak_user_packages = {}
|
||||||
|
for user, pkgs in decman.flatpak_user_packages.items():
|
||||||
|
flatpak_user_packages[user] = set(pkgs)
|
||||||
|
|
||||||
return l.Source(
|
return l.Source(
|
||||||
pacman_packages=set(decman.packages),
|
pacman_packages=set(decman.packages),
|
||||||
aur_packages=set(decman.aur_packages),
|
aur_packages=set(decman.aur_packages),
|
||||||
@@ -356,6 +497,9 @@ def _resolve_source() -> l.Source:
|
|||||||
files=decman.files,
|
files=decman.files,
|
||||||
directories=decman.directories,
|
directories=decman.directories,
|
||||||
modules=set(decman.modules),
|
modules=set(decman.modules),
|
||||||
|
flatpak_packages=set(decman.flatpak_packages),
|
||||||
|
flatpak_user_packages=flatpak_user_packages,
|
||||||
|
ignored_flatpak_packages=set(decman.ignored_flatpak_packages),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,20 @@ class Commands:
|
|||||||
"""
|
"""
|
||||||
return ["pacman", "-Qeq", "--color=never"]
|
return ["pacman", "-Qeq", "--color=never"]
|
||||||
|
|
||||||
|
def list_flatpak_pkgs(self, as_user: bool = False) -> list[str]:
|
||||||
|
"""
|
||||||
|
Running this command outputs a newline separated list of installed flatpak application ids
|
||||||
|
The first line just says 'Application ID' so this one is ignored.
|
||||||
|
"""
|
||||||
|
return [
|
||||||
|
"flatpak",
|
||||||
|
"list",
|
||||||
|
"--app",
|
||||||
|
"--user" if as_user else "--system",
|
||||||
|
"--columns",
|
||||||
|
"application",
|
||||||
|
]
|
||||||
|
|
||||||
def list_foreign_pkgs_versioned(self) -> list[str]:
|
def list_foreign_pkgs_versioned(self) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Running this command outputs a newline seperated list of installed packages and their
|
Running this command outputs a newline seperated list of installed packages and their
|
||||||
@@ -47,6 +61,12 @@ class Commands:
|
|||||||
"""
|
"""
|
||||||
return ["pacman", "-S", "--color=always", "--needed"] + pkgs
|
return ["pacman", "-S", "--color=always", "--needed"] + pkgs
|
||||||
|
|
||||||
|
def install_flatpak_pkgs(self, pkgs: list[str], as_user: bool = False) -> list[str]:
|
||||||
|
"""
|
||||||
|
Running this command installs all listed packages, and their dependencies/runtimes automatically.
|
||||||
|
"""
|
||||||
|
return ["flatpak", "install", "-y", "--user" if as_user else "--system"] + pkgs
|
||||||
|
|
||||||
def install_files(self, pkg_files: list[str]) -> list[str]:
|
def install_files(self, pkg_files: list[str]) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Running this command installs the given packages files.
|
Running this command installs the given packages files.
|
||||||
@@ -78,6 +98,18 @@ class Commands:
|
|||||||
"""
|
"""
|
||||||
return ["pacman", "-Syu", "--color=always"]
|
return ["pacman", "-Syu", "--color=always"]
|
||||||
|
|
||||||
|
def upgrade_flatpak(self, as_user: bool = False) -> list[str]:
|
||||||
|
"""
|
||||||
|
Updates all installed flatpak REFs including runtimes and dependencies.
|
||||||
|
"""
|
||||||
|
return [
|
||||||
|
"flatpak",
|
||||||
|
"update",
|
||||||
|
"--noninteractive",
|
||||||
|
"-y",
|
||||||
|
"--user" if as_user else "--system",
|
||||||
|
]
|
||||||
|
|
||||||
def remove(self, pkgs: list[str]) -> list[str]:
|
def remove(self, pkgs: list[str]) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Running this command removes the given packages and their dependencies
|
Running this command removes the given packages and their dependencies
|
||||||
@@ -85,6 +117,31 @@ class Commands:
|
|||||||
"""
|
"""
|
||||||
return ["pacman", "-Rs", "--color=always"] + pkgs
|
return ["pacman", "-Rs", "--color=always"] + pkgs
|
||||||
|
|
||||||
|
def remove_flatpak(self, pkgs: list[str], as_user: bool = False) -> list[str]:
|
||||||
|
"""
|
||||||
|
Running this command will remove the listed REFs. Unused dependencies might be kept, but to remove them another command needs to be run.
|
||||||
|
"""
|
||||||
|
return [
|
||||||
|
"flatpak",
|
||||||
|
"remove",
|
||||||
|
"--noninteractive",
|
||||||
|
"-y",
|
||||||
|
"--user" if as_user else "--system",
|
||||||
|
] + pkgs
|
||||||
|
|
||||||
|
def remove_unused_flatpak(self, as_user: bool = False) -> list[str]:
|
||||||
|
"""
|
||||||
|
This will remove all unused flatpak dependencies and runtimes.
|
||||||
|
"""
|
||||||
|
return [
|
||||||
|
"flatpak",
|
||||||
|
"remove",
|
||||||
|
"--noninteractive",
|
||||||
|
"-y",
|
||||||
|
"--unused",
|
||||||
|
"--user" if as_user else "--system",
|
||||||
|
]
|
||||||
|
|
||||||
def enable_units(self, units: list[str]) -> list[str]:
|
def enable_units(self, units: list[str]) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Running this command enables the given systemd units.
|
Running this command enables the given systemd units.
|
||||||
@@ -234,4 +291,5 @@ build_dir: str = "/tmp/decman/build"
|
|||||||
pkg_cache_dir: str = "/var/cache/decman"
|
pkg_cache_dir: str = "/var/cache/decman"
|
||||||
aur_rpc_timeout: typing.Optional[int] = 30
|
aur_rpc_timeout: typing.Optional[int] = 30
|
||||||
enable_fpm: bool = True
|
enable_fpm: bool = True
|
||||||
|
enable_flatpak: bool = False
|
||||||
number_of_packages_stored_in_cache: int = 3
|
number_of_packages_stored_in_cache: int = 3
|
||||||
|
|||||||
+213
-2
@@ -5,10 +5,9 @@ Library module for decman.
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import pty
|
import pty
|
||||||
|
import pwd
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
|
||||||
import threading
|
|
||||||
import time
|
import time
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
@@ -419,6 +418,9 @@ class Source:
|
|||||||
files: dict[str, decman.File],
|
files: dict[str, decman.File],
|
||||||
directories: dict[str, decman.Directory],
|
directories: dict[str, decman.Directory],
|
||||||
modules: set[decman.Module],
|
modules: set[decman.Module],
|
||||||
|
flatpak_packages: set[str],
|
||||||
|
flatpak_user_packages: dict[str, set[str]],
|
||||||
|
ignored_flatpak_packages: set[str],
|
||||||
):
|
):
|
||||||
self.pacman_packages = pacman_packages
|
self.pacman_packages = pacman_packages
|
||||||
self.aur_packages = aur_packages
|
self.aur_packages = aur_packages
|
||||||
@@ -429,6 +431,9 @@ class Source:
|
|||||||
self.files = files
|
self.files = files
|
||||||
self.directories = directories
|
self.directories = directories
|
||||||
self.modules = modules
|
self.modules = modules
|
||||||
|
self.flatpak_packages = flatpak_packages
|
||||||
|
self.flatpak_user_packages = flatpak_user_packages
|
||||||
|
self.ignored_flatpak_packages = ignored_flatpak_packages
|
||||||
|
|
||||||
def run_on_enable(self, store: Store):
|
def run_on_enable(self, store: Store):
|
||||||
"""
|
"""
|
||||||
@@ -639,6 +644,43 @@ class Source:
|
|||||||
result.append(pkg)
|
result.append(pkg)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def flatpak_packages_to_install(
|
||||||
|
self,
|
||||||
|
currently_installed_packages: list[str],
|
||||||
|
as_user: bool = False,
|
||||||
|
which_user: str = "",
|
||||||
|
) -> list[str]:
|
||||||
|
"""
|
||||||
|
Returns all flatpak packages, that are not installed or ignored
|
||||||
|
"""
|
||||||
|
|
||||||
|
result: list[str] = []
|
||||||
|
for pkg in self._all_flatpak_packages(as_user, which_user):
|
||||||
|
if pkg in self.ignored_flatpak_packages:
|
||||||
|
continue
|
||||||
|
if pkg not in currently_installed_packages:
|
||||||
|
result.append(pkg)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def flatpak_packages_to_remove(
|
||||||
|
self,
|
||||||
|
currently_installed_packages: list[str],
|
||||||
|
as_user: bool = False,
|
||||||
|
which_user: str = "",
|
||||||
|
) -> list[str]:
|
||||||
|
"""
|
||||||
|
This returns a list of flatpak app ids, that need to be removed since they are installed but not found in either the list of ignored packages,
|
||||||
|
the list of system packages or the list of user packages that need to be installed.
|
||||||
|
"""
|
||||||
|
result: list[str] = []
|
||||||
|
for package in currently_installed_packages:
|
||||||
|
if package in self.ignored_flatpak_packages:
|
||||||
|
continue
|
||||||
|
if package not in self._all_flatpak_packages(as_user, which_user):
|
||||||
|
result.append(package)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def all_enabled_modules(self) -> list[tuple[str, str]]:
|
def all_enabled_modules(self) -> list[tuple[str, str]]:
|
||||||
"""
|
"""
|
||||||
Returns all enabled modules and their versions.
|
Returns all enabled modules and their versions.
|
||||||
@@ -668,6 +710,27 @@ class Source:
|
|||||||
result.update(module.pacman_packages())
|
result.update(module.pacman_packages())
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def _all_flatpak_packages(
|
||||||
|
self, as_user: bool = False, which_user: str = ""
|
||||||
|
) -> set[str]:
|
||||||
|
# loop through all the user packages and save which ones are owned by the currently selected user
|
||||||
|
current_user_flatpak_packages = self.flatpak_user_packages.get(which_user, [])
|
||||||
|
|
||||||
|
result = set()
|
||||||
|
result.update(
|
||||||
|
self.flatpak_packages if not as_user else current_user_flatpak_packages
|
||||||
|
)
|
||||||
|
for module in self.modules:
|
||||||
|
if not module.enabled:
|
||||||
|
continue
|
||||||
|
result.update(
|
||||||
|
module.flatpak_packages()
|
||||||
|
if not as_user
|
||||||
|
else module.flatpak_user_packages().get(which_user, [])
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def _all_foreign_pkgs(self) -> set[str]:
|
def _all_foreign_pkgs(self) -> set[str]:
|
||||||
result = set()
|
result = set()
|
||||||
result.update(self.aur_packages)
|
result.update(self.aur_packages)
|
||||||
@@ -922,6 +985,154 @@ def echo_and_capture_command(program: list[str]) -> tuple[int, str]:
|
|||||||
return (returncode, output)
|
return (returncode, output)
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_info(username: str) -> tuple[int, int]:
|
||||||
|
info = pwd.getpwnam(username)
|
||||||
|
return (info.pw_uid, info.pw_gid)
|
||||||
|
|
||||||
|
|
||||||
|
class Flatpak:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_installed(self, as_user: bool = False, which_user: str = "") -> list[str]:
|
||||||
|
"""
|
||||||
|
Return all of the installed applications. Dependencies and runtimes are exluded since they will not be explicitly installed and thus flatpak will manage them.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
uinfo: tuple[int, int] = (0, 0)
|
||||||
|
|
||||||
|
env = os.environ.copy()
|
||||||
|
user_env = env.copy()
|
||||||
|
user_env["HOME"] = os.path.expanduser(f"~{which_user}")
|
||||||
|
|
||||||
|
if as_user:
|
||||||
|
uinfo = get_user_info(which_user)
|
||||||
|
|
||||||
|
proc = subprocess.run(
|
||||||
|
conf.commands.list_flatpak_pkgs(as_user),
|
||||||
|
check=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
user=uinfo[0],
|
||||||
|
group=uinfo[1],
|
||||||
|
env=user_env if as_user else env,
|
||||||
|
)
|
||||||
|
packages = proc.stdout.decode().strip().split("\n")
|
||||||
|
|
||||||
|
# print(
|
||||||
|
# f"as_user: {as_user}, which_user: {which_user}, uinfo: {uinfo}, stdout: {proc.stdout.decode()}, packages: {packages}"
|
||||||
|
# )
|
||||||
|
|
||||||
|
# The header might be included. It might also not. This will make sure that it is not present.
|
||||||
|
if "Application ID" in packages:
|
||||||
|
packages.remove("Application ID")
|
||||||
|
|
||||||
|
if packages == [""]:
|
||||||
|
return []
|
||||||
|
|
||||||
|
return packages
|
||||||
|
except subprocess.CalledProcessError as error:
|
||||||
|
raise err.UserFacingError(
|
||||||
|
user_facing_msg=f"Failed to get installed flatpak packages using '{error.cmd}'. Output: {error.stdout}."
|
||||||
|
) from error
|
||||||
|
|
||||||
|
def install(
|
||||||
|
self, packages: list[str], as_user: bool = False, which_user: str = "root"
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Install the listed flatpak packages.
|
||||||
|
"""
|
||||||
|
if not packages:
|
||||||
|
return
|
||||||
|
|
||||||
|
uinfo: tuple[int, int] = (0, 0)
|
||||||
|
if as_user:
|
||||||
|
uinfo = get_user_info(which_user)
|
||||||
|
|
||||||
|
env = os.environ.copy()
|
||||||
|
user_env = env.copy()
|
||||||
|
user_env["HOME"] = os.path.expanduser(f"~{which_user}")
|
||||||
|
|
||||||
|
proc = subprocess.run(
|
||||||
|
conf.commands.install_flatpak_pkgs(packages, as_user),
|
||||||
|
check=True,
|
||||||
|
user=uinfo[0],
|
||||||
|
group=uinfo[1],
|
||||||
|
env=user_env if as_user else env,
|
||||||
|
)
|
||||||
|
|
||||||
|
if proc.returncode != 0:
|
||||||
|
raise err.UserFacingError(
|
||||||
|
f"Failed to install flatpak packages. Process exited with code {proc.returncode}."
|
||||||
|
)
|
||||||
|
|
||||||
|
def upgrade(self, as_user: bool = False, which_user: str = "root") -> None:
|
||||||
|
"""
|
||||||
|
Upgrade all flatpak packages.
|
||||||
|
"""
|
||||||
|
uinfo: tuple[int, int] = (0, 0)
|
||||||
|
if as_user:
|
||||||
|
uinfo = get_user_info(which_user)
|
||||||
|
|
||||||
|
env = os.environ.copy()
|
||||||
|
user_env = env.copy()
|
||||||
|
user_env["HOME"] = os.path.expanduser(f"~{which_user}")
|
||||||
|
|
||||||
|
proc = subprocess.run(
|
||||||
|
conf.commands.upgrade_flatpak(as_user=True),
|
||||||
|
check=True,
|
||||||
|
user=uinfo[0],
|
||||||
|
group=uinfo[1],
|
||||||
|
env=user_env if as_user else env,
|
||||||
|
)
|
||||||
|
if not proc.returncode == 0:
|
||||||
|
raise err.UserFacingError(
|
||||||
|
f"Failed to upgrade flatpak packages. Process exited with code {proc.returncode}."
|
||||||
|
)
|
||||||
|
|
||||||
|
def remove(
|
||||||
|
self, packages: list[str], as_user: bool = False, which_user: str = "root"
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Remove all the listed packages and their unused dependecies. This has to happen in two steps.
|
||||||
|
"""
|
||||||
|
if not packages:
|
||||||
|
return
|
||||||
|
|
||||||
|
uinfo: tuple[int, int] = (0, 0)
|
||||||
|
if as_user:
|
||||||
|
uinfo = get_user_info(which_user)
|
||||||
|
|
||||||
|
env = os.environ.copy()
|
||||||
|
user_env = env.copy()
|
||||||
|
user_env["HOME"] = os.path.expanduser(f"~{which_user}")
|
||||||
|
|
||||||
|
proc = subprocess.run(
|
||||||
|
conf.commands.remove_flatpak(packages, as_user),
|
||||||
|
check=True,
|
||||||
|
user=uinfo[0],
|
||||||
|
group=uinfo[1],
|
||||||
|
env=user_env if as_user else env,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not proc.returncode == 0:
|
||||||
|
raise err.UserFacingError(
|
||||||
|
f"Failed to remove flatpak packages. Process exited with code {proc.returncode}."
|
||||||
|
)
|
||||||
|
|
||||||
|
proc = subprocess.run(
|
||||||
|
conf.commands.remove_unused_flatpak(as_user),
|
||||||
|
check=True,
|
||||||
|
user=uinfo[0] if as_user else 0,
|
||||||
|
group=uinfo[1] if as_user else 0,
|
||||||
|
env=user_env if as_user else env,
|
||||||
|
)
|
||||||
|
|
||||||
|
if not proc.returncode == 0:
|
||||||
|
raise err.UserFacingError(
|
||||||
|
f"Failed to remove unused flatpak packages. Process exited with code {proc.returncode}."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Systemd:
|
class Systemd:
|
||||||
"""
|
"""
|
||||||
Interface for interacting with systemd.
|
Interface for interacting with systemd.
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
|
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
|
||||||
|
|
||||||
|
from typing import override
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
from decman import Module, UserPackage
|
||||||
from decman.lib import Source, Store
|
from decman.lib import Source, Store
|
||||||
from decman import UserPackage, Module
|
|
||||||
|
|
||||||
|
|
||||||
class ExistingTestModule(Module):
|
class ExistingTestModule(Module):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.on_enable_executed = False
|
self.on_enable_executed = False
|
||||||
self.on_disable_executed = False
|
self.on_disable_executed = False
|
||||||
@@ -28,7 +29,6 @@ class ExistingTestModule(Module):
|
|||||||
|
|
||||||
|
|
||||||
class ExistingChangedVersionTestModule(Module):
|
class ExistingChangedVersionTestModule(Module):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.on_enable_executed = False
|
self.on_enable_executed = False
|
||||||
self.on_disable_executed = False
|
self.on_disable_executed = False
|
||||||
@@ -50,7 +50,6 @@ class ExistingChangedVersionTestModule(Module):
|
|||||||
|
|
||||||
|
|
||||||
class EnabledTestModule(Module):
|
class EnabledTestModule(Module):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.on_enable_executed = False
|
self.on_enable_executed = False
|
||||||
self.on_disable_executed = False
|
self.on_disable_executed = False
|
||||||
@@ -76,9 +75,11 @@ class EnabledTestModule(Module):
|
|||||||
def systemd_user_units(self) -> dict[str, list[str]]:
|
def systemd_user_units(self) -> dict[str, list[str]]:
|
||||||
return {"muser": ["M_u1.service"]}
|
return {"muser": ["M_u1.service"]}
|
||||||
|
|
||||||
|
def flatpak_packages(self) -> list[str]:
|
||||||
|
return ["M_f1", "M_f2"]
|
||||||
|
|
||||||
|
|
||||||
class DisabledTestModule(Module):
|
class DisabledTestModule(Module):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.on_enable_executed = False
|
self.on_enable_executed = False
|
||||||
self.on_disable_executed = False
|
self.on_disable_executed = False
|
||||||
@@ -106,7 +107,6 @@ class DisabledTestModule(Module):
|
|||||||
|
|
||||||
|
|
||||||
class TestSource(unittest.TestCase):
|
class TestSource(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.disabled_module = DisabledTestModule()
|
self.disabled_module = DisabledTestModule()
|
||||||
self.enabled_module = EnabledTestModule()
|
self.enabled_module = EnabledTestModule()
|
||||||
@@ -133,7 +133,7 @@ class TestSource(unittest.TestCase):
|
|||||||
version="1",
|
version="1",
|
||||||
dependencies=["d2"],
|
dependencies=["d2"],
|
||||||
git_url="/am/url/yes",
|
git_url="/am/url/yes",
|
||||||
)
|
),
|
||||||
},
|
},
|
||||||
ignored_packages={"i1", "i2"},
|
ignored_packages={"i1", "i2"},
|
||||||
systemd_units={"1.service", "2.timer"},
|
systemd_units={"1.service", "2.timer"},
|
||||||
@@ -141,11 +141,13 @@ class TestSource(unittest.TestCase):
|
|||||||
modules=modules,
|
modules=modules,
|
||||||
files={},
|
files={},
|
||||||
directories={},
|
directories={},
|
||||||
|
flatpak_packages={"f1", "f2", "f3"},
|
||||||
|
flatpak_user_packages={"fu1", "fu2", "fu3"},
|
||||||
|
ignored_flatpak_packages={"i1", "i2"},
|
||||||
)
|
)
|
||||||
|
|
||||||
store = Store()
|
store = Store()
|
||||||
store.enabled_systemd_units.extend(
|
store.enabled_systemd_units.extend(["1.service", "3.service", "M_1.service"])
|
||||||
["1.service", "3.service", "M_1.service"])
|
|
||||||
store.add_enabled_user_systemd_unit("user", "u1.service")
|
store.add_enabled_user_systemd_unit("user", "u1.service")
|
||||||
store.add_enabled_user_systemd_unit("user", "u3.service")
|
store.add_enabled_user_systemd_unit("user", "u3.service")
|
||||||
store.enabled_modules = {
|
store.enabled_modules = {
|
||||||
@@ -174,16 +176,19 @@ class TestSource(unittest.TestCase):
|
|||||||
self.currently_installed_packages = currently_installed_packages
|
self.currently_installed_packages = currently_installed_packages
|
||||||
|
|
||||||
def test_all_enabled_modules(self):
|
def test_all_enabled_modules(self):
|
||||||
enabled_modules = [("Enabled", "1"), ("Existing", "1"),
|
enabled_modules = [
|
||||||
("ExistingChanged", "2")]
|
("Enabled", "1"),
|
||||||
self.assertCountEqual(self.source.all_enabled_modules(),
|
("Existing", "1"),
|
||||||
enabled_modules)
|
("ExistingChanged", "2"),
|
||||||
|
]
|
||||||
|
self.assertCountEqual(self.source.all_enabled_modules(), enabled_modules)
|
||||||
|
|
||||||
def test_files_to_remove(self):
|
def test_files_to_remove(self):
|
||||||
created_files = ["/test/file1", "/test/file4"]
|
created_files = ["/test/file1", "/test/file4"]
|
||||||
self.assertCountEqual(
|
self.assertCountEqual(
|
||||||
self.source.files_to_remove(self.store, created_files),
|
self.source.files_to_remove(self.store, created_files),
|
||||||
["/test/file2", "/test/file3"])
|
["/test/file2", "/test/file3"],
|
||||||
|
)
|
||||||
|
|
||||||
def test_after_update_executed(self):
|
def test_after_update_executed(self):
|
||||||
self.source.run_after_update()
|
self.source.run_after_update()
|
||||||
@@ -197,8 +202,7 @@ class TestSource(unittest.TestCase):
|
|||||||
self.source.run_after_version_change(self.store)
|
self.source.run_after_version_change(self.store)
|
||||||
|
|
||||||
self.assertTrue(self.enabled_module.after_version_change_executed)
|
self.assertTrue(self.enabled_module.after_version_change_executed)
|
||||||
self.assertTrue(
|
self.assertTrue(self.existing_module_changed.after_version_change_executed)
|
||||||
self.existing_module_changed.after_version_change_executed)
|
|
||||||
self.assertFalse(self.existing_module.after_version_change_executed)
|
self.assertFalse(self.existing_module.after_version_change_executed)
|
||||||
self.assertFalse(self.disabled_module.after_version_change_executed)
|
self.assertFalse(self.disabled_module.after_version_change_executed)
|
||||||
|
|
||||||
@@ -233,10 +237,7 @@ class TestSource(unittest.TestCase):
|
|||||||
def test_user_units_to_enable(self):
|
def test_user_units_to_enable(self):
|
||||||
self.assertDictEqual(
|
self.assertDictEqual(
|
||||||
self.source.user_units_to_enable(self.store),
|
self.source.user_units_to_enable(self.store),
|
||||||
{
|
{"user": ["u2.timer"], "muser": ["M_u1.service"]},
|
||||||
"user": ["u2.timer"],
|
|
||||||
"muser": ["M_u1.service"]
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_user_units_to_disable(self):
|
def test_user_units_to_disable(self):
|
||||||
@@ -247,15 +248,13 @@ class TestSource(unittest.TestCase):
|
|||||||
|
|
||||||
def test_pacman_packages_to_install(self):
|
def test_pacman_packages_to_install(self):
|
||||||
self.assertCountEqual(
|
self.assertCountEqual(
|
||||||
self.source.pacman_packages_to_install(
|
self.source.pacman_packages_to_install(self.currently_installed_packages),
|
||||||
self.currently_installed_packages),
|
|
||||||
["p3", "M_p1", "M_p2"],
|
["p3", "M_p1", "M_p2"],
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_foreign_packages_to_install(self):
|
def test_foreign_packages_to_install(self):
|
||||||
self.assertCountEqual(
|
self.assertCountEqual(
|
||||||
self.source.foreign_packages_to_install(
|
self.source.foreign_packages_to_install(self.currently_installed_packages),
|
||||||
self.currently_installed_packages),
|
|
||||||
["A1", "U2"],
|
["A1", "U2"],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -265,48 +264,40 @@ class TestSource(unittest.TestCase):
|
|||||||
["p4", "A4", "M_A1", "M_A2"],
|
["p4", "A4", "M_A1", "M_A2"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestModuleUserServices(unittest.TestCase):
|
class TestModuleUserServices(unittest.TestCase):
|
||||||
|
|
||||||
class ModuleWithUserServiceOne(Module):
|
class ModuleWithUserServiceOne(Module):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__("one", True, "0")
|
super().__init__("one", True, "0")
|
||||||
|
|
||||||
def systemd_user_units(self) -> dict[str, list[str]]:
|
def systemd_user_units(self) -> dict[str, list[str]]:
|
||||||
return {
|
return {"user": ["foo.service"]}
|
||||||
"user": ['foo.service']
|
|
||||||
}
|
|
||||||
|
|
||||||
class ModuleWithUserServiceTwo(Module):
|
class ModuleWithUserServiceTwo(Module):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__("two", True, "0")
|
super().__init__("two", True, "0")
|
||||||
|
|
||||||
def systemd_user_units(self) -> dict[str, list[str]]:
|
def systemd_user_units(self) -> dict[str, list[str]]:
|
||||||
return {
|
return {"user": ["bar.service"]}
|
||||||
"user": ['bar.service']
|
|
||||||
}
|
|
||||||
|
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
self.source = Source(
|
self.source = Source(
|
||||||
pacman_packages=set(),
|
pacman_packages=set(),
|
||||||
aur_packages=set(),
|
aur_packages=set(),
|
||||||
user_packages=set(),
|
user_packages=set(),
|
||||||
ignored_packages=set(),
|
ignored_packages=set(),
|
||||||
systemd_units=set(),
|
systemd_units=set(),
|
||||||
systemd_user_units={},
|
systemd_user_units={},
|
||||||
files={},
|
files={},
|
||||||
directories={},
|
directories={},
|
||||||
modules={
|
modules={self.ModuleWithUserServiceOne(), self.ModuleWithUserServiceTwo()},
|
||||||
self.ModuleWithUserServiceOne(),
|
flatpak_packages=set(),
|
||||||
self.ModuleWithUserServiceTwo()
|
flatpak_user_packages=set(),
|
||||||
},
|
ignored_flatpak_packages=set(),
|
||||||
)
|
)
|
||||||
self.store = Store()
|
self.store = Store()
|
||||||
|
|
||||||
|
|
||||||
def test_user_units_to_enable(self):
|
def test_user_units_to_enable(self):
|
||||||
self.assertDictEqual(
|
result = self.source.user_units_to_enable(self.store)
|
||||||
self.source.user_units_to_enable(self.store),
|
self.assertEqual(len(result), 1)
|
||||||
{"user": ["foo.service", "bar.service"]},
|
self.assertCountEqual(result["user"], ["foo.service", "bar.service"])
|
||||||
)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user