diff --git a/README.md b/README.md index 1c47ca3..2ae21a1 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ Decman is a declarative package & configuration manager for Arch Linux. It allow ## Overview +[See the example for a quick tutorial.](/example/README.md) + To use decman, you need a source file that declares your system installation. I recommend you put this file in source control, for example in a git repository. `/home/user/config/source.py`: diff --git a/docs/README.md b/docs/README.md index b392381..e64fd46 100644 --- a/docs/README.md +++ b/docs/README.md @@ -375,10 +375,10 @@ For conveniance, decman provides some plugins with quick access. ```py import decman -decman.pacman = decman.plugins.get("pacman") -decman.aur = decman.plugins.get("aur") -decman.systemd = decman.plugins.get("systemd") -decman.flatpak = decman.plugins.get("flatpak") +assert decman.pacman == decman.plugins.get("pacman") +assert decman.aur == decman.plugins.get("aur") +assert decman.systemd == decman.plugins.get("systemd") +assert decman.flatpak == decman.plugins.get("flatpak") ``` ### Creating custom plugins @@ -457,6 +457,7 @@ In `pyproject.toml` set: systemd = "decman.plugins.systemd:Systemd" pacman = "decman.plugins.pacman:Pacman" aur = "decman.plugins.aur:AUR" +flatpak = "decman.plugins.flatpak:Flatpak" ``` ## Useful utilities diff --git a/docs/aur.md b/docs/aur.md index 594c308..6922c45 100644 --- a/docs/aur.md +++ b/docs/aur.md @@ -43,6 +43,18 @@ decman.aur.custom_packages |= { This plugin's execution order step name is `aur`. +### Command line + +This plugin accepts params via the command line. + +```sh +sudo decman --params aur-upgrade-devel aur-force +``` + +`aur-upgrade-devel` causes devel packages (packages from version control, such as `*-git` packages) to be upgraded. + +`aur-force` causes decman to rebuild packages that were already cached. + ### Within modules Modules can also define AUR packages and custom packages. Decorate a module's method with `@decman.plugins.aur.packages` or `@decman.plugins.aur.custom_packages`. For AUR packages return a `set[str]` of package names from that module. Custom packages should return a `set[CustomPackage]`. diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..80be67c --- /dev/null +++ b/example/README.md @@ -0,0 +1,212 @@ +# Example + +This directory contains an example of a minimal decman configuration. This also functions as a tutorial for starting out with decman. I recommend looking at the [docs](/docs/README.md) after this. + +## Tutorial + +### Installing decman + +I will first install git and base-devel. Then I'll clone the PKGBUILD and install decman. + +```sh +sudo pacman -S git base-devel +git clone https://aur.archlinux.org/decman.git +cd decman/ +makepkg -sic +``` + +### Starting out + +I will create a source directory for the system's configuration. + +```sh +mkdir ~/source +cd ~/source +``` + +Decman will remove all explicitly installed packages not found in the source. Let's find all explicitly installed packages. + +```sh +$ pacman -Qeq +base +base-devel +btrfs-progs +decman +dosfstools +efibootmgr +git +grub +linux +openssh +qemu-guest-agent +sudo +vim +``` + +First thing to note: `decman` is not a native package. I remember this, but if you don't, you can find only native packages with `pacman -Qeqn` and foreign packages with `pacman -Qeqm`. Since decman is not a native package, the pacman plugin cannot handle it. I'll add decman to AUR packages. + +Instead of adding all of these packages to `decman.pacman.packages`, I will first create a module for base system packages in `~/source/base.py`. + +```py +import decman +from decman.plugins import pacman, aur + +class BaseModule(decman.Module): + + def __init__(self): + # I'll intend this module to be a singleton (only one instance ever), + # so I'll inline the module name + super().__init__("base") + + @pacman.packages + def pkgs(self) -> set[str]: + return { + "base", + "btrfs-progs", + "dosfstools", + "efibootmgr", + "grub", + "linux", + + # I'll also include git and base-devel here, they are essential to this system + "git", + "base-devel", + } + + @aur.packages + def aurpkgs(self) -> set[str]: + return {"decman"} +``` + +Then I'll create the main source file with the rest of the packages. I'll import `BaseModule` and add it to `decman.modules`. The main file is `~/source/source.py`. + +```py +import decman +from base import BaseModule + +decman.pacman.packages |= {"openssh", "qemu-guest-agent", "sudo", "vim"} +decman.modules |= {BaseModule()} +``` + +This config is already enough to run decman for the first time. + +```sh +sudo decman --source /home/arch/source/source.py +``` + +This will run a system upgrade, but otherwise nothing else happens, since my system already matches the desired configuration. + +### Extending my config with files and commands + +Now I'll want to gradually add more stuff to my config. As an example, I'll add my custom `mkinitcpio.conf`. I'll create the file `~/source/files/mkinitcpio.conf` with the desired content. Then I'll add the file to my `BaseModule`. Since I want to run the command `mkinitcpio -P` every time I update my config, I'll add a on change hook as well. I'll update the file `~/source/base.py`. + +```py +class BaseModule(decman.Module): + ... + + def files(self) -> dict[str, decman.File]: + return {"/etc/mkinitcpio.conf": decman.File(source_file="./files/mkinitcpio.conf")} + + def on_change(self, store): + decman.prg(["mkinitcpio", "-P"]) +``` + +I'll also add my vim config to decman. I could now create a Vim module, but since my config is simple, I feel that is not needed. I'll update the main source file `~/source/source.py`. + +```py +import decman + +... + +decman.files["/home/arch/.vimrc"] = decman.File(source_file="./files/vimrc", owner="arch", permissions=0o600) +``` + +Then I'll apply my changes. Decman will remember my source, so no need to give it as an argument anymore. I don't want to waste time checking for aur updates, so I'll skip them. + +```sh +sudo decman --skip aur +``` + +### Systemd services and flatpaks + +I want add a desktop environment. I'll create a module for that in the file `~/source/kde.py`. I'll use SDDM as the login manager. SDDM service needs to be enabled, so I'll use the systemd plugin for that. + +```py +import decman +from decman.plugins import pacman, systemd + +class KDE(decman.Module): + + def __init__(self): + super().__init__("kde") + + @pacman.packages + def pkgs(self) -> set[str]: + return { + "plasma-desktop", + "konsole", + "sddm", + } + + @systemd.units + def units(self) -> set[str]: + return {"sddm.service"} +``` + +I'll add the module to enabled modules in `~/source/source.py`. + +```py +import decman +from base import BaseModule +from kde import KDE + +... + +decman.modules |= {BaseModule(), KDE()} +``` + +I'll run decman once again. I'll also start SDDM manually, since decman can't autostart it. + +```sh +sudo decman +sudo systemctl start sddm +``` + +Lastly I want to install some packages with flatpak. I'll first have to install flatpak to make the plugin available. I'll do it manually since it's quicker. + +```sh +sudo pacman -S flatpak +``` + +Then I'll modify `~/source/source.py`. I must add `flatpak` to execution steps to run the plugin. + +```py +import decman + +... + +decman.execution_order = [ + "files", + "pacman", + "aur", + "flatpak", + "systemd", +] + +decman.pacman.packages.add("flatpak") +decman.flatpak.packages |= {"org.mozilla.firefox", "org.signal.Signal"} +``` + +Then run decman. + +```sh +sudo decman +``` + +### Maintaining a system with decman + +Decman is intended to replace your upgrade procedures. Instead of running `yay -Syu` for example, you would run `sudo decman`. With `after_update` hooks you can chain other update commands such as `rustup update`. This way you'll only have to remember to run decman. All other update steps are defined in your source. + +## Plugins + +It is possible to create your own plugins for decman. However, you probably won't need to do that, as modules are already very capable. This example directory also contains a **very** minimal plugin. To learn more about plugins, look at [the docs](/docs/README.md). diff --git a/example/files/app-config/config.cfg b/example/files/app-config/config.cfg deleted file mode 100644 index bff80b8..0000000 --- a/example/files/app-config/config.cfg +++ /dev/null @@ -1 +0,0 @@ -# Imagine something here diff --git a/example/files/app-config/f.txt b/example/files/app-config/f.txt deleted file mode 100644 index cf66dbf..0000000 --- a/example/files/app-config/f.txt +++ /dev/null @@ -1,3 +0,0 @@ -Why are you looking here? - -What is '%msg%'? diff --git a/example/files/app-config/sub-dir/i-will-be-copied-too.txt b/example/files/app-config/sub-dir/i-will-be-copied-too.txt deleted file mode 100644 index 44a3b38..0000000 --- a/example/files/app-config/sub-dir/i-will-be-copied-too.txt +++ /dev/null @@ -1 +0,0 @@ -Thats right! diff --git a/example/files/mkinitcpio.conf b/example/files/mkinitcpio.conf new file mode 100644 index 0000000..5251226 --- /dev/null +++ b/example/files/mkinitcpio.conf @@ -0,0 +1,4 @@ +MODULES=() +BINARIES=() +FILES=() +HOOKS=(base systemd autodetect microcode modconf kms keyboard keymap sd-vconsole block filesystems fsck) diff --git a/example/files/user-script.sh b/example/files/user-script.sh deleted file mode 100644 index 3ed70fb..0000000 --- a/example/files/user-script.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -echo "Hello, World!" diff --git a/example/files/vimrc b/example/files/vimrc new file mode 100644 index 0000000..17357aa --- /dev/null +++ b/example/files/vimrc @@ -0,0 +1,2 @@ +set number +syntax on diff --git a/example/my_module.py b/example/my_module.py deleted file mode 100644 index dc391f5..0000000 --- a/example/my_module.py +++ /dev/null @@ -1,124 +0,0 @@ -# from import is ok for importing classes and functions -# just remember to not import variables this way - -from decman import Directory, File, Module, UserPackage, prg, sh - - -class MyModule(Module): - def __init__(self): - self.pkgs = ["rust"] - self.update_rustup = False - # Modules have names and versions. - # Names must be unique. - - # If you disable a module, all packages, files etc assocated with module are removed. - super().__init__(name="Example module", enabled=True, version="1") - - # You can add any methods etc to your modules. - def enable_my_custom_feature(self, b: bool): - if b: - self.pkgs = ["rustup"] - self.update_rustup = True - - # This is ran, when the module gets enabled - def on_enable(self): - # Run arbitary shell code easily with the included sh function. - sh("groupadd mygroup") - - # or run a program with arguments. - prg(["usermod", "--append", "--groups", "mygroup", "kk"]) - - # NOTE! Removing a enabled module from decman.module means that on_disable will not run. - # Instead disable the module. - def on_disable(self): - # You can run commands as any user - sh("whoami", user="kk") - - # And override environment variables - sh("echo $HI", env_overrides={"HI": "Hello!"}) - - # Same options apply to prg as well. - - def after_update(self): - # Run code after running decman. - if self.update_rustup: - prg(["rustup", "update"], user="kk") - - def after_version_change(self): - # Modules have version numbers to allow conditionally running code. - # You could for example run mkinitcpio only after your config has changed. - # Just remember to change the version number. - prg(["mkinitcpio", "-P"]) - - # Files defined here are the same as outside of modules. - # There is however an additional feature: - # You may add variables to text files, that will be replaced with the given value. - - def file_variables(self) -> dict[str, str]: - return {"%msg%": "Hello, world!"} - - def files(self) -> dict[str, File]: - # Variables are substituted in text files automatically. - return { - "/usr/local/bin/say-hello": File( - content="#!/usr/bin/env bash\necho %msg%", permissions=0o755 - ), - # Variables are not substituted in binary files. - "/usr/local/share/say-hello/image.png": File( - source_file="files/i-dont-exist.png", bin_file=True - ), - } - - def directories(self) -> dict[str, Directory]: - # Directories are handeled the same way. Variables are substituted in text files. - return { - "/home/kk/.config/mod-app/": Directory(source_directory="files/app-config", owner="kk") - } - - # Packages and systemd units are basically the same with modules as without modules. - - def pacman_packages(self) -> list[str]: - # Return pacman packages depending on the usage of this module. - return self.pkgs - - def user_packages(self) -> list[UserPackage]: - # Note, decman now has a aur package, I recommend using that instead. - # Also, this example may be out of date - return [ - UserPackage( - pkgname="decman-git", - version="0.4.1", - provides=["decman"], - dependencies=[ - "python", - "python-requests", - "devtools", - "systemd", - "pacman", - "git", - "less", - ], - make_dependencies=[ - "python-setuptools", - "python-build", - "python-installer", - "python-wheel", - ], - git_url="https://github.com/kiviktnm/decman-pkgbuild.git", - ) - ] - - def aur_packages(self) -> list[str]: - 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]: - return ["reflector.timer"] - - def systemd_user_units(self) -> dict[str, list[str]]: - return {"kk": ["syncthing.service"]} diff --git a/example/plugin/decman_plugin_example.py b/example/plugin/decman_plugin_example.py index 80b3260..2381664 100644 --- a/example/plugin/decman_plugin_example.py +++ b/example/plugin/decman_plugin_example.py @@ -8,3 +8,13 @@ class Example(decman.Plugin): def available(self) -> bool: return os.path.exists("/tmp/example_plugin_available") + + def process_modules(self, store: decman.Store, modules: set[decman.Module]): + # Toy example for setting modules as changed + for module in modules: + module._changed = True + + def apply( + self, store: decman.Store, dry_run: bool = False, params: list[str] | None = None + ) -> bool: + return True diff --git a/example/source.py b/example/source.py deleted file mode 100644 index e6c06f8..0000000 --- a/example/source.py +++ /dev/null @@ -1,320 +0,0 @@ -# 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. - -import os -import socket - -# Note: Do NOT use from imports for global variables -# BAD: from decman import packages/modules/etc -import decman -import decman.config - -# This is fine since the thing being imported is a class and not a global variable. -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. -# Duplicates are OK, so if you have multiple modules that want to ensure a package is installed, -# you can add the same package multiple times. -decman.packages += ["python", "python", "devtools", "git", "networkmanager"] - -# Decman matches installed packages to those defined in the configuration. -# This means that: -# - all packages not installed on the system but defined in the source are installed -# - all packages installed on the system but not defined in the source are removed -# To make decman not care if a package is installed or not, add it to ignored_packages. -# Ignored packages can be normal packages or aur packages. -decman.ignored_packages += ["rustup", "yay"] - -# Installing AUR packages is easy. -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. -# It can easily be done with python as well. -os.environ["GNUPGHOME"] = "/home/kk/.gnupg/" -# You then must set the user that builds the packages to the owner of the GPG home. -decman.config.makepkg_user = "kk" - -# You can also install packages from anywhere, but then you must include some -# information about the package. The git_url is the url to the PKGBUILD, -# -# Note, decman now has a aur package, I recommend using that instead. -# Also, this example may be out of date -decman.user_packages.append( - UserPackage( - pkgname="decman-git", - version="0.4.1", - provides=["decman"], - dependencies=[ - "python", - "python-requests", - "devtools", - "pacman", - "systemd", - "git", - "less", - ], - make_dependencies=[ - "python-setuptools", - "python-build", - "python-installer", - "python-wheel", - ], - git_url="https://github.com/kiviktnm/decman-pkgbuild.git", - ) -) - -# Managing only packages with decman is not that interesting. -# Decman also has really powerful ways of managing config files, scripts etc. - -# IMPORTANT: Decman will remove files that were created by decman, but are no longer in the decman source. -# Keep your files in version control to avoid losing important files accidentally. - -# Define file content inline. -# Default text file encoding is utf-8 but it can be changed. -decman.files["/etc/vconsole.conf"] = File(content="KEYMAP=us", encoding="utf-8") - -# Include file content from another file, set the file owner and permissions. -# The source_file is relative to the directory where the main decman source.py is located. -# By default, the file group is set to the group of the owner, but it can be overridden with the group argument. -decman.files["/home/kk/.bin/user-script.sh"] = File( - source_file="files/user-script.sh", owner="kk", permissions=0o744 -) - -# Non-text files such as images can also be managed. -decman.files["/home/kk/.background.png"] = File( - source_file="files/i-dont-actually-exist.png", bin_file=True, owner="kk" -) - -# If you need to install multiple files at once, use directories. -# All files from the source directory will be copied recursively to the target. -decman.directories["/home/kk/.config/app/"] = Directory( - source_directory="files/app-config", owner="kk" -) - -# Decman has built in support for managing systemd units as well. -# Decman will enable services declared here, and disable services removed from here. -# If you don't want decman to manage a service, don't add it here. It will ignore all units that -# weren't enabled here. -decman.enabled_systemd_units += ["NetworkManager.service"] - -# You can manage units for users as well. - -# Ensure that previous user unit declarations aren't overwritten and they are initialized. -decman.enabled_systemd_user_units["kk"] = decman.enabled_systemd_user_units.get("kk", []) -# Add user unit. -decman.enabled_systemd_user_units["kk"].append("syncthing.service") - -# Most powerful feature of decman are modules. -# In this file you see how to include your module, but to really see what modules are capable of -# look at the MyModule class. -from my_module import MyModule - -my_own_mod = MyModule() - -# You have full access to python, which makes your configuration very dynamic. -# For example: do something if the computers hostname is arch-1 -if socket.gethostname() == "arch-1": - # Modules make dynamic configuration easy. - # This executes code defined in MyModule which can affect for example what packages are - # installed as a part of this module. - my_own_mod.enable_my_custom_feature(True) -else: - # If you want to abort running decman from your config because something is wrong, raise a UserRaisedError - raise UserRaisedError("Unknown hostname!") - -decman.modules += [my_own_mod] - -# Configuring the behavior of decman is also done here. -# These are the default values. - -# Note: you probably don't want to change these 2 settings and instead you'll want to to use the --debug CLI option. -# Show debug output -decman.config.debug_output = False -# Suppress output of some commands that you probably don't want to see. -decman.config.suppress_command_output = True - -# Make output less verbose. Summaries are still printed. -decman.config.quiet_output = False - -# Decman captures pacman command output, and any line (and adjacent lines) that contains any of -# the following keywords (case-insensetive) will be printed after the pacman command finishes. -# -# REMEMBER: You should still generally pay attention to pacman output -# since these keywords may not catch all cases. -decman.config.pacman_output_keywords = [ - "pacsave", - "pacnew", - # Additional keywords can be: - # "warning", - # "error", - # "note", - # They might cause too many highlights however. -] -# If you don't want to print lines that contain keywords, set this to False -decman.config.print_pacman_output_highlights = True - -# The user which builds aur and user packages. -# decman.config.makepkg_user = "nobody" # This was set in a previous example. Let's not override it. - -# The build directory decman uses for creating a chroot etc. -decman.config.build_dir = "/tmp/decman/build" - -# Built packages are stored here. -decman.config.pkg_cache_dir = "/var/cache/decman" - -# Timeout in seconds for fetching aur package details. -decman.config.aur_rpc_timeout = 30 - -# Enable installing and upgrading foreign packages. -decman.config.enable_fpm = True - -# Number of package files per package kept in the cache -# All built AUR packages and user packages are stored in cache. -decman.config.number_of_packages_stored_in_cache = 3 - - -# Changing the default commands decman uses for things is a bit more complex. -# Create a child class of the decman.config.Commands class and override methods. -# These are the defaults. -class MyCommands(decman.config.Commands): - def list_pkgs(self) -> list[str]: - return ["pacman", "-Qeq", "--color=never"] - - def list_foreign_pkgs_versioned(self) -> list[str]: - return ["pacman", "-Qm", "--color=never"] - - # --color=always is used in many commands since --color=auto results in no color. - # It seems a sensible default for me, since decman already uses color and it can't be disabled. - - def install_pkgs(self, pkgs: list[str]) -> list[str]: - return ["pacman", "-S", "--color=always", "--needed"] + pkgs - - def install_files(self, pkg_files: list[str]) -> list[str]: - return ["pacman", "-U", "--color=always", "--asdeps"] + pkg_files - - def set_as_explicitly_installed(self, pkgs: list[str]) -> list[str]: - return ["pacman", "-D", "--asexplicit"] + pkgs - - def install_deps(self, deps: list[str]) -> list[str]: - return ["pacman", "-S", "--color=always", "--needed", "--asdeps"] + deps - - def is_installable(self, pkg: str) -> list[str]: - return ["pacman", "-Sddp", pkg] - - def upgrade(self) -> list[str]: - return ["pacman", "-Syu", "--color=always"] - - def remove(self, pkgs: list[str]) -> list[str]: - return ["pacman", "-Rs", "--color=always"] + pkgs - - def enable_units(self, units: list[str]) -> list[str]: - return ["systemctl", "enable"] + units - - def disable_units(self, units: list[str]) -> list[str]: - return ["systemctl", "disable"] + units - - def enable_user_units(self, units: list[str], user: str) -> list[str]: - return ["systemctl", "--user", "-M", f"{user}@", "enable"] + units - - def disable_user_units(self, units: list[str], user: str) -> list[str]: - return ["systemctl", "--user", "-M", f"{user}@", "disable"] + units - - def compare_versions(self, installed_version: str, new_version: str) -> list[str]: - return ["vercmp", installed_version, new_version] - - def git_clone(self, repo: str, dest: str) -> list[str]: - return ["git", "clone", repo, dest] - - def git_diff(self, from_commit: str) -> list[str]: - return ["git", "diff", from_commit] - - def git_get_commit_id(self) -> list[str]: - return ["git", "rev-parse", "HEAD"] - - def git_log_commit_ids(self) -> list[str]: - return ["git", "log", "--format=format:%H"] - - def review_file(self, file: str) -> list[str]: - return ["less", file] - - def make_chroot(self, chroot_dir: str, with_pkgs: list[str]) -> list[str]: - return ["mkarchroot", chroot_dir] + with_pkgs - - def install_chroot_packages(self, chroot_dir: str, packages: list[str]): - return [ - "arch-nspawn", - chroot_dir, - "pacman", - "-S", - "--needed", - "--noconfirm", - ] + packages - - def resolve_real_name(self, chroot_dir: str, pkg: str) -> list[str]: - return [ - "arch-nspawn", - chroot_dir, - "pacman", - "-Sddp", - "--print-format=%n", - pkg, - ] - - def remove_chroot_packages(self, chroot_dir: str, packages: list[str]): - return ["arch-nspawn", chroot_dir, "pacman", "-Rsu", "--noconfirm"] + packages - - def make_chroot_pkg( - self, chroot_wd_dir: str, user: str, pkgfiles_to_install: list[str] - ) -> list[str]: - makechrootpkg_cmd = ["makechrootpkg", "-c", "-r", chroot_wd_dir, "-U", user] - - for pkgfile in pkgfiles_to_install: - makechrootpkg_cmd += ["-I", pkgfile] - - return makechrootpkg_cmd - - -# To apply your overrides, set the commands variable. -decman.config.commands = MyCommands() - -# Alternative to the built in AUR support: -# If you don't want to use the built in AUR helper, you can use some pacman wrapper that can run as root, such as pikaur. -# To do this, override commands and disable fpm. - - -class PikaurWrapperCommands(decman.config.Commands): - def list_pkgs(self) -> list[str]: - return ["pikaur", "-Qeq"] - - def install_pkgs(self, pkgs: list[str]) -> list[str]: - return ["pikaur", "-S"] + pkgs - - def upgrade(self) -> list[str]: - return ["pikaur", "-Syu"] - - def remove(self, pkgs: list[str]) -> list[str]: - return ["pikaur", "-Rs"] + pkgs - - # it doesn't matter if all pacman commands aren't overridden since they wont be used when fpm is disabled. - - -# decman.config.enable_fpm = False -# decman.config.commands = PikaurWrapperCommands() - -# Then simply add all AUR packages to decman.packages -# decman.packages += ["pikaur"] diff --git a/src/decman/app.py b/src/decman/app.py index 8f182a1..183c00f 100644 --- a/src/decman/app.py +++ b/src/decman/app.py @@ -23,7 +23,7 @@ def main(): parser = argparse.ArgumentParser( prog="decman", description="Declarative package & configuration manager for Arch Linux", - epilog="See more help at: https://github.com/kiviktnm/decman", + epilog="See the documentation: https://github.com/kiviktnm/decman", ) parser.add_argument("--source", action="store", help="python file containing configuration") @@ -54,7 +54,7 @@ def main(): help="don't print messages with color", ) parser.add_argument( - "--params", nargs="*", type=str, help="additional parameters passed to plugins" + "--params", nargs="*", default=[], type=str, help="additional parameters passed to plugins" ) args = parser.parse_args() diff --git a/src/decman/plugins/flatpak.py b/src/decman/plugins/flatpak.py index eba3612..08690f1 100644 --- a/src/decman/plugins/flatpak.py +++ b/src/decman/plugins/flatpak.py @@ -218,8 +218,6 @@ class FlatpakInterface: cmd, command.run(cmd, user=user, mimic_login=as_user) ) packages = packages_text.strip().split("\n") - # Remove header "Application ID" - packages.pop(0) return set(packages)