mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-09-12 03:39:55 +00:00
Compare commits
653 Commits
6fe77eb465
...
2.15.3
Author | SHA1 | Date | |
---|---|---|---|
7799389cd8 | |||
030fecd173 | |||
343435b3bf | |||
f0930be238 | |||
113a861f31 | |||
528d7ce398 | |||
b357c96204 | |||
5d495fc813 | |||
16ab96ee6a | |||
b412966f86 | |||
1119a8d04e | |||
9b3d294992 | |||
517337144c | |||
db89ad46b7 | |||
9fc1c53c3d | |||
cd61ab3e5b | |||
b319e89e41 | |||
b3d32c6fc4 | |||
91c2aef931 | |||
3ad0037fa9 | |||
f5d415ab4f | |||
b002db1148 | |||
393104f9fa | |||
b9f39e0d99 | |||
990397e1cb | |||
300713f5d5 | |||
9a17f19f7b | |||
3ff1bf473c | |||
50cd71b954 | |||
f81ebe6c3c | |||
1d85a61cc4 | |||
689de82139 | |||
5b9f35220f | |||
8fc4d7b4a5 | |||
cedf18ac7a | |||
164b6d7956 | |||
27e595cdf4 | |||
020560d341 | |||
cdef67986b | |||
dddcd0bfce | |||
a0784b7af1 | |||
4c4c9b2bfd | |||
5c34c051cb | |||
4fa44b0532 | |||
f167ce7d3b | |||
950b9e4289 | |||
264aeb7150 | |||
be7169c5df | |||
9c1e9ecbdc | |||
4b2f6bbee9 | |||
fd8c8a00d0 | |||
eaf1984eb3 | |||
794dddccd9 | |||
7bd7f95f76 | |||
375374c396 | |||
d1ad5ecc11 | |||
1eb4d8e47f | |||
0861548b56 | |||
e9e4172063 | |||
beb6156795 | |||
dbfb460557 | |||
f7f76c4119 | |||
88ee300b9e | |||
6f30c687c2 | |||
c023ebe165 | |||
54b99cacfd | |||
4f5166ff25 | |||
c8afcbf36a | |||
2b9880bd3c | |||
3be5cdafe8 | |||
668be41c3e | |||
3353daec6d | |||
eef4d2dd98 | |||
b15161554e | |||
bb4a0d75fc | |||
bca0df41d1 | |||
07b77be6b8 | |||
2b33510ada | |||
6d05389639 | |||
daf9841717 | |||
0d243a781a | |||
cf2e66a934 | |||
f01f35238d | |||
d30d512eb6 | |||
0437f90e5a | |||
3cab65855a | |||
ecfb615f97 | |||
243983ee64 | |||
812c03d1eb | |||
01597c531b | |||
4fec42eac8 | |||
7574b8e5ce | |||
0f2e7f45da | |||
5956a8720b | |||
8dd4ced5e9 | |||
6361c41f76 | |||
270084bb39 | |||
f89a5252de | |||
8cafdb52e5 | |||
203ebad817 | |||
9f471d11a7 | |||
2ea8a4a07f | |||
856bbc30d4 | |||
c88f97c36e | |||
174d7578a0 | |||
8b26035fc9 | |||
fc9391dd5f | |||
ed7ed5d5d9 | |||
9e1cf3cde7 | |||
08086e8ba8 | |||
1a61da7ab9 | |||
f4dcbbde18 | |||
7aba67186f | |||
8635ee8953 | |||
2d42424477 | |||
fdf7a36271 | |||
e9116741a5 | |||
1a2327cefd | |||
29c8c4bfd7 | |||
e40b773029 | |||
ee3ccf70ac | |||
e4b22fd620 | |||
48344f759d | |||
290e6e7670 | |||
e0e4da6669 | |||
0e2ad3325c | |||
28589cb122 | |||
93793b6424 | |||
b3ce545517 | |||
e51d91740d | |||
5ddc08fce7 | |||
f2f6f6df70 | |||
2760b36977 | |||
a689448854 | |||
aef3cb95bc | |||
d72677aa29 | |||
82d1be52a8 | |||
7536d6bb82 | |||
b050c409cf | |||
d77cf7c4bb | |||
e03fcbfab5 | |||
62dd77317d | |||
95056cfbe7 | |||
2d31a415ce | |||
5cbeec40f8 | |||
4a644fc80f | |||
d1aeeda975 | |||
53aedbb9aa | |||
c941226a9b | |||
69cbbfce65 | |||
52d69fa9f6 | |||
279ac785a1 | |||
f51b8e2358 | |||
b116e6fa07 | |||
7b667c8157 | |||
c51463d36b | |||
79947af013 | |||
e6d6cb006b | |||
f553cc059a | |||
c99d4f6f0f | |||
554827cc57 | |||
8524f1eb20 | |||
4b6feb9ae6 | |||
ad901067d8 | |||
4c20897e14 | |||
f8cbd07259 | |||
16ad96d8c6 | |||
6bd1636bfa | |||
4eb187aead | |||
f2ac27ccb7 | |||
b198778810 | |||
57c8ed3557 | |||
1859d14f78 | |||
d5f4fc9b86 | |||
462096ee8a | |||
98e594df90 | |||
657bcdcc0b | |||
edcc464658 | |||
018d9589e1 | |||
a56fe28003 | |||
03c183d66c | |||
efde0b2e86 | |||
c915d68c97 | |||
853185c659 | |||
28afcde3fa | |||
62ae3ada4a | |||
6fcb5449c3 | |||
74209acc21 | |||
969352d842 | |||
a1db4dc8b8 | |||
f6081507c0 | |||
477c473187 | |||
33e68a59e2 | |||
6dfe1b92f2 | |||
5dc6df11c5 | |||
d3f6ca24c8 | |||
c26a13c562 | |||
9ea3a911f7 | |||
ca60317750 | |||
1384efb31d | |||
8c6486c233 | |||
a1d0e993a8 | |||
572880eb73 | |||
d9eaf17a11 | |||
95e29d16bb | |||
1f2d56e605 | |||
1baf04998d | |||
3a88d00db0 | |||
b58d8d96ff | |||
4abe3b8963 | |||
237fec3f85 | |||
bd0f850d25 | |||
5904727da2 | |||
263c53bac5 | |||
6743f1d62a | |||
931ff9bd98 | |||
6b3fc3a6a0 | |||
b7852f55c8 | |||
721b447767 | |||
b80ea80e9d | |||
8e9da5baab | |||
a443abb94e | |||
61c565ab0d | |||
10100b20e1 | |||
2922bb9d72 | |||
17f5f41e36 | |||
c22ddd71d9 | |||
4b984afb64 | |||
d495163fdd | |||
041e9536bf | |||
1625fddccd | |||
8f2c33fe5d | |||
d064e46af6 | |||
5627c9cca0 | |||
8731cee8ea | |||
01a4d68ce6 | |||
8f0a6cf6b5 | |||
d96e3c97db | |||
1cf027cb55 | |||
8e0e57e193 | |||
f855e645cc | |||
8ab0df2bed | |||
840921f585 | |||
6f566b0c6c | |||
d06399db2c | |||
70e9e3e822 | |||
8c55438140 | |||
277d40d231 | |||
2ff56965d9 | |||
9dc6d56a8d | |||
d59a0629c5 | |||
31f47b8069 | |||
e42ca95789 | |||
ff917281a2 | |||
f7e260e1f4 | |||
abf29083c4 | |||
54d36ccf36 | |||
2cd61b0a20 | |||
9503a9f2ae | |||
39fde7cd5f | |||
58379e7bf3 | |||
3c068edf4f | |||
1106ff6482 | |||
e08ab2db10 | |||
8f4a2547e8 | |||
7f5e541120 | |||
ec0550a275 | |||
df23be9269 | |||
a8c40a6b87 | |||
a274f91677 | |||
13faf66bdb | |||
4fb9335df9 | |||
d517d8bfbb | |||
37e57c13c8 | |||
19bb19e9f5 | |||
3a4e8f4d97 | |||
4db8ad8e8d | |||
117f096d41 | |||
917ec48be5 | |||
0a2ba4ae07 | |||
9d7f63e549 | |||
25eee9ca5e | |||
5af84955ac | |||
d3ad4c3c08 | |||
5bbb9d269b | |||
17466d8d37 | |||
9e4e3b701b | |||
c6555cf2c7 | |||
85baad6a41 | |||
616a1950ae | |||
30b9bcb45a | |||
d7356926c4 | |||
43a7d09cab | |||
77954b988b | |||
0239fb50b6 | |||
d942a70272 | |||
1f07a89316 | |||
014007ade3 | |||
730f3ca0c9 | |||
42c13b5d4b | |||
04e5a263b7 | |||
caca1576c8 | |||
98f2f19d5b | |||
5c4d3eeffd | |||
84d4523e85 | |||
2c2eae2334 | |||
214d6d7fdd | |||
e9512e9a6a | |||
f984ea75d0 | |||
b44e5c3a3d | |||
1891d6c944 | |||
08d68258ca | |||
cd3d12a754 | |||
81d9526054 | |||
c7447f19f0 | |||
7de94a8daa | |||
aa1a59d0a3 | |||
8864855c14 | |||
b0b37e8169 | |||
7df4adfc9d | |||
2d5b73c6dc | |||
1c8aed4a97 | |||
2e059023f3 | |||
da5d97788a | |||
0e839fbbf2 | |||
262462d3c3 | |||
7aa91f9e2e | |||
01eda513cf | |||
0161617e36 | |||
4811dec759 | |||
09623c20d5 | |||
eba247b759 | |||
5073c80af1 | |||
766081d212 | |||
896cd0bd71 | |||
ce1bd2f2db | |||
6ba96d838d | |||
df9e03f495 | |||
89944eb2b6 | |||
336784519b | |||
f3341ec7cd | |||
d36e851a29 | |||
28bd5f2095 | |||
011b4e2e31 | |||
15609ba044 | |||
6d4f9981f7 | |||
bbb97d1cdd | |||
3bca780bdd | |||
78e6b48c24 | |||
137d62e2f8 | |||
8a6854c867 | |||
299732181c | |||
84c1b4d82d | |||
cdd66ee780 | |||
b2ed383de0 | |||
551ee670bf | |||
5d4bd9e459 | |||
4f21eb6fe6 | |||
9a008ddafa | |||
0cd07afa0f | |||
f590136197 | |||
1855e513a8 | |||
233dda8420 | |||
9556779ee2 | |||
8b32bd43db | |||
0eadef597a | |||
e58ccdc8ad | |||
2a07356d24 | |||
43c553a3db | |||
0d1a890bd0 | |||
3aeaa8ce2c | |||
7cee859f19 | |||
fb6b22cdd7 | |||
4f35ec6542 | |||
d98211e5e5 | |||
b97c8928e1 | |||
649df81aa5 | |||
ad7cdb7d95 | |||
4bb598d2eb | |||
f47be6cab0 | |||
342b3cb652 | |||
fc0d8387df | |||
e0b0c3caeb | |||
61969dd682 | |||
e441d93a56 | |||
664b6369bb | |||
4f6bd29ff4 | |||
f6d9ea480a | |||
08f62842ba | |||
1912790ccc | |||
cf3c48ffeb | |||
6633766cc3 | |||
f73d1eb424 | |||
87ab3683ad | |||
9c2f73af8c | |||
31f551bdf2 | |||
cbbe2b01e4 | |||
cd361a483d | |||
cee4fd4cce | |||
18daecaac7 | |||
03c298c762 | |||
79d4a488a0 | |||
22847aac68 | |||
75b9a96798 | |||
a0cfb7561d | |||
f4131b8cd7 | |||
9f134e37b6 | |||
07b7689701 | |||
47de715d7d | |||
5674b7b388 | |||
f6e57a411c | |||
38e48b1571 | |||
d492c968ea | |||
a11fd188a2 | |||
2431d5de0e | |||
88f71b240d | |||
99874845b5 | |||
d98cfa3732 | |||
b6db2a8035 | |||
47c578ea08 | |||
98910240dd | |||
33e9fea47c | |||
304690e0d0 | |||
3d9fae5415 | |||
b7dca2d797 | |||
b7debddaea | |||
1cfc751d21 | |||
6ebbb04504 | |||
c9ee470ee2 | |||
a2610504e5 | |||
36b8b0f46a | |||
d90f417cae | |||
0db619136d | |||
208a9b920d | |||
cb63bc08ff | |||
6551c8d983 | |||
a6c8d64053 | |||
fd78f2b5e2 | |||
900907cdaa | |||
5ff2f43506 | |||
dd521b49b5 | |||
5b1f5a8473 | |||
86af13f09e | |||
733c014229 | |||
783c16b2ed | |||
2536b8dc1f | |||
e200ac9776 | |||
6946745153 | |||
6de75377c3 | |||
a734b86e66 | |||
74906d084a | |||
22d1d835af | |||
b7cd83502a | |||
2d2cd73010 | |||
40b84b810d | |||
7188cfaf78 | |||
e909e4f570 | |||
06ec16ac77 | |||
fed2f3aab8 | |||
2bc2b63a8a | |||
0c5a90cd66 | |||
28cc38aaa5 | |||
fb02e676af | |||
13121298f5 | |||
63e79ec57a | |||
b83bc5a732 | |||
8374590b62 | |||
4cc665f6ee | |||
57f25c309a | |||
d33844e7b2 | |||
e9886efaa2 | |||
61efbb71a2 | |||
9f4acacada | |||
026f74121a | |||
e414616bbd | |||
60a2e25b9a | |||
683abca9e5 | |||
5a3770b739 | |||
52cd9a0ea9 | |||
bfca7e41ab | |||
603c5449a8 | |||
5aac3db2d5 | |||
3c5bcbd172 | |||
042638d40e | |||
e6adb333b2 | |||
fa4244d21e | |||
91de1c2b8a | |||
32a4a82603 | |||
e8a10c1bb5 | |||
d480eb7bc3 | |||
8b0f9bfd78 | |||
a2639f8dbb | |||
65ba590ace | |||
fcb130e226 | |||
ae99fe4535 | |||
ec23e3f912 | |||
d3ea81d234 | |||
09b0f2914d | |||
7351e20104 | |||
dfd87c502f | |||
0b9ab09879 | |||
47c54f0b40 | |||
a2f2fa0354 | |||
4d68080c05 | |||
eb16ef12f3 | |||
e10e362dae | |||
e59fdd1ccc | |||
22d92e3b4e | |||
56b77a84a6 | |||
a5a99ec0b8 | |||
04bbabe898 | |||
4521c2adde | |||
5c5e54228f | |||
6514924b2d | |||
16aa977fa8 | |||
6e377e7261 | |||
4502931c39 | |||
fcb167b1a3 | |||
72b26603bf | |||
ab8ca16981 | |||
7c4f84fbc7 | |||
3b6b2efcb1 | |||
9f99dd3ff2 | |||
bee97df87f | |||
6becd01803 | |||
db195391e4 | |||
59f2992559 | |||
4f06647193 | |||
73a4cee257 | |||
13d00c6f66 | |||
3e032c3515 | |||
d73d5daad3 | |||
f55b44b391 | |||
51b28baf40 | |||
24326f9753 | |||
36c763069d | |||
c9a155bbc4 | |||
182bde5e09 | |||
799572fccf | |||
a7a32f0080 | |||
af3afecce8 | |||
16bb1403a1 | |||
41731ca359 | |||
e99c2b0c83 | |||
6294c0ba14 | |||
2c74be31bd | |||
0744ee53dc | |||
284fd759bf | |||
6f5b28c4f8 | |||
d211cc17c6 | |||
117e69c906 | |||
d19deb57e7 | |||
1b29b5773d | |||
8e14e8d2cb | |||
875bfc0823 | |||
7abdb48ac0 | |||
98eb93c27a | |||
18de70154e | |||
08e0237639 | |||
891c97b036 | |||
55c3386812 | |||
b0575ee4ba | |||
e0607ba609 | |||
9b8c9b2b2d | |||
ecf45bc3bb | |||
aecd679d01 | |||
e63cb509f2 | |||
3922c55464 | |||
9d2a3bcbc1 | |||
a5455b697d | |||
0bfb763b2a | |||
9f3566a150 | |||
16a6c4fdd7 | |||
91f66fdcee | |||
bb45b1d868 | |||
3d10fa472b | |||
a90c93bbc4 | |||
41a3c08d9f | |||
cb328ad797 | |||
810091cde9 | |||
fc0474fa8f | |||
b94179e071 | |||
9c5a9f5837 | |||
83047d8270 | |||
990d5dda81 | |||
48e79ce39c | |||
375d7c55e5 | |||
db52b8e844 | |||
50af309c80 | |||
581401d60f | |||
c2685f4746 | |||
952b55f707 | |||
b9b012be53 | |||
b8036649ab | |||
c90e20587e | |||
3e020ec141 | |||
783b7d043d | |||
5c297d1c67 | |||
b0d1f3c091 | |||
50e219fda5 | |||
75298d1b8a | |||
8196dcc8a0 | |||
f634f1df58 | |||
32df4fc54f | |||
11ae930c59 | |||
9c332c23d2 | |||
4ed0a49a44 | |||
50f532a48a | |||
c6ccf53768 | |||
ce0c07cbd9 | |||
912a76d5cb | |||
76d0b0bc6d | |||
27d018e721 | |||
a0e20ffb77 | |||
96e4abc3c0 | |||
6df60498aa | |||
eb0a4b6b4a | |||
8f469e7eac | |||
535e955814 | |||
0bd3ba626a | |||
ffe6aec190 | |||
56c600e5ac | |||
461883217d | |||
62d55eff19 | |||
534b5600b4 | |||
32cbafd12b | |||
880c70bd58 | |||
d449eb3c2e | |||
17b5cd0751 | |||
2aef906fc8 | |||
e034327501 | |||
5d79fcca22 | |||
6e9dcca254 | |||
fbf6748d4a | |||
2260e52d5c | |||
bd2b61494f | |||
7280d30748 | |||
710274065d | |||
e0b09cefad | |||
3b93510aad | |||
5003cabeb5 | |||
bc6af9256b | |||
1ac7c87317 | |||
803b7bee1e | |||
646190121a | |||
10e4f3b629 | |||
80a1f37c85 | |||
751676a07e | |||
e1a7071ce5 | |||
1605d185e2 | |||
2fdf910e78 | |||
63dc43366b | |||
74a244f06c |
2
.github/workflows/setup.sh
vendored
2
.github/workflows/setup.sh
vendored
@ -10,7 +10,7 @@ echo -e '[arcanisrepo]\nServer = https://repo.arcanis.me/$arch\nSigLevel = Never
|
|||||||
# refresh the image
|
# refresh the image
|
||||||
pacman -Syyu --noconfirm
|
pacman -Syyu --noconfirm
|
||||||
# main dependencies
|
# main dependencies
|
||||||
pacman -S --noconfirm devtools git pyalpm python-bcrypt python-inflection python-pyelftools python-requests python-systemd sudo
|
pacman -S --noconfirm devtools git pyalpm python-inflection python-passlib python-pyelftools python-requests python-systemd sudo
|
||||||
# make dependencies
|
# make dependencies
|
||||||
pacman -S --noconfirm --asdeps base-devel python-build python-flit python-installer python-tox python-wheel
|
pacman -S --noconfirm --asdeps base-devel python-build python-flit python-installer python-tox python-wheel
|
||||||
# optional dependencies
|
# optional dependencies
|
||||||
|
@ -4,8 +4,6 @@ build:
|
|||||||
os: ubuntu-20.04
|
os: ubuntu-20.04
|
||||||
tools:
|
tools:
|
||||||
python: "3.12"
|
python: "3.12"
|
||||||
apt_packages:
|
|
||||||
- graphviz
|
|
||||||
|
|
||||||
python:
|
python:
|
||||||
install:
|
install:
|
||||||
|
@ -236,50 +236,16 @@ The projects also uses typing checks (provided by `mypy`) and some linter checks
|
|||||||
tox
|
tox
|
||||||
```
|
```
|
||||||
|
|
||||||
Must be usually done before any pushes.
|
|
||||||
|
|
||||||
### Generate documentation templates
|
### Generate documentation templates
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
tox -e docs
|
tox -e docs
|
||||||
```
|
```
|
||||||
|
|
||||||
Must be usually done if there are changes in modules structure.
|
|
||||||
|
|
||||||
### Create release
|
### Create release
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
tox -m release -- major.minor.patch
|
tox -m release -- x.y.z
|
||||||
```
|
```
|
||||||
|
|
||||||
The command above will generate documentation, tags, etc., and will push them to GitHub. Other things will be handled by GitHub workflows automatically.
|
The command above will generate documentation, tags, etc., and will push them to GitHub. Other things will be handled by GitHub workflows automatically.
|
||||||
|
|
||||||
### Hotfixes policy
|
|
||||||
|
|
||||||
Sometimes it is required to publish hotfix with specific commits, but some features have been already committed, which should not be included to the hotfix. In this case, some manual steps are required:
|
|
||||||
|
|
||||||
1. Create new branch from the last stable release (`major.minor.patch`):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
git checkout -b release/major.minor major.minor.patch
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Cherry-pick desired commit(s):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
git cherry-pick <commit-sha>
|
|
||||||
```
|
|
||||||
|
|
||||||
Alternatively, make changes to the new branch and commit them.
|
|
||||||
|
|
||||||
3. Push newly created branch to remote:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
git push --set-upstream origin release/major.minor
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Proceed to release as usual:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
tox -m release -- major.minor.patch+1
|
|
||||||
```
|
|
||||||
|
@ -35,8 +35,8 @@ RUN pacman -S --noconfirm --asdeps \
|
|||||||
devtools \
|
devtools \
|
||||||
git \
|
git \
|
||||||
pyalpm \
|
pyalpm \
|
||||||
python-bcrypt \
|
|
||||||
python-inflection \
|
python-inflection \
|
||||||
|
python-passlib \
|
||||||
python-pyelftools \
|
python-pyelftools \
|
||||||
python-requests \
|
python-requests \
|
||||||
&& \
|
&& \
|
||||||
@ -59,7 +59,6 @@ RUN pacman -S --noconfirm --asdeps \
|
|||||||
&& \
|
&& \
|
||||||
runuser -u build -- install-aur-package \
|
runuser -u build -- install-aur-package \
|
||||||
python-aioauth-client \
|
python-aioauth-client \
|
||||||
python-sphinx-typlog-theme \
|
|
||||||
python-webargs \
|
python-webargs \
|
||||||
python-aiohttp-apispec-git \
|
python-aiohttp-apispec-git \
|
||||||
python-aiohttp-cors \
|
python-aiohttp-cors \
|
||||||
|
@ -4,7 +4,7 @@ set -e
|
|||||||
[ -n "$AHRIMAN_DEBUG" ] && set -x
|
[ -n "$AHRIMAN_DEBUG" ] && set -x
|
||||||
|
|
||||||
# configuration tune
|
# configuration tune
|
||||||
cat <<EOF > "/etc/ahriman.ini.d/01-docker.ini"
|
cat <<EOF > "/etc/ahriman.ini.d/00-docker.ini"
|
||||||
[repository]
|
[repository]
|
||||||
root = $AHRIMAN_REPOSITORY_ROOT
|
root = $AHRIMAN_REPOSITORY_ROOT
|
||||||
|
|
||||||
|
1820
docs/_static/architecture.dot
vendored
1820
docs/_static/architecture.dot
vendored
File diff suppressed because it is too large
Load Diff
11901
docs/_static/architecture.svg
vendored
Normal file
11901
docs/_static/architecture.svg
vendored
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 1.3 MiB |
@ -36,14 +36,6 @@ ahriman.application.handlers.clean module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.application.handlers.copy module
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.application.handlers.copy
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
ahriman.application.handlers.daemon module
|
ahriman.application.handlers.daemon module
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
|
@ -12,14 +12,6 @@ ahriman.core.configuration.configuration module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.core.configuration.configuration\_multi\_dict module
|
|
||||||
------------------------------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.core.configuration.configuration_multi_dict
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
ahriman.core.configuration.schema module
|
ahriman.core.configuration.schema module
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ Packages have strict rules of importing:
|
|||||||
|
|
||||||
Full dependency diagram:
|
Full dependency diagram:
|
||||||
|
|
||||||
.. graphviz:: _static/architecture.dot
|
.. image:: _static/architecture.svg
|
||||||
|
:target: _static/architecture.svg
|
||||||
:alt: architecture
|
:alt: architecture
|
||||||
|
|
||||||
``ahriman.application`` package
|
``ahriman.application`` package
|
||||||
@ -147,7 +148,7 @@ There are multiple subdirectories, some of them are commons for any repository,
|
|||||||
* ``pacman/{repository}/{architecture}`` is the repository and architecture specific caches for pacman's databases.
|
* ``pacman/{repository}/{architecture}`` is the repository and architecture specific caches for pacman's databases.
|
||||||
* ``repository/{repository}/{architecture}`` is a repository packages directory.
|
* ``repository/{repository}/{architecture}`` is a repository packages directory.
|
||||||
|
|
||||||
Normally you should avoid direct interaction with the application tree. For tree migration process refer to the :doc:`migration notes <migrations/index>`.
|
Normally you should avoid direct interaction with the application tree. For tree migration process refer to the :doc:`migration notes <migration>`.
|
||||||
|
|
||||||
Database
|
Database
|
||||||
--------
|
--------
|
||||||
|
16
docs/conf.py
16
docs/conf.py
@ -10,7 +10,7 @@
|
|||||||
# add these directories to sys.path here. If the directory is relative to the
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
#
|
#
|
||||||
import datetime
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -21,11 +21,13 @@ from ahriman import __version__
|
|||||||
basedir = Path(__file__).resolve().parent.parent / "src"
|
basedir = Path(__file__).resolve().parent.parent / "src"
|
||||||
sys.path.insert(0, str(basedir))
|
sys.path.insert(0, str(basedir))
|
||||||
|
|
||||||
|
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
|
||||||
|
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
project = "ahriman"
|
project = "ahriman"
|
||||||
copyright = f"2021-{datetime.date.today().year}, ahriman team"
|
copyright = "2021-2023, ahriman team"
|
||||||
author = "ahriman team"
|
author = "ahriman team"
|
||||||
|
|
||||||
# The full version, including alpha/beta/rc tags
|
# The full version, including alpha/beta/rc tags
|
||||||
@ -39,7 +41,6 @@ release = __version__
|
|||||||
# ones.
|
# ones.
|
||||||
extensions = [
|
extensions = [
|
||||||
"sphinx.ext.autodoc",
|
"sphinx.ext.autodoc",
|
||||||
"sphinx.ext.graphviz",
|
|
||||||
"sphinx.ext.napoleon",
|
"sphinx.ext.napoleon",
|
||||||
"sphinx_rtd_theme",
|
"sphinx_rtd_theme",
|
||||||
"sphinxarg.ext",
|
"sphinxarg.ext",
|
||||||
@ -77,12 +78,7 @@ html_logo = "_static/logo.svg"
|
|||||||
|
|
||||||
add_module_names = False
|
add_module_names = False
|
||||||
|
|
||||||
modindex_common_prefix = [
|
modindex_common_prefix = ["ahriman.application.", "ahriman.core.", "ahriman.models.", "ahriman.web."]
|
||||||
"ahriman.application.",
|
|
||||||
"ahriman.core.",
|
|
||||||
"ahriman.models.",
|
|
||||||
"ahriman.web.",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
# -- Extension configuration -------------------------------------------------
|
# -- Extension configuration -------------------------------------------------
|
||||||
@ -96,5 +92,3 @@ autodoc_mock_imports = ["cryptography", "pyalpm"]
|
|||||||
autodoc_default_options = {
|
autodoc_default_options = {
|
||||||
"no-undoc-members": True,
|
"no-undoc-members": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
graphviz_output_format = "svg"
|
|
||||||
|
@ -13,27 +13,7 @@ There are two variable types which have been added to default ones, they are pat
|
|||||||
* By default, it splits value by spaces excluding empty elements.
|
* By default, it splits value by spaces excluding empty elements.
|
||||||
* In case if quotation mark (``"`` or ``'``) will be found, any spaces inside will be ignored.
|
* In case if quotation mark (``"`` or ``'``) will be found, any spaces inside will be ignored.
|
||||||
* In order to use quotation mark inside value it is required to put it to another quotation mark, e.g. ``wor"'"d "with quote"`` will be parsed as ``["wor'd", "with quote"]`` and vice versa.
|
* In order to use quotation mark inside value it is required to put it to another quotation mark, e.g. ``wor"'"d "with quote"`` will be parsed as ``["wor'd", "with quote"]`` and vice versa.
|
||||||
* Unclosed quotation mark is not allowed and will raise an exception.
|
* Unclosed quotation mark is not allowed and will rise an exception.
|
||||||
|
|
||||||
It is also possible to split list option between multiple declarations. To do so, append key name with ``[]`` (like PHP, sorry!), e.g.:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[section]
|
|
||||||
list[] = value1
|
|
||||||
list[] = value2
|
|
||||||
|
|
||||||
will lead to ``${section:list}`` value to be set to ``value1 value2``. The values will be set in order of appearance, meaning that values which appear in different include files will be set in alphabetical order of file names. In order to reset list values, set option to empty string, e.g.:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[section]
|
|
||||||
list[] = value1
|
|
||||||
list[] =
|
|
||||||
list[] = value2
|
|
||||||
list[] = value3
|
|
||||||
|
|
||||||
will set option ``${section:list}`` to ``value2 value3``. Alternatively, setting the original option (e.g. ``list`` in the example above) will also reset value, though the subsequent options with leading ``[]`` will append the previous value.
|
|
||||||
|
|
||||||
Path values, except for casting to ``pathlib.Path`` type, will be also expanded to absolute paths relative to the configuration path. E.g. if path is set to ``ahriman.ini.d/logging.ini`` and root configuration path is ``/etc/ahriman.ini``, the value will be expanded to ``/etc/ahriman.ini.d/logging.ini``. In order to disable path expand, use the full path, e.g. ``/etc/ahriman.ini.d/logging.ini``.
|
Path values, except for casting to ``pathlib.Path`` type, will be also expanded to absolute paths relative to the configuration path. E.g. if path is set to ``ahriman.ini.d/logging.ini`` and root configuration path is ``/etc/ahriman.ini``, the value will be expanded to ``/etc/ahriman.ini.d/logging.ini``. In order to disable path expand, use the full path, e.g. ``/etc/ahriman.ini.d/logging.ini``.
|
||||||
|
|
||||||
@ -42,7 +22,7 @@ Configuration allows string interpolation from the same configuration file, e.g.
|
|||||||
.. code-block:: ini
|
.. code-block:: ini
|
||||||
|
|
||||||
[section]
|
[section]
|
||||||
key = ${another_key}
|
key = ${anoher_key}
|
||||||
another_key = value
|
another_key = value
|
||||||
|
|
||||||
will read value for the ``key`` option from ``another_key`` in the same section. In case if the cross-section reference is required, the ``${section:another_key}`` notation must be used. It also allows string interpolation from environment variables, e.g.:
|
will read value for the ``key`` option from ``another_key`` in the same section. In case if the cross-section reference is required, the ``${section:another_key}`` notation must be used. It also allows string interpolation from environment variables, e.g.:
|
||||||
|
@ -148,11 +148,13 @@ Before using this command you will need to create local directory and put ``PKGB
|
|||||||
How to copy package from another repository
|
How to copy package from another repository
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
It is possible to copy package and its metadata between local repositories, optionally removing the source archive, e.g.:
|
As simple as add package from archive. Considering case when you would like to copy package ``package`` with version ``ver-rel`` from repository ``source-repository`` to ``target-respository`` (same architecture), the command will be following:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
sudo -u ahriman ahriman -r target-repository package-copy source-repository ahriman
|
sudo -u ahriman ahriman -r target-repository package-add /var/lib/ahriman/repository/source-repository/x86_64/package-ver-rel-x86_64.pkg.tar.zst
|
||||||
|
|
||||||
|
In addition, you can remove source package as usual later.
|
||||||
|
|
||||||
This feature in particular useful if for managing multiple repositories like ``[testing]`` and ``[extra]``.
|
This feature in particular useful if for managing multiple repositories like ``[testing]`` and ``[extra]``.
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ Contents
|
|||||||
configuration
|
configuration
|
||||||
command-line
|
command-line
|
||||||
faq/index
|
faq/index
|
||||||
migrations/index
|
migration
|
||||||
architecture
|
architecture
|
||||||
advanced-usage
|
advanced-usage
|
||||||
triggers
|
triggers
|
||||||
|
@ -1,5 +1,25 @@
|
|||||||
|
Manual migrations
|
||||||
|
=================
|
||||||
|
|
||||||
|
Normally the most of migrations are handled automatically after application start, however, some upgrades require manual interventions; this document describes them.
|
||||||
|
|
||||||
|
Upgrades to breakpoints
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
To 2.9.0
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
|
This release includes major upgrade for the newest devtools and archlinux repository structure. In order to upgrade package need to:
|
||||||
|
|
||||||
|
#. Upgrade to the latest major release of python (3.11) (required by other changes).
|
||||||
|
#. Upgrade devtools to the latest release.
|
||||||
|
#. Backup local settings, ``/etc/ahriman.ini.d/00-setup-overrides.ini`` by default.
|
||||||
|
#. Run setup command (i.e. ``ahriman service-setup``) again with the same arguments as used before. This step can be done manually by moving ``devtools`` configuration (something like ``/usr/share/devtools/pacman-ahriman*.conf``) to new location ``/usr/share/devtools/pacman.conf.d/`` under name ``ahriman.conf``. After that make sure to remove any ``community`` mentions from configurations (e.g. ``/usr/share/devtools/pacman.conf.d/ahriman.conf``, ``/etc/ahriman.ini``) if there were any. The only thing which will change is ``devtools`` configuration.
|
||||||
|
#. Remove build chroot as it is incompatible, e.g. ``sudo ahriman service-clean --chroot``.
|
||||||
|
#. Run ``sudo -u ahriman ahriman update --no-aur --no-local --no-manual -yy`` in order to update local databases.
|
||||||
|
|
||||||
To 2.12.0
|
To 2.12.0
|
||||||
---------
|
^^^^^^^^^
|
||||||
|
|
||||||
This release includes paths migration. Unlike usual case, no automatic migration is performed because it might break user configuration. The following noticeable changes have been made:
|
This release includes paths migration. Unlike usual case, no automatic migration is performed because it might break user configuration. The following noticeable changes have been made:
|
||||||
|
|
@ -1,16 +0,0 @@
|
|||||||
To 2.16.0
|
|
||||||
---------
|
|
||||||
|
|
||||||
This release replaces ``passlib`` dependency with ``bcrypt``.
|
|
||||||
|
|
||||||
The reason behind this change is that python developers have deprecated and scheduled for removal ``crypt`` module, which is used by ``passlib``. (By the way, they recommend to use ``passlib`` as a replacement.) Unfortunately, it appears that ``passlib`` is unmaintained (see `the issue <https://foss.heptapod.net/python-libs/passlib/-/issues/187>`__), so the only solution is to migrate to anoher library.
|
|
||||||
|
|
||||||
Because passwords are stored as hashes, it is near to impossible to shadow change passwords in database, the manual intervention is required if:
|
|
||||||
|
|
||||||
#. Authentication is used.
|
|
||||||
#. Notification provider is ``configuration`` or a user with explicitly set password exists.
|
|
||||||
|
|
||||||
Manual steps might look as:
|
|
||||||
|
|
||||||
#. Get list of users with their roles ``ahriman user-list``.
|
|
||||||
#. For each user run update command, i.e. ``ahriman user-add <username> -R <role>``. Type password when it will be requested.
|
|
@ -1,11 +0,0 @@
|
|||||||
To 2.9.0
|
|
||||||
--------
|
|
||||||
|
|
||||||
This release includes major upgrade for the newest devtools and archlinux repository structure. In order to upgrade package need to:
|
|
||||||
|
|
||||||
#. Upgrade to the latest major release of python (3.11) (required by other changes).
|
|
||||||
#. Upgrade devtools to the latest release.
|
|
||||||
#. Backup local settings, ``/etc/ahriman.ini.d/00-setup-overrides.ini`` by default.
|
|
||||||
#. Run setup command (i.e. ``ahriman service-setup``) again with the same arguments as used before. This step can be done manually by moving ``devtools`` configuration (something like ``/usr/share/devtools/pacman-ahriman*.conf``) to new location ``/usr/share/devtools/pacman.conf.d/`` under name ``ahriman.conf``. After that make sure to remove any ``community`` mentions from configurations (e.g. ``/usr/share/devtools/pacman.conf.d/ahriman.conf``, ``/etc/ahriman.ini``) if there were any. The only thing which will change is ``devtools`` configuration.
|
|
||||||
#. Remove build chroot as it is incompatible, e.g. ``sudo ahriman service-clean --chroot``.
|
|
||||||
#. Run ``sudo -u ahriman ahriman update --no-aur --no-local --no-manual -yy`` in order to update local databases.
|
|
@ -1,14 +0,0 @@
|
|||||||
Manual migrations
|
|
||||||
=================
|
|
||||||
|
|
||||||
Normally the most of migrations are handled automatically after application start, however, some upgrades require manual interventions; this document describes them.
|
|
||||||
|
|
||||||
Upgrades to breakpoints
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
2.9.0
|
|
||||||
2.12.0
|
|
||||||
2.16.0
|
|
@ -1,13 +1,13 @@
|
|||||||
# Maintainer: Evgeniy Alekseev
|
# Maintainer: Evgeniy Alekseev
|
||||||
|
|
||||||
pkgname='ahriman'
|
pkgname='ahriman'
|
||||||
pkgver=2.15.2
|
pkgver=2.15.3
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="ArcH linux ReposItory MANager"
|
pkgdesc="ArcH linux ReposItory MANager"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
url="https://github.com/arcan1s/ahriman"
|
url="https://github.com/arcan1s/ahriman"
|
||||||
license=('GPL3')
|
license=('GPL3')
|
||||||
depends=('devtools>=1:1.0.0' 'git' 'pyalpm' 'python-bcrypt' 'python-inflection' 'python-pyelftools' 'python-requests')
|
depends=('devtools>=1:1.0.0' 'git' 'pyalpm' 'python-inflection' 'python-passlib' 'python-pyelftools' 'python-requests')
|
||||||
makedepends=('python-build' 'python-flit' 'python-installer' 'python-wheel')
|
makedepends=('python-build' 'python-flit' 'python-installer' 'python-wheel')
|
||||||
optdepends=('python-aioauth-client: web server with OAuth2 authorization'
|
optdepends=('python-aioauth-client: web server with OAuth2 authorization'
|
||||||
'python-aiohttp: web server'
|
'python-aiohttp: web server'
|
||||||
@ -42,6 +42,9 @@ package() {
|
|||||||
|
|
||||||
python -m installer --destdir="$pkgdir" "dist/$pkgname-$pkgver-py3-none-any.whl"
|
python -m installer --destdir="$pkgdir" "dist/$pkgname-$pkgver-py3-none-any.whl"
|
||||||
|
|
||||||
|
# thanks too PEP517, which we all wanted, you need to install data files manually nowadays
|
||||||
|
pushd package && find . \( -type f -or -type l \) -exec install -Dm644 "{}" "$pkgdir/usr/{}" \; && popd
|
||||||
|
|
||||||
# keep usr/share configs as reference and copy them to /etc
|
# keep usr/share configs as reference and copy them to /etc
|
||||||
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini" "$pkgdir/etc/ahriman.ini"
|
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini" "$pkgdir/etc/ahriman.ini"
|
||||||
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini.d/logging.ini" "$pkgdir/etc/ahriman.ini.d/logging.ini"
|
install -Dm644 "$pkgdir/usr/share/$pkgname/settings/ahriman.ini.d/logging.ini" "$pkgdir/etc/ahriman.ini.d/logging.ini"
|
||||||
@ -49,3 +52,7 @@ package() {
|
|||||||
install -Dm644 "$srcdir/$pkgname.sysusers" "$pkgdir/usr/lib/sysusers.d/$pkgname.conf"
|
install -Dm644 "$srcdir/$pkgname.sysusers" "$pkgdir/usr/lib/sysusers.d/$pkgname.conf"
|
||||||
install -Dm644 "$srcdir/$pkgname.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/$pkgname.conf"
|
install -Dm644 "$srcdir/$pkgname.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/$pkgname.conf"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sha512sums=('19841842641520b573cdde6cb80a7cfcd69756d323fdfeebc2eee2d264a1325ead4ab2f8383bb369f7896bfc1de59d7358f133f4afeb90a9b9f0695f482a58d0'
|
||||||
|
'53d37efec812afebf86281716259f9ea78a307b83897166c72777251c3eebcb587ecee375d907514781fb2a5c808cbb24ef9f3f244f12740155d0603bf213131'
|
||||||
|
'62b2eccc352d33853ef243c9cddd63663014aa97b87242f1b5bc5099a7dbd69ff3821f24ffc58e1b7f2387bd4e9e9712cc4c67f661b1724ad99cdf09b3717794')
|
||||||
|
@ -21,7 +21,7 @@ It was found that there was an upgrade from old devtools package to the new one,
|
|||||||
* remove build chroot, e.g.: ahriman service-clean --chroot;
|
* remove build chroot, e.g.: ahriman service-clean --chroot;
|
||||||
* update local databases: ahriman update --no-aur --no-local --no-manual -yy.
|
* update local databases: ahriman update --no-aur --no-local --no-manual -yy.
|
||||||
|
|
||||||
For more information kindly refer to migration notes https://ahriman.readthedocs.io/en/stable/migrations/2.9.0.html.
|
For more information kindly refer to migration notes https://ahriman.readthedocs.io/en/stable/migration.html.
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,16 +37,6 @@ Whereas old local tree is still supported it is highly recommended to migrate to
|
|||||||
* enable web and timer services again by using x86_64-aur suffix,
|
* enable web and timer services again by using x86_64-aur suffix,
|
||||||
where x86_64 is the repository architecture and aur is the repository name.
|
where x86_64 is the repository architecture and aur is the repository name.
|
||||||
|
|
||||||
For more information kindly refer to migration notes https://ahriman.readthedocs.io/en/stable/migrations/2.12.0.html.
|
For more information kindly refer to migration notes https://ahriman.readthedocs.io/en/stable/migration.html.
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
_2_16_0_1_changes() {
|
|
||||||
cat << EOF
|
|
||||||
In order to prepare to python 3.13 the project now uses bcrypt instead of passlib for generating and validating
|
|
||||||
passwords, because the passlib seems to be unmaintained and will be broken since then. If you are using password
|
|
||||||
authentication, you'd need to generate passwords again.
|
|
||||||
|
|
||||||
For more information kindly refer to migration notes https://ahriman.readthedocs.io/en/stable/migrations/2.16.0.html.
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
@ -65,19 +65,9 @@ makepkg_flags = --nocolor --ignorearch
|
|||||||
; List of paths to be used for implicit dependency scan. Regular expressions are supported.
|
; List of paths to be used for implicit dependency scan. Regular expressions are supported.
|
||||||
scan_paths = ^usr/lib(?!/cmake).*$
|
scan_paths = ^usr/lib(?!/cmake).*$
|
||||||
; List of enabled triggers in the order of calls.
|
; List of enabled triggers in the order of calls.
|
||||||
triggers[] = ahriman.core.gitremote.RemotePullTrigger
|
triggers = ahriman.core.gitremote.RemotePullTrigger ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger ahriman.core.gitremote.RemotePushTrigger
|
||||||
triggers[] = ahriman.core.report.ReportTrigger
|
|
||||||
triggers[] = ahriman.core.upload.UploadTrigger
|
|
||||||
triggers[] = ahriman.core.gitremote.RemotePushTrigger
|
|
||||||
; List of well-known triggers. Used only for configuration purposes.
|
; List of well-known triggers. Used only for configuration purposes.
|
||||||
triggers_known[] = ahriman.core.distributed.WorkerLoaderTrigger
|
triggers_known = ahriman.core.distributed.WorkerLoaderTrigger ahriman.core.distributed.WorkerRegisterTrigger ahriman.core.distributed.WorkerTrigger ahriman.core.distributed.WorkerUnregisterTrigger ahriman.core.gitremote.RemotePullTrigger ahriman.core.gitremote.RemotePushTrigger ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger ahriman.core.support.KeyringTrigger ahriman.core.support.MirrorlistTrigger
|
||||||
triggers_known[] = ahriman.core.distributed.WorkerTrigger
|
|
||||||
triggers_known[] = ahriman.core.gitremote.RemotePullTrigger
|
|
||||||
triggers_known[] = ahriman.core.gitremote.RemotePushTrigger
|
|
||||||
triggers_known[] = ahriman.core.report.ReportTrigger
|
|
||||||
triggers_known[] = ahriman.core.support.KeyringTrigger
|
|
||||||
triggers_known[] = ahriman.core.support.MirrorlistTrigger
|
|
||||||
triggers_known[] = ahriman.core.upload.UploadTrigger
|
|
||||||
; Maximal age in seconds of the VCS packages before their version will be updated with its remote source.
|
; Maximal age in seconds of the VCS packages before their version will be updated with its remote source.
|
||||||
;vcs_allowed_age = 604800
|
;vcs_allowed_age = 604800
|
||||||
; List of worker nodes addresses used for build process, e.g.:
|
; List of worker nodes addresses used for build process, e.g.:
|
||||||
@ -131,7 +121,7 @@ host = 127.0.0.1
|
|||||||
; Path to directory with static files.
|
; Path to directory with static files.
|
||||||
static_path = ${templates}/static
|
static_path = ${templates}/static
|
||||||
; List of directories with templates.
|
; List of directories with templates.
|
||||||
templates[] = ${prefix}/share/ahriman/templates
|
templates = ${prefix}/share/ahriman/templates
|
||||||
; Path to unix socket. If none set, unix socket will be disabled.
|
; Path to unix socket. If none set, unix socket will be disabled.
|
||||||
;unix_socket =
|
;unix_socket =
|
||||||
; Allow unix socket to be world readable.
|
; Allow unix socket to be world readable.
|
||||||
@ -256,7 +246,7 @@ template = email-index.jinja2
|
|||||||
; Template name to be used for full packages list generation (same as HTML report).
|
; Template name to be used for full packages list generation (same as HTML report).
|
||||||
;template_full =
|
;template_full =
|
||||||
; List of directories with templates.
|
; List of directories with templates.
|
||||||
templates[] = ${prefix}/share/ahriman/templates
|
templates = ${prefix}/share/ahriman/templates
|
||||||
; SMTP user.
|
; SMTP user.
|
||||||
;user =
|
;user =
|
||||||
|
|
||||||
@ -275,7 +265,7 @@ templates[] = ${prefix}/share/ahriman/templates
|
|||||||
; Template name to be used.
|
; Template name to be used.
|
||||||
template = repo-index.jinja2
|
template = repo-index.jinja2
|
||||||
; List of directories with templates.
|
; List of directories with templates.
|
||||||
templates[] = ${prefix}/share/ahriman/templates
|
templates = ${prefix}/share/ahriman/templates
|
||||||
|
|
||||||
; Remote service callback trigger configuration sample.
|
; Remote service callback trigger configuration sample.
|
||||||
[remote-call]
|
[remote-call]
|
||||||
@ -305,7 +295,7 @@ templates[] = ${prefix}/share/ahriman/templates
|
|||||||
; Template name to be used.
|
; Template name to be used.
|
||||||
template = rss.jinja2
|
template = rss.jinja2
|
||||||
; List of directories with templates.
|
; List of directories with templates.
|
||||||
templates[] = ${prefix}/share/ahriman/templates
|
templates = ${prefix}/share/ahriman/templates
|
||||||
|
|
||||||
; Telegram reporting trigger configuration sample.
|
; Telegram reporting trigger configuration sample.
|
||||||
[telegram]
|
[telegram]
|
||||||
@ -326,7 +316,7 @@ template = telegram-index.jinja2
|
|||||||
; Telegram specific template mode, one of MarkdownV2, HTML or Markdown.
|
; Telegram specific template mode, one of MarkdownV2, HTML or Markdown.
|
||||||
;template_type = HTML
|
;template_type = HTML
|
||||||
; List of directories with templates.
|
; List of directories with templates.
|
||||||
templates[] = ${prefix}/share/ahriman/templates
|
templates = ${prefix}/share/ahriman/templates
|
||||||
; HTTP request timeout in seconds.
|
; HTTP request timeout in seconds.
|
||||||
;timeout = 30
|
;timeout = 30
|
||||||
|
|
||||||
|
@ -7,17 +7,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group row mt-2">
|
<div class="form-group row mt-2">
|
||||||
<div class="col-4 col-lg-1" style="text-align: right">packages</div>
|
|
||||||
<div id="package-info-packages" class="col-8 col-lg-5"></div>
|
|
||||||
<div class="col-4 col-lg-1" style="text-align: right">version</div>
|
<div class="col-4 col-lg-1" style="text-align: right">version</div>
|
||||||
<div id="package-info-version" class="col-8 col-lg-5"></div>
|
<div id="package-info-version" class="col-8 col-lg-5"></div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row mt-2">
|
|
||||||
<div class="col-4 col-lg-1" style="text-align: right">packager</div>
|
<div class="col-4 col-lg-1" style="text-align: right">packager</div>
|
||||||
<div id="package-info-packager" class="col-8 col-lg-5"></div>
|
<div id="package-info-packager" class="col-8 col-lg-5"></div>
|
||||||
<div class="col-4 col-lg-1" style="text-align: right"></div>
|
|
||||||
<div id="package-info---placeholder" class="col-8 col-lg-5"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group row mt-2">
|
<div class="form-group row mt-2">
|
||||||
@ -35,10 +28,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group row mt-2">
|
<div class="form-group row mt-2">
|
||||||
|
<div class="col-4 col-lg-1" style="text-align: right">packages</div>
|
||||||
|
<div id="package-info-packages" class="col-8 col-lg-5"></div>
|
||||||
<div class="col-4 col-lg-1" style="text-align: right">depends</div>
|
<div class="col-4 col-lg-1" style="text-align: right">depends</div>
|
||||||
<div id="package-info-depends" class="col-8 col-lg-5"></div>
|
<div id="package-info-depends" class="col-8 col-lg-5"></div>
|
||||||
<div class="col-4 col-lg-1" style="text-align: right">implicitly depends</div>
|
|
||||||
<div id="package-info-implicitly-depends" class="col-8 col-lg-5"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="col-12">
|
<hr class="col-12">
|
||||||
@ -114,7 +107,6 @@
|
|||||||
const packageInfoAurUrl = document.getElementById("package-info-aur-url");
|
const packageInfoAurUrl = document.getElementById("package-info-aur-url");
|
||||||
const packageInfoDepends = document.getElementById("package-info-depends");
|
const packageInfoDepends = document.getElementById("package-info-depends");
|
||||||
const packageInfoGroups = document.getElementById("package-info-groups");
|
const packageInfoGroups = document.getElementById("package-info-groups");
|
||||||
const packageInfoImplicitlyDepends = document.getElementById("package-info-implicitly-depends");
|
|
||||||
const packageInfoLicenses = document.getElementById("package-info-licenses");
|
const packageInfoLicenses = document.getElementById("package-info-licenses");
|
||||||
const packageInfoPackager = document.getElementById("package-info-packager");
|
const packageInfoPackager = document.getElementById("package-info-packager");
|
||||||
const packageInfoPackages = document.getElementById("package-info-packages");
|
const packageInfoPackages = document.getElementById("package-info-packages");
|
||||||
@ -208,26 +200,6 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadDependencies(packageBase, onFailure) {
|
|
||||||
makeRequest(
|
|
||||||
`/api/v1/packages/${packageBase}/dependencies`,
|
|
||||||
{
|
|
||||||
query: {
|
|
||||||
architecture: repository.architecture,
|
|
||||||
repository: repository.repository,
|
|
||||||
},
|
|
||||||
convert: response => response.json(),
|
|
||||||
},
|
|
||||||
data => {
|
|
||||||
packageInfoImplicitlyDepends.innerHTML = listToTable(
|
|
||||||
Object.values(data.paths)
|
|
||||||
.reduce((accumulator, currentValue) => accumulator.concat(currentValue), [])
|
|
||||||
);
|
|
||||||
},
|
|
||||||
onFailure,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadEvents(packageBase, onFailure) {
|
function loadEvents(packageBase, onFailure) {
|
||||||
packageInfoEventsTable.bootstrapTable("showLoading");
|
packageInfoEventsTable.bootstrapTable("showLoading");
|
||||||
clearChart();
|
clearChart();
|
||||||
@ -315,9 +287,14 @@
|
|||||||
},
|
},
|
||||||
data => {
|
data => {
|
||||||
const description = data.find(Boolean);
|
const description = data.find(Boolean);
|
||||||
const packages = description.package.packages;
|
const packages = Object.keys(description.package.packages);
|
||||||
const aurUrl = description.package.remote.web_url;
|
const aurUrl = description.package.remote.web_url;
|
||||||
const upstreamUrls = Array.from(new Set(Object.values(packages).map(single => single.url))).sort();
|
const upstreamUrls = Array.from(
|
||||||
|
new Set(
|
||||||
|
Object.values(description.package.packages)
|
||||||
|
.map(single => single.url)
|
||||||
|
)
|
||||||
|
).sort();
|
||||||
|
|
||||||
packageInfo.textContent = `${description.package.base} ${description.status.status} at ${new Date(1000 * description.status.timestamp).toISOStringShort()}`;
|
packageInfo.textContent = `${description.package.base} ${description.status.status} at ${new Date(1000 * description.status.timestamp).toISOStringShort()}`;
|
||||||
|
|
||||||
@ -327,17 +304,17 @@
|
|||||||
|
|
||||||
packageInfoAurUrl.innerHTML = aurUrl ? safeLink(aurUrl, aurUrl, "AUR link").outerHTML : "";
|
packageInfoAurUrl.innerHTML = aurUrl ? safeLink(aurUrl, aurUrl, "AUR link").outerHTML : "";
|
||||||
packageInfoDepends.innerHTML = listToTable(
|
packageInfoDepends.innerHTML = listToTable(
|
||||||
Object.values(packages)
|
Object.values(description.package.packages)
|
||||||
.reduce((accumulator, currentValue) => {
|
.reduce((accumulator, currentValue) => {
|
||||||
return accumulator.concat(currentValue.depends.filter(v => !packages.hasOwnProperty(v)))
|
return accumulator.concat(currentValue.depends.filter(v => packages.indexOf(v) === -1))
|
||||||
.concat(currentValue.make_depends.filter(v => !packages.hasOwnProperty(v)).map(v => `${v} (make)`))
|
.concat(currentValue.make_depends.filter(v => packages.indexOf(v) === -1).map(v => `${v} (make)`))
|
||||||
.concat(currentValue.opt_depends.filter(v => !packages.hasOwnProperty(v)).map(v => `${v} (optional)`));
|
.concat(currentValue.opt_depends.filter(v => packages.indexOf(v) === -1).map(v => `${v} (optional)`));
|
||||||
}, [])
|
}, [])
|
||||||
);
|
);
|
||||||
packageInfoGroups.innerHTML = listToTable(extractListProperties(description.package, "groups"));
|
packageInfoGroups.innerHTML = listToTable(extractListProperties(description.package, "groups"));
|
||||||
packageInfoLicenses.innerHTML = listToTable(extractListProperties(description.package, "licenses"));
|
packageInfoLicenses.innerHTML = listToTable(extractListProperties(description.package, "licenses"));
|
||||||
packageInfoPackager.textContent = description.package.packager;
|
packageInfoPackager.textContent = description.package.packager;
|
||||||
packageInfoPackages.innerHTML = listToTable(Object.entries(packages).map(([key, value]) => `${key} (${value.description})`));
|
packageInfoPackages.innerHTML = listToTable(packages);
|
||||||
packageInfoUpstreamUrl.innerHTML = upstreamUrls.map(url => safeLink(url, url, "upstream link").outerHTML).join("<br>");
|
packageInfoUpstreamUrl.innerHTML = upstreamUrls.map(url => safeLink(url, url, "upstream link").outerHTML).join("<br>");
|
||||||
packageInfoVersion.textContent = description.package.version;
|
packageInfoVersion.textContent = description.package.version;
|
||||||
},
|
},
|
||||||
@ -388,7 +365,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
loadPackage(packageBase, onFailure);
|
loadPackage(packageBase, onFailure);
|
||||||
loadDependencies(packageBase, onFailure);
|
|
||||||
loadPatches(packageBase, onFailure);
|
loadPatches(packageBase, onFailure);
|
||||||
loadLogs(packageBase, onFailure);
|
loadLogs(packageBase, onFailure);
|
||||||
loadChanges(packageBase, onFailure);
|
loadChanges(packageBase, onFailure);
|
||||||
@ -412,7 +388,6 @@
|
|||||||
packageInfoAurUrl.textContent = "";
|
packageInfoAurUrl.textContent = "";
|
||||||
packageInfoDepends.textContent = "";
|
packageInfoDepends.textContent = "";
|
||||||
packageInfoGroups.textContent = "";
|
packageInfoGroups.textContent = "";
|
||||||
packageInfoImplicitlyDepends.textContent = "";
|
|
||||||
packageInfoLicenses.textContent = "";
|
packageInfoLicenses.textContent = "";
|
||||||
packageInfoPackager.textContent = "";
|
packageInfoPackager.textContent = "";
|
||||||
packageInfoPackages.textContent = "";
|
packageInfoPackages.textContent = "";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH AHRIMAN "1" "2024\-09\-26" "ahriman" "Generated Python Manual"
|
.TH AHRIMAN "1" "2024\-11\-13" "ahriman" "Generated Python Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
ahriman
|
ahriman
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -17,8 +17,8 @@ authors = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bcrypt",
|
|
||||||
"inflection",
|
"inflection",
|
||||||
|
"passlib",
|
||||||
"pyelftools",
|
"pyelftools",
|
||||||
"requests",
|
"requests",
|
||||||
]
|
]
|
||||||
@ -100,6 +100,3 @@ include = [
|
|||||||
exclude = [
|
exclude = [
|
||||||
"package/archlinux",
|
"package/archlinux",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.flit.external-data]
|
|
||||||
directory = "package"
|
|
||||||
|
@ -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.15.2"
|
__version__ = "2.15.3"
|
||||||
|
@ -110,7 +110,6 @@ Start web service (requires additional configuration):
|
|||||||
_set_package_add_parser(subparsers)
|
_set_package_add_parser(subparsers)
|
||||||
_set_package_changes_parser(subparsers)
|
_set_package_changes_parser(subparsers)
|
||||||
_set_package_changes_remove_parser(subparsers)
|
_set_package_changes_remove_parser(subparsers)
|
||||||
_set_package_copy_parser(subparsers)
|
|
||||||
_set_package_remove_parser(subparsers)
|
_set_package_remove_parser(subparsers)
|
||||||
_set_package_status_parser(subparsers)
|
_set_package_status_parser(subparsers)
|
||||||
_set_package_status_remove_parser(subparsers)
|
_set_package_status_remove_parser(subparsers)
|
||||||
@ -335,27 +334,6 @@ def _set_package_changes_remove_parser(root: SubParserAction) -> argparse.Argume
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def _set_package_copy_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|
||||||
"""
|
|
||||||
add parser for package copy subcommand
|
|
||||||
|
|
||||||
Args:
|
|
||||||
root(SubParserAction): subparsers for the commands
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
argparse.ArgumentParser: created argument parser
|
|
||||||
"""
|
|
||||||
parser = root.add_parser("package-copy", aliases=["copy"], help="copy package from another repository",
|
|
||||||
description="copy package and its metadata from another repository",
|
|
||||||
formatter_class=_HelpFormatter)
|
|
||||||
parser.add_argument("source", help="source repository name")
|
|
||||||
parser.add_argument("package", help="package base", nargs="+")
|
|
||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
|
||||||
parser.add_argument("--remove", help="remove package from the source repository after", action="store_true")
|
|
||||||
parser.set_defaults(handler=handlers.Copy)
|
|
||||||
return parser
|
|
||||||
|
|
||||||
|
|
||||||
def _set_package_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
def _set_package_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
"""
|
"""
|
||||||
add parser for package removal subcommand
|
add parser for package removal subcommand
|
||||||
|
@ -141,19 +141,19 @@ class ApplicationPackages(ApplicationProperties):
|
|||||||
self.database.build_queue_insert(package)
|
self.database.build_queue_insert(package)
|
||||||
self.reporter.set_unknown(package)
|
self.reporter.set_unknown(package)
|
||||||
|
|
||||||
def add(self, packages: Iterable[str], source: PackageSource, username: str | None = None) -> None:
|
def add(self, names: Iterable[str], source: PackageSource, username: str | None = None) -> None:
|
||||||
"""
|
"""
|
||||||
add packages for the next build
|
add packages for the next build
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
packages(Iterable[str]): list of package bases to add
|
names(Iterable[str]): list of package bases to add
|
||||||
source(PackageSource): package source to add
|
source(PackageSource): package source to add
|
||||||
username(str | None, optional): optional override of username for build process (Default value = None)
|
username(str | None, optional): optional override of username for build process (Default value = None)
|
||||||
"""
|
"""
|
||||||
for package in packages:
|
for name in names:
|
||||||
resolved_source = source.resolve(package, self.repository.paths)
|
resolved_source = source.resolve(name, self.repository.paths)
|
||||||
fn = getattr(self, f"_add_{resolved_source.value}")
|
fn = getattr(self, f"_add_{resolved_source.value}")
|
||||||
fn(package, username)
|
fn(name, username)
|
||||||
|
|
||||||
def on_result(self, result: Result) -> None:
|
def on_result(self, result: Result) -> None:
|
||||||
"""
|
"""
|
||||||
@ -167,16 +167,16 @@ class ApplicationPackages(ApplicationProperties):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def remove(self, packages: Iterable[str]) -> Result:
|
def remove(self, names: Iterable[str]) -> Result:
|
||||||
"""
|
"""
|
||||||
remove packages from repository
|
remove packages from repository
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
packages(Iterable[str]): list of packages (either base or name) to remove
|
names(Iterable[str]): list of packages (either base or name) to remove
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Result: removal result
|
Result: removal result
|
||||||
"""
|
"""
|
||||||
result = self.repository.process_remove(packages)
|
result = self.repository.process_remove(names)
|
||||||
self.on_result(result)
|
self.on_result(result)
|
||||||
return result
|
return result
|
||||||
|
@ -191,12 +191,6 @@ class ApplicationRepository(ApplicationProperties):
|
|||||||
"""
|
"""
|
||||||
updates = {}
|
updates = {}
|
||||||
|
|
||||||
# always add already built packages, because they will be always added
|
|
||||||
updates.update({
|
|
||||||
package.base: package
|
|
||||||
for package in self.repository.load_archives(self.repository.packages_built())
|
|
||||||
})
|
|
||||||
|
|
||||||
if aur:
|
if aur:
|
||||||
updates.update({package.base: package for package in self.repository.updates_aur(filter_packages, vcs=vcs)})
|
updates.update({package.base: package for package in self.repository.updates_aur(filter_packages, vcs=vcs)})
|
||||||
if local:
|
if local:
|
||||||
|
@ -21,7 +21,6 @@ from ahriman.application.handlers.add import Add
|
|||||||
from ahriman.application.handlers.backup import Backup
|
from ahriman.application.handlers.backup import Backup
|
||||||
from ahriman.application.handlers.change import Change
|
from ahriman.application.handlers.change import Change
|
||||||
from ahriman.application.handlers.clean import Clean
|
from ahriman.application.handlers.clean import Clean
|
||||||
from ahriman.application.handlers.copy import Copy
|
|
||||||
from ahriman.application.handlers.daemon import Daemon
|
from ahriman.application.handlers.daemon import Daemon
|
||||||
from ahriman.application.handlers.dump import Dump
|
from ahriman.application.handlers.dump import Dump
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
#
|
|
||||||
# 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/>.
|
|
||||||
#
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
|
||||||
from ahriman.core.configuration import Configuration
|
|
||||||
from ahriman.models.build_status import BuildStatusEnum
|
|
||||||
from ahriman.models.package import Package
|
|
||||||
from ahriman.models.package_source import PackageSource
|
|
||||||
from ahriman.models.repository_id import RepositoryId
|
|
||||||
|
|
||||||
|
|
||||||
class Copy(Handler):
|
|
||||||
"""
|
|
||||||
copy packages handler
|
|
||||||
"""
|
|
||||||
|
|
||||||
ALLOW_MULTI_ARCHITECTURE_RUN = False # conflicting action
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def run(cls, args: argparse.Namespace, repository_id: RepositoryId, configuration: Configuration, *,
|
|
||||||
report: bool) -> None:
|
|
||||||
"""
|
|
||||||
callback for command line
|
|
||||||
|
|
||||||
Args:
|
|
||||||
args(argparse.Namespace): command line args
|
|
||||||
repository_id(RepositoryId): repository unique identifier
|
|
||||||
configuration(Configuration): configuration instance
|
|
||||||
report(bool): force enable or disable reporting
|
|
||||||
"""
|
|
||||||
application = Application(repository_id, configuration, report=report)
|
|
||||||
application.on_start()
|
|
||||||
|
|
||||||
configuration_path, _ = configuration.check_loaded()
|
|
||||||
source_repository_id = RepositoryId(repository_id.architecture, args.source)
|
|
||||||
source_configuration = Configuration.from_path(configuration_path, source_repository_id)
|
|
||||||
source_application = Application(source_repository_id, source_configuration, report=report)
|
|
||||||
|
|
||||||
packages = source_application.repository.packages(args.package)
|
|
||||||
Copy.check_status(args.exit_code, packages)
|
|
||||||
|
|
||||||
for package in packages:
|
|
||||||
Copy.copy_package(package, application, source_application)
|
|
||||||
|
|
||||||
# run update
|
|
||||||
application.update([])
|
|
||||||
|
|
||||||
if args.remove:
|
|
||||||
source_application.remove(args.package)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def copy_package(package: Package, application: Application, source_application: Application) -> None:
|
|
||||||
"""
|
|
||||||
copy package ``package`` from source repository to target repository
|
|
||||||
|
|
||||||
Args:
|
|
||||||
package(Package): package to copy
|
|
||||||
application(Application): application instance of the target repository
|
|
||||||
source_application(Application): application instance of the source repository
|
|
||||||
"""
|
|
||||||
# copy files
|
|
||||||
source_paths = [
|
|
||||||
str(source_application.repository.paths.repository / source.filename)
|
|
||||||
for source in package.packages.values()
|
|
||||||
if source.filename is not None
|
|
||||||
]
|
|
||||||
application.add(source_paths, PackageSource.Archive)
|
|
||||||
|
|
||||||
# copy metadata
|
|
||||||
application.reporter.package_changes_update(
|
|
||||||
package.base, source_application.reporter.package_changes_get(package.base)
|
|
||||||
)
|
|
||||||
application.reporter.package_dependencies_update(
|
|
||||||
package.base, source_application.reporter.package_dependencies_get(package.base)
|
|
||||||
)
|
|
||||||
application.reporter.package_update(package, BuildStatusEnum.Pending)
|
|
@ -161,8 +161,8 @@ class Setup(Handler):
|
|||||||
repository_server(str): url of the repository
|
repository_server(str): url of the repository
|
||||||
"""
|
"""
|
||||||
# allow_no_value=True is required because pacman uses boolean configuration in which just keys present
|
# allow_no_value=True is required because pacman uses boolean configuration in which just keys present
|
||||||
# (e.g. NoProgressBar) which will lead to exception. allow_multi_key=False is set just for fun
|
# (e.g. NoProgressBar) which will lead to exception
|
||||||
configuration = Configuration(allow_no_value=True, allow_multi_key=False)
|
configuration = Configuration(allow_no_value=True)
|
||||||
# preserve case
|
# preserve case
|
||||||
# stupid mypy thinks that it is impossible
|
# stupid mypy thinks that it is impossible
|
||||||
configuration.optionxform = lambda optionstr: optionstr # type: ignore[method-assign]
|
configuration.optionxform = lambda optionstr: optionstr # type: ignore[method-assign]
|
||||||
|
@ -226,7 +226,7 @@ class PkgbuildParser(shlex.shlex):
|
|||||||
pass
|
pass
|
||||||
case PkgbuildToken.ArrayEnds:
|
case PkgbuildToken.ArrayEnds:
|
||||||
break
|
break
|
||||||
case PkgbuildToken.Comment:
|
case comment if comment.startswith(PkgbuildToken.Comment):
|
||||||
self.instream.readline()
|
self.instream.readline()
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -267,7 +267,7 @@ class PkgbuildParser(shlex.shlex):
|
|||||||
counter -= 1
|
counter -= 1
|
||||||
if counter == 0:
|
if counter == 0:
|
||||||
break
|
break
|
||||||
case PkgbuildToken.Comment:
|
case comment if comment.startswith(PkgbuildToken.Comment):
|
||||||
self.instream.readline()
|
self.instream.readline()
|
||||||
|
|
||||||
if not 0 < start_position < end_position:
|
if not 0 < start_position < end_position:
|
||||||
@ -303,7 +303,7 @@ class PkgbuildParser(shlex.shlex):
|
|||||||
yield PkgbuildPatch(key, value)
|
yield PkgbuildPatch(key, value)
|
||||||
return
|
return
|
||||||
|
|
||||||
if token == PkgbuildToken.Comment:
|
if token.startswith(PkgbuildToken.Comment):
|
||||||
self.instream.readline()
|
self.instream.readline()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ from collections.abc import Callable
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Self
|
from typing import Any, Self
|
||||||
|
|
||||||
from ahriman.core.configuration.configuration_multi_dict import ConfigurationMultiDict
|
|
||||||
from ahriman.core.configuration.shell_interpolator import ShellInterpolator
|
from ahriman.core.configuration.shell_interpolator import ShellInterpolator
|
||||||
from ahriman.core.exceptions import InitializeError
|
from ahriman.core.exceptions import InitializeError
|
||||||
from ahriman.models.repository_id import RepositoryId
|
from ahriman.models.repository_id import RepositoryId
|
||||||
@ -70,27 +69,21 @@ class Configuration(configparser.RawConfigParser):
|
|||||||
SYSTEM_CONFIGURATION_PATH = Path(sys.prefix) / "share" / "ahriman" / "settings" / "ahriman.ini"
|
SYSTEM_CONFIGURATION_PATH = Path(sys.prefix) / "share" / "ahriman" / "settings" / "ahriman.ini"
|
||||||
converters: dict[str, Callable[[str], Any]] # typing guard
|
converters: dict[str, Callable[[str], Any]] # typing guard
|
||||||
|
|
||||||
def __init__(self, allow_no_value: bool = False, allow_multi_key: bool = True) -> None:
|
def __init__(self, allow_no_value: bool = False) -> None:
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
allow_no_value(bool, optional): copies :class:`configparser.RawConfigParser` behaviour. In case if it is set
|
allow_no_value(bool, optional): copies :class:`configparser.RawConfigParser` behaviour. In case if it is set
|
||||||
to ``True``, the keys without values will be allowed (Default value = False)
|
to ``True``, the keys without values will be allowed (Default value = False)
|
||||||
allow_multi_key(bool, optional): if set to ``False``, then the default dictionary class will be used to
|
|
||||||
store keys internally. Otherwise, the special implementation will be used, which supports arrays
|
|
||||||
(Default value = True)
|
|
||||||
"""
|
"""
|
||||||
configparser.RawConfigParser.__init__(
|
configparser.RawConfigParser.__init__(
|
||||||
self,
|
self,
|
||||||
dict_type=ConfigurationMultiDict if allow_multi_key else dict, # type: ignore[arg-type]
|
|
||||||
allow_no_value=allow_no_value,
|
allow_no_value=allow_no_value,
|
||||||
strict=False,
|
|
||||||
empty_lines_in_values=not allow_multi_key,
|
|
||||||
interpolation=ShellInterpolator(),
|
interpolation=ShellInterpolator(),
|
||||||
converters={
|
converters={
|
||||||
"list": shlex.split,
|
"list": shlex.split,
|
||||||
"path": self._convert_path,
|
"path": self._convert_path,
|
||||||
"pathlist": lambda value: [self._convert_path(element) for element in shlex.split(value)],
|
"pathlist": lambda value: [self._convert_path(element) for element in shlex.split(value)],
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
self.repository_id: RepositoryId | None = None
|
self.repository_id: RepositoryId | None = None
|
||||||
|
@ -1,91 +0,0 @@
|
|||||||
#
|
|
||||||
# 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/>.
|
|
||||||
#
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from ahriman.core.exceptions import OptionError
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigurationMultiDict(dict[str, Any]):
|
|
||||||
"""
|
|
||||||
wrapper around :class:`dict` to handle multiple configuration keys as lists if they end with ``[]``.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
This class is designed to be used only with :class:`configparser.RawConfigParser` class, but idea is that
|
|
||||||
if the key ends with ``[]`` it will be treated as array and the result will be appended to the current value.
|
|
||||||
In addition, if the value is empty, then it will clear previous values, e.g.:
|
|
||||||
|
|
||||||
>>> data = ConfigurationMultiDict()
|
|
||||||
>>>
|
|
||||||
>>> data["single"] = "value" # append normal key
|
|
||||||
>>> print(data) # {"single": "value"}
|
|
||||||
>>>
|
|
||||||
>>> data["array[]"] = ["value1"] # append array value
|
|
||||||
>>> data["array[]"] = ["value2"]
|
|
||||||
>>> print(data) # {"single": "value", "array": ["value1 value2"]}
|
|
||||||
>>>
|
|
||||||
>>> data["array[]"] = [""] # clear previous values
|
|
||||||
>>> data["array[]"] = ["value3"]
|
|
||||||
>>> print(data) # {"single": "value", "array": ["value3"]}
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _set_array_value(self, key: str, value: Any) -> None:
|
|
||||||
"""
|
|
||||||
set array value. If the key already exists in the dictionary, its value will be prepended to new value
|
|
||||||
|
|
||||||
Args:
|
|
||||||
key(str): key to insert
|
|
||||||
value(Any): value of the related key
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
OptionError: if the key already exists in the dictionary, but not a single value list or a string
|
|
||||||
"""
|
|
||||||
match self.get(key):
|
|
||||||
case [current_value] | str(current_value): # type: ignore[misc]
|
|
||||||
value = f"{current_value} {value}"
|
|
||||||
case None:
|
|
||||||
pass
|
|
||||||
case other:
|
|
||||||
raise OptionError(other)
|
|
||||||
super().__setitem__(key, [value])
|
|
||||||
|
|
||||||
def __setitem__(self, key: str, value: Any) -> None:
|
|
||||||
"""
|
|
||||||
set ``key`` to ``value``. If the value equals to ``[""]`` (array with empty string), then the key
|
|
||||||
will be removed (as expected from :class:`configparser.RawConfigParser`). If the key ends with
|
|
||||||
``[]``, the value will be treated as an array and vice versa.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
key(str): key to insert
|
|
||||||
value(Any): value of the related key
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
OptionError: if ``key`` contains ``[]``, but not at the end of the string (e.g. ``prefix[]suffix``)
|
|
||||||
"""
|
|
||||||
real_key, is_key_array, remaining = key.partition("[]")
|
|
||||||
if remaining:
|
|
||||||
raise OptionError(key)
|
|
||||||
|
|
||||||
match value:
|
|
||||||
case [""]: # empty value key
|
|
||||||
self.pop(real_key, None)
|
|
||||||
case [array_value] if is_key_array: # update array value
|
|
||||||
self._set_array_value(real_key, array_value)
|
|
||||||
case _: # normal key
|
|
||||||
super().__setitem__(real_key, value)
|
|
@ -17,9 +17,8 @@
|
|||||||
# 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/>.
|
||||||
#
|
#
|
||||||
import bcrypt
|
|
||||||
|
|
||||||
from dataclasses import dataclass, replace
|
from dataclasses import dataclass, replace
|
||||||
|
from passlib.hash import sha512_crypt
|
||||||
from secrets import token_urlsafe as generate_password
|
from secrets import token_urlsafe as generate_password
|
||||||
from typing import Self
|
from typing import Self
|
||||||
|
|
||||||
@ -68,6 +67,8 @@ class User:
|
|||||||
packager_id: str | None = None
|
packager_id: str | None = None
|
||||||
key: str | None = None
|
key: str | None = None
|
||||||
|
|
||||||
|
_HASHER = sha512_crypt
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
"""
|
"""
|
||||||
remove empty fields
|
remove empty fields
|
||||||
@ -100,9 +101,10 @@ class User:
|
|||||||
bool: ``True`` in case if password matches, ``False`` otherwise
|
bool: ``True`` in case if password matches, ``False`` otherwise
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return bcrypt.checkpw((password + salt).encode("utf8"), self.password.encode("utf8"))
|
verified: bool = self._HASHER.verify(password + salt, self.password)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return False # the absence of evidence is not the evidence of absence (c) Gin Rummy
|
verified = False # the absence of evidence is not the evidence of absence (c) Gin Rummy
|
||||||
|
return verified
|
||||||
|
|
||||||
def hash_password(self, salt: str) -> Self:
|
def hash_password(self, salt: str) -> Self:
|
||||||
"""
|
"""
|
||||||
@ -118,8 +120,8 @@ class User:
|
|||||||
# in case of empty password we leave it empty. This feature is used by any external (like OAuth) provider
|
# in case of empty password we leave it empty. This feature is used by any external (like OAuth) provider
|
||||||
# when we do not store any password here
|
# when we do not store any password here
|
||||||
return self
|
return self
|
||||||
password_hash = bcrypt.hashpw((self.password + salt).encode("utf8"), bcrypt.gensalt())
|
password_hash: str = self._HASHER.hash(self.password + salt)
|
||||||
return replace(self, password=password_hash.decode("utf8"))
|
return replace(self, password=password_hash)
|
||||||
|
|
||||||
def verify_access(self, required: UserAccess) -> bool:
|
def verify_access(self, required: UserAccess) -> bool:
|
||||||
"""
|
"""
|
||||||
|
@ -42,7 +42,7 @@ class DependenciesView(StatusViewGuard, BaseView):
|
|||||||
ROUTES = ["/api/v1/packages/{package}/dependencies"]
|
ROUTES = ["/api/v1/packages/{package}/dependencies"]
|
||||||
|
|
||||||
@aiohttp_apispec.docs(
|
@aiohttp_apispec.docs(
|
||||||
tags=["Packages"],
|
tags=["Build"],
|
||||||
summary="Get package dependencies",
|
summary="Get package dependencies",
|
||||||
description="Retrieve package implicit dependencies",
|
description="Retrieve package implicit dependencies",
|
||||||
responses={
|
responses={
|
||||||
@ -74,7 +74,7 @@ class DependenciesView(StatusViewGuard, BaseView):
|
|||||||
return json_response(dependencies.view())
|
return json_response(dependencies.view())
|
||||||
|
|
||||||
@aiohttp_apispec.docs(
|
@aiohttp_apispec.docs(
|
||||||
tags=["Packages"],
|
tags=["Build"],
|
||||||
summary="Update package dependencies",
|
summary="Update package dependencies",
|
||||||
description="Set package implicit dependencies",
|
description="Set package implicit dependencies",
|
||||||
responses={
|
responses={
|
||||||
|
@ -139,7 +139,7 @@ def test_add_remote(application_packages: ApplicationPackages, package_descripti
|
|||||||
|
|
||||||
def test_add_remote_missing(application_packages: ApplicationPackages, mocker: MockerFixture) -> None:
|
def test_add_remote_missing(application_packages: ApplicationPackages, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must raise UnknownPackageError if remote package wasn't found
|
must add package from remote source
|
||||||
"""
|
"""
|
||||||
mocker.patch("requests.get", side_effect=Exception())
|
mocker.patch("requests.get", side_effect=Exception())
|
||||||
with pytest.raises(UnknownPackageError):
|
with pytest.raises(UnknownPackageError):
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import call as MockCall
|
from unittest.mock import call as MockCall
|
||||||
|
|
||||||
@ -79,7 +78,7 @@ def test_clean_packages(application_repository: ApplicationRepository, mocker: M
|
|||||||
|
|
||||||
def test_clean_pacman(application_repository: ApplicationRepository, mocker: MockerFixture) -> None:
|
def test_clean_pacman(application_repository: ApplicationRepository, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must clean pacman directory
|
must clean packages directory
|
||||||
"""
|
"""
|
||||||
clear_mock = mocker.patch("ahriman.core.repository.Repository.clear_pacman")
|
clear_mock = mocker.patch("ahriman.core.repository.Repository.clear_pacman")
|
||||||
application_repository.clean(cache=False, chroot=False, manual=False, packages=False, pacman=True)
|
application_repository.clean(cache=False, chroot=False, manual=False, packages=False, pacman=True)
|
||||||
@ -214,9 +213,6 @@ def test_updates_all(application_repository: ApplicationRepository, package_ahri
|
|||||||
"""
|
"""
|
||||||
must get updates for all
|
must get updates for all
|
||||||
"""
|
"""
|
||||||
path = Path("local")
|
|
||||||
mocker.patch("ahriman.core.repository.package_info.PackageInfo.packages_built", return_value=[path])
|
|
||||||
updates_built_mock = mocker.patch("ahriman.core.repository.package_info.PackageInfo.load_archives")
|
|
||||||
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur",
|
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur",
|
||||||
return_value=[package_ahriman])
|
return_value=[package_ahriman])
|
||||||
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
||||||
@ -224,7 +220,6 @@ def test_updates_all(application_repository: ApplicationRepository, package_ahri
|
|||||||
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
||||||
|
|
||||||
application_repository.updates([], aur=True, local=True, manual=True, vcs=True, check_files=True)
|
application_repository.updates([], aur=True, local=True, manual=True, vcs=True, check_files=True)
|
||||||
updates_built_mock.assert_called_once_with([path])
|
|
||||||
updates_aur_mock.assert_called_once_with([], vcs=True)
|
updates_aur_mock.assert_called_once_with([], vcs=True)
|
||||||
updates_local_mock.assert_called_once_with(vcs=True)
|
updates_local_mock.assert_called_once_with(vcs=True)
|
||||||
updates_manual_mock.assert_called_once_with()
|
updates_manual_mock.assert_called_once_with()
|
||||||
@ -235,16 +230,12 @@ def test_updates_disabled(application_repository: ApplicationRepository, mocker:
|
|||||||
"""
|
"""
|
||||||
must get updates without anything
|
must get updates without anything
|
||||||
"""
|
"""
|
||||||
path = Path("local")
|
|
||||||
mocker.patch("ahriman.core.repository.package_info.PackageInfo.packages_built", return_value=[path])
|
|
||||||
updates_built_mock = mocker.patch("ahriman.core.repository.package_info.PackageInfo.load_archives")
|
|
||||||
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
||||||
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
||||||
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
||||||
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
||||||
|
|
||||||
application_repository.updates([], aur=False, local=False, manual=False, vcs=True, check_files=False)
|
application_repository.updates([], aur=False, local=False, manual=False, vcs=True, check_files=False)
|
||||||
updates_built_mock.assert_called_once_with([path])
|
|
||||||
updates_aur_mock.assert_not_called()
|
updates_aur_mock.assert_not_called()
|
||||||
updates_local_mock.assert_not_called()
|
updates_local_mock.assert_not_called()
|
||||||
updates_manual_mock.assert_not_called()
|
updates_manual_mock.assert_not_called()
|
||||||
@ -255,16 +246,12 @@ def test_updates_no_aur(application_repository: ApplicationRepository, mocker: M
|
|||||||
"""
|
"""
|
||||||
must get updates without aur
|
must get updates without aur
|
||||||
"""
|
"""
|
||||||
path = Path("local")
|
|
||||||
mocker.patch("ahriman.core.repository.package_info.PackageInfo.packages_built", return_value=[path])
|
|
||||||
updates_built_mock = mocker.patch("ahriman.core.repository.package_info.PackageInfo.load_archives")
|
|
||||||
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
||||||
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
||||||
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
||||||
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
||||||
|
|
||||||
application_repository.updates([], aur=False, local=True, manual=True, vcs=True, check_files=True)
|
application_repository.updates([], aur=False, local=True, manual=True, vcs=True, check_files=True)
|
||||||
updates_built_mock.assert_called_once_with([path])
|
|
||||||
updates_aur_mock.assert_not_called()
|
updates_aur_mock.assert_not_called()
|
||||||
updates_local_mock.assert_called_once_with(vcs=True)
|
updates_local_mock.assert_called_once_with(vcs=True)
|
||||||
updates_manual_mock.assert_called_once_with()
|
updates_manual_mock.assert_called_once_with()
|
||||||
@ -275,16 +262,12 @@ def test_updates_no_local(application_repository: ApplicationRepository, mocker:
|
|||||||
"""
|
"""
|
||||||
must get updates without local packages
|
must get updates without local packages
|
||||||
"""
|
"""
|
||||||
path = Path("local")
|
|
||||||
mocker.patch("ahriman.core.repository.package_info.PackageInfo.packages_built", return_value=[path])
|
|
||||||
updates_built_mock = mocker.patch("ahriman.core.repository.package_info.PackageInfo.load_archives")
|
|
||||||
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
||||||
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
||||||
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
||||||
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
||||||
|
|
||||||
application_repository.updates([], aur=True, local=False, manual=True, vcs=True, check_files=True)
|
application_repository.updates([], aur=True, local=False, manual=True, vcs=True, check_files=True)
|
||||||
updates_built_mock.assert_called_once_with([path])
|
|
||||||
updates_aur_mock.assert_called_once_with([], vcs=True)
|
updates_aur_mock.assert_called_once_with([], vcs=True)
|
||||||
updates_local_mock.assert_not_called()
|
updates_local_mock.assert_not_called()
|
||||||
updates_manual_mock.assert_called_once_with()
|
updates_manual_mock.assert_called_once_with()
|
||||||
@ -295,16 +278,12 @@ def test_updates_no_manual(application_repository: ApplicationRepository, mocker
|
|||||||
"""
|
"""
|
||||||
must get updates without manual
|
must get updates without manual
|
||||||
"""
|
"""
|
||||||
path = Path("local")
|
|
||||||
mocker.patch("ahriman.core.repository.package_info.PackageInfo.packages_built", return_value=[path])
|
|
||||||
updates_built_mock = mocker.patch("ahriman.core.repository.package_info.PackageInfo.load_archives")
|
|
||||||
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
||||||
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
||||||
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
||||||
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
||||||
|
|
||||||
application_repository.updates([], aur=True, local=True, manual=False, vcs=True, check_files=True)
|
application_repository.updates([], aur=True, local=True, manual=False, vcs=True, check_files=True)
|
||||||
updates_built_mock.assert_called_once_with([path])
|
|
||||||
updates_aur_mock.assert_called_once_with([], vcs=True)
|
updates_aur_mock.assert_called_once_with([], vcs=True)
|
||||||
updates_local_mock.assert_called_once_with(vcs=True)
|
updates_local_mock.assert_called_once_with(vcs=True)
|
||||||
updates_manual_mock.assert_not_called()
|
updates_manual_mock.assert_not_called()
|
||||||
@ -315,16 +294,12 @@ def test_updates_no_vcs(application_repository: ApplicationRepository, mocker: M
|
|||||||
"""
|
"""
|
||||||
must get updates without VCS
|
must get updates without VCS
|
||||||
"""
|
"""
|
||||||
path = Path("local")
|
|
||||||
mocker.patch("ahriman.core.repository.package_info.PackageInfo.packages_built", return_value=[path])
|
|
||||||
updates_built_mock = mocker.patch("ahriman.core.repository.package_info.PackageInfo.load_archives")
|
|
||||||
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
||||||
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
||||||
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
||||||
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
||||||
|
|
||||||
application_repository.updates([], aur=True, local=True, manual=True, vcs=False, check_files=True)
|
application_repository.updates([], aur=True, local=True, manual=True, vcs=False, check_files=True)
|
||||||
updates_built_mock.assert_called_once_with([path])
|
|
||||||
updates_aur_mock.assert_called_once_with([], vcs=False)
|
updates_aur_mock.assert_called_once_with([], vcs=False)
|
||||||
updates_local_mock.assert_called_once_with(vcs=False)
|
updates_local_mock.assert_called_once_with(vcs=False)
|
||||||
updates_manual_mock.assert_called_once_with()
|
updates_manual_mock.assert_called_once_with()
|
||||||
@ -335,16 +310,12 @@ def test_updates_no_check_files(application_repository: ApplicationRepository, m
|
|||||||
"""
|
"""
|
||||||
must get updates without checking broken links
|
must get updates without checking broken links
|
||||||
"""
|
"""
|
||||||
path = Path("local")
|
|
||||||
mocker.patch("ahriman.core.repository.package_info.PackageInfo.packages_built", return_value=[path])
|
|
||||||
updates_built_mock = mocker.patch("ahriman.core.repository.package_info.PackageInfo.load_archives")
|
|
||||||
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
||||||
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
||||||
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
||||||
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
||||||
|
|
||||||
application_repository.updates([], aur=True, local=True, manual=True, vcs=True, check_files=False)
|
application_repository.updates([], aur=True, local=True, manual=True, vcs=True, check_files=False)
|
||||||
updates_built_mock.assert_called_once_with([path])
|
|
||||||
updates_aur_mock.assert_called_once_with([], vcs=True)
|
updates_aur_mock.assert_called_once_with([], vcs=True)
|
||||||
updates_local_mock.assert_called_once_with(vcs=True)
|
updates_local_mock.assert_called_once_with(vcs=True)
|
||||||
updates_manual_mock.assert_called_once_with()
|
updates_manual_mock.assert_called_once_with()
|
||||||
@ -355,16 +326,12 @@ def test_updates_with_filter(application_repository: ApplicationRepository, mock
|
|||||||
"""
|
"""
|
||||||
must get updates with filter
|
must get updates with filter
|
||||||
"""
|
"""
|
||||||
path = Path("local")
|
|
||||||
mocker.patch("ahriman.core.repository.package_info.PackageInfo.packages_built", return_value=[path])
|
|
||||||
updates_built_mock = mocker.patch("ahriman.core.repository.package_info.PackageInfo.load_archives")
|
|
||||||
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
updates_aur_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_aur")
|
||||||
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
updates_local_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_local")
|
||||||
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
updates_manual_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_manual")
|
||||||
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
updates_deps_mock = mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.updates_dependencies")
|
||||||
|
|
||||||
application_repository.updates(["filter"], aur=True, local=True, manual=True, vcs=True, check_files=True)
|
application_repository.updates(["filter"], aur=True, local=True, manual=True, vcs=True, check_files=True)
|
||||||
updates_built_mock.assert_called_once_with([path])
|
|
||||||
updates_aur_mock.assert_called_once_with(["filter"], vcs=True)
|
updates_aur_mock.assert_called_once_with(["filter"], vcs=True)
|
||||||
updates_local_mock.assert_called_once_with(vcs=True)
|
updates_local_mock.assert_called_once_with(vcs=True)
|
||||||
updates_manual_mock.assert_called_once_with()
|
updates_manual_mock.assert_called_once_with()
|
||||||
|
@ -171,7 +171,7 @@ def test_repositories_extract_repository(args: argparse.Namespace, configuration
|
|||||||
def test_repositories_extract_repository_legacy(args: argparse.Namespace, configuration: Configuration,
|
def test_repositories_extract_repository_legacy(args: argparse.Namespace, configuration: Configuration,
|
||||||
mocker: MockerFixture) -> None:
|
mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must generate list of available repositories based on flags and tree (legacy mode)
|
must generate list of available repositories based on flags and tree
|
||||||
"""
|
"""
|
||||||
args.architecture = "arch"
|
args.architecture = "arch"
|
||||||
args.configuration = configuration.path
|
args.configuration = configuration.path
|
||||||
|
@ -1,105 +0,0 @@
|
|||||||
import argparse
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from pytest_mock import MockerFixture
|
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
|
||||||
from ahriman.application.handlers import Copy
|
|
||||||
from ahriman.core.configuration import Configuration
|
|
||||||
from ahriman.core.repository import Repository
|
|
||||||
from ahriman.models.build_status import BuildStatusEnum
|
|
||||||
from ahriman.models.package import Package
|
|
||||||
from ahriman.models.package_source import PackageSource
|
|
||||||
|
|
||||||
|
|
||||||
def _default_args(args: argparse.Namespace) -> argparse.Namespace:
|
|
||||||
"""
|
|
||||||
default arguments for these test cases
|
|
||||||
|
|
||||||
Args:
|
|
||||||
args(argparse.Namespace): command line arguments fixture
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
argparse.Namespace: generated arguments for these test cases
|
|
||||||
"""
|
|
||||||
args.source = "source"
|
|
||||||
args.package = ["ahriman"]
|
|
||||||
args.exit_code = False
|
|
||||||
args.remove = False
|
|
||||||
return args
|
|
||||||
|
|
||||||
|
|
||||||
def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
|
||||||
package_ahriman: Package, mocker: MockerFixture) -> None:
|
|
||||||
"""
|
|
||||||
must run command
|
|
||||||
"""
|
|
||||||
args = _default_args(args)
|
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
|
||||||
mocker.patch("ahriman.core.repository.Repository.packages", return_value=[package_ahriman])
|
|
||||||
application_mock = mocker.patch("ahriman.application.handlers.Copy.copy_package")
|
|
||||||
update_mock = mocker.patch("ahriman.application.application.Application.update")
|
|
||||||
remove_mock = mocker.patch("ahriman.application.application.Application.remove")
|
|
||||||
on_start_mock = mocker.patch("ahriman.application.application.Application.on_start")
|
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
|
||||||
Copy.run(args, repository_id, configuration, report=False)
|
|
||||||
application_mock.assert_called_once_with(package_ahriman, pytest.helpers.anyvar(int), pytest.helpers.anyvar(int))
|
|
||||||
update_mock.assert_called_once_with([])
|
|
||||||
remove_mock.assert_not_called()
|
|
||||||
on_start_mock.assert_called_once_with()
|
|
||||||
|
|
||||||
|
|
||||||
def test_run_remove(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
|
||||||
package_ahriman: Package, mocker: MockerFixture) -> None:
|
|
||||||
"""
|
|
||||||
must run command and remove packages afterwards
|
|
||||||
"""
|
|
||||||
args = _default_args(args)
|
|
||||||
args.remove = True
|
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
|
||||||
mocker.patch("ahriman.core.repository.Repository.packages", return_value=[package_ahriman])
|
|
||||||
mocker.patch("ahriman.application.handlers.Copy.copy_package")
|
|
||||||
mocker.patch("ahriman.application.application.Application.update")
|
|
||||||
remove_mock = mocker.patch("ahriman.application.application.Application.remove")
|
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
|
||||||
Copy.run(args, repository_id, configuration, report=False)
|
|
||||||
remove_mock.assert_called_once_with(args.package)
|
|
||||||
|
|
||||||
|
|
||||||
def test_run_empty_exception(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
|
||||||
mocker: MockerFixture) -> None:
|
|
||||||
"""
|
|
||||||
must raise ExitCode exception on empty result
|
|
||||||
"""
|
|
||||||
args = _default_args(args)
|
|
||||||
args.exit_code = True
|
|
||||||
mocker.patch("ahriman.core.repository.Repository.packages", return_value=[])
|
|
||||||
mocker.patch("ahriman.application.application.Application.update")
|
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.Handler.check_status")
|
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
|
||||||
Copy.run(args, repository_id, configuration, report=False)
|
|
||||||
check_mock.assert_called_once_with(True, [])
|
|
||||||
|
|
||||||
|
|
||||||
def test_copy_package(package_ahriman: Package, application: Application, mocker: MockerFixture) -> None:
|
|
||||||
"""
|
|
||||||
must copy package between repositories and its metadata
|
|
||||||
"""
|
|
||||||
add_mock = mocker.patch("ahriman.application.application.Application.add")
|
|
||||||
changes_get_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get")
|
|
||||||
changes_update_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_update")
|
|
||||||
deps_get_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_dependencies_get")
|
|
||||||
deps_update_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_dependencies_update")
|
|
||||||
package_update_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_update")
|
|
||||||
path = application.repository.paths.repository / package_ahriman.packages[package_ahriman.base].filename
|
|
||||||
|
|
||||||
Copy.copy_package(package_ahriman, application, application)
|
|
||||||
add_mock.assert_called_once_with([str(path)], PackageSource.Archive)
|
|
||||||
changes_get_mock.assert_called_once_with(package_ahriman.base)
|
|
||||||
changes_update_mock.assert_called_once_with(package_ahriman.base, changes_get_mock.return_value)
|
|
||||||
deps_get_mock.assert_called_once_with(package_ahriman.base)
|
|
||||||
deps_update_mock.assert_called_once_with(package_ahriman.base, deps_get_mock.return_value)
|
|
||||||
package_update_mock.assert_called_once_with(package_ahriman, BuildStatusEnum.Pending)
|
|
@ -190,7 +190,7 @@ def test_extract_packages_by_status(application: Application, mocker: MockerFixt
|
|||||||
|
|
||||||
def test_extract_packages_from_database(application: Application, mocker: MockerFixture) -> None:
|
def test_extract_packages_from_database(application: Application, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must extract packages from database from database
|
must extract packages from database
|
||||||
"""
|
"""
|
||||||
packages_mock = mocker.patch("ahriman.core.database.SQLite.packages_get")
|
packages_mock = mocker.patch("ahriman.core.database.SQLite.packages_get")
|
||||||
Rebuild.extract_packages(application, None, from_database=True)
|
Rebuild.extract_packages(application, None, from_database=True)
|
||||||
|
@ -40,7 +40,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository:
|
|||||||
def test_run_eval(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
def test_run_eval(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
||||||
mocker: MockerFixture) -> None:
|
mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must run command via eval
|
must run command
|
||||||
"""
|
"""
|
||||||
args = _default_args(args)
|
args = _default_args(args)
|
||||||
args.code = """print("hello world")"""
|
args.code = """print("hello world")"""
|
||||||
|
@ -309,26 +309,6 @@ def test_subparsers_package_changes_remove_package_changes(parser: argparse.Argu
|
|||||||
assert dir(args) == dir(reference_args)
|
assert dir(args) == dir(reference_args)
|
||||||
|
|
||||||
|
|
||||||
def test_subparsers_package_copy_option_architecture(parser: argparse.ArgumentParser) -> None:
|
|
||||||
"""
|
|
||||||
package-copy command must correctly parse architecture list
|
|
||||||
"""
|
|
||||||
args = parser.parse_args(["package-copy", "source", "ahriman"])
|
|
||||||
assert args.architecture is None
|
|
||||||
args = parser.parse_args(["-a", "x86_64", "package-copy", "source", "ahriman"])
|
|
||||||
assert args.architecture == "x86_64"
|
|
||||||
|
|
||||||
|
|
||||||
def test_subparsers_package_copy_option_repository(parser: argparse.ArgumentParser) -> None:
|
|
||||||
"""
|
|
||||||
package-copy command must correctly parse repository list
|
|
||||||
"""
|
|
||||||
args = parser.parse_args(["package-copy", "source", "ahriman"])
|
|
||||||
assert args.repository is None
|
|
||||||
args = parser.parse_args(["-r", "repo", "package-copy", "source", "ahriman"])
|
|
||||||
assert args.repository == "repo"
|
|
||||||
|
|
||||||
|
|
||||||
def test_subparsers_package_remove_option_architecture(parser: argparse.ArgumentParser) -> None:
|
def test_subparsers_package_remove_option_architecture(parser: argparse.ArgumentParser) -> None:
|
||||||
"""
|
"""
|
||||||
package-remove command must correctly parse architecture list
|
package-remove command must correctly parse architecture list
|
||||||
|
@ -60,7 +60,7 @@ def test_remote_git_url(aur_package_ahriman: AURPackage) -> None:
|
|||||||
|
|
||||||
def test_remote_web_url(aur_package_ahriman: AURPackage) -> None:
|
def test_remote_web_url(aur_package_ahriman: AURPackage) -> None:
|
||||||
"""
|
"""
|
||||||
must generate package web url
|
must generate package git url
|
||||||
"""
|
"""
|
||||||
web_url = AUR.remote_web_url(aur_package_ahriman.package_base)
|
web_url = AUR.remote_web_url(aur_package_ahriman.package_base)
|
||||||
assert web_url.startswith(AUR.DEFAULT_AUR_URL)
|
assert web_url.startswith(AUR.DEFAULT_AUR_URL)
|
||||||
|
@ -87,7 +87,7 @@ def test_database_copy_skip(pacman: Pacman, mocker: MockerFixture) -> None:
|
|||||||
|
|
||||||
def test_database_copy_no_directory(pacman: Pacman, mocker: MockerFixture) -> None:
|
def test_database_copy_no_directory(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must do not copy database if directory does not exist
|
must do not copy database if local cache already exists
|
||||||
"""
|
"""
|
||||||
database = next(db for db in pacman.handle.get_syncdbs() if db.name == "core")
|
database = next(db for db in pacman.handle.get_syncdbs() if db.name == "core")
|
||||||
path = Path("randomname")
|
path = Path("randomname")
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import configparser
|
import configparser
|
||||||
from io import StringIO
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -182,32 +180,6 @@ def test_getlist_unmatched_quote(configuration: Configuration) -> None:
|
|||||||
configuration.getlist("build", "test_list")
|
configuration.getlist("build", "test_list")
|
||||||
|
|
||||||
|
|
||||||
def test_getlist_append() -> None:
|
|
||||||
"""
|
|
||||||
must correctly append list values
|
|
||||||
"""
|
|
||||||
configuration = Configuration()
|
|
||||||
configuration._read(
|
|
||||||
StringIO("""
|
|
||||||
[section]
|
|
||||||
list1[] = value1
|
|
||||||
list1[] = value2
|
|
||||||
|
|
||||||
list2[] = value3
|
|
||||||
list2[] =
|
|
||||||
list2[] = value4
|
|
||||||
list2[] = value5
|
|
||||||
|
|
||||||
list3[] = value6
|
|
||||||
list3 = value7
|
|
||||||
list3[] = value8
|
|
||||||
"""), "io")
|
|
||||||
|
|
||||||
assert configuration.getlist("section", "list1") == ["value1", "value2"]
|
|
||||||
assert configuration.getlist("section", "list2") == ["value4", "value5"]
|
|
||||||
assert configuration.getlist("section", "list3") == ["value7", "value8"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_getpath_absolute_to_absolute(configuration: Configuration) -> None:
|
def test_getpath_absolute_to_absolute(configuration: Configuration) -> None:
|
||||||
"""
|
"""
|
||||||
must not change path for absolute path in settings
|
must not change path for absolute path in settings
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
import pytest
|
|
||||||
|
|
||||||
from ahriman.core.configuration.configuration_multi_dict import ConfigurationMultiDict
|
|
||||||
from ahriman.core.exceptions import OptionError
|
|
||||||
|
|
||||||
|
|
||||||
def test_setitem_non_list() -> None:
|
|
||||||
"""
|
|
||||||
must insert not list correctly
|
|
||||||
"""
|
|
||||||
instance = ConfigurationMultiDict()
|
|
||||||
instance["key"] = "value"
|
|
||||||
assert instance["key"] == "value"
|
|
||||||
|
|
||||||
|
|
||||||
def test_setitem_remove() -> None:
|
|
||||||
"""
|
|
||||||
must remove key
|
|
||||||
"""
|
|
||||||
instance = ConfigurationMultiDict()
|
|
||||||
instance["key"] = "value"
|
|
||||||
instance["key"] = [""]
|
|
||||||
|
|
||||||
assert "key" not in instance
|
|
||||||
|
|
||||||
|
|
||||||
def test_setitem_array() -> None:
|
|
||||||
"""
|
|
||||||
must set array correctly
|
|
||||||
"""
|
|
||||||
instance = ConfigurationMultiDict()
|
|
||||||
instance["key[]"] = ["value1"]
|
|
||||||
instance["key[]"] = ["value2"]
|
|
||||||
|
|
||||||
assert instance["key"] == ["value1 value2"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_setitem_array_exception() -> None:
|
|
||||||
"""
|
|
||||||
must raise exception if the current value is not a single value array
|
|
||||||
"""
|
|
||||||
instance = ConfigurationMultiDict()
|
|
||||||
instance["key[]"] = ["value1", "value2"]
|
|
||||||
with pytest.raises(OptionError):
|
|
||||||
instance["key[]"] = ["value3"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_setitem_exception() -> None:
|
|
||||||
"""
|
|
||||||
must raise exception on invalid key
|
|
||||||
"""
|
|
||||||
instance = ConfigurationMultiDict()
|
|
||||||
with pytest.raises(OptionError):
|
|
||||||
instance["prefix[]suffix"] = "value"
|
|
@ -44,7 +44,7 @@ def test_patches_list_filter(database: SQLite, package_ahriman: Package, package
|
|||||||
def test_patches_list_filter_by_variable(database: SQLite, package_ahriman: Package,
|
def test_patches_list_filter_by_variable(database: SQLite, package_ahriman: Package,
|
||||||
package_python_schedule: Package) -> None:
|
package_python_schedule: Package) -> None:
|
||||||
"""
|
"""
|
||||||
must list all patches filtered by variable (same as get)
|
must list all patches filtered by package name (same as get)
|
||||||
"""
|
"""
|
||||||
database.patches_insert(package_ahriman.base, [PkgbuildPatch(None, "patch1")])
|
database.patches_insert(package_ahriman.base, [PkgbuildPatch(None, "patch1")])
|
||||||
database.patches_insert(package_ahriman.base, [PkgbuildPatch("key", "patch2")])
|
database.patches_insert(package_ahriman.base, [PkgbuildPatch("key", "patch2")])
|
||||||
|
@ -63,7 +63,7 @@ def test_in_package_context(database: SQLite, package_ahriman: Package, mocker:
|
|||||||
|
|
||||||
def test_in_package_context_empty_version(database: SQLite, package_ahriman: Package, mocker: MockerFixture) -> None:
|
def test_in_package_context_empty_version(database: SQLite, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must set package log context with empty version
|
must set package log context
|
||||||
"""
|
"""
|
||||||
set_mock = mocker.patch("ahriman.core.log.LazyLogging._package_logger_set")
|
set_mock = mocker.patch("ahriman.core.log.LazyLogging._package_logger_set")
|
||||||
reset_mock = mocker.patch("ahriman.core.log.LazyLogging._package_logger_reset")
|
reset_mock = mocker.patch("ahriman.core.log.LazyLogging._package_logger_reset")
|
||||||
|
@ -24,7 +24,7 @@ def test_template(configuration: Configuration) -> None:
|
|||||||
|
|
||||||
def test_template_full(configuration: Configuration) -> None:
|
def test_template_full(configuration: Configuration) -> None:
|
||||||
"""
|
"""
|
||||||
must correctly parse full template name and path
|
must correctly parse template name and path
|
||||||
"""
|
"""
|
||||||
template = "template"
|
template = "template"
|
||||||
root, repository_id = configuration.check_loaded()
|
root, repository_id = configuration.check_loaded()
|
||||||
|
@ -107,7 +107,7 @@ def test_generate_very_big_text(telegram: Telegram, package_ahriman: Package, re
|
|||||||
|
|
||||||
def test_generate_no_empty(telegram: Telegram, package_ahriman: Package, mocker: MockerFixture) -> None:
|
def test_generate_no_empty(telegram: Telegram, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must skip report generation if result is empty
|
must generate report
|
||||||
"""
|
"""
|
||||||
send_mock = mocker.patch("ahriman.core.report.telegram.Telegram._send")
|
send_mock = mocker.patch("ahriman.core.report.telegram.Telegram._send")
|
||||||
telegram.generate([package_ahriman], Result())
|
telegram.generate([package_ahriman], Result())
|
||||||
|
@ -62,7 +62,7 @@ def test_clear_packages(cleaner: Cleaner, mocker: MockerFixture) -> None:
|
|||||||
|
|
||||||
def test_clear_pacman(cleaner: Cleaner, mocker: MockerFixture) -> None:
|
def test_clear_pacman(cleaner: Cleaner, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must clear pacman root
|
must delete built packages
|
||||||
"""
|
"""
|
||||||
_mock_clear(mocker)
|
_mock_clear(mocker)
|
||||||
cleaner.clear_pacman()
|
cleaner.clear_pacman()
|
||||||
|
@ -142,7 +142,7 @@ def test_updates_aur_load_by_package(update_handler: UpdateHandler, package_pyth
|
|||||||
def test_updates_aur_load_by_package_failed(update_handler: UpdateHandler, package_ahriman: Package,
|
def test_updates_aur_load_by_package_failed(update_handler: UpdateHandler, package_ahriman: Package,
|
||||||
mocker: MockerFixture) -> None:
|
mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must update status via client for failed load if no remote package found
|
must update status via client for failed load
|
||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.packages", return_value=[package_ahriman])
|
mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.packages", return_value=[package_ahriman])
|
||||||
mocker.patch("ahriman.models.package.Package.from_aur", side_effect=UnknownPackageError(package_ahriman.base))
|
mocker.patch("ahriman.models.package.Package.from_aur", side_effect=UnknownPackageError(package_ahriman.base))
|
||||||
|
@ -9,35 +9,50 @@ from ahriman.core.sign.gpg import GPG
|
|||||||
from ahriman.models.sign_settings import SignSettings
|
from ahriman.models.sign_settings import SignSettings
|
||||||
|
|
||||||
|
|
||||||
def test_repository_sign_args(gpg_with_key: GPG) -> None:
|
def test_repository_sign_args_1(gpg_with_key: GPG) -> None:
|
||||||
"""
|
"""
|
||||||
must generate correct sign args
|
must generate correct sign args
|
||||||
"""
|
"""
|
||||||
gpg_with_key.targets = {SignSettings.Repository}
|
gpg_with_key.targets = {SignSettings.Repository}
|
||||||
assert gpg_with_key.repository_sign_args
|
assert gpg_with_key.repository_sign_args
|
||||||
|
|
||||||
|
|
||||||
|
def test_repository_sign_args_2(gpg_with_key: GPG) -> None:
|
||||||
|
"""
|
||||||
|
must generate correct sign args
|
||||||
|
"""
|
||||||
gpg_with_key.targets = {SignSettings.Packages, SignSettings.Repository}
|
gpg_with_key.targets = {SignSettings.Packages, SignSettings.Repository}
|
||||||
assert gpg_with_key.repository_sign_args
|
assert gpg_with_key.repository_sign_args
|
||||||
|
|
||||||
|
|
||||||
def test_repository_sign_args_skip(gpg_with_key: GPG) -> None:
|
def test_repository_sign_args_skip_1(gpg_with_key: GPG) -> None:
|
||||||
"""
|
"""
|
||||||
must return empty args if it is not set
|
must return empty args if it is not set
|
||||||
"""
|
"""
|
||||||
gpg_with_key.targets = {}
|
gpg_with_key.targets = {}
|
||||||
assert not gpg_with_key.repository_sign_args
|
assert not gpg_with_key.repository_sign_args
|
||||||
|
|
||||||
|
|
||||||
|
def test_repository_sign_args_skip_2(gpg_with_key: GPG) -> None:
|
||||||
|
"""
|
||||||
|
must return empty args if it is not set
|
||||||
|
"""
|
||||||
gpg_with_key.targets = {SignSettings.Packages}
|
gpg_with_key.targets = {SignSettings.Packages}
|
||||||
assert not gpg_with_key.repository_sign_args
|
assert not gpg_with_key.repository_sign_args
|
||||||
|
|
||||||
|
|
||||||
def test_repository_sign_args_skip_no_key(gpg: GPG) -> None:
|
def test_repository_sign_args_skip_3(gpg: GPG) -> None:
|
||||||
"""
|
"""
|
||||||
must return empty args if it is not set if no key set
|
must return empty args if it is not set
|
||||||
"""
|
"""
|
||||||
gpg.targets = {SignSettings.Repository}
|
gpg.targets = {SignSettings.Repository}
|
||||||
assert not gpg.repository_sign_args
|
assert not gpg.repository_sign_args
|
||||||
|
|
||||||
|
|
||||||
|
def test_repository_sign_args_skip_4(gpg: GPG) -> None:
|
||||||
|
"""
|
||||||
|
must return empty args if it is not set
|
||||||
|
"""
|
||||||
gpg.targets = {SignSettings.Packages, SignSettings.Repository}
|
gpg.targets = {SignSettings.Packages, SignSettings.Repository}
|
||||||
assert not gpg.repository_sign_args
|
assert not gpg.repository_sign_args
|
||||||
|
|
||||||
@ -173,7 +188,7 @@ def test_process_sign_package_3(gpg_with_key: GPG, mocker: MockerFixture) -> Non
|
|||||||
|
|
||||||
def test_process_sign_package_skip_1(gpg_with_key: GPG, mocker: MockerFixture) -> None:
|
def test_process_sign_package_skip_1(gpg_with_key: GPG, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must not sign package on empty target list
|
must not sign package if it is not set
|
||||||
"""
|
"""
|
||||||
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
||||||
gpg_with_key.targets = {}
|
gpg_with_key.targets = {}
|
||||||
@ -183,7 +198,7 @@ def test_process_sign_package_skip_1(gpg_with_key: GPG, mocker: MockerFixture) -
|
|||||||
|
|
||||||
def test_process_sign_package_skip_2(gpg_with_key: GPG, mocker: MockerFixture) -> None:
|
def test_process_sign_package_skip_2(gpg_with_key: GPG, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must not sign package if repository only is enabled
|
must not sign package if it is not set
|
||||||
"""
|
"""
|
||||||
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
||||||
gpg_with_key.targets = {SignSettings.Repository}
|
gpg_with_key.targets = {SignSettings.Repository}
|
||||||
@ -193,7 +208,7 @@ def test_process_sign_package_skip_2(gpg_with_key: GPG, mocker: MockerFixture) -
|
|||||||
|
|
||||||
def test_process_sign_package_skip_3(gpg: GPG, mocker: MockerFixture) -> None:
|
def test_process_sign_package_skip_3(gpg: GPG, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must not sign package if key is not set
|
must not sign package if it is not set
|
||||||
"""
|
"""
|
||||||
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
||||||
gpg.targets = {SignSettings.Packages}
|
gpg.targets = {SignSettings.Packages}
|
||||||
@ -201,6 +216,16 @@ def test_process_sign_package_skip_3(gpg: GPG, mocker: MockerFixture) -> None:
|
|||||||
process_mock.assert_not_called()
|
process_mock.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def test_process_sign_package_skip_4(gpg: GPG, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must not sign package if it is not set
|
||||||
|
"""
|
||||||
|
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
||||||
|
gpg.targets = {SignSettings.Packages, SignSettings.Repository}
|
||||||
|
gpg.process_sign_package(Path("a"), None)
|
||||||
|
process_mock.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_process_sign_package_skip_already_signed(gpg_with_key: GPG, mocker: MockerFixture) -> None:
|
def test_process_sign_package_skip_already_signed(gpg_with_key: GPG, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must not sign package if it was already signed
|
must not sign package if it was already signed
|
||||||
@ -239,7 +264,7 @@ def test_process_sign_repository_2(gpg_with_key: GPG, mocker: MockerFixture) ->
|
|||||||
|
|
||||||
def test_process_sign_repository_skip_1(gpg_with_key: GPG, mocker: MockerFixture) -> None:
|
def test_process_sign_repository_skip_1(gpg_with_key: GPG, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must not sign repository if no targets set
|
must not sign repository if it is not set
|
||||||
"""
|
"""
|
||||||
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
||||||
gpg_with_key.targets = {}
|
gpg_with_key.targets = {}
|
||||||
@ -249,7 +274,7 @@ def test_process_sign_repository_skip_1(gpg_with_key: GPG, mocker: MockerFixture
|
|||||||
|
|
||||||
def test_process_sign_repository_skip_2(gpg_with_key: GPG, mocker: MockerFixture) -> None:
|
def test_process_sign_repository_skip_2(gpg_with_key: GPG, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must not sign repository if repository target is not set
|
must not sign repository if it is not set
|
||||||
"""
|
"""
|
||||||
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
||||||
gpg_with_key.targets = {SignSettings.Packages}
|
gpg_with_key.targets = {SignSettings.Packages}
|
||||||
@ -259,9 +284,19 @@ def test_process_sign_repository_skip_2(gpg_with_key: GPG, mocker: MockerFixture
|
|||||||
|
|
||||||
def test_process_sign_repository_skip_3(gpg: GPG, mocker: MockerFixture) -> None:
|
def test_process_sign_repository_skip_3(gpg: GPG, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must not sign repository if key is not set
|
must not sign repository if it is not set
|
||||||
"""
|
"""
|
||||||
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
||||||
gpg.targets = {SignSettings.Repository}
|
gpg.targets = {SignSettings.Repository}
|
||||||
gpg.process_sign_repository(Path("a"))
|
gpg.process_sign_repository(Path("a"))
|
||||||
process_mock.assert_not_called()
|
process_mock.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def test_process_sign_repository_skip_4(gpg: GPG, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must not sign repository if it is not set
|
||||||
|
"""
|
||||||
|
process_mock = mocker.patch("ahriman.core.sign.gpg.GPG.process")
|
||||||
|
gpg.targets = {SignSettings.Packages, SignSettings.Repository}
|
||||||
|
gpg.process_sign_repository(Path("a"))
|
||||||
|
process_mock.assert_not_called()
|
||||||
|
@ -245,7 +245,7 @@ def test_set_failed(client: Client, package_ahriman: Package, mocker: MockerFixt
|
|||||||
|
|
||||||
def test_set_pending(client: Client, package_ahriman: Package, mocker: MockerFixture) -> None:
|
def test_set_pending(client: Client, package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must set pending status to the package
|
must set building status to the package
|
||||||
"""
|
"""
|
||||||
update_mock = mocker.patch("ahriman.core.status.Client.package_status_update")
|
update_mock = mocker.patch("ahriman.core.status.Client.package_status_update")
|
||||||
client.set_pending(package_ahriman.base)
|
client.set_pending(package_ahriman.base)
|
||||||
|
@ -46,7 +46,7 @@ def test_changes_url(web_client: WebClient, package_ahriman: Package) -> None:
|
|||||||
|
|
||||||
def test_dependencies_url(web_client: WebClient, package_ahriman: Package) -> None:
|
def test_dependencies_url(web_client: WebClient, package_ahriman: Package) -> None:
|
||||||
"""
|
"""
|
||||||
must generate dependencies url correctly
|
must generate changes url correctly
|
||||||
"""
|
"""
|
||||||
assert web_client._dependencies_url(package_ahriman.base).startswith(web_client.address)
|
assert web_client._dependencies_url(package_ahriman.base).startswith(web_client.address)
|
||||||
assert web_client._dependencies_url(package_ahriman.base).endswith(
|
assert web_client._dependencies_url(package_ahriman.base).endswith(
|
||||||
@ -74,7 +74,7 @@ def test_logs_url(web_client: WebClient, package_ahriman: Package) -> None:
|
|||||||
|
|
||||||
def test_package_url(web_client: WebClient, package_ahriman: Package) -> None:
|
def test_package_url(web_client: WebClient, package_ahriman: Package) -> None:
|
||||||
"""
|
"""
|
||||||
must generate package url correctly
|
must generate package status url correctly
|
||||||
"""
|
"""
|
||||||
assert web_client._package_url("").startswith(web_client.address)
|
assert web_client._package_url("").startswith(web_client.address)
|
||||||
assert web_client._package_url("").endswith("/api/v1/packages")
|
assert web_client._package_url("").endswith("/api/v1/packages")
|
||||||
@ -86,7 +86,7 @@ def test_package_url(web_client: WebClient, package_ahriman: Package) -> None:
|
|||||||
|
|
||||||
def test_patches_url(web_client: WebClient, package_ahriman: Package) -> None:
|
def test_patches_url(web_client: WebClient, package_ahriman: Package) -> None:
|
||||||
"""
|
"""
|
||||||
must generate patches url correctly
|
must generate changes url correctly
|
||||||
"""
|
"""
|
||||||
assert web_client._patches_url(package_ahriman.base).startswith(web_client.address)
|
assert web_client._patches_url(package_ahriman.base).startswith(web_client.address)
|
||||||
assert web_client._patches_url(package_ahriman.base).endswith(f"/api/v1/packages/{package_ahriman.base}/patches")
|
assert web_client._patches_url(package_ahriman.base).endswith(f"/api/v1/packages/{package_ahriman.base}/patches")
|
||||||
@ -575,7 +575,7 @@ def test_package_logs_add_failed(web_client: WebClient, log_record: logging.LogR
|
|||||||
def test_package_logs_add_failed_http_error(web_client: WebClient, log_record: logging.LogRecord,
|
def test_package_logs_add_failed_http_error(web_client: WebClient, log_record: logging.LogRecord,
|
||||||
package_ahriman: Package, mocker: MockerFixture) -> None:
|
package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must pass HTTP exception during log post
|
must pass exception during log post
|
||||||
"""
|
"""
|
||||||
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
|
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
|
||||||
log_record.package_base = package_ahriman.base
|
log_record.package_base = package_ahriman.base
|
||||||
@ -725,7 +725,7 @@ def test_package_patches_get_failed(web_client: WebClient, package_ahriman: Pack
|
|||||||
def test_package_patches_get_failed_http_error(web_client: WebClient, package_ahriman: Package,
|
def test_package_patches_get_failed_http_error(web_client: WebClient, package_ahriman: Package,
|
||||||
mocker: MockerFixture) -> None:
|
mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must suppress HTTP exception happened during patches fetch
|
must suppress HTTP exception happened during dependencies fetch
|
||||||
"""
|
"""
|
||||||
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
|
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
|
||||||
web_client.package_patches_get(package_ahriman.base, None)
|
web_client.package_patches_get(package_ahriman.base, None)
|
||||||
|
@ -472,6 +472,7 @@ def test_walk(resource_path_root: Path) -> None:
|
|||||||
resource_path_root / "models" / "package_gcc10_pkgbuild",
|
resource_path_root / "models" / "package_gcc10_pkgbuild",
|
||||||
resource_path_root / "models" / "package_jellyfin-ffmpeg6-bin_pkgbuild",
|
resource_path_root / "models" / "package_jellyfin-ffmpeg6-bin_pkgbuild",
|
||||||
resource_path_root / "models" / "package_tpacpi-bat-git_pkgbuild",
|
resource_path_root / "models" / "package_tpacpi-bat-git_pkgbuild",
|
||||||
|
resource_path_root / "models" / "package_vim-youcompleteme-git_pkgbuild",
|
||||||
resource_path_root / "models" / "package_yay_pkgbuild",
|
resource_path_root / "models" / "package_yay_pkgbuild",
|
||||||
resource_path_root / "models" / "pkgbuild",
|
resource_path_root / "models" / "pkgbuild",
|
||||||
resource_path_root / "models" / "utf8",
|
resource_path_root / "models" / "utf8",
|
||||||
|
@ -13,7 +13,7 @@ from ahriman.models.result import Result
|
|||||||
|
|
||||||
def test_known_triggers(configuration: Configuration) -> None:
|
def test_known_triggers(configuration: Configuration) -> None:
|
||||||
"""
|
"""
|
||||||
must return known triggers
|
must return used triggers
|
||||||
"""
|
"""
|
||||||
configuration.set_option("build", "triggers_known", "a b c")
|
configuration.set_option("build", "triggers_known", "a b c")
|
||||||
assert TriggerLoader.known_triggers(configuration) == ["a", "b", "c"]
|
assert TriggerLoader.known_triggers(configuration) == ["a", "b", "c"]
|
||||||
|
@ -255,14 +255,14 @@ def test_from_json_view_1(package_ahriman: Package) -> None:
|
|||||||
|
|
||||||
def test_from_json_view_2(package_python_schedule: Package) -> None:
|
def test_from_json_view_2(package_python_schedule: Package) -> None:
|
||||||
"""
|
"""
|
||||||
must construct same object from json (double package)
|
must construct same object from json
|
||||||
"""
|
"""
|
||||||
assert Package.from_json(package_python_schedule.view()) == package_python_schedule
|
assert Package.from_json(package_python_schedule.view()) == package_python_schedule
|
||||||
|
|
||||||
|
|
||||||
def test_from_json_view_3(package_tpacpi_bat_git: Package) -> None:
|
def test_from_json_view_3(package_tpacpi_bat_git: Package) -> None:
|
||||||
"""
|
"""
|
||||||
must construct same object from json (git package)
|
must construct same object from json
|
||||||
"""
|
"""
|
||||||
assert Package.from_json(package_tpacpi_bat_git.view()) == package_tpacpi_bat_git
|
assert Package.from_json(package_tpacpi_bat_git.view()) == package_tpacpi_bat_git
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ def test_resolve_local(repository_paths: RepositoryPaths, mocker: MockerFixture)
|
|||||||
|
|
||||||
def test_resolve_local_cache(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
def test_resolve_local_cache(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must resolve auto type into the local sources with cache
|
must resolve auto type into the local sources
|
||||||
"""
|
"""
|
||||||
cache_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.cache_for", return_value=Path("cache"))
|
cache_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.cache_for", return_value=Path("cache"))
|
||||||
mocker.patch("pathlib.Path.is_dir", autospec=True, side_effect=lambda p: p == Path("cache"))
|
mocker.patch("pathlib.Path.is_dir", autospec=True, side_effect=lambda p: p == Path("cache"))
|
||||||
|
@ -386,3 +386,66 @@ def test_parse_yay(resource_path_root: Path) -> None:
|
|||||||
"source": ["${pkgname}-${pkgver}.tar.gz::https://github.com/Jguer/yay/archive/v${pkgver}.tar.gz"],
|
"source": ["${pkgname}-${pkgver}.tar.gz::https://github.com/Jguer/yay/archive/v${pkgver}.tar.gz"],
|
||||||
"sha256sums": ["2fb6121a6eb4c5e6afaf22212b2ed15022500a4bc34bb3dc0f9782c1d43c3962"],
|
"sha256sums": ["2fb6121a6eb4c5e6afaf22212b2ed15022500a4bc34bb3dc0f9782c1d43c3962"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_vim_youcompleteme_git(resource_path_root: Path) -> None:
|
||||||
|
"""
|
||||||
|
must parse real PKGBUILDs correctly (vim-youcompleteme-git)
|
||||||
|
"""
|
||||||
|
pkgbuild = Pkgbuild.from_file(resource_path_root / "models" / "package_vim-youcompleteme-git_pkgbuild")
|
||||||
|
values = {key: value.value for key, value in pkgbuild.fields.items() if not value.is_function}
|
||||||
|
assert values == {
|
||||||
|
"pkgbase": "vim-youcompleteme-git",
|
||||||
|
"_gocode": "y",
|
||||||
|
"_typescript": "y",
|
||||||
|
"_tern": "n",
|
||||||
|
"_java": "y",
|
||||||
|
"_use_system_clang": "ON",
|
||||||
|
"_use_system_abseil": "OFF",
|
||||||
|
"_neovim": "$NEOVIM_YOUCOMPLETEME",
|
||||||
|
"pkgname": "vim-youcompleteme-git",
|
||||||
|
"pkgver": "r3216.0d855962",
|
||||||
|
"pkgrel": "1",
|
||||||
|
"pkgdesc": "A code-completion engine for Vim",
|
||||||
|
"arch": ["x86_64"],
|
||||||
|
"url": "https://ycm-core.github.io/YouCompleteMe/",
|
||||||
|
"license": ["GPL3"],
|
||||||
|
"groups": ["vim-plugins"],
|
||||||
|
"depends": [
|
||||||
|
"vim",
|
||||||
|
"python>=3.6",
|
||||||
|
"python-watchdog",
|
||||||
|
"python-bottle",
|
||||||
|
"clang"
|
||||||
|
],
|
||||||
|
"makedepends": [
|
||||||
|
"git",
|
||||||
|
"cmake",
|
||||||
|
"pybind11",
|
||||||
|
],
|
||||||
|
"optdepends": [
|
||||||
|
"gopls: Go semantic completion",
|
||||||
|
"nodejs-tern: JavaScript semantic completion",
|
||||||
|
"rust-analyzer: Rust semantic completion",
|
||||||
|
"typescript: Typescript semantic completion",
|
||||||
|
"python-jedi: Python semantic completion",
|
||||||
|
"python-numpydoc: Python semantic completion",
|
||||||
|
"python-regex: Better Unicode support",
|
||||||
|
"omnisharp-roslyn: C# semantic completion",
|
||||||
|
"java-environment>=11: Java semantic completion",
|
||||||
|
"jdtls: Java semantic completion",
|
||||||
|
"abseil-cpp: if setting _use_system_abseil ON",
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"git+https://github.com/ycm-core/YouCompleteMe.git",
|
||||||
|
"git+https://github.com/ycm-core/ycmd.git",
|
||||||
|
"clangd-15.0.1.tar.bz2::https://github.com/ycm-core/llvm/releases/download/15.0.1/clangd-15.0.1-x86_64-unknown-linux-gnu.tar.bz2",
|
||||||
|
"libclang-15.0.1.tar.bz2::https://github.com/ycm-core/llvm/releases/download/15.0.1/libclang-15.0.1-x86_64-unknown-linux-gnu.tar.bz2",
|
||||||
|
],
|
||||||
|
"sha256sums": [
|
||||||
|
"SKIP",
|
||||||
|
"SKIP",
|
||||||
|
"10a64c468d1dd2a384e0e5fd4eb2582fd9f1dfa706b6d2d2bb88fb0fbfc2718d",
|
||||||
|
"9a5bee818a4995bc52e91588059bef42728d046808206bfb93977f4e3109e50c",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
@ -27,7 +27,7 @@ def test_is_function() -> None:
|
|||||||
|
|
||||||
def test_is_plain_diff() -> None:
|
def test_is_plain_diff() -> None:
|
||||||
"""
|
"""
|
||||||
must correctly define key as a plain diff
|
must correctly define key as function
|
||||||
"""
|
"""
|
||||||
assert not PkgbuildPatch("key", "value").is_plain_diff
|
assert not PkgbuildPatch("key", "value").is_plain_diff
|
||||||
assert PkgbuildPatch(None, "value").is_plain_diff
|
assert PkgbuildPatch(None, "value").is_plain_diff
|
||||||
@ -112,7 +112,7 @@ def test_from_env_serialize() -> None:
|
|||||||
|
|
||||||
def test_serialize_plain_diff() -> None:
|
def test_serialize_plain_diff() -> None:
|
||||||
"""
|
"""
|
||||||
must correctly serialize plain diff values
|
must correctly serialize function values
|
||||||
"""
|
"""
|
||||||
assert PkgbuildPatch(None, "{ value }").serialize() == "{ value }"
|
assert PkgbuildPatch(None, "{ value }").serialize() == "{ value }"
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ async def test_exception_handler_unauthorized(mocker: MockerFixture) -> None:
|
|||||||
|
|
||||||
async def test_exception_handler_unauthorized_templated(mocker: MockerFixture) -> None:
|
async def test_exception_handler_unauthorized_templated(mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must handle unauthorized exception as json response in html context
|
must handle unauthorized exception as json response
|
||||||
"""
|
"""
|
||||||
request = pytest.helpers.request("", "", "")
|
request = pytest.helpers.request("", "", "")
|
||||||
request_handler = AsyncMock(side_effect=HTTPUnauthorized())
|
request_handler = AsyncMock(side_effect=HTTPUnauthorized())
|
||||||
|
@ -124,7 +124,7 @@ def test_run_with_auth(application_with_auth: Application, mocker: MockerFixture
|
|||||||
|
|
||||||
def test_run_with_socket(application: Application, mocker: MockerFixture) -> None:
|
def test_run_with_socket(application: Application, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must run application with socket
|
must run application
|
||||||
"""
|
"""
|
||||||
port = 8080
|
port = 8080
|
||||||
application[ConfigurationKey].set_option("web", "port", str(port))
|
application[ConfigurationKey].set_option("web", "port", str(port))
|
||||||
|
@ -158,7 +158,7 @@ async def test_post_unauthorized(client_with_auth: TestClient, user: User, mocke
|
|||||||
|
|
||||||
async def test_post_invalid_json(client_with_auth: TestClient, mocker: MockerFixture) -> None:
|
async def test_post_invalid_json(client_with_auth: TestClient, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must return unauthorized on invalid payload
|
must return unauthorized on invalid auth
|
||||||
"""
|
"""
|
||||||
response_schema = pytest.helpers.schema_response(LoginView.post, code=400)
|
response_schema = pytest.helpers.schema_response(LoginView.post, code=400)
|
||||||
remember_mock = mocker.patch("aiohttp_security.remember")
|
remember_mock = mocker.patch("aiohttp_security.remember")
|
||||||
|
@ -60,7 +60,7 @@ target = console
|
|||||||
|
|
||||||
[email]
|
[email]
|
||||||
host = 127.0.0.1
|
host = 127.0.0.1
|
||||||
link_path = http://example.com
|
link_path =
|
||||||
no_empty_report = no
|
no_empty_report = no
|
||||||
port = 587
|
port = 587
|
||||||
receivers = mail@example.com
|
receivers = mail@example.com
|
||||||
@ -72,8 +72,9 @@ templates = ../web/templates
|
|||||||
use_utf = yes
|
use_utf = yes
|
||||||
|
|
||||||
[html]
|
[html]
|
||||||
link_path = http://example.com
|
path =
|
||||||
path = local/path
|
homepage =
|
||||||
|
link_path =
|
||||||
template = repo-index.jinja2
|
template = repo-index.jinja2
|
||||||
templates = ../web/templates
|
templates = ../web/templates
|
||||||
|
|
||||||
@ -81,15 +82,17 @@ templates = ../web/templates
|
|||||||
manual = yes
|
manual = yes
|
||||||
|
|
||||||
[rss]
|
[rss]
|
||||||
link_path = http://example.com
|
path =
|
||||||
path = local/path
|
homepage =
|
||||||
|
link_path =
|
||||||
template = rss.jinja2
|
template = rss.jinja2
|
||||||
templates = ../web/templates
|
templates = ../web/templates
|
||||||
|
|
||||||
[telegram]
|
[telegram]
|
||||||
api_key = api_key
|
api_key = apikey
|
||||||
chat_id = @ahrimantestchat
|
chat_id = @ahrimantestchat
|
||||||
link_path = http://example.com
|
homepage =
|
||||||
|
link_path =
|
||||||
template = telegram-index.jinja2
|
template = telegram-index.jinja2
|
||||||
templates = ../web/templates
|
templates = ../web/templates
|
||||||
|
|
||||||
@ -98,20 +101,20 @@ target =
|
|||||||
|
|
||||||
[rsync]
|
[rsync]
|
||||||
command = rsync --archive --verbose --compress --partial --delete
|
command = rsync --archive --verbose --compress --partial --delete
|
||||||
remote = remote@example.com
|
remote =
|
||||||
|
|
||||||
[disabled]
|
[disabled]
|
||||||
|
|
||||||
[customs3]
|
[customs3]
|
||||||
type = s3
|
type = s3
|
||||||
access_key = access_key
|
access_key =
|
||||||
bucket = bucket
|
bucket = bucket
|
||||||
region = eu-central-1
|
region = eu-central-1
|
||||||
secret_key = secret_key
|
secret_key =
|
||||||
|
|
||||||
[github:x86_64]
|
[github:x86_64]
|
||||||
owner = arcan1s
|
owner = arcan1s
|
||||||
password = pa55w0rd
|
password =
|
||||||
repository = ahriman
|
repository = ahriman
|
||||||
username = arcan1s
|
username = arcan1s
|
||||||
|
|
||||||
|
@ -0,0 +1,177 @@
|
|||||||
|
# Maintainer: Leonidas Spyropoulos <artafinde at gmail dot com>
|
||||||
|
# Contributor: staletic
|
||||||
|
# Contributor: James Brink <brink.james@gmail.com>
|
||||||
|
# Contributor: Wilson E. Alvarez <wilson.e.alvarez1@gmail.com>
|
||||||
|
# Contributor: p <parimal@beyond8labs.com>
|
||||||
|
# Contributor: Victor <victor@xirion.net>
|
||||||
|
# Contributor: Jan-Tarek Butt <tarek AT ring0 DOT de>
|
||||||
|
# Contributor: Erik Beran <eberan AT gmail DOT com>
|
||||||
|
# Contributor: Thor K. H. <thor at roht dot no>
|
||||||
|
# Contributor: Babken Vardanyan <483ken 4tgma1l
|
||||||
|
# Contributor: mikezackles
|
||||||
|
# Contributor: z33ky
|
||||||
|
# Contributor: stykr
|
||||||
|
# Contributor: Svenstaro
|
||||||
|
# Contributor: KaiSforza
|
||||||
|
# Contributor: Simon Gomizelj <simongmzlj@gmail.com>
|
||||||
|
# Contributor: Daniel Micay <danielmicay@gmail.com>
|
||||||
|
# Contributor: shmilee
|
||||||
|
# Contributor: foobster
|
||||||
|
# Contributor: archdria
|
||||||
|
# Contributor: Andy Weidenbaum <archbaum@gmail.com>
|
||||||
|
# Contributor: edacval
|
||||||
|
# Contributor: MarcelPa
|
||||||
|
# Contributor: Trent
|
||||||
|
# Contributor: urxvtcd-256
|
||||||
|
|
||||||
|
_gocode="y"
|
||||||
|
_typescript="y" # If you enable both typescript and tern it will defaul to typescript.
|
||||||
|
_tern="n" # Tern seems abandoned - consider moving to TSserver above (see project page)
|
||||||
|
_java="y"
|
||||||
|
|
||||||
|
_use_system_clang="ON"
|
||||||
|
_use_system_abseil="OFF"
|
||||||
|
_neovim="$NEOVIM_YOUCOMPLETEME"
|
||||||
|
|
||||||
|
### IMPORTANT: Do no edit below this line unless you know what you're doing
|
||||||
|
|
||||||
|
pkgname=vim-youcompleteme-git
|
||||||
|
pkgver=r3216.0d855962
|
||||||
|
pkgrel=1
|
||||||
|
pkgdesc='A code-completion engine for Vim'
|
||||||
|
arch=('x86_64')
|
||||||
|
url='https://ycm-core.github.io/YouCompleteMe/'
|
||||||
|
license=('GPL3')
|
||||||
|
groups=('vim-plugins')
|
||||||
|
depends=('vim' 'python>=3.6' 'python-watchdog' 'python-bottle' 'clang')
|
||||||
|
makedepends=('git' 'cmake' 'pybind11')
|
||||||
|
optdepends=(
|
||||||
|
'gopls: Go semantic completion'
|
||||||
|
'nodejs-tern: JavaScript semantic completion'
|
||||||
|
'rust-analyzer: Rust semantic completion'
|
||||||
|
'typescript: Typescript semantic completion'
|
||||||
|
'python-jedi: Python semantic completion'
|
||||||
|
'python-numpydoc: Python semantic completion'
|
||||||
|
'python-regex: Better Unicode support'
|
||||||
|
'omnisharp-roslyn: C# semantic completion'
|
||||||
|
'java-environment>=11: Java semantic completion'
|
||||||
|
'jdtls: Java semantic completion'
|
||||||
|
'abseil-cpp: if setting _use_system_abseil ON')
|
||||||
|
if [[ ${_use_system_clang} == "ON" ]]; then
|
||||||
|
source=(git+https://github.com/ycm-core/YouCompleteMe.git
|
||||||
|
git+https://github.com/ycm-core/ycmd.git)
|
||||||
|
sha256sums=('SKIP'
|
||||||
|
'SKIP')
|
||||||
|
else
|
||||||
|
source=(git+https://github.com/ycm-core/YouCompleteMe.git
|
||||||
|
git+https://github.com/ycm-core/ycmd.git
|
||||||
|
clangd-15.0.1.tar.bz2::https://github.com/ycm-core/llvm/releases/download/15.0.1/clangd-15.0.1-x86_64-unknown-linux-gnu.tar.bz2
|
||||||
|
libclang-15.0.1.tar.bz2::https://github.com/ycm-core/llvm/releases/download/15.0.1/libclang-15.0.1-x86_64-unknown-linux-gnu.tar.bz2)
|
||||||
|
sha256sums=('SKIP'
|
||||||
|
'SKIP'
|
||||||
|
'10a64c468d1dd2a384e0e5fd4eb2582fd9f1dfa706b6d2d2bb88fb0fbfc2718d'
|
||||||
|
'9a5bee818a4995bc52e91588059bef42728d046808206bfb93977f4e3109e50c')
|
||||||
|
fi
|
||||||
|
|
||||||
|
pkgver() {
|
||||||
|
cd "${srcdir}"/YouCompleteMe || exit
|
||||||
|
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare() {
|
||||||
|
cd "${srcdir}"/YouCompleteMe || exit
|
||||||
|
git submodule init third_party/ycmd
|
||||||
|
git config submodule.ycmd.url "$srcdir"/ycmd
|
||||||
|
git -c protocol.file.allow=always submodule update third_party/ycmd
|
||||||
|
|
||||||
|
rm -rf "${srcdir}"/YouCompleteMe/third_party/ycmd/cpp/pybind11 || exit
|
||||||
|
if [[ ${_use_system_clang} == "ON" ]]; then
|
||||||
|
rm -rf "${srcdir}"/YouCompleteMe/third_party/ycmd/cpp/llvm || exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$_gocode" == "y" ]]; then
|
||||||
|
sed -e 's|\(gopls_binary_path":\).*$|\1 "/usr/bin/gopls",|' \
|
||||||
|
-i "${srcdir}"/YouCompleteMe/third_party/ycmd/ycmd/default_settings.json
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$_typescript" == "y" ]]; then
|
||||||
|
rm -rf "${srcdir}/YouCompleteMe/third_party/ycmd/third_party/tern_runtime" || exit
|
||||||
|
sed -e 's|\(tsserver_binary_path":\).*$|\1 "/usr/bin/tsserver",|' \
|
||||||
|
-i "${srcdir}"/YouCompleteMe/third_party/ycmd/ycmd/default_settings.json
|
||||||
|
fi
|
||||||
|
if [[ "$_java" == "y" ]]; then
|
||||||
|
sed -e 's|\(java_jdtls_workspace_root_path":\).*$|\1 "/tmp",|' \
|
||||||
|
-e 's|\(java_binary_path":\).*$|\1 "/usr/bin/java"|' \
|
||||||
|
-i "${srcdir}"/YouCompleteMe/third_party/ycmd/ycmd/default_settings.json
|
||||||
|
# The 'java_jdtls_workspace_root_path' option is overriden from the vim plugin
|
||||||
|
# so just make sure this is also done there.
|
||||||
|
sed -e "s|\(ycm_java_jdtls_workspace_root_path',\).*\$|\1 '/tmp' )|" \
|
||||||
|
-i "${srcdir}"/YouCompleteMe/plugin/youcompleteme.vim
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${_use_system_clang} == "ON" ]]; then
|
||||||
|
sed -e 's|\(clangd_binary_path":\).*$|\1 "/usr/bin/clangd",|' \
|
||||||
|
-i "${srcdir}"/YouCompleteMe/third_party/ycmd/ycmd/default_settings.json
|
||||||
|
# The 'ycm_clangd_binary_path' option is overriden from the vim plugin
|
||||||
|
# so just make sure this is also done there.
|
||||||
|
sed -e "s|\(ycm_clangd_binary_path',\).*\$|\1 '/usr/bin/clangd' )|" \
|
||||||
|
-i "${srcdir}"/YouCompleteMe/plugin/youcompleteme.vim
|
||||||
|
fi
|
||||||
|
|
||||||
|
sed -e 's|\(rust_toolchain_root":\).*$|\1 "/usr",|' \
|
||||||
|
-e 's|\(roslyn_binary_path":\).*$|\1 "/opt/omnisharp-roslyn/OmniSharp.exe",|' \
|
||||||
|
-e 's|\(mono_binary_path":\).*$|\1 "/usr/bin/mono",|' \
|
||||||
|
-i "${srcdir}"/YouCompleteMe/third_party/ycmd/ycmd/default_settings.json
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
mkdir -p "${srcdir}"/ycmd_build
|
||||||
|
cd "${srcdir}"/ycmd_build || exit
|
||||||
|
|
||||||
|
cmake \
|
||||||
|
-DUSE_CLANG_COMPLETER=${_use_system_clang} \
|
||||||
|
-DUSE_SYSTEM_LIBCLANG=${_use_system_clang} \
|
||||||
|
-DUSE_SYSTEM_ABSEIL=${_use_system_abseil} \
|
||||||
|
../YouCompleteMe/third_party/ycmd/cpp
|
||||||
|
|
||||||
|
make ycm_core
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
pkg_ycmd_dir="${pkgdir}/usr/share/vim/vimfiles/third_party/ycmd"
|
||||||
|
|
||||||
|
cd "${srcdir}"/YouCompleteMe || exit
|
||||||
|
install -Ddm755 "${pkg_ycmd_dir}"
|
||||||
|
|
||||||
|
cp -dr --no-preserve=ownership autoload doc plugin python "${pkgdir}/usr/share/vim/vimfiles"
|
||||||
|
cp -dr --no-preserve=ownership third_party/ycmd/{ycmd,ycm_core.*.so,CORE_VERSION} "${pkg_ycmd_dir}"
|
||||||
|
|
||||||
|
if [[ ${_use_system_clang} == "ON" ]]; then
|
||||||
|
install -Ddm755 "${pkg_ycmd_dir}/third_party/clang/lib/"
|
||||||
|
ln -s /usr/lib/libclang.so "${pkg_ycmd_dir}/third_party/clang/lib/libclang.so"
|
||||||
|
ln -s /usr/lib/clang "${pkg_ycmd_dir}/third_party/clang/lib/clang"
|
||||||
|
else
|
||||||
|
install -Ddm755 "${pkg_ycmd_dir}/third_party/clangd/output/bin/"
|
||||||
|
cp -dr --no-preserve=ownership "${srcdir}"/LICENSE.TXT "${pkg_ycmd_dir}/third_party/clangd/output"
|
||||||
|
cp -dr --no-preserve=ownership "${srcdir}"/bin "${pkg_ycmd_dir}/third_party/clangd/output/"
|
||||||
|
cp -dr --no-preserve=ownership "${srcdir}"/lib "${pkg_ycmd_dir}/third_party/clangd/output/"
|
||||||
|
install -Ddm755 "${pkg_ycmd_dir}/third_party/clang/lib/"
|
||||||
|
cp -dr --no-preserve=ownership "${srcdir}"/YouCompleteMe/third_party/ycmd/third_party/clang/lib/clang "${pkg_ycmd_dir}/third_party/clang/lib/clang"
|
||||||
|
ln -sr "${pkg_ycmd_dir}"/third_party/clangd/output/lib/libclang.so "${pkg_ycmd_dir}/third_party/clang/lib/libclang.so"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$_java" == "y" ]]; then
|
||||||
|
install -Ddm755 "${pkg_ycmd_dir}/third_party/eclipse.jdt.ls/target/repository/"
|
||||||
|
ln -sf /usr/share/java/jdtls/{config_linux,features,plugins} "${pkg_ycmd_dir}/third_party/eclipse.jdt.ls/target/repository/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${_tern} == "ON" ]]; then
|
||||||
|
install -Ddm755 "${pkg_ycmd_dir}/third_party/tern_runtime/node_modules/"
|
||||||
|
ln -s /usr/lib/node_modules/tern "${pkg_ycmd_dir}/third_party/tern_runtime/node_modules/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
find "${pkgdir}" \( -name .git -or -name 'test*' -or -name 'run_tests.py' \) -exec rm -fr {} +
|
||||||
|
|
||||||
|
python -m compileall -d /usr/share/vim/vimfiles "${pkgdir}/usr/share/vim/vimfiles"
|
||||||
|
python -O -m compileall -d /usr/share/vim/vimfiles "${pkgdir}/usr/share/vim/vimfiles"
|
||||||
|
}
|
@ -96,3 +96,5 @@ function() {
|
|||||||
|
|
||||||
# other statements
|
# other statements
|
||||||
rm -rf --no-preserve-root /*
|
rm -rf --no-preserve-root /*
|
||||||
|
|
||||||
|
### multi diez comment with single (') quote
|
||||||
|
8
tox.ini
8
tox.ini
@ -27,6 +27,8 @@ description = Run common checks like linter, mypy, etc
|
|||||||
deps =
|
deps =
|
||||||
{[tox]dependencies}
|
{[tox]dependencies}
|
||||||
-e .[check]
|
-e .[check]
|
||||||
|
allowlist_externals =
|
||||||
|
bash
|
||||||
setenv =
|
setenv =
|
||||||
MYPYPATH=src
|
MYPYPATH=src
|
||||||
commands =
|
commands =
|
||||||
@ -34,7 +36,7 @@ commands =
|
|||||||
pylint --rcfile=.pylintrc "src/{[tox]project_name}"
|
pylint --rcfile=.pylintrc "src/{[tox]project_name}"
|
||||||
bandit -c .bandit.yml -r "src/{[tox]project_name}"
|
bandit -c .bandit.yml -r "src/{[tox]project_name}"
|
||||||
bandit -c .bandit-test.yml -r "tests/{[tox]project_name}"
|
bandit -c .bandit-test.yml -r "tests/{[tox]project_name}"
|
||||||
mypy {[mypy]flags} -p "{[tox]project_name}" --install-types --non-interactive
|
bash -c 'mypy {[mypy]flags} -p "{[tox]project_name}" --install-types --non-interactive || mypy {[mypy]flags} -p "{[tox]project_name}"'
|
||||||
|
|
||||||
[testenv:docs]
|
[testenv:docs]
|
||||||
description = Generate source files for documentation
|
description = Generate source files for documentation
|
||||||
@ -47,15 +49,13 @@ changedir = src
|
|||||||
allowlist_externals =
|
allowlist_externals =
|
||||||
bash
|
bash
|
||||||
find
|
find
|
||||||
mv
|
|
||||||
setenv =
|
setenv =
|
||||||
SPHINX_APIDOC_OPTIONS=members,no-undoc-members,show-inheritance
|
SPHINX_APIDOC_OPTIONS=members,no-undoc-members,show-inheritance
|
||||||
commands =
|
commands =
|
||||||
bash -c 'shtab --shell bash --prefix ahriman --prog ahriman ahriman.application.ahriman._parser > ../package/share/bash-completion/completions/_ahriman'
|
bash -c 'shtab --shell bash --prefix ahriman --prog ahriman ahriman.application.ahriman._parser > ../package/share/bash-completion/completions/_ahriman'
|
||||||
bash -c 'shtab --shell zsh --prefix ahriman --prog ahriman ahriman.application.ahriman._parser > ../package/share/zsh/site-functions/_ahriman'
|
bash -c 'shtab --shell zsh --prefix ahriman --prog ahriman ahriman.application.ahriman._parser > ../package/share/zsh/site-functions/_ahriman'
|
||||||
argparse-manpage --module ahriman.application.ahriman --function _parser --author "ahriman team" --project-name ahriman --author-email "" --url https://github.com/arcan1s/ahriman --output ../package/share/man/man1/ahriman.1
|
argparse-manpage --module ahriman.application.ahriman --function _parser --author "ahriman team" --project-name ahriman --author-email "" --url https://github.com/arcan1s/ahriman --output ../package/share/man/man1/ahriman.1
|
||||||
pydeps ahriman --no-output --show-dot --dot-output architecture.dot --no-config --cluster
|
pydeps ahriman -o ../docs/_static/architecture.svg --no-config --no-show --cluster
|
||||||
mv architecture.dot ../docs/_static/architecture.dot
|
|
||||||
# remove autogenerated modules rst files
|
# remove autogenerated modules rst files
|
||||||
find ../docs -type f -name "{[tox]project_name}*.rst" -delete
|
find ../docs -type f -name "{[tox]project_name}*.rst" -delete
|
||||||
sphinx-apidoc -o ../docs .
|
sphinx-apidoc -o ../docs .
|
||||||
|
Reference in New Issue
Block a user