Compare commits

..
8 Commits
Author SHA1 Message Date
arcanis 885893ab35 use local devtools configs instead of global ones 2026-08-13 18:15:48 +03:00
arcanis 695424fa16 feat: remove makepkg.conf local configuration, use ahriman own
configuration instead

We used .makepkg.conf solely for two features - MAKEFLAGS and PACKAGER,
which could be actually easily implemented by using environment
variables
2026-08-13 16:39:13 +03:00
arcanis 255ebe117a feat: read includes from list of directories 2026-08-13 16:39:13 +03:00
arcanis a9a12cd247 feat: get rid of sudoers modification during setup command
This commit introduces small shell wrapper, which calls archbuild
mimicing symlinked command. It allows to distribute static sudoers file.

Additionally build_command option has been renamed to devtools_wrapper
in order to allow to keep backward compatibility
2026-08-13 14:26:49 +03:00
arcanis 8dc198aa2b build: tox cleanup 2026-08-13 14:26:49 +03:00
arcanis 1133b75c33 refactor: implement generic optional import mechanisms
this project is actively using optional imports, which leads to
duplicate handling here and there. This commit implements logic in
special method to reduce complexity and simplify tests paths
2026-08-13 14:26:49 +03:00
arcanis 777bedf772 build: handle local imports in pylint check correctly 2026-08-13 14:26:49 +03:00
arcanis cc6ca46342 build: fix mypy type install 2026-08-13 14:26:49 +03:00
8 changed files with 139 additions and 69 deletions
@@ -28,7 +28,7 @@ from urllib.parse import quote_plus as url_encode
from ahriman.application.application import Application from ahriman.application.application import Application
from ahriman.application.handlers.handler import Handler, SubParserAction from ahriman.application.handlers.handler import Handler, SubParserAction
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import MissingArchitectureError from ahriman.core.exceptions import InitializeError, MissingArchitectureError
from ahriman.core.utils import enum_values from ahriman.core.utils import enum_values
from ahriman.models.repository_id import RepositoryId from ahriman.models.repository_id import RepositoryId
from ahriman.models.sign_settings import SignSettings from ahriman.models.sign_settings import SignSettings
@@ -63,24 +63,20 @@ class Setup(Handler):
if args.architecture is None or args.repository is None: if args.architecture is None or args.repository is None:
raise MissingArchitectureError(args.command) raise MissingArchitectureError(args.command)
Setup.configuration_create_ahriman(args, repository_id, configuration) target_directory = Setup.configuration_create_directory(configuration)
Setup.configuration_create_ahriman(args, repository_id, configuration, target_directory)
configuration.reload() configuration.reload()
application = Application(repository_id, configuration, report=report) application = Application(repository_id, configuration, report=report)
paths = application.repository.paths
# basically we create configuration here as root, but it is ok, because those files are only used for reading repository_server = f"file://{paths.repository}" if args.server is None else args.server
repository_server = f"file://{application.repository.paths.repository}" if args.server is None else args.server target_directory = paths.ensure_exists(configuration.getpath("build", "devtools_configs"))
Setup.configuration_create_devtools( Setup.configuration_create_devtools(repository_id, args.from_configuration, target_directory, args.mirror,
repository_id, args.multilib, repository_server)
args.from_configuration,
configuration.repository_paths.ensure_exists(configuration.getpath("build", "devtools_configs")),
args.mirror,
args.multilib,
repository_server,
)
# finish initialization # finish initialization
with application.repository.paths.preserve_owner(): with paths.preserve_owner():
application.repository.repo.init() application.repository.repo.init()
# lazy database sync # lazy database sync
application.repository.pacman.handle # pylint: disable=pointless-statement application.repository.pacman.handle # pylint: disable=pointless-statement
@@ -125,7 +121,7 @@ class Setup(Handler):
@staticmethod @staticmethod
def configuration_create_ahriman(args: argparse.Namespace, repository_id: RepositoryId, def configuration_create_ahriman(args: argparse.Namespace, repository_id: RepositoryId,
root: Configuration) -> None: root: Configuration, target_directory: Path) -> None:
""" """
create service specific configuration create service specific configuration
@@ -133,6 +129,7 @@ class Setup(Handler):
args(argparse.Namespace): command line args args(argparse.Namespace): command line args
repository_id(RepositoryId): repository unique identifier repository_id(RepositoryId): repository unique identifier
root(Configuration): root configuration instance root(Configuration): root configuration instance
target_directory(Path): path to directory where configuration files will be written
""" """
configuration = Configuration() configuration = Configuration()
@@ -170,9 +167,7 @@ class Setup(Handler):
if args.generate_salt: if args.generate_salt:
configuration.set_option("auth", "salt", User.generate_password(20)) configuration.set_option("auth", "salt", User.generate_password(20))
include_path = next(path for path in root.include if os.access(path, os.W_OK)) target = target_directory / f"00-setup-overrides-{repository_id.id}.ini"
(include_path / "00-setup-overrides.ini").unlink(missing_ok=True) # remove old-style configuration
target = include_path / f"00-setup-overrides-{repository_id.id}.ini"
with target.open("w", encoding="utf8") as ahriman_configuration: with target.open("w", encoding="utf8") as ahriman_configuration:
configuration.write(ahriman_configuration) configuration.write(ahriman_configuration)
@@ -227,4 +222,28 @@ class Setup(Handler):
with target.open("w", encoding="utf8") as devtools_configuration: with target.open("w", encoding="utf8") as devtools_configuration:
configuration.write(devtools_configuration) configuration.write(devtools_configuration)
@staticmethod
def configuration_create_directory(root: Configuration) -> Path:
"""
create directory for includes
Args:
root(Configuration): root configuration instance
Returns:
Path: path to first writable directory
Raises:
InitializeError: if no writable directories have been found
"""
for include_path in root.getpathlist("settings", "include"):
try:
directory = root.repository_paths.ensure_exists(include_path)
if os.access(directory, os.W_OK | os.X_OK):
return directory
except OSError:
continue
raise InitializeError("No writable include directory found")
arguments = [_set_service_setup_parser] arguments = [_set_service_setup_parser]
@@ -119,12 +119,9 @@ class Task(LazyLogging):
command = self._legacy_build_command[:] command = self._legacy_build_command[:]
if not command: if not command:
command = self.build_command + [ command = self.build_command + [
"-r", "-r", self.repository_id.name,
self.repository_id.name, "-a", self.repository_id.architecture,
"-a", "-c", str(self.devtools_configs),
self.repository_id.architecture,
"-c",
str(self.devtools_configs),
"--", "--",
] ]
@@ -108,16 +108,6 @@ class Configuration(configparser.RawConfigParser):
_, repository_id = self.check_loaded() _, repository_id = self.check_loaded()
return repository_id.architecture return repository_id.architecture
@property
def include(self) -> list[Path]:
"""
get full path to include directory(ies)
Returns:
list[Path]: path to directory with configuration includes
"""
return self.getpathlist("settings", "include")
@property @property
def logging_path(self) -> Path: def logging_path(self) -> Path:
""" """
@@ -332,14 +322,28 @@ class Configuration(configparser.RawConfigParser):
self.includes = [] # reset state self.includes = [] # reset state
try: try:
for path in self.include: # pylint: disable=not-an-iterable # raw processing to make sure that options are applied correctly
for include in sorted(path.glob("*.ini")): include_directories = shlex.split(self.get("settings", "include", raw=True))
if include == self.logging_path: except (configparser.NoOptionError, configparser.NoSectionError):
continue # we don't want to load logging explicitly return
self.read(include)
self.includes.append(include) for directory in include_directories:
except (FileNotFoundError, configparser.NoOptionError, configparser.NoSectionError): value = self._interpolation.before_get( # type: ignore[attr-defined]
pass self,
"settings",
"include",
directory,
self._unify_values("settings", None), # type: ignore[attr-defined]
)
path = self._convert_path(value)
if not path.is_dir():
continue
for include in sorted(path.glob("*.ini")):
if include == self.logging_path:
continue # we don't want to load logging explicitly
self.read(include)
self.includes.append(include)
def merge_sections(self, repository_id: RepositoryId) -> None: def merge_sections(self, repository_id: RepositoryId) -> None:
""" """
@@ -399,6 +403,7 @@ class Configuration(configparser.RawConfigParser):
# create another instance and copy values from there # create another instance and copy values from there
instance = self.from_path(path, repository_id) instance = self.from_path(path, repository_id)
self.copy_from(instance) self.copy_from(instance)
self.includes = instance.includes
def set_option(self, section: str, option: str, value: str) -> None: def set_option(self, section: str, option: str, value: str) -> None:
""" """
@@ -1,5 +1,6 @@
import argparse import argparse
import multiprocessing import multiprocessing
import os
import pytest import pytest
from pathlib import Path from pathlib import Path
@@ -11,9 +12,8 @@ from urllib.parse import quote_plus as url_encode
from ahriman.application.handlers.setup import Setup from ahriman.application.handlers.setup import Setup
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.database import SQLite from ahriman.core.database import SQLite
from ahriman.core.exceptions import MissingArchitectureError from ahriman.core.exceptions import InitializeError, MissingArchitectureError
from ahriman.core.repository import Repository from ahriman.core.repository import Repository
from ahriman.models.repository_id import RepositoryId
from ahriman.models.repository_paths import RepositoryPaths from ahriman.models.repository_paths import RepositoryPaths
from ahriman.models.sign_settings import SignSettings from ahriman.models.sign_settings import SignSettings
@@ -51,8 +51,11 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
must run command must run command
""" """
args = _default_args(args) args = _default_args(args)
local = Path("local")
mocker.patch("ahriman.core.database.SQLite.load", return_value=database) mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
mkdir_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_directory",
return_value=local)
ahriman_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_ahriman") ahriman_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_ahriman")
devtools_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_devtools") devtools_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_devtools")
init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init") init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init")
@@ -61,9 +64,16 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
_, repository_id = configuration.check_loaded() _, repository_id = configuration.check_loaded()
Setup.run(args, repository_id, configuration, report=False) Setup.run(args, repository_id, configuration, report=False)
owner_guard_mock.assert_called_once_with() owner_guard_mock.assert_called_once_with()
ahriman_configuration_mock.assert_called_once_with(args, repository_id, configuration) mkdir_mock.assert_called_once_with(configuration)
ahriman_configuration_mock.assert_called_once_with(args, repository_id, configuration, local)
devtools_configuration_mock.assert_called_once_with( devtools_configuration_mock.assert_called_once_with(
repository_id, args.from_configuration, args.mirror, args.multilib, f"file://{repository_paths.repository}") repository_id,
args.from_configuration,
configuration.getpath("build", "devtools_configs"),
args.mirror,
args.multilib,
f"file://{repository_paths.repository}",
)
init_mock.assert_called_once_with() init_mock.assert_called_once_with()
@@ -102,11 +112,17 @@ def test_run_with_server(args: argparse.Namespace, configuration: Configuration,
_, repository_id = configuration.check_loaded() _, repository_id = configuration.check_loaded()
Setup.run(args, repository_id, configuration, report=False) Setup.run(args, repository_id, configuration, report=False)
devtools_configuration_mock.assert_called_once_with( devtools_configuration_mock.assert_called_once_with(
repository_id, args.from_configuration, args.mirror, args.multilib, "server") repository_id,
args.from_configuration,
configuration.getpath("build", "devtools_configs"),
args.mirror,
args.multilib,
"server",
)
def test_configuration_create_ahriman(args: argparse.Namespace, configuration: Configuration, def test_configuration_create_ahriman(args: argparse.Namespace, configuration: Configuration, tmp_path: Path,
repository_paths: RepositoryPaths, mocker: MockerFixture) -> None: mocker: MockerFixture) -> None:
""" """
must create configuration for the service must create configuration for the service
""" """
@@ -114,10 +130,9 @@ def test_configuration_create_ahriman(args: argparse.Namespace, configuration: C
mocker.patch("pathlib.Path.open") mocker.patch("pathlib.Path.open")
set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option") set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option")
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
remove_mock = mocker.patch("pathlib.Path.unlink", autospec=True)
_, repository_id = configuration.check_loaded() _, repository_id = configuration.check_loaded()
Setup.configuration_create_ahriman(args, repository_id, configuration) Setup.configuration_create_ahriman(args, repository_id, configuration, tmp_path)
set_option_mock.assert_has_calls([ set_option_mock.assert_has_calls([
MockCall("repository", "name", repository_id.name), MockCall("repository", "name", repository_id.name),
MockCall(Configuration.section_name("build", repository_id.name, repository_id.architecture), MockCall(Configuration.section_name("build", repository_id.name, repository_id.architecture),
@@ -139,15 +154,10 @@ def test_configuration_create_ahriman(args: argparse.Namespace, configuration: C
MockCall("auth", "salt", pytest.helpers.anyvar(str, strict=True)), MockCall("auth", "salt", pytest.helpers.anyvar(str, strict=True)),
]) ])
write_mock.assert_called_once_with(pytest.helpers.anyvar(int)) write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
remove_mock.assert_called_once_with(
next(
path for path in configuration.include) /
"00-setup-overrides.ini",
missing_ok=True)
def test_configuration_create_ahriman_no_multilib(args: argparse.Namespace, configuration: Configuration, def test_configuration_create_ahriman_no_multilib(args: argparse.Namespace, configuration: Configuration,
mocker: MockerFixture) -> None: tmp_path: Path, mocker: MockerFixture) -> None:
""" """
must create configuration for the service without multilib repository must create configuration for the service without multilib repository
""" """
@@ -158,14 +168,14 @@ def test_configuration_create_ahriman_no_multilib(args: argparse.Namespace, conf
set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option") set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option")
_, repository_id = configuration.check_loaded() _, repository_id = configuration.check_loaded()
Setup.configuration_create_ahriman(args, repository_id, configuration) Setup.configuration_create_ahriman(args, repository_id, configuration, tmp_path)
set_option_mock.assert_has_calls([ set_option_mock.assert_has_calls([
MockCall(Configuration.section_name("alpm", repository_id.name, repository_id.architecture), "mirror", MockCall(Configuration.section_name("alpm", repository_id.name, repository_id.architecture), "mirror",
args.mirror), args.mirror),
]) # non-strict check called intentionally ]) # non-strict check called intentionally
def test_configuration_create_devtools(args: argparse.Namespace, configuration: Configuration, def test_configuration_create_devtools(args: argparse.Namespace, configuration: Configuration, tmp_path: Path,
mocker: MockerFixture) -> None: mocker: MockerFixture) -> None:
""" """
must create configuration for the devtools must create configuration for the devtools
@@ -177,12 +187,12 @@ def test_configuration_create_devtools(args: argparse.Namespace, configuration:
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
_, repository_id = configuration.check_loaded() _, repository_id = configuration.check_loaded()
Setup.configuration_create_devtools(repository_id, args.from_configuration, None, args.multilib, "server") Setup.configuration_create_devtools(repository_id, args.from_configuration, tmp_path, None, args.multilib, "server")
add_section_mock.assert_has_calls([MockCall("multilib"), MockCall(repository_id.name)]) add_section_mock.assert_has_calls([MockCall("multilib"), MockCall(repository_id.name)])
write_mock.assert_called_once_with(pytest.helpers.anyvar(int)) write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
def test_configuration_create_devtools_mirror(args: argparse.Namespace, configuration: Configuration, def test_configuration_create_devtools_mirror(args: argparse.Namespace, configuration: Configuration, tmp_path: Path,
mocker: MockerFixture) -> None: mocker: MockerFixture) -> None:
""" """
must create configuration for the devtools with mirror set explicitly must create configuration for the devtools with mirror set explicitly
@@ -202,14 +212,21 @@ def test_configuration_create_devtools_mirror(args: argparse.Namespace, configur
set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option") set_option_mock = mocker.patch("ahriman.core.configuration.Configuration.set_option")
_, repository_id = configuration.check_loaded() _, repository_id = configuration.check_loaded()
Setup.configuration_create_devtools(repository_id, args.from_configuration, args.mirror, args.multilib, "server") Setup.configuration_create_devtools(
repository_id,
args.from_configuration,
tmp_path,
args.mirror,
args.multilib,
"server",
)
get_mock.assert_has_calls([MockCall("core", "Include", fallback=None), MockCall("extra", "Include", fallback=None)]) get_mock.assert_has_calls([MockCall("core", "Include", fallback=None), MockCall("extra", "Include", fallback=None)])
remove_option_mock.assert_called_once_with("core", "Include") remove_option_mock.assert_called_once_with("core", "Include")
set_option_mock.assert_has_calls([MockCall("core", "Server", args.mirror)]) # non-strict check called intentionally set_option_mock.assert_has_calls([MockCall("core", "Server", args.mirror)]) # non-strict check called intentionally
def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, configuration: Configuration, def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, configuration: Configuration,
mocker: MockerFixture) -> None: tmp_path: Path, mocker: MockerFixture) -> None:
""" """
must create configuration for the devtools without multilib must create configuration for the devtools without multilib
""" """
@@ -219,10 +236,33 @@ def test_configuration_create_devtools_no_multilib(args: argparse.Namespace, con
write_mock = mocker.patch("ahriman.core.configuration.Configuration.write") write_mock = mocker.patch("ahriman.core.configuration.Configuration.write")
_, repository_id = configuration.check_loaded() _, repository_id = configuration.check_loaded()
Setup.configuration_create_devtools(repository_id, args.from_configuration, args.mirror, False, "server") Setup.configuration_create_devtools(repository_id, args.from_configuration, tmp_path, args.mirror, False, "server")
write_mock.assert_called_once_with(pytest.helpers.anyvar(int)) write_mock.assert_called_once_with(pytest.helpers.anyvar(int))
def test_configuration_create_directory(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must create writable directory for includes
"""
configuration.set_option("settings", "include", f"/path1 /path2 /path3")
mkdir_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.ensure_exists",
side_effect=[OSError, "/path2", "/path3"])
access_mock = mocker.patch("os.access", side_effect=[False, True])
assert Setup.configuration_create_directory(configuration) == "/path3"
mkdir_mock.assert_has_calls([MockCall(Path("/path1")), MockCall(Path("/path2")), MockCall(Path("/path3"))])
access_mock.assert_has_calls([MockCall("/path2", os.W_OK | os.X_OK), MockCall("/path3", os.W_OK | os.X_OK)])
def test_configuration_create_directory_no_writable(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must raise InitializeError if no writable directories found
"""
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.ensure_exists", side_effect=OSError)
with pytest.raises(InitializeError):
Setup.configuration_create_directory(configuration)
def test_disallow_multi_architecture_run() -> None: def test_disallow_multi_architecture_run() -> None:
""" """
must not allow multi architecture run must not allow multi architecture run
@@ -63,7 +63,7 @@ def test_run_default(args: argparse.Namespace, configuration: Configuration) ->
default = Configuration.from_path(Configuration.SYSTEM_CONFIGURATION_PATH, repository_id) default = Configuration.from_path(Configuration.SYSTEM_CONFIGURATION_PATH, repository_id)
# copy autogenerated values # copy autogenerated values
for section, key in (("repository", "root"),): for section, key in (("repository", "root"), ("build", "devtools_configs")):
value = configuration.get(section, key) value = configuration.get(section, key)
default.set_option(section, key, value) default.set_option(section, key, value)
@@ -54,7 +54,9 @@ def test_build(task_ahriman: Task, mocker: MockerFixture) -> None:
assert task_ahriman.build(local) == [task_ahriman.package.base] assert task_ahriman.build(local) == [task_ahriman.package.base]
check_output_mock.assert_called_once_with( check_output_mock.assert_called_once_with(
"ahriman-archbuild", "ahriman-archbuild",
"-r", task_ahriman.repository_id.name, "-a", task_ahriman.repository_id.architecture, "-r", task_ahriman.repository_id.name,
"-a", task_ahriman.repository_id.architecture,
"-c", str(task_ahriman.devtools_configs),
"--", "-r", str(task_ahriman.paths.chroot), "--", "-r", str(task_ahriman.paths.chroot),
"--", "-D", str(task_ahriman.paths.archive), "--", "-D", str(task_ahriman.paths.archive),
"--", "--skippgpcheck", "--", "--skippgpcheck",
@@ -81,7 +83,9 @@ def test_build_environment(task_ahriman: Task, mocker: MockerFixture) -> None:
task_ahriman.build(local, **environment, empty=None) task_ahriman.build(local, **environment, empty=None)
check_output_mock.assert_called_once_with( check_output_mock.assert_called_once_with(
"ahriman-archbuild", "ahriman-archbuild",
"-r", task_ahriman.repository_id.name, "-a", task_ahriman.repository_id.architecture, "-r", task_ahriman.repository_id.name,
"-a", task_ahriman.repository_id.architecture,
"-c", str(task_ahriman.devtools_configs),
"--", "-r", str(task_ahriman.paths.chroot), "--", "-r", str(task_ahriman.paths.chroot),
"--", "-D", str(task_ahriman.paths.archive), "--", "-D", str(task_ahriman.paths.archive),
"--", "--skippgpcheck", "--", "--skippgpcheck",
@@ -106,7 +110,9 @@ def test_build_makeflags(task_ahriman: Task, mocker: MockerFixture) -> None:
task_ahriman.build(local) task_ahriman.build(local)
check_output_mock.assert_called_once_with( check_output_mock.assert_called_once_with(
"ahriman-archbuild", "ahriman-archbuild",
"-r", task_ahriman.repository_id.name, "-a", task_ahriman.repository_id.architecture, "-r", task_ahriman.repository_id.name,
"-a", task_ahriman.repository_id.architecture,
"-c", str(task_ahriman.devtools_configs),
"--", "-r", str(task_ahriman.paths.chroot), "--", "-r", str(task_ahriman.paths.chroot),
"--", "-D", str(task_ahriman.paths.archive), "--", "-D", str(task_ahriman.paths.archive),
"--", "--skippgpcheck", "--", "--skippgpcheck",
@@ -130,7 +136,9 @@ def test_build_dry_run(task_ahriman: Task, mocker: MockerFixture) -> None:
task_ahriman.build(local, dry_run=True) task_ahriman.build(local, dry_run=True)
check_output_mock.assert_called_once_with( check_output_mock.assert_called_once_with(
"ahriman-archbuild", "ahriman-archbuild",
"-r", task_ahriman.repository_id.name, "-a", task_ahriman.repository_id.architecture, "-r", task_ahriman.repository_id.name,
"-a", task_ahriman.repository_id.architecture,
"-c", str(task_ahriman.devtools_configs),
"--", "-r", str(task_ahriman.paths.chroot), "--", "-r", str(task_ahriman.paths.chroot),
"--", "-D", str(task_ahriman.paths.archive), "--", "-D", str(task_ahriman.paths.archive),
"--", "--skippgpcheck", "--", "--skippgpcheck",
+1 -1
View File
@@ -48,7 +48,7 @@ if [ -n "$AHRIMAN_UNIX_SOCKET" ]; then
fi fi
[ -n "$AHRIMAN_PRESETUP_COMMAND" ] && eval "$AHRIMAN_PRESETUP_COMMAND" [ -n "$AHRIMAN_PRESETUP_COMMAND" ] && eval "$AHRIMAN_PRESETUP_COMMAND"
ahriman "${AHRIMAN_DEFAULT_ARGS[@]}" service-setup "${AHRIMAN_SETUP_ARGS[@]}" sudo -E -u "$AHRIMAN_USER" -- ahriman "${AHRIMAN_DEFAULT_ARGS[@]}" service-setup "${AHRIMAN_SETUP_ARGS[@]}"
[ -n "$AHRIMAN_POSTSETUP_COMMAND" ] && eval "$AHRIMAN_POSTSETUP_COMMAND" [ -n "$AHRIMAN_POSTSETUP_COMMAND" ] && eval "$AHRIMAN_POSTSETUP_COMMAND"
# validate configuration if set # validate configuration if set
+1
View File
@@ -120,6 +120,7 @@ dependency_groups = [
] ]
deps = [ deps = [
{ replace = "ref", of = ["project", "extras"], extend = true }, { replace = "ref", of = ["project", "extras"], extend = true },
"pip",
] ]
pip_pre = true pip_pre = true
set_env.CFLAGS = "-Wno-unterminated-string-initialization" set_env.CFLAGS = "-Wno-unterminated-string-initialization"