mirror of
https://github.com/kiviktnm/decman.git
synced 2026-09-19 12:08:28 +00:00
Merge pull request #41 from kiviktnm/split-packages
Split plugins to seperate packages
This commit is contained in:
+15
-3
@@ -7,15 +7,27 @@ Before committing ensure all tests pass and format files.
|
||||
Run decman as root to test all changes:
|
||||
|
||||
```sh
|
||||
sudo uv run decman
|
||||
sudo uv run --all-packages decman
|
||||
```
|
||||
|
||||
## Python shell
|
||||
|
||||
Running a python shell with all the packages.
|
||||
|
||||
```sh
|
||||
sudo uv run --all-packages python
|
||||
sudo uv run --exact --package decman python
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Run all unit tests (`-s` disables output capturing):
|
||||
Run all unit tests (`-s` disables output capturing, needed for PTY test):
|
||||
|
||||
```sh
|
||||
uv run pytest -s
|
||||
uv run --package decman pytest -s tests/
|
||||
uv run --package decman-pacman pytest packages/decman-pacman/tests/
|
||||
uv run --package decman-systemd pytest packages/decman-systemd/tests/
|
||||
uv run --package decman-flatpak pytest packages/decman-flatpak/tests/
|
||||
```
|
||||
|
||||
## Formatting
|
||||
|
||||
+4
-4
@@ -391,7 +391,7 @@ Create your own modules by subclassing `Plugin`. Then override the methods docum
|
||||
from decman.plugins import Plugin
|
||||
|
||||
class MyPlugin(Plugin):
|
||||
# Plugins should be singletons.
|
||||
# Plugins should be singletons. (Only one instance exists ever.)
|
||||
# This name should be the same as the key used in decman.plugins dict.
|
||||
NAME = "my-plugin"
|
||||
```
|
||||
@@ -454,10 +454,8 @@ In `pyproject.toml` set:
|
||||
|
||||
```toml
|
||||
[project.entry-points."decman.plugins"]
|
||||
systemd = "decman.plugins.systemd:Systemd"
|
||||
pacman = "decman.plugins.pacman:Pacman"
|
||||
aur = "decman.plugins.aur:AUR"
|
||||
flatpak = "decman.plugins.flatpak:Flatpak"
|
||||
```
|
||||
|
||||
## Useful utilities
|
||||
@@ -474,6 +472,7 @@ decman.prg(
|
||||
["nvim", "--headless", "+Lazy! sync", "+qa"],
|
||||
user = "user",
|
||||
env_overrides = {"EXAMPLE": "value"},
|
||||
pass_environment = True,
|
||||
mimic_login = True,
|
||||
pty = True,
|
||||
check = True,
|
||||
@@ -484,7 +483,8 @@ decman.prg(
|
||||
|
||||
- `cmd: list[str]`: Command to execute.
|
||||
- `user: str`: User name to run the command as. If set, the command is executed after dropping privileges to this user.
|
||||
- `env_overrides dict[str, str]`: Environment variables to override or add for the command execution. These values are merged on top of the current process environment.
|
||||
- `pass_environment: bool`: Copy decman's execution environment variables and pass them to the subprocess.
|
||||
- `env_overrides: dict[str, str]`: Environment variables to override or add for the command execution. These values are merged on top of the current process environment.
|
||||
- `mimic_login: bool`: If mimic_login is True, will set the following environment variables according to the given user's passwd file details. This only happens when user is set.
|
||||
- `HOME`
|
||||
- `USER`
|
||||
|
||||
+3
-23
@@ -6,7 +6,8 @@ I recommend reading decman's new documentation. This document is supposed to be
|
||||
|
||||
This change is mostly architectural and doesn't change decman's behavior, but there are a few exceptions.
|
||||
|
||||
- The pacman plugin will now remove orphan packages
|
||||
- The pacman plugin will now remove orphan packages.
|
||||
- **Packages that are only optionally required by other packages are considered orphans.**
|
||||
- Explicitly installed packages that are required by other explicitly installed packages are no longer uninstalled when removed from the source.
|
||||
- Module's `on_disable` will now be executed when the module is no longer present in `decman.modules`.
|
||||
- It will be executed even when the module is removed completely from the source
|
||||
@@ -596,7 +597,7 @@ class MyCommands(decman.config.Commands):
|
||||
|
||||
#### New
|
||||
|
||||
AUR and pacman commands are a seperate setting, but they share the same subclass, so it's possible to set them in a one place. New commands have also been added but it is better to look at the plugin documentation for those options. Notable changes are: `list_pkgs` have been split to `list_explicit_native` and `list_explicit_foreign`.
|
||||
AUR and pacman commands are a seperate setting, but they share the same subclass, so it's possible to set them in a one place. Many pacman query commands have been deleted since pyalpm is used now. New commands have also been added but it is better to look at the plugin documentation for those options.
|
||||
|
||||
These values are the new defaults.
|
||||
|
||||
@@ -608,18 +609,6 @@ decman.aur.commands = MyAurAndPacmanCommands()
|
||||
decman.pacman.commands = MyAurAndPacmanCommands()
|
||||
|
||||
class MyAurAndPacmanCommands(aur.AurCommands):
|
||||
def list_explicit_native(self) -> list[str]:
|
||||
return ["pacman", "-Qeqn", "--color=never"]
|
||||
|
||||
def list_explicit_foreign(self) -> list[str]:
|
||||
return ["pacman", "-Qeqm", "--color=never"]
|
||||
|
||||
def list_orphans_native(self) -> list[str]:
|
||||
return ["pacman", "-Qndtq", "--color=never"]
|
||||
|
||||
def list_dependants(self, pkg: str) -> list[str]:
|
||||
return ["pacman", "-Rc", "--print", "--print-format", "%n", pkg]
|
||||
|
||||
def install(self, pkgs: set[str]) -> list[str]:
|
||||
return ["pacman", "-S", "--needed"] + list(pkgs)
|
||||
|
||||
@@ -635,15 +624,6 @@ class MyAurAndPacmanCommands(aur.AurCommands):
|
||||
def remove(self, pkgs: set[str]) -> list[str]:
|
||||
return ["pacman", "-Rs"] + list(pkgs)
|
||||
|
||||
def list_orphans_foreign(self) -> list[str]:
|
||||
return ["pacman", "-Qmdtq", "--color=never"]
|
||||
|
||||
def list_foreign_versioned(self) -> list[str]:
|
||||
return ["pacman", "-Qm", "--color=never"]
|
||||
|
||||
def is_installable(self, pkg: str) -> list[str]:
|
||||
return ["pacman", "-Sddp", pkg]
|
||||
|
||||
def install_as_dependencies(self, pkgs: set[str]) -> list[str]:
|
||||
return ["pacman", "-S", "--needed", "--asdeps"] + list(pkgs)
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
[project]
|
||||
name = "decman-flatpak"
|
||||
version = "1.0.0"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = ["decman==1.0.0"]
|
||||
|
||||
[project.entry-points."decman.plugins"]
|
||||
flatpak = "decman.plugins.flatpak:Flatpak"
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=61.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
namespaces = true
|
||||
include = ["decman.plugins*"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
@@ -0,0 +1,25 @@
|
||||
[project]
|
||||
name = "decman-pacman"
|
||||
version = "1.0.0"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"decman==1.0.0",
|
||||
"pyalpm",
|
||||
"requests",
|
||||
]
|
||||
|
||||
[project.entry-points."decman.plugins"]
|
||||
pacman = "decman.plugins.pacman:Pacman"
|
||||
aur = "decman.plugins.aur:AUR"
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=61.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
namespaces = true
|
||||
include = ["decman.plugins*"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
+7
-7
@@ -2,13 +2,6 @@ import os
|
||||
import shutil
|
||||
|
||||
import pyalpm
|
||||
|
||||
import decman.config as config
|
||||
import decman.core.error as errors
|
||||
import decman.core.module as module
|
||||
import decman.core.output as output
|
||||
import decman.core.store as _store
|
||||
import decman.plugins as plugins
|
||||
from decman.plugins.aur.commands import AurCommands, AurPacmanInterface
|
||||
from decman.plugins.aur.error import (
|
||||
AurRPCError,
|
||||
@@ -19,6 +12,13 @@ from decman.plugins.aur.error import (
|
||||
from decman.plugins.aur.fpm import ForeignPackageManager
|
||||
from decman.plugins.aur.package import CustomPackage, PackageSearch
|
||||
|
||||
import decman.config as config
|
||||
import decman.core.error as errors
|
||||
import decman.core.module as module
|
||||
import decman.core.output as output
|
||||
import decman.core.store as _store
|
||||
import decman.plugins as plugins
|
||||
|
||||
# Re-exports
|
||||
__all__ = [
|
||||
"AUR",
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
import decman.plugins.pacman as pacman
|
||||
import pyalpm
|
||||
|
||||
import decman.config as config
|
||||
import decman.core.command as command
|
||||
import decman.plugins.pacman as pacman
|
||||
|
||||
|
||||
class AurCommands(pacman.PacmanCommands):
|
||||
+5
-4
@@ -3,15 +3,16 @@ import shutil
|
||||
import time
|
||||
import typing
|
||||
|
||||
from decman.plugins.aur.commands import AurCommands
|
||||
from decman.plugins.aur.error import ForeignPackageManagerError
|
||||
from decman.plugins.aur.package import AurPacmanInterface, PackageSearch
|
||||
from decman.plugins.aur.resolver import DepGraph, ForeignPackage
|
||||
|
||||
import decman.config as config
|
||||
import decman.core.command as command
|
||||
import decman.core.error as errors
|
||||
import decman.core.output as output
|
||||
import decman.core.store as _store
|
||||
from decman.plugins.aur.commands import AurCommands
|
||||
from decman.plugins.aur.error import ForeignPackageManagerError
|
||||
from decman.plugins.aur.package import AurPacmanInterface, PackageSearch
|
||||
from decman.plugins.aur.resolver import DepGraph, ForeignPackage
|
||||
|
||||
|
||||
def find_latest_cached_package(store: _store.Store, package: str) -> tuple[str, str] | None:
|
||||
+3
-3
@@ -4,15 +4,15 @@ import pathlib
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
import decman.plugins.pacman as pacman_module
|
||||
import requests # type: ignore
|
||||
from decman.plugins.aur.commands import AurCommands, AurPacmanInterface
|
||||
from decman.plugins.aur.error import AurRPCError, PKGBUILDParseError
|
||||
|
||||
import decman.config as config
|
||||
import decman.core.command as command
|
||||
import decman.core.error as errors
|
||||
import decman.core.output as output
|
||||
import decman.plugins.pacman as pacman_module
|
||||
from decman.plugins.aur.commands import AurCommands, AurPacmanInterface
|
||||
from decman.plugins.aur.error import AurRPCError, PKGBUILDParseError
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True, slots=True)
|
||||
-1
@@ -1,7 +1,6 @@
|
||||
import pathlib
|
||||
|
||||
import pytest
|
||||
|
||||
from decman.plugins.aur import package as pkg_mod
|
||||
from decman.plugins.aur.error import AurRPCError, PKGBUILDParseError
|
||||
from decman.plugins.aur.package import (
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
import pytest
|
||||
|
||||
from decman.plugins.aur.error import DependencyCycleError
|
||||
from decman.plugins.aur.resolver import DepGraph, ForeignPackage
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
[project]
|
||||
name = "decman-systemd"
|
||||
version = "1.0.0"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = ["decman==1.0.0"]
|
||||
|
||||
[project.entry-points."decman.plugins"]
|
||||
systemd = "decman.plugins.systemd:Systemd"
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=61.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
namespaces = true
|
||||
include = ["decman.plugins*"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
+21
-10
@@ -7,20 +7,15 @@ authors = [
|
||||
{name = "Kivi Kaitaniemi"}
|
||||
]
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"requests",
|
||||
"pyalpm",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
pacman = ["decman-pacman"]
|
||||
systemd = ["decman-systemd"]
|
||||
flatpak = ["decman-flatpak"]
|
||||
|
||||
[project.scripts]
|
||||
decman = "decman.app:main"
|
||||
|
||||
[project.entry-points."decman.plugins"]
|
||||
systemd = "decman.plugins.systemd:Systemd"
|
||||
pacman = "decman.plugins.pacman:Pacman"
|
||||
aur = "decman.plugins.aur:AUR"
|
||||
flatpak = "decman.plugins.flatpak:Flatpak"
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"ruff>=0.14.9",
|
||||
@@ -31,6 +26,22 @@ dev = [
|
||||
requires = ["setuptools>=61.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.uv.workspace]
|
||||
members = [
|
||||
"packages/decman-pacman",
|
||||
"packages/decman-systemd",
|
||||
"packages/decman-flatpak",
|
||||
]
|
||||
|
||||
[tool.uv.sources]
|
||||
decman = { workspace = true }
|
||||
decman-pacman = { workspace = true }
|
||||
decman-systemd = { workspace = true }
|
||||
decman-flatpak = { workspace = true }
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 100
|
||||
target-version = "py313"
|
||||
|
||||
+35
-25
@@ -8,12 +8,45 @@ from decman.core.module import Module
|
||||
from decman.core.store import Store
|
||||
from decman.plugins import Plugin, available_plugins
|
||||
|
||||
# Plugin types
|
||||
plugins: dict[str, Plugin] = available_plugins()
|
||||
|
||||
# Quick access for default plugins
|
||||
try:
|
||||
from decman.plugins.aur import AUR
|
||||
from decman.plugins.flatpak import Flatpak
|
||||
from decman.plugins.pacman import Pacman
|
||||
|
||||
pacman: None | Pacman = None
|
||||
_pacman = plugins.get("pacman", None)
|
||||
if isinstance(_pacman, Pacman):
|
||||
pacman = _pacman
|
||||
|
||||
aur: None | AUR = None
|
||||
_aur = plugins.get("aur", None)
|
||||
if isinstance(_aur, AUR):
|
||||
aur = _aur
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
|
||||
try:
|
||||
from decman.plugins.flatpak import Flatpak
|
||||
|
||||
flatpak: None | Flatpak = None
|
||||
_flatpak = plugins.get("flatpak", None)
|
||||
if isinstance(_flatpak, Flatpak):
|
||||
flatpak = _flatpak
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
|
||||
try:
|
||||
from decman.plugins.systemd import Systemd
|
||||
|
||||
systemd: None | Systemd = None
|
||||
_systemd = plugins.get("systemd", None)
|
||||
if isinstance(_systemd, Systemd):
|
||||
systemd = _systemd
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
|
||||
__all__ = [
|
||||
"SourceError",
|
||||
"File",
|
||||
@@ -31,7 +64,6 @@ __all__ = [
|
||||
files: dict[str, File] = {}
|
||||
directories: dict[str, Directory] = {}
|
||||
modules: set[Module] = set()
|
||||
plugins: dict[str, Plugin] = available_plugins()
|
||||
execution_order: list[str] = [
|
||||
"files",
|
||||
"pacman",
|
||||
@@ -39,28 +71,6 @@ execution_order: list[str] = [
|
||||
"systemd",
|
||||
]
|
||||
|
||||
# Default plugins get quick access
|
||||
pacman: None | Pacman = None
|
||||
aur: None | AUR = None
|
||||
systemd: None | Systemd = None
|
||||
flatpak: None | Flatpak = None
|
||||
|
||||
_pacman = plugins.get("pacman", None)
|
||||
if isinstance(_pacman, Pacman):
|
||||
pacman = _pacman
|
||||
|
||||
_aur = plugins.get("aur", None)
|
||||
if isinstance(_aur, AUR):
|
||||
aur = _aur
|
||||
|
||||
_systemd = plugins.get("systemd", None)
|
||||
if isinstance(_systemd, Systemd):
|
||||
systemd = _systemd
|
||||
|
||||
_flatpak = plugins.get("flatpak", None)
|
||||
if isinstance(_flatpak, Flatpak):
|
||||
flatpak = _flatpak
|
||||
|
||||
|
||||
def sh(
|
||||
sh_cmd: str,
|
||||
|
||||
@@ -2,6 +2,14 @@ version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.13"
|
||||
|
||||
[manifest]
|
||||
members = [
|
||||
"decman",
|
||||
"decman-flatpak",
|
||||
"decman-pacman",
|
||||
"decman-systemd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2025.11.12"
|
||||
@@ -65,9 +73,16 @@ wheels = [
|
||||
name = "decman"
|
||||
version = "1.0.0"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "pyalpm" },
|
||||
{ name = "requests" },
|
||||
|
||||
[package.optional-dependencies]
|
||||
flatpak = [
|
||||
{ name = "decman-flatpak" },
|
||||
]
|
||||
pacman = [
|
||||
{ name = "decman-pacman" },
|
||||
]
|
||||
systemd = [
|
||||
{ name = "decman-systemd" },
|
||||
]
|
||||
|
||||
[package.dev-dependencies]
|
||||
@@ -78,9 +93,11 @@ dev = [
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "pyalpm" },
|
||||
{ name = "requests" },
|
||||
{ name = "decman-flatpak", marker = "extra == 'flatpak'", editable = "packages/decman-flatpak" },
|
||||
{ name = "decman-pacman", marker = "extra == 'pacman'", editable = "packages/decman-pacman" },
|
||||
{ name = "decman-systemd", marker = "extra == 'systemd'", editable = "packages/decman-systemd" },
|
||||
]
|
||||
provides-extras = ["pacman", "systemd", "flatpak"]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
@@ -88,6 +105,45 @@ dev = [
|
||||
{ name = "ruff", specifier = ">=0.14.9" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "decman-flatpak"
|
||||
version = "1.0.0"
|
||||
source = { editable = "packages/decman-flatpak" }
|
||||
dependencies = [
|
||||
{ name = "decman" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "decman", editable = "." }]
|
||||
|
||||
[[package]]
|
||||
name = "decman-pacman"
|
||||
version = "1.0.0"
|
||||
source = { editable = "packages/decman-pacman" }
|
||||
dependencies = [
|
||||
{ name = "decman" },
|
||||
{ name = "pyalpm" },
|
||||
{ name = "requests" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "decman", editable = "." },
|
||||
{ name = "pyalpm" },
|
||||
{ name = "requests" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "decman-systemd"
|
||||
version = "1.0.0"
|
||||
source = { editable = "packages/decman-systemd" }
|
||||
dependencies = [
|
||||
{ name = "decman" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "decman", editable = "." }]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.11"
|
||||
|
||||
Reference in New Issue
Block a user