mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-06-29 23:25:49 +00:00
Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
bb4a0d75fc | |||
bca0df41d1 | |||
07b77be6b8 | |||
2b33510ada | |||
6d05389639 | |||
daf9841717 | |||
0d243a781a | |||
cf2e66a934 | |||
f01f35238d | |||
d30d512eb6 | |||
0437f90e5a | |||
3cab65855a | |||
ecfb615f97 | |||
243983ee64 | |||
812c03d1eb | |||
01597c531b | |||
4fec42eac8 | |||
7574b8e5ce | |||
0f2e7f45da | |||
5956a8720b | |||
8dd4ced5e9 |
9
.github/workflows/setup.sh
vendored
9
.github/workflows/setup.sh
vendored
@ -12,7 +12,7 @@ pacman -Syu --noconfirm
|
|||||||
# main dependencies
|
# main dependencies
|
||||||
pacman -Sy --noconfirm devtools git pyalpm python-cerberus python-inflection python-passlib python-requests python-srcinfo python-systemd sudo
|
pacman -Sy --noconfirm devtools git pyalpm python-cerberus python-inflection python-passlib python-requests python-srcinfo python-systemd sudo
|
||||||
# make dependencies
|
# make dependencies
|
||||||
pacman -Sy --noconfirm python-build python-flit python-installer python-tox python-wheel
|
pacman -Sy --noconfirm --asdeps base-devel python-build python-flit python-installer python-tox python-wheel
|
||||||
# optional dependencies
|
# optional dependencies
|
||||||
if [[ -z $MINIMAL_INSTALL ]]; then
|
if [[ -z $MINIMAL_INSTALL ]]; then
|
||||||
# VCS support
|
# VCS support
|
||||||
@ -32,10 +32,13 @@ mv dist/ahriman-*.tar.gz package/archlinux
|
|||||||
chmod +777 package/archlinux # because fuck you that's why
|
chmod +777 package/archlinux # because fuck you that's why
|
||||||
cd package/archlinux
|
cd package/archlinux
|
||||||
sudo -u nobody -- makepkg -cf --skipchecksums --noconfirm
|
sudo -u nobody -- makepkg -cf --skipchecksums --noconfirm
|
||||||
sudo -u nobody -- makepkg --packagelist | pacman -U --noconfirm -
|
sudo -u nobody -- makepkg --packagelist | grep -v -- -debug- | pacman -U --noconfirm -
|
||||||
# create machine-id which is required by build tools
|
# create machine-id which is required by build tools
|
||||||
systemd-machine-id-setup
|
systemd-machine-id-setup
|
||||||
|
|
||||||
|
# remove unused dependencies
|
||||||
|
pacman -Qdtq | pacman -Rscn --noconfirm -
|
||||||
|
|
||||||
# initial setup command as root
|
# initial setup command as root
|
||||||
[[ -z $MINIMAL_INSTALL ]] && WEB_ARGS=("--web-port" "8080")
|
[[ -z $MINIMAL_INSTALL ]] && WEB_ARGS=("--web-port" "8080")
|
||||||
ahriman -a x86_64 -r "github" service-setup --packager "ahriman bot <ahriman@example.com>" "${WEB_ARGS[@]}"
|
ahriman -a x86_64 -r "github" service-setup --packager "ahriman bot <ahriman@example.com>" "${WEB_ARGS[@]}"
|
||||||
@ -50,7 +53,7 @@ if [[ -z $MINIMAL_INSTALL ]]; then
|
|||||||
WEB_PID=$!
|
WEB_PID=$!
|
||||||
fi
|
fi
|
||||||
# add the first package
|
# add the first package
|
||||||
sudo -u ahriman -- ahriman package-add --now ahriman
|
sudo -u ahriman -- ahriman --log-handler console package-add --now ahriman
|
||||||
# check if package was actually installed
|
# check if package was actually installed
|
||||||
test -n "$(find "/var/lib/ahriman/repository/github/x86_64" -name "ahriman*pkg*")"
|
test -n "$(find "/var/lib/ahriman/repository/github/x86_64" -name "ahriman*pkg*")"
|
||||||
# run package check
|
# run package check
|
||||||
|
@ -3,7 +3,7 @@ version: 2
|
|||||||
build:
|
build:
|
||||||
os: ubuntu-20.04
|
os: ubuntu-20.04
|
||||||
tools:
|
tools:
|
||||||
python: "3.11"
|
python: "3.12"
|
||||||
|
|
||||||
python:
|
python:
|
||||||
install:
|
install:
|
||||||
|
@ -33,9 +33,9 @@ COPY "docker/install-aur-package.sh" "/usr/local/bin/install-aur-package"
|
|||||||
## install package dependencies
|
## install package dependencies
|
||||||
## darcs is not installed by reasons, because it requires a lot haskell packages which dramatically increase image size
|
## darcs is not installed by reasons, because it requires a lot haskell packages which dramatically increase image size
|
||||||
RUN pacman -Sy --noconfirm --asdeps devtools git pyalpm python-cerberus python-inflection python-passlib python-requests python-srcinfo && \
|
RUN pacman -Sy --noconfirm --asdeps devtools git pyalpm python-cerberus python-inflection python-passlib python-requests python-srcinfo && \
|
||||||
pacman -Sy --noconfirm --asdeps python-build python-flit python-installer python-wheel && \
|
pacman -Sy --noconfirm --asdeps base-devel python-build python-flit python-installer python-wheel && \
|
||||||
pacman -Sy --noconfirm --asdeps breezy git mercurial python-aiohttp python-boto3 python-cryptography python-jinja python-requests-unixsocket python-systemd rsync subversion && \
|
pacman -Sy --noconfirm --asdeps breezy git mercurial python-aiohttp python-boto3 python-cryptography python-jinja python-requests-unixsocket python-systemd rsync subversion && \
|
||||||
runuser -u build -- install-aur-package python-aioauth-client python-aiohttp-apispec-git python-aiohttp-cors \
|
runuser -u build -- install-aur-package python-aioauth-client python-webargs python-aiohttp-apispec-git python-aiohttp-cors \
|
||||||
python-aiohttp-jinja2 python-aiohttp-session python-aiohttp-security
|
python-aiohttp-jinja2 python-aiohttp-session python-aiohttp-security
|
||||||
|
|
||||||
## FIXME since 1.0.4 devtools requires dbus to be run, which doesn't work now in container
|
## FIXME since 1.0.4 devtools requires dbus to be run, which doesn't work now in container
|
||||||
|
@ -6,7 +6,7 @@ for PACKAGE in "$@"; do
|
|||||||
BUILD_DIR="$(mktemp -d)"
|
BUILD_DIR="$(mktemp -d)"
|
||||||
git clone https://aur.archlinux.org/"$PACKAGE".git "$BUILD_DIR"
|
git clone https://aur.archlinux.org/"$PACKAGE".git "$BUILD_DIR"
|
||||||
cd "$BUILD_DIR"
|
cd "$BUILD_DIR"
|
||||||
makepkg --noconfirm --install --rmdeps --syncdeps
|
makepkg --nocheck --noconfirm --install --rmdeps --syncdeps
|
||||||
cd /
|
cd /
|
||||||
rm -r "$BUILD_DIR"
|
rm -r "$BUILD_DIR"
|
||||||
done
|
done
|
||||||
|
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.1 MiB |
61
docs/ahriman.web.views.v1.packages.rst
Normal file
61
docs/ahriman.web.views.v1.packages.rst
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
ahriman.web.views.v1.packages package
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Submodules
|
||||||
|
----------
|
||||||
|
|
||||||
|
ahriman.web.views.v1.packages.changes module
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.v1.packages.changes
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.web.views.v1.packages.logs module
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.v1.packages.logs
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.web.views.v1.packages.package module
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.v1.packages.package
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.web.views.v1.packages.packages module
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.v1.packages.packages
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.web.views.v1.packages.patch module
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.v1.packages.patch
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.web.views.v1.packages.patches module
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.v1.packages.patches
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
Module contents
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.v1.packages
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
@ -8,6 +8,7 @@ Subpackages
|
|||||||
:maxdepth: 4
|
:maxdepth: 4
|
||||||
|
|
||||||
ahriman.web.views.v1.distributed
|
ahriman.web.views.v1.distributed
|
||||||
|
ahriman.web.views.v1.packages
|
||||||
ahriman.web.views.v1.service
|
ahriman.web.views.v1.service
|
||||||
ahriman.web.views.v1.status
|
ahriman.web.views.v1.status
|
||||||
ahriman.web.views.v1.user
|
ahriman.web.views.v1.user
|
||||||
|
@ -4,14 +4,6 @@ ahriman.web.views.v1.status package
|
|||||||
Submodules
|
Submodules
|
||||||
----------
|
----------
|
||||||
|
|
||||||
ahriman.web.views.v1.status.changes module
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.web.views.v1.status.changes
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
ahriman.web.views.v1.status.info module
|
ahriman.web.views.v1.status.info module
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
@ -20,46 +12,6 @@ ahriman.web.views.v1.status.info module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.web.views.v1.status.logs module
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.web.views.v1.status.logs
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
ahriman.web.views.v1.status.package module
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.web.views.v1.status.package
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
ahriman.web.views.v1.status.packages module
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.web.views.v1.status.packages
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
ahriman.web.views.v1.status.patch module
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.web.views.v1.status.patch
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
ahriman.web.views.v1.status.patches module
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.web.views.v1.status.patches
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
ahriman.web.views.v1.status.repositories module
|
ahriman.web.views.v1.status.repositories module
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
|
|
||||||
|
21
docs/ahriman.web.views.v2.packages.rst
Normal file
21
docs/ahriman.web.views.v2.packages.rst
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
ahriman.web.views.v2.packages package
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Submodules
|
||||||
|
----------
|
||||||
|
|
||||||
|
ahriman.web.views.v2.packages.logs module
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.v2.packages.logs
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
Module contents
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.web.views.v2.packages
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
@ -7,7 +7,7 @@ Subpackages
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 4
|
:maxdepth: 4
|
||||||
|
|
||||||
ahriman.web.views.v2.status
|
ahriman.web.views.v2.packages
|
||||||
|
|
||||||
Module contents
|
Module contents
|
||||||
---------------
|
---------------
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
ahriman.web.views.v2.status package
|
|
||||||
===================================
|
|
||||||
|
|
||||||
Submodules
|
|
||||||
----------
|
|
||||||
|
|
||||||
ahriman.web.views.v2.status.logs module
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.web.views.v2.status.logs
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
Module contents
|
|
||||||
---------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.web.views.v2.status
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
@ -81,6 +81,7 @@ Build related configuration. Group name can refer to architecture, e.g. ``build:
|
|||||||
* ``archbuild_flags`` - additional flags passed to ``archbuild`` command, space separated list of strings, optional.
|
* ``archbuild_flags`` - additional flags passed to ``archbuild`` command, space separated list of strings, optional.
|
||||||
* ``build_command`` - default build command, string, required.
|
* ``build_command`` - default build command, string, required.
|
||||||
* ``ignore_packages`` - list packages to ignore during a regular update (manual update will still work), space separated list of strings, optional.
|
* ``ignore_packages`` - list packages to ignore during a regular update (manual update will still work), space separated list of strings, optional.
|
||||||
|
* ``include_debug_packages`` - distribute debug packages, boolean, optional, default ``yes``.
|
||||||
* ``makepkg_flags`` - additional flags passed to ``makepkg`` command, space separated list of strings, optional.
|
* ``makepkg_flags`` - additional flags passed to ``makepkg`` command, space separated list of strings, optional.
|
||||||
* ``makechrootpkg_flags`` - additional flags passed to ``makechrootpkg`` command, space separated list of strings, optional.
|
* ``makechrootpkg_flags`` - additional flags passed to ``makechrootpkg`` command, space separated list of strings, optional.
|
||||||
* ``triggers`` - list of ``ahriman.core.triggers.Trigger`` class implementation (e.g. ``ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger``) which will be loaded and run at the end of processing, space separated list of strings, optional. You can also specify triggers by their paths, e.g. ``/usr/lib/python3.10/site-packages/ahriman/core/report/report.py.ReportTrigger``. Triggers are run in the order of definition.
|
* ``triggers`` - list of ``ahriman.core.triggers.Trigger`` class implementation (e.g. ``ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger``) which will be loaded and run at the end of processing, space separated list of strings, optional. You can also specify triggers by their paths, e.g. ``/usr/lib/python3.10/site-packages/ahriman/core/report/report.py.ReportTrigger``. Triggers are run in the order of definition.
|
||||||
|
12
docs/faq.rst
12
docs/faq.rst
@ -208,6 +208,18 @@ This command will prompt for new value of the PKGBUILD variable ``version``. You
|
|||||||
|
|
||||||
sudo -u ahriman ahriman patch-add ahriman version version.patch
|
sudo -u ahriman ahriman patch-add ahriman version version.patch
|
||||||
|
|
||||||
|
The command also supports arrays, but in this case you need to specify full array, e.g.
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
sudo -u ahriman ahriman patch-add ahriman depends
|
||||||
|
|
||||||
|
Post new function or variable value below. Press Ctrl-D to finish:
|
||||||
|
(python python-aiohttp)
|
||||||
|
^D
|
||||||
|
|
||||||
|
will set depends PKGBUILD variable (exactly) to array ``["python", "python-aiohttp"]``.
|
||||||
|
|
||||||
Alternatively you can create full-diff patches, which are calculated by using ``git diff`` from current PKGBUILD master branch:
|
Alternatively you can create full-diff patches, which are calculated by using ``git diff`` from current PKGBUILD master branch:
|
||||||
|
|
||||||
#.
|
#.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Maintainer: Evgeniy Alekseev
|
# Maintainer: Evgeniy Alekseev
|
||||||
|
|
||||||
pkgname='ahriman'
|
pkgname='ahriman'
|
||||||
pkgver=2.13.1
|
pkgver=2.13.8
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="ArcH linux ReposItory MANager"
|
pkgdesc="ArcH linux ReposItory MANager"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
|
@ -46,8 +46,12 @@ allow_read_only = yes
|
|||||||
[build]
|
[build]
|
||||||
; List of additional flags passed to archbuild command.
|
; List of additional flags passed to archbuild command.
|
||||||
;archbuild_flags =
|
;archbuild_flags =
|
||||||
|
; Path to build command
|
||||||
|
;build_command =
|
||||||
; List of packages to be ignored during automatic updates.
|
; List of packages to be ignored during automatic updates.
|
||||||
;ignore_packages =
|
;ignore_packages =
|
||||||
|
; Include debug packages
|
||||||
|
;include_debug_packages = yes
|
||||||
; List of additional flags passed to makechrootpkg command.
|
; List of additional flags passed to makechrootpkg command.
|
||||||
;makechrootpkg_flags =
|
;makechrootpkg_flags =
|
||||||
; List of additional flags passed to makepkg command.
|
; List of additional flags passed to makepkg command.
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<!-- Embed elements Elements via Web Component -->
|
<!-- Embed elements Elements via Web Component -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@stoplight/elements@7.13.7/web-components.min.js" integrity="sha384-aKMPitODat9Dqj3Mva9Rs9jS5Z3KPSW0sFlAOazuULJMFYhAfmORI5SlH9aWIst8" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@stoplight/elements@7.13.7/web-components.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@stoplight/elements@7.13.7/styles.min.css" integrity="sha384-wPzTs1aFAoGq9gqp9NAs2YVTkFXcU2d6Bx11aKRFhVw2B7o1bCwaV9pGHTlUfD2+" crossorigin="anonymous" type="text/css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@stoplight/elements@7.13.7/styles.min.css" crossorigin="anonymous" type="text/css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<nav class="navbar navbar-expand-lg">
|
<nav class="navbar navbar-expand-lg">
|
||||||
<div class="navbar-brand"><img src="/static/logo.svg" width="30" height="30" alt=""> ahriman</div>
|
<div class="navbar-brand"><img src="/static/logo.svg" width="30" height="30" alt=""></div>
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#repositories-navbar-supported-content" aria-controls="repositories-navbar-supported-content" aria-expanded="false" aria-label="Toggle navigation">
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#repositories-navbar-supported-content" aria-controls="repositories-navbar-supported-content" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -38,10 +38,6 @@
|
|||||||
<script>
|
<script>
|
||||||
const keyImportModal = $("#key-import-modal");
|
const keyImportModal = $("#key-import-modal");
|
||||||
const keyImportForm = $("#key-import-form");
|
const keyImportForm = $("#key-import-form");
|
||||||
keyImportModal.on("hidden.bs.modal", () => {
|
|
||||||
keyImportBodyInput.text("");
|
|
||||||
keyImportForm.trigger("reset");
|
|
||||||
});
|
|
||||||
|
|
||||||
const keyImportBodyInput = $("#key-import-body-input");
|
const keyImportBodyInput = $("#key-import-body-input");
|
||||||
const keyImportCopyButton = $("#key-import-copy-button");
|
const keyImportCopyButton = $("#key-import-copy-button");
|
||||||
@ -90,4 +86,11 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
keyImportModal.on("hidden.bs.modal", () => {
|
||||||
|
keyImportBodyInput.text("");
|
||||||
|
keyImportForm.trigger("reset");
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -36,9 +36,6 @@
|
|||||||
<script>
|
<script>
|
||||||
const loginModal = $("#login-modal");
|
const loginModal = $("#login-modal");
|
||||||
const loginForm = $("#login-form");
|
const loginForm = $("#login-form");
|
||||||
loginModal.on("hidden.bs.modal", () => {
|
|
||||||
loginForm.trigger("reset");
|
|
||||||
});
|
|
||||||
|
|
||||||
const loginPasswordInput = $("#login-password");
|
const loginPasswordInput = $("#login-password");
|
||||||
const loginUsernameInput = $("#login-username");
|
const loginUsernameInput = $("#login-username");
|
||||||
@ -77,4 +74,10 @@
|
|||||||
showHidePasswordButton.addClass("bi-eye");
|
showHidePasswordButton.addClass("bi-eye");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
loginModal.on("hidden.bs.modal", () => {
|
||||||
|
loginForm.trigger("reset");
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -43,41 +43,10 @@
|
|||||||
<script>
|
<script>
|
||||||
const packageAddModal = $("#package-add-modal");
|
const packageAddModal = $("#package-add-modal");
|
||||||
const packageAddForm = $("#package-add-form");
|
const packageAddForm = $("#package-add-form");
|
||||||
packageAddModal.on("shown.bs.modal", () => {
|
|
||||||
$(`#package-add-repository-input option[value="${repository.architecture}-${repository.repository}"]`).prop("selected", true);
|
|
||||||
});
|
|
||||||
packageAddModal.on("hidden.bs.modal", () => {
|
|
||||||
packageAddVariablesDiv.empty();
|
|
||||||
packageAddForm.trigger("reset");
|
|
||||||
});
|
|
||||||
|
|
||||||
const packageAddInput = $("#package-add-input");
|
const packageAddInput = $("#package-add-input");
|
||||||
const packageAddRepositoryInput = $("#package-add-repository-input");
|
const packageAddRepositoryInput = $("#package-add-repository-input");
|
||||||
const packageAddKnownPackagesList = $("#package-add-known-packages-dlist");
|
const packageAddKnownPackagesList = $("#package-add-known-packages-dlist");
|
||||||
packageAddInput.keyup(() => {
|
|
||||||
clearTimeout(packageAddInput.data("timeout"));
|
|
||||||
packageAddInput.data("timeout", setTimeout($.proxy(() => {
|
|
||||||
const value = packageAddInput.val();
|
|
||||||
|
|
||||||
if (value.length >= 3) {
|
|
||||||
$.ajax({
|
|
||||||
url: "/api/v1/service/search",
|
|
||||||
data: {"for": value},
|
|
||||||
type: "GET",
|
|
||||||
dataType: "json",
|
|
||||||
success: response => {
|
|
||||||
const options = response.map(pkg => {
|
|
||||||
const option = document.createElement("option");
|
|
||||||
option.value = pkg.package;
|
|
||||||
option.innerText = `${pkg.package} (${pkg.description})`;
|
|
||||||
return option;
|
|
||||||
});
|
|
||||||
packageAddKnownPackagesList.empty().append(options);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, this), 500));
|
|
||||||
});
|
|
||||||
|
|
||||||
const packageAddVariablesDiv = $("#package-add-variables-div");
|
const packageAddVariablesDiv = $("#package-add-variables-div");
|
||||||
|
|
||||||
@ -156,4 +125,39 @@
|
|||||||
doPackageAction("/api/v1/service/request", [packages], repository, onSuccess, onFailure, patches);
|
doPackageAction("/api/v1/service/request", [packages], repository, onSuccess, onFailure, patches);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
packageAddModal.on("shown.bs.modal", () => {
|
||||||
|
$(`#package-add-repository-input option[value="${repository.architecture}-${repository.repository}"]`).prop("selected", true);
|
||||||
|
});
|
||||||
|
packageAddModal.on("hidden.bs.modal", () => {
|
||||||
|
packageAddVariablesDiv.empty();
|
||||||
|
packageAddForm.trigger("reset");
|
||||||
|
});
|
||||||
|
|
||||||
|
packageAddInput.keyup(() => {
|
||||||
|
clearTimeout(packageAddInput.data("timeout"));
|
||||||
|
packageAddInput.data("timeout", setTimeout($.proxy(() => {
|
||||||
|
const value = packageAddInput.val();
|
||||||
|
|
||||||
|
if (value.length >= 3) {
|
||||||
|
$.ajax({
|
||||||
|
url: "/api/v1/service/search",
|
||||||
|
data: {"for": value},
|
||||||
|
type: "GET",
|
||||||
|
dataType: "json",
|
||||||
|
success: response => {
|
||||||
|
const options = response.map(pkg => {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.value = pkg.package;
|
||||||
|
option.innerText = `${pkg.package} (${pkg.description})`;
|
||||||
|
return option;
|
||||||
|
});
|
||||||
|
packageAddKnownPackagesList.empty().append(options);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, this), 500));
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -72,26 +72,6 @@
|
|||||||
const packageInfoModal = $("#package-info-modal");
|
const packageInfoModal = $("#package-info-modal");
|
||||||
const packageInfoModalHeader = $("#package-info-modal-header");
|
const packageInfoModalHeader = $("#package-info-modal-header");
|
||||||
const packageInfo = $("#package-info");
|
const packageInfo = $("#package-info");
|
||||||
packageInfoModal.on("hidden.bs.modal", () => {
|
|
||||||
packageInfoAurUrl.empty();
|
|
||||||
packageInfoDepends.empty();
|
|
||||||
packageInfoGroups.empty();
|
|
||||||
packageInfoLicenses.empty();
|
|
||||||
packageInfoPackager.empty();
|
|
||||||
packageInfoPackages.empty();
|
|
||||||
packageInfoUpstreamUrl.empty();
|
|
||||||
packageInfoVersion.empty();
|
|
||||||
|
|
||||||
packageInfoVariablesBlock.attr("hidden", true);
|
|
||||||
packageInfoVariablesDiv.empty();
|
|
||||||
|
|
||||||
packageInfoLogsInput.empty();
|
|
||||||
packageInfoChangesInput.empty();
|
|
||||||
|
|
||||||
packageInfoModal.trigger("reset");
|
|
||||||
|
|
||||||
hideInfoControls(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
const packageInfoLogsInput = $("#package-info-logs-input");
|
const packageInfoLogsInput = $("#package-info-logs-input");
|
||||||
const packageInfoLogsCopyButton = $("#package-info-logs-copy-button");
|
const packageInfoLogsCopyButton = $("#package-info-logs-copy-button");
|
||||||
@ -309,4 +289,27 @@
|
|||||||
|
|
||||||
if (isPackageBaseSet) packageInfoModal.modal("show");
|
if (isPackageBaseSet) packageInfoModal.modal("show");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
packageInfoModal.on("hidden.bs.modal", () => {
|
||||||
|
packageInfoAurUrl.empty();
|
||||||
|
packageInfoDepends.empty();
|
||||||
|
packageInfoGroups.empty();
|
||||||
|
packageInfoLicenses.empty();
|
||||||
|
packageInfoPackager.empty();
|
||||||
|
packageInfoPackages.empty();
|
||||||
|
packageInfoUpstreamUrl.empty();
|
||||||
|
packageInfoVersion.empty();
|
||||||
|
|
||||||
|
packageInfoVariablesBlock.attr("hidden", true);
|
||||||
|
packageInfoVariablesDiv.empty();
|
||||||
|
|
||||||
|
packageInfoLogsInput.empty();
|
||||||
|
packageInfoChangesInput.empty();
|
||||||
|
|
||||||
|
packageInfoModal.trigger("reset");
|
||||||
|
|
||||||
|
hideInfoControls(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -35,11 +35,6 @@
|
|||||||
<script>
|
<script>
|
||||||
const packageRebuildModal = $("#package-rebuild-modal");
|
const packageRebuildModal = $("#package-rebuild-modal");
|
||||||
const packageRebuildForm = $("#package-rebuild-form");
|
const packageRebuildForm = $("#package-rebuild-form");
|
||||||
packageRebuildModal.on("shown.bs.modal", () => {
|
|
||||||
$(`#package-rebuild-repository-input option[value="${repository.architecture}-${repository.repository}"]`).prop("selected", true);
|
|
||||||
|
|
||||||
});
|
|
||||||
packageRebuildModal.on("hidden.bs.modal", () => { packageRebuildForm.trigger("reset"); });
|
|
||||||
|
|
||||||
const packageRebuildDependencyInput = $("#package-rebuild-dependency-input");
|
const packageRebuildDependencyInput = $("#package-rebuild-dependency-input");
|
||||||
const packageRebuildRepositoryInput = $("#package-rebuild-repository-input");
|
const packageRebuildRepositoryInput = $("#package-rebuild-repository-input");
|
||||||
@ -54,4 +49,12 @@
|
|||||||
doPackageAction("/api/v1/service/rebuild", [packages], repository, onSuccess, onFailure);
|
doPackageAction("/api/v1/service/rebuild", [packages], repository, onSuccess, onFailure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
packageRebuildModal.on("shown.bs.modal", () => {
|
||||||
|
$(`#package-rebuild-repository-input option[value="${repository.architecture}-${repository.repository}"]`).prop("selected", true);
|
||||||
|
|
||||||
|
});
|
||||||
|
packageRebuildModal.on("hidden.bs.modal", () => { packageRebuildForm.trigger("reset"); });
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -9,46 +9,8 @@
|
|||||||
const packageInfoUpdateButton = $("#package-info-update-button");
|
const packageInfoUpdateButton = $("#package-info-update-button");
|
||||||
|
|
||||||
let repository = null;
|
let repository = null;
|
||||||
$("#repositories a").on("click", (event) => {
|
|
||||||
const element = event.target;
|
|
||||||
repository = {
|
|
||||||
architecture: element.dataset.architecture,
|
|
||||||
repository: element.dataset.repository,
|
|
||||||
};
|
|
||||||
packageUpdateButton.html(`<i class="bi bi-play"></i> update<span class="d-none d-sm-inline"> ${safe(repository.repository)} (${safe(repository.architecture)})</span>`);
|
|
||||||
$(`#${element.id}`).tab("show");
|
|
||||||
reload();
|
|
||||||
});
|
|
||||||
|
|
||||||
const table = $("#packages");
|
const table = $("#packages");
|
||||||
table.on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table", () => {
|
|
||||||
packageRemoveButton.prop("disabled", !table.bootstrapTable("getSelections").length);
|
|
||||||
});
|
|
||||||
table.on("click-row.bs.table", (self, data, row, cell) => {
|
|
||||||
if (0 === cell || "base" === cell) {
|
|
||||||
const method = data[0] === true ? "uncheckBy" : "checkBy"; // fck javascript
|
|
||||||
table.bootstrapTable(method, {field: "id", values: [data.id]});
|
|
||||||
} else showPackageInfo(data.id);
|
|
||||||
});
|
|
||||||
table.on("created-controls.bs.table", () => {
|
|
||||||
const pickerInput = $(".bootstrap-table-filter-control-timestamp");
|
|
||||||
pickerInput.daterangepicker({
|
|
||||||
autoUpdateInput: false,
|
|
||||||
locale: {
|
|
||||||
cancelLabel: "Clear",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
pickerInput.on("apply.daterangepicker", (event, picker) => {
|
|
||||||
pickerInput.val(`${picker.startDate.format("YYYY-MM-DD")} - ${picker.endDate.format("YYYY-MM-DD")}`);
|
|
||||||
table.bootstrapTable("triggerSearch");
|
|
||||||
});
|
|
||||||
|
|
||||||
pickerInput.on("cancel.daterangepicker", () => {
|
|
||||||
pickerInput.val("");
|
|
||||||
table.bootstrapTable("triggerSearch");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const statusBadge = $("#badge-status");
|
const statusBadge = $("#badge-status");
|
||||||
const versionBadge = $("#badge-version");
|
const versionBadge = $("#badge-version");
|
||||||
@ -221,8 +183,47 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$(() => {
|
$(() => {
|
||||||
table.bootstrapTable({});
|
$("#repositories a").on("click", event => {
|
||||||
|
const element = event.target;
|
||||||
|
repository = {
|
||||||
|
architecture: element.dataset.architecture,
|
||||||
|
repository: element.dataset.repository,
|
||||||
|
};
|
||||||
|
packageUpdateButton.html(`<i class="bi bi-play"></i> update<span class="d-none d-sm-inline"> ${safe(repository.repository)} (${safe(repository.architecture)})</span>`);
|
||||||
|
$(`#${element.id}`).tab("show");
|
||||||
|
reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
table.on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table", () => {
|
||||||
|
packageRemoveButton.prop("disabled", !table.bootstrapTable("getSelections").length);
|
||||||
|
});
|
||||||
|
table.on("click-row.bs.table", (self, data, row, cell) => {
|
||||||
|
if (0 === cell || "base" === cell) {
|
||||||
|
const method = data[0] === true ? "uncheckBy" : "checkBy"; // fck javascript
|
||||||
|
table.bootstrapTable(method, {field: "id", values: [data.id]});
|
||||||
|
} else showPackageInfo(data.id);
|
||||||
|
});
|
||||||
|
table.on("created-controls.bs.table", () => {
|
||||||
|
const pickerInput = $(".bootstrap-table-filter-control-timestamp");
|
||||||
|
pickerInput.daterangepicker({
|
||||||
|
autoUpdateInput: false,
|
||||||
|
locale: {
|
||||||
|
cancelLabel: "Clear",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
pickerInput.on("apply.daterangepicker", (event, picker) => {
|
||||||
|
pickerInput.val(`${picker.startDate.format("YYYY-MM-DD")} - ${picker.endDate.format("YYYY-MM-DD")}`);
|
||||||
|
table.bootstrapTable("triggerSearch");
|
||||||
|
});
|
||||||
|
|
||||||
|
pickerInput.on("cancel.daterangepicker", () => {
|
||||||
|
pickerInput.val("");
|
||||||
|
table.bootstrapTable("triggerSearch");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
statusBadge.popover();
|
statusBadge.popover();
|
||||||
selectRepository();
|
selectRepository();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -102,25 +102,6 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
const table = $("#packages");
|
const table = $("#packages");
|
||||||
table.on("created-controls.bs.table", () => {
|
|
||||||
const pickerInput = $(".bootstrap-table-filter-control-timestamp");
|
|
||||||
pickerInput.daterangepicker({
|
|
||||||
autoUpdateInput: false,
|
|
||||||
locale: {
|
|
||||||
cancelLabel: "Clear",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
pickerInput.on("apply.daterangepicker", (event, picker) => {
|
|
||||||
pickerInput.val(`${picker.startDate.format("YYYY-MM-DD")} - ${picker.endDate.format("YYYY-MM-DD")}`);
|
|
||||||
table.bootstrapTable("triggerSearch");
|
|
||||||
});
|
|
||||||
|
|
||||||
pickerInput.on("cancel.daterangepicker", () => {
|
|
||||||
pickerInput.val("");
|
|
||||||
table.bootstrapTable("triggerSearch");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const pacmanConf = $("#pacman-conf");
|
const pacmanConf = $("#pacman-conf");
|
||||||
const pacmanConfCopyButton = $("#copy-btn");
|
const pacmanConfCopyButton = $("#copy-btn");
|
||||||
@ -141,6 +122,28 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
|
|||||||
function filterListLicenses() {
|
function filterListLicenses() {
|
||||||
return extractDataList(table.bootstrapTable("getData"), "licenses");
|
return extractDataList(table.bootstrapTable("getData"), "licenses");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
table.on("created-controls.bs.table", () => {
|
||||||
|
const pickerInput = $(".bootstrap-table-filter-control-timestamp");
|
||||||
|
pickerInput.daterangepicker({
|
||||||
|
autoUpdateInput: false,
|
||||||
|
locale: {
|
||||||
|
cancelLabel: "Clear",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
pickerInput.on("apply.daterangepicker", (event, picker) => {
|
||||||
|
pickerInput.val(`${picker.startDate.format("YYYY-MM-DD")} - ${picker.endDate.format("YYYY-MM-DD")}`);
|
||||||
|
table.bootstrapTable("triggerSearch");
|
||||||
|
});
|
||||||
|
|
||||||
|
pickerInput.on("cancel.daterangepicker", () => {
|
||||||
|
pickerInput.val("");
|
||||||
|
table.bootstrapTable("triggerSearch");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js" integrity="sha384-1H217gwSVyLSIfaLxHbE7dRb3v4mYCKbpQvzx0cegeju1MVsGrX5xXxAvs/HgeFs" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.4/moment.min.js" integrity="sha384-8hHkOkbWN1TLWwet/jpbJ0zbx3FJDeYJgQ8dX1mRrv/vfCfHCqFSFZYCgaMML3z9" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.4/moment.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/daterangepicker@3.1.0/daterangepicker.min.js" integrity="sha384-u4eJN1VWrTf/FnYYQJo2kqJyVxEQf5UmWY4iUcNAoLenOEtEuCkfwc5bKvZOWBi5" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/daterangepicker@3.1.0/daterangepicker.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/tableexport.jquery.plugin@1.28.0/tableExport.min.js" integrity="sha384-1Rz4Kz/y1rSWw+ZsjTcxB684XgofbO8iizY+UFIzCwFeQ+QUyhBNWBMh/STOyomI" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/tableexport.jquery.plugin@1.28.0/tableExport.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.min.js" integrity="sha384-IazMVNyYoUNx6357fWJoqtHYUWWCNHIXxFVtbpVgvImQNWuRP2WbHPaIb3QF8j97" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" integrity="sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/bootstrap-table.min.js" integrity="sha384-GVLHfbEvuGA/RFiQ3MK2ClEJkWYJXABg55t9LpoDPZFGIsSq8xhFlQydm5poV2jW" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/bootstrap-table.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/export/bootstrap-table-export.min.js" integrity="sha384-g9OAB1Moamcy8+l1Q/tajHlMf6NTkS79ehKLTYbA80aQRbRhFCjrSuezv+FE2Kwe" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/export/bootstrap-table-export.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/resizable/bootstrap-table-resizable.js" integrity="sha384-wd8Vc6Febikdnsnk9vthRWRvMwffw246vhqiqNO3aSNe1maTEA07Vh3zAQiSyDji" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/resizable/bootstrap-table-resizable.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/filter-control/bootstrap-table-filter-control.js" integrity="sha384-NIqcjpr/3eZI1iNzz7hgT5rgp70qFUzkZffeCgVva9gi80B5vqcm7gn+8QvlWxko" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/filter-control/bootstrap-table-filter-control.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js" integrity="sha384-F/bZzf7p3Joyp5psL90p/p89AZJsndkSoGwRpXcZhleCWhd8SnRuoYo4d0yirjJp" crossorigin="anonymous" type="application/javascript"></script>
|
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
async function copyToClipboard(text, button) {
|
async function copyToClipboard(text, button) {
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous" type="text/css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" crossorigin="anonymous" type="text/css">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css" integrity="sha384-4LISF5TTJX/fLmGSxO53rV4miRxdg84mZsxmO8Rx5jGtp/LbrixFETvWa5a6sESd" crossorigin="anonymous" type="text/css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css" crossorigin="anonymous" type="text/css">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/bootstrap-table.min.css" integrity="sha384-sN3NwxbjH33ZidqZnPmX+nQ5IF+LoiI7HvZSoZj5wGacmu0/q4RJfsN0xqN+LIa5" crossorigin="anonymous" type="text/css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/bootstrap-table.min.css" crossorigin="anonymous" type="text/css">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.css" integrity="sha384-1sLxvR8mXzjhvFY9f8mzXl97DNLepeZ0PnRiMMdm/rQsKjsrPZPJxYle2wwT2PMg" crossorigin="anonymous" type="text/css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.css" crossorigin="anonymous" type="text/css">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/filter-control/bootstrap-table-filter-control.css" integrity="sha384-4Glx18jZ0Un+yDG6KUpYJ/af8hkssJ02jRASuFv23gfCl0mTXaVMPI9cB4cn3GvE" crossorigin="anonymous" type="text/css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/filter-control/bootstrap-table-filter-control.css" crossorigin="anonymous" type="text/css">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootswatch@5.3.2/dist/cosmo/bootstrap.min.css" integrity="sha384-RfV5VNj9uqyOdZbN0hFNmoq56291KK2Y4iKhoRAbcfBfjYlpasjxK6TefPjxiAiN" crossorigin="anonymous" type="text/css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootswatch@5.3.2/dist/cosmo/bootstrap.min.css" crossorigin="anonymous" type="text/css">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/daterangepicker@3.1.0/daterangepicker.css" integrity="sha384-zLkQsiLfAQqGeIJeKLC+rcCR1YoYaQFLCL7cLDUoKE1ajKJzySpjzWGfYS2vjSG+" crossorigin="anonymous" type="text/css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/daterangepicker@3.1.0/daterangepicker.css" crossorigin="anonymous" type="text/css">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/github.min.css" integrity="sha384-eFTL69TLRZTkNfYZOLM+G04821K1qZao/4QLJbet1pP4tcF+fdXq/9CdqAbWRl/L" crossorigin="anonymous" type="text/css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/github.min.css" crossorigin="anonymous" type="text/css">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.pre-scrollable {
|
.pre-scrollable {
|
||||||
|
@ -584,7 +584,7 @@ _set_new_action() {
|
|||||||
current_action_nargs=1
|
current_action_nargs=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
current_action_args_start_index=$(( $word_index + 1 ))
|
current_action_args_start_index=$(( $word_index + 1 - $pos_only ))
|
||||||
|
|
||||||
current_action_is_positional=$2
|
current_action_is_positional=$2
|
||||||
}
|
}
|
||||||
@ -611,6 +611,7 @@ _shtab_ahriman() {
|
|||||||
|
|
||||||
local prefix=_shtab_ahriman
|
local prefix=_shtab_ahriman
|
||||||
local word_index=0
|
local word_index=0
|
||||||
|
local pos_only=0 # "--" delimeter not encountered yet
|
||||||
_set_parser_defaults
|
_set_parser_defaults
|
||||||
word_index=1
|
word_index=1
|
||||||
|
|
||||||
@ -619,26 +620,30 @@ _shtab_ahriman() {
|
|||||||
while [ $word_index -ne $COMP_CWORD ]; do
|
while [ $word_index -ne $COMP_CWORD ]; do
|
||||||
local this_word="${COMP_WORDS[$word_index]}"
|
local this_word="${COMP_WORDS[$word_index]}"
|
||||||
|
|
||||||
if [[ -n $sub_parsers && " ${sub_parsers[@]} " == *" ${this_word} "* ]]; then
|
if [[ $pos_only = 1 || " $this_word " != " -- " ]]; then
|
||||||
# valid subcommand: add it to the prefix & reset the current action
|
if [[ -n $sub_parsers && " ${sub_parsers[@]} " == *" ${this_word} "* ]]; then
|
||||||
prefix="${prefix}_$(_shtab_replace_nonword $this_word)"
|
# valid subcommand: add it to the prefix & reset the current action
|
||||||
_set_parser_defaults
|
prefix="${prefix}_$(_shtab_replace_nonword $this_word)"
|
||||||
fi
|
_set_parser_defaults
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ " ${current_option_strings[@]} " == *" ${this_word} "* ]]; then
|
if [[ " ${current_option_strings[@]} " == *" ${this_word} "* ]]; then
|
||||||
# a new action should be acquired (due to recognised option string or
|
# a new action should be acquired (due to recognised option string or
|
||||||
# no more input expected from current action);
|
# no more input expected from current action);
|
||||||
# the next positional action can fill in here
|
# the next positional action can fill in here
|
||||||
_set_new_action $this_word false
|
_set_new_action $this_word false
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$current_action_nargs" != "*" ]] && \
|
if [[ "$current_action_nargs" != "*" ]] && \
|
||||||
[[ "$current_action_nargs" != "+" ]] && \
|
[[ "$current_action_nargs" != "+" ]] && \
|
||||||
[[ "$current_action_nargs" != *"..." ]] && \
|
[[ "$current_action_nargs" != *"..." ]] && \
|
||||||
(( $word_index + 1 - $current_action_args_start_index >= \
|
(( $word_index + 1 - $current_action_args_start_index - $pos_only >= \
|
||||||
$current_action_nargs )); then
|
$current_action_nargs )); then
|
||||||
$current_action_is_positional && let "completed_positional_actions += 1"
|
$current_action_is_positional && let "completed_positional_actions += 1"
|
||||||
_set_new_action "pos_${completed_positional_actions}" true
|
_set_new_action "pos_${completed_positional_actions}" true
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
pos_only=1 # "--" delimeter encountered
|
||||||
fi
|
fi
|
||||||
|
|
||||||
let "word_index+=1"
|
let "word_index+=1"
|
||||||
@ -646,7 +651,7 @@ _shtab_ahriman() {
|
|||||||
|
|
||||||
# Generate the completions
|
# Generate the completions
|
||||||
|
|
||||||
if [[ "${completing_word}" == -* ]]; then
|
if [[ $pos_only = 0 && "${completing_word}" == -* ]]; then
|
||||||
# optional argument started: use option strings
|
# optional argument started: use option strings
|
||||||
COMPREPLY=( $(compgen -W "${current_option_strings[*]}" -- "${completing_word}") )
|
COMPREPLY=( $(compgen -W "${current_option_strings[*]}" -- "${completing_word}") )
|
||||||
else
|
else
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH AHRIMAN "1" "2024\-01\-08" "ahriman" "Generated Python Manual"
|
.TH AHRIMAN "1" "2024\-05\-12" "ahriman" "Generated Python Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
ahriman
|
ahriman
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -736,4 +736,12 @@ _shtab_ahriman() {
|
|||||||
|
|
||||||
|
|
||||||
typeset -A opt_args
|
typeset -A opt_args
|
||||||
_shtab_ahriman "$@"
|
|
||||||
|
if [[ $zsh_eval_context[-1] == eval ]]; then
|
||||||
|
# eval/source/. command, register function for later
|
||||||
|
compdef _shtab_ahriman -N ahriman
|
||||||
|
else
|
||||||
|
# autoload from fpath, call function directly
|
||||||
|
_shtab_ahriman "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ web = [
|
|||||||
"aiohttp_security",
|
"aiohttp_security",
|
||||||
"cryptography",
|
"cryptography",
|
||||||
"requests-unixsocket", # required by unix socket support
|
"requests-unixsocket", # required by unix socket support
|
||||||
|
"setuptools", # required by aiohttp-apispec
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.flit.sdist]
|
[tool.flit.sdist]
|
||||||
|
@ -17,4 +17,4 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
__version__ = "2.13.1"
|
__version__ = "2.13.8"
|
||||||
|
@ -163,8 +163,8 @@ class ApplicationRepository(ApplicationProperties):
|
|||||||
built_packages = self.repository.packages_built()
|
built_packages = self.repository.packages_built()
|
||||||
if built_packages: # speedup a bit
|
if built_packages: # speedup a bit
|
||||||
build_result = self.repository.process_update(built_packages, packagers)
|
build_result = self.repository.process_update(built_packages, packagers)
|
||||||
|
self.on_result(build_result)
|
||||||
result.merge(build_result)
|
result.merge(build_result)
|
||||||
self.on_result(result.merge(build_result))
|
|
||||||
|
|
||||||
builder = Updater.load(self.repository_id, self.configuration, self.repository)
|
builder = Updater.load(self.repository_id, self.configuration, self.repository)
|
||||||
|
|
||||||
@ -173,7 +173,8 @@ class ApplicationRepository(ApplicationProperties):
|
|||||||
for num, partition in enumerate(partitions):
|
for num, partition in enumerate(partitions):
|
||||||
self.logger.info("processing chunk #%i %s", num, [package.base for package in partition])
|
self.logger.info("processing chunk #%i %s", num, [package.base for package in partition])
|
||||||
build_result = builder.update(partition, packagers, bump_pkgrel=bump_pkgrel)
|
build_result = builder.update(partition, packagers, bump_pkgrel=bump_pkgrel)
|
||||||
self.on_result(result.merge(build_result))
|
self.on_result(build_result)
|
||||||
|
result.merge(build_result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -102,8 +102,9 @@ class Patch(Handler):
|
|||||||
patch = "".join(list(sys.stdin))
|
patch = "".join(list(sys.stdin))
|
||||||
else:
|
else:
|
||||||
patch = patch_path.read_text(encoding="utf8")
|
patch = patch_path.read_text(encoding="utf8")
|
||||||
patch = patch.strip() # remove spaces around the patch
|
# remove spaces around the patch and parse to correct type
|
||||||
return PkgbuildPatch(variable, patch)
|
parsed = PkgbuildPatch.parse(patch.strip())
|
||||||
|
return PkgbuildPatch(variable, parsed)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def patch_set_create(application: Application, package_base: str, patch: PkgbuildPatch) -> None:
|
def patch_set_create(application: Application, package_base: str, patch: PkgbuildPatch) -> None:
|
||||||
|
@ -68,7 +68,7 @@ class Repo(LazyLogging):
|
|||||||
path(Path): path to archive to add
|
path(Path): path to archive to add
|
||||||
"""
|
"""
|
||||||
check_output(
|
check_output(
|
||||||
"repo-add", *self.sign_args, "-R", str(self.repo_path), str(path),
|
"repo-add", *self.sign_args, "--remove", str(self.repo_path), str(path),
|
||||||
exception=BuildError.from_process(path.name),
|
exception=BuildError.from_process(path.name),
|
||||||
cwd=self.paths.repository,
|
cwd=self.paths.repository,
|
||||||
logger=self.logger,
|
logger=self.logger,
|
||||||
@ -78,8 +78,13 @@ class Repo(LazyLogging):
|
|||||||
"""
|
"""
|
||||||
create empty repository database. It just calls add with empty arguments
|
create empty repository database. It just calls add with empty arguments
|
||||||
"""
|
"""
|
||||||
check_output("repo-add", *self.sign_args, str(self.repo_path),
|
# since pacman-6.1.0 repo-add doesn't create empty database in case if no packages supplied
|
||||||
cwd=self.paths.repository, logger=self.logger, user=self.uid)
|
# this code creates empty files instead
|
||||||
|
if self.repo_path.exists():
|
||||||
|
return # database is already created, skip this part
|
||||||
|
|
||||||
|
self.repo_path.touch(exist_ok=True)
|
||||||
|
(self.paths.repository / f"{self.name}.db").symlink_to(self.repo_path)
|
||||||
|
|
||||||
def remove(self, package: str, filename: Path) -> None:
|
def remove(self, package: str, filename: Path) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -69,7 +69,8 @@ class OAuth(Mapping):
|
|||||||
Returns:
|
Returns:
|
||||||
str: login control as html code to insert
|
str: login control as html code to insert
|
||||||
"""
|
"""
|
||||||
return f"""<a class="nav-link" href="/api/v1/login" title="login via OAuth2"><i class="bi bi-{self.icon}"></i> login</a>"""
|
return f"""<a class="nav-link" href="/api/v1/login" title="login via OAuth2"><i class="bi bi-{
|
||||||
|
self.icon}"></i> login</a>"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_provider(name: str) -> type[aioauth_client.OAuth2Client]:
|
def get_provider(name: str) -> type[aioauth_client.OAuth2Client]:
|
||||||
|
@ -38,6 +38,7 @@ class Task(LazyLogging):
|
|||||||
archbuild_flags(list[str]): command flags for archbuild command
|
archbuild_flags(list[str]): command flags for archbuild command
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
build_command(str): build command
|
build_command(str): build command
|
||||||
|
include_debug_packages(bool): whether to include debug packages or not
|
||||||
makechrootpkg_flags(list[str]): command flags for makechrootpkg command
|
makechrootpkg_flags(list[str]): command flags for makechrootpkg command
|
||||||
makepkg_flags(list[str]): command flags for makepkg command
|
makepkg_flags(list[str]): command flags for makepkg command
|
||||||
package(Package): package definitions
|
package(Package): package definitions
|
||||||
@ -63,6 +64,7 @@ class Task(LazyLogging):
|
|||||||
|
|
||||||
self.archbuild_flags = configuration.getlist("build", "archbuild_flags", fallback=[])
|
self.archbuild_flags = configuration.getlist("build", "archbuild_flags", fallback=[])
|
||||||
self.build_command = configuration.get("build", "build_command")
|
self.build_command = configuration.get("build", "build_command")
|
||||||
|
self.include_debug_packages = configuration.getboolean("build", "include_debug_packages", fallback=True)
|
||||||
self.makepkg_flags = configuration.getlist("build", "makepkg_flags", fallback=[])
|
self.makepkg_flags = configuration.getlist("build", "makepkg_flags", fallback=[])
|
||||||
self.makechrootpkg_flags = configuration.getlist("build", "makechrootpkg_flags", fallback=[])
|
self.makechrootpkg_flags = configuration.getlist("build", "makechrootpkg_flags", fallback=[])
|
||||||
|
|
||||||
@ -99,15 +101,20 @@ class Task(LazyLogging):
|
|||||||
environment=environment,
|
environment=environment,
|
||||||
)
|
)
|
||||||
|
|
||||||
# well it is not actually correct, but we can deal with it
|
package_list_command = ["makepkg", "--packagelist"]
|
||||||
|
if not self.include_debug_packages:
|
||||||
|
package_list_command.append("OPTIONS=(!debug)") # disable debug flag manually
|
||||||
packages = check_output(
|
packages = check_output(
|
||||||
"makepkg", "--packagelist",
|
*package_list_command,
|
||||||
exception=BuildError.from_process(self.package.base),
|
exception=BuildError.from_process(self.package.base),
|
||||||
cwd=sources_dir,
|
cwd=sources_dir,
|
||||||
logger=self.logger,
|
logger=self.logger,
|
||||||
environment=environment,
|
environment=environment,
|
||||||
).splitlines()
|
).splitlines()
|
||||||
return [Path(package) for package in packages]
|
# some dirty magic here
|
||||||
|
# the filter is applied in order to make sure that result will only contain packages which were actually built
|
||||||
|
# e.g. in some cases packagelist command produces debug packages which were not actually built
|
||||||
|
return list(filter(lambda path: path.is_file(), map(Path, packages)))
|
||||||
|
|
||||||
def init(self, sources_dir: Path, database: SQLite, local_version: str | None) -> str | None:
|
def init(self, sources_dir: Path, database: SQLite, local_version: str | None) -> str | None:
|
||||||
"""
|
"""
|
||||||
|
@ -176,6 +176,10 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = {
|
|||||||
"empty": False,
|
"empty": False,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"include_debug_packages": {
|
||||||
|
"type": "boolean",
|
||||||
|
"coerce": "boolean",
|
||||||
|
},
|
||||||
"makepkg_flags": {
|
"makepkg_flags": {
|
||||||
"type": "list",
|
"type": "list",
|
||||||
"coerce": "list",
|
"coerce": "list",
|
||||||
|
@ -330,5 +330,5 @@ class UnsafeRunError(RuntimeError):
|
|||||||
root_uid(int): ID of the owner of root directory
|
root_uid(int): ID of the owner of root directory
|
||||||
"""
|
"""
|
||||||
RuntimeError.__init__(self, f"Current UID {current_uid} differs from root owner {root_uid}. "
|
RuntimeError.__init__(self, f"Current UID {current_uid} differs from root owner {root_uid}. "
|
||||||
f"Note that for the most actions it is unsafe to run application as different user."
|
f"Note that for the most actions it is unsafe to run application as different user."
|
||||||
f" If you are 100% sure that it must be there try --unsafe option")
|
f" If you are 100% sure that it must be there try --unsafe option")
|
||||||
|
@ -106,7 +106,7 @@ class RemoteCall(Report):
|
|||||||
"aur": self.update_aur,
|
"aur": self.update_aur,
|
||||||
"local": self.update_local,
|
"local": self.update_local,
|
||||||
"manual": self.update_manual,
|
"manual": self.update_manual,
|
||||||
})
|
})
|
||||||
response_json = response.json()
|
response_json = response.json()
|
||||||
|
|
||||||
process_id: str = response_json["process_id"]
|
process_id: str = response_json["process_id"]
|
||||||
|
@ -117,7 +117,8 @@ class Executor(PackageInfo, Cleaner):
|
|||||||
|
|
||||||
# build package list based on user input
|
# build package list based on user input
|
||||||
result = Result()
|
result = Result()
|
||||||
requested = set(packages)
|
packages = set(packages) # remove duplicates
|
||||||
|
requested = packages | {f"{package}-debug" for package in packages} # append debug packages
|
||||||
for local in self.packages():
|
for local in self.packages():
|
||||||
if local.base in packages or all(package in requested for package in local.packages):
|
if local.base in packages or all(package in requested for package in local.packages):
|
||||||
packages_to_remove.update({
|
packages_to_remove.update({
|
||||||
@ -136,7 +137,7 @@ class Executor(PackageInfo, Cleaner):
|
|||||||
|
|
||||||
# check for packages which were requested to remove, but weren't found locally
|
# check for packages which were requested to remove, but weren't found locally
|
||||||
# it might happen for example, if there were no success build before
|
# it might happen for example, if there were no success build before
|
||||||
for unknown in requested:
|
for unknown in packages:
|
||||||
if unknown in packages_to_remove or unknown in bases_to_remove:
|
if unknown in packages_to_remove or unknown in bases_to_remove:
|
||||||
continue
|
continue
|
||||||
bases_to_remove.append(unknown)
|
bases_to_remove.append(unknown)
|
||||||
|
@ -183,11 +183,12 @@ post_install() {{
|
|||||||
Returns:
|
Returns:
|
||||||
str: package() function for PKGBUILD
|
str: package() function for PKGBUILD
|
||||||
"""
|
"""
|
||||||
|
# somehow autopep thinks that construction inside contains valid python code and reformats it
|
||||||
return f"""{{
|
return f"""{{
|
||||||
install -Dm644 "{Path("$srcdir") / f"{self.name}.gpg"}" "{Path("$pkgdir") / "usr" / "share" / "pacman" / "keyrings" / f"{self.name}.gpg"}"
|
install -Dm644 "{Path("$srcdir") / f"{self.name}.gpg"}" "{Path("$pkgdir") / "usr" / "share" / "pacman" / "keyrings" / f"{self.name}.gpg"}"
|
||||||
install -Dm644 "{Path("$srcdir") / f"{self.name}-revoked"}" "{Path("$pkgdir") / "usr" / "share" / "pacman" / "keyrings" / f"{self.name}-revoked"}"
|
install -Dm644 "{Path("$srcdir") / f"{self.name}-revoked"}" "{Path("$pkgdir") / "usr" / "share" / "pacman" / "keyrings" / f"{self.name}-revoked"}"
|
||||||
install -Dm644 "{Path("$srcdir") / f"{self.name}-trusted"}" "{Path("$pkgdir") / "usr" / "share" / "pacman" / "keyrings" / f"{self.name}-trusted"}"
|
install -Dm644 "{Path("$srcdir") / f"{self.name}-trusted"}" "{Path("$pkgdir") / "usr" / "share" / "pacman" / "keyrings" / f"{self.name}-trusted"}"
|
||||||
}}"""
|
}}""" # nopep8
|
||||||
|
|
||||||
def sources(self) -> dict[str, Callable[[Path], None]]:
|
def sources(self) -> dict[str, Callable[[Path], None]]:
|
||||||
"""
|
"""
|
||||||
|
@ -162,7 +162,8 @@ class GitHub(Upload, HttpUpload):
|
|||||||
Returns:
|
Returns:
|
||||||
dict[str, Any] | None: GitHub API release object if release found and None otherwise
|
dict[str, Any] | None: GitHub API release object if release found and None otherwise
|
||||||
"""
|
"""
|
||||||
url = f"https://api.github.com/repos/{self.github_owner}/{self.github_repository}/releases/tags/{self.github_release_tag}"
|
url = f"https://api.github.com/repos/{self.github_owner}/{
|
||||||
|
self.github_repository}/releases/tags/{self.github_release_tag}"
|
||||||
try:
|
try:
|
||||||
response = self.make_request("GET", url)
|
response = self.make_request("GET", url)
|
||||||
release: dict[str, Any] = response.json()
|
release: dict[str, Any] = response.json()
|
||||||
|
@ -56,7 +56,6 @@ __all__ = [
|
|||||||
"srcinfo_property",
|
"srcinfo_property",
|
||||||
"srcinfo_property_list",
|
"srcinfo_property_list",
|
||||||
"trim_package",
|
"trim_package",
|
||||||
"unquote",
|
|
||||||
"utcnow",
|
"utcnow",
|
||||||
"walk",
|
"walk",
|
||||||
]
|
]
|
||||||
@ -349,7 +348,7 @@ def pretty_datetime(timestamp: datetime.datetime | float | int | None) -> str:
|
|||||||
if timestamp is None:
|
if timestamp is None:
|
||||||
return ""
|
return ""
|
||||||
if isinstance(timestamp, (int, float)):
|
if isinstance(timestamp, (int, float)):
|
||||||
timestamp = datetime.datetime.utcfromtimestamp(timestamp)
|
timestamp = datetime.datetime.fromtimestamp(timestamp, datetime.UTC)
|
||||||
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
|
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
|
|
||||||
@ -466,38 +465,6 @@ def trim_package(package_name: str) -> str:
|
|||||||
return package_name
|
return package_name
|
||||||
|
|
||||||
|
|
||||||
def unquote(source: str) -> str:
|
|
||||||
"""
|
|
||||||
like :func:`shlex.quote()`, but opposite
|
|
||||||
|
|
||||||
Args:
|
|
||||||
source(str): source string to remove quotes
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: string with quotes removed
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
ValueError: if no closing quotation
|
|
||||||
"""
|
|
||||||
def generator() -> Generator[str, None, None]:
|
|
||||||
token = None
|
|
||||||
for char in source:
|
|
||||||
if token is not None:
|
|
||||||
if char == token:
|
|
||||||
token = None # closed quote
|
|
||||||
else:
|
|
||||||
yield char # character inside quotes
|
|
||||||
elif char in ("'", "\""):
|
|
||||||
token = char # first quote found
|
|
||||||
else:
|
|
||||||
yield char # normal character
|
|
||||||
|
|
||||||
if token is not None:
|
|
||||||
raise ValueError("No closing quotation")
|
|
||||||
|
|
||||||
return "".join(generator())
|
|
||||||
|
|
||||||
|
|
||||||
def utcnow() -> datetime.datetime:
|
def utcnow() -> datetime.datetime:
|
||||||
"""
|
"""
|
||||||
get current time
|
get current time
|
||||||
@ -505,7 +472,7 @@ def utcnow() -> datetime.datetime:
|
|||||||
Returns:
|
Returns:
|
||||||
datetime.datetime: current time in UTC
|
datetime.datetime: current time in UTC
|
||||||
"""
|
"""
|
||||||
return datetime.datetime.utcnow()
|
return datetime.datetime.now(datetime.UTC)
|
||||||
|
|
||||||
|
|
||||||
def walk(directory_path: Path) -> Generator[Path, None, None]:
|
def walk(directory_path: Path) -> Generator[Path, None, None]:
|
||||||
|
@ -137,8 +137,8 @@ class AURPackage:
|
|||||||
description=package.desc,
|
description=package.desc,
|
||||||
num_votes=0,
|
num_votes=0,
|
||||||
popularity=0.0,
|
popularity=0.0,
|
||||||
first_submitted=datetime.datetime.utcfromtimestamp(0),
|
first_submitted=datetime.datetime.fromtimestamp(0, datetime.UTC),
|
||||||
last_modified=datetime.datetime.utcfromtimestamp(package.builddate),
|
last_modified=datetime.datetime.fromtimestamp(package.builddate, datetime.UTC),
|
||||||
url_path="",
|
url_path="",
|
||||||
url=package.url,
|
url=package.url,
|
||||||
out_of_date=None,
|
out_of_date=None,
|
||||||
@ -175,13 +175,11 @@ class AURPackage:
|
|||||||
description=dump["pkgdesc"],
|
description=dump["pkgdesc"],
|
||||||
num_votes=0,
|
num_votes=0,
|
||||||
popularity=0.0,
|
popularity=0.0,
|
||||||
first_submitted=datetime.datetime.utcfromtimestamp(0),
|
first_submitted=datetime.datetime.fromtimestamp(0, datetime.UTC),
|
||||||
last_modified=datetime.datetime.strptime(dump["last_update"], "%Y-%m-%dT%H:%M:%S.%fZ"),
|
last_modified=datetime.datetime.fromisoformat(dump["last_update"]),
|
||||||
url_path="",
|
url_path="",
|
||||||
url=dump["url"],
|
url=dump["url"],
|
||||||
out_of_date=datetime.datetime.strptime(
|
out_of_date=datetime.datetime.fromisoformat(dump["flag_date"]) if dump.get("flag_date") else None,
|
||||||
dump["flag_date"],
|
|
||||||
"%Y-%m-%dT%H:%M:%S.%fZ") if dump["flag_date"] is not None else None,
|
|
||||||
maintainer=next(iter(dump["maintainers"]), None),
|
maintainer=next(iter(dump["maintainers"]), None),
|
||||||
submitter=None,
|
submitter=None,
|
||||||
repository=dump["repo"],
|
repository=dump["repo"],
|
||||||
@ -208,9 +206,9 @@ class AURPackage:
|
|||||||
"""
|
"""
|
||||||
identity_mapper: Callable[[Any], Any] = lambda value: value
|
identity_mapper: Callable[[Any], Any] = lambda value: value
|
||||||
value_mapper: dict[str, Callable[[Any], Any]] = {
|
value_mapper: dict[str, Callable[[Any], Any]] = {
|
||||||
"out_of_date": lambda value: datetime.datetime.utcfromtimestamp(value) if value is not None else None,
|
"out_of_date": lambda value: datetime.datetime.fromtimestamp(value, datetime.UTC) if value is not None else None,
|
||||||
"first_submitted": datetime.datetime.utcfromtimestamp,
|
"first_submitted": lambda value: datetime.datetime.fromtimestamp(value, datetime.UTC),
|
||||||
"last_modified": datetime.datetime.utcfromtimestamp,
|
"last_modified": lambda value: datetime.datetime.fromtimestamp(value, datetime.UTC),
|
||||||
}
|
}
|
||||||
|
|
||||||
result: dict[str, Any] = {}
|
result: dict[str, Any] = {}
|
||||||
|
@ -21,9 +21,9 @@ import shlex
|
|||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Self
|
from typing import Any, Generator, Self
|
||||||
|
|
||||||
from ahriman.core.util import dataclass_view, unquote
|
from ahriman.core.util import dataclass_view
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
@ -81,14 +81,57 @@ class PkgbuildPatch:
|
|||||||
Self: package properties
|
Self: package properties
|
||||||
"""
|
"""
|
||||||
key, *value_parts = variable.split("=", maxsplit=1)
|
key, *value_parts = variable.split("=", maxsplit=1)
|
||||||
|
|
||||||
raw_value = next(iter(value_parts), "") # extract raw value
|
raw_value = next(iter(value_parts), "") # extract raw value
|
||||||
if raw_value.startswith("(") and raw_value.endswith(")"):
|
return cls(key, cls.parse(raw_value))
|
||||||
value: str | list[str] = shlex.split(raw_value[1:-1]) # arrays for poor
|
|
||||||
else:
|
|
||||||
value = unquote(raw_value)
|
|
||||||
|
|
||||||
return cls(key, value)
|
@staticmethod
|
||||||
|
def parse(source: str) -> str | list[str]:
|
||||||
|
"""
|
||||||
|
parse string value to the PKGBUILD patch value. This method simply takes string, tries to identify it as array
|
||||||
|
or just string and return the respective value. Functions should be processed correctly, however, not guaranteed
|
||||||
|
|
||||||
|
Args:
|
||||||
|
source(str): source string to parse
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str | list[str]: parsed value either string or list of strings
|
||||||
|
"""
|
||||||
|
if source.startswith("(") and source.endswith(")"):
|
||||||
|
return shlex.split(source[1:-1]) # arrays for poor
|
||||||
|
return PkgbuildPatch.unquote(source)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def unquote(source: str) -> str:
|
||||||
|
"""
|
||||||
|
like :func:`shlex.quote()`, but opposite
|
||||||
|
|
||||||
|
Args:
|
||||||
|
source(str): source string to remove quotes
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: string with quotes removed
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: if no closing quotation
|
||||||
|
"""
|
||||||
|
|
||||||
|
def generator() -> Generator[str, None, None]:
|
||||||
|
token = None
|
||||||
|
for char in source:
|
||||||
|
if token is not None:
|
||||||
|
if char == token:
|
||||||
|
token = None # closed quote
|
||||||
|
else:
|
||||||
|
yield char # character inside quotes
|
||||||
|
elif char in ("'", "\""):
|
||||||
|
token = char # first quote found
|
||||||
|
else:
|
||||||
|
yield char # normal character
|
||||||
|
|
||||||
|
if token is not None:
|
||||||
|
raise ValueError("No closing quotation")
|
||||||
|
|
||||||
|
return "".join(generator())
|
||||||
|
|
||||||
def serialize(self) -> str:
|
def serialize(self) -> str:
|
||||||
"""
|
"""
|
||||||
|
19
src/ahriman/web/views/v2/packages/__init__.py
Normal file
19
src/ahriman/web/views/v2/packages/__init__.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2021-2024 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/>.
|
||||||
|
#
|
@ -122,11 +122,10 @@ def test_patch_create_from_function(mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
must create function patch from file
|
must create function patch from file
|
||||||
"""
|
"""
|
||||||
path = Path("local")
|
|
||||||
patch = PkgbuildPatch("version", "patch")
|
patch = PkgbuildPatch("version", "patch")
|
||||||
read_mock = mocker.patch("pathlib.Path.read_text", return_value=patch.value)
|
read_mock = mocker.patch("pathlib.Path.read_text", return_value=patch.value)
|
||||||
|
|
||||||
assert Patch.patch_create_from_function(patch.key, path) == patch
|
assert Patch.patch_create_from_function(patch.key, Path("local")) == patch
|
||||||
read_mock.assert_called_once_with(encoding="utf8")
|
read_mock.assert_called_once_with(encoding="utf8")
|
||||||
|
|
||||||
|
|
||||||
@ -148,6 +147,15 @@ def test_patch_create_from_function_strip(mocker: MockerFixture) -> None:
|
|||||||
assert Patch.patch_create_from_function(patch.key, None) == patch
|
assert Patch.patch_create_from_function(patch.key, None) == patch
|
||||||
|
|
||||||
|
|
||||||
|
def test_patch_create_from_function_array(mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must correctly read array variable
|
||||||
|
"""
|
||||||
|
patch = PkgbuildPatch("version", ["array", "patch"])
|
||||||
|
mocker.patch("pathlib.Path.read_text", return_value=f"({" ".join(patch.value)})")
|
||||||
|
assert Patch.patch_create_from_function(patch.key, Path("local")) == patch
|
||||||
|
|
||||||
|
|
||||||
def test_patch_set_list(application: Application, mocker: MockerFixture) -> None:
|
def test_patch_set_list(application: Application, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must list available patches for the command
|
must list available patches for the command
|
||||||
|
@ -133,8 +133,8 @@ def aur_package_ahriman() -> AURPackage:
|
|||||||
description="ArcH linux ReposItory MANager",
|
description="ArcH linux ReposItory MANager",
|
||||||
num_votes=0,
|
num_votes=0,
|
||||||
popularity=0,
|
popularity=0,
|
||||||
first_submitted=datetime.datetime.utcfromtimestamp(1618008285),
|
first_submitted=datetime.datetime.fromtimestamp(1618008285, datetime.UTC),
|
||||||
last_modified=datetime.datetime.utcfromtimestamp(1673826351),
|
last_modified=datetime.datetime.fromtimestamp(1673826351, datetime.UTC),
|
||||||
url_path="/cgit/aur.git/snapshot/ahriman.tar.gz",
|
url_path="/cgit/aur.git/snapshot/ahriman.tar.gz",
|
||||||
url="https://github.com/arcan1s/ahriman",
|
url="https://github.com/arcan1s/ahriman",
|
||||||
out_of_date=None,
|
out_of_date=None,
|
||||||
@ -200,8 +200,8 @@ def aur_package_akonadi() -> AURPackage:
|
|||||||
description="PIM layer, which provides an asynchronous API to access all kind of PIM data",
|
description="PIM layer, which provides an asynchronous API to access all kind of PIM data",
|
||||||
num_votes=0,
|
num_votes=0,
|
||||||
popularity=0.0,
|
popularity=0.0,
|
||||||
first_submitted=datetime.datetime.utcfromtimestamp(0),
|
first_submitted=datetime.datetime.fromtimestamp(0, datetime.UTC),
|
||||||
last_modified=datetime.datetime.utcfromtimestamp(1646555990.610),
|
last_modified=datetime.datetime.fromtimestamp(1646555990.610, datetime.UTC),
|
||||||
url_path="",
|
url_path="",
|
||||||
url="https://kontact.kde.org",
|
url="https://kontact.kde.org",
|
||||||
out_of_date=None,
|
out_of_date=None,
|
||||||
|
@ -26,13 +26,28 @@ def test_repo_add(repo: Repo, mocker: MockerFixture) -> None:
|
|||||||
|
|
||||||
def test_repo_init(repo: Repo, mocker: MockerFixture) -> None:
|
def test_repo_init(repo: Repo, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must call repo-add with empty package list on repo initializing
|
must create empty database files
|
||||||
"""
|
"""
|
||||||
check_output_mock = mocker.patch("ahriman.core.alpm.repo.check_output")
|
mocker.patch("pathlib.Path.exists", return_value=False)
|
||||||
|
touch_mock = mocker.patch("pathlib.Path.touch")
|
||||||
|
symlink_mock = mocker.patch("pathlib.Path.symlink_to")
|
||||||
|
|
||||||
repo.init()
|
repo.init()
|
||||||
check_output_mock.assert_called_once() # it will be checked later
|
touch_mock.assert_called_once_with(exist_ok=True)
|
||||||
assert check_output_mock.call_args[0][0] == "repo-add"
|
symlink_mock.assert_called_once_with(repo.repo_path)
|
||||||
|
|
||||||
|
|
||||||
|
def test_repo_init_skip(repo: Repo, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must do not create files if database already exists
|
||||||
|
"""
|
||||||
|
mocker.patch("pathlib.Path.exists", return_value=True)
|
||||||
|
touch_mock = mocker.patch("pathlib.Path.touch")
|
||||||
|
symlink_mock = mocker.patch("pathlib.Path.symlink_to")
|
||||||
|
|
||||||
|
repo.init()
|
||||||
|
touch_mock.assert_not_called()
|
||||||
|
symlink_mock.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_repo_remove(repo: Repo, mocker: MockerFixture) -> None:
|
def test_repo_remove(repo: Repo, mocker: MockerFixture) -> None:
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
from unittest.mock import call as MockCall
|
||||||
|
|
||||||
from ahriman.core.build_tools.task import Task
|
from ahriman.core.build_tools.task import Task
|
||||||
from ahriman.core.database import SQLite
|
from ahriman.core.database import SQLite
|
||||||
@ -9,9 +12,83 @@ def test_build(task_ahriman: Task, mocker: MockerFixture) -> None:
|
|||||||
"""
|
"""
|
||||||
must build package
|
must build package
|
||||||
"""
|
"""
|
||||||
|
local = Path("local")
|
||||||
check_output_mock = mocker.patch("ahriman.core.build_tools.task.check_output")
|
check_output_mock = mocker.patch("ahriman.core.build_tools.task.check_output")
|
||||||
task_ahriman.build(Path("ahriman"))
|
|
||||||
check_output_mock.assert_called()
|
task_ahriman.build(local)
|
||||||
|
check_output_mock.assert_has_calls([
|
||||||
|
MockCall(
|
||||||
|
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck",
|
||||||
|
exception=pytest.helpers.anyvar(int),
|
||||||
|
cwd=local,
|
||||||
|
logger=task_ahriman.logger,
|
||||||
|
user=task_ahriman.uid,
|
||||||
|
environment={},
|
||||||
|
),
|
||||||
|
MockCall(
|
||||||
|
"makepkg", "--packagelist",
|
||||||
|
exception=pytest.helpers.anyvar(int),
|
||||||
|
cwd=local,
|
||||||
|
logger=task_ahriman.logger,
|
||||||
|
environment={},
|
||||||
|
),
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_environment(task_ahriman: Task, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must build package with environment variables set
|
||||||
|
"""
|
||||||
|
local = Path("local")
|
||||||
|
check_output_mock = mocker.patch("ahriman.core.build_tools.task.check_output")
|
||||||
|
environment = {"variable": "value"}
|
||||||
|
|
||||||
|
task_ahriman.build(local, **environment, empty=None)
|
||||||
|
check_output_mock.assert_has_calls([
|
||||||
|
MockCall(
|
||||||
|
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck",
|
||||||
|
exception=pytest.helpers.anyvar(int),
|
||||||
|
cwd=local,
|
||||||
|
logger=task_ahriman.logger,
|
||||||
|
user=task_ahriman.uid,
|
||||||
|
environment=environment,
|
||||||
|
),
|
||||||
|
MockCall(
|
||||||
|
"makepkg", "--packagelist",
|
||||||
|
exception=pytest.helpers.anyvar(int),
|
||||||
|
cwd=local,
|
||||||
|
logger=task_ahriman.logger,
|
||||||
|
environment=environment,
|
||||||
|
),
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_no_debug(task_ahriman: Task, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must filter debug packages from result
|
||||||
|
"""
|
||||||
|
local = Path("local")
|
||||||
|
check_output_mock = mocker.patch("ahriman.core.build_tools.task.check_output")
|
||||||
|
task_ahriman.include_debug_packages = False
|
||||||
|
|
||||||
|
task_ahriman.build(local)
|
||||||
|
check_output_mock.assert_has_calls([
|
||||||
|
MockCall(
|
||||||
|
"extra-x86_64-build", "-r", str(task_ahriman.paths.chroot), "--", "--", "--skippgpcheck",
|
||||||
|
exception=pytest.helpers.anyvar(int),
|
||||||
|
cwd=local,
|
||||||
|
logger=task_ahriman.logger,
|
||||||
|
user=task_ahriman.uid,
|
||||||
|
environment={},
|
||||||
|
),
|
||||||
|
MockCall(
|
||||||
|
"makepkg", "--packagelist", "OPTIONS=(!debug)",
|
||||||
|
exception=pytest.helpers.anyvar(int),
|
||||||
|
cwd=local,
|
||||||
|
logger=task_ahriman.logger,
|
||||||
|
environment={},
|
||||||
|
),
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def test_init(task_ahriman: Task, database: SQLite, mocker: MockerFixture) -> None:
|
def test_init(task_ahriman: Task, database: SQLite, mocker: MockerFixture) -> None:
|
||||||
|
@ -85,7 +85,7 @@ def test_remote_update(remote_call: RemoteCall, mocker: MockerFixture) -> None:
|
|||||||
"aur": False,
|
"aur": False,
|
||||||
"local": False,
|
"local": False,
|
||||||
"manual": True,
|
"manual": True,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def test_remote_wait(remote_call: RemoteCall, mocker: MockerFixture) -> None:
|
def test_remote_wait(remote_call: RemoteCall, mocker: MockerFixture) -> None:
|
||||||
|
@ -89,6 +89,28 @@ def test_process_remove_base(executor: Executor, package_ahriman: Package, mocke
|
|||||||
commit_sha_mock.assert_called_once_with(package_ahriman.base)
|
commit_sha_mock.assert_called_once_with(package_ahriman.base)
|
||||||
|
|
||||||
|
|
||||||
|
def test_process_remove_with_debug(executor: Executor, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must run remove debug packages too
|
||||||
|
"""
|
||||||
|
package_ahriman.packages = {
|
||||||
|
package_ahriman.base: package_ahriman.packages[package_ahriman.base],
|
||||||
|
f"{package_ahriman.base}-debug": package_ahriman.packages[package_ahriman.base],
|
||||||
|
}
|
||||||
|
mocker.patch("ahriman.core.repository.executor.Executor.packages", return_value=[package_ahriman])
|
||||||
|
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_clear")
|
||||||
|
mocker.patch("ahriman.core.database.SQLite.package_clear")
|
||||||
|
mocker.patch("ahriman.core.status.client.Client.package_remove")
|
||||||
|
repo_remove_mock = mocker.patch("ahriman.core.alpm.repo.Repo.remove")
|
||||||
|
|
||||||
|
executor.process_remove([package_ahriman.base])
|
||||||
|
# must remove via alpm wrapper
|
||||||
|
repo_remove_mock.assert_has_calls([
|
||||||
|
MockCall(package_ahriman.base, package_ahriman.packages[package_ahriman.base].filepath),
|
||||||
|
MockCall(f"{package_ahriman.base}-debug", package_ahriman.packages[package_ahriman.base].filepath),
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def test_process_remove_base_multiple(executor: Executor, package_python_schedule: Package,
|
def test_process_remove_base_multiple(executor: Executor, package_python_schedule: Package,
|
||||||
mocker: MockerFixture) -> None:
|
mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -6,7 +6,6 @@ from pytest_mock import MockerFixture
|
|||||||
from unittest.mock import MagicMock, call as MockCall
|
from unittest.mock import MagicMock, call as MockCall
|
||||||
|
|
||||||
from ahriman.core.support.pkgbuild.pkgbuild_generator import PkgbuildGenerator
|
from ahriman.core.support.pkgbuild.pkgbuild_generator import PkgbuildGenerator
|
||||||
from ahriman.core.util import utcnow
|
|
||||||
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||||
|
|
||||||
|
|
||||||
@ -38,7 +37,7 @@ def test_pkgver(pkgbuild_generator: PkgbuildGenerator, mocker: MockerFixture) ->
|
|||||||
must implement default version as current date
|
must implement default version as current date
|
||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.core.support.pkgbuild.pkgbuild_generator.utcnow", return_value=datetime.datetime(2002, 3, 11))
|
mocker.patch("ahriman.core.support.pkgbuild.pkgbuild_generator.utcnow", return_value=datetime.datetime(2002, 3, 11))
|
||||||
assert pkgbuild_generator.pkgver == utcnow().strftime("20020311")
|
assert pkgbuild_generator.pkgver == "20020311"
|
||||||
|
|
||||||
|
|
||||||
def test_url(pkgbuild_generator: PkgbuildGenerator) -> None:
|
def test_url(pkgbuild_generator: PkgbuildGenerator) -> None:
|
||||||
|
@ -12,7 +12,7 @@ from unittest.mock import call as MockCall
|
|||||||
from ahriman.core.exceptions import BuildError, CalledProcessError, OptionError, UnsafeRunError
|
from ahriman.core.exceptions import BuildError, CalledProcessError, OptionError, UnsafeRunError
|
||||||
from ahriman.core.util import check_output, check_user, dataclass_view, enum_values, extract_user, filter_json, \
|
from ahriman.core.util 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, \
|
full_version, minmax, package_like, parse_version, partition, pretty_datetime, pretty_size, safe_filename, \
|
||||||
srcinfo_property, srcinfo_property_list, trim_package, unquote, utcnow, walk
|
srcinfo_property, srcinfo_property_list, trim_package, utcnow, walk
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
from ahriman.models.package_source import PackageSource
|
from ahriman.models.package_source import PackageSource
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
@ -445,26 +445,6 @@ def test_trim_package() -> None:
|
|||||||
assert trim_package("package: a description") == "package"
|
assert trim_package("package: a description") == "package"
|
||||||
|
|
||||||
|
|
||||||
def test_unquote() -> None:
|
|
||||||
"""
|
|
||||||
must remove quotation marks
|
|
||||||
"""
|
|
||||||
for source in (
|
|
||||||
"abc",
|
|
||||||
"ab'c",
|
|
||||||
"ab\"c",
|
|
||||||
):
|
|
||||||
assert unquote(shlex.quote(source)) == source
|
|
||||||
|
|
||||||
|
|
||||||
def test_unquote_error() -> None:
|
|
||||||
"""
|
|
||||||
must raise value error on invalid quotation
|
|
||||||
"""
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
unquote("ab'c")
|
|
||||||
|
|
||||||
|
|
||||||
def test_utcnow() -> None:
|
def test_utcnow() -> None:
|
||||||
"""
|
"""
|
||||||
must generate correct timestamp
|
must generate correct timestamp
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
import pytest
|
||||||
|
import shlex
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import MagicMock, call
|
from unittest.mock import MagicMock, call
|
||||||
@ -48,6 +51,35 @@ def test_from_env() -> None:
|
|||||||
assert PkgbuildPatch.from_env("KEY") == PkgbuildPatch("KEY", "")
|
assert PkgbuildPatch.from_env("KEY") == PkgbuildPatch("KEY", "")
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse() -> None:
|
||||||
|
"""
|
||||||
|
must parse string correctly
|
||||||
|
"""
|
||||||
|
assert PkgbuildPatch.parse("VALUE") == "VALUE"
|
||||||
|
assert PkgbuildPatch.parse("(ARRAY VALUE)") == ["ARRAY", "VALUE"]
|
||||||
|
assert PkgbuildPatch.parse("""("QU'OUTED" ARRAY VALUE)""") == ["QU'OUTED", "ARRAY", "VALUE"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_unquote() -> None:
|
||||||
|
"""
|
||||||
|
must remove quotation marks
|
||||||
|
"""
|
||||||
|
for source in (
|
||||||
|
"abc",
|
||||||
|
"ab'c",
|
||||||
|
"ab\"c",
|
||||||
|
):
|
||||||
|
assert PkgbuildPatch.unquote(shlex.quote(source)) == source
|
||||||
|
|
||||||
|
|
||||||
|
def test_unquote_error() -> None:
|
||||||
|
"""
|
||||||
|
must raise value error on invalid quotation
|
||||||
|
"""
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
PkgbuildPatch.unquote("ab'c")
|
||||||
|
|
||||||
|
|
||||||
def test_serialize() -> None:
|
def test_serialize() -> None:
|
||||||
"""
|
"""
|
||||||
must correctly serialize string values
|
must correctly serialize string values
|
||||||
|
@ -6,7 +6,7 @@ from ahriman.models.build_status import BuildStatusEnum
|
|||||||
from ahriman.models.changes import Changes
|
from ahriman.models.changes import Changes
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
from ahriman.models.user_access import UserAccess
|
from ahriman.models.user_access import UserAccess
|
||||||
from ahriman.web.views.v1.status.changes import ChangesView
|
from ahriman.web.views.v1.packages.changes import ChangesView
|
||||||
|
|
||||||
|
|
||||||
async def test_get_permission() -> None:
|
async def test_get_permission() -> None:
|
@ -5,7 +5,7 @@ from aiohttp.test_utils import TestClient
|
|||||||
from ahriman.models.build_status import BuildStatusEnum
|
from ahriman.models.build_status import BuildStatusEnum
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
from ahriman.models.user_access import UserAccess
|
from ahriman.models.user_access import UserAccess
|
||||||
from ahriman.web.views.v1.status.logs import LogsView
|
from ahriman.web.views.v1.packages.logs import LogsView
|
||||||
|
|
||||||
|
|
||||||
async def test_get_permission() -> None:
|
async def test_get_permission() -> None:
|
@ -6,7 +6,7 @@ from ahriman.models.build_status import BuildStatus, BuildStatusEnum
|
|||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
from ahriman.models.user_access import UserAccess
|
from ahriman.models.user_access import UserAccess
|
||||||
from ahriman.web.views.v1.status.package import PackageView
|
from ahriman.web.views.v1.packages.package import PackageView
|
||||||
|
|
||||||
|
|
||||||
async def test_get_permission() -> None:
|
async def test_get_permission() -> None:
|
@ -6,7 +6,7 @@ from pytest_mock import MockerFixture
|
|||||||
from ahriman.models.build_status import BuildStatusEnum
|
from ahriman.models.build_status import BuildStatusEnum
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
from ahriman.models.user_access import UserAccess
|
from ahriman.models.user_access import UserAccess
|
||||||
from ahriman.web.views.v1.status.packages import (PackagesView)
|
from ahriman.web.views.v1.packages.packages import (PackagesView)
|
||||||
|
|
||||||
|
|
||||||
async def test_get_permission() -> None:
|
async def test_get_permission() -> None:
|
@ -6,7 +6,7 @@ from ahriman.models.build_status import BuildStatusEnum
|
|||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||||
from ahriman.models.user_access import UserAccess
|
from ahriman.models.user_access import UserAccess
|
||||||
from ahriman.web.views.v1.status.patch import PatchView
|
from ahriman.web.views.v1.packages.patch import PatchView
|
||||||
|
|
||||||
|
|
||||||
async def test_get_permission() -> None:
|
async def test_get_permission() -> None:
|
@ -6,7 +6,7 @@ from ahriman.models.build_status import BuildStatusEnum
|
|||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||||
from ahriman.models.user_access import UserAccess
|
from ahriman.models.user_access import UserAccess
|
||||||
from ahriman.web.views.v1.status.patches import PatchesView
|
from ahriman.web.views.v1.packages.patches import PatchesView
|
||||||
|
|
||||||
|
|
||||||
async def test_get_permission() -> None:
|
async def test_get_permission() -> None:
|
@ -5,7 +5,7 @@ from aiohttp.test_utils import TestClient
|
|||||||
from ahriman.models.build_status import BuildStatusEnum
|
from ahriman.models.build_status import BuildStatusEnum
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
from ahriman.models.user_access import UserAccess
|
from ahriman.models.user_access import UserAccess
|
||||||
from ahriman.web.views.v2.status.logs import LogsView
|
from ahriman.web.views.v2.packages.logs import LogsView
|
||||||
|
|
||||||
|
|
||||||
async def test_get_permission() -> None:
|
async def test_get_permission() -> None:
|
Reference in New Issue
Block a user