migrate to tox

this also requires to move default configuration files to share/ahriman.
Thus the following features have been added
* default configuration is not stored in /usr/share/ahriman/settings
* package installed via PKGBUILD now copies files from /usr
* configuration class now fallbacks to default in /usr
This commit is contained in:
Evgenii Alekseev 2022-03-21 02:58:45 +03:00
parent 13121298f5
commit fb02e676af
27 changed files with 115 additions and 83 deletions

View File

@ -11,12 +11,14 @@ jobs:
runs-on: ubuntu-latest
container:
image: archlinux:latest
volumes:
- ${{ github.workspace }}:/build
options: --privileged -w /build
steps:
- uses: actions/checkout@v2
- name: setup the service in arch linux container
run: |
docker run --privileged \
-v ${{ github.workspace }}:/build -w /build \
archlinux:latest \
.github/workflows/setup.sh
run: .github/workflows/setup.sh

View File

@ -11,12 +11,14 @@ jobs:
runs-on: ubuntu-latest
container:
image: archlinux:latest
volumes:
- ${{ github.workspace }}:/build
options: -w /build
steps:
- uses: actions/checkout@v2
- name: run check and tests in arch linux container
run: |
docker run \
-v ${{ github.workspace }}:/build -w /build \
archlinux:latest \
.github/workflows/tests.sh
run: .github/workflows/tests.sh

View File

@ -10,7 +10,7 @@ pacman --noconfirm -Syu
# main dependencies
pacman --noconfirm -Sy base-devel devtools git pyalpm python-aur python-passlib python-srcinfo sudo
# make dependencies
pacman --noconfirm -Sy python-pip
pacman --noconfirm -Sy python-build python-installer python-wheel
# optional dependencies
# VCS support
pacman --noconfirm -Sy breezy darcs mercurial subversion

View File

@ -4,13 +4,7 @@
set -ex
# install dependencies
pacman --noconfirm -Syu base-devel python-pip
# install python packages
pip install -e .[web]
pip install -e .[check]
pip install -e .[s3]
pip install -e .[test]
pacman --noconfirm -Syu base-devel python-pip python-tox
# run test and check targets
make check tests

1
.gitignore vendored
View File

@ -94,3 +94,4 @@ ENV/
.venv/
*.tar.xz
status_cache.json

View File

@ -25,7 +25,7 @@ RUN YAY_DIR="$(runuser -u build -- mktemp -d)" && \
cd - && rm -r "$YAY_DIR"
## install package dependencies
RUN runuser -u build -- yay --noconfirm -Sy devtools git pyalpm python-inflection python-passlib python-requests python-srcinfo && \
runuser -u build -- yay --noconfirm -Sy python-pip && \
runuser -u build -- yay --noconfirm -Sy python-build python-installer python-wheel && \
runuser -u build -- yay --noconfirm -Sy breezy darcs mercurial python-aioauth-client python-aiohttp \
python-aiohttp-debugtoolbar python-aiohttp-jinja2 python-aiohttp-security \
python-aiohttp-session python-boto3 python-cryptography python-jinja \

View File

@ -3,7 +3,7 @@
PROJECT := ahriman
FILES := AUTHORS COPYING README.md docs package src setup.cfg setup.py web.png
FILES := AUTHORS COPYING README.md docs package src setup.py tox.ini web.png
TARGET_FILES := $(addprefix $(PROJECT)/, $(FILES))
IGNORE_FILES := package/archlinux src/.mypy_cache
@ -26,11 +26,8 @@ archive_directory: $(TARGET_FILES)
archlinux: archive
sed -i "s/pkgver=[0-9.]*/pkgver=$(VERSION)/" package/archlinux/PKGBUILD
check: clean mypy
autopep8 --exit-code --max-line-length 120 -aa -i -j 0 -r "src/$(PROJECT)" "tests/$(PROJECT)"
pylint --rcfile=.pylintrc "src/$(PROJECT)"
bandit -c .bandit.yml -r "src/$(PROJECT)"
bandit -c .bandit-test.yml -r "tests/$(PROJECT)"
check: clean
tox -e check
clean:
find . -type f -name "$(PROJECT)-*-src.tar.xz" -delete
@ -42,10 +39,6 @@ directory: clean
man:
cd src && PYTHONPATH=. argparse-manpage --module ahriman.application.ahriman --function _parser --author "ahriman team" --project-name ahriman --author-email "" --url https://github.com/arcan1s/ahriman --output ../docs/ahriman.1
mypy:
cd src && mypy --implicit-reexport --strict -p "$(PROJECT)" --install-types --non-interactive || true
cd src && mypy --implicit-reexport --strict -p "$(PROJECT)"
push: architecture man archlinux
git add package/archlinux/PKGBUILD src/ahriman/version.py docs/ahriman-architecture.svg docs/ahriman.1
git commit -m "Release $(VERSION)"
@ -54,7 +47,7 @@ push: architecture man archlinux
git push --tags
tests: clean
python setup.py test
tox -e tests
version:
ifndef VERSION

View File

@ -2,6 +2,7 @@
[![tests status](https://github.com/arcan1s/ahriman/actions/workflows/run-tests.yml/badge.svg)](https://github.com/arcan1s/ahriman/actions/workflows/run-tests.yml)
[![setup status](https://github.com/arcan1s/ahriman/actions/workflows/run-setup.yml/badge.svg)](https://github.com/arcan1s/ahriman/actions/workflows/run-setup.yml)
[![docker image](https://github.com/arcan1s/ahriman/actions/workflows/docker-image.yml/badge.svg)](https://github.com/arcan1s/ahriman/actions/workflows/docker-image.yml)
[![CodeFactor](https://www.codefactor.io/repository/github/arcan1s/ahriman/badge)](https://www.codefactor.io/repository/github/arcan1s/ahriman)
Wrapper for managing custom repository inspired by [repo-scripts](https://github.com/arcan1s/repo-scripts).

View File

@ -8,7 +8,7 @@ arch=('any')
url="https://github.com/arcan1s/ahriman"
license=('GPL3')
depends=('devtools' 'git' 'pyalpm' 'python-inflection' 'python-passlib' 'python-requests' 'python-srcinfo')
makedepends=('python-pip')
makedepends=('python-build' 'python-installer' 'python-wheel')
optdepends=('breezy: -bzr packages support'
'darcs: -darcs packages support'
'mercurial: -hg packages support'
@ -32,18 +32,23 @@ backup=('etc/ahriman.ini'
build() {
cd "$pkgname"
python setup.py build
python -m build --wheel --no-isolation
}
package() {
cd "$pkgname"
python setup.py install --root="$pkgdir"
python -m installer --destdir="$pkgdir" dist/*.whl
# python-installer actually thinks that you cannot just copy files to root
# thus we need to copy them manually
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 "$srcdir/$pkgname.sysusers" "$pkgdir/usr/lib/sysusers.d/$pkgname.conf"
install -Dm644 "$srcdir/$pkgname.tmpfiles" "$pkgdir/usr/lib/tmpfiles.d/$pkgname.conf"
}
sha512sums=('6ab741bfb42f92ab00d1b6ecfc44426c00e5c433486e014efbdb585715d9a12dbbafc280e5a9f85b941c8681b13a9dad41327a3e3c44a9683ae30c1d6f017f50'
'13718afec2c6786a18f0b223ef8e58dccf0688bca4cdbe203f14071f5031ed20120eb0ce38b52c76cfd6e8b6581a9c9eaa2743eb11abbaca637451a84c33f075'
'55b20f6da3d66e7bbf2add5d95a3b60632df121717d25a993e56e737d14f51fe063eb6f1b38bd81cc32e05db01c0c1d80aaa720c45cde87f238d8b46cdb8cbc4')
sha512sums=('112b0d8aac68e5330bbdd2b86a59c8a9af8ab7a7c636489623c8460bb90f1318585851edd2a97a8ce20e2d2ad93b847b522685df707c190aa39d23ab908fa8ef'
'53d37efec812afebf86281716259f9ea78a307b83897166c72777251c3eebcb587ecee375d907514781fb2a5c808cbb24ef9f3f244f12740155d0603bf213131'
'62b2eccc352d33853ef243c9cddd63663014aa97b87242f1b5bc5099a7dbd69ff3821f24ffc58e1b7f2387bd4e9e9712cc4c67f661b1724ad99cdf09b3717794')

View File

@ -1,6 +1,6 @@
[settings]
include = /etc/ahriman.ini.d
logging = /etc/ahriman.ini.d/logging.ini
include = ahriman.ini.d
logging = ahriman.ini.d/logging.ini
[alpm]
aur_url = https://aur.archlinux.org
@ -36,13 +36,13 @@ target = console
use_utf = yes
[email]
full_template_path = /usr/share/ahriman/repo-index.jinja2
full_template_path = /usr/share/ahriman/templates/repo-index.jinja2
no_empty_report = yes
template_path = /usr/share/ahriman/email-index.jinja2
template_path = /usr/share/ahriman/templates/email-index.jinja2
ssl = disabled
[html]
template_path = /usr/share/ahriman/repo-index.jinja2
template_path = /usr/share/ahriman/templates/repo-index.jinja2
[upload]
target =
@ -58,5 +58,5 @@ debug = no
debug_check_host = no
debug_allowed_hosts =
host = 127.0.0.1
static_path = /usr/share/ahriman/static
templates = /usr/share/ahriman
static_path = /usr/share/ahriman/templates/static
templates = /usr/share/ahriman/templates

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -1,7 +0,0 @@
[aliases]
test = pytest
[tool:pytest]
addopts = --cov=ahriman --cov-report term-missing:skip-covered --spec
asyncio_mode = legacy
spec_test_format = {result} {docstring_summary}

View File

@ -36,7 +36,6 @@ setup(
"srcinfo",
],
setup_requires=[
"pytest-runner",
],
tests_require=[
"pytest",
@ -53,33 +52,33 @@ setup(
"package/bin/ahriman",
],
data_files=[
("/etc", [
"package/etc/ahriman.ini",
("share/ahriman/settings", [
"package/share/ahriman/settings/ahriman.ini",
]),
("/etc/ahriman.ini.d", [
"package/etc/ahriman.ini.d/logging.ini",
("share/ahriman/settings/ahriman.ini.d", [
"package/share/ahriman/settings/ahriman.ini.d/logging.ini",
]),
("lib/systemd/system", [
"package/lib/systemd/system/ahriman@.service",
"package/lib/systemd/system/ahriman@.timer",
"package/lib/systemd/system/ahriman-web@.service",
]),
("share/ahriman", [
"package/share/ahriman/build-status.jinja2",
"package/share/ahriman/email-index.jinja2",
"package/share/ahriman/repo-index.jinja2",
("share/ahriman/templates", [
"package/share/ahriman/templates/build-status.jinja2",
"package/share/ahriman/templates/email-index.jinja2",
"package/share/ahriman/templates/repo-index.jinja2",
]),
("share/ahriman/build-status", [
"package/share/ahriman/build-status/login-modal.jinja2",
"package/share/ahriman/build-status/package-actions-modals.jinja2",
"package/share/ahriman/build-status/package-actions-script.jinja2",
("share/ahriman/templates/build-status", [
"package/share/ahriman/templates/build-status/login-modal.jinja2",
"package/share/ahriman/templates/build-status/package-actions-modals.jinja2",
"package/share/ahriman/templates/build-status/package-actions-script.jinja2",
]),
("share/ahriman/static", [
"package/share/ahriman/static/favicon.ico",
("share/ahriman/templates/static", [
"package/share/ahriman/templates/static/favicon.ico",
]),
("share/ahriman/utils", [
"package/share/ahriman/utils/bootstrap-scripts.jinja2",
"package/share/ahriman/utils/style.jinja2",
("share/ahriman/templates/utils", [
"package/share/ahriman/templates/utils/bootstrap-scripts.jinja2",
"package/share/ahriman/templates/utils/style.jinja2",
]),
("share/man/man1", [
"docs/ahriman.1",
@ -96,7 +95,7 @@ setup(
"s3": [
"boto3",
],
"test": [
"tests": [
"pytest",
"pytest-aiohttp",
"pytest-cov",

View File

@ -21,6 +21,7 @@ from __future__ import annotations
import configparser
import logging
import sys
from logging.config import fileConfig
from pathlib import Path
@ -37,12 +38,14 @@ class Configuration(configparser.RawConfigParser):
:cvar ARCHITECTURE_SPECIFIC_SECTIONS: known sections which can be architecture specific (required by dump)
:cvar DEFAULT_LOG_FORMAT: default log format (in case of fallback)
:cvar DEFAULT_LOG_LEVEL: default log level (in case of fallback)
:cvar SYSTEM_CONFIGURATION_PATH: default system configuration path distributed by package
"""
DEFAULT_LOG_FORMAT = "[%(levelname)s %(asctime)s] [%(filename)s:%(lineno)d %(funcName)s]: %(message)s"
DEFAULT_LOG_LEVEL = logging.DEBUG
ARCHITECTURE_SPECIFIC_SECTIONS = ["build", "sign", "web"]
SYSTEM_CONFIGURATION_PATH = Path(sys.prefix) / "share" / "ahriman" / "settings" / "ahriman.ini"
def __init__(self) -> None:
"""
@ -172,6 +175,8 @@ class Configuration(configparser.RawConfigParser):
fully load configuration
:param path: path to root configuration file
"""
if not path.is_file(): # fallback to the system file
path = self.SYSTEM_CONFIGURATION_PATH
self.path = path
self.read(self.path)
self.load_includes()

View File

@ -131,7 +131,7 @@ def test_configuration_create_with_plain_password(
assert generated.check_credentials(service.password, configuration.get("auth", "salt"))
def test_configuration_get_exists(mocker: MockerFixture) -> None:
def test_configuration_get(mocker: MockerFixture) -> None:
"""
must load configuration from filesystem
"""
@ -143,18 +143,6 @@ def test_configuration_get_exists(mocker: MockerFixture) -> None:
read_mock.assert_called_once_with(Path("path") / "auth.ini")
def test_configuration_get_not_exists(mocker: MockerFixture) -> None:
"""
must try to load configuration from filesystem
"""
mocker.patch("pathlib.Path.open")
mocker.patch("pathlib.Path.is_file", return_value=False)
read_mock = mocker.patch("ahriman.core.configuration.Configuration.read")
assert User.configuration_get(Path("path"))
read_mock.assert_called_once_with(Path("path") / "auth.ini")
def test_configuration_write(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must write configuration

View File

@ -14,6 +14,7 @@ def test_from_path(mocker: MockerFixture) -> None:
"""
must load configuration
"""
mocker.patch("pathlib.Path.is_file", return_value=True)
read_mock = mocker.patch("ahriman.core.configuration.Configuration.read")
load_includes_mock = mocker.patch("ahriman.core.configuration.Configuration.load_includes")
load_logging_mock = mocker.patch("ahriman.core.configuration.Configuration.load_logging")
@ -26,6 +27,19 @@ def test_from_path(mocker: MockerFixture) -> None:
load_logging_mock.assert_called_once_with(True)
def test_from_path_file_missing(mocker: MockerFixture) -> None:
"""
must load configuration based on package files
"""
mocker.patch("pathlib.Path.is_file", return_value=False)
mocker.patch("ahriman.core.configuration.Configuration.load_includes")
mocker.patch("ahriman.core.configuration.Configuration.load_logging")
read_mock = mocker.patch("ahriman.core.configuration.Configuration.read")
configuration = Configuration.from_path(Path("path"), "x86_64", True)
read_mock.assert_called_once_with(configuration.SYSTEM_CONFIGURATION_PATH)
def test_dump(configuration: Configuration) -> None:
"""
dump must not be empty

View File

@ -1 +1 @@
../../../package/share/ahriman
../../../package/share/ahriman/templates

35
tox.ini Normal file
View File

@ -0,0 +1,35 @@
[tox]
envlist = check, tests
dependencies = -e .[s3,web]
project_name = ahriman
[pytest]
addopts = --cov=ahriman --cov-report=term-missing:skip-covered --spec
asyncio_mode = legacy
spec_test_format = {result} {docstring_summary}
[testenv]
deps =
-e .[s3,web]
[testenv:check]
deps =
{[tox]dependencies}
-e .[check]
allowlist_externals =
/bin/bash
setenv =
MYPYPATH=src
commands =
autopep8 --exit-code --max-line-length 120 -aa -i -j 0 -r "src/{[tox]project_name}" "tests/{[tox]project_name}"
pylint --rcfile=.pylintrc "src/{[tox]project_name}"
bandit -c .bandit.yml -r "src/{[tox]project_name}"
bandit -c .bandit-test.yml -r "tests/{[tox]project_name}"
/bin/bash -c 'mypy --implicit-reexport --strict -p "{[tox]project_name}" --install-types --non-interactive || mypy --implicit-reexport --strict -p "{[tox]project_name}"'
[testenv:tests]
deps =
{[tox]dependencies}
-e .[tests]
commands =
pytest