decman.modules should be a list

This commit is contained in:
Kivi Kaitaniemi
2025-12-28 05:02:17 +02:00
parent 7e0b49be2f
commit 9b3454f434
18 changed files with 47 additions and 19 deletions
+1 -1
View File
@@ -102,7 +102,7 @@ Then import your module in your main source file.
import decman
from syncthing import Syncthing
decman.modules |= {Syncthing()}
decman.modules += [Syncthing()]
```
Then run decman.
+5 -3
View File
@@ -7,6 +7,8 @@ This contains the documentation for decman. Each plugin has its own documentatio
- [aur](/docs/aur.md)
- [flatpak](/docs/flatpak.md)
Check out [extras](docs/extras.md) for documentation for built-in modules.
## Quick notes
"Decman source" or "source" refers to your system configuration. It is set using the `--source` command line argument with decman.
@@ -210,11 +212,11 @@ A **Module** is the primary unit for grouping related files, directories, packag
Each module is uniquely identified by its `name`.
Remember to add modules to decman.
Remember to add modules to decman. Modules are added to a list to preserve deterministic execution order for hooks.
```py
import decman
decman.modules |= {MyModule()}
decman.modules += [MyModule()]
```
### Basic Structure
@@ -418,7 +420,7 @@ This method only gathers information. It doesn't apply it.
```py
from decman import Store, Module
def process_modules(self, store: Store, modules: set[Module]):
def process_modules(self, store: Store, modules: list[Module]):
...
# Toy example for setting modules as changed
+5
View File
@@ -79,6 +79,11 @@ class MyModule(decman.Module):
If these sets change, this plugin will flag the module as changed. The module's `on_change` method will be executed.
## Keys used in the decman store
- `aur_packages_for_module`
- `custom_packages_for_module`
## Configuration
This module has partially the same configuration with pacman. You'll have to define pacman output keywords and database options again.
+5
View File
@@ -47,6 +47,11 @@ class MyModule(decman.Module):
If packages or user packages change, this plugin will flag the module as changed. The module's `on_change` method will be executed.
## Keys used in the decman store
- `flatpaks_for_module`
- `user_flatpaks_for_module`
## Configuration
It's possible to override the commands this plugin uses. Create your own `FlatpakCommands` class and override methods returning commands. These are the defaults.
+1 -3
View File
@@ -232,8 +232,6 @@ class MyModule(Module):
#### New
`decman.modules` is now a set instead of a list. If you wish to have multiple instances of the same module class, just name them differently. Name needs to be unique accross modules.
Modules no longer have `version`s or `enabled` values. A module is enabled when it gets added to `decman.modules` and disabled when it gets removed from `decman.modules`. Versions are no longer needed because `after_version_change` has been removed and `on_change` has been added. `on_change` is executed automatically after the content of the module changes. `on_disable` will be executed automatically when the module is removed from `decman.modules`. It is no longer a instance method. Instead it must be a self-contained method with no references outside it. Not even imports.
Module methods will get a `Store` instance passed to them as an argument. It can be used to store key-value pairs between decman runs.
@@ -245,7 +243,7 @@ import decman
from decman import Module, Store, prg, sh
from decman.plugins import pacman, aur, systemd, flatpak
decman.modules |= {MyModule()}
decman.modules += [MyModule()]
class MyModule(Module):
def __init__(self):
+4
View File
@@ -42,6 +42,10 @@ class MyModule(decman.Module):
If this set changes, this plugin will flag the module as changed. The module's `on_change` method will be executed.
## Keys used in the decman store
- `packages_for_module`
## Configuration
This plugin has a pacman output highlight function. If pacman output contains some keywords, it will be highlighted. You can disable this feature or set the keywords.
+5
View File
@@ -45,6 +45,11 @@ class MyModule(decman.Module):
If units or user units change, this plugin will flag the module as changed. The module's `on_change` method will be executed.
## Keys used in the decman store
- `systemd_units_for_module`
- `systemd_user_units_for_module`
## Configuration
It's possible to override the commands this plugin uses. Create your own `SystemdCommands` class and override methods returning commands. These are the defaults.
+2 -2
View File
@@ -85,7 +85,7 @@ import decman
from base import BaseModule
decman.pacman.packages |= {"openssh", "qemu-guest-agent", "sudo", "vim"}
decman.modules |= {BaseModule()}
decman.modules += [BaseModule()]
```
This config is already enough to run decman for the first time.
@@ -162,7 +162,7 @@ from kde import KDE
...
decman.modules |= {BaseModule(), KDE()}
decman.modules += [BaseModule(), KDE()]
```
I'll run decman once again. I'll also start SDDM manually, since decman can't autostart it.
+1 -1
View File
@@ -9,7 +9,7 @@ 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]):
def process_modules(self, store: decman.Store, modules: list[decman.Module]):
# Toy example for setting modules as changed
for module in modules:
module._changed = True
+1 -1
View File
@@ -5,7 +5,7 @@ import decman
decman.pacman.packages |= {"openssh", "qemu-guest-agent", "sudo", "vim"}
decman.modules |= {BaseModule(), KDE()}
decman.modules += [BaseModule(), KDE()]
decman.files["/home/arch/.vimrc"] = decman.File(
source_file="./files/vimrc", owner="arch", permissions=0o600
@@ -46,7 +46,7 @@ class Flatpak(plugins.Plugin):
def available(self) -> bool:
return shutil.which("flatpak") is not None
def process_modules(self, store: _store.Store, modules: set[module.Module]):
def process_modules(self, store: _store.Store, modules: list[module.Module]):
# These store keys are used to track changes in modules.
# This way when these change, module can be marked as changed
store.ensure("flatpaks_for_module", {})
@@ -90,7 +90,7 @@ class AUR(plugins.Plugin):
and shutil.which("mkarchroot") is not None
)
def process_modules(self, store: _store.Store, modules: set[module.Module]):
def process_modules(self, store: _store.Store, modules: list[module.Module]):
# This is used to track changes in modules.
store.ensure("aur_packages_for_module", {})
store.ensure("custom_packages_for_module", {})
@@ -58,7 +58,7 @@ class Pacman(plugins.Plugin):
def available(self) -> bool:
return shutil.which("pacman") is not None
def process_modules(self, store: _store.Store, modules: set[module.Module]):
def process_modules(self, store: _store.Store, modules: list[module.Module]):
# This is used to track changes in modules.
store.ensure("packages_for_module", {})
@@ -83,7 +83,7 @@ class Systemd(plugins.Plugin):
def available(self) -> bool:
return shutil.which("systemctl") is not None
def process_modules(self, store: _store.Store, modules: set[module.Module]):
def process_modules(self, store: _store.Store, modules: list[module.Module]):
# These store keys are used to track changes in modules.
# This way when these change, module can be marked as changed
store.ensure("systemd_units_for_module", {})
+1 -1
View File
@@ -63,7 +63,7 @@ __all__ = [
# -----------------------------------------
files: dict[str, File] = {}
directories: dict[str, Directory] = {}
modules: set[Module] = set()
modules: list[Module] = []
execution_order: list[str] = [
"files",
"pacman",
+1 -1
View File
@@ -10,7 +10,7 @@ import decman.core.store as _store
def update_files(
store: _store.Store,
modules: set[module.Module],
modules: list[module.Module],
files: dict[str, fs.File],
directories: dict[str, fs.Directory],
dry_run: bool = False,
+10 -1
View File
@@ -74,5 +74,14 @@ class _SetJSONEncoder(json.JSONEncoder):
def _decode_sets(obj: typing.Any) -> typing.Any:
if isinstance(obj, dict) and obj.get("__type__") == "set" and "items" in obj:
return set(obj["items"])
# decode lists inside sets as tuples
norm = []
for item in obj["items"]:
if isinstance(item, list):
norm.append(tuple(item))
else:
norm.append(item)
return set(norm)
return obj
+1 -1
View File
@@ -40,7 +40,7 @@ class Plugin:
"""
return True
def process_modules(self, store: _store.Store, modules: set[module.Module]):
def process_modules(self, store: _store.Store, modules: list[module.Module]):
"""
Processes a module.
"""