mirror of
https://github.com/arcan1s/ahriman.git
synced 2026-02-03 20:09:48 +00:00
Compare commits
1 Commits
release/2.
...
939a94d889
| Author | SHA1 | Date | |
|---|---|---|---|
| 939a94d889 |
@@ -215,7 +215,6 @@ Again, the most checks can be performed by `tox` command, though some additional
|
||||
* It is allowed to change web API to add new fields or remove optional ones. However, in case of model changes, new API version must be introduced.
|
||||
* On the other hand, it is allowed to change method signatures, however, it is recommended to add new parameters as optional if possible. Deprecated API can be dropped during major release.
|
||||
* Enumerations (`Enum` classes) are allowed and recommended. However, it is recommended to use `StrEnum` class if there are from/to string conversions and `IntEnum` otherwise.
|
||||
* `Generator` return type is not allowed. Generator functions must return generic `Iterator` object. Documentation should be described as `Yields`, however, because of pylint checks. Unfortunately, `Iterable` return type is not available for generators also, because of specific `contextlib.contextmanager` case.
|
||||
|
||||
### Other checks
|
||||
|
||||
|
||||
127
docs/_static/architecture.dot
vendored
127
docs/_static/architecture.dot
vendored
@@ -184,7 +184,7 @@ digraph G {
|
||||
ahriman_core_upload_upload [fillcolor="blue",fontcolor="white",label="ahriman\.\ncore\.\nupload\.\nupload",shape="box"];
|
||||
ahriman_core_upload_upload_trigger [fillcolor="blue",fontcolor="white",label="ahriman\.\ncore\.\nupload\.\nupload_trigger",shape="box"];
|
||||
ahriman_core_util [fillcolor="#ac6349",fontcolor="#ffffff",label="ahriman\.\ncore\.\nutil"];
|
||||
ahriman_core_utils [fillcolor="#ef4306",fontcolor="#ffffff",label="ahriman\.\ncore\.\nutils"];
|
||||
ahriman_core_utils [fillcolor="#db3d05",fontcolor="#ffffff",label="ahriman\.\ncore\.\nutils"];
|
||||
ahriman_models [fillcolor="#f94d10",fontcolor="#ffffff",label="ahriman.models"];
|
||||
ahriman_models_action [fillcolor="#e75622",fontcolor="#ffffff",label="ahriman\.\nmodels\.\naction"];
|
||||
ahriman_models_aur_package [fillcolor="#db3d05",fontcolor="#ffffff",label="ahriman\.\nmodels\.\naur_package"];
|
||||
@@ -215,7 +215,7 @@ digraph G {
|
||||
ahriman_models_remote_source [fillcolor="#d13a05",fontcolor="#ffffff",label="ahriman\.\nmodels\.\nremote_source"];
|
||||
ahriman_models_report_settings [fillcolor="#c26747",fontcolor="#ffffff",label="ahriman\.\nmodels\.\nreport_settings"];
|
||||
ahriman_models_repository_id [fillcolor="#f94d10",fontcolor="#ffffff",label="ahriman\.\nmodels\.\nrepository_id"];
|
||||
ahriman_models_repository_paths [fillcolor="#c73705",fontcolor="#ffffff",label="ahriman\.\nmodels\.\nrepository_paths"];
|
||||
ahriman_models_repository_paths [fillcolor="#d13a05",fontcolor="#ffffff",label="ahriman\.\nmodels\.\nrepository_paths"];
|
||||
ahriman_models_repository_stats [fillcolor="#ca4516",fontcolor="#ffffff",label="ahriman\.\nmodels\.\nrepository_stats"];
|
||||
ahriman_models_result [fillcolor="#ef4306",fontcolor="#ffffff",label="ahriman\.\nmodels\.\nresult"];
|
||||
ahriman_models_scan_paths [fillcolor="#ce613b",fontcolor="#ffffff",label="ahriman\.\nmodels\.\nscan_paths"];
|
||||
@@ -952,57 +952,56 @@ digraph G {
|
||||
ahriman_core_upload_upload -> ahriman_core_upload_s3 [fillcolor="blue",weight="3"];
|
||||
ahriman_core_upload_upload -> ahriman_core_upload_upload_trigger [fillcolor="blue",weight="3"];
|
||||
ahriman_core_upload_upload_trigger -> ahriman_core_upload [fillcolor="blue",weight="3"];
|
||||
ahriman_core_utils -> ahriman_application_ahriman [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_application_application_application_packages [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_add [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_daemon [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_rebuild [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_setup [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_statistics [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_status [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_status_update [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_update [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_users [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_lock [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_core_alpm_pacman [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_alpm_repo [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_auth_pam [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_build_tools_package_archive [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_build_tools_sources [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_build_tools_task [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_formatters_aur_printer [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_formatters_repository_stats_printer [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_formatters_update_printer [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_gitremote_remote_pull [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_report_email [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_report_jinja_template [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_repository_executor [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_repository_package_info [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_sign_gpg [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_support_pkgbuild_pkgbuild_generator [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_tree [fillcolor="#ef4306",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_upload_github [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_upload_rsync [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_upload_s3 [fillcolor="#ef4306",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_util [fillcolor="#ef4306",weight="2"];
|
||||
ahriman_core_utils -> ahriman_models_aur_package [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_build_status [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_changes [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_counters [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_dependencies [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_event [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_filesystem_package [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_internal_status [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_package [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_package_description [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_package_source [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_pkgbuild_patch [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_remote_source [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_repository_paths [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_repository_stats [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_worker [fillcolor="#ef4306",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_web_views_api_swagger [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_web_views_v1_packages_logs [fillcolor="#ef4306",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_ahriman [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_application_application_application_packages [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_add [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_daemon [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_rebuild [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_setup [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_statistics [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_status [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_status_update [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_update [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_handlers_users [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_application_lock [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_core_alpm_pacman [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_alpm_repo [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_auth_pam [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_build_tools_package_archive [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_build_tools_sources [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_build_tools_task [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_formatters_aur_printer [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_formatters_repository_stats_printer [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_formatters_update_printer [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_gitremote_remote_pull [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_report_email [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_report_jinja_template [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_repository_executor [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_repository_package_info [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_sign_gpg [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_support_pkgbuild_pkgbuild_generator [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_tree [fillcolor="#db3d05",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_upload_github [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_upload_rsync [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_upload_s3 [fillcolor="#db3d05",minlen="2",weight="2"];
|
||||
ahriman_core_utils -> ahriman_core_util [fillcolor="#db3d05",weight="2"];
|
||||
ahriman_core_utils -> ahriman_models_aur_package [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_build_status [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_changes [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_counters [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_dependencies [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_event [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_filesystem_package [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_internal_status [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_package [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_package_description [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_package_source [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_pkgbuild_patch [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_remote_source [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_repository_stats [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_models_worker [fillcolor="#db3d05",minlen="2"];
|
||||
ahriman_core_utils -> ahriman_web_views_api_swagger [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_core_utils -> ahriman_web_views_v1_packages_logs [fillcolor="#db3d05",minlen="3"];
|
||||
ahriman_models -> ahriman_application_ahriman [fillcolor="#f94d10",minlen="2"];
|
||||
ahriman_models -> ahriman_application_application_application [fillcolor="#f94d10",minlen="3"];
|
||||
ahriman_models -> ahriman_application_application_application_packages [fillcolor="#f94d10",minlen="3"];
|
||||
@@ -1137,6 +1136,7 @@ digraph G {
|
||||
ahriman_models -> ahriman_core_upload_s3 [fillcolor="#f94d10",minlen="3"];
|
||||
ahriman_models -> ahriman_core_upload_upload [fillcolor="#f94d10",minlen="3"];
|
||||
ahriman_models -> ahriman_core_upload_upload_trigger [fillcolor="#f94d10",minlen="3"];
|
||||
ahriman_models -> ahriman_core_utils [fillcolor="#f94d10",minlen="2"];
|
||||
ahriman_models -> ahriman_web_apispec_decorators [fillcolor="#f94d10",minlen="3"];
|
||||
ahriman_models -> ahriman_web_keys [fillcolor="#f94d10",minlen="2"];
|
||||
ahriman_models -> ahriman_web_middlewares_auth_handler [fillcolor="#f94d10",minlen="3"];
|
||||
@@ -1475,16 +1475,17 @@ digraph G {
|
||||
ahriman_models_repository_id -> ahriman_web_keys [fillcolor="#f94d10",minlen="2"];
|
||||
ahriman_models_repository_id -> ahriman_web_views_base [fillcolor="#f94d10",minlen="3"];
|
||||
ahriman_models_repository_id -> ahriman_web_web [fillcolor="#f94d10",minlen="2"];
|
||||
ahriman_models_repository_paths -> ahriman_application_handlers_handler [fillcolor="#c73705",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_application_handlers_setup [fillcolor="#c73705",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_application_handlers_tree_migrate [fillcolor="#c73705",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_core_alpm_repo [fillcolor="#c73705",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_core_build_tools_sources [fillcolor="#c73705",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_core_build_tools_task [fillcolor="#c73705",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_core_configuration_configuration [fillcolor="#c73705",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_core_repository_repository_properties [fillcolor="#c73705",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_models_package_source [fillcolor="#c73705",weight="2"];
|
||||
ahriman_models_repository_paths -> ahriman_web_views_v1_service_upload [fillcolor="#c73705",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_application_handlers_handler [fillcolor="#d13a05",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_application_handlers_setup [fillcolor="#d13a05",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_application_handlers_tree_migrate [fillcolor="#d13a05",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_core_alpm_repo [fillcolor="#d13a05",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_core_build_tools_sources [fillcolor="#d13a05",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_core_build_tools_task [fillcolor="#d13a05",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_core_configuration_configuration [fillcolor="#d13a05",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_core_repository_repository_properties [fillcolor="#d13a05",minlen="3"];
|
||||
ahriman_models_repository_paths -> ahriman_core_utils [fillcolor="#d13a05",minlen="2"];
|
||||
ahriman_models_repository_paths -> ahriman_models_package_source [fillcolor="#d13a05",weight="2"];
|
||||
ahriman_models_repository_paths -> ahriman_web_views_v1_service_upload [fillcolor="#d13a05",minlen="3"];
|
||||
ahriman_models_repository_stats -> ahriman_core_formatters_repository_stats_printer [fillcolor="#ca4516",minlen="3"];
|
||||
ahriman_models_repository_stats -> ahriman_core_status_client [fillcolor="#ca4516",minlen="3"];
|
||||
ahriman_models_repository_stats -> ahriman_models_internal_status [fillcolor="#ca4516",weight="2"];
|
||||
|
||||
@@ -140,6 +140,14 @@ ahriman.web.schemas.logs\_schema module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.web.schemas.logs\_search\_schema module
|
||||
-----------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.web.schemas.logs_search_schema
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.web.schemas.oauth2\_schema module
|
||||
-----------------------------------------
|
||||
|
||||
|
||||
@@ -138,8 +138,6 @@ Build related configuration. Group name can refer to architecture, e.g. ``build:
|
||||
|
||||
Base repository settings.
|
||||
|
||||
* ``architecture`` - repository architecture, string. This field is read-only and generated automatically from run options if possible.
|
||||
* ``name`` - repository name, string. This field is read-only and generated automatically from run options if possible.
|
||||
* ``root`` - root path for application, string, required.
|
||||
|
||||
``sign:*`` groups
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
pkgbase='ahriman'
|
||||
pkgname=('ahriman' 'ahriman-core' 'ahriman-triggers' 'ahriman-web')
|
||||
pkgver=2.19.4
|
||||
pkgver=2.19.0
|
||||
pkgrel=1
|
||||
pkgdesc="ArcH linux ReposItory MANager"
|
||||
arch=('any')
|
||||
|
||||
@@ -101,6 +101,8 @@
|
||||
<button id="package-info-update-button" type="submit" class="btn btn-success" onclick="packageInfoUpdate()" data-bs-dismiss="modal"><i class="bi bi-play"></i><span class="d-none d-sm-inline"> update</span></button>
|
||||
<button id="package-info-remove-button" type="submit" class="btn btn-danger" onclick="packageInfoRemove()" data-bs-dismiss="modal"><i class="bi bi-trash"></i><span class="d-none d-sm-inline"> remove</span></button>
|
||||
{% endif %}
|
||||
<input id="package-info-autoreload-button" type="checkbox" class="btn-check" autocomplete="off" onclick="togglePackageInfoAutoReload()" checked>
|
||||
<label for="package-info-autoreload-button" class="btn btn-outline-secondary" title="toggle auto reload"><i class="bi bi-clock"></i></label>
|
||||
<button type="button" class="btn btn-secondary" onclick="showPackageInfo()"><i class="bi bi-arrow-clockwise"></i><span class="d-none d-sm-inline"> reload</span></button>
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal"><i class="bi bi-x"></i><span class="d-none d-sm-inline"> close</span></button>
|
||||
</div>
|
||||
@@ -140,6 +142,9 @@
|
||||
|
||||
const packageInfoRefreshInput = document.getElementById("package-info-refresh-input");
|
||||
|
||||
const packageInfoAutoReloadButton = document.getElementById("package-info-autoreload-button");
|
||||
let packageInfoAutoReloadTask = null;
|
||||
|
||||
function clearChart() {
|
||||
packageInfoEventsUpdateChartCanvas.hidden = true;
|
||||
if (packageInfoEventsUpdateChart) {
|
||||
@@ -148,6 +153,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
function convertLogs(data, filter) {
|
||||
return data
|
||||
.filter((filter || Boolean))
|
||||
.map(log_record => `[${new Date(1000 * log_record.created).toISOString()}] ${log_record.message}`)
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
async function copyChanges() {
|
||||
const changes = packageInfoChangesInput.textContent;
|
||||
await copyToClipboard(changes, packageInfoChangesCopyButton);
|
||||
@@ -319,15 +331,19 @@
|
||||
const link = document.createElement("a");
|
||||
link.classList.add("dropdown-item");
|
||||
|
||||
link.dataset.version = version.version;
|
||||
link.dataset.processId = version.process_id;
|
||||
link.dataset.logs = convertLogs(data, log_record => log_record.version === version.version && log_record.process_id === version.process_id);
|
||||
|
||||
link.textContent = new Date(1000 * version.created).toISOStringShort();
|
||||
link.href = "#";
|
||||
link.onclick = _ => {
|
||||
const logs = data
|
||||
.filter(log_record => log_record.version === version.version && log_record.process_id === version.process_id)
|
||||
.map(log_record => `[${new Date(1000 * log_record.created).toISOString()}] ${log_record.message}`);
|
||||
|
||||
packageInfoLogsInput.textContent = logs.join("\n");
|
||||
// check if we are at the bottom of the code block
|
||||
const isScrolledToBottom = packageInfoLogsInput.scrollTop + packageInfoLogsInput.clientHeight >= packageInfoLogsInput.scrollHeight;
|
||||
packageInfoLogsInput.textContent = link.dataset.logs;
|
||||
highlight(packageInfoLogsInput);
|
||||
if (isScrolledToBottom)
|
||||
packageInfoLogsInput.scrollTop = packageInfoLogsInput.scrollHeight; // scroll to the new end
|
||||
|
||||
Array.from(packageInfoLogsVersions.children).forEach(el => el.classList.remove("active"));
|
||||
link.classList.add("active");
|
||||
@@ -403,23 +419,46 @@
|
||||
}
|
||||
|
||||
function packageInfoRemove() {
|
||||
const packageBase = packageInfoModal.package;
|
||||
const packageBase = packageInfoModal.dataset.package;
|
||||
packagesRemove([packageBase]);
|
||||
}
|
||||
|
||||
function packageInfoUpdate() {
|
||||
const packageBase = packageInfoModal.package;
|
||||
const packageBase = packageInfoModal.dataset.package;
|
||||
packagesAdd(packageBase, [], repository, {refresh: packageInfoRefreshInput.checked});
|
||||
}
|
||||
|
||||
function reloadActiveLogs(packageBase) {
|
||||
const activeLogSelector = packageInfoLogsVersions.querySelector(".active");
|
||||
|
||||
if (activeLogSelector) {
|
||||
makeRequest(
|
||||
`/api/v2/packages/${packageBase}/logs`,
|
||||
{
|
||||
query: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
version: activeLogSelector.dataset.version,
|
||||
process_id: activeLogSelector.dataset.processId,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
data => {
|
||||
activeLogSelector.dataset.logs = convertLogs(data);
|
||||
activeLogSelector.click();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPackageInfo(packageBase) {
|
||||
const isPackageBaseSet = packageBase !== undefined;
|
||||
if (isPackageBaseSet) {
|
||||
// set package base as currently used
|
||||
packageInfoModal.package = packageBase;
|
||||
packageInfoModal.dataset.package = packageBase;
|
||||
} else {
|
||||
// read package base from the current window attribute
|
||||
packageBase = packageInfoModal.package;
|
||||
packageBase = packageInfoModal.dataset.package;
|
||||
}
|
||||
|
||||
const onFailure = error => {
|
||||
@@ -438,6 +477,21 @@
|
||||
|
||||
if (isPackageBaseSet) {
|
||||
bootstrap.Modal.getOrCreateInstance(packageInfoModal).show();
|
||||
togglePackageInfoAutoReload();
|
||||
}
|
||||
}
|
||||
|
||||
function togglePackageInfoAutoReload() {
|
||||
clearInterval(packageInfoAutoReloadTask);
|
||||
if (packageInfoAutoReloadButton.checked) {
|
||||
packageInfoAutoReloadTask = setInterval(_ => {
|
||||
if (!hasActiveSelection()) {
|
||||
const packageBase = packageInfoModal.dataset.package;
|
||||
// we only poll status and logs here
|
||||
loadPackage(packageBase);
|
||||
reloadActiveLogs(packageBase);
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,6 +522,9 @@
|
||||
packageInfoChangesInput.textContent = "";
|
||||
packageInfoEventsTable.bootstrapTable("load", []);
|
||||
clearChart();
|
||||
|
||||
clearInterval(packageInfoAutoReloadTask);
|
||||
packageInfoAutoReloadTask = null; // not really required (?) but lets clear everything
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -58,6 +58,10 @@
|
||||
return value.includes(dataList[index].toLowerCase());
|
||||
}
|
||||
|
||||
function hasActiveSelection() {
|
||||
return !document.getSelection().isCollapsed; // not sure if it is a valid way, but I guess so
|
||||
}
|
||||
|
||||
function headerClass(status) {
|
||||
if (status === "pending") return ["bg-warning"];
|
||||
if (status === "building") return ["bg-warning"];
|
||||
|
||||
@@ -674,7 +674,6 @@ _shtab_ahriman() {
|
||||
|
||||
if [[ "$current_action_nargs" != "*" ]] && \
|
||||
[[ "$current_action_nargs" != "+" ]] && \
|
||||
[[ "$current_action_nargs" != "?" ]] && \
|
||||
[[ "$current_action_nargs" != *"..." ]] && \
|
||||
(( $word_index + 1 - $current_action_args_start_index - $pos_only >= \
|
||||
$current_action_nargs )); then
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.TH AHRIMAN "1" "2026\-02\-02" "ahriman 2.19.4" "ArcH linux ReposItory MANager"
|
||||
.TH AHRIMAN "1" "2025\-06\-29" "ahriman 2.19.0" "ArcH linux ReposItory MANager"
|
||||
.SH NAME
|
||||
ahriman \- ArcH linux ReposItory MANager
|
||||
.SH SYNOPSIS
|
||||
.B [0m[1;35mahriman[0m
|
||||
[[32m-h[0m] [[32m-a [33mARCHITECTURE[0m] [[32m-c [33mCONFIGURATION[0m] [[36m--force[0m] [[32m-l [33mLOCK[0m] [[36m--log-handler [33m{console,syslog,journald}[0m] [[32m-q[0m] [[36m--report | --no-report[0m] [[32m-r [33mREPOSITORY[0m] [[36m--unsafe[0m] [[32m-V[0m] [[36m--wait-timeout [33mWAIT_TIMEOUT[0m] [32m{add,aur-search,check,clean,config,config-validate,copy,daemon,help,help-commands-unsafe,help-updates,help-version,init,key-import,package-add,package-changes,package-changes-remove,package-copy,package-remove,package-status,package-status-remove,package-status-update,package-update,patch-add,patch-list,patch-remove,patch-set-add,rebuild,remove,remove-unknown,repo-backup,repo-check,repo-clean,repo-config,repo-config-validate,repo-create-keyring,repo-create-mirrorlist,repo-daemon,repo-init,repo-rebuild,repo-remove-unknown,repo-report,repo-restore,repo-setup,repo-sign,repo-statistics,repo-status-update,repo-sync,repo-tree,repo-triggers,repo-update,report,run,search,service-clean,service-config,service-config-validate,service-key-import,service-repositories,service-run,service-setup,service-shell,service-tree-migrate,setup,shell,sign,status,status-update,sync,update,user-add,user-list,user-remove,version,web} ...[0m
|
||||
.B ahriman
|
||||
[-h] [-a ARCHITECTURE] [-c CONFIGURATION] [--force] [-l LOCK] [--log-handler {console,syslog,journald}] [-q] [--report | --no-report] [-r REPOSITORY] [--unsafe] [-V] [--wait-timeout WAIT_TIMEOUT] {add,aur-search,check,clean,config,config-validate,copy,daemon,help,help-commands-unsafe,help-updates,help-version,init,key-import,package-add,package-changes,package-changes-remove,package-copy,package-remove,package-status,package-status-remove,package-status-update,package-update,patch-add,patch-list,patch-remove,patch-set-add,rebuild,remove,remove-unknown,repo-backup,repo-check,repo-clean,repo-config,repo-config-validate,repo-create-keyring,repo-create-mirrorlist,repo-daemon,repo-init,repo-rebuild,repo-remove-unknown,repo-report,repo-restore,repo-setup,repo-sign,repo-statistics,repo-status-update,repo-sync,repo-tree,repo-triggers,repo-update,report,run,search,service-clean,service-config,service-config-validate,service-key-import,service-repositories,service-run,service-setup,service-shell,service-tree-migrate,setup,shell,sign,status,status-update,sync,update,user-add,user-list,user-remove,version,web} ...
|
||||
.SH DESCRIPTION
|
||||
ArcH linux ReposItory MANager
|
||||
|
||||
@@ -195,9 +195,9 @@ remove user
|
||||
web server
|
||||
|
||||
.SH COMMAND \fI\,'ahriman aur\-search'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman aur\-search[0m [[32m\-h[0m] [[32m\-e[0m] [[36m\-\-info | \-\-no\-info[0m]
|
||||
[[36m\-\-sort\-by [33m{description,first_submitted,id,last_modified,maintainer,name,num_votes,out_of_date,package_base,package_base_id,popularity,repository,submitter,url,url_path,version}[0m]
|
||||
[32msearch [search ...][0m
|
||||
usage: ahriman aur\-search [\-h] [\-e] [\-\-info | \-\-no\-info]
|
||||
[\-\-sort\-by {description,first_submitted,id,last_modified,maintainer,name,num_votes,out_of_date,package_base,package_base_id,popularity,repository,submitter,url,url_path,version}]
|
||||
search [search ...]
|
||||
|
||||
search for package in AUR using API
|
||||
|
||||
@@ -220,7 +220,7 @@ sort field by this field. In case if two packages have the same value of the spe
|
||||
by name
|
||||
|
||||
.SH COMMAND \fI\,'ahriman help'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman help[0m [[32m\-h[0m] [32m[subcommand][0m
|
||||
usage: ahriman help [\-h] [subcommand]
|
||||
|
||||
show help message for application or command and exit
|
||||
|
||||
@@ -229,7 +229,7 @@ show help message for application or command and exit
|
||||
show help message for specific command
|
||||
|
||||
.SH COMMAND \fI\,'ahriman help\-commands\-unsafe'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman help\-commands\-unsafe[0m [[32m\-h[0m] [32m[subcommand ...][0m
|
||||
usage: ahriman help\-commands\-unsafe [\-h] [subcommand ...]
|
||||
|
||||
list unsafe commands as defined in default args
|
||||
|
||||
@@ -239,7 +239,7 @@ instead of showing commands, just test command line for unsafe subcommand and re
|
||||
otherwise
|
||||
|
||||
.SH COMMAND \fI\,'ahriman help\-updates'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman help\-updates[0m [[32m\-h[0m] [[32m\-e[0m]
|
||||
usage: ahriman help\-updates [\-h] [\-e]
|
||||
|
||||
request AUR for current version and compare with current service version
|
||||
|
||||
@@ -249,15 +249,15 @@ request AUR for current version and compare with current service version
|
||||
return non\-zero exit code if updates available
|
||||
|
||||
.SH COMMAND \fI\,'ahriman help\-version'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman help\-version[0m [[32m\-h[0m]
|
||||
usage: ahriman help\-version [\-h]
|
||||
|
||||
print application and its dependencies versions
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-add'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman package\-add[0m [[32m\-h[0m] [[36m\-\-changes | \-\-no\-changes[0m] [[36m\-\-dependencies | \-\-no\-dependencies[0m] [[32m\-e[0m]
|
||||
[[36m\-\-increment | \-\-no\-increment[0m] [[32m\-n[0m] [[32m\-y[0m]
|
||||
[[32m\-s [33m{auto,archive,aur,directory,local,remote,repository}[0m] [[32m\-u [33mUSERNAME[0m] [[32m\-v [33mVARIABLE[0m]
|
||||
[32mpackage [package ...][0m
|
||||
usage: ahriman package\-add [\-h] [\-\-changes | \-\-no\-changes] [\-\-dependencies | \-\-no\-dependencies] [\-e]
|
||||
[\-\-increment | \-\-no\-increment] [\-n] [\-y]
|
||||
[\-s {auto,archive,aur,directory,local,remote,repository}] [\-u USERNAME] [\-v VARIABLE]
|
||||
package [package ...]
|
||||
|
||||
add existing or new package to the build queue
|
||||
|
||||
@@ -303,7 +303,7 @@ build as user
|
||||
apply specified makepkg variables to the next build
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-changes'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman package\-changes[0m [[32m\-h[0m] [[32m\-e[0m] [32mpackage[0m
|
||||
usage: ahriman package\-changes [\-h] [\-e] package
|
||||
|
||||
retrieve package changes stored in database
|
||||
|
||||
@@ -317,7 +317,7 @@ package base
|
||||
return non\-zero exit status if result is empty
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-changes\-remove'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman package\-changes\-remove[0m [[32m\-h[0m] [32mpackage[0m
|
||||
usage: ahriman package\-changes\-remove [\-h] package
|
||||
|
||||
remove the package changes stored remotely
|
||||
|
||||
@@ -326,7 +326,7 @@ remove the package changes stored remotely
|
||||
package base
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-copy'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman package\-copy[0m [[32m\-h[0m] [[32m\-e[0m] [[36m\-\-remove[0m] [32msource[0m [32mpackage [package ...][0m
|
||||
usage: ahriman package\-copy [\-h] [\-e] [\-\-remove] source package [package ...]
|
||||
|
||||
copy package and its metadata from another repository
|
||||
|
||||
@@ -348,7 +348,7 @@ return non\-zero exit status if result is empty
|
||||
remove package from the source repository after
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-remove'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman package\-remove[0m [[32m\-h[0m] [32mpackage [package ...][0m
|
||||
usage: ahriman package\-remove [\-h] package [package ...]
|
||||
|
||||
remove package from the repository
|
||||
|
||||
@@ -357,8 +357,8 @@ remove package from the repository
|
||||
package name or base
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-status'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman package\-status[0m [[32m\-h[0m] [[36m\-\-ahriman[0m] [[32m\-e[0m] [[36m\-\-info | \-\-no\-info[0m] [[32m\-s [33m{unknown,pending,building,failed,success}[0m]
|
||||
[32m[package ...][0m
|
||||
usage: ahriman package\-status [\-h] [\-\-ahriman] [\-e] [\-\-info | \-\-no\-info] [\-s {unknown,pending,building,failed,success}]
|
||||
[package ...]
|
||||
|
||||
request status of the package
|
||||
|
||||
@@ -384,7 +384,7 @@ show additional package information
|
||||
filter packages by status
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-status\-remove'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman package\-status\-remove[0m [[32m\-h[0m] [32mpackage [package ...][0m
|
||||
usage: ahriman package\-status\-remove [\-h] package [package ...]
|
||||
|
||||
remove the package from the status page
|
||||
|
||||
@@ -393,7 +393,7 @@ remove the package from the status page
|
||||
remove specified packages from status page
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-status\-update'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman package\-status\-update[0m [[32m\-h[0m] [[32m\-s [33m{unknown,pending,building,failed,success}[0m] [32m[package ...][0m
|
||||
usage: ahriman package\-status\-update [\-h] [\-s {unknown,pending,building,failed,success}] [package ...]
|
||||
|
||||
update package status on the status page
|
||||
|
||||
@@ -407,7 +407,7 @@ set status for specified packages. If no packages supplied, service status will
|
||||
new package build status
|
||||
|
||||
.SH COMMAND \fI\,'ahriman patch\-add'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman patch\-add[0m [[32m\-h[0m] [32mpackage[0m [32mvariable[0m [32m[patch][0m
|
||||
usage: ahriman patch\-add [\-h] package variable [patch]
|
||||
|
||||
create or update patched PKGBUILD function or variable
|
||||
|
||||
@@ -424,7 +424,7 @@ PKGBUILD variable or function name. If variable is a function, it must end with
|
||||
path to file which contains function or variable value. If not set, the value will be read from stdin
|
||||
|
||||
.SH COMMAND \fI\,'ahriman patch\-list'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman patch\-list[0m [[32m\-h[0m] [[32m\-e[0m] [[32m\-v [33mVARIABLE[0m] [32mpackage[0m
|
||||
usage: ahriman patch\-list [\-h] [\-e] [\-v VARIABLE] package
|
||||
|
||||
list available patches for the package
|
||||
|
||||
@@ -442,7 +442,7 @@ return non\-zero exit status if result is empty
|
||||
if set, show only patches for specified PKGBUILD variables
|
||||
|
||||
.SH COMMAND \fI\,'ahriman patch\-remove'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman patch\-remove[0m [[32m\-h[0m] [[32m\-v [33mVARIABLE[0m] [32mpackage[0m
|
||||
usage: ahriman patch\-remove [\-h] [\-v VARIABLE] package
|
||||
|
||||
remove patches for the package
|
||||
|
||||
@@ -457,7 +457,7 @@ should be used for single\-function patches in case if you wold like to remove o
|
||||
if not set, it will remove all patches related to the package
|
||||
|
||||
.SH COMMAND \fI\,'ahriman patch\-set\-add'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman patch\-set\-add[0m [[32m\-h[0m] [[32m\-t [33mTRACK[0m] [32mpackage[0m
|
||||
usage: ahriman patch\-set\-add [\-h] [\-t TRACK] package
|
||||
|
||||
create or update source patches
|
||||
|
||||
@@ -471,7 +471,7 @@ path to directory with changed files for patch addition/update
|
||||
files which has to be tracked
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-backup'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-backup[0m [[32m\-h[0m] [32mpath[0m
|
||||
usage: ahriman repo\-backup [\-h] path
|
||||
|
||||
backup repository settings and database
|
||||
|
||||
@@ -480,9 +480,9 @@ backup repository settings and database
|
||||
path of the output archive
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-check'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-check[0m [[32m\-h[0m] [[36m\-\-changes | \-\-no\-changes[0m] [[36m\-\-check\-files | \-\-no\-check\-files[0m] [[32m\-e[0m] [[36m\-\-vcs | \-\-no\-vcs[0m]
|
||||
[[32m\-y[0m]
|
||||
[32m[package ...][0m
|
||||
usage: ahriman repo\-check [\-h] [\-\-changes | \-\-no\-changes] [\-\-check\-files | \-\-no\-check\-files] [\-e] [\-\-vcs | \-\-no\-vcs]
|
||||
[\-y]
|
||||
[package ...]
|
||||
|
||||
check for packages updates. Same as repo\-update \-\-dry\-run \-\-no\-manual
|
||||
|
||||
@@ -512,20 +512,20 @@ fetch actual version of VCS packages
|
||||
download fresh package databases from the mirror before actions, \-yy to force refresh even if up to date
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-create\-keyring'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-create\-keyring[0m [[32m\-h[0m]
|
||||
usage: ahriman repo\-create\-keyring [\-h]
|
||||
|
||||
create package which contains list of trusted keys as set by configuration. Note, that this action will only create package, the package itself has to be built manually
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-create\-mirrorlist'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-create\-mirrorlist[0m [[32m\-h[0m]
|
||||
usage: ahriman repo\-create\-mirrorlist [\-h]
|
||||
|
||||
create package which contains list of available mirrors as set by configuration. Note, that this action will only create package, the package itself has to be built manually
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-daemon'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-daemon[0m [[32m\-h[0m] [[32m\-i [33mINTERVAL[0m] [[36m\-\-aur | \-\-no\-aur[0m] [[36m\-\-changes | \-\-no\-changes[0m]
|
||||
[[36m\-\-check\-files | \-\-no\-check\-files[0m] [[36m\-\-dependencies | \-\-no\-dependencies[0m] [[36m\-\-dry\-run[0m]
|
||||
[[36m\-\-increment | \-\-no\-increment[0m] [[36m\-\-local | \-\-no\-local[0m] [[36m\-\-manual | \-\-no\-manual[0m]
|
||||
[[36m\-\-partitions | \-\-no\-partitions[0m] [[32m\-u [33mUSERNAME[0m] [[36m\-\-vcs | \-\-no\-vcs[0m] [[32m\-y[0m]
|
||||
usage: ahriman repo\-daemon [\-h] [\-i INTERVAL] [\-\-aur | \-\-no\-aur] [\-\-changes | \-\-no\-changes]
|
||||
[\-\-check\-files | \-\-no\-check\-files] [\-\-dependencies | \-\-no\-dependencies] [\-\-dry\-run]
|
||||
[\-\-increment | \-\-no\-increment] [\-\-local | \-\-no\-local] [\-\-manual | \-\-no\-manual]
|
||||
[\-\-partitions | \-\-no\-partitions] [\-u USERNAME] [\-\-vcs | \-\-no\-vcs] [\-y]
|
||||
|
||||
start process which periodically will run update process
|
||||
|
||||
@@ -583,8 +583,8 @@ fetch actual version of VCS packages
|
||||
download fresh package databases from the mirror before actions, \-yy to force refresh even if up to date
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-rebuild'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-rebuild[0m [[32m\-h[0m] [[36m\-\-depends\-on [33mDEPENDS_ON[0m] [[36m\-\-dry\-run[0m] [[36m\-\-from\-database[0m] [[36m\-\-increment | \-\-no\-increment[0m]
|
||||
[[32m\-e[0m] [[32m\-s [33m{unknown,pending,building,failed,success}[0m] [[32m\-u [33mUSERNAME[0m]
|
||||
usage: ahriman repo\-rebuild [\-h] [\-\-depends\-on DEPENDS_ON] [\-\-dry\-run] [\-\-from\-database] [\-\-increment | \-\-no\-increment]
|
||||
[\-e] [\-s {unknown,pending,building,failed,success}] [\-u USERNAME]
|
||||
|
||||
force rebuild whole repository
|
||||
|
||||
@@ -620,7 +620,7 @@ filter packages by status. Requires \-\-from\-database to be set
|
||||
build as user
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-remove\-unknown'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-remove\-unknown[0m [[32m\-h[0m] [[36m\-\-dry\-run[0m]
|
||||
usage: ahriman repo\-remove\-unknown [\-h] [\-\-dry\-run]
|
||||
|
||||
remove packages which are missing in AUR and do not have local PKGBUILDs
|
||||
|
||||
@@ -630,12 +630,12 @@ remove packages which are missing in AUR and do not have local PKGBUILDs
|
||||
just perform check for packages without removal
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-report'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-report[0m [[32m\-h[0m]
|
||||
usage: ahriman repo\-report [\-h]
|
||||
|
||||
generate repository report according to current settings
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-restore'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-restore[0m [[32m\-h[0m] [[32m\-o [33mOUTPUT[0m] [32mpath[0m
|
||||
usage: ahriman repo\-restore [\-h] [\-o OUTPUT] path
|
||||
|
||||
restore settings and database
|
||||
|
||||
@@ -649,7 +649,7 @@ path of the input archive
|
||||
root path of the extracted files
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-sign'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-sign[0m [[32m\-h[0m] [32m[package ...][0m
|
||||
usage: ahriman repo\-sign [\-h] [package ...]
|
||||
|
||||
(re\-)sign packages and repository database according to current settings
|
||||
|
||||
@@ -658,10 +658,10 @@ root path of the extracted files
|
||||
sign only specified packages
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-statistics'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-statistics[0m [[32m\-h[0m] [[36m\-\-chart [33mCHART[0m]
|
||||
[[32m\-e [33m{package\-outdated,package\-removed,package\-update\-failed,package\-updated}[0m]
|
||||
[[36m\-\-from\-date [33mFROM_DATE[0m] [[36m\-\-limit [33mLIMIT[0m] [[36m\-\-offset [33mOFFSET[0m] [[36m\-\-to\-date [33mTO_DATE[0m]
|
||||
[32m[package][0m
|
||||
usage: ahriman repo\-statistics [\-h] [\-\-chart CHART]
|
||||
[\-e {package\-outdated,package\-removed,package\-update\-failed,package\-updated}]
|
||||
[\-\-from\-date FROM_DATE] [\-\-limit LIMIT] [\-\-offset OFFSET] [\-\-to\-date TO_DATE]
|
||||
[package]
|
||||
|
||||
fetch repository statistics
|
||||
|
||||
@@ -695,7 +695,7 @@ skip specified amount of events
|
||||
only fetch events which are older than the date
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-status\-update'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-status\-update[0m [[32m\-h[0m] [[32m\-s [33m{unknown,pending,building,failed,success}[0m]
|
||||
usage: ahriman repo\-status\-update [\-h] [\-s {unknown,pending,building,failed,success}]
|
||||
|
||||
update repository status on the status page
|
||||
|
||||
@@ -705,12 +705,12 @@ update repository status on the status page
|
||||
new status
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-sync'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-sync[0m [[32m\-h[0m]
|
||||
usage: ahriman repo\-sync [\-h]
|
||||
|
||||
sync repository files to remote server according to current settings
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-tree'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-tree[0m [[32m\-h[0m] [[32m\-p [33mPARTITIONS[0m]
|
||||
usage: ahriman repo\-tree [\-h] [\-p PARTITIONS]
|
||||
|
||||
dump repository tree based on packages dependencies
|
||||
|
||||
@@ -720,7 +720,7 @@ dump repository tree based on packages dependencies
|
||||
also divide packages by independent partitions
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-triggers'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-triggers[0m [[32m\-h[0m] [32m[trigger ...][0m
|
||||
usage: ahriman repo\-triggers [\-h] [trigger ...]
|
||||
|
||||
run triggers on empty build result as configured by settings
|
||||
|
||||
@@ -729,10 +729,10 @@ run triggers on empty build result as configured by settings
|
||||
instead of running all triggers as set by configuration, just process specified ones in order of mention
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-update'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman repo\-update[0m [[32m\-h[0m] [[36m\-\-aur | \-\-no\-aur[0m] [[36m\-\-changes | \-\-no\-changes[0m] [[36m\-\-check\-files | \-\-no\-check\-files[0m]
|
||||
[[36m\-\-dependencies | \-\-no\-dependencies[0m] [[36m\-\-dry\-run[0m] [[32m\-e[0m] [[36m\-\-increment | \-\-no\-increment[0m]
|
||||
[[36m\-\-local | \-\-no\-local[0m] [[36m\-\-manual | \-\-no\-manual[0m] [[32m\-u [33mUSERNAME[0m] [[36m\-\-vcs | \-\-no\-vcs[0m] [[32m\-y[0m]
|
||||
[32m[package ...][0m
|
||||
usage: ahriman repo\-update [\-h] [\-\-aur | \-\-no\-aur] [\-\-changes | \-\-no\-changes] [\-\-check\-files | \-\-no\-check\-files]
|
||||
[\-\-dependencies | \-\-no\-dependencies] [\-\-dry\-run] [\-e] [\-\-increment | \-\-no\-increment]
|
||||
[\-\-local | \-\-no\-local] [\-\-manual | \-\-no\-manual] [\-u USERNAME] [\-\-vcs | \-\-no\-vcs] [\-y]
|
||||
[package ...]
|
||||
|
||||
check for packages updates and run build process if requested
|
||||
|
||||
@@ -790,8 +790,8 @@ fetch actual version of VCS packages
|
||||
download fresh package databases from the mirror before actions, \-yy to force refresh even if up to date
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-clean'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman service\-clean[0m [[32m\-h[0m] [[36m\-\-cache | \-\-no\-cache[0m] [[36m\-\-chroot | \-\-no\-chroot[0m] [[36m\-\-manual | \-\-no\-manual[0m]
|
||||
[[36m\-\-packages | \-\-no\-packages[0m] [[36m\-\-pacman | \-\-no\-pacman[0m]
|
||||
usage: ahriman service\-clean [\-h] [\-\-cache | \-\-no\-cache] [\-\-chroot | \-\-no\-chroot] [\-\-manual | \-\-no\-manual]
|
||||
[\-\-packages | \-\-no\-packages] [\-\-pacman | \-\-no\-pacman]
|
||||
|
||||
remove local caches
|
||||
|
||||
@@ -817,7 +817,7 @@ clear directory with built packages
|
||||
clear directory with pacman local database cache
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-config'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman service\-config[0m [[32m\-h[0m] [[36m\-\-info | \-\-no\-info[0m] [[36m\-\-secure | \-\-no\-secure[0m] [32m[section][0m [32m[key][0m
|
||||
usage: ahriman service\-config [\-h] [\-\-info | \-\-no\-info] [\-\-secure | \-\-no\-secure] [section] [key]
|
||||
|
||||
dump configuration for the specified architecture
|
||||
|
||||
@@ -839,7 +839,7 @@ show additional information, e.g. configuration files
|
||||
hide passwords and secrets from output
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-config\-validate'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman service\-config\-validate[0m [[32m\-h[0m] [[32m\-e[0m]
|
||||
usage: ahriman service\-config\-validate [\-h] [\-e]
|
||||
|
||||
validate configuration and print found errors
|
||||
|
||||
@@ -849,7 +849,7 @@ validate configuration and print found errors
|
||||
return non\-zero exit status if configuration is invalid
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-key\-import'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman service\-key\-import[0m [[32m\-h[0m] [[36m\-\-key\-server [33mKEY_SERVER[0m] [32mkey[0m
|
||||
usage: ahriman service\-key\-import [\-h] [\-\-key\-server KEY_SERVER] key
|
||||
|
||||
import PGP key from public sources to the repository user
|
||||
|
||||
@@ -863,7 +863,7 @@ PGP key to import from public server
|
||||
key server for key import
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-repositories'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman service\-repositories[0m [[32m\-h[0m] [[36m\-\-id\-only | \-\-no\-id\-only[0m]
|
||||
usage: ahriman service\-repositories [\-h] [\-\-id\-only | \-\-no\-id\-only]
|
||||
|
||||
list all available repositories
|
||||
|
||||
@@ -873,7 +873,7 @@ list all available repositories
|
||||
show machine readable identifier instead
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-run'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman service\-run[0m [[32m\-h[0m] [32mcommand [command ...][0m
|
||||
usage: ahriman service\-run [\-h] command [command ...]
|
||||
|
||||
run multiple commands on success run of the previous command
|
||||
|
||||
@@ -882,11 +882,11 @@ run multiple commands on success run of the previous command
|
||||
command to be run (quoted) without ``ahriman``
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-setup'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman service\-setup[0m [[32m\-h[0m] [[36m\-\-build\-as\-user [33mBUILD_AS_USER[0m] [[36m\-\-from\-configuration [33mFROM_CONFIGURATION[0m]
|
||||
[[36m\-\-generate\-salt | \-\-no\-generate\-salt[0m] [[36m\-\-makeflags\-jobs | \-\-no\-makeflags\-jobs[0m]
|
||||
[[36m\-\-mirror [33mMIRROR[0m] [[36m\-\-multilib | \-\-no\-multilib[0m] [36m\-\-packager [33mPACKAGER[0m [[36m\-\-server [33mSERVER[0m]
|
||||
[[36m\-\-sign\-key [33mSIGN_KEY[0m] [[36m\-\-sign\-target [33m{disabled,packages,repository}[0m] [[36m\-\-web\-port [33mWEB_PORT[0m]
|
||||
[[36m\-\-web\-unix\-socket [33mWEB_UNIX_SOCKET[0m]
|
||||
usage: ahriman service\-setup [\-h] [\-\-build\-as\-user BUILD_AS_USER] [\-\-from\-configuration FROM_CONFIGURATION]
|
||||
[\-\-generate\-salt | \-\-no\-generate\-salt] [\-\-makeflags\-jobs | \-\-no\-makeflags\-jobs]
|
||||
[\-\-mirror MIRROR] [\-\-multilib | \-\-no\-multilib] \-\-packager PACKAGER [\-\-server SERVER]
|
||||
[\-\-sign\-key SIGN_KEY] [\-\-sign\-target {disabled,packages,repository}] [\-\-web\-port WEB_PORT]
|
||||
[\-\-web\-unix\-socket WEB_UNIX_SOCKET]
|
||||
|
||||
create initial service configuration, requires root
|
||||
|
||||
@@ -940,7 +940,7 @@ port of the web service
|
||||
path to unix socket used for interprocess communications
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-shell'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman service\-shell[0m [[32m\-h[0m] [[32m\-o [33mOUTPUT[0m] [32m[code][0m
|
||||
usage: ahriman service\-shell [\-h] [\-o OUTPUT] [code]
|
||||
|
||||
drop into python shell
|
||||
|
||||
@@ -954,13 +954,13 @@ instead of dropping into shell, just execute the specified code
|
||||
output commands and result to the file
|
||||
|
||||
.SH COMMAND \fI\,'ahriman service\-tree\-migrate'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman service\-tree\-migrate[0m [[32m\-h[0m]
|
||||
usage: ahriman service\-tree\-migrate [\-h]
|
||||
|
||||
migrate repository tree between versions
|
||||
|
||||
.SH COMMAND \fI\,'ahriman user\-add'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman user\-add[0m [[32m\-h[0m] [[36m\-\-key [33mKEY[0m] [[36m\-\-packager [33mPACKAGER[0m] [[32m\-p [33mPASSWORD[0m] [[32m\-R [33m{unauthorized,read,reporter,full}[0m]
|
||||
[32musername[0m
|
||||
usage: ahriman user\-add [\-h] [\-\-key KEY] [\-\-packager PACKAGER] [\-p PASSWORD] [\-R {unauthorized,read,reporter,full}]
|
||||
username
|
||||
|
||||
update user for web services with the given password and role. In case if password was not entered it will be asked interactively
|
||||
|
||||
@@ -987,7 +987,7 @@ authorization type.
|
||||
user access level
|
||||
|
||||
.SH COMMAND \fI\,'ahriman user\-list'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman user\-list[0m [[32m\-h[0m] [[32m\-e[0m] [[32m\-R [33m{unauthorized,read,reporter,full}[0m] [32m[username][0m
|
||||
usage: ahriman user\-list [\-h] [\-e] [\-R {unauthorized,read,reporter,full}] [username]
|
||||
|
||||
list users from the user mapping and their roles
|
||||
|
||||
@@ -1005,7 +1005,7 @@ return non\-zero exit status if result is empty
|
||||
filter users by role
|
||||
|
||||
.SH COMMAND \fI\,'ahriman user\-remove'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman user\-remove[0m [[32m\-h[0m] [32musername[0m
|
||||
usage: ahriman user\-remove [\-h] username
|
||||
|
||||
remove user from the user mapping and update the configuration
|
||||
|
||||
@@ -1014,7 +1014,7 @@ remove user from the user mapping and update the configuration
|
||||
username for web service
|
||||
|
||||
.SH COMMAND \fI\,'ahriman web'\/\fR
|
||||
[1;34musage: [0m[1;35mahriman web[0m [[32m\-h[0m]
|
||||
usage: ahriman web [\-h]
|
||||
|
||||
start web server
|
||||
|
||||
|
||||
@@ -99,9 +99,6 @@ _shtab_ahriman_options=(
|
||||
"--wait-timeout[wait for lock to be free. Negative value will lead to immediate application run even if there is lock file. In case of zero value, the application will wait infinitely (default\: -1)]:wait_timeout:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_defaults_added=0
|
||||
|
||||
_shtab_ahriman_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available (default\: True)]:changes:"
|
||||
@@ -116,9 +113,6 @@ _shtab_ahriman_add_options=(
|
||||
"(*):package source (base name, path to local files, remote URL):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_add_defaults_added=0
|
||||
|
||||
_shtab_ahriman_aur_search_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
@@ -127,9 +121,6 @@ _shtab_ahriman_aur_search_options=(
|
||||
"(*):search terms, can be specified multiple times, the result will match all terms:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_aur_search_defaults_added=0
|
||||
|
||||
_shtab_ahriman_check_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available (default\: True)]:changes:"
|
||||
@@ -140,9 +131,6 @@ _shtab_ahriman_check_options=(
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_check_defaults_added=0
|
||||
|
||||
_shtab_ahriman_clean_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--cache,--no-cache}"[clear directory with package caches (default\: False)]:cache:"
|
||||
@@ -152,9 +140,6 @@ _shtab_ahriman_clean_options=(
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: False)]:pacman:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_clean_defaults_added=0
|
||||
|
||||
_shtab_ahriman_config_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--info,--no-info}"[show additional information, e.g. configuration files (default\: True)]:info:"
|
||||
@@ -163,17 +148,11 @@ _shtab_ahriman_config_options=(
|
||||
":filter settings by key (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_config_defaults_added=0
|
||||
|
||||
_shtab_ahriman_config_validate_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid (default\: False)]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_config_validate_defaults_added=0
|
||||
|
||||
_shtab_ahriman_copy_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
@@ -182,9 +161,6 @@ _shtab_ahriman_copy_options=(
|
||||
"(*):package base:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_copy_defaults_added=0
|
||||
|
||||
_shtab_ahriman_daemon_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-i,--interval}"[interval between runs in seconds (default\: 43200)]:interval:"
|
||||
@@ -202,40 +178,25 @@ _shtab_ahriman_daemon_options=(
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_daemon_defaults_added=0
|
||||
|
||||
_shtab_ahriman_help_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
":show help message for specific command (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_help_defaults_added=0
|
||||
|
||||
_shtab_ahriman_help_commands_unsafe_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*)::instead of showing commands, just test command line for unsafe subcommand and return 0 in case if command is safe and 1 otherwise (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_help_commands_unsafe_defaults_added=0
|
||||
|
||||
_shtab_ahriman_help_updates_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit code if updates available (default\: False)]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_help_updates_defaults_added=0
|
||||
|
||||
_shtab_ahriman_help_version_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_help_version_defaults_added=0
|
||||
|
||||
_shtab_ahriman_init_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
@@ -252,18 +213,12 @@ _shtab_ahriman_init_options=(
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_init_defaults_added=0
|
||||
|
||||
_shtab_ahriman_key_import_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--key-server[key server for key import (default\: keyserver.ubuntu.com)]:key_server:"
|
||||
":PGP key to import from public server:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_key_import_defaults_added=0
|
||||
|
||||
_shtab_ahriman_package_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available (default\: True)]:changes:"
|
||||
@@ -278,26 +233,17 @@ _shtab_ahriman_package_add_options=(
|
||||
"(*):package source (base name, path to local files, remote URL):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_package_add_defaults_added=0
|
||||
|
||||
_shtab_ahriman_package_changes_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
":package base:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_package_changes_defaults_added=0
|
||||
|
||||
_shtab_ahriman_package_changes_remove_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
":package base:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_package_changes_remove_defaults_added=0
|
||||
|
||||
_shtab_ahriman_package_copy_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
@@ -306,17 +252,11 @@ _shtab_ahriman_package_copy_options=(
|
||||
"(*):package base:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_package_copy_defaults_added=0
|
||||
|
||||
_shtab_ahriman_package_remove_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*):package name or base:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_package_remove_defaults_added=0
|
||||
|
||||
_shtab_ahriman_package_status_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--ahriman[get service status itself (default\: False)]"
|
||||
@@ -326,26 +266,17 @@ _shtab_ahriman_package_status_options=(
|
||||
"(*)::filter status by package base (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_package_status_defaults_added=0
|
||||
|
||||
_shtab_ahriman_package_status_remove_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*):remove specified packages from status page:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_package_status_remove_defaults_added=0
|
||||
|
||||
_shtab_ahriman_package_status_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-s,--status}"[new package build status (default\: success)]:status:(unknown pending building failed success)"
|
||||
"(*)::set status for specified packages. If no packages supplied, service status will be updated (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_package_status_update_defaults_added=0
|
||||
|
||||
_shtab_ahriman_package_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available (default\: True)]:changes:"
|
||||
@@ -360,9 +291,6 @@ _shtab_ahriman_package_update_options=(
|
||||
"(*):package source (base name, path to local files, remote URL):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_package_update_defaults_added=0
|
||||
|
||||
_shtab_ahriman_patch_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
":package base:"
|
||||
@@ -370,9 +298,6 @@ _shtab_ahriman_patch_add_options=(
|
||||
":path to file which contains function or variable value. If not set, the value will be read from stdin (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_patch_add_defaults_added=0
|
||||
|
||||
_shtab_ahriman_patch_list_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
@@ -380,27 +305,18 @@ _shtab_ahriman_patch_list_options=(
|
||||
":package base:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_patch_list_defaults_added=0
|
||||
|
||||
_shtab_ahriman_patch_remove_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"*"{-v,--variable}"[should be used for single-function patches in case if you wold like to remove only specified PKGBUILD variables. In case if not set, it will remove all patches related to the package (default\: None)]:variable:"
|
||||
":package base:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_patch_remove_defaults_added=0
|
||||
|
||||
_shtab_ahriman_patch_set_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"*"{-t,--track}"[files which has to be tracked (default\: \[\'\*.diff\', \'\*.patch\'\])]:track:"
|
||||
":path to directory with changed files for patch addition\/update:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_patch_set_add_defaults_added=0
|
||||
|
||||
_shtab_ahriman_rebuild_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"*--depends-on[only rebuild packages that depend on specified packages (default\: None)]:depends_on:"
|
||||
@@ -412,33 +328,21 @@ _shtab_ahriman_rebuild_options=(
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_rebuild_defaults_added=0
|
||||
|
||||
_shtab_ahriman_remove_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*):package name or base:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_remove_defaults_added=0
|
||||
|
||||
_shtab_ahriman_remove_unknown_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--dry-run[just perform check for packages without removal (default\: False)]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_remove_unknown_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_backup_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
":path of the output archive:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_backup_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_check_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available (default\: True)]:changes:"
|
||||
@@ -449,9 +353,6 @@ _shtab_ahriman_repo_check_options=(
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_check_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_clean_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--cache,--no-cache}"[clear directory with package caches (default\: False)]:cache:"
|
||||
@@ -461,9 +362,6 @@ _shtab_ahriman_repo_clean_options=(
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: False)]:pacman:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_clean_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_config_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--info,--no-info}"[show additional information, e.g. configuration files (default\: True)]:info:"
|
||||
@@ -472,31 +370,19 @@ _shtab_ahriman_repo_config_options=(
|
||||
":filter settings by key (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_config_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_config_validate_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid (default\: False)]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_config_validate_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_create_keyring_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_create_keyring_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_create_mirrorlist_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_create_mirrorlist_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_daemon_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-i,--interval}"[interval between runs in seconds (default\: 43200)]:interval:"
|
||||
@@ -514,9 +400,6 @@ _shtab_ahriman_repo_daemon_options=(
|
||||
"*"{-y,--refresh}"[download fresh package databases from the mirror before actions, -yy to force refresh even if up to date (default\: False)]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_daemon_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_init_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
@@ -533,9 +416,6 @@ _shtab_ahriman_repo_init_options=(
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_init_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_rebuild_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"*--depends-on[only rebuild packages that depend on specified packages (default\: None)]:depends_on:"
|
||||
@@ -547,33 +427,21 @@ _shtab_ahriman_repo_rebuild_options=(
|
||||
{-u,--username}"[build as user (default\: None)]:username:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_rebuild_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_remove_unknown_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--dry-run[just perform check for packages without removal (default\: False)]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_remove_unknown_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_report_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_report_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_restore_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-o,--output}"[root path of the extracted files (default\: \/)]:output:"
|
||||
":path of the input archive:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_restore_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_setup_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
@@ -590,17 +458,11 @@ _shtab_ahriman_repo_setup_options=(
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_setup_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_sign_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*)::sign only specified packages (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_sign_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_statistics_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--chart[create updates chart and save it to the specified path (default\: None)]:chart:"
|
||||
@@ -612,40 +474,25 @@ _shtab_ahriman_repo_statistics_options=(
|
||||
":fetch only events for the specified package (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_statistics_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_status_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-s,--status}"[new status (default\: success)]:status:(unknown pending building failed success)"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_status_update_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_sync_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_sync_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_tree_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-p,--partitions}"[also divide packages by independent partitions (default\: 1)]:partitions:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_tree_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_triggers_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*)::instead of running all triggers as set by configuration, just process specified ones in order of mention (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_triggers_defaults_added=0
|
||||
|
||||
_shtab_ahriman_repo_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: True)]:aur:"
|
||||
@@ -663,24 +510,15 @@ _shtab_ahriman_repo_update_options=(
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_repo_update_defaults_added=0
|
||||
|
||||
_shtab_ahriman_report_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_report_defaults_added=0
|
||||
|
||||
_shtab_ahriman_run_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*):command to be run (quoted) without \`\`ahriman\`\`:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_run_defaults_added=0
|
||||
|
||||
_shtab_ahriman_search_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
@@ -689,9 +527,6 @@ _shtab_ahriman_search_options=(
|
||||
"(*):search terms, can be specified multiple times, the result will match all terms:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_search_defaults_added=0
|
||||
|
||||
_shtab_ahriman_service_clean_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--cache,--no-cache}"[clear directory with package caches (default\: False)]:cache:"
|
||||
@@ -701,9 +536,6 @@ _shtab_ahriman_service_clean_options=(
|
||||
{--pacman,--no-pacman}"[clear directory with pacman local database cache (default\: False)]:pacman:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_service_clean_defaults_added=0
|
||||
|
||||
_shtab_ahriman_service_config_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--info,--no-info}"[show additional information, e.g. configuration files (default\: True)]:info:"
|
||||
@@ -712,42 +544,27 @@ _shtab_ahriman_service_config_options=(
|
||||
":filter settings by key (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_service_config_defaults_added=0
|
||||
|
||||
_shtab_ahriman_service_config_validate_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if configuration is invalid (default\: False)]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_service_config_validate_defaults_added=0
|
||||
|
||||
_shtab_ahriman_service_key_import_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--key-server[key server for key import (default\: keyserver.ubuntu.com)]:key_server:"
|
||||
":PGP key to import from public server:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_service_key_import_defaults_added=0
|
||||
|
||||
_shtab_ahriman_service_repositories_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--id-only,--no-id-only}"[show machine readable identifier instead (default\: False)]:id_only:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_service_repositories_defaults_added=0
|
||||
|
||||
_shtab_ahriman_service_run_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*):command to be run (quoted) without \`\`ahriman\`\`:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_service_run_defaults_added=0
|
||||
|
||||
_shtab_ahriman_service_setup_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
@@ -764,25 +581,16 @@ _shtab_ahriman_service_setup_options=(
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_service_setup_defaults_added=0
|
||||
|
||||
_shtab_ahriman_service_shell_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-o,--output}"[output commands and result to the file (default\: None)]:output:"
|
||||
":instead of dropping into shell, just execute the specified code (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_service_shell_defaults_added=0
|
||||
|
||||
_shtab_ahriman_service_tree_migrate_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_service_tree_migrate_defaults_added=0
|
||||
|
||||
_shtab_ahriman_setup_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--build-as-user[force makepkg user to the specific one (default\: None)]:build_as_user:"
|
||||
@@ -799,26 +607,17 @@ _shtab_ahriman_setup_options=(
|
||||
"--web-unix-socket[path to unix socket used for interprocess communications (default\: None)]:web_unix_socket:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_setup_defaults_added=0
|
||||
|
||||
_shtab_ahriman_shell_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-o,--output}"[output commands and result to the file (default\: None)]:output:"
|
||||
":instead of dropping into shell, just execute the specified code (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_shell_defaults_added=0
|
||||
|
||||
_shtab_ahriman_sign_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"(*)::sign only specified packages (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_sign_defaults_added=0
|
||||
|
||||
_shtab_ahriman_status_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--ahriman[get service status itself (default\: False)]"
|
||||
@@ -828,25 +627,16 @@ _shtab_ahriman_status_options=(
|
||||
"(*)::filter status by package base (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_status_defaults_added=0
|
||||
|
||||
_shtab_ahriman_status_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-s,--status}"[new package build status (default\: success)]:status:(unknown pending building failed success)"
|
||||
"(*)::set status for specified packages. If no packages supplied, service status will be updated (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_status_update_defaults_added=0
|
||||
|
||||
_shtab_ahriman_sync_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_sync_defaults_added=0
|
||||
|
||||
_shtab_ahriman_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--aur,--no-aur}"[enable or disable checking for AUR updates (default\: True)]:aur:"
|
||||
@@ -864,9 +654,6 @@ _shtab_ahriman_update_options=(
|
||||
"(*)::filter check by package base (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_update_defaults_added=0
|
||||
|
||||
_shtab_ahriman_user_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--key[optional PGP key used by this user. The private key must be imported (default\: None)]:key:"
|
||||
@@ -876,9 +663,6 @@ _shtab_ahriman_user_add_options=(
|
||||
":username for web service:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_user_add_defaults_added=0
|
||||
|
||||
_shtab_ahriman_user_list_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
@@ -886,41 +670,25 @@ _shtab_ahriman_user_list_options=(
|
||||
":filter users by username (default\: None):"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_user_list_defaults_added=0
|
||||
|
||||
_shtab_ahriman_user_remove_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
":username for web service:"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_user_remove_defaults_added=0
|
||||
|
||||
_shtab_ahriman_version_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_version_defaults_added=0
|
||||
|
||||
_shtab_ahriman_web_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
)
|
||||
|
||||
# guard to ensure default positional specs are added only once per session
|
||||
_shtab_ahriman_web_defaults_added=0
|
||||
|
||||
|
||||
_shtab_ahriman() {
|
||||
local context state line curcontext="$curcontext" one_or_more='(*)' remainder='(-)*' default='*::: :->ahriman'
|
||||
local context state line curcontext="$curcontext" one_or_more='(-)*' remainder='(*)'
|
||||
|
||||
# Add default positional/remainder specs only if none exist, and only once per session
|
||||
if (( ! _shtab_ahriman_defaults_added )); then
|
||||
if (( ${_shtab_ahriman_options[(I)${(q)one_or_more}*]} + ${_shtab_ahriman_options[(I)${(q)remainder}*]} + ${_shtab_ahriman_options[(I)${(q)default}]} == 0 )); then
|
||||
_shtab_ahriman_options+=(': :_shtab_ahriman_commands' '*::: :->ahriman')
|
||||
fi
|
||||
_shtab_ahriman_defaults_added=1
|
||||
if ((${_shtab_ahriman_options[(I)${(q)one_or_more}*]} + ${_shtab_ahriman_options[(I)${(q)remainder}*]} == 0)); then # noqa: E501
|
||||
_shtab_ahriman_options+=(': :_shtab_ahriman_commands' '*::: :->ahriman')
|
||||
fi
|
||||
_arguments -C -s $_shtab_ahriman_options
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ services:
|
||||
AHRIMAN_OUTPUT: console
|
||||
AHRIMAN_PASSWORD: ${AHRIMAN_PASSWORD}
|
||||
AHRIMAN_PORT: 8080
|
||||
AHRIMAN_POSTSETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_PRESETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_REPOSITORY: ahriman-demo
|
||||
AHRIMAN_UNIX_SOCKET: /var/lib/ahriman/ahriman/ahriman.sock
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ services:
|
||||
AHRIMAN_OUTPUT: console
|
||||
AHRIMAN_PASSWORD: ${AHRIMAN_PASSWORD}
|
||||
AHRIMAN_PORT: 8080
|
||||
AHRIMAN_POSTSETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_PRESETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_REPOSITORY: ahriman-demo
|
||||
AHRIMAN_UNIX_SOCKET: /var/lib/ahriman/ahriman/ahriman.sock
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ services:
|
||||
AHRIMAN_OUTPUT: console
|
||||
AHRIMAN_PASSWORD: ${AHRIMAN_PASSWORD}
|
||||
AHRIMAN_PORT: 8080
|
||||
AHRIMAN_POSTSETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_PRESETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_REPOSITORY: ahriman-demo
|
||||
AHRIMAN_UNIX_SOCKET: /var/lib/ahriman/ahriman/ahriman.sock
|
||||
|
||||
@@ -62,7 +62,7 @@ services:
|
||||
AHRIMAN_OUTPUT: console
|
||||
AHRIMAN_PASSWORD: ${AHRIMAN_PASSWORD}
|
||||
AHRIMAN_PORT: 8080
|
||||
AHRIMAN_POSTSETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_PRESETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_REPOSITORY: ahriman-demo
|
||||
AHRIMAN_REPOSITORY_SERVER: http://frontend/repo/$$repo/$$arch
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ services:
|
||||
AHRIMAN_PACMAN_MIRROR: https://de.mirror.archlinux32.org/$$arch/$$repo
|
||||
AHRIMAN_PASSWORD: ${AHRIMAN_PASSWORD}
|
||||
AHRIMAN_PORT: 8080
|
||||
AHRIMAN_POSTSETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_PRESETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_REPOSITORY: ahriman-demo
|
||||
AHRIMAN_UNIX_SOCKET: /var/lib/ahriman/ahriman/ahriman.sock
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ services:
|
||||
AHRIMAN_OUTPUT: console
|
||||
AHRIMAN_PASSWORD: ${AHRIMAN_PASSWORD}
|
||||
AHRIMAN_PORT: 8080
|
||||
AHRIMAN_POSTSETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_PRESETUP_COMMAND: ahriman --architecture x86_64 --repository another-demo service-setup --build-as-user ahriman --packager 'ahriman bot <ahriman@example.com>'
|
||||
AHRIMAN_POSTSETUP_COMMAND: ahriman --architecture x86_64 --repository another-demo service-setup --build-as-user ahriman --packager 'ahriman bot <ahriman@example.com>'
|
||||
AHRIMAN_PRESETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_REPOSITORY: ahriman-demo
|
||||
AHRIMAN_UNIX_SOCKET: /var/lib/ahriman/ahriman/ahriman.sock
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ services:
|
||||
AHRIMAN_OAUTH_CLIENT_SECRET: ${AHRIMAN_OAUTH_CLIENT_SECRET}
|
||||
AHRIMAN_OUTPUT: console
|
||||
AHRIMAN_PORT: 8080
|
||||
AHRIMAN_POSTSETUP_COMMAND: sudo -u ahriman ahriman user-add ${AHRIMAN_OAUTH_USER} -R full -p ""
|
||||
AHRIMAN_PRESETUP_COMMAND: sudo -u ahriman ahriman user-add ${AHRIMAN_OAUTH_USER} -R full -p ""
|
||||
AHRIMAN_REPOSITORY: ahriman-demo
|
||||
AHRIMAN_UNIX_SOCKET: /var/lib/ahriman/ahriman/ahriman.sock
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ services:
|
||||
environment:
|
||||
AHRIMAN_DEBUG: yes
|
||||
AHRIMAN_OUTPUT: console
|
||||
AHRIMAN_POSTSETUP_COMMAND: sudo -u ahriman gpg --import /run/secrets/key
|
||||
AHRIMAN_PRESETUP_COMMAND: sudo -u ahriman gpg --import /run/secrets/key
|
||||
AHRIMAN_REPOSITORY: ahriman-demo
|
||||
|
||||
configs:
|
||||
|
||||
@@ -8,7 +8,7 @@ services:
|
||||
AHRIMAN_OUTPUT: console
|
||||
AHRIMAN_PASSWORD: ${AHRIMAN_PASSWORD}
|
||||
AHRIMAN_PORT: 8080
|
||||
AHRIMAN_POSTSETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_PRESETUP_COMMAND: (cat /run/secrets/password; echo; cat /run/secrets/password) | sudo -u ahriman ahriman user-add demo -R full
|
||||
AHRIMAN_REPOSITORY: ahriman-demo
|
||||
AHRIMAN_UNIX_SOCKET: /var/lib/ahriman/ahriman/ahriman.sock
|
||||
|
||||
|
||||
@@ -17,4 +17,4 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
__version__ = "2.19.4"
|
||||
__version__ = "2.19.0"
|
||||
|
||||
@@ -72,17 +72,16 @@ class Setup(Handler):
|
||||
|
||||
application = Application(repository_id, configuration, report=report)
|
||||
|
||||
with application.repository.paths.preserve_owner():
|
||||
Setup.configuration_create_makepkg(args.packager, args.makeflags_jobs, application.repository.paths)
|
||||
Setup.executable_create(application.repository.paths, repository_id)
|
||||
repository_server = f"file://{application.repository.paths.repository}" if args.server is None else args.server
|
||||
Setup.configuration_create_devtools(
|
||||
repository_id, args.from_configuration, args.mirror, args.multilib, repository_server)
|
||||
Setup.configuration_create_sudo(application.repository.paths, repository_id)
|
||||
Setup.configuration_create_makepkg(args.packager, args.makeflags_jobs, application.repository.paths)
|
||||
Setup.executable_create(application.repository.paths, repository_id)
|
||||
repository_server = f"file://{application.repository.paths.repository}" if args.server is None else args.server
|
||||
Setup.configuration_create_devtools(
|
||||
repository_id, args.from_configuration, args.mirror, args.multilib, repository_server)
|
||||
Setup.configuration_create_sudo(application.repository.paths, repository_id)
|
||||
|
||||
application.repository.repo.init()
|
||||
# lazy database sync
|
||||
application.repository.pacman.handle # pylint: disable=pointless-statement
|
||||
application.repository.repo.init()
|
||||
# lazy database sync
|
||||
application.repository.pacman.handle # pylint: disable=pointless-statement
|
||||
|
||||
@staticmethod
|
||||
def _set_service_setup_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
@@ -281,5 +280,6 @@ class Setup(Handler):
|
||||
command = Setup.build_command(paths.root, repository_id)
|
||||
command.unlink(missing_ok=True)
|
||||
command.symlink_to(Setup.ARCHBUILD_COMMAND_PATH)
|
||||
paths.chown(command) # we would like to keep owner inside ahriman's home
|
||||
|
||||
arguments = [_set_service_setup_parser]
|
||||
|
||||
@@ -52,7 +52,7 @@ class Validate(Handler):
|
||||
"""
|
||||
from ahriman.core.configuration.validator import Validator
|
||||
|
||||
schema = Validate.schema(configuration)
|
||||
schema = Validate.schema(repository_id, configuration)
|
||||
validator = Validator(configuration=configuration, schema=schema)
|
||||
|
||||
if validator.validate(configuration.dump()):
|
||||
@@ -83,11 +83,12 @@ class Validate(Handler):
|
||||
return parser
|
||||
|
||||
@staticmethod
|
||||
def schema(configuration: Configuration) -> ConfigurationSchema:
|
||||
def schema(repository_id: RepositoryId, configuration: Configuration) -> ConfigurationSchema:
|
||||
"""
|
||||
get schema with triggers
|
||||
|
||||
Args:
|
||||
repository_id(RepositoryId): repository unique identifier
|
||||
configuration(Configuration): configuration instance
|
||||
|
||||
Returns:
|
||||
@@ -106,12 +107,12 @@ class Validate(Handler):
|
||||
continue
|
||||
|
||||
# default settings if any
|
||||
for schema_name, schema in trigger_class.configuration_schema(None).items():
|
||||
for schema_name, schema in trigger_class.configuration_schema(repository_id, None).items():
|
||||
erased = Validate.schema_erase_required(copy.deepcopy(schema))
|
||||
root[schema_name] = Validate.schema_merge(root.get(schema_name, {}), erased)
|
||||
|
||||
# settings according to enabled triggers
|
||||
for schema_name, schema in trigger_class.configuration_schema(configuration).items():
|
||||
for schema_name, schema in trigger_class.configuration_schema(repository_id, configuration).items():
|
||||
root[schema_name] = Validate.schema_merge(root.get(schema_name, {}), copy.deepcopy(schema))
|
||||
|
||||
return root
|
||||
|
||||
@@ -21,7 +21,7 @@ import argparse
|
||||
import re
|
||||
import sys
|
||||
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
from importlib import metadata
|
||||
from typing import ClassVar
|
||||
|
||||
@@ -77,7 +77,7 @@ class Versions(Handler):
|
||||
return parser
|
||||
|
||||
@staticmethod
|
||||
def package_dependencies(root: str) -> Iterator[tuple[str, str]]:
|
||||
def package_dependencies(root: str) -> Generator[tuple[str, str], None, None]:
|
||||
"""
|
||||
extract list of ahriman package dependencies installed into system with their versions
|
||||
|
||||
@@ -87,7 +87,7 @@ class Versions(Handler):
|
||||
Yields:
|
||||
tuple[str, str]: map of installed dependency to its version
|
||||
"""
|
||||
def dependencies_by_key(key: str) -> Iterator[str]:
|
||||
def dependencies_by_key(key: str) -> Generator[str, None, None]:
|
||||
# in importlib it returns requires in the following format
|
||||
# ["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"]
|
||||
try:
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
import argparse
|
||||
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.application.handlers.handler import Handler, SubParserAction
|
||||
@@ -86,7 +86,7 @@ class Web(Handler):
|
||||
return parser
|
||||
|
||||
@staticmethod
|
||||
def extract_arguments(args: argparse.Namespace, configuration: Configuration) -> Iterator[str]:
|
||||
def extract_arguments(args: argparse.Namespace, configuration: Configuration) -> Generator[str, None, None]:
|
||||
"""
|
||||
extract list of arguments used for current command, except for command specific ones
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ class Lock(LazyLogging):
|
||||
"""
|
||||
check if current user is actually owner of ahriman root
|
||||
"""
|
||||
check_user(self.paths.root, unsafe=self.unsafe)
|
||||
check_user(self.paths, unsafe=self.unsafe)
|
||||
self.paths.tree_create()
|
||||
|
||||
def check_version(self) -> None:
|
||||
|
||||
@@ -21,7 +21,7 @@ import itertools
|
||||
import shutil
|
||||
import tarfile
|
||||
|
||||
from collections.abc import Iterable, Iterator
|
||||
from collections.abc import Generator, Iterable
|
||||
from functools import cached_property
|
||||
from pathlib import Path
|
||||
from pyalpm import DB, Handle, Package, SIG_DATABASE_OPTIONAL, SIG_PACKAGE_OPTIONAL # type: ignore[import-not-found]
|
||||
@@ -130,8 +130,8 @@ class Pacman(LazyLogging):
|
||||
return # database for some reason deos not exist
|
||||
|
||||
self.logger.info("copy pacman database %s from operating system root to ahriman's home %s", src, dst)
|
||||
with self.repository_paths.preserve_owner(dst.parent):
|
||||
shutil.copy(src, dst)
|
||||
shutil.copy(src, dst)
|
||||
self.repository_paths.chown(dst)
|
||||
|
||||
def database_init(self, handle: Handle, repository: str, architecture: str) -> DB:
|
||||
"""
|
||||
@@ -188,7 +188,7 @@ class Pacman(LazyLogging):
|
||||
Returns:
|
||||
dict[str, set[str]]: map of package name to its list of files
|
||||
"""
|
||||
def extract(tar: tarfile.TarFile, versions: dict[str, str]) -> Iterator[tuple[str, set[str]]]:
|
||||
def extract(tar: tarfile.TarFile, versions: dict[str, str]) -> Generator[tuple[str, set[str]], None, None]:
|
||||
for package_name, version in versions.items():
|
||||
path = Path(f"{package_name}-{version}") / "files"
|
||||
try:
|
||||
@@ -223,7 +223,7 @@ class Pacman(LazyLogging):
|
||||
|
||||
return result
|
||||
|
||||
def package(self, package_name: str) -> Iterator[Package]:
|
||||
def package(self, package_name: str) -> Generator[Package, None, None]:
|
||||
"""
|
||||
retrieve list of the packages from the repository by name
|
||||
|
||||
@@ -256,7 +256,7 @@ class Pacman(LazyLogging):
|
||||
|
||||
return result
|
||||
|
||||
def provided_by(self, package_name: str) -> Iterator[Package]:
|
||||
def provided_by(self, package_name: str) -> Generator[Package, None, None]:
|
||||
"""
|
||||
search through databases and emit packages which provides the ``package_name``
|
||||
|
||||
@@ -267,8 +267,7 @@ class Pacman(LazyLogging):
|
||||
Package: list of packages which were returned by the query
|
||||
"""
|
||||
def is_package_provided(package: Package) -> bool:
|
||||
provides = [trim_package(name) for name in package.provides]
|
||||
return package_name in provides
|
||||
return package_name in package.provides
|
||||
|
||||
for database in self.handle.get_syncdbs():
|
||||
yield from filter(is_package_provided, database.search(package_name))
|
||||
|
||||
@@ -21,7 +21,7 @@ import itertools
|
||||
import re
|
||||
import shlex
|
||||
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
from enum import StrEnum
|
||||
from typing import IO
|
||||
|
||||
@@ -209,7 +209,7 @@ class PkgbuildParser(shlex.shlex):
|
||||
Raises:
|
||||
PkgbuildParserError: if array is not closed
|
||||
"""
|
||||
def extract() -> Iterator[str]:
|
||||
def extract() -> Generator[str, None, None]:
|
||||
while token := self.get_token():
|
||||
match token:
|
||||
case _ if self._is_escaped():
|
||||
@@ -276,7 +276,7 @@ class PkgbuildParser(shlex.shlex):
|
||||
|
||||
return content
|
||||
|
||||
def _parse_token(self, token: str) -> Iterator[PkgbuildPatch]:
|
||||
def _parse_token(self, token: str) -> Generator[PkgbuildPatch, None, None]:
|
||||
"""
|
||||
parse single token to the PKGBUILD field
|
||||
|
||||
@@ -360,7 +360,7 @@ class PkgbuildParser(shlex.shlex):
|
||||
|
||||
raise PkgbuildParserError("reached starting position, no valid symbols found")
|
||||
|
||||
def parse(self) -> Iterator[PkgbuildPatch]:
|
||||
def parse(self) -> Generator[PkgbuildPatch, None, None]:
|
||||
"""
|
||||
parse source stream and yield parsed entries
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ class AUR(Remote):
|
||||
# search api provides reduced models
|
||||
for stub in self.package_search(package_name, pacman=pacman, search_by="provides")
|
||||
# verity that found package actually provides it
|
||||
if package_name in (package := self.package_info(stub.name, pacman=pacman)).provides
|
||||
if package_name in (package := self.package_info(stub.package_base, pacman=pacman)).provides
|
||||
]
|
||||
|
||||
def package_search(self, *keywords: str, pacman: Pacman | None, search_by: str | None) -> list[AURPackage]:
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
import shutil
|
||||
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
from pathlib import Path
|
||||
from typing import ClassVar
|
||||
|
||||
@@ -347,7 +347,7 @@ class Sources(LazyLogging):
|
||||
"""
|
||||
gitconfig = gitconfig or {}
|
||||
|
||||
def configuration_flags() -> Iterator[str]:
|
||||
def configuration_flags() -> Generator[str, None, None]:
|
||||
for option, value in (self.GITCONFIG | gitconfig).items():
|
||||
yield "-c"
|
||||
yield f"{option}=\"{value}\""
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.core.build_tools.sources import Sources
|
||||
@@ -77,7 +77,7 @@ class Task(LazyLogging):
|
||||
Returns:
|
||||
list[Path]: list of file paths which looks like freshly generated archives
|
||||
"""
|
||||
def files() -> Iterator[Path]:
|
||||
def files() -> Generator[Path, None, None]:
|
||||
for filepath in sources_dir.iterdir():
|
||||
if filepath in source_files:
|
||||
continue # skip files which were already there
|
||||
|
||||
@@ -41,6 +41,7 @@ class Configuration(configparser.RawConfigParser):
|
||||
SYSTEM_CONFIGURATION_PATH(Path): (class attribute) default system configuration path distributed by package
|
||||
includes(list[Path]): list of includes which were read
|
||||
path(Path | None): path to root configuration file
|
||||
repository_id(RepositoryId | None): repository unique identifier
|
||||
|
||||
Examples:
|
||||
Configuration class provides additional method in order to handle application configuration. Since this class is
|
||||
@@ -90,7 +91,7 @@ class Configuration(configparser.RawConfigParser):
|
||||
},
|
||||
)
|
||||
|
||||
self._repository_id: RepositoryId | None = None
|
||||
self.repository_id: RepositoryId | None = None
|
||||
self.path: Path | None = None
|
||||
self.includes: list[Path] = []
|
||||
|
||||
@@ -125,32 +126,6 @@ class Configuration(configparser.RawConfigParser):
|
||||
"""
|
||||
return self.getpath("settings", "logging")
|
||||
|
||||
@property
|
||||
def repository_id(self) -> RepositoryId | None:
|
||||
"""
|
||||
repository identifier
|
||||
|
||||
Returns:
|
||||
RepositoryId: repository unique identifier
|
||||
"""
|
||||
return self._repository_id
|
||||
|
||||
@repository_id.setter
|
||||
def repository_id(self, repository_id: RepositoryId | None) -> None:
|
||||
"""
|
||||
setter for repository identifier
|
||||
|
||||
Args:
|
||||
repository_id(RepositoryId | None): repository unique identifier
|
||||
"""
|
||||
self._repository_id = repository_id
|
||||
if repository_id is None or repository_id.is_empty:
|
||||
self.remove_option("repository", "name")
|
||||
self.remove_option("repository", "architecture")
|
||||
else:
|
||||
self.set_option("repository", "name", repository_id.name)
|
||||
self.set_option("repository", "architecture", repository_id.architecture)
|
||||
|
||||
@property
|
||||
def repository_name(self) -> str:
|
||||
"""
|
||||
|
||||
@@ -57,7 +57,7 @@ class ConfigurationMultiDict(dict[str, Any]):
|
||||
OptionError: if the key already exists in the dictionary, but not a single value list or a string
|
||||
"""
|
||||
match self.get(key):
|
||||
case [current_value] | (str() as current_value):
|
||||
case [current_value] | str(current_value):
|
||||
value = f"{current_value} {value}"
|
||||
case None:
|
||||
pass
|
||||
|
||||
@@ -254,10 +254,6 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = {
|
||||
"repository": {
|
||||
"type": "dict",
|
||||
"schema": {
|
||||
"architecture": {
|
||||
"type": "string",
|
||||
"empty": False,
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"empty": False,
|
||||
|
||||
@@ -21,7 +21,7 @@ import configparser
|
||||
import os
|
||||
import sys
|
||||
|
||||
from collections.abc import Iterator, Mapping, MutableMapping
|
||||
from collections.abc import Generator, Mapping, MutableMapping
|
||||
from string import Template
|
||||
from typing import Any, ClassVar
|
||||
|
||||
@@ -37,7 +37,7 @@ class ShellInterpolator(configparser.Interpolation):
|
||||
|
||||
@staticmethod
|
||||
def _extract_variables(parser: MutableMapping[str, Mapping[str, str]], value: str,
|
||||
defaults: Mapping[str, str]) -> Iterator[tuple[str, str]]:
|
||||
defaults: Mapping[str, str]) -> Generator[tuple[str, str], None, None]:
|
||||
"""
|
||||
extract keys and values (if available) from the configuration. In case if a key is not available, it will be
|
||||
silently skipped from the result
|
||||
@@ -50,7 +50,7 @@ class ShellInterpolator(configparser.Interpolation):
|
||||
Yields:
|
||||
tuple[str, str]: variable name used for substitution and its value
|
||||
"""
|
||||
def identifiers() -> Iterator[tuple[str | None, str]]:
|
||||
def identifiers() -> Generator[tuple[str | None, str], None, None]:
|
||||
# extract all found identifiers and parse them
|
||||
for identifier in ShellTemplate(value).get_identifiers():
|
||||
match identifier.rsplit(":", maxsplit=1):
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import fnmatch
|
||||
import re
|
||||
|
||||
from collections.abc import Iterator, Mapping
|
||||
from collections.abc import Generator, Mapping
|
||||
from string import Template
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ class ShellTemplate(Template):
|
||||
(self._REPLACE, self._replace, "/"),
|
||||
)
|
||||
|
||||
def generator(variables: dict[str, str]) -> Iterator[tuple[str, str]]:
|
||||
def generator(variables: dict[str, str]) -> Generator[tuple[str, str], None, None]:
|
||||
for identifier in self.get_identifiers():
|
||||
for regex, function, greediness in substitutions:
|
||||
if m := regex.match(identifier):
|
||||
|
||||
@@ -29,13 +29,15 @@ class LogsOperations(Operations):
|
||||
logs operations
|
||||
"""
|
||||
|
||||
def logs_get(self, package_base: str, limit: int = -1, offset: int = 0,
|
||||
repository_id: RepositoryId | None = None) -> list[LogRecord]:
|
||||
def logs_get(self, package_base: str, version: str | None = None, process_id: str | None = None,
|
||||
limit: int = -1, offset: int = 0, repository_id: RepositoryId | None = None) -> list[LogRecord]:
|
||||
"""
|
||||
extract logs for specified package base
|
||||
|
||||
Args:
|
||||
package_base(str): package base to extract logs
|
||||
version(str | None, optional): package version to filter (Default value = None)
|
||||
process_id(str | None, optional): process identifier to filter (Default value = None)
|
||||
limit(int, optional): limit records to the specified count, -1 means unlimited (Default value = -1)
|
||||
offset(int, optional): records offset (Default value = 0)
|
||||
repository_id(RepositoryId, optional): repository unique identifier override (Default value = None)
|
||||
@@ -52,12 +54,17 @@ class LogsOperations(Operations):
|
||||
"""
|
||||
select created, message, version, process_id from (
|
||||
select * from logs
|
||||
where package_base = :package_base and repository = :repository
|
||||
where package_base = :package_base
|
||||
and repository = :repository
|
||||
and (:version is null or version = :version)
|
||||
and (:process_id is null or process_id = :process_id)
|
||||
order by created desc limit :limit offset :offset
|
||||
) order by created asc
|
||||
""",
|
||||
{
|
||||
"package_base": package_base,
|
||||
"version": version,
|
||||
"process_id": process_id,
|
||||
"repository": repository_id.id,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from collections.abc import Iterable, Iterator
|
||||
from collections.abc import Generator, Iterable
|
||||
from sqlite3 import Connection
|
||||
|
||||
from ahriman.core.database.operations.operations import Operations
|
||||
@@ -263,7 +263,7 @@ class PackageOperations(Operations):
|
||||
"""
|
||||
repository_id = repository_id or self._repository_id
|
||||
|
||||
def run(connection: Connection) -> Iterator[tuple[Package, BuildStatus]]:
|
||||
def run(connection: Connection) -> Generator[tuple[Package, BuildStatus], None, None]:
|
||||
packages = self._packages_get_select_package_bases(connection, repository_id)
|
||||
statuses = self._packages_get_select_statuses(connection, repository_id)
|
||||
per_package_base = self._packages_get_select_packages(connection, packages, repository_id)
|
||||
|
||||
@@ -94,13 +94,9 @@ class SQLite(
|
||||
sqlite3.register_adapter(list, json.dumps)
|
||||
sqlite3.register_converter("json", json.loads)
|
||||
|
||||
if not self._configuration.getboolean("settings", "apply_migrations", fallback=True):
|
||||
return
|
||||
if self._repository_id.is_empty:
|
||||
return # do not perform migration on empty repository identifier (e.g. multirepo command)
|
||||
|
||||
with self._repository_paths.preserve_owner():
|
||||
if self._configuration.getboolean("settings", "apply_migrations", fallback=True):
|
||||
self.with_connection(lambda connection: Migrations.migrate(connection, self._configuration))
|
||||
self._repository_paths.chown(self.path)
|
||||
|
||||
def package_clear(self, package_base: str, repository_id: RepositoryId | None = None) -> None:
|
||||
"""
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
from typing import Any
|
||||
|
||||
from ahriman.core.formatters.string_printer import StringPrinter
|
||||
@@ -44,7 +44,8 @@ class ValidationPrinter(StringPrinter):
|
||||
self.errors = errors
|
||||
|
||||
@staticmethod
|
||||
def get_error_messages(node: str, errors: list[str | dict[str, Any]], current_level: int = 1) -> Iterator[Property]:
|
||||
def get_error_messages(node: str, errors: list[str | dict[str, Any]],
|
||||
current_level: int = 1) -> Generator[Property, None, None]:
|
||||
"""
|
||||
extract default error message from cerberus class
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
import shutil
|
||||
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
@@ -96,7 +96,7 @@ class RemotePush(LazyLogging):
|
||||
# ...and finally return path to the copied directory
|
||||
return package.base
|
||||
|
||||
def packages_update(self, result: Result, target_dir: Path) -> Iterator[str]:
|
||||
def packages_update(self, result: Result, target_dir: Path) -> Generator[str, None, None]:
|
||||
"""
|
||||
update all packages from the build result
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@ class SyncHttpClient(LazyLogging):
|
||||
"""
|
||||
session = requests.Session()
|
||||
python_version = ".".join(map(str, sys.version_info[:3])) # just major.minor.patch
|
||||
session.headers["User-Agent"] = f"ahriman/{__version__} " \
|
||||
f"{requests.utils.default_user_agent()} " \
|
||||
session.headers["User-Agent"] = f"ahriman/{__version__}" \
|
||||
f"{requests.utils.default_user_agent()}" \
|
||||
f"python/{python_version}"
|
||||
|
||||
return session
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import contextlib
|
||||
import logging
|
||||
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
from functools import cached_property
|
||||
from typing import Any
|
||||
|
||||
@@ -80,7 +80,7 @@ class LazyLogging:
|
||||
logging.setLogRecordFactory(package_record_factory)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_package_context(self, package_base: str, version: str | None) -> Iterator[None]:
|
||||
def in_package_context(self, package_base: str, version: str | None) -> Generator[None, None, None]:
|
||||
"""
|
||||
execute function while setting package context
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
import inspect
|
||||
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
from importlib import import_module
|
||||
from pathlib import Path
|
||||
from pkgutil import ModuleInfo, walk_packages
|
||||
@@ -33,7 +33,7 @@ __all__ = ["implementations"]
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
def _modules(module_root: Path, prefix: str) -> Iterator[ModuleInfo]:
|
||||
def _modules(module_root: Path, prefix: str) -> Generator[ModuleInfo, None, None]:
|
||||
"""
|
||||
extract available modules from package
|
||||
|
||||
@@ -52,7 +52,7 @@ def _modules(module_root: Path, prefix: str) -> Iterator[ModuleInfo]:
|
||||
yield module_info
|
||||
|
||||
|
||||
def implementations(root_module: ModuleType, base_class: type[T]) -> Iterator[type[T]]:
|
||||
def implementations(root_module: ModuleType, base_class: type[T]) -> Generator[type[T], None, None]:
|
||||
"""
|
||||
extract implementations of the ``base_class`` from the module
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
import contextlib
|
||||
|
||||
from collections.abc import Iterator
|
||||
from typing import Generator
|
||||
|
||||
from ahriman.core.status import Client
|
||||
from ahriman.models.event import Event, EventType
|
||||
@@ -55,7 +55,7 @@ class EventLogger:
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_event(self, package_base: str, event: EventType, message: str | None = None,
|
||||
failure: EventType | None = None) -> Iterator[None]:
|
||||
failure: EventType | None = None) -> Generator[None, None, None]:
|
||||
"""
|
||||
perform action in package context and log event with time elapsed
|
||||
|
||||
|
||||
@@ -203,12 +203,15 @@ class Client:
|
||||
"""
|
||||
# this method does not raise NotImplementedError because it is actively used as dummy client for http log
|
||||
|
||||
def package_logs_get(self, package_base: str, limit: int = -1, offset: int = 0) -> list[LogRecord]:
|
||||
def package_logs_get(self, package_base: str, version: str | None = None, process_id: str | None = None,
|
||||
limit: int = -1, offset: int = 0) -> list[LogRecord]:
|
||||
"""
|
||||
get package logs
|
||||
|
||||
Args:
|
||||
package_base(str): package base
|
||||
version(str | None, optional): package version to search (Default value = None)
|
||||
process_id(str | None, optional): process identifier to search (Default value = None)
|
||||
limit(int, optional): limit records to the specified count, -1 means unlimited (Default value = -1)
|
||||
offset(int, optional): records offset (Default value = 0)
|
||||
|
||||
|
||||
@@ -152,19 +152,22 @@ class LocalClient(Client):
|
||||
"""
|
||||
self.database.logs_insert(log_record, self.repository_id)
|
||||
|
||||
def package_logs_get(self, package_base: str, limit: int = -1, offset: int = 0) -> list[LogRecord]:
|
||||
def package_logs_get(self, package_base: str, version: str | None = None, process_id: str | None = None,
|
||||
limit: int = -1, offset: int = 0) -> list[LogRecord]:
|
||||
"""
|
||||
get package logs
|
||||
|
||||
Args:
|
||||
package_base(str): package base
|
||||
version(str | None, optional): package version to search (Default value = None)
|
||||
process_id(str | None, optional): process identifier to search (Default value = None)
|
||||
limit(int, optional): limit records to the specified count, -1 means unlimited (Default value = -1)
|
||||
offset(int, optional): records offset (Default value = 0)
|
||||
|
||||
Returns:
|
||||
list[LogRecord]: package logs
|
||||
"""
|
||||
return self.database.logs_get(package_base, limit, offset, self.repository_id)
|
||||
return self.database.logs_get(package_base, version, process_id, limit, offset, self.repository_id)
|
||||
|
||||
def package_logs_remove(self, package_base: str, version: str | None) -> None:
|
||||
"""
|
||||
|
||||
@@ -109,7 +109,7 @@ class Watcher(LazyLogging):
|
||||
|
||||
package_logs_add: Callable[[LogRecord], None]
|
||||
|
||||
package_logs_get: Callable[[str, int, int], list[LogRecord]]
|
||||
package_logs_get: Callable[[str, str | None, str | None, int, int], list[LogRecord]]
|
||||
|
||||
package_logs_remove: Callable[[str, str | None], None]
|
||||
|
||||
|
||||
@@ -326,12 +326,15 @@ class WebClient(Client, SyncAhrimanClient):
|
||||
self.make_request("POST", self._logs_url(log_record.log_record_id.package_base),
|
||||
params=self.repository_id.query(), json=payload, suppress_errors=True)
|
||||
|
||||
def package_logs_get(self, package_base: str, limit: int = -1, offset: int = 0) -> list[LogRecord]:
|
||||
def package_logs_get(self, package_base: str, version: str | None = None, process_id: str | None = None,
|
||||
limit: int = -1, offset: int = 0) -> list[LogRecord]:
|
||||
"""
|
||||
get package logs
|
||||
|
||||
Args:
|
||||
package_base(str): package base
|
||||
version(str | None, optional): package version to search (Default value = None)
|
||||
process_id(str | None, optional): process identifier to search (Default value = None)
|
||||
limit(int, optional): limit records to the specified count, -1 means unlimited (Default value = -1)
|
||||
offset(int, optional): records offset (Default value = 0)
|
||||
|
||||
@@ -339,6 +342,10 @@ class WebClient(Client, SyncAhrimanClient):
|
||||
list[LogRecord]: package logs
|
||||
"""
|
||||
query = self.repository_id.query() + [("limit", str(limit)), ("offset", str(offset))]
|
||||
if version is not None:
|
||||
query.append(("version", version))
|
||||
if process_id is not None:
|
||||
query.append(("process_id", process_id))
|
||||
|
||||
with contextlib.suppress(Exception):
|
||||
response = self.make_request("GET", self._logs_url(package_base), params=query)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import hashlib
|
||||
import itertools
|
||||
|
||||
from collections.abc import Callable, Iterator
|
||||
from collections.abc import Callable, Generator
|
||||
from pathlib import Path
|
||||
from typing import ClassVar
|
||||
|
||||
@@ -187,7 +187,7 @@ class PkgbuildGenerator:
|
||||
Returns:
|
||||
list[PkgbuildPatch]: list of patches to be applied to the PKGBUILD
|
||||
"""
|
||||
def sources_generator() -> Iterator[tuple[str, str]]:
|
||||
def sources_generator() -> Generator[tuple[str, str], None, None]:
|
||||
for source, generator in sorted(self.sources().items()):
|
||||
source_path = source_dir / source
|
||||
generator(source_path)
|
||||
|
||||
@@ -80,7 +80,8 @@ class Trigger(LazyLogging):
|
||||
return self.repository_id.architecture
|
||||
|
||||
@classmethod
|
||||
def configuration_schema(cls, configuration: Configuration | None) -> ConfigurationSchema:
|
||||
def configuration_schema(cls, repository_id: RepositoryId,
|
||||
configuration: Configuration | None) -> ConfigurationSchema:
|
||||
"""
|
||||
configuration schema based on supplied service configuration
|
||||
|
||||
@@ -88,6 +89,7 @@ class Trigger(LazyLogging):
|
||||
Schema must be in cerberus format, for details and examples you can check built-in triggers.
|
||||
|
||||
Args:
|
||||
repository_id(str): repository unique identifier
|
||||
configuration(Configuration | None): configuration instance. If set to None, the default schema
|
||||
should be returned
|
||||
|
||||
@@ -99,15 +101,13 @@ class Trigger(LazyLogging):
|
||||
|
||||
result: ConfigurationSchema = {}
|
||||
for target in cls.configuration_sections(configuration):
|
||||
for section in configuration.sections():
|
||||
if not (section == target or section.startswith(f"{target}:")):
|
||||
# either repository specific or exact name
|
||||
continue
|
||||
schema_name = configuration.get(section, "type", fallback=section)
|
||||
|
||||
if schema_name not in cls.CONFIGURATION_SCHEMA:
|
||||
continue
|
||||
result[section] = cls.CONFIGURATION_SCHEMA[schema_name]
|
||||
if not configuration.has_section(target):
|
||||
continue
|
||||
section, schema_name = configuration.gettype(
|
||||
target, repository_id, fallback=cls.CONFIGURATION_SCHEMA_FALLBACK)
|
||||
if schema_name not in cls.CONFIGURATION_SCHEMA:
|
||||
continue
|
||||
result[section] = cls.CONFIGURATION_SCHEMA[schema_name]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import contextlib
|
||||
import os
|
||||
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
from importlib import import_module, machinery
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
@@ -119,7 +119,7 @@ class TriggerLoader(LazyLogging):
|
||||
return configuration.getlist("build", "triggers", fallback=[])
|
||||
|
||||
@contextlib.contextmanager
|
||||
def __execute_trigger(self, trigger: Trigger) -> Iterator[None]:
|
||||
def __execute_trigger(self, trigger: Trigger) -> Generator[None, None, None]:
|
||||
"""
|
||||
decorator for calling triggers
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import re
|
||||
import selectors
|
||||
import subprocess
|
||||
|
||||
from collections.abc import Callable, Iterable, Iterator, Mapping
|
||||
from collections.abc import Callable, Generator, Iterable, Mapping
|
||||
from dataclasses import asdict
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
@@ -35,6 +35,7 @@ from pwd import getpwuid
|
||||
from typing import Any, IO, TypeVar
|
||||
|
||||
from ahriman.core.exceptions import CalledProcessError, OptionError, UnsafeRunError
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
|
||||
__all__ = [
|
||||
@@ -46,14 +47,12 @@ __all__ = [
|
||||
"filter_json",
|
||||
"full_version",
|
||||
"minmax",
|
||||
"owner",
|
||||
"package_like",
|
||||
"parse_version",
|
||||
"partition",
|
||||
"pretty_datetime",
|
||||
"pretty_size",
|
||||
"safe_filename",
|
||||
"safe_iterdir",
|
||||
"srcinfo_property",
|
||||
"srcinfo_property_list",
|
||||
"trim_package",
|
||||
@@ -113,7 +112,7 @@ def check_output(*args: str, exception: Exception | Callable[[int, list[str], st
|
||||
return channel if channel is not None else io.StringIO()
|
||||
|
||||
# wrapper around selectors polling
|
||||
def poll(sel: selectors.BaseSelector) -> Iterator[tuple[str, str]]:
|
||||
def poll(sel: selectors.BaseSelector) -> Generator[tuple[str, str], None, None]:
|
||||
for key, _ in sel.select(): # we don't need to check mask here because we have only subscribed on reading
|
||||
line = key.fileobj.readline() # type: ignore[union-attr]
|
||||
if not line: # in case of empty line we remove selector as there is no data here anymore
|
||||
@@ -170,13 +169,12 @@ def check_output(*args: str, exception: Exception | Callable[[int, list[str], st
|
||||
return stdout
|
||||
|
||||
|
||||
def check_user(root: Path, *, unsafe: bool) -> None:
|
||||
def check_user(paths: RepositoryPaths, *, unsafe: bool) -> None:
|
||||
"""
|
||||
check if current user is the owner of the root
|
||||
|
||||
Args:
|
||||
root(Path): path to root directory (e.g. repository root
|
||||
:attr:`ahriman.models.repository_paths.RepositoryPaths.root`)
|
||||
paths(RepositoryPaths): repository paths object
|
||||
unsafe(bool): if set no user check will be performed before path creation
|
||||
|
||||
Raises:
|
||||
@@ -185,16 +183,14 @@ def check_user(root: Path, *, unsafe: bool) -> None:
|
||||
Examples:
|
||||
Simply run function with arguments::
|
||||
|
||||
>>> check_user(root, unsafe=False)
|
||||
>>> check_user(paths, unsafe=False)
|
||||
"""
|
||||
if not root.exists():
|
||||
if not paths.root.exists():
|
||||
return # no directory found, skip check
|
||||
if unsafe:
|
||||
return # unsafe flag is enabled, no check performed
|
||||
|
||||
current_uid = os.getuid()
|
||||
root_uid, _ = owner(root)
|
||||
|
||||
root_uid, _ = paths.root_owner
|
||||
if current_uid != root_uid:
|
||||
raise UnsafeRunError(current_uid, root_uid)
|
||||
|
||||
@@ -292,20 +288,6 @@ def minmax(source: Iterable[T], *, key: Callable[[T], Any] | None = None) -> tup
|
||||
return min(first_iter, key=key), max(second_iter, key=key) # type: ignore
|
||||
|
||||
|
||||
def owner(path: Path) -> tuple[int, int]:
|
||||
"""
|
||||
retrieve owner information by path
|
||||
|
||||
Args:
|
||||
path(Path): path for which extract ids
|
||||
|
||||
Returns:
|
||||
tuple[int, int]: owner user and group ids of the directory
|
||||
"""
|
||||
stat = path.stat()
|
||||
return stat.st_uid, stat.st_gid
|
||||
|
||||
|
||||
def package_like(filename: Path) -> bool:
|
||||
"""
|
||||
check if file looks like package
|
||||
@@ -426,22 +408,6 @@ def safe_filename(source: str) -> str:
|
||||
return re.sub(r"[^A-Za-z\d\-._~:\[\]@]", "-", source)
|
||||
|
||||
|
||||
def safe_iterdir(path: Path) -> Iterator[Path]:
|
||||
"""
|
||||
wrapper around :func:`pathlib.Path.iterdir`, which suppresses :exc:`PermissionError`
|
||||
|
||||
Args:
|
||||
path(Path): path to iterate
|
||||
|
||||
Yields:
|
||||
Path: content of the directory
|
||||
"""
|
||||
try:
|
||||
yield from path.iterdir()
|
||||
except PermissionError:
|
||||
pass
|
||||
|
||||
|
||||
def srcinfo_property(key: str, srcinfo: Mapping[str, Any], package_srcinfo: Mapping[str, Any], *,
|
||||
default: Any = None) -> Any:
|
||||
"""
|
||||
@@ -510,7 +476,7 @@ def utcnow() -> datetime.datetime:
|
||||
return datetime.datetime.now(datetime.UTC)
|
||||
|
||||
|
||||
def walk(directory_path: Path) -> Iterator[Path]:
|
||||
def walk(directory_path: Path) -> Generator[Path, None, None]:
|
||||
"""
|
||||
list all file paths in given directory
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ from dataclasses import dataclass, field, fields
|
||||
from pyalpm import Package # type: ignore[import-not-found]
|
||||
from typing import Any, Self
|
||||
|
||||
from ahriman.core.utils import filter_json, full_version, trim_package
|
||||
from ahriman.core.utils import filter_json, full_version
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@@ -103,17 +103,6 @@ class AURPackage:
|
||||
keywords: list[str] = field(default_factory=list)
|
||||
groups: list[str] = field(default_factory=list)
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
"""
|
||||
update packages lists accordingly
|
||||
"""
|
||||
object.__setattr__(self, "depends", [trim_package(package) for package in self.depends])
|
||||
object.__setattr__(self, "make_depends", [trim_package(package) for package in self.make_depends])
|
||||
object.__setattr__(self, "opt_depends", [trim_package(package) for package in self.opt_depends])
|
||||
object.__setattr__(self, "check_depends", [trim_package(package) for package in self.check_depends])
|
||||
object.__setattr__(self, "conflicts", [trim_package(package) for package in self.conflicts])
|
||||
object.__setattr__(self, "provides", [trim_package(package) for package in self.provides])
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, dump: dict[str, Any]) -> Self:
|
||||
"""
|
||||
|
||||
@@ -22,7 +22,7 @@ from __future__ import annotations
|
||||
|
||||
import copy
|
||||
|
||||
from collections.abc import Callable, Iterable, Iterator
|
||||
from collections.abc import Callable, Generator, Iterable
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from pyalpm import vercmp # type: ignore[import-not-found]
|
||||
@@ -205,7 +205,7 @@ class Package(LazyLogging):
|
||||
package = pacman.handle.load_pkg(str(path))
|
||||
description = PackageDescription.from_package(package, path)
|
||||
return cls(
|
||||
base=package.base or package.name,
|
||||
base=package.base,
|
||||
version=package.version,
|
||||
remote=RemoteSource(source=PackageSource.Archive),
|
||||
packages={package.name: description},
|
||||
@@ -346,7 +346,7 @@ class Package(LazyLogging):
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def local_files(path: Path) -> Iterator[Path]:
|
||||
def local_files(path: Path) -> Generator[Path, None, None]:
|
||||
"""
|
||||
extract list of local files
|
||||
|
||||
@@ -407,7 +407,7 @@ class Package(LazyLogging):
|
||||
Returns:
|
||||
list[str]: combined list of unique entries in properties list
|
||||
"""
|
||||
def generator() -> Iterator[str]:
|
||||
def generator() -> Generator[str, None, None]:
|
||||
for package in self.packages.values():
|
||||
yield from extractor(package)
|
||||
|
||||
@@ -570,7 +570,7 @@ class Package(LazyLogging):
|
||||
"""
|
||||
return dataclass_view(self)
|
||||
|
||||
def with_packages(self, packages: Iterable[Path], pacman: Pacman) -> None:
|
||||
def with_packages(self, packages: list[Path], pacman: Pacman) -> None:
|
||||
"""
|
||||
replace packages descriptions with ones from archives
|
||||
|
||||
|
||||
@@ -83,13 +83,12 @@ class PackageDescription:
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
"""
|
||||
update packages lists accordingly
|
||||
update dependencies list accordingly
|
||||
"""
|
||||
self.depends = [trim_package(package) for package in self.depends]
|
||||
self.make_depends = [trim_package(package) for package in self.make_depends]
|
||||
self.opt_depends = [trim_package(package) for package in self.opt_depends]
|
||||
self.make_depends = [trim_package(package) for package in self.make_depends]
|
||||
self.check_depends = [trim_package(package) for package in self.check_depends]
|
||||
self.provides = [trim_package(package) for package in self.provides]
|
||||
|
||||
@property
|
||||
def filepath(self) -> Path | None:
|
||||
|
||||
@@ -22,7 +22,7 @@ import shlex
|
||||
|
||||
from dataclasses import dataclass, fields
|
||||
from pathlib import Path
|
||||
from typing import Any, Iterator, Self
|
||||
from typing import Any, Generator, Self
|
||||
|
||||
from ahriman.core.configuration.shell_template import ShellTemplate
|
||||
from ahriman.core.utils import dataclass_view, filter_json
|
||||
@@ -166,7 +166,7 @@ class PkgbuildPatch:
|
||||
ValueError: if no closing quotation
|
||||
"""
|
||||
|
||||
def generator() -> Iterator[str]:
|
||||
def generator() -> Generator[str, None, None]:
|
||||
token = None
|
||||
for char in source:
|
||||
if token is not None:
|
||||
|
||||
@@ -17,11 +17,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import contextlib
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
from dataclasses import dataclass, field
|
||||
from functools import cached_property
|
||||
from pathlib import Path
|
||||
@@ -29,7 +28,6 @@ from pwd import getpwuid
|
||||
|
||||
from ahriman.core.exceptions import PathError
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.core.utils import owner, safe_iterdir
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
||||
@@ -94,7 +92,7 @@ class RepositoryPaths(LazyLogging):
|
||||
Returns:
|
||||
Path: path to directory in which build process is run
|
||||
"""
|
||||
uid, _ = owner(self.root)
|
||||
uid, _ = self.owner(self.root)
|
||||
return self.chroot / f"{self.repository_id.name}-{self.repository_id.architecture}" / getpwuid(uid).pw_name
|
||||
|
||||
@property
|
||||
@@ -156,7 +154,7 @@ class RepositoryPaths(LazyLogging):
|
||||
Returns:
|
||||
tuple[int, int]: owner user and group of the root directory
|
||||
"""
|
||||
return owner(self.root)
|
||||
return self.owner(self.root)
|
||||
|
||||
# pylint: disable=protected-access
|
||||
@classmethod
|
||||
@@ -171,7 +169,7 @@ class RepositoryPaths(LazyLogging):
|
||||
Returns:
|
||||
set[str]: list of repository architectures for which there is created tree
|
||||
"""
|
||||
def walk(repository_dir: Path) -> Iterator[str]:
|
||||
def walk(repository_dir: Path) -> Generator[str, None, None]:
|
||||
for architecture in filter(lambda path: path.is_dir(), repository_dir.iterdir()):
|
||||
yield architecture.name
|
||||
|
||||
@@ -198,7 +196,7 @@ class RepositoryPaths(LazyLogging):
|
||||
is loaded in legacy mode
|
||||
"""
|
||||
# simply walk through the root. In case if there are subdirectories, emit the name
|
||||
def walk(paths: RepositoryPaths) -> Iterator[str]:
|
||||
def walk(paths: RepositoryPaths) -> Generator[str, None, None]:
|
||||
for repository in filter(lambda path: path.is_dir(), paths._repository_root.iterdir()):
|
||||
if any(path.is_dir() for path in repository.iterdir()):
|
||||
yield repository.name
|
||||
@@ -209,32 +207,19 @@ class RepositoryPaths(LazyLogging):
|
||||
|
||||
return set(walk(instance))
|
||||
|
||||
def _chown(self, path: Path) -> None:
|
||||
@staticmethod
|
||||
def owner(path: Path) -> tuple[int, int]:
|
||||
"""
|
||||
set owner of path recursively (from root) to root owner
|
||||
|
||||
Notes:
|
||||
More likely you don't want to call this method explicitly, consider using :func:`preserve_owner`
|
||||
as context manager instead
|
||||
retrieve owner information by path
|
||||
|
||||
Args:
|
||||
path(Path): path to be chown
|
||||
path(Path): path for which extract ids
|
||||
|
||||
Raises:
|
||||
PathError: if path does not belong to root
|
||||
Returns:
|
||||
tuple[int, int]: owner user and group ids of the directory
|
||||
"""
|
||||
def set_owner(current: Path) -> None:
|
||||
uid, gid = owner(current)
|
||||
if uid == root_uid and gid == root_gid:
|
||||
return
|
||||
os.chown(current, root_uid, root_gid, follow_symlinks=False)
|
||||
|
||||
if self.root not in path.parents:
|
||||
raise PathError(path, self.root)
|
||||
root_uid, root_gid = self.root_owner
|
||||
while path != self.root:
|
||||
set_owner(path)
|
||||
path = path.parent
|
||||
stat = path.stat()
|
||||
return stat.st_uid, stat.st_gid
|
||||
|
||||
def cache_for(self, package_base: str) -> Path:
|
||||
"""
|
||||
@@ -248,43 +233,28 @@ class RepositoryPaths(LazyLogging):
|
||||
"""
|
||||
return self.cache / package_base
|
||||
|
||||
@contextlib.contextmanager
|
||||
def preserve_owner(self, path: Path | None = None) -> Iterator[None]:
|
||||
def chown(self, path: Path) -> None:
|
||||
"""
|
||||
perform any action preserving owner for any newly created file or directory
|
||||
set owner of path recursively (from root) to root owner
|
||||
|
||||
Args:
|
||||
path(Path | None, optional): use this path as root instead of repository root (Default value = None)
|
||||
path(Path): path to be chown
|
||||
|
||||
Examples:
|
||||
This method is designed to use as context manager when you are going to perform operations which might
|
||||
change filesystem, especially if you are doing it under unsafe flag, e.g.::
|
||||
|
||||
>>> with paths.preserve_owner():
|
||||
>>> paths.tree_create()
|
||||
|
||||
Note, however, that this method doesn't handle any exceptions and will eventually interrupt
|
||||
if there will be any.
|
||||
Raises:
|
||||
PathError: if path does not belong to root
|
||||
"""
|
||||
path = path or self.root
|
||||
def set_owner(current: Path) -> None:
|
||||
uid, gid = self.owner(current)
|
||||
if uid == root_uid and gid == root_gid:
|
||||
return
|
||||
os.chown(current, root_uid, root_gid, follow_symlinks=False)
|
||||
|
||||
def walk(root: Path) -> Iterator[Path]:
|
||||
# basically walk, but skipping some content
|
||||
for child in safe_iterdir(root):
|
||||
yield child
|
||||
if child in (self.chroot.parent,):
|
||||
yield from safe_iterdir(child) # we only yield top-level in chroot directory
|
||||
elif child.is_dir():
|
||||
yield from walk(child)
|
||||
|
||||
# get current filesystem and run action
|
||||
previous_snapshot = set(walk(path))
|
||||
yield
|
||||
|
||||
# get newly created files and directories and chown them
|
||||
new_entries = set(walk(path)).difference(previous_snapshot)
|
||||
for entry in new_entries:
|
||||
self._chown(entry)
|
||||
if self.root not in path.parents:
|
||||
raise PathError(path, self.root)
|
||||
root_uid, root_gid = self.root_owner
|
||||
while path != self.root:
|
||||
set_owner(path)
|
||||
path = path.parent
|
||||
|
||||
def tree_clear(self, package_base: str) -> None:
|
||||
"""
|
||||
@@ -304,13 +274,12 @@ class RepositoryPaths(LazyLogging):
|
||||
"""
|
||||
if self.repository_id.is_empty:
|
||||
return # do not even try to create tree in case if no repository id set
|
||||
|
||||
with self.preserve_owner():
|
||||
for directory in (
|
||||
self.cache,
|
||||
self.chroot,
|
||||
self.packages,
|
||||
self.pacman,
|
||||
self.repository,
|
||||
):
|
||||
directory.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
for directory in (
|
||||
self.cache,
|
||||
self.chroot,
|
||||
self.packages,
|
||||
self.pacman,
|
||||
self.repository,
|
||||
):
|
||||
directory.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
self.chown(directory)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import re
|
||||
|
||||
from aiohttp.web import Application, View
|
||||
from collections.abc import Iterator
|
||||
from collections.abc import Generator
|
||||
|
||||
import ahriman.web.views
|
||||
|
||||
@@ -32,7 +32,7 @@ from ahriman.web.views.base import BaseView
|
||||
__all__ = ["setup_routes"]
|
||||
|
||||
|
||||
def _dynamic_routes(configuration: Configuration) -> Iterator[tuple[str, type[View]]]:
|
||||
def _dynamic_routes(configuration: Configuration) -> Generator[tuple[str, type[View]], None, None]:
|
||||
"""
|
||||
extract dynamic routes based on views
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ from ahriman.web.schemas.log_schema import LogSchema
|
||||
from ahriman.web.schemas.login_schema import LoginSchema
|
||||
from ahriman.web.schemas.logs_rotate_schema import LogsRotateSchema
|
||||
from ahriman.web.schemas.logs_schema import LogsSchema
|
||||
from ahriman.web.schemas.logs_search_schema import LogsSearchSchema
|
||||
from ahriman.web.schemas.oauth2_schema import OAuth2Schema
|
||||
from ahriman.web.schemas.package_name_schema import PackageNameSchema
|
||||
from ahriman.web.schemas.package_names_schema import PackageNamesSchema
|
||||
|
||||
36
src/ahriman/web/schemas/logs_search_schema.py
Normal file
36
src/ahriman/web/schemas/logs_search_schema.py
Normal file
@@ -0,0 +1,36 @@
|
||||
#
|
||||
# Copyright (c) 2021-2025 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from ahriman import __version__
|
||||
from ahriman.web.apispec import fields
|
||||
from ahriman.web.schemas.pagination_schema import PaginationSchema
|
||||
|
||||
|
||||
class LogsSearchSchema(PaginationSchema):
|
||||
"""
|
||||
request log search schema
|
||||
"""
|
||||
|
||||
version = fields.String(metadata={
|
||||
"description": "Package version to search",
|
||||
"example": __version__,
|
||||
})
|
||||
process_id = fields.String(metadata={
|
||||
"description": "Process unique identifier to search",
|
||||
})
|
||||
@@ -90,7 +90,7 @@ class LogsView(StatusViewGuard, BaseView):
|
||||
|
||||
try:
|
||||
_, status = self.service().package_get(package_base)
|
||||
logs = self.service(package_base=package_base).package_logs_get(package_base, -1, 0)
|
||||
logs = self.service(package_base=package_base).package_logs_get(package_base, None, None, -1, 0)
|
||||
except UnknownPackageError:
|
||||
raise HTTPNotFound(reason=f"Package {package_base} is unknown")
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ from typing import ClassVar
|
||||
|
||||
from ahriman.models.user_access import UserAccess
|
||||
from ahriman.web.apispec.decorators import apidocs
|
||||
from ahriman.web.schemas import LogSchema, PackageNameSchema, PaginationSchema
|
||||
from ahriman.web.schemas import LogSchema, LogsSearchSchema, PackageNameSchema
|
||||
from ahriman.web.views.base import BaseView
|
||||
from ahriman.web.views.status_view_guard import StatusViewGuard
|
||||
|
||||
@@ -47,7 +47,7 @@ class LogsView(StatusViewGuard, BaseView):
|
||||
error_404_description="Package base and/or repository are unknown",
|
||||
schema=LogSchema(many=True),
|
||||
match_schema=PackageNameSchema,
|
||||
query_schema=PaginationSchema,
|
||||
query_schema=LogsSearchSchema,
|
||||
)
|
||||
async def get(self) -> Response:
|
||||
"""
|
||||
@@ -61,8 +61,10 @@ class LogsView(StatusViewGuard, BaseView):
|
||||
"""
|
||||
package_base = self.request.match_info["package"]
|
||||
limit, offset = self.page()
|
||||
version = self.request.query.get("version", None)
|
||||
process = self.request.query.get("process_id", None)
|
||||
|
||||
logs = self.service(package_base=package_base).package_logs_get(package_base, limit, offset)
|
||||
logs = self.service(package_base=package_base).package_logs_get(package_base, version, process, limit, offset)
|
||||
|
||||
response = [log_record.view() for log_record in logs]
|
||||
return json_response(response)
|
||||
|
||||
@@ -166,16 +166,11 @@ def setup_server(configuration: Configuration, spawner: Spawn, repositories: lis
|
||||
# package cache
|
||||
if not repositories:
|
||||
raise InitializeError("No repositories configured, exiting")
|
||||
database = SQLite.load(configuration)
|
||||
watchers: dict[RepositoryId, Watcher] = {}
|
||||
configuration_path, _ = configuration.check_loaded()
|
||||
for repository_id in repositories:
|
||||
application.logger.info("load repository %s", repository_id)
|
||||
# load settings explicitly for architecture if any
|
||||
repository_configuration = Configuration.from_path(configuration_path, repository_id)
|
||||
# load database instance, because it holds identifier
|
||||
database = SQLite.load(repository_configuration)
|
||||
# explicitly load local client
|
||||
client = Client.load(repository_id, repository_configuration, database, report=False)
|
||||
client = Client.load(repository_id, configuration, database, report=False) # explicitly load local client
|
||||
watchers[repository_id] = Watcher(client)
|
||||
application[WatcherKey] = watchers
|
||||
# workers cache
|
||||
@@ -184,7 +179,6 @@ def setup_server(configuration: Configuration, spawner: Spawn, repositories: lis
|
||||
application[SpawnKey] = spawner
|
||||
|
||||
application.logger.info("setup authorization")
|
||||
database = SQLite.load(configuration)
|
||||
validator = application[AuthKey] = Auth.load(configuration, database)
|
||||
if validator.enabled:
|
||||
from ahriman.web.middlewares.auth_handler import setup_auth
|
||||
|
||||
@@ -58,11 +58,9 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
||||
sudo_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_sudo")
|
||||
executable_mock = mocker.patch("ahriman.application.handlers.setup.Setup.executable_create")
|
||||
init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init")
|
||||
owner_guard_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.preserve_owner")
|
||||
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Setup.run(args, repository_id, configuration, report=False)
|
||||
owner_guard_mock.assert_called_once_with()
|
||||
ahriman_configuration_mock.assert_called_once_with(args, repository_id, configuration)
|
||||
devtools_configuration_mock.assert_called_once_with(
|
||||
repository_id, args.from_configuration, args.mirror, args.multilib, f"file://{repository_paths.repository}")
|
||||
@@ -270,11 +268,13 @@ def test_executable_create(configuration: Configuration, repository_paths: Repos
|
||||
"""
|
||||
must create executable
|
||||
"""
|
||||
chown_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.chown")
|
||||
symlink_mock = mocker.patch("pathlib.Path.symlink_to")
|
||||
unlink_mock = mocker.patch("pathlib.Path.unlink")
|
||||
|
||||
_, repository_id = configuration.check_loaded()
|
||||
Setup.executable_create(repository_paths, repository_id)
|
||||
chown_mock.assert_called_once_with(Setup.build_command(repository_paths.root, repository_id))
|
||||
symlink_mock.assert_called_once_with(Setup.ARCHBUILD_COMMAND_PATH)
|
||||
unlink_mock.assert_called_once_with(missing_ok=True)
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import argparse
|
||||
import json
|
||||
import pytest
|
||||
|
||||
from pathlib import Path
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.application.handlers.validate import Validate
|
||||
@@ -54,50 +53,12 @@ def test_run_skip(args: argparse.Namespace, configuration: Configuration, mocker
|
||||
print_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_run_default(args: argparse.Namespace, configuration: Configuration) -> None:
|
||||
"""
|
||||
must run on default configuration without errors
|
||||
"""
|
||||
args.exit_code = True
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
default = Configuration.from_path(Configuration.SYSTEM_CONFIGURATION_PATH, repository_id)
|
||||
# copy autogenerated values
|
||||
for section, key in (("build", "build_command"), ("repository", "root")):
|
||||
value = configuration.get(section, key)
|
||||
default.set_option(section, key, value)
|
||||
|
||||
Validate.run(args, repository_id, default, report=False)
|
||||
|
||||
|
||||
def test_run_repo_specific_triggers(args: argparse.Namespace, configuration: Configuration,
|
||||
resource_path_root: Path) -> None:
|
||||
"""
|
||||
must correctly insert repo specific triggers
|
||||
"""
|
||||
args.exit_code = True
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
# remove unused sections
|
||||
for section in ("customs3", "github:x86_64", "logs-rotation", "mirrorlist"):
|
||||
configuration.remove_section(section)
|
||||
|
||||
configuration.set_option("report", "target", "test")
|
||||
for section in ("test", "test:i686", "test:another-repo:x86_64"):
|
||||
configuration.set_option(section, "type", "html")
|
||||
configuration.set_option(section, "link_path", "http://link_path")
|
||||
configuration.set_option(section, "path", "path")
|
||||
configuration.set_option(section, "template", "template")
|
||||
configuration.set_option(section, "templates", str(resource_path_root))
|
||||
|
||||
Validate.run(args, repository_id, configuration, report=False)
|
||||
|
||||
|
||||
def test_schema(configuration: Configuration) -> None:
|
||||
"""
|
||||
must generate full schema correctly
|
||||
"""
|
||||
schema = Validate.schema(configuration)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
schema = Validate.schema(repository_id, configuration)
|
||||
|
||||
# defaults
|
||||
assert schema.pop("console")
|
||||
@@ -130,7 +91,9 @@ def test_schema_invalid_trigger(configuration: Configuration) -> None:
|
||||
"""
|
||||
configuration.set_option("build", "triggers", "some.invalid.trigger.path.Trigger")
|
||||
configuration.remove_option("build", "triggers_known")
|
||||
assert Validate.schema(configuration) == CONFIGURATION_SCHEMA
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
assert Validate.schema(repository_id, configuration) == CONFIGURATION_SCHEMA
|
||||
|
||||
|
||||
def test_schema_erase_required() -> None:
|
||||
|
||||
@@ -142,7 +142,7 @@ def test_check_user(lock: Lock, mocker: MockerFixture) -> None:
|
||||
tree_create = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
|
||||
|
||||
lock.check_user()
|
||||
check_user_patch.assert_called_once_with(lock.paths.root, unsafe=False)
|
||||
check_user_patch.assert_called_once_with(lock.paths, unsafe=False)
|
||||
tree_create.assert_called_once_with()
|
||||
|
||||
|
||||
|
||||
@@ -62,12 +62,12 @@ def test_database_copy(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||
mocker.patch("pathlib.Path.is_file", autospec=True, side_effect=lambda p: p.is_relative_to(path))
|
||||
mkdir_mock = mocker.patch("pathlib.Path.mkdir")
|
||||
copy_mock = mocker.patch("shutil.copy")
|
||||
owner_guard_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.preserve_owner")
|
||||
chown_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.chown")
|
||||
|
||||
pacman.database_copy(pacman.handle, database, path, use_ahriman_cache=True)
|
||||
mkdir_mock.assert_called_once_with(mode=0o755, exist_ok=True)
|
||||
copy_mock.assert_called_once_with(path / "sync" / "core.db", dst_path)
|
||||
owner_guard_mock.assert_called_once_with(dst_path.parent)
|
||||
chown_mock.assert_called_once_with(dst_path)
|
||||
|
||||
|
||||
def test_database_copy_skip(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||
@@ -289,4 +289,3 @@ def test_package_provided_by(pacman: Pacman) -> None:
|
||||
must search through the provides lists
|
||||
"""
|
||||
assert list(pacman.provided_by("sh"))
|
||||
assert list(pacman.provided_by("libacl.so")) # case with exact version
|
||||
|
||||
@@ -20,40 +20,6 @@ def test_architecture(configuration: Configuration) -> None:
|
||||
assert configuration.architecture == "x86_64"
|
||||
|
||||
|
||||
def test_repository_id(configuration: Configuration, repository_id: RepositoryId) -> None:
|
||||
"""
|
||||
must return repository identifier
|
||||
"""
|
||||
assert configuration.repository_id == repository_id
|
||||
assert configuration.get("repository", "name") == repository_id.name
|
||||
assert configuration.get("repository", "architecture") == repository_id.architecture
|
||||
|
||||
|
||||
def test_repository_id_erase(configuration: Configuration) -> None:
|
||||
"""
|
||||
must remove repository identifier properties if empty identifier supplied
|
||||
"""
|
||||
configuration.repository_id = None
|
||||
assert configuration.get("repository", "name", fallback=None) is None
|
||||
assert configuration.get("repository", "architecture", fallback=None) is None
|
||||
|
||||
configuration.repository_id = RepositoryId("", "")
|
||||
assert configuration.get("repository", "name", fallback=None) is None
|
||||
assert configuration.get("repository", "architecture", fallback=None) is None
|
||||
|
||||
|
||||
def test_repository_id_update(configuration: Configuration, repository_id: RepositoryId) -> None:
|
||||
"""
|
||||
must update repository identifier and related configuration options
|
||||
"""
|
||||
repository_id = RepositoryId("i686", repository_id.name)
|
||||
|
||||
configuration.repository_id = repository_id
|
||||
assert configuration.repository_id == repository_id
|
||||
assert configuration.get("repository", "name") == repository_id.name
|
||||
assert configuration.get("repository", "architecture") == repository_id.architecture
|
||||
|
||||
|
||||
def test_repository_name(configuration: Configuration) -> None:
|
||||
"""
|
||||
must return valid repository name
|
||||
|
||||
@@ -71,11 +71,35 @@ def test_logs_insert_get_pagination(database: SQLite, package_ahriman: Package)
|
||||
"""
|
||||
database.logs_insert(LogRecord(LogRecordId(package_ahriman.base, "1"), 42.0, "message 1"))
|
||||
database.logs_insert(LogRecord(LogRecordId(package_ahriman.base, "1"), 43.0, "message 2"))
|
||||
assert database.logs_get(package_ahriman.base, 1, 1) == [
|
||||
assert database.logs_get(package_ahriman.base, None, None, 1, 1) == [
|
||||
LogRecord(LogRecordId(package_ahriman.base, "1"), 42.0, "message 1"),
|
||||
]
|
||||
|
||||
|
||||
def test_logs_insert_get_filter_by_version(database: SQLite, package_ahriman: Package) -> None:
|
||||
"""
|
||||
must insert and get package logs with pagination
|
||||
"""
|
||||
database.logs_insert(LogRecord(LogRecordId(package_ahriman.base, "1", "p1"), 42.0, "message 1"))
|
||||
database.logs_insert(LogRecord(LogRecordId(package_ahriman.base, "1", "p2"), 43.0, "message 2"))
|
||||
database.logs_insert(LogRecord(LogRecordId(package_ahriman.base, "2", "p1"), 44.0, "message 3"))
|
||||
|
||||
assert database.logs_get(package_ahriman.base, "1", None) == [
|
||||
LogRecord(LogRecordId(package_ahriman.base, "1", "p1"), 42.0, "message 1"),
|
||||
LogRecord(LogRecordId(package_ahriman.base, "1", "p2"), 43.0, "message 2"),
|
||||
]
|
||||
assert database.logs_get(package_ahriman.base, "2", None) == [
|
||||
LogRecord(LogRecordId(package_ahriman.base, "2", "p1"), 44.0, "message 3"),
|
||||
]
|
||||
assert database.logs_get(package_ahriman.base, None, "p1") == [
|
||||
LogRecord(LogRecordId(package_ahriman.base, "1", "p1"), 42.0, "message 1"),
|
||||
LogRecord(LogRecordId(package_ahriman.base, "2", "p1"), 44.0, "message 3"),
|
||||
]
|
||||
assert database.logs_get(package_ahriman.base, "1", "p1") == [
|
||||
LogRecord(LogRecordId(package_ahriman.base, "1", "p1"), 42.0, "message 1"),
|
||||
]
|
||||
|
||||
|
||||
def test_logs_insert_get_multi(database: SQLite, package_ahriman: Package) -> None:
|
||||
"""
|
||||
must insert and get package logs for multiple repositories
|
||||
|
||||
@@ -36,17 +36,6 @@ def test_init_skip_migration(database: SQLite, mocker: MockerFixture) -> None:
|
||||
migrate_schema_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_init_skip_empty_repository(database: SQLite, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must skip migrations if repository identifier is not set
|
||||
"""
|
||||
database._repository_id = RepositoryId("", "")
|
||||
migrate_schema_mock = mocker.patch("ahriman.core.database.migrations.Migrations.migrate")
|
||||
|
||||
database.init()
|
||||
migrate_schema_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_package_clear(database: SQLite, repository_id: RepositoryId, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must clear package data
|
||||
|
||||
@@ -124,8 +124,9 @@ def test_package_logs_get(local_client: LocalClient, package_ahriman: Package, m
|
||||
must retrieve package logs
|
||||
"""
|
||||
logs_mock = mocker.patch("ahriman.core.database.SQLite.logs_get")
|
||||
local_client.package_logs_get(package_ahriman.base, 1, 2)
|
||||
logs_mock.assert_called_once_with(package_ahriman.base, 1, 2, local_client.repository_id)
|
||||
local_client.package_logs_get(package_ahriman.base, package_ahriman.version, "process", 1, 2)
|
||||
logs_mock.assert_called_once_with(package_ahriman.base, package_ahriman.version, "process", 1, 2,
|
||||
local_client.repository_id)
|
||||
|
||||
|
||||
def test_package_logs_remove(local_client: LocalClient, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
|
||||
@@ -658,7 +658,7 @@ def test_package_logs_get(web_client: WebClient, package_ahriman: Package, mocke
|
||||
|
||||
requests_mock = mocker.patch("ahriman.core.status.web_client.WebClient.make_request", return_value=response_obj)
|
||||
|
||||
result = web_client.package_logs_get(package_ahriman.base, 1, 2)
|
||||
result = web_client.package_logs_get(package_ahriman.base, None, None, 1, 2)
|
||||
requests_mock.assert_called_once_with("GET", pytest.helpers.anyvar(str, True),
|
||||
params=web_client.repository_id.query() + [("limit", "1"), ("offset", "2")])
|
||||
assert result == [
|
||||
@@ -666,6 +666,21 @@ def test_package_logs_get(web_client: WebClient, package_ahriman: Package, mocke
|
||||
]
|
||||
|
||||
|
||||
def test_package_logs_get_filter(web_client: WebClient, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must get logs with version and process id filter
|
||||
"""
|
||||
requests_mock = mocker.patch("ahriman.core.status.web_client.WebClient.make_request")
|
||||
web_client.package_logs_get(package_ahriman.base, package_ahriman.version, LogRecordId.DEFAULT_PROCESS_ID, 1, 2)
|
||||
requests_mock.assert_called_once_with("GET", pytest.helpers.anyvar(str, True),
|
||||
params=web_client.repository_id.query() + [
|
||||
("limit", "1"),
|
||||
("offset", "2"),
|
||||
("version", package_ahriman.version),
|
||||
("process_id", LogRecordId.DEFAULT_PROCESS_ID),
|
||||
])
|
||||
|
||||
|
||||
def test_package_logs_get_failed(web_client: WebClient, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must suppress any exception happened during logs fetch
|
||||
|
||||
@@ -6,10 +6,12 @@ import pytest
|
||||
from pathlib import Path
|
||||
from pytest_mock import MockerFixture
|
||||
from typing import Any
|
||||
from unittest.mock import MagicMock, call as MockCall
|
||||
from unittest.mock import call as MockCall
|
||||
|
||||
from ahriman.core.exceptions import BuildError, CalledProcessError, OptionError, UnsafeRunError
|
||||
from ahriman.core.utils import *
|
||||
from ahriman.core.utils import check_output, check_user, dataclass_view, enum_values, extract_user, filter_json, \
|
||||
full_version, minmax, package_like, parse_version, partition, pretty_datetime, pretty_size, safe_filename, \
|
||||
srcinfo_property, srcinfo_property_list, trim_package, utcnow, walk
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.package_source import PackageSource
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
@@ -161,7 +163,7 @@ def test_check_user(repository_id: RepositoryId, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
paths = RepositoryPaths(Path.cwd(), repository_id)
|
||||
mocker.patch("os.getuid", return_value=paths.root_owner[0])
|
||||
check_user(paths.root, unsafe=False)
|
||||
check_user(paths, unsafe=False)
|
||||
|
||||
|
||||
def test_check_user_no_directory(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
@@ -169,7 +171,7 @@ def test_check_user_no_directory(repository_paths: RepositoryPaths, mocker: Mock
|
||||
must not fail in case if no directory found
|
||||
"""
|
||||
mocker.patch("pathlib.Path.exists", return_value=False)
|
||||
check_user(repository_paths.root, unsafe=False)
|
||||
check_user(repository_paths, unsafe=False)
|
||||
|
||||
|
||||
def test_check_user_exception(repository_id: RepositoryId, mocker: MockerFixture) -> None:
|
||||
@@ -180,7 +182,7 @@ def test_check_user_exception(repository_id: RepositoryId, mocker: MockerFixture
|
||||
mocker.patch("os.getuid", return_value=paths.root_owner[0] + 1)
|
||||
|
||||
with pytest.raises(UnsafeRunError):
|
||||
check_user(paths.root, unsafe=False)
|
||||
check_user(paths, unsafe=False)
|
||||
|
||||
|
||||
def test_check_user_unsafe(repository_id: RepositoryId, mocker: MockerFixture) -> None:
|
||||
@@ -189,7 +191,7 @@ def test_check_user_unsafe(repository_id: RepositoryId, mocker: MockerFixture) -
|
||||
"""
|
||||
paths = RepositoryPaths(Path.cwd(), repository_id)
|
||||
mocker.patch("os.getuid", return_value=paths.root_owner[0] + 1)
|
||||
check_user(paths.root, unsafe=True)
|
||||
check_user(paths, unsafe=True)
|
||||
|
||||
|
||||
def test_dataclass_view(package_ahriman: Package) -> None:
|
||||
@@ -273,18 +275,6 @@ def test_minmax() -> None:
|
||||
assert minmax([[1, 2, 3], [4, 5], [6, 7, 8, 9]], key=len) == ([4, 5], [6, 7, 8, 9])
|
||||
|
||||
|
||||
def test_owner(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must correctly retrieve owner of the path
|
||||
"""
|
||||
stat_mock = MagicMock()
|
||||
stat_mock.st_uid = 42
|
||||
stat_mock.st_gid = 142
|
||||
mocker.patch("pathlib.Path.stat", return_value=stat_mock)
|
||||
|
||||
assert owner(repository_paths.root) == (42, 142)
|
||||
|
||||
|
||||
def test_package_like(package_ahriman: Package) -> None:
|
||||
"""
|
||||
package_like must return true for archives
|
||||
@@ -424,17 +414,6 @@ def test_safe_filename() -> None:
|
||||
assert safe_filename("tolua++-1.0.93-4-x86_64.pkg.tar.zst") == "tolua---1.0.93-4-x86_64.pkg.tar.zst"
|
||||
|
||||
|
||||
def test_safe_iterdir(mocker: MockerFixture, resource_path_root: Path) -> None:
|
||||
"""
|
||||
must suppress PermissionError
|
||||
"""
|
||||
assert list(safe_iterdir(resource_path_root))
|
||||
|
||||
iterdir_mock = mocker.patch("pathlib.Path.iterdir", side_effect=PermissionError)
|
||||
assert list(safe_iterdir(Path("root"))) == []
|
||||
iterdir_mock.assert_called_once_with()
|
||||
|
||||
|
||||
def test_srcinfo_property() -> None:
|
||||
"""
|
||||
must correctly extract properties
|
||||
|
||||
@@ -19,9 +19,10 @@ def test_configuration_schema(configuration: Configuration) -> None:
|
||||
"""
|
||||
section = "console"
|
||||
configuration.set_option("report", "target", section)
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
expected = {section: ReportTrigger.CONFIGURATION_SCHEMA[section]}
|
||||
assert ReportTrigger.configuration_schema(configuration) == expected
|
||||
assert ReportTrigger.configuration_schema(repository_id, configuration) == expected
|
||||
|
||||
|
||||
def test_configuration_schema_no_section(configuration: Configuration) -> None:
|
||||
@@ -30,7 +31,9 @@ def test_configuration_schema_no_section(configuration: Configuration) -> None:
|
||||
"""
|
||||
section = "abracadabra"
|
||||
configuration.set_option("report", "target", section)
|
||||
assert ReportTrigger.configuration_schema(configuration) == {}
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
assert ReportTrigger.configuration_schema(repository_id, configuration) == {}
|
||||
|
||||
|
||||
def test_configuration_schema_no_schema(configuration: Configuration) -> None:
|
||||
@@ -40,15 +43,17 @@ def test_configuration_schema_no_schema(configuration: Configuration) -> None:
|
||||
section = "abracadabra"
|
||||
configuration.set_option("report", "target", section)
|
||||
configuration.set_option(section, "key", "value")
|
||||
_, repository_id = configuration.check_loaded()
|
||||
|
||||
assert ReportTrigger.configuration_schema(configuration) == {}
|
||||
assert ReportTrigger.configuration_schema(repository_id, configuration) == {}
|
||||
|
||||
|
||||
def test_configuration_schema_empty(configuration: Configuration) -> None:
|
||||
"""
|
||||
must return default schema if no configuration set
|
||||
"""
|
||||
assert ReportTrigger.configuration_schema(None) == ReportTrigger.CONFIGURATION_SCHEMA
|
||||
_, repository_id = configuration.check_loaded()
|
||||
assert ReportTrigger.configuration_schema(repository_id, None) == ReportTrigger.CONFIGURATION_SCHEMA
|
||||
|
||||
|
||||
def test_configuration_schema_variables() -> None:
|
||||
|
||||
@@ -2,7 +2,7 @@ import datetime
|
||||
import json
|
||||
import pyalpm # typing: ignore
|
||||
|
||||
from dataclasses import asdict, fields, replace
|
||||
from dataclasses import asdict, fields
|
||||
from pathlib import Path
|
||||
from pytest_mock import MockerFixture
|
||||
from typing import Any
|
||||
@@ -38,25 +38,6 @@ def _get_official_data(resource_path_root: Path) -> dict[str, Any]:
|
||||
return json.loads(response)["results"][0]
|
||||
|
||||
|
||||
def test_post_init(aur_package_ahriman: AURPackage) -> None:
|
||||
"""
|
||||
must trim versions and descriptions from packages list
|
||||
"""
|
||||
package = replace(
|
||||
aur_package_ahriman,
|
||||
depends=["a=1"],
|
||||
make_depends=["b>=3"],
|
||||
opt_depends=["c: a description"],
|
||||
check_depends=["d=4"],
|
||||
provides=["e=5"],
|
||||
)
|
||||
assert package.depends == ["a"]
|
||||
assert package.make_depends == ["b"]
|
||||
assert package.opt_depends == ["c"]
|
||||
assert package.check_depends == ["d"]
|
||||
assert package.provides == ["e"]
|
||||
|
||||
|
||||
def test_from_json(aur_package_ahriman: AURPackage, resource_path_root: Path) -> None:
|
||||
"""
|
||||
must load package from json
|
||||
|
||||
@@ -2,7 +2,7 @@ import copy
|
||||
|
||||
from pathlib import Path
|
||||
from pytest_mock import MockerFixture
|
||||
from unittest.mock import MagicMock, PropertyMock, call as MockCall
|
||||
from unittest.mock import MagicMock, call as MockCall
|
||||
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.configuration import Configuration
|
||||
@@ -163,23 +163,6 @@ def test_from_archive(package_ahriman: Package, pyalpm_handle: MagicMock, mocker
|
||||
assert generated == package_ahriman
|
||||
|
||||
|
||||
def test_from_archive_empty_base(package_ahriman: Package, pyalpm_package_ahriman: MagicMock,
|
||||
mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must construct package with empty base from alpm library
|
||||
"""
|
||||
pyalpm_handle = MagicMock()
|
||||
type(pyalpm_package_ahriman).base = PropertyMock(return_value=None)
|
||||
pyalpm_handle.handle.load_pkg.return_value = pyalpm_package_ahriman
|
||||
|
||||
mocker.patch("ahriman.models.package_description.PackageDescription.from_package",
|
||||
return_value=package_ahriman.packages[package_ahriman.base])
|
||||
generated = Package.from_archive(Path("path"), pyalpm_handle)
|
||||
generated.remote = package_ahriman.remote
|
||||
|
||||
assert generated == package_ahriman
|
||||
|
||||
|
||||
def test_from_aur(package_ahriman: Package, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must construct package from aur
|
||||
|
||||
@@ -6,15 +6,10 @@ from ahriman.models.package_description import PackageDescription
|
||||
|
||||
def test_post_init() -> None:
|
||||
"""
|
||||
must trim versions and descriptions from packages list
|
||||
must trim versions and descriptions from dependencies list
|
||||
"""
|
||||
assert PackageDescription(
|
||||
depends=["a=1"],
|
||||
make_depends=["b>=3"],
|
||||
opt_depends=["c: a description"],
|
||||
check_depends=["d=4"],
|
||||
provides=["e=5"]
|
||||
) == PackageDescription(depends=["a"], make_depends=["b"], opt_depends=["c"], check_depends=["d"], provides=["e"])
|
||||
assert PackageDescription(depends=["a=1"], make_depends=["b>=3"], opt_depends=["c: a description"]) == \
|
||||
PackageDescription(depends=["a"], make_depends=["b"], opt_depends=["c"])
|
||||
|
||||
|
||||
def test_filepath(package_description_ahriman: PackageDescription) -> None:
|
||||
|
||||
@@ -55,7 +55,7 @@ def test_root_owner(repository_paths: RepositoryPaths, mocker: MockerFixture) ->
|
||||
"""
|
||||
must correctly define root directory owner
|
||||
"""
|
||||
mocker.patch("ahriman.models.repository_paths.owner", return_value=(42, 142))
|
||||
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.owner", return_value=(42, 142))
|
||||
assert repository_paths.root_owner == (42, 142)
|
||||
|
||||
|
||||
@@ -186,54 +186,16 @@ def test_known_repositories_empty(repository_paths: RepositoryPaths, mocker: Moc
|
||||
iterdir_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_chown(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
def test_owner(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must correctly set owner for the directory
|
||||
must correctly retrieve owner of the path
|
||||
"""
|
||||
mocker.patch("ahriman.models.repository_paths.owner", _get_owner(repository_paths.root, same=False))
|
||||
mocker.patch.object(RepositoryPaths, "root_owner", (42, 42))
|
||||
chown_mock = mocker.patch("os.chown")
|
||||
stat_mock = MagicMock()
|
||||
stat_mock.st_uid = 42
|
||||
stat_mock.st_gid = 142
|
||||
mocker.patch("pathlib.Path.stat", return_value=stat_mock)
|
||||
|
||||
path = repository_paths.root / "path"
|
||||
repository_paths._chown(path)
|
||||
chown_mock.assert_called_once_with(path, 42, 42, follow_symlinks=False)
|
||||
|
||||
|
||||
def test_chown_parent(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must correctly set owner for the directory including parents
|
||||
"""
|
||||
mocker.patch("ahriman.models.repository_paths.owner", _get_owner(repository_paths.root, same=False))
|
||||
mocker.patch.object(RepositoryPaths, "root_owner", (42, 42))
|
||||
chown_mock = mocker.patch("os.chown")
|
||||
|
||||
path = repository_paths.root / "parent" / "path"
|
||||
repository_paths._chown(path)
|
||||
chown_mock.assert_has_calls([
|
||||
MockCall(path, 42, 42, follow_symlinks=False),
|
||||
MockCall(path.parent, 42, 42, follow_symlinks=False)
|
||||
])
|
||||
|
||||
|
||||
def test_chown_skip(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must skip ownership set in case if it is same as root
|
||||
"""
|
||||
mocker.patch("ahriman.models.repository_paths.owner", _get_owner(repository_paths.root, same=True))
|
||||
mocker.patch.object(RepositoryPaths, "root_owner", (42, 42))
|
||||
chown_mock = mocker.patch("os.chown")
|
||||
|
||||
path = repository_paths.root / "path"
|
||||
repository_paths._chown(path)
|
||||
chown_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_chown_invalid_path(repository_paths: RepositoryPaths) -> None:
|
||||
"""
|
||||
must raise invalid path exception in case if directory outside the root supplied
|
||||
"""
|
||||
with pytest.raises(PathError):
|
||||
repository_paths._chown(repository_paths.root.parent)
|
||||
assert RepositoryPaths.owner(repository_paths.root) == (42, 142)
|
||||
|
||||
|
||||
def test_cache_for(repository_paths: RepositoryPaths, package_ahriman: Package) -> None:
|
||||
@@ -245,34 +207,54 @@ def test_cache_for(repository_paths: RepositoryPaths, package_ahriman: Package)
|
||||
assert path.parent == repository_paths.cache
|
||||
|
||||
|
||||
def test_preserve_owner(tmp_path: Path, repository_id: RepositoryId, mocker: MockerFixture) -> None:
|
||||
def test_chown(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must preserve file owner during operations
|
||||
must correctly set owner for the directory
|
||||
"""
|
||||
repository_paths = RepositoryPaths(tmp_path, repository_id)
|
||||
repository_paths.tree_create()
|
||||
chown_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths._chown")
|
||||
object.__setattr__(repository_paths, "owner", _get_owner(repository_paths.root, same=False))
|
||||
mocker.patch.object(RepositoryPaths, "root_owner", (42, 42))
|
||||
chown_mock = mocker.patch("os.chown")
|
||||
|
||||
with repository_paths.preserve_owner():
|
||||
(repository_paths.root / "created1").touch()
|
||||
(repository_paths.chroot / "created2").touch()
|
||||
chown_mock.assert_has_calls([MockCall(repository_paths.root / "created1")])
|
||||
path = repository_paths.root / "path"
|
||||
repository_paths.chown(path)
|
||||
chown_mock.assert_called_once_with(path, 42, 42, follow_symlinks=False)
|
||||
|
||||
|
||||
def test_preserve_owner_specific(tmp_path: Path, repository_id: RepositoryId, mocker: MockerFixture) -> None:
|
||||
def test_chown_parent(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must preserve file owner during operations only in specific directory
|
||||
must correctly set owner for the directory including parents
|
||||
"""
|
||||
repository_paths = RepositoryPaths(tmp_path, repository_id)
|
||||
repository_paths.tree_create()
|
||||
(repository_paths.root / "content").mkdir()
|
||||
chown_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths._chown")
|
||||
object.__setattr__(repository_paths, "owner", _get_owner(repository_paths.root, same=False))
|
||||
mocker.patch.object(RepositoryPaths, "root_owner", (42, 42))
|
||||
chown_mock = mocker.patch("os.chown")
|
||||
|
||||
with repository_paths.preserve_owner(repository_paths.root / "content"):
|
||||
(repository_paths.root / "created1").touch()
|
||||
(repository_paths.root / "content" / "created2").touch()
|
||||
(repository_paths.chroot / "created3").touch()
|
||||
chown_mock.assert_has_calls([MockCall(repository_paths.root / "content" / "created2")])
|
||||
path = repository_paths.root / "parent" / "path"
|
||||
repository_paths.chown(path)
|
||||
chown_mock.assert_has_calls([
|
||||
MockCall(path, 42, 42, follow_symlinks=False),
|
||||
MockCall(path.parent, 42, 42, follow_symlinks=False)
|
||||
])
|
||||
|
||||
|
||||
def test_chown_skip(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must skip ownership set in case if it is same as root
|
||||
"""
|
||||
object.__setattr__(repository_paths, "owner", _get_owner(repository_paths.root, same=True))
|
||||
mocker.patch.object(RepositoryPaths, "root_owner", (42, 42))
|
||||
chown_mock = mocker.patch("os.chown")
|
||||
|
||||
path = repository_paths.root / "path"
|
||||
repository_paths.chown(path)
|
||||
chown_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_chown_invalid_path(repository_paths: RepositoryPaths) -> None:
|
||||
"""
|
||||
must raise invalid path exception in case if directory outside the root supplied
|
||||
"""
|
||||
with pytest.raises(PathError):
|
||||
repository_paths.chown(repository_paths.root.parent)
|
||||
|
||||
|
||||
def test_tree_clear(repository_paths: RepositoryPaths, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
@@ -311,11 +293,11 @@ def test_tree_create(repository_paths: RepositoryPaths, mocker: MockerFixture) -
|
||||
and not callable(getattr(repository_paths, prop))
|
||||
}
|
||||
mkdir_mock = mocker.patch("pathlib.Path.mkdir")
|
||||
owner_guard_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.preserve_owner")
|
||||
chown_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.chown")
|
||||
|
||||
repository_paths.tree_create()
|
||||
mkdir_mock.assert_has_calls([MockCall(mode=0o755, parents=True, exist_ok=True) for _ in paths], any_order=True)
|
||||
owner_guard_mock.assert_called_once_with()
|
||||
chown_mock.assert_has_calls([MockCall(pytest.helpers.anyvar(int)) for _ in paths], any_order=True)
|
||||
|
||||
|
||||
def test_tree_create_skip(mocker: MockerFixture) -> None:
|
||||
|
||||
1
tests/ahriman/web/schemas/test_logs_search_schema.py
Normal file
1
tests/ahriman/web/schemas/test_logs_search_schema.py
Normal file
@@ -0,0 +1 @@
|
||||
# schema testing goes in view class tests
|
||||
@@ -86,6 +86,31 @@ async def test_get_with_pagination(client: TestClient, package_ahriman: Package)
|
||||
]
|
||||
|
||||
|
||||
async def test_get_with_filter(client: TestClient, package_ahriman: Package) -> None:
|
||||
"""
|
||||
must get logs with filter by version and process identifier
|
||||
"""
|
||||
await client.post(f"/api/v1/packages/{package_ahriman.base}",
|
||||
json={"status": BuildStatusEnum.Success.value, "package": package_ahriman.view()})
|
||||
await client.post(f"/api/v1/packages/{package_ahriman.base}/logs",
|
||||
json={"created": 42.0, "message": "message 1", "version": "42"})
|
||||
await client.post(f"/api/v1/packages/{package_ahriman.base}/logs",
|
||||
json={"created": 43.0, "message": "message 2", "version": "43"})
|
||||
request_schema = pytest.helpers.schema_request(LogsView.get, location="querystring")
|
||||
response_schema = pytest.helpers.schema_response(LogsView.get)
|
||||
|
||||
payload = {"version": "42", "process_id": LogRecordId.DEFAULT_PROCESS_ID}
|
||||
assert not request_schema.validate(payload)
|
||||
response = await client.get(f"/api/v2/packages/{package_ahriman.base}/logs", params=payload)
|
||||
assert response.status == 200
|
||||
|
||||
logs = await response.json()
|
||||
assert not response_schema.validate(logs)
|
||||
assert logs == [
|
||||
{"created": 42.0, "message": "message 1", "version": "42", "process_id": LogRecordId.DEFAULT_PROCESS_ID},
|
||||
]
|
||||
|
||||
|
||||
async def test_get_bad_request(client: TestClient, package_ahriman: Package) -> None:
|
||||
"""
|
||||
must return bad request for invalid query parameters
|
||||
|
||||
Reference in New Issue
Block a user