From d90f417cae475b577f777a31a33aa7f202d860e4 Mon Sep 17 00:00:00 2001 From: Evgenii Alekseev Date: Sun, 17 Apr 2022 20:25:28 +0300 Subject: [PATCH] Docstring update (#58) * migrate docstrings from reST to google format * add raises note Also change behaviour of the `from_option` method to fallback to disabled instead of raising exception on unknown option * fix part of warnings for sphinx * make identation a bit more readable * review fixes * add verbose description for properties to make them parsed by sphinx extenstion * add demo sphinx generator --- Makefile | 12 +- .../ahriman.application.application.rst | 50 ++++ docs/source/ahriman.application.handlers.rst | 221 ++++++++++++++++ docs/source/ahriman.application.rst | 41 +++ docs/source/ahriman.core.alpm.remote.rst | 41 +++ docs/source/ahriman.core.alpm.rst | 40 +++ docs/source/ahriman.core.auth.rst | 50 ++++ docs/source/ahriman.core.build_tools.rst | 32 +++ docs/source/ahriman.core.database.data.rst | 41 +++ .../ahriman.core.database.migrations.rst | 23 ++ .../ahriman.core.database.operations.rst | 59 +++++ docs/source/ahriman.core.database.rst | 33 +++ docs/source/ahriman.core.formatters.rst | 95 +++++++ docs/source/ahriman.core.report.rst | 68 +++++ docs/source/ahriman.core.repository.rst | 59 +++++ docs/source/ahriman.core.rst | 76 ++++++ docs/source/ahriman.core.sign.rst | 23 ++ docs/source/ahriman.core.status.rst | 41 +++ docs/source/ahriman.core.upload.rst | 59 +++++ docs/source/ahriman.models.rst | 203 +++++++++++++++ docs/source/ahriman.rst | 34 +++ docs/source/ahriman.web.middlewares.rst | 32 +++ docs/source/ahriman.web.rst | 41 +++ docs/source/ahriman.web.views.rst | 42 +++ docs/source/ahriman.web.views.service.rst | 50 ++++ docs/source/ahriman.web.views.status.rst | 50 ++++ docs/source/ahriman.web.views.user.rst | 32 +++ docs/source/conf.py | 73 ++++++ docs/source/index.rst | 20 ++ docs/source/modules.rst | 7 + src/ahriman/application/ahriman.py | 244 +++++++++++++----- .../application/application/application.py | 8 +- .../application/application/packages.py | 62 +++-- .../application/application/properties.py | 22 +- .../application/application/repository.py | 62 +++-- src/ahriman/application/handlers/add.py | 12 +- src/ahriman/application/handlers/backup.py | 20 +- src/ahriman/application/handlers/clean.py | 12 +- src/ahriman/application/handlers/dump.py | 12 +- src/ahriman/application/handlers/handler.py | 62 +++-- src/ahriman/application/handlers/help.py | 12 +- .../application/handlers/key_import.py | 12 +- src/ahriman/application/handlers/patch.py | 34 ++- src/ahriman/application/handlers/rebuild.py | 20 +- src/ahriman/application/handlers/remove.py | 12 +- .../application/handlers/remove_unknown.py | 12 +- src/ahriman/application/handlers/report.py | 12 +- src/ahriman/application/handlers/restore.py | 12 +- src/ahriman/application/handlers/search.py | 29 ++- src/ahriman/application/handlers/setup.py | 74 ++++-- src/ahriman/application/handlers/sign.py | 12 +- src/ahriman/application/handlers/status.py | 12 +- .../application/handlers/status_update.py | 12 +- src/ahriman/application/handlers/sync.py | 14 +- .../application/handlers/unsafe_commands.py | 32 ++- src/ahriman/application/handlers/update.py | 22 +- src/ahriman/application/handlers/user.py | 56 ++-- src/ahriman/application/handlers/web.py | 12 +- src/ahriman/application/lock.py | 45 ++-- src/ahriman/core/alpm/pacman.py | 12 +- src/ahriman/core/alpm/remote/aur.py | 55 ++-- src/ahriman/core/alpm/remote/official.py | 47 +++- src/ahriman/core/alpm/remote/remote.py | 50 +++- src/ahriman/core/alpm/repo.py | 35 ++- src/ahriman/core/auth/auth.py | 59 +++-- src/ahriman/core/auth/helpers.py | 32 ++- src/ahriman/core/auth/mapping.py | 52 ++-- src/ahriman/core/auth/oauth.py | 52 ++-- src/ahriman/core/build_tools/sources.py | 60 +++-- src/ahriman/core/build_tools/task.py | 34 ++- src/ahriman/core/configuration.py | 117 ++++++--- src/ahriman/core/database/data/__init__.py | 10 +- .../core/database/data/package_statuses.py | 6 +- src/ahriman/core/database/data/patches.py | 6 +- src/ahriman/core/database/data/users.py | 6 +- .../core/database/migrations/__init__.py | 28 +- .../database/operations/auth_operations.py | 26 +- .../database/operations/build_operations.py | 12 +- .../core/database/operations/operations.py | 30 ++- .../database/operations/package_operations.py | 74 ++++-- .../database/operations/patch_operations.py | 26 +- src/ahriman/core/database/sqlite.py | 20 +- src/ahriman/core/exceptions.py | 48 +++- src/ahriman/core/formatters/aur_printer.py | 12 +- src/ahriman/core/formatters/build_printer.py | 18 +- .../core/formatters/configuration_printer.py | 14 +- .../core/formatters/package_printer.py | 16 +- src/ahriman/core/formatters/printer.py | 17 +- src/ahriman/core/formatters/status_printer.py | 4 +- src/ahriman/core/formatters/string_printer.py | 8 +- src/ahriman/core/formatters/update_printer.py | 16 +- src/ahriman/core/formatters/user_printer.py | 12 +- src/ahriman/core/report/console.py | 18 +- src/ahriman/core/report/email.py | 42 +-- src/ahriman/core/report/html.py | 20 +- src/ahriman/core/report/jinja_template.py | 61 +++-- src/ahriman/core/report/report.py | 41 ++- src/ahriman/core/report/telegram.py | 32 ++- src/ahriman/core/repository/cleaner.py | 7 +- src/ahriman/core/repository/executor.py | 56 +++- src/ahriman/core/repository/properties.py | 38 +-- src/ahriman/core/repository/repository.py | 24 +- src/ahriman/core/repository/update_handler.py | 25 +- src/ahriman/core/sign/gpg.py | 95 ++++--- src/ahriman/core/spawn.py | 50 ++-- src/ahriman/core/status/client.py | 64 +++-- src/ahriman/core/status/watcher.py | 56 ++-- src/ahriman/core/status/web_client.py | 79 ++++-- src/ahriman/core/tree.py | 57 ++-- src/ahriman/core/upload/github.py | 83 +++--- src/ahriman/core/upload/http_upload.py | 48 +++- src/ahriman/core/upload/rsync.py | 20 +- src/ahriman/core/upload/s3.py | 67 +++-- src/ahriman/core/upload/upload.py | 41 ++- src/ahriman/core/util.py | 101 ++++++-- src/ahriman/models/action.py | 8 +- src/ahriman/models/aur_package.py | 66 +++-- src/ahriman/models/auth_settings.py | 27 +- src/ahriman/models/build_status.py | 42 ++- src/ahriman/models/counters.py | 30 ++- src/ahriman/models/internal_status.py | 22 +- src/ahriman/models/migration.py | 8 +- src/ahriman/models/migration_result.py | 14 +- src/ahriman/models/package.py | 167 ++++++++---- src/ahriman/models/package_description.py | 51 ++-- src/ahriman/models/package_source.py | 24 +- src/ahriman/models/property.py | 8 +- src/ahriman/models/report_settings.py | 24 +- src/ahriman/models/repository_paths.py | 70 +++-- src/ahriman/models/result.py | 48 +++- src/ahriman/models/sign_settings.py | 20 +- src/ahriman/models/smtp_ssl_settings.py | 16 +- src/ahriman/models/upload_settings.py | 22 +- src/ahriman/models/user.py | 58 +++-- src/ahriman/models/user_access.py | 9 +- src/ahriman/models/user_identity.py | 40 ++- src/ahriman/web/middlewares/auth_handler.py | 42 ++- .../web/middlewares/exception_handler.py | 12 +- src/ahriman/web/routes.py | 41 +-- src/ahriman/web/views/base.py | 51 +++- src/ahriman/web/views/index.py | 58 +++-- src/ahriman/web/views/service/add.py | 19 +- src/ahriman/web/views/service/remove.py | 19 +- src/ahriman/web/views/service/request.py | 19 +- src/ahriman/web/views/service/search.py | 12 +- src/ahriman/web/views/status/ahriman.py | 25 +- src/ahriman/web/views/status/package.py | 40 ++- src/ahriman/web/views/status/packages.py | 18 +- src/ahriman/web/views/status/status.py | 10 +- src/ahriman/web/views/user/login.py | 30 ++- src/ahriman/web/views/user/logout.py | 12 +- src/ahriman/web/web.py | 27 +- .../application/application/conftest.py | 36 ++- tests/ahriman/application/conftest.py | 30 ++- .../application/handlers/test_handler_add.py | 8 +- .../handlers/test_handler_backup.py | 8 +- .../handlers/test_handler_clean.py | 8 +- .../application/handlers/test_handler_help.py | 8 +- .../handlers/test_handler_key_import.py | 8 +- .../handlers/test_handler_patch.py | 8 +- .../handlers/test_handler_rebuild.py | 8 +- .../handlers/test_handler_remove.py | 8 +- .../handlers/test_handler_remove_unknown.py | 8 +- .../handlers/test_handler_report.py | 8 +- .../handlers/test_handler_restore.py | 8 +- .../handlers/test_handler_search.py | 8 +- .../handlers/test_handler_setup.py | 8 +- .../application/handlers/test_handler_sign.py | 8 +- .../handlers/test_handler_status.py | 8 +- .../handlers/test_handler_status_update.py | 8 +- .../application/handlers/test_handler_sync.py | 8 +- .../handlers/test_handler_unsafe_commands.py | 20 +- .../handlers/test_handler_update.py | 8 +- .../application/handlers/test_handler_user.py | 8 +- .../application/handlers/test_handler_web.py | 8 +- tests/ahriman/conftest.py | 139 +++++++--- tests/ahriman/core/alpm/remote/conftest.py | 12 +- tests/ahriman/core/alpm/remote/test_aur.py | 8 +- .../ahriman/core/alpm/remote/test_official.py | 8 +- tests/ahriman/core/auth/conftest.py | 20 +- tests/ahriman/core/conftest.py | 47 +++- tests/ahriman/core/database/conftest.py | 4 +- .../core/database/migrations/conftest.py | 8 +- tests/ahriman/core/formatters/conftest.py | 43 ++- tests/ahriman/core/repository/conftest.py | 58 +++-- tests/ahriman/core/repository/test_cleaner.py | 4 +- tests/ahriman/core/sign/conftest.py | 16 +- tests/ahriman/core/sign/test_gpg.py | 13 + tests/ahriman/core/status/conftest.py | 13 +- tests/ahriman/core/upload/conftest.py | 32 ++- tests/ahriman/models/conftest.py | 48 +++- tests/ahriman/models/test_aur_package.py | 16 +- tests/ahriman/models/test_auth_settings.py | 8 +- tests/ahriman/models/test_package_source.py | 10 +- tests/ahriman/models/test_report_settings.py | 8 +- tests/ahriman/models/test_repository_paths.py | 10 +- tests/ahriman/models/test_sign_settings.py | 8 +- tests/ahriman/models/test_upload_settings.py | 8 +- tests/ahriman/web/conftest.py | 62 +++-- tests/ahriman/web/middlewares/conftest.py | 9 +- .../web/middlewares/test_auth_handler.py | 8 +- .../web/middlewares/test_exception_handler.py | 8 +- tests/ahriman/web/views/conftest.py | 50 ++-- 203 files changed, 5246 insertions(+), 1636 deletions(-) create mode 100644 docs/source/ahriman.application.application.rst create mode 100644 docs/source/ahriman.application.handlers.rst create mode 100644 docs/source/ahriman.application.rst create mode 100644 docs/source/ahriman.core.alpm.remote.rst create mode 100644 docs/source/ahriman.core.alpm.rst create mode 100644 docs/source/ahriman.core.auth.rst create mode 100644 docs/source/ahriman.core.build_tools.rst create mode 100644 docs/source/ahriman.core.database.data.rst create mode 100644 docs/source/ahriman.core.database.migrations.rst create mode 100644 docs/source/ahriman.core.database.operations.rst create mode 100644 docs/source/ahriman.core.database.rst create mode 100644 docs/source/ahriman.core.formatters.rst create mode 100644 docs/source/ahriman.core.report.rst create mode 100644 docs/source/ahriman.core.repository.rst create mode 100644 docs/source/ahriman.core.rst create mode 100644 docs/source/ahriman.core.sign.rst create mode 100644 docs/source/ahriman.core.status.rst create mode 100644 docs/source/ahriman.core.upload.rst create mode 100644 docs/source/ahriman.models.rst create mode 100644 docs/source/ahriman.rst create mode 100644 docs/source/ahriman.web.middlewares.rst create mode 100644 docs/source/ahriman.web.rst create mode 100644 docs/source/ahriman.web.views.rst create mode 100644 docs/source/ahriman.web.views.service.rst create mode 100644 docs/source/ahriman.web.views.status.rst create mode 100644 docs/source/ahriman.web.views.user.rst create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst create mode 100644 docs/source/modules.rst diff --git a/Makefile b/Makefile index c1f5a79b..cab5da77 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: architecture archive archive_directory archlinux check clean directory man push tests version +.PHONY: architecture archive archive_directory archlinux check clean directory docs docs-source man push tests version .DEFAULT_GOAL := archlinux PROJECT := ahriman @@ -32,14 +32,22 @@ check: clean clean: find . -type f -name "$(PROJECT)-*-src.tar.xz" -delete rm -rf "$(PROJECT)" + find docs/source -type f -name "$(PROJECT)*.rst" -delete + rm -rf docs/html docs/source/modules.rst directory: clean mkdir "$(PROJECT)" +docs: docs-source + sphinx-build -b html -a -j auto docs/source docs/html + +docs-source: clean + SPHINX_APIDOC_OPTIONS=members,no-undoc-members,show-inheritance sphinx-apidoc --force --private -o docs/source src + 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 -push: architecture man archlinux +push: architecture docs-source man archlinux git add package/archlinux/PKGBUILD src/ahriman/version.py docs/ahriman-architecture.svg docs/ahriman.1 git commit -m "Release $(VERSION)" git tag "$(VERSION)" diff --git a/docs/source/ahriman.application.application.rst b/docs/source/ahriman.application.application.rst new file mode 100644 index 00000000..6a50bdac --- /dev/null +++ b/docs/source/ahriman.application.application.rst @@ -0,0 +1,50 @@ +ahriman.application.application package +======================================= + +Submodules +---------- + +ahriman.application.application.application module +-------------------------------------------------- + +.. automodule:: ahriman.application.application.application + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.application.packages module +----------------------------------------------- + +.. automodule:: ahriman.application.application.packages + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.application.properties module +------------------------------------------------- + +.. automodule:: ahriman.application.application.properties + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.application.repository module +------------------------------------------------- + +.. automodule:: ahriman.application.application.repository + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.application.application + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.application.handlers.rst b/docs/source/ahriman.application.handlers.rst new file mode 100644 index 00000000..fc35624d --- /dev/null +++ b/docs/source/ahriman.application.handlers.rst @@ -0,0 +1,221 @@ +ahriman.application.handlers package +==================================== + +Submodules +---------- + +ahriman.application.handlers.add module +--------------------------------------- + +.. automodule:: ahriman.application.handlers.add + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.backup module +------------------------------------------ + +.. automodule:: ahriman.application.handlers.backup + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.clean module +----------------------------------------- + +.. automodule:: ahriman.application.handlers.clean + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.dump module +---------------------------------------- + +.. automodule:: ahriman.application.handlers.dump + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.handler module +------------------------------------------- + +.. automodule:: ahriman.application.handlers.handler + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.help module +---------------------------------------- + +.. automodule:: ahriman.application.handlers.help + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.key\_import module +----------------------------------------------- + +.. automodule:: ahriman.application.handlers.key_import + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.patch module +----------------------------------------- + +.. automodule:: ahriman.application.handlers.patch + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.rebuild module +------------------------------------------- + +.. automodule:: ahriman.application.handlers.rebuild + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.remove module +------------------------------------------ + +.. automodule:: ahriman.application.handlers.remove + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.remove\_unknown module +--------------------------------------------------- + +.. automodule:: ahriman.application.handlers.remove_unknown + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.report module +------------------------------------------ + +.. automodule:: ahriman.application.handlers.report + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.restore module +------------------------------------------- + +.. automodule:: ahriman.application.handlers.restore + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.search module +------------------------------------------ + +.. automodule:: ahriman.application.handlers.search + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.setup module +----------------------------------------- + +.. automodule:: ahriman.application.handlers.setup + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.sign module +---------------------------------------- + +.. automodule:: ahriman.application.handlers.sign + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.status module +------------------------------------------ + +.. automodule:: ahriman.application.handlers.status + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.status\_update module +-------------------------------------------------- + +.. automodule:: ahriman.application.handlers.status_update + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.sync module +---------------------------------------- + +.. automodule:: ahriman.application.handlers.sync + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.unsafe\_commands module +---------------------------------------------------- + +.. automodule:: ahriman.application.handlers.unsafe_commands + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.update module +------------------------------------------ + +.. automodule:: ahriman.application.handlers.update + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.user module +---------------------------------------- + +.. automodule:: ahriman.application.handlers.user + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.handlers.web module +--------------------------------------- + +.. automodule:: ahriman.application.handlers.web + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.application.handlers + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.application.rst b/docs/source/ahriman.application.rst new file mode 100644 index 00000000..32f5ec43 --- /dev/null +++ b/docs/source/ahriman.application.rst @@ -0,0 +1,41 @@ +ahriman.application package +=========================== + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + ahriman.application.application + ahriman.application.handlers + +Submodules +---------- + +ahriman.application.ahriman module +---------------------------------- + +.. automodule:: ahriman.application.ahriman + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.application.lock module +------------------------------- + +.. automodule:: ahriman.application.lock + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.application + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.alpm.remote.rst b/docs/source/ahriman.core.alpm.remote.rst new file mode 100644 index 00000000..c8b94741 --- /dev/null +++ b/docs/source/ahriman.core.alpm.remote.rst @@ -0,0 +1,41 @@ +ahriman.core.alpm.remote package +================================ + +Submodules +---------- + +ahriman.core.alpm.remote.aur module +----------------------------------- + +.. automodule:: ahriman.core.alpm.remote.aur + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.alpm.remote.official module +---------------------------------------- + +.. automodule:: ahriman.core.alpm.remote.official + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.alpm.remote.remote module +-------------------------------------- + +.. automodule:: ahriman.core.alpm.remote.remote + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.alpm.remote + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.alpm.rst b/docs/source/ahriman.core.alpm.rst new file mode 100644 index 00000000..06c1537e --- /dev/null +++ b/docs/source/ahriman.core.alpm.rst @@ -0,0 +1,40 @@ +ahriman.core.alpm package +========================= + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + ahriman.core.alpm.remote + +Submodules +---------- + +ahriman.core.alpm.pacman module +------------------------------- + +.. automodule:: ahriman.core.alpm.pacman + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.alpm.repo module +----------------------------- + +.. automodule:: ahriman.core.alpm.repo + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.alpm + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.auth.rst b/docs/source/ahriman.core.auth.rst new file mode 100644 index 00000000..ca006ea3 --- /dev/null +++ b/docs/source/ahriman.core.auth.rst @@ -0,0 +1,50 @@ +ahriman.core.auth package +========================= + +Submodules +---------- + +ahriman.core.auth.auth module +----------------------------- + +.. automodule:: ahriman.core.auth.auth + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.auth.helpers module +-------------------------------- + +.. automodule:: ahriman.core.auth.helpers + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.auth.mapping module +-------------------------------- + +.. automodule:: ahriman.core.auth.mapping + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.auth.oauth module +------------------------------ + +.. automodule:: ahriman.core.auth.oauth + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.auth + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.build_tools.rst b/docs/source/ahriman.core.build_tools.rst new file mode 100644 index 00000000..41506c7d --- /dev/null +++ b/docs/source/ahriman.core.build_tools.rst @@ -0,0 +1,32 @@ +ahriman.core.build\_tools package +================================= + +Submodules +---------- + +ahriman.core.build\_tools.sources module +---------------------------------------- + +.. automodule:: ahriman.core.build_tools.sources + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.build\_tools.task module +------------------------------------- + +.. automodule:: ahriman.core.build_tools.task + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.build_tools + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.database.data.rst b/docs/source/ahriman.core.database.data.rst new file mode 100644 index 00000000..2b3bea60 --- /dev/null +++ b/docs/source/ahriman.core.database.data.rst @@ -0,0 +1,41 @@ +ahriman.core.database.data package +================================== + +Submodules +---------- + +ahriman.core.database.data.package\_statuses module +--------------------------------------------------- + +.. automodule:: ahriman.core.database.data.package_statuses + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.database.data.patches module +----------------------------------------- + +.. automodule:: ahriman.core.database.data.patches + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.database.data.users module +--------------------------------------- + +.. automodule:: ahriman.core.database.data.users + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.database.data + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.database.migrations.rst b/docs/source/ahriman.core.database.migrations.rst new file mode 100644 index 00000000..f0144d5f --- /dev/null +++ b/docs/source/ahriman.core.database.migrations.rst @@ -0,0 +1,23 @@ +ahriman.core.database.migrations package +======================================== + +Submodules +---------- + +ahriman.core.database.migrations.m000\_initial module +----------------------------------------------------- + +.. automodule:: ahriman.core.database.migrations.m000_initial + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.database.migrations + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.database.operations.rst b/docs/source/ahriman.core.database.operations.rst new file mode 100644 index 00000000..e595e6b4 --- /dev/null +++ b/docs/source/ahriman.core.database.operations.rst @@ -0,0 +1,59 @@ +ahriman.core.database.operations package +======================================== + +Submodules +---------- + +ahriman.core.database.operations.auth\_operations module +-------------------------------------------------------- + +.. automodule:: ahriman.core.database.operations.auth_operations + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.database.operations.build\_operations module +--------------------------------------------------------- + +.. automodule:: ahriman.core.database.operations.build_operations + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.database.operations.operations module +-------------------------------------------------- + +.. automodule:: ahriman.core.database.operations.operations + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.database.operations.package\_operations module +----------------------------------------------------------- + +.. automodule:: ahriman.core.database.operations.package_operations + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.database.operations.patch\_operations module +--------------------------------------------------------- + +.. automodule:: ahriman.core.database.operations.patch_operations + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.database.operations + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.database.rst b/docs/source/ahriman.core.database.rst new file mode 100644 index 00000000..b6726207 --- /dev/null +++ b/docs/source/ahriman.core.database.rst @@ -0,0 +1,33 @@ +ahriman.core.database package +============================= + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + ahriman.core.database.data + ahriman.core.database.migrations + ahriman.core.database.operations + +Submodules +---------- + +ahriman.core.database.sqlite module +----------------------------------- + +.. automodule:: ahriman.core.database.sqlite + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.database + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.formatters.rst b/docs/source/ahriman.core.formatters.rst new file mode 100644 index 00000000..eddd4249 --- /dev/null +++ b/docs/source/ahriman.core.formatters.rst @@ -0,0 +1,95 @@ +ahriman.core.formatters package +=============================== + +Submodules +---------- + +ahriman.core.formatters.aur\_printer module +------------------------------------------- + +.. automodule:: ahriman.core.formatters.aur_printer + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.formatters.build\_printer module +--------------------------------------------- + +.. automodule:: ahriman.core.formatters.build_printer + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.formatters.configuration\_printer module +----------------------------------------------------- + +.. automodule:: ahriman.core.formatters.configuration_printer + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.formatters.package\_printer module +----------------------------------------------- + +.. automodule:: ahriman.core.formatters.package_printer + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.formatters.printer module +-------------------------------------- + +.. automodule:: ahriman.core.formatters.printer + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.formatters.status\_printer module +---------------------------------------------- + +.. automodule:: ahriman.core.formatters.status_printer + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.formatters.string\_printer module +---------------------------------------------- + +.. automodule:: ahriman.core.formatters.string_printer + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.formatters.update\_printer module +---------------------------------------------- + +.. automodule:: ahriman.core.formatters.update_printer + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.formatters.user\_printer module +-------------------------------------------- + +.. automodule:: ahriman.core.formatters.user_printer + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.formatters + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.report.rst b/docs/source/ahriman.core.report.rst new file mode 100644 index 00000000..6449007c --- /dev/null +++ b/docs/source/ahriman.core.report.rst @@ -0,0 +1,68 @@ +ahriman.core.report package +=========================== + +Submodules +---------- + +ahriman.core.report.console module +---------------------------------- + +.. automodule:: ahriman.core.report.console + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.report.email module +-------------------------------- + +.. automodule:: ahriman.core.report.email + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.report.html module +------------------------------- + +.. automodule:: ahriman.core.report.html + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.report.jinja\_template module +------------------------------------------ + +.. automodule:: ahriman.core.report.jinja_template + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.report.report module +--------------------------------- + +.. automodule:: ahriman.core.report.report + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.report.telegram module +----------------------------------- + +.. automodule:: ahriman.core.report.telegram + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.report + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.repository.rst b/docs/source/ahriman.core.repository.rst new file mode 100644 index 00000000..263967b2 --- /dev/null +++ b/docs/source/ahriman.core.repository.rst @@ -0,0 +1,59 @@ +ahriman.core.repository package +=============================== + +Submodules +---------- + +ahriman.core.repository.cleaner module +-------------------------------------- + +.. automodule:: ahriman.core.repository.cleaner + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.repository.executor module +--------------------------------------- + +.. automodule:: ahriman.core.repository.executor + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.repository.properties module +----------------------------------------- + +.. automodule:: ahriman.core.repository.properties + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.repository.repository module +----------------------------------------- + +.. automodule:: ahriman.core.repository.repository + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.repository.update\_handler module +---------------------------------------------- + +.. automodule:: ahriman.core.repository.update_handler + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.repository + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.rst b/docs/source/ahriman.core.rst new file mode 100644 index 00000000..1e0c42c0 --- /dev/null +++ b/docs/source/ahriman.core.rst @@ -0,0 +1,76 @@ +ahriman.core package +==================== + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + ahriman.core.alpm + ahriman.core.auth + ahriman.core.build_tools + ahriman.core.database + ahriman.core.formatters + ahriman.core.report + ahriman.core.repository + ahriman.core.sign + ahriman.core.status + ahriman.core.upload + +Submodules +---------- + +ahriman.core.configuration module +--------------------------------- + +.. automodule:: ahriman.core.configuration + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.exceptions module +------------------------------ + +.. automodule:: ahriman.core.exceptions + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.spawn module +------------------------- + +.. automodule:: ahriman.core.spawn + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.tree module +------------------------ + +.. automodule:: ahriman.core.tree + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.util module +------------------------ + +.. automodule:: ahriman.core.util + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.sign.rst b/docs/source/ahriman.core.sign.rst new file mode 100644 index 00000000..4e5461ba --- /dev/null +++ b/docs/source/ahriman.core.sign.rst @@ -0,0 +1,23 @@ +ahriman.core.sign package +========================= + +Submodules +---------- + +ahriman.core.sign.gpg module +---------------------------- + +.. automodule:: ahriman.core.sign.gpg + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.sign + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.status.rst b/docs/source/ahriman.core.status.rst new file mode 100644 index 00000000..c59be323 --- /dev/null +++ b/docs/source/ahriman.core.status.rst @@ -0,0 +1,41 @@ +ahriman.core.status package +=========================== + +Submodules +---------- + +ahriman.core.status.client module +--------------------------------- + +.. automodule:: ahriman.core.status.client + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.status.watcher module +---------------------------------- + +.. automodule:: ahriman.core.status.watcher + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.status.web\_client module +-------------------------------------- + +.. automodule:: ahriman.core.status.web_client + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.status + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.core.upload.rst b/docs/source/ahriman.core.upload.rst new file mode 100644 index 00000000..9f71884f --- /dev/null +++ b/docs/source/ahriman.core.upload.rst @@ -0,0 +1,59 @@ +ahriman.core.upload package +=========================== + +Submodules +---------- + +ahriman.core.upload.github module +--------------------------------- + +.. automodule:: ahriman.core.upload.github + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.upload.http\_upload module +--------------------------------------- + +.. automodule:: ahriman.core.upload.http_upload + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.upload.rsync module +-------------------------------- + +.. automodule:: ahriman.core.upload.rsync + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.upload.s3 module +----------------------------- + +.. automodule:: ahriman.core.upload.s3 + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.core.upload.upload module +--------------------------------- + +.. automodule:: ahriman.core.upload.upload + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.core.upload + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.models.rst b/docs/source/ahriman.models.rst new file mode 100644 index 00000000..aca973e0 --- /dev/null +++ b/docs/source/ahriman.models.rst @@ -0,0 +1,203 @@ +ahriman.models package +====================== + +Submodules +---------- + +ahriman.models.action module +---------------------------- + +.. automodule:: ahriman.models.action + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.aur\_package module +---------------------------------- + +.. automodule:: ahriman.models.aur_package + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.auth\_settings module +------------------------------------ + +.. automodule:: ahriman.models.auth_settings + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.build\_status module +----------------------------------- + +.. automodule:: ahriman.models.build_status + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.counters module +------------------------------ + +.. automodule:: ahriman.models.counters + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.internal\_status module +-------------------------------------- + +.. automodule:: ahriman.models.internal_status + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.migration module +------------------------------- + +.. automodule:: ahriman.models.migration + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.migration\_result module +--------------------------------------- + +.. automodule:: ahriman.models.migration_result + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.package module +----------------------------- + +.. automodule:: ahriman.models.package + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.package\_description module +------------------------------------------ + +.. automodule:: ahriman.models.package_description + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.package\_source module +------------------------------------- + +.. automodule:: ahriman.models.package_source + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.property module +------------------------------ + +.. automodule:: ahriman.models.property + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.report\_settings module +-------------------------------------- + +.. automodule:: ahriman.models.report_settings + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.repository\_paths module +--------------------------------------- + +.. automodule:: ahriman.models.repository_paths + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.result module +---------------------------- + +.. automodule:: ahriman.models.result + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.sign\_settings module +------------------------------------ + +.. automodule:: ahriman.models.sign_settings + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.smtp\_ssl\_settings module +----------------------------------------- + +.. automodule:: ahriman.models.smtp_ssl_settings + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.upload\_settings module +-------------------------------------- + +.. automodule:: ahriman.models.upload_settings + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.user module +-------------------------- + +.. automodule:: ahriman.models.user + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.user\_access module +---------------------------------- + +.. automodule:: ahriman.models.user_access + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.models.user\_identity module +------------------------------------ + +.. automodule:: ahriman.models.user_identity + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.models + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.rst b/docs/source/ahriman.rst new file mode 100644 index 00000000..18024099 --- /dev/null +++ b/docs/source/ahriman.rst @@ -0,0 +1,34 @@ +ahriman package +=============== + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + ahriman.application + ahriman.core + ahriman.models + ahriman.web + +Submodules +---------- + +ahriman.version module +---------------------- + +.. automodule:: ahriman.version + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.web.middlewares.rst b/docs/source/ahriman.web.middlewares.rst new file mode 100644 index 00000000..1ed3254d --- /dev/null +++ b/docs/source/ahriman.web.middlewares.rst @@ -0,0 +1,32 @@ +ahriman.web.middlewares package +=============================== + +Submodules +---------- + +ahriman.web.middlewares.auth\_handler module +-------------------------------------------- + +.. automodule:: ahriman.web.middlewares.auth_handler + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.web.middlewares.exception\_handler module +------------------------------------------------- + +.. automodule:: ahriman.web.middlewares.exception_handler + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.web.middlewares + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.web.rst b/docs/source/ahriman.web.rst new file mode 100644 index 00000000..5cff3e8e --- /dev/null +++ b/docs/source/ahriman.web.rst @@ -0,0 +1,41 @@ +ahriman.web package +=================== + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + ahriman.web.middlewares + ahriman.web.views + +Submodules +---------- + +ahriman.web.routes module +------------------------- + +.. automodule:: ahriman.web.routes + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.web.web module +---------------------- + +.. automodule:: ahriman.web.web + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.web + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.web.views.rst b/docs/source/ahriman.web.views.rst new file mode 100644 index 00000000..0dd278fc --- /dev/null +++ b/docs/source/ahriman.web.views.rst @@ -0,0 +1,42 @@ +ahriman.web.views package +========================= + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + ahriman.web.views.service + ahriman.web.views.status + ahriman.web.views.user + +Submodules +---------- + +ahriman.web.views.base module +----------------------------- + +.. automodule:: ahriman.web.views.base + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.web.views.index module +------------------------------ + +.. automodule:: ahriman.web.views.index + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.web.views + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.web.views.service.rst b/docs/source/ahriman.web.views.service.rst new file mode 100644 index 00000000..f02d8ab8 --- /dev/null +++ b/docs/source/ahriman.web.views.service.rst @@ -0,0 +1,50 @@ +ahriman.web.views.service package +================================= + +Submodules +---------- + +ahriman.web.views.service.add module +------------------------------------ + +.. automodule:: ahriman.web.views.service.add + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.web.views.service.remove module +--------------------------------------- + +.. automodule:: ahriman.web.views.service.remove + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.web.views.service.request module +---------------------------------------- + +.. automodule:: ahriman.web.views.service.request + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.web.views.service.search module +--------------------------------------- + +.. automodule:: ahriman.web.views.service.search + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.web.views.service + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.web.views.status.rst b/docs/source/ahriman.web.views.status.rst new file mode 100644 index 00000000..b118ff75 --- /dev/null +++ b/docs/source/ahriman.web.views.status.rst @@ -0,0 +1,50 @@ +ahriman.web.views.status package +================================ + +Submodules +---------- + +ahriman.web.views.status.ahriman module +--------------------------------------- + +.. automodule:: ahriman.web.views.status.ahriman + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.web.views.status.package module +--------------------------------------- + +.. automodule:: ahriman.web.views.status.package + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.web.views.status.packages module +---------------------------------------- + +.. automodule:: ahriman.web.views.status.packages + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.web.views.status.status module +-------------------------------------- + +.. automodule:: ahriman.web.views.status.status + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.web.views.status + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/ahriman.web.views.user.rst b/docs/source/ahriman.web.views.user.rst new file mode 100644 index 00000000..5d76b5ae --- /dev/null +++ b/docs/source/ahriman.web.views.user.rst @@ -0,0 +1,32 @@ +ahriman.web.views.user package +============================== + +Submodules +---------- + +ahriman.web.views.user.login module +----------------------------------- + +.. automodule:: ahriman.web.views.user.login + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +ahriman.web.views.user.logout module +------------------------------------ + +.. automodule:: ahriman.web.views.user.logout + :members: + :no-undoc-members: + :show-inheritance: + :private-members: + +Module contents +--------------- + +.. automodule:: ahriman.web.views.user + :members: + :no-undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..23d83fab --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,73 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# 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. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath(".")) + + +# -- Project information ----------------------------------------------------- + +project = "ahriman" +copyright = "2022, ahriman team" +author = "ahriman team" + +# The full version, including alpha/beta/rc tags +release = "2021-2022" + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named "sphinx.ext.*") or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = "en" + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "alabaster" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + + +# -- Extension configuration ------------------------------------------------- + +autodoc_member_order = "groupwise" + +autodoc_default_options = { + "no-undoc-members": True, +} diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..b6ac1df5 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,20 @@ +.. ahriman documentation master file, created by + sphinx-quickstart on Sun Apr 17 18:05:36 2022. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to ahriman's documentation! +=================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/modules.rst b/docs/source/modules.rst new file mode 100644 index 00000000..fe25d185 --- /dev/null +++ b/docs/source/modules.rst @@ -0,0 +1,7 @@ +src +=== + +.. toctree:: + :maxdepth: 4 + + ahriman diff --git a/src/ahriman/application/ahriman.py b/src/ahriman/application/ahriman.py index f80ed1bf..6c937151 100644 --- a/src/ahriman/application/ahriman.py +++ b/src/ahriman/application/ahriman.py @@ -43,8 +43,12 @@ SubParserAction = TypeVar("SubParserAction", bound="argparse._SubParsersAction[a def _formatter(prog: str) -> argparse.HelpFormatter: """ formatter for the help message - :param prog: application name - :return: formatter used by default + + Args: + prog(str): application name + + Returns: + argparse.HelpFormatter: formatter used by default """ return argparse.ArgumentDefaultsHelpFormatter(prog, width=120) @@ -52,7 +56,9 @@ def _formatter(prog: str) -> argparse.HelpFormatter: def _parser() -> argparse.ArgumentParser: """ command line parser generator - :return: command line parser for the application + + Returns: + argparse.ArgumentParser: command line parser for the application """ parser = argparse.ArgumentParser(prog="ahriman", description="ArcH Linux ReposItory MANager", epilog="Argument list can also be read from file by using @ prefix.", @@ -107,8 +113,12 @@ def _parser() -> argparse.ArgumentParser: def _set_aur_search_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for AUR search subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("aur-search", aliases=["search"], help="search for package", description="search for package in AUR using API", formatter_class=_formatter) @@ -126,8 +136,12 @@ def _set_aur_search_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_help_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for listing help subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("help", help="show help message", description="show help message for application or command and exit", @@ -141,8 +155,12 @@ def _set_help_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_help_commands_unsafe_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for listing unsafe commands - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("help-commands-unsafe", help="list unsafe commands", description="list unsafe commands as defined in default args", formatter_class=_formatter) @@ -156,8 +174,12 @@ def _set_help_commands_unsafe_parser(root: SubParserAction) -> argparse.Argument def _set_key_import_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for key import subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("key-import", help="import PGP key", description="import PGP key from public sources to the repository user", @@ -175,8 +197,12 @@ def _set_key_import_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for package addition subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("package-add", aliases=["add", "package-update"], help="add package", description="add existing or new package to the build queue", @@ -204,8 +230,12 @@ def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_package_remove_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for package removal subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("package-remove", aliases=["remove"], help="remove package", description="remove package from the repository", formatter_class=_formatter) @@ -217,8 +247,12 @@ def _set_package_remove_parser(root: SubParserAction) -> argparse.ArgumentParser def _set_package_status_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for package status subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("package-status", aliases=["status"], help="get package status", description="request status of the package", @@ -237,8 +271,12 @@ def _set_package_status_parser(root: SubParserAction) -> argparse.ArgumentParser def _set_package_status_remove_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for package status remove subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("package-status-remove", help="remove package status", description="remove the package from the status page", @@ -254,8 +292,12 @@ def _set_package_status_remove_parser(root: SubParserAction) -> argparse.Argumen def _set_package_status_update_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for package status update subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("package-status-update", aliases=["status-update"], help="update package status", description="update package status on the status page", formatter_class=_formatter) @@ -272,8 +314,12 @@ def _set_package_status_update_parser(root: SubParserAction) -> argparse.Argumen def _set_patch_add_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for new patch subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("patch-add", help="add patch set", description="create or update source patches", epilog="In order to add a patch set for the package you will need to clone " @@ -292,8 +338,12 @@ def _set_patch_add_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_patch_list_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for list patches subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("patch-list", help="list patch sets", description="list available patches for the package", formatter_class=_formatter) @@ -306,8 +356,12 @@ def _set_patch_list_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_patch_remove_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for remove patches subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("patch-remove", help="remove patch set", description="remove patches for the package", formatter_class=_formatter) @@ -319,8 +373,12 @@ def _set_patch_remove_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_backup_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for repository backup subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-backup", help="backup repository data", description="backup settings and database", formatter_class=_formatter) @@ -332,8 +390,12 @@ def _set_repo_backup_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_check_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for repository check subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-check", aliases=["check"], help="check for updates", description="check for packages updates. Same as update --dry-run --no-manual", @@ -348,8 +410,12 @@ def _set_repo_check_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_clean_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for repository clean subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-clean", aliases=["clean"], help="clean local caches", description="remove local caches", @@ -368,8 +434,12 @@ def _set_repo_clean_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_config_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for config subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-config", aliases=["config"], help="dump configuration", description="dump configuration for the specified architecture", @@ -381,8 +451,12 @@ def _set_repo_config_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_rebuild_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for repository rebuild subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-rebuild", aliases=["rebuild"], help="rebuild repository", description="force rebuild whole repository", formatter_class=_formatter) @@ -403,8 +477,12 @@ def _set_repo_rebuild_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_remove_unknown_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for remove unknown packages subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-remove-unknown", aliases=["remove-unknown"], help="remove unknown packages", description="remove packages which are missing in AUR and do not have local PKGBUILDs", @@ -418,8 +496,12 @@ def _set_repo_remove_unknown_parser(root: SubParserAction) -> argparse.ArgumentP def _set_repo_report_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for report subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-report", aliases=["report"], help="generate report", description="generate repository report according to current settings", @@ -433,8 +515,12 @@ def _set_repo_report_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_restore_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for repository restore subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-restore", help="restore repository data", description="restore settings and database", formatter_class=_formatter) @@ -447,8 +533,12 @@ def _set_repo_restore_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_setup_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for setup subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-setup", aliases=["init", "repo-init", "setup"], help="initial service configuration", description="create initial service configuration, requires root", @@ -472,8 +562,12 @@ def _set_repo_setup_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_sign_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for sign subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-sign", aliases=["sign"], help="sign packages", description="(re-)sign packages and repository database according to current settings", @@ -487,8 +581,12 @@ def _set_repo_sign_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_status_update_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for repository status update subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-status-update", help="update repository status", description="update repository status on the status page", formatter_class=_formatter) @@ -502,8 +600,12 @@ def _set_repo_status_update_parser(root: SubParserAction) -> argparse.ArgumentPa def _set_repo_sync_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for repository sync subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-sync", aliases=["sync"], help="sync repository", description="sync repository files to remote server according to current settings", @@ -517,8 +619,12 @@ def _set_repo_sync_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_repo_update_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for repository update subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("repo-update", aliases=["update"], help="update packages", description="check for packages updates and run build process if requested", @@ -537,8 +643,12 @@ def _set_repo_update_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_user_add_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for create user subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("user-add", help="create or update user", description="update user for web services with the given password and role. " @@ -559,8 +669,12 @@ def _set_user_add_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_user_list_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for user list subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("user-list", help="user known users and their access", description="list users from the user mapping and their roles", @@ -576,8 +690,12 @@ def _set_user_list_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_user_remove_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for user removal subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("user-remove", help="remove user", description="remove user from the user mapping and update the configuration", @@ -592,8 +710,12 @@ def _set_user_remove_parser(root: SubParserAction) -> argparse.ArgumentParser: def _set_web_parser(root: SubParserAction) -> argparse.ArgumentParser: """ add parser for web subcommand - :param root: subparsers for the commands - :return: created argument parser + + Args: + root(SubParserAction): subparsers for the commands + + Returns: + argparse.ArgumentParser: created argument parser """ parser = root.add_parser("web", help="web server", description="start web server", formatter_class=_formatter) parser.set_defaults(handler=handlers.Web, lock=None, no_report=True, parser=_parser) diff --git a/src/ahriman/application/application/application.py b/src/ahriman/application/application/application.py index 343fc90b..c7eb4afb 100644 --- a/src/ahriman/application/application/application.py +++ b/src/ahriman/application/application/application.py @@ -32,7 +32,9 @@ class Application(Packages, Repository): def _finalize(self, result: Result) -> None: """ generate report and sync to remote server - :param result: build result + + Args: + result(Result): build result """ self.report([], result) self.sync([], result.success) @@ -40,7 +42,9 @@ class Application(Packages, Repository): def _known_packages(self) -> Set[str]: """ load packages from repository and pacman repositories - :return: list of known packages + + Returns: + Set[str]: list of known packages """ known_packages: Set[str] = set() # local set diff --git a/src/ahriman/application/application/packages.py b/src/ahriman/application/application/packages.py index e2dc5747..2329d701 100644 --- a/src/ahriman/application/application/packages.py +++ b/src/ahriman/application/application/packages.py @@ -39,21 +39,33 @@ class Packages(Properties): def _finalize(self, result: Result) -> None: """ generate report and sync to remote server - :param result: build result + + Args: + result(Result): build result + + Raises: + NotImplementedError: not implemented method """ raise NotImplementedError def _known_packages(self) -> Set[str]: """ load packages from repository and pacman repositories - :return: list of known packages + + Returns: + Set[str]: list of known packages + + Raises: + NotImplementedError: not implemented method """ raise NotImplementedError def _add_archive(self, source: str, *_: Any) -> None: """ add package from archive - :param source: path to package archive + + Args: + source(str): path to package archive """ local_path = Path(source) dst = self.repository.paths.packages / local_path.name @@ -62,9 +74,11 @@ class Packages(Properties): def _add_aur(self, source: str, known_packages: Set[str], without_dependencies: bool) -> None: """ add package from AUR - :param source: package base name - :param known_packages: list of packages which are known by the service - :param without_dependencies: if set, dependency check will be disabled + + Args: + source(str): package base name + known_packages(Set[str]): list of packages which are known by the service + without_dependencies(bool): if set, dependency check will be disabled """ package = Package.load(source, PackageSource.AUR, self.repository.pacman, self.repository.aur_url) @@ -77,7 +91,9 @@ class Packages(Properties): def _add_directory(self, source: str, *_: Any) -> None: """ add packages from directory - :param source: path to local directory + + Args: + source(str): path to local directory """ local_path = Path(source) for full_path in filter(package_like, local_path.iterdir()): @@ -86,9 +102,11 @@ class Packages(Properties): def _add_local(self, source: str, known_packages: Set[str], without_dependencies: bool) -> None: """ add package from local PKGBUILDs - :param source: path to directory with local source files - :param known_packages: list of packages which are known by the service - :param without_dependencies: if set, dependency check will be disabled + + Args: + source(str): path to directory with local source files + known_packages(Set[str]): list of packages which are known by the service + without_dependencies(bool): if set, dependency check will be disabled """ package = Package.load(source, PackageSource.Local, self.repository.pacman, self.repository.aur_url) cache_dir = self.repository.paths.cache_for(package.base) @@ -102,7 +120,9 @@ class Packages(Properties): def _add_remote(self, source: str, *_: Any) -> None: """ add package from remote sources (e.g. HTTP) - :param remote_url: remote URL to the package archive + + Args: + source(str): remote URL of the package archive """ dst = self.repository.paths.packages / Path(source).name # URL is path, is not it? response = requests.get(source, stream=True) @@ -115,9 +135,11 @@ class Packages(Properties): def _process_dependencies(self, local_path: Path, known_packages: Set[str], without_dependencies: bool) -> None: """ process package dependencies - :param local_path: path to local package sources (i.e. cloned AUR repository) - :param known_packages: list of packages which are known by the service - :param without_dependencies: if set, dependency check will be disabled + + Args: + local_path(Path): path to local package sources (i.e. cloned AUR repository) + known_packages(Set[str]): list of packages which are known by the service + without_dependencies(bool): if set, dependency check will be disabled """ if without_dependencies: return @@ -128,9 +150,11 @@ class Packages(Properties): def add(self, names: Iterable[str], source: PackageSource, without_dependencies: bool) -> None: """ add packages for the next build - :param names: list of package bases to add - :param source: package source to add - :param without_dependencies: if set, dependency check will be disabled + + Args: + names(Iterable[str]): list of package bases to add + source(PackageSource): package source to add + without_dependencies(bool): if set, dependency check will be disabled """ known_packages = self._known_packages() # speedup dependencies processing @@ -142,7 +166,9 @@ class Packages(Properties): def remove(self, names: Iterable[str]) -> None: """ remove packages from repository - :param names: list of packages (either base or name) to remove + + Args: + names(Iterable[str]): list of packages (either base or name) to remove """ self.repository.process_remove(names) self._finalize(Result()) diff --git a/src/ahriman/application/application/properties.py b/src/ahriman/application/application/properties.py index 7648e4fe..e40c5ac0 100644 --- a/src/ahriman/application/application/properties.py +++ b/src/ahriman/application/application/properties.py @@ -27,20 +27,24 @@ from ahriman.core.repository import Repository class Properties: """ application base properties class - :ivar architecture: repository architecture - :ivar configuration: configuration instance - :ivar database: database instance - :ivar logger: application logger - :ivar repository: repository instance + + Attributes: + architecture(str): repository architecture + configuration(Configuration): configuration instance + database(SQLite): database instance + logger(logging.Logger): application logger + repository(Repository): repository instance """ def __init__(self, architecture: str, configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ self.logger = logging.getLogger("root") self.configuration = configuration diff --git a/src/ahriman/application/application/repository.py b/src/ahriman/application/application/repository.py index d021cb23..a2d2b625 100644 --- a/src/ahriman/application/application/repository.py +++ b/src/ahriman/application/application/repository.py @@ -38,17 +38,24 @@ class Repository(Properties): def _finalize(self, result: Result) -> None: """ generate report and sync to remote server - :param result: build result + + Args: + result(Result): build result + + Raises: + NotImplementedError: not implemented method """ raise NotImplementedError def clean(self, cache: bool, chroot: bool, manual: bool, packages: bool) -> None: """ run all clean methods. Warning: some functions might not be available under non-root - :param cache: clear directory with package caches - :param chroot: clear build chroot - :param manual: clear directory with manually added packages - :param packages: clear directory with built packages + + Args: + cache(bool): clear directory with package caches + chroot(bool): clear build chroot + manual(bool): clear directory with manually added packages + packages(bool): clear directory with built packages """ if cache: self.repository.clear_cache() @@ -62,8 +69,10 @@ class Repository(Properties): def report(self, target: Iterable[str], result: Result) -> None: """ generate report - :param target: list of targets to run (e.g. html) - :param result: build result + + Args: + target(Iterable[str]): list of targets to run (e.g. html) + result(Result): build result """ targets = target or None self.repository.process_report(targets, result) @@ -71,7 +80,9 @@ class Repository(Properties): def sign(self, packages: Iterable[str]) -> None: """ sign packages and repository - :param packages: only sign specified packages + + Args: + packages(Iterable[str]): only sign specified packages """ # copy to prebuilt directory for package in self.repository.packages(): @@ -94,8 +105,10 @@ class Repository(Properties): def sync(self, target: Iterable[str], built_packages: Iterable[Package]) -> None: """ sync to remote server - :param target: list of targets to run (e.g. s3) - :param built_packages: list of packages which has just been built + + Args: + target(Iterable[str]): list of targets to run (e.g. s3) + built_packages(Iterable[Package]): list of packages which has just been built """ targets = target or None self.repository.process_sync(targets, built_packages) @@ -103,7 +116,9 @@ class Repository(Properties): def unknown(self) -> List[str]: """ get packages which were not found in AUR - :return: unknown package archive list + + Returns: + List[str]: unknown package archive list """ def has_local(probe: Package) -> bool: cache_dir = self.repository.paths.cache_for(probe.base) @@ -135,7 +150,12 @@ class Repository(Properties): def update(self, updates: Iterable[Package]) -> Result: """ run package updates - :param updates: list of packages to update + + Args: + updates(Iterable[Package]): list of packages to update + + Returns: + Result: update result """ def process_update(paths: Iterable[Path], result: Result) -> None: if not paths: @@ -162,13 +182,17 @@ class Repository(Properties): log_fn: Callable[[str], None]) -> List[Package]: """ get list of packages to run update process - :param filter_packages: do not check every package just specified in the list - :param no_aur: do not check for aur updates - :param no_local: do not check local packages for updates - :param no_manual: do not check for manual updates - :param no_vcs: do not check VCS packages - :param log_fn: logger function to log updates - :return: list of out-of-dated packages + + Args: + filter_packages(Iterable[str]): do not check every package just specified in the list + no_aur(bool): do not check for aur updates + no_local(bool): do not check local packages for updates + no_manual(bool): do not check for manual updates + no_vcs(bool): do not check VCS packages + log_fn(Callable[[str], None]): logger function to log updates + + Returns: + List[Package]: list of out-of-dated packages """ updates = {} diff --git a/src/ahriman/application/handlers/add.py b/src/ahriman/application/handlers/add.py index 48e4d0ca..654a1daf 100644 --- a/src/ahriman/application/handlers/add.py +++ b/src/ahriman/application/handlers/add.py @@ -36,11 +36,13 @@ class Add(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ application = Application(architecture, configuration, no_report, unsafe) application.add(args.package, args.source, args.without_dependencies) diff --git a/src/ahriman/application/handlers/backup.py b/src/ahriman/application/handlers/backup.py index 3595f6a4..e3dafc45 100644 --- a/src/ahriman/application/handlers/backup.py +++ b/src/ahriman/application/handlers/backup.py @@ -41,11 +41,13 @@ class Backup(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ backup_paths = Backup.get_paths(configuration) with TarFile(args.path, mode="w") as archive: # well we don't actually use compression @@ -56,8 +58,12 @@ class Backup(Handler): def get_paths(configuration: Configuration) -> Set[Path]: """ extract paths to backup - :param configuration: configuration instance - :return: map of the filesystem paths + + Args: + configuration(Configuration): configuration instance + + Returns: + Set[Path]: map of the filesystem paths """ paths = set(configuration.include.glob("*.ini")) diff --git a/src/ahriman/application/handlers/clean.py b/src/ahriman/application/handlers/clean.py index 95fc6a55..45396e1a 100644 --- a/src/ahriman/application/handlers/clean.py +++ b/src/ahriman/application/handlers/clean.py @@ -36,11 +36,13 @@ class Clean(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ Application(architecture, configuration, no_report, unsafe).clean( args.cache, args.chroot, args.manual, args.packages) diff --git a/src/ahriman/application/handlers/dump.py b/src/ahriman/application/handlers/dump.py index 1cf7ed3b..ad5ced25 100644 --- a/src/ahriman/application/handlers/dump.py +++ b/src/ahriman/application/handlers/dump.py @@ -38,11 +38,13 @@ class Dump(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ dump = configuration.dump() for section, values in sorted(dump.items()): diff --git a/src/ahriman/application/handlers/handler.py b/src/ahriman/application/handlers/handler.py index 001b92cb..f8e3ddf9 100644 --- a/src/ahriman/application/handlers/handler.py +++ b/src/ahriman/application/handlers/handler.py @@ -34,8 +34,10 @@ from ahriman.models.repository_paths import RepositoryPaths class Handler: """ base handler class for command callbacks - :cvar ALLOW_AUTO_ARCHITECTURE_RUN: allow to define architecture from existing repositories - :cvar ALLOW_MULTI_ARCHITECTURE_RUN: allow to run with multiple architectures + + Attributes: + ALLOW_AUTO_ARCHITECTURE_RUN(bool): (class attribute) allow defining architecture from existing repositories + ALLOW_MULTI_ARCHITECTURE_RUN(bool): (class attribute) allow running with multiple architectures """ ALLOW_AUTO_ARCHITECTURE_RUN = True @@ -45,8 +47,15 @@ class Handler: def architectures_extract(cls: Type[Handler], args: argparse.Namespace) -> List[str]: """ get known architectures - :param args: command line args - :return: list of architectures for which tree is created + + Args: + args(argparse.Namespace): command line args + + Returns: + List[str]: list of architectures for which tree is created + + Raises: + MissingArchitecture: if no architecture set and automatic detection is not allowed or failed """ if not cls.ALLOW_AUTO_ARCHITECTURE_RUN and args.architecture is None: # for some parsers (e.g. config) we need to run with specific architecture @@ -69,9 +78,13 @@ class Handler: def call(cls: Type[Handler], args: argparse.Namespace, architecture: str) -> bool: """ additional function to wrap all calls for multiprocessing library - :param args: command line args - :param architecture: repository architecture - :return: True on success, False otherwise + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + + Returns: + bool: True on success, False otherwise """ try: configuration = Configuration.from_path(args.configuration, architecture, args.quiet) @@ -89,8 +102,15 @@ class Handler: def execute(cls: Type[Handler], args: argparse.Namespace) -> int: """ execute function for all aru - :param args: command line args - :return: 0 on success, 1 otherwise + + Args: + args(argparse.Namespace): command line args + + Returns: + int: 0 on success, 1 otherwise + + Raises: + MultipleArchitectures: if more than one architecture supplied and no multi architecture supported """ architectures = cls.architectures_extract(args) @@ -112,11 +132,16 @@ class Handler: configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation + + Raises: + NotImplementedError: not implemented method """ raise NotImplementedError @@ -124,8 +149,13 @@ class Handler: def check_if_empty(enabled: bool, predicate: bool) -> None: """ check condition and flag and raise ExitCode exception in case if it is enabled and condition match - :param enabled: if False no check will be performed - :param predicate: indicates condition on which exception should be thrown + + Args: + enabled(bool): if False no check will be performed + predicate(bool): indicates condition on which exception should be thrown + + Raises: + ExitCode: if result is empty and check is enabled """ if enabled and predicate: raise ExitCode() diff --git a/src/ahriman/application/handlers/help.py b/src/ahriman/application/handlers/help.py index b1be3a2b..b74a6ac8 100644 --- a/src/ahriman/application/handlers/help.py +++ b/src/ahriman/application/handlers/help.py @@ -37,11 +37,13 @@ class Help(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ parser: argparse.ArgumentParser = args.parser() if args.command is None: diff --git a/src/ahriman/application/handlers/key_import.py b/src/ahriman/application/handlers/key_import.py index cbbb3dc9..42ba3c2f 100644 --- a/src/ahriman/application/handlers/key_import.py +++ b/src/ahriman/application/handlers/key_import.py @@ -38,11 +38,13 @@ class KeyImport(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ Application(architecture, configuration, no_report, unsafe).repository.sign.key_import( args.key_server, args.key) diff --git a/src/ahriman/application/handlers/patch.py b/src/ahriman/application/handlers/patch.py index 7b79223e..919891d2 100644 --- a/src/ahriman/application/handlers/patch.py +++ b/src/ahriman/application/handlers/patch.py @@ -42,11 +42,13 @@ class Patch(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ application = Application(architecture, configuration, no_report, unsafe) @@ -61,9 +63,11 @@ class Patch(Handler): def patch_set_create(application: Application, sources_dir: str, track: List[str]) -> None: """ create patch set for the package base - :param application: application instance - :param sources_dir: path to directory with the package sources - :param track: track files which match the glob before creating the patch + + Args: + application(Application): application instance + sources_dir(str): path to directory with the package sources + track(List[str]): track files which match the glob before creating the patch """ package = Package.load(sources_dir, PackageSource.Local, application.repository.pacman, application.repository.aur_url) @@ -74,9 +78,11 @@ class Patch(Handler): def patch_set_list(application: Application, package_base: Optional[str], exit_code: bool) -> None: """ list patches available for the package base - :param application: application instance - :param package_base: package base - :param exit_code: raise ExitCode on empty search result + + Args: + application(Application): application instance + package_base(Optional[str]): package base + exit_code(bool): exit with error on empty search result """ patches = application.database.patches_list(package_base) Patch.check_if_empty(exit_code, not patches) @@ -89,7 +95,9 @@ class Patch(Handler): def patch_set_remove(application: Application, package_base: str) -> None: """ remove patch set for the package base - :param application: application instance - :param package_base: package base + + Args: + application(Application): application instance + package_base(str): package base """ application.database.patches_remove(package_base) diff --git a/src/ahriman/application/handlers/rebuild.py b/src/ahriman/application/handlers/rebuild.py index b1dd87ed..2e28df2c 100644 --- a/src/ahriman/application/handlers/rebuild.py +++ b/src/ahriman/application/handlers/rebuild.py @@ -38,11 +38,13 @@ class Rebuild(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ depends_on = set(args.depends_on) if args.depends_on else None @@ -65,7 +67,11 @@ class Rebuild(Handler): def extract_packages(application: Application) -> List[Package]: """ extract packages from database file - :param application: application instance - :return: list of packages which were stored in database + + Args: + application(Application): application instance + + Returns: + List[Package]: list of packages which were stored in database """ return [package for (package, _) in application.database.packages_get()] diff --git a/src/ahriman/application/handlers/remove.py b/src/ahriman/application/handlers/remove.py index bb048f28..99f14c13 100644 --- a/src/ahriman/application/handlers/remove.py +++ b/src/ahriman/application/handlers/remove.py @@ -36,10 +36,12 @@ class Remove(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ Application(architecture, configuration, no_report, unsafe).remove(args.package) diff --git a/src/ahriman/application/handlers/remove_unknown.py b/src/ahriman/application/handlers/remove_unknown.py index c10a1f2d..415c4f18 100644 --- a/src/ahriman/application/handlers/remove_unknown.py +++ b/src/ahriman/application/handlers/remove_unknown.py @@ -37,11 +37,13 @@ class RemoveUnknown(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ application = Application(architecture, configuration, no_report, unsafe) unknown_packages = application.unknown() diff --git a/src/ahriman/application/handlers/report.py b/src/ahriman/application/handlers/report.py index b7c29d52..715327e0 100644 --- a/src/ahriman/application/handlers/report.py +++ b/src/ahriman/application/handlers/report.py @@ -37,10 +37,12 @@ class Report(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ Application(architecture, configuration, no_report, unsafe).report(args.target, Result()) diff --git a/src/ahriman/application/handlers/restore.py b/src/ahriman/application/handlers/restore.py index 1dd4da24..7cb50339 100644 --- a/src/ahriman/application/handlers/restore.py +++ b/src/ahriman/application/handlers/restore.py @@ -38,11 +38,13 @@ class Restore(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ with TarFile(args.path) as archive: archive.extractall(path=args.output) diff --git a/src/ahriman/application/handlers/search.py b/src/ahriman/application/handlers/search.py index 2c58b314..0d5e7c61 100644 --- a/src/ahriman/application/handlers/search.py +++ b/src/ahriman/application/handlers/search.py @@ -34,7 +34,9 @@ from ahriman.models.aur_package import AURPackage class Search(Handler): """ packages search handler - :cvar SORT_FIELDS: allowed fields to sort the package list + + Attributes: + SORT_FIELDS(Set[str]): (class attribute) allowed fields to sort the package list """ ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture" @@ -45,11 +47,13 @@ class Search(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ official_packages_list = Official.multisearch(*args.search) aur_packages_list = AUR.multisearch(*args.search) @@ -64,9 +68,16 @@ class Search(Handler): def sort(packages: Iterable[AURPackage], sort_by: str) -> List[AURPackage]: """ sort package list by specified field - :param packages: packages list to sort - :param sort_by: AUR package field name to sort by - :return: sorted list for packages + + Args: + packages(Iterable[AURPackage]): packages list to sort + sort_by(str): AUR package field name to sort by + + Returns: + List[AURPackage]: sorted list for packages + + Raises: + InvalidOption: if search fields is not in list of allowed ones """ if sort_by not in Search.SORT_FIELDS: raise InvalidOption(sort_by) diff --git a/src/ahriman/application/handlers/setup.py b/src/ahriman/application/handlers/setup.py index 89d8ccc0..63cec015 100644 --- a/src/ahriman/application/handlers/setup.py +++ b/src/ahriman/application/handlers/setup.py @@ -31,10 +31,12 @@ from ahriman.models.repository_paths import RepositoryPaths class Setup(Handler): """ setup handler - :cvar ARCHBUILD_COMMAND_PATH: default devtools command - :cvar BIN_DIR_PATH: directory for custom binaries - :cvar MIRRORLIST_PATH: path to pacman default mirrorlist (used by multilib repository) - :cvar SUDOERS_PATH: path to sudoers.d include configuration + + Attributes: + ARCHBUILD_COMMAND_PATH(Path): (class attribute) default devtools command + BIN_DIR_PATH(Path): (class attribute) directory for custom binaries + MIRRORLIST_PATH(Path): (class attribute) path to pacman default mirrorlist (used by multilib repository) + SUDOERS_PATH(Path): (class attribute) path to sudoers.d include configuration """ ALLOW_AUTO_ARCHITECTURE_RUN = False @@ -49,11 +51,13 @@ class Setup(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ Setup.configuration_create_ahriman(args, architecture, args.repository, configuration.include) configuration.reload() @@ -72,9 +76,13 @@ class Setup(Handler): def build_command(prefix: str, architecture: str) -> Path: """ generate build command name - :param prefix: command prefix in {prefix}-{architecture}-build - :param architecture: repository architecture - :return: valid devtools command name + + Args: + prefix(str): command prefix in {prefix}-{architecture}-build + architecture(str): repository architecture + + Returns: + Path: valid devtools command name """ return Setup.BIN_DIR_PATH / f"{prefix}-{architecture}-build" @@ -83,10 +91,12 @@ class Setup(Handler): include_path: Path) -> None: """ create service specific configuration - :param args: command line args - :param architecture: repository architecture - :param repository: repository name - :param include_path: path to directory with configuration includes + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + repository(str): repository name + include_path(Path): path to directory with configuration includes """ configuration = Configuration() @@ -114,12 +124,14 @@ class Setup(Handler): no_multilib: bool, repository: str, paths: RepositoryPaths) -> None: """ create configuration for devtools based on `source` configuration - :param prefix: command prefix in {prefix}-{architecture}-build - :param architecture: repository architecture - :param source: path to source configuration file - :param no_multilib: do not add multilib repository - :param repository: repository name - :param paths: repository paths instance + + Args: + prefix(str): command prefix in {prefix}-{architecture}-build + architecture(str): repository architecture + source(Path): path to source configuration file + no_multilib(bool): do not add multilib repository + repository(str): repository name + paths(RepositoryPaths): repository paths instance """ configuration = Configuration() # preserve case @@ -149,8 +161,10 @@ class Setup(Handler): def configuration_create_makepkg(packager: str, paths: RepositoryPaths) -> None: """ create configuration for makepkg - :param packager: packager identifier (e.g. name, email) - :param paths: repository paths instance + + Args: + packager(str): packager identifier (e.g. name, email) + paths(RepositoryPaths): repository paths instance """ (paths.root / ".makepkg.conf").write_text(f"PACKAGER='{packager}'\n", encoding="utf8") @@ -158,8 +172,10 @@ class Setup(Handler): def configuration_create_sudo(prefix: str, architecture: str) -> None: """ create configuration to run build command with sudo without password - :param prefix: command prefix in {prefix}-{architecture}-build - :param architecture: repository architecture + + Args: + prefix(str): command prefix in {prefix}-{architecture}-build + architecture(str): repository architecture """ command = Setup.build_command(prefix, architecture) Setup.SUDOERS_PATH.write_text(f"ahriman ALL=(ALL) NOPASSWD: {command} *\n", encoding="utf8") @@ -169,8 +185,10 @@ class Setup(Handler): def executable_create(prefix: str, architecture: str) -> None: """ create executable for the service - :param prefix: command prefix in {prefix}-{architecture}-build - :param architecture: repository architecture + + Args: + prefix(str): command prefix in {prefix}-{architecture}-build + architecture(str): repository architecture """ command = Setup.build_command(prefix, architecture) command.unlink(missing_ok=True) diff --git a/src/ahriman/application/handlers/sign.py b/src/ahriman/application/handlers/sign.py index 18ed6d90..5d7a8436 100644 --- a/src/ahriman/application/handlers/sign.py +++ b/src/ahriman/application/handlers/sign.py @@ -36,10 +36,12 @@ class Sign(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ Application(architecture, configuration, no_report, unsafe).sign(args.package) diff --git a/src/ahriman/application/handlers/status.py b/src/ahriman/application/handlers/status.py index 7a20d222..9cf60412 100644 --- a/src/ahriman/application/handlers/status.py +++ b/src/ahriman/application/handlers/status.py @@ -42,11 +42,13 @@ class Status(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ # we are using reporter here client = Application(architecture, configuration, no_report=False, unsafe=unsafe).repository.reporter diff --git a/src/ahriman/application/handlers/status_update.py b/src/ahriman/application/handlers/status_update.py index 365cc562..fd988382 100644 --- a/src/ahriman/application/handlers/status_update.py +++ b/src/ahriman/application/handlers/status_update.py @@ -39,11 +39,13 @@ class StatusUpdate(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ # we are using reporter here client = Application(architecture, configuration, no_report=False, unsafe=unsafe).repository.reporter diff --git a/src/ahriman/application/handlers/sync.py b/src/ahriman/application/handlers/sync.py index 86849c37..66c781a0 100644 --- a/src/ahriman/application/handlers/sync.py +++ b/src/ahriman/application/handlers/sync.py @@ -28,7 +28,7 @@ from ahriman.core.configuration import Configuration class Sync(Handler): """ - remove sync handler + remote sync handler """ @classmethod @@ -36,10 +36,12 @@ class Sync(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ Application(architecture, configuration, no_report, unsafe).sync(args.target, []) diff --git a/src/ahriman/application/handlers/unsafe_commands.py b/src/ahriman/application/handlers/unsafe_commands.py index b391ad45..f14486a1 100644 --- a/src/ahriman/application/handlers/unsafe_commands.py +++ b/src/ahriman/application/handlers/unsafe_commands.py @@ -24,7 +24,6 @@ from typing import List, Type from ahriman.application.handlers.handler import Handler from ahriman.core.configuration import Configuration -from ahriman.core.exceptions import ExitCode from ahriman.core.formatters.string_printer import StringPrinter @@ -40,11 +39,13 @@ class UnsafeCommands(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ parser = args.parser() unsafe_commands = UnsafeCommands.get_unsafe_commands(parser) @@ -58,20 +59,25 @@ class UnsafeCommands(Handler): def check_unsafe(command: str, unsafe_commands: List[str], parser: argparse.ArgumentParser) -> None: """ check if command is unsafe - :param command: command to check - :param unsafe_commands: list of unsafe commands - :param parser: generated argument parser + + Args: + command(str): command to check + unsafe_commands(List[str]): list of unsafe commands + parser(argparse.ArgumentParser): generated argument parser """ args = parser.parse_args(shlex.split(command)) - if args.command in unsafe_commands: - raise ExitCode() + UnsafeCommands.check_if_empty(True, args.command in unsafe_commands) @staticmethod def get_unsafe_commands(parser: argparse.ArgumentParser) -> List[str]: """ extract unsafe commands from argument parser - :param parser: generated argument parser - :return: list of commands with default unsafe flag + + Args: + parser(argparse.ArgumentParser): generated argument parser + + Returns: + List[str]: list of commands with default unsafe flag """ # pylint: disable=protected-access subparser = next(action for action in parser._actions if isinstance(action, argparse._SubParsersAction)) diff --git a/src/ahriman/application/handlers/update.py b/src/ahriman/application/handlers/update.py index 216b4e88..9ac19fd6 100644 --- a/src/ahriman/application/handlers/update.py +++ b/src/ahriman/application/handlers/update.py @@ -36,11 +36,13 @@ class Update(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ application = Application(architecture, configuration, no_report, unsafe) packages = application.updates(args.package, args.no_aur, args.no_local, args.no_manual, args.no_vcs, @@ -56,9 +58,13 @@ class Update(Handler): def log_fn(application: Application, dry_run: bool) -> Callable[[str], None]: """ package updates log function - :param application: application instance - :param dry_run: do not perform update itself - :return: in case if dry_run is set it will return print, logger otherwise + + Args: + application(Application): application instance + dry_run(bool): do not perform update itself + + Returns: + Callable[[str], None]: in case if dry_run is set it will return print, logger otherwise """ def inner(line: str) -> None: return print(line) if dry_run else application.logger.info(line) diff --git a/src/ahriman/application/handlers/user.py b/src/ahriman/application/handlers/user.py index c65beabf..0e7d1cab 100644 --- a/src/ahriman/application/handlers/user.py +++ b/src/ahriman/application/handlers/user.py @@ -43,11 +43,13 @@ class User(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ database = SQLite.load(configuration) @@ -72,11 +74,13 @@ class User(Handler): as_service_user: bool, secure: bool) -> None: """ enable configuration if it has been disabled - :param configuration: configuration instance - :param user: user descriptor - :param salt: password hash salt - :param as_service_user: add user as service user, also set password and user to configuration - :param secure: if true then set file permissions to 0o600 + + Args: + configuration(Configuration): configuration instance + user(MUser): user descriptor + salt(str): password hash salt + as_service_user(bool): add user as service user, also set password and user to configuration + secure(bool): if true then set file permissions to 0o600 """ configuration.set_option("auth", "salt", salt) if as_service_user: @@ -88,8 +92,12 @@ class User(Handler): def configuration_get(include_path: Path) -> Configuration: """ create configuration instance - :param include_path: path to directory with configuration includes - :return: configuration instance. In case if there are local settings they will be loaded + + Args: + include_path(Path): path to directory with configuration includes + + Returns: + Configuration: configuration instance. In case if there are local settings they will be loaded """ target = include_path / "auth.ini" configuration = Configuration() @@ -103,8 +111,10 @@ class User(Handler): def configuration_write(configuration: Configuration, secure: bool) -> None: """ write configuration file - :param configuration: configuration instance - :param secure: if true then set file permissions to 0o600 + + Args: + configuration(Configuration): configuration instance + secure(bool): if true then set file permissions to 0o600 """ path, _ = configuration.check_loaded() with path.open("w") as ahriman_configuration: @@ -116,9 +126,13 @@ class User(Handler): def get_salt(configuration: Configuration, salt_length: int = 20) -> str: """ get salt from configuration or create new string - :param configuration: configuration instance - :param salt_length: salt length - :return: current salt + + Args: + configuration(Configuration): configuration instance + salt_length(int, optional): salt length (Default value = 20) + + Returns: + str: current salt """ if salt := configuration.get("auth", "salt", fallback=None): return salt @@ -128,8 +142,12 @@ class User(Handler): def user_create(args: argparse.Namespace) -> MUser: """ create user descriptor from arguments - :param args: command line args - :return: built user descriptor + + Args: + args(argparse.Namespace): command line args + + Returns: + MUser: built user descriptor """ user = MUser(args.username, args.password, args.role) if user.password is None: diff --git a/src/ahriman/application/handlers/web.py b/src/ahriman/application/handlers/web.py index d013963e..8ac8b894 100644 --- a/src/ahriman/application/handlers/web.py +++ b/src/ahriman/application/handlers/web.py @@ -39,11 +39,13 @@ class Web(Handler): configuration: Configuration, no_report: bool, unsafe: bool) -> None: """ callback for command line - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ # we are using local import for optional dependencies from ahriman.web.web import run_server, setup_service diff --git a/src/ahriman/application/lock.py b/src/ahriman/application/lock.py index 0b50cf26..9b157fcb 100644 --- a/src/ahriman/application/lock.py +++ b/src/ahriman/application/lock.py @@ -37,19 +37,23 @@ from ahriman.models.build_status import BuildStatusEnum class Lock: """ wrapper for application lock file - :ivar force: remove lock file on start if any - :ivar path: path to lock file if any - :ivar reporter: build status reporter instance - :ivar paths: repository paths instance - :ivar unsafe: skip user check + + Attributes: + force(bool): remove lock file on start if any + path(Path): path to lock file if any + reporter(Client): build status reporter instance + paths(RepositoryPaths): repository paths instance + unsafe(bool): skip user check """ def __init__(self, args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: """ default constructor - :param args: command line args - :param architecture: repository architecture - :param configuration: configuration instance + + Args: + args(argparse.Namespace): command line args + architecture(str): repository architecture + configuration(Configuration): configuration instance """ self.path = Path(f"{args.lock}_{architecture}") if args.lock is not None else None self.force = args.force @@ -62,11 +66,11 @@ class Lock: """ default workflow is the following: - check user UID - check if there is lock file - check web status watcher status - create lock file - report to web if enabled + 1. Check user UID + 2. Check if there is lock file + 3. Check web status watcher status + 4. Create lock file + 5. Report to status page if enabled """ self.check_user() self.check_version() @@ -78,10 +82,14 @@ class Lock: exc_tb: TracebackType) -> Literal[False]: """ remove lock file when done - :param exc_type: exception type name if any - :param exc_val: exception raised if any - :param exc_tb: exception traceback if any - :return: always False (do not suppress any exception) + + Args: + exc_type(Optional[Type[Exception]]): exception type name if any + exc_val(Optional[Exception]): exception raised if any + exc_tb(TracebackType): exception traceback if any + + Returns: + Literal[False]: always False (do not suppress any exception) """ self.clear() status = BuildStatusEnum.Success if exc_val is None else BuildStatusEnum.Failed @@ -116,6 +124,9 @@ class Lock: def create(self) -> None: """ create lock file + + Raises: + DuplicateRun: if lock exists and no force flag supplied """ if self.path is None: return diff --git a/src/ahriman/core/alpm/pacman.py b/src/ahriman/core/alpm/pacman.py index 1bd8093a..cca3ce37 100644 --- a/src/ahriman/core/alpm/pacman.py +++ b/src/ahriman/core/alpm/pacman.py @@ -26,13 +26,17 @@ from ahriman.core.configuration import Configuration class Pacman: """ alpm wrapper - :ivar handle: pyalpm root `Handle` + + Attributes: + handle(Handle): pyalpm root `Handle` """ def __init__(self, configuration: Configuration) -> None: """ default constructor - :param configuration: configuration instance + + Args: + configuration(Configuration): configuration instance """ root = configuration.get("alpm", "root") pacman_root = configuration.getpath("alpm", "database") @@ -43,7 +47,9 @@ class Pacman: def all_packages(self) -> Set[str]: """ get list of packages known for alpm - :return: list of package names + + Returns: + Set[str]: list of package names """ result: Set[str] = set() for database in self.handle.get_syncdbs(): diff --git a/src/ahriman/core/alpm/remote/aur.py b/src/ahriman/core/alpm/remote/aur.py index 01b7fe1a..34a6c225 100644 --- a/src/ahriman/core/alpm/remote/aur.py +++ b/src/ahriman/core/alpm/remote/aur.py @@ -30,10 +30,12 @@ from ahriman.models.aur_package import AURPackage class AUR(Remote): """ AUR RPC wrapper - :cvar DEFAULT_RPC_URL: default AUR RPC url - :cvar DEFAULT_RPC_VERSION: default AUR RPC version - :ivar rpc_url: AUR RPC url - :ivar rpc_version: AUR RPC version + + Attributes: + DEFAULT_RPC_URL(str): (class attribute) default AUR RPC url + DEFAULT_RPC_VERSION(str): (class attribute) default AUR RPC version + rpc_url(str): AUR RPC url + rpc_version(str): AUR RPC version """ DEFAULT_RPC_URL = "https://aur.archlinux.org/rpc" @@ -42,8 +44,10 @@ class AUR(Remote): def __init__(self, rpc_url: Optional[str] = None, rpc_version: Optional[str] = None) -> None: """ default constructor - :param rpc_url: AUR RPC url - :param rpc_version: AUR RPC version + + Args: + rpc_url(Optional[str], optional): AUR RPC url (Default value = None) + rpc_version(Optional[str], optional): AUR RPC version (Default value = None) """ Remote.__init__(self) self.rpc_url = rpc_url or self.DEFAULT_RPC_URL @@ -53,8 +57,15 @@ class AUR(Remote): def parse_response(response: Dict[str, Any]) -> List[AURPackage]: """ parse RPC response to package list - :param response: RPC response json - :return: list of parsed packages + + Args: + response(Dict[str, Any]): RPC response json + + Returns: + List[AURPackage]: list of parsed packages + + Raises: + InvalidPackageInfo: for error API response """ response_type = response["type"] if response_type == "error": @@ -65,10 +76,14 @@ class AUR(Remote): def make_request(self, request_type: str, *args: str, **kwargs: str) -> List[AURPackage]: """ perform request to AUR RPC - :param request_type: AUR request type, e.g. search, info - :param args: list of arguments to be passed as args query parameter - :param kwargs: list of additional named parameters like by - :return: response parsed to package list + + Args: + request_type(str): AUR request type, e.g. search, info + *args(str): list of arguments to be passed as args query parameter + **kwargs(str): list of additional named parameters like by + + Returns: + List[AURPackage]: response parsed to package list """ query: Dict[str, Any] = { "type": request_type, @@ -98,8 +113,12 @@ class AUR(Remote): def package_info(self, package_name: str) -> AURPackage: """ get package info by its name - :param package_name: package name to search - :return: package which match the package name + + Args: + package_name(str): package name to search + + Returns: + AURPackage: package which match the package name """ packages = self.make_request("info", package_name) return next(package for package in packages if package.name == package_name) @@ -107,7 +126,11 @@ class AUR(Remote): def package_search(self, *keywords: str) -> List[AURPackage]: """ search package in AUR web - :param keywords: keywords to search - :return: list of packages which match the criteria + + Args: + *keywords(str): keywords to search + + Returns: + List[AURPackage]: list of packages which match the criteria """ return self.make_request("search", *keywords, by="name-desc") diff --git a/src/ahriman/core/alpm/remote/official.py b/src/ahriman/core/alpm/remote/official.py index 3e20ad25..7430154c 100644 --- a/src/ahriman/core/alpm/remote/official.py +++ b/src/ahriman/core/alpm/remote/official.py @@ -30,8 +30,10 @@ from ahriman.models.aur_package import AURPackage class Official(Remote): """ official repository RPC wrapper - :cvar DEFAULT_RPC_URL: default AUR RPC url - :ivar rpc_url: AUR RPC url + + Attributes: + DEFAULT_RPC_URL(str): (class attribute) default AUR RPC url + rpc_url(str): AUR RPC url """ DEFAULT_RPC_URL = "https://archlinux.org/packages/search/json" @@ -39,7 +41,9 @@ class Official(Remote): def __init__(self, rpc_url: Optional[str] = None) -> None: """ default constructor - :param rpc_url: AUR RPC url + + Args: + rpc_url(Optional[str], optional): AUR RPC url (Default value = None) """ Remote.__init__(self) self.rpc_url = rpc_url or self.DEFAULT_RPC_URL @@ -48,8 +52,15 @@ class Official(Remote): def parse_response(response: Dict[str, Any]) -> List[AURPackage]: """ parse RPC response to package list - :param response: RPC response json - :return: list of parsed packages + + Args: + response(Dict[str, Any]): RPC response json + + Returns: + List[AURPackage]: list of parsed packages + + Raises: + InvalidPackageInfo: for error API response """ if not response["valid"]: raise InvalidPackageInfo("API validation error") @@ -58,9 +69,13 @@ class Official(Remote): def make_request(self, *args: str, by: str) -> List[AURPackage]: """ perform request to official repositories RPC - :param args: list of arguments to be passed as args query parameter - :param by: search by the field - :return: response parsed to package list + + Args: + *args(str): list of arguments to be passed as args query parameter + by(str): search by the field + + Returns: + List[AURPackage]: response parsed to package list """ try: response = requests.get(self.rpc_url, params={by: args}) @@ -76,8 +91,12 @@ class Official(Remote): def package_info(self, package_name: str) -> AURPackage: """ get package info by its name - :param package_name: package name to search - :return: package which match the package name + + Args: + package_name(str): package name to search + + Returns: + AURPackage: package which match the package name """ packages = self.make_request(package_name, by="name") return next(package for package in packages if package.name == package_name) @@ -85,7 +104,11 @@ class Official(Remote): def package_search(self, *keywords: str) -> List[AURPackage]: """ search package in AUR web - :param keywords: keywords to search - :return: list of packages which match the criteria + + Args: + *keywords(str): keywords to search + + Returns: + List[AURPackage]: list of packages which match the criteria """ return self.make_request(*keywords, by="q") diff --git a/src/ahriman/core/alpm/remote/remote.py b/src/ahriman/core/alpm/remote/remote.py index 7ac55488..57665f7e 100644 --- a/src/ahriman/core/alpm/remote/remote.py +++ b/src/ahriman/core/alpm/remote/remote.py @@ -29,7 +29,9 @@ from ahriman.models.aur_package import AURPackage class Remote: """ base class for remote package search - :ivar logger: class logger + + Attributes: + logger(logging.Logger): class logger """ def __init__(self) -> None: @@ -42,8 +44,12 @@ class Remote: def info(cls: Type[Remote], package_name: str) -> AURPackage: """ get package info by its name - :param package_name: package name to search - :return: package which match the package name + + Args: + package_name(str): package name to search + + Returns: + AURPackage: package which match the package name """ return cls().package_info(package_name) @@ -52,8 +58,12 @@ class Remote: """ search in remote repository by using API with multiple words. This method is required in order to handle https://bugs.archlinux.org/task/49133. In addition, short words will be dropped - :param keywords: search terms, e.g. "ahriman", "is", "cool" - :return: list of packages each of them matches all search terms + + Args: + *keywords(str): search terms, e.g. "ahriman", "is", "cool" + + Returns: + List[AURPackage]: list of packages each of them matches all search terms """ instance = cls() packages: Dict[str, AURPackage] = {} @@ -70,23 +80,41 @@ class Remote: def search(cls: Type[Remote], *keywords: str) -> List[AURPackage]: """ search package in AUR web - :param keywords: keywords to search - :return: list of packages which match the criteria + + Args: + *keywords(str): search terms, e.g. "ahriman", "is", "cool" + + Returns: + List[AURPackage]: list of packages which match the criteria """ return cls().package_search(*keywords) def package_info(self, package_name: str) -> AURPackage: """ get package info by its name - :param package_name: package name to search - :return: package which match the package name + + Args: + package_name(str): package name to search + + Returns: + AURPackage: package which match the package name + + Raises: + NotImplementedError: not implemented method """ raise NotImplementedError def package_search(self, *keywords: str) -> List[AURPackage]: """ search package in AUR web - :param keywords: keywords to search - :return: list of packages which match the criteria + + Args: + *keywords(str): keywords to search + + Returns: + List[AURPackage]: list of packages which match the criteria + + Raises: + NotImplementedError: not implemented method """ raise NotImplementedError diff --git a/src/ahriman/core/alpm/repo.py b/src/ahriman/core/alpm/repo.py index 7cbd6670..72d52fdf 100644 --- a/src/ahriman/core/alpm/repo.py +++ b/src/ahriman/core/alpm/repo.py @@ -30,11 +30,13 @@ from ahriman.models.repository_paths import RepositoryPaths class Repo: """ repo-add and repo-remove wrapper - :ivar logger: class logger - :ivar name: repository name - :ivar paths: repository paths instance - :ivar sign_args: additional args which have to be used to sign repository archive - :ivar uid: uid of the repository owner user + + Attributes: + logger(logging.Logger): class logger + name(str): repository name + paths(RepositoryPaths): repository paths instance + sign_args(List[str]): additional args which have to be used to sign repository archive + uid(int): uid of the repository owner user """ _check_output = check_output @@ -42,9 +44,11 @@ class Repo: def __init__(self, name: str, paths: RepositoryPaths, sign_args: List[str]) -> None: """ default constructor - :param name: repository name - :param paths: repository paths instance - :param sign_args: additional args which have to be used to sign repository archive + + Args: + name(str): repository name + paths(RepositoryPaths): repository paths instance + sign_args(List[str]): additional args which have to be used to sign repository archive """ self.logger = logging.getLogger("build_details") self.name = name @@ -55,14 +59,19 @@ class Repo: @property def repo_path(self) -> Path: """ - :return: path to repository database + get full path to the repository database + + Returns: + Path: path to repository database """ return self.paths.repository / f"{self.name}.db.tar.gz" def add(self, path: Path) -> None: """ add new package to repository - :param path: path to archive to add + + Args: + path(Path): path to archive to add """ Repo._check_output( "repo-add", *self.sign_args, "-R", str(self.repo_path), str(path), @@ -85,8 +94,10 @@ class Repo: def remove(self, package: str, filename: Path) -> None: """ remove package from repository - :param package: package name to remove - :param filename: package filename to remove + + Args: + package(str): package name to remove + filename(Path): package filename to remove """ # remove package and signature (if any) from filesystem for full_path in self.paths.repository.glob(f"{filename}*"): diff --git a/src/ahriman/core/auth/auth.py b/src/ahriman/core/auth/auth.py index 17c8d732..3a2f4b17 100644 --- a/src/ahriman/core/auth/auth.py +++ b/src/ahriman/core/auth/auth.py @@ -32,16 +32,21 @@ from ahriman.models.user_access import UserAccess class Auth: """ helper to deal with user authorization - :ivar enabled: indicates if authorization is enabled - :ivar max_age: session age in seconds. It will be used for both client side and server side checks - :ivar safe_build_status: allow read only access to the index page + + Attributes: + enabled(bool): indicates if authorization is enabled + logger(logging.Logger): class logger + max_age(int): session age in seconds. It will be used for both client side and server side checks + safe_build_status(bool): allow read only access to the index page """ def __init__(self, configuration: Configuration, provider: AuthSettings = AuthSettings.Disabled) -> None: """ default constructor - :param configuration: configuration instance - :param provider: authorization type definition + + Args: + configuration(Configuration): configuration instance + provider(AuthSettings, optional): authorization type definition (Default value = AuthSettings.Disabled) """ self.logger = logging.getLogger("http") @@ -57,7 +62,9 @@ class Auth: In case of internal authentication it must provide an interface (modal form) to login with button sends POST request. But for an external providers behaviour can be different: e.g. OAuth provider requires sending GET request to external resource - :return: login control as html code to insert + + Returns: + str: login control as html code to insert """ return """""" @@ -65,9 +72,13 @@ class Auth: def load(cls: Type[Auth], configuration: Configuration, database: SQLite) -> Auth: """ load authorization module from settings - :param configuration: configuration instance - :param database: database instance - :return: authorization module according to current settings + + Args: + configuration(Configuration): configuration instance + database(SQLite): database instance + + Returns: + Auth: authorization module according to current settings """ provider = AuthSettings.from_option(configuration.get("auth", "target", fallback="disabled")) if provider == AuthSettings.Configuration: @@ -81,9 +92,13 @@ class Auth: async def check_credentials(self, username: Optional[str], password: Optional[str]) -> bool: # pylint: disable=no-self-use """ validate user password - :param username: username - :param password: entered password - :return: True in case if password matches, False otherwise + + Args: + username(Optional[str]): username + password(Optional[str]): entered password + + Returns: + bool: True in case if password matches, False otherwise """ del username, password return True @@ -91,8 +106,12 @@ class Auth: async def known_username(self, username: Optional[str]) -> bool: # pylint: disable=no-self-use """ check if user is known - :param username: username - :return: True in case if user is known and can be authorized and False otherwise + + Args: + username(Optional[str]): username + + Returns: + bool: True in case if user is known and can be authorized and False otherwise """ del username return True @@ -100,10 +119,14 @@ class Auth: async def verify_access(self, username: str, required: UserAccess, context: Optional[str]) -> bool: # pylint: disable=no-self-use """ validate if user has access to requested resource - :param username: username - :param required: required access level - :param context: URI request path - :return: True in case if user is allowed to do this request and False otherwise + + Args: + username(str): username + required(UserAccess): required access level + context(Optional[str]): URI request path + + Returns: + bool: True in case if user is allowed to do this request and False otherwise """ del username, required, context return True diff --git a/src/ahriman/core/auth/helpers.py b/src/ahriman/core/auth/helpers.py index 1110694e..c25d9508 100644 --- a/src/ahriman/core/auth/helpers.py +++ b/src/ahriman/core/auth/helpers.py @@ -29,8 +29,12 @@ except ImportError: async def authorized_userid(*args: Any) -> Any: """ handle aiohttp security methods - :param args: argument list as provided by authorized_userid function - :return: None in case if no aiohttp_security module found and function call otherwise + + Args: + *args(Any): argument list as provided by authorized_userid function + + Returns: + Any: None in case if no aiohttp_security module found and function call otherwise """ if _has_aiohttp_security: return await aiohttp_security.authorized_userid(*args) # pylint: disable=no-value-for-parameter @@ -40,8 +44,12 @@ async def authorized_userid(*args: Any) -> Any: async def check_authorized(*args: Any) -> Any: """ handle aiohttp security methods - :param args: argument list as provided by check_authorized function - :return: None in case if no aiohttp_security module found and function call otherwise + + Args: + *args(Any): argument list as provided by check_authorized function + + Returns: + Any: None in case if no aiohttp_security module found and function call otherwise """ if _has_aiohttp_security: return await aiohttp_security.check_authorized(*args) # pylint: disable=no-value-for-parameter @@ -51,8 +59,12 @@ async def check_authorized(*args: Any) -> Any: async def forget(*args: Any) -> Any: """ handle aiohttp security methods - :param args: argument list as provided by forget function - :return: None in case if no aiohttp_security module found and function call otherwise + + Args: + *args(Any): argument list as provided by forget function + + Returns: + Any: None in case if no aiohttp_security module found and function call otherwise """ if _has_aiohttp_security: return await aiohttp_security.forget(*args) # pylint: disable=no-value-for-parameter @@ -62,8 +74,12 @@ async def forget(*args: Any) -> Any: async def remember(*args: Any) -> Any: """ handle disabled auth - :param args: argument list as provided by remember function - :return: None in case if no aiohttp_security module found and function call otherwise + + Args: + *args(Any): argument list as provided by remember function + + Returns: + Any: None in case if no aiohttp_security module found and function call otherwise """ if _has_aiohttp_security: return await aiohttp_security.remember(*args) # pylint: disable=no-value-for-parameter diff --git a/src/ahriman/core/auth/mapping.py b/src/ahriman/core/auth/mapping.py index 22c08d96..76140151 100644 --- a/src/ahriman/core/auth/mapping.py +++ b/src/ahriman/core/auth/mapping.py @@ -31,17 +31,21 @@ from ahriman.models.user_access import UserAccess class Mapping(Auth): """ user authorization based on mapping from configuration file - :ivar salt: random generated string to salt passwords - :ivar database: database instance + + Attributes: + salt(str): random generated string to salt passwords + database(SQLite): database instance """ def __init__(self, configuration: Configuration, database: SQLite, provider: AuthSettings = AuthSettings.Configuration) -> None: """ default constructor - :param configuration: configuration instance - :param database: database instance - :param provider: authorization type definition + + Args: + configuration(Configuration): configuration instance + database(SQLite): database instance + provider(AuthSettings, optional): authorization type definition (Default value = AuthSettings.Configuration) """ Auth.__init__(self, configuration, provider) self.database = database @@ -50,9 +54,13 @@ class Mapping(Auth): async def check_credentials(self, username: Optional[str], password: Optional[str]) -> bool: """ validate user password - :param username: username - :param password: entered password - :return: True in case if password matches, False otherwise + + Args: + username(Optional[str]): username + password(Optional[str]): entered password + + Returns: + bool: True in case if password matches, False otherwise """ if username is None or password is None: return False # invalid data supplied @@ -62,26 +70,38 @@ class Mapping(Auth): def get_user(self, username: str) -> Optional[User]: """ retrieve user from in-memory mapping - :param username: username - :return: user descriptor if username is known and None otherwise + + Args: + username(str): username + + Returns: + Optional[User]: user descriptor if username is known and None otherwise """ return self.database.user_get(username) async def known_username(self, username: Optional[str]) -> bool: """ check if user is known - :param username: username - :return: True in case if user is known and can be authorized and False otherwise + + Args: + username(Optional[str]): username + + Returns: + bool: True in case if user is known and can be authorized and False otherwise """ return username is not None and self.get_user(username) is not None async def verify_access(self, username: str, required: UserAccess, context: Optional[str]) -> bool: """ validate if user has access to requested resource - :param username: username - :param required: required access level - :param context: URI request path - :return: True in case if user is allowed to do this request and False otherwise + + Args: + username(str): username + required(UserAccess): required access level + context(Optional[str]): URI request path + + Returns: + bool: True in case if user is allowed to do this request and False otherwise """ user = self.get_user(username) return user is not None and user.verify_access(required) diff --git a/src/ahriman/core/auth/oauth.py b/src/ahriman/core/auth/oauth.py index f583d3bd..55dbb607 100644 --- a/src/ahriman/core/auth/oauth.py +++ b/src/ahriman/core/auth/oauth.py @@ -32,20 +32,24 @@ class OAuth(Mapping): """ OAuth user authorization. It is required to create application first and put application credentials. - :ivar client_id: application client id - :ivar client_secret: application client secret key - :ivar provider: provider class, should be one of aiohttp-client provided classes - :ivar redirect_uri: redirect URI registered in provider - :ivar scopes: list of scopes required by the application + + Attributes: + client_id(str): application client id + client_secret(str): application client secret key + provider(aioauth_client.OAuth2Client): provider class, should be one of aiohttp-client provided classes + redirect_uri(str): redirect URI registered in provider + scopes(str): list of scopes required by the application """ def __init__(self, configuration: Configuration, database: SQLite, provider: AuthSettings = AuthSettings.OAuth) -> None: """ default constructor - :param configuration: configuration instance - :param database: database instance - :param provider: authorization type definition + + Args: + configuration(Configuration): configuration instance + database(SQLite): database instance + provider(AuthSettings, optional): authorization type definition (Default value = AuthSettings.OAuth) """ Mapping.__init__(self, configuration, database, provider) self.client_id = configuration.get("auth", "client_id") @@ -60,7 +64,10 @@ class OAuth(Mapping): @property def auth_control(self) -> str: """ - :return: login control as html code to insert + get authorization html control + + Returns: + str: login control as html code to insert """ return """login""" @@ -68,8 +75,15 @@ class OAuth(Mapping): def get_provider(name: str) -> Type[aioauth_client.OAuth2Client]: """ load OAuth2 provider by name - :param name: name of the provider. Must be valid class defined in aioauth-client library - :return: loaded provider type + + Args: + name(str): name of the provider. Must be valid class defined in aioauth-client library + + Returns: + Type[aioauth_client.OAuth2Client]: loaded provider type + + Raises: + InvalidOption: in case if invalid OAuth provider name supplied """ provider: Type[aioauth_client.OAuth2Client] = getattr(aioauth_client, name) try: @@ -83,14 +97,18 @@ class OAuth(Mapping): def get_client(self) -> aioauth_client.OAuth2Client: """ load client from parameters - :return: generated client according to current settings + + Returns: + aioauth_client.OAuth2Client: generated client according to current settings """ return self.provider(client_id=self.client_id, client_secret=self.client_secret) def get_oauth_url(self) -> str: """ get authorization URI for the specified settings - :return: authorization URI as a string + + Returns: + str: authorization URI as a string """ client = self.get_client() uri: str = client.get_authorize_url(scope=self.scopes, redirect_uri=self.redirect_uri) @@ -99,8 +117,12 @@ class OAuth(Mapping): async def get_oauth_username(self, code: str) -> Optional[str]: """ extract OAuth username from remote - :param code: authorization code provided by external service - :return: username as is in OAuth provider + + Args: + code(str): authorization code provided by external service + + Returns: + Optional[str]: username as is in OAuth provider """ try: client = self.get_client() diff --git a/src/ahriman/core/build_tools/sources.py b/src/ahriman/core/build_tools/sources.py index 21eb9f9c..8261e176 100644 --- a/src/ahriman/core/build_tools/sources.py +++ b/src/ahriman/core/build_tools/sources.py @@ -28,7 +28,9 @@ from ahriman.core.util import check_output class Sources: """ helper to download package sources (PKGBUILD etc) - :cvar logger: class logger + + Attributes: + logger(logging.Logger): (class attribute) class logger """ logger = logging.getLogger("build_details") @@ -40,8 +42,10 @@ class Sources: def add(sources_dir: Path, *pattern: str) -> None: """ track found files via git - :param sources_dir: local path to git repository - :param pattern: glob patterns + + Args: + sources_dir(Path): local path to git repository + *pattern(str): glob patterns """ # glob directory to find files which match the specified patterns found_files: List[Path] = [] @@ -59,8 +63,12 @@ class Sources: def diff(sources_dir: Path) -> str: """ generate diff from the current version and write it to the output file - :param sources_dir: local path to git repository - :return: patch as plain string + + Args: + sources_dir(Path): local path to git repository + + Returns: + str: patch as plain string """ return Sources._check_output("git", "diff", exception=None, cwd=sources_dir, logger=Sources.logger) @@ -68,8 +76,10 @@ class Sources: def fetch(sources_dir: Path, remote: Optional[str]) -> None: """ either clone repository or update it to origin/`branch` - :param sources_dir: local path to fetch - :param remote: remote target (from where to fetch) + + Args: + sources_dir(Path): local path to fetch + remote(Optional[str]): remote target (from where to fetch) """ # local directory exists and there is .git directory is_initialized_git = (sources_dir / ".git").is_dir() @@ -98,8 +108,12 @@ class Sources: def has_remotes(sources_dir: Path) -> bool: """ check if there are remotes for the repository - :param sources_dir: local path to git repository - :return: True in case if there is any remote and false otherwise + + Args: + sources_dir(Path): local path to git repository + + Returns: + bool: True in case if there is any remote and false otherwise """ remotes = Sources._check_output("git", "remote", exception=None, cwd=sources_dir, logger=Sources.logger) return bool(remotes) @@ -108,7 +122,9 @@ class Sources: def init(sources_dir: Path) -> None: """ create empty git repository at the specified path - :param sources_dir: local path to sources + + Args: + sources_dir(Path): local path to sources """ Sources._check_output("git", "init", "--initial-branch", Sources._branch, exception=None, cwd=sources_dir, logger=Sources.logger) @@ -117,9 +133,11 @@ class Sources: def load(sources_dir: Path, remote: str, patch: Optional[str]) -> None: """ fetch sources from remote and apply patches - :param sources_dir: local path to fetch - :param remote: remote target (from where to fetch) - :param patch: optional patch to be applied + + Args: + sources_dir(Path): local path to fetch + remote(str): remote target (from where to fetch) + patch(Optional[str]): optional patch to be applied """ Sources.fetch(sources_dir, remote) if patch is None: @@ -131,8 +149,10 @@ class Sources: def patch_apply(sources_dir: Path, patch: str) -> None: """ apply patches if any - :param sources_dir: local path to directory with git sources - :param patch: patch to be applied + + Args: + sources_dir(Path): local path to directory with git sources + patch(str): patch to be applied """ # create patch Sources.logger.info("apply patch from database") @@ -143,9 +163,13 @@ class Sources: def patch_create(sources_dir: Path, *pattern: str) -> str: """ create patch set for the specified local path - :param sources_dir: local path to git repository - :param pattern: glob patterns - :return: patch as plain text + + Args: + sources_dir(Path): local path to git repository + *pattern(str): glob patterns + + Returns: + str: patch as plain text """ Sources.add(sources_dir, *pattern) diff = Sources.diff(sources_dir) diff --git a/src/ahriman/core/build_tools/task.py b/src/ahriman/core/build_tools/task.py index 94291436..45625d29 100644 --- a/src/ahriman/core/build_tools/task.py +++ b/src/ahriman/core/build_tools/task.py @@ -35,11 +35,13 @@ from ahriman.models.repository_paths import RepositoryPaths class Task: """ base package build task - :ivar build_logger: logger for build process - :ivar logger: class logger - :ivar package: package definitions - :ivar paths: repository paths instance - :ivar uid: uid of the repository owner user + + Attributes: + build_logger(logging.Logger): logger for build process + logger(logging.Logger): class logger + package(Package): package definitions + paths(RepositoryPaths): repository paths instance + uid(int): uid of the repository owner user """ _check_output = check_output @@ -47,9 +49,11 @@ class Task: def __init__(self, package: Package, configuration: Configuration, paths: RepositoryPaths) -> None: """ default constructor - :param package: package definitions - :param configuration: configuration instance - :param paths: repository paths instance + + Args: + package(Package): package definitions + configuration(Configuration): configuration instance + paths(RepositoryPaths): repository paths instance """ self.logger = logging.getLogger("root") self.build_logger = logging.getLogger("build_details") @@ -65,8 +69,12 @@ class Task: def build(self, sources_path: Path) -> List[Path]: """ run package build - :param sources_path: path to where sources are - :return: paths of produced packages + + Args: + sources_path(Path): path to where sources are + + Returns: + List[Path]: paths of produced packages """ command = [self.build_command, "-r", str(self.paths.chroot)] command.extend(self.archbuild_flags) @@ -91,8 +99,10 @@ class Task: def init(self, path: Path, database: SQLite) -> None: """ fetch package from git - :param path: local path to fetch - :param database: database instance + + Args: + path(Path): local path to fetch + database(SQLite): database instance """ if self.paths.cache_for(self.package.base).is_dir(): # no need to clone whole repository, just copy from cache first diff --git a/src/ahriman/core/configuration.py b/src/ahriman/core/configuration.py index 4f1ec2ef..dcb85447 100644 --- a/src/ahriman/core/configuration.py +++ b/src/ahriman/core/configuration.py @@ -34,12 +34,15 @@ from ahriman.models.repository_paths import RepositoryPaths class Configuration(configparser.RawConfigParser): """ extension for built-in configuration parser - :ivar architecture: repository architecture - :ivar path: path to root configuration file - :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 + + Attributes: + ARCHITECTURE_SPECIFIC_SECTIONS(List[str]): (class attribute) known sections which can be architecture specific. + Required by dump and merging functions + DEFAULT_LOG_FORMAT(str): (class attribute) default log format (in case of fallback) + DEFAULT_LOG_LEVEL(int): (class attribute) default log level (in case of fallback) + SYSTEM_CONFIGURATION_PATH(Path): (class attribute) default system configuration path distributed by package + architecture(Optional[str]): repository architecture + path(Optional[Path]): path to root configuration file """ DEFAULT_LOG_FORMAT = "[%(levelname)s %(asctime)s] [%(filename)s:%(lineno)d %(funcName)s]: %(message)s" @@ -62,21 +65,30 @@ class Configuration(configparser.RawConfigParser): @property def include(self) -> Path: """ - :return: path to directory with configuration includes + get full path to include directory + + Returns: + Path: path to directory with configuration includes """ return self.getpath("settings", "include") @property def logging_path(self) -> Path: """ - :return: path to logging configuration + get full path to logging configuration + + Returns: + Path: path to logging configuration """ return self.getpath("settings", "logging") @property def repository_paths(self) -> RepositoryPaths: """ - :return: repository paths instance + construct RepositoryPaths instance based on the configuration + + Returns: + RepositoryPaths: repository paths instance """ _, architecture = self.check_loaded() return RepositoryPaths(self.getpath("repository", "root"), architecture) @@ -85,10 +97,14 @@ class Configuration(configparser.RawConfigParser): def from_path(cls: Type[Configuration], path: Path, architecture: str, quiet: bool) -> Configuration: """ constructor with full object initialization - :param path: path to root configuration file - :param architecture: repository architecture - :param quiet: force disable any log messages - :return: configuration instance + + Args: + path(Path): path to root configuration file + architecture(str): repository architecture + quiet(bool): force disable any log messages + + Returns: + Configuration: configuration instance """ config = cls() config.load(path) @@ -100,8 +116,15 @@ class Configuration(configparser.RawConfigParser): def __convert_list(value: str) -> List[str]: """ convert string value to list of strings - :param value: string configuration value - :return: list of string from the parsed string + + Args: + value(str): string configuration value + + Returns: + List[str]: list of string from the parsed string + + Raises: + ValueError: in case if option value contains unclosed quotes """ def generator() -> Generator[str, None, None]: quote_mark = None @@ -111,7 +134,7 @@ class Configuration(configparser.RawConfigParser): quote_mark = char elif char == quote_mark: # quoted part ended, reset quotation quote_mark = None - elif char == " " and quote_mark is None: # found space outside of the quotation, yield the word + elif char == " " and quote_mark is None: # found space outside the quotation, yield the word yield word word = "" else: # append character to the buffer @@ -126,17 +149,25 @@ class Configuration(configparser.RawConfigParser): def section_name(section: str, suffix: str) -> str: """ generate section name for sections which depends on context - :param section: section name - :param suffix: session suffix, e.g. repository architecture - :return: correct section name for repository specific section + + Args: + section(str): section name + suffix(str): session suffix, e.g. repository architecture + + Returns: + str: correct section name for repository specific section """ return f"{section}:{suffix}" def __convert_path(self, value: str) -> Path: """ convert string value to path object - :param value: string configuration value - :return: path object which represents the configuration value + + Args: + value(str): string configuration value + + Returns: + Path: path object which represents the configuration value """ path = Path(value) if self.path is None or path.is_absolute(): @@ -146,7 +177,12 @@ class Configuration(configparser.RawConfigParser): def check_loaded(self) -> Tuple[Path, str]: """ check if service was actually loaded - :return: configuration root path and architecture if loaded + + Returns: + Tuple[Path, str]: configuration root path and architecture if loaded + + Raises: + InitializeException: in case if architecture and/or path are not set """ if self.path is None or self.architecture is None: raise InitializeException("Configuration path and/or architecture are not set") @@ -155,7 +191,9 @@ class Configuration(configparser.RawConfigParser): def dump(self) -> Dict[str, Dict[str, str]]: """ dump configuration to dictionary - :return: configuration dump for specific architecture + + Returns: + Dict[str, Dict[str, str]]: configuration dump for specific architecture """ return { section: dict(self[section]) @@ -172,9 +210,16 @@ class Configuration(configparser.RawConfigParser): """ get type variable with fallback to old logic Despite the fact that it has same semantics as other get* methods, but it has different argument list - :param section: section name - :param architecture: repository architecture - :return: section name and found type name + + Args: + section(str): section name + architecture(str): repository architecture + + Returns: + Tuple[str, str]: section name and found type name + + Raises: + configparser.NoSectionError: in case if no section found """ group_type = self.get(section, "type", fallback=None) # new-style logic if group_type is not None: @@ -191,7 +236,9 @@ class Configuration(configparser.RawConfigParser): def load(self, path: Path) -> None: """ fully load configuration - :param path: path to root configuration file + + Args: + path(Path): path to root configuration file """ if not path.is_file(): # fallback to the system file path = self.SYSTEM_CONFIGURATION_PATH @@ -214,7 +261,9 @@ class Configuration(configparser.RawConfigParser): def load_logging(self, quiet: bool) -> None: """ setup logging settings from configuration - :param quiet: force disable any log messages + + Args: + quiet(bool): force disable any log messages """ try: path = self.logging_path @@ -229,7 +278,9 @@ class Configuration(configparser.RawConfigParser): def merge_sections(self, architecture: str) -> None: """ merge architecture specific sections into main configuration - :param architecture: repository architecture + + Args: + architecture(str): repository architecture """ self.architecture = architecture for section in self.ARCHITECTURE_SPECIFIC_SECTIONS: @@ -260,9 +311,11 @@ class Configuration(configparser.RawConfigParser): def set_option(self, section: str, option: str, value: Optional[str]) -> None: """ set option. Unlike default `configparser.RawConfigParser.set` it also creates section if it does not exist - :param section: section name - :param option: option name - :param value: option value as string in parsable format + + Args: + section(str): section name + option(str): option name + value(Optional[str]): option value as string in parsable format """ if not self.has_section(section): self.add_section(section) diff --git a/src/ahriman/core/database/data/__init__.py b/src/ahriman/core/database/data/__init__.py index bf93944e..380bd85f 100644 --- a/src/ahriman/core/database/data/__init__.py +++ b/src/ahriman/core/database/data/__init__.py @@ -31,10 +31,12 @@ def migrate_data(result: MigrationResult, connection: Connection, configuration: Configuration, paths: RepositoryPaths) -> None: """ perform data migration - :param result: result of the schema migration - :param connection: database connection - :param configuration: configuration instance - :param paths: repository paths instance + + Args: + result(MigrationResult): result of the schema migration + connection(Connection): database connection + configuration(Configuration): configuration instance + paths(RepositoryPaths): repository paths instance """ # initial data migration if result.old_version <= 0: diff --git a/src/ahriman/core/database/data/package_statuses.py b/src/ahriman/core/database/data/package_statuses.py index 6671d276..7a766d79 100644 --- a/src/ahriman/core/database/data/package_statuses.py +++ b/src/ahriman/core/database/data/package_statuses.py @@ -29,8 +29,10 @@ from ahriman.models.repository_paths import RepositoryPaths def migrate_package_statuses(connection: Connection, paths: RepositoryPaths) -> None: """ perform migration for package statuses - :param connection: database connection - :param paths: repository paths instance + + Args: + connection(Connection): database connection + paths(RepositoryPaths): repository paths instance """ def insert_base(metadata: Package, last_status: BuildStatus) -> None: connection.execute( diff --git a/src/ahriman/core/database/data/patches.py b/src/ahriman/core/database/data/patches.py index 900a1fa1..487e8bfe 100644 --- a/src/ahriman/core/database/data/patches.py +++ b/src/ahriman/core/database/data/patches.py @@ -25,8 +25,10 @@ from ahriman.models.repository_paths import RepositoryPaths def migrate_patches(connection: Connection, paths: RepositoryPaths) -> None: """ perform migration for patches - :param connection: database connection - :param paths: repository paths instance + + Args: + connection(Connection): database connection + paths(RepositoryPaths): repository paths instance """ root = paths.root / "patches" if not root.is_dir(): diff --git a/src/ahriman/core/database/data/users.py b/src/ahriman/core/database/data/users.py index fbfab632..bd51a8eb 100644 --- a/src/ahriman/core/database/data/users.py +++ b/src/ahriman/core/database/data/users.py @@ -25,8 +25,10 @@ from ahriman.core.configuration import Configuration def migrate_users_data(connection: Connection, configuration: Configuration) -> None: """ perform migration for users - :param connection: database connection - :param configuration: configuration instance + + Args: + connection(Connection): database connection + configuration(Configuration): configuration instance """ for section in configuration.sections(): for option, value in configuration[section].items(): diff --git a/src/ahriman/core/database/migrations/__init__.py b/src/ahriman/core/database/migrations/__init__.py index ebd53581..8d7597f4 100644 --- a/src/ahriman/core/database/migrations/__init__.py +++ b/src/ahriman/core/database/migrations/__init__.py @@ -35,14 +35,18 @@ class Migrations: """ simple migration wrapper for the sqlite idea comes from https://www.ash.dev/blog/simple-migration-system-in-sqlite/ - :ivar connection: database connection - :ivar logger: class logger + + Attributes: + connection(Connection): database connection + logger(logging.Logger): class logger """ def __init__(self, connection: Connection) -> None: """ default constructor - :param connection: database connection + + Args: + connection(Connection): database connection """ self.connection = connection self.logger = logging.getLogger("database") @@ -51,8 +55,12 @@ class Migrations: def migrate(cls: Type[Migrations], connection: Connection) -> MigrationResult: """ perform migrations implicitly - :param connection: database connection - :return: current schema version + + Args: + connection(Connection): database connection + + Returns: + MigrationResult: current schema version """ return cls(connection).run() @@ -61,6 +69,8 @@ class Migrations: extract all migrations from the current package idea comes from https://julienharbulot.com/python-dynamical-import.html + Returns: + List[Migration]: list of found migrations """ migrations: List[Migration] = [] package_dir = Path(__file__).resolve().parent @@ -77,7 +87,9 @@ class Migrations: def run(self) -> MigrationResult: """ perform migrations - :return: current schema version + + Return: + MigrationResult: current schema version """ migrations = self.migrations() current_version = self.user_version() @@ -118,7 +130,9 @@ class Migrations: def user_version(self) -> int: """ get schema version from sqlite database - ;return: current schema version + + Returns: + int: current schema version """ cursor = self.connection.execute("pragma user_version") current_version: int = cursor.fetchone()["user_version"] diff --git a/src/ahriman/core/database/operations/auth_operations.py b/src/ahriman/core/database/operations/auth_operations.py index bd6c97fc..86454003 100644 --- a/src/ahriman/core/database/operations/auth_operations.py +++ b/src/ahriman/core/database/operations/auth_operations.py @@ -33,17 +33,25 @@ class AuthOperations(Operations): def user_get(self, username: str) -> Optional[User]: """ get user by username - :param username: username - :return: user if it was found + + Args: + username(str): username + + Returns: + Optional[User]: user if it was found """ return next(iter(self.user_list(username, None)), None) def user_list(self, username: Optional[str], access: Optional[UserAccess]) -> List[User]: """ get users by filter - :param username: optional filter by username - :param access: optional filter by role - :return: list of users who match criteria + + Args: + username(Optional[str]): optional filter by username + access(Optional[UserAccess]): optional filter by role + + Returns: + List[User]: list of users who match criteria """ username_filter = username.lower() if username is not None else username access_filter = access.value if access is not None else access @@ -64,7 +72,9 @@ class AuthOperations(Operations): def user_remove(self, username: str) -> None: """ remove user from storage - :param username: username + + Args: + username(str): username """ def run(connection: Connection) -> None: connection.execute("""delete from users where username = :username""", {"username": username.lower()}) @@ -74,7 +84,9 @@ class AuthOperations(Operations): def user_update(self, user: User) -> None: """ update user by username - :param user: user descriptor + + Args: + user(User): user descriptor """ def run(connection: Connection) -> None: connection.execute( diff --git a/src/ahriman/core/database/operations/build_operations.py b/src/ahriman/core/database/operations/build_operations.py index c2636b19..65d2bcd7 100644 --- a/src/ahriman/core/database/operations/build_operations.py +++ b/src/ahriman/core/database/operations/build_operations.py @@ -32,7 +32,9 @@ class BuildOperations(Operations): def build_queue_clear(self, package_base: Optional[str]) -> None: """ remove packages from build queue - :param package_base: optional filter by package base + + Args: + package_base(Optional[str]): optional filter by package base """ def run(connection: Connection) -> None: connection.execute( @@ -47,7 +49,9 @@ class BuildOperations(Operations): def build_queue_get(self) -> List[Package]: """ retrieve packages from build queue - :return: list of packages to be built + + Return: + List[Package]: list of packages to be built """ def run(connection: Connection) -> List[Package]: return [ @@ -60,7 +64,9 @@ class BuildOperations(Operations): def build_queue_insert(self, package: Package) -> None: """ insert packages to build queue - :param package: package to be inserted + + Args: + package(Package): package to be inserted """ def run(connection: Connection) -> None: connection.execute( diff --git a/src/ahriman/core/database/operations/operations.py b/src/ahriman/core/database/operations/operations.py index b36e1243..5e984e9d 100644 --- a/src/ahriman/core/database/operations/operations.py +++ b/src/ahriman/core/database/operations/operations.py @@ -31,14 +31,18 @@ T = TypeVar("T") class Operations: """ base operation class - :ivar logger: class logger - :ivar path: path to the database file + + Attributes: + logger(logging.Logger): class logger + path(Path): path to the database file """ def __init__(self, path: Path) -> None: """ default constructor - :param path: path to the database file + + Args: + path(Path): path to the database file """ self.path = path self.logger = logging.getLogger("database") @@ -47,9 +51,13 @@ class Operations: def factory(cursor: Cursor, row: Tuple[Any, ...]) -> Dict[str, Any]: """ dictionary factory based on official documentation - :param cursor: cursor descriptor - :param row: fetched row - :return: row converted to dictionary + + Args: + cursor(Cursor): cursor descriptor + row(Tuple[Any, ...]): fetched row + + Returns: + Dict[str, Any]: row converted to dictionary """ result = {} for index, column in enumerate(cursor.description): @@ -59,9 +67,13 @@ class Operations: def with_connection(self, query: Callable[[Connection], T], commit: bool = False) -> T: """ perform operation in connection - :param query: function to be called with connection - :param commit: if True commit() will be called on success - :return: result of the `query` call + + Args: + query(Callable[[Connection], T]): function to be called with connection + commit(bool, optional): if True commit() will be called on success (Default value = False) + + Returns: + T: result of the `query` call """ with sqlite3.connect(self.path, detect_types=sqlite3.PARSE_DECLTYPES) as connection: connection.row_factory = self.factory diff --git a/src/ahriman/core/database/operations/package_operations.py b/src/ahriman/core/database/operations/package_operations.py index 93624876..421bba3e 100644 --- a/src/ahriman/core/database/operations/package_operations.py +++ b/src/ahriman/core/database/operations/package_operations.py @@ -35,8 +35,10 @@ class PackageOperations(Operations): def _package_remove_package_base(connection: Connection, package_base: str) -> None: """ remove package base information - :param connection: database connection - :param package_base: package base name + + Args: + connection(Connection): database connection + package_base(str): package base name """ connection.execute("""delete from package_statuses where package_base = :package_base""", {"package_base": package_base}) @@ -47,9 +49,11 @@ class PackageOperations(Operations): def _package_remove_packages(connection: Connection, package_base: str, current_packages: Iterable[str]) -> None: """ remove packages belong to the package base - :param connection: database connection - :param package_base: package base name - :param current_packages: current packages list which has to be left in database + + Args: + connection(Connection): database connection + package_base(str): package base name + current_packages(Iterable[str]): current packages list which has to be left in database """ packages = [ package @@ -63,8 +67,10 @@ class PackageOperations(Operations): def _package_update_insert_base(connection: Connection, package: Package) -> None: """ insert base package into table - :param connection: database connection - :param package: package properties + + Args: + connection(Connection): database connection + package(Package): package properties """ connection.execute( """ @@ -81,8 +87,10 @@ class PackageOperations(Operations): def _package_update_insert_packages(connection: Connection, package: Package) -> None: """ insert packages into table - :param connection: database connection - :param package: package properties + + Args: + connection(Connection): database connection + package(Package): package properties """ package_list = [] for name, description in package.packages.items(): @@ -108,9 +116,11 @@ class PackageOperations(Operations): def _package_update_insert_status(connection: Connection, package_base: str, status: BuildStatus) -> None: """ insert base package status into table - :param connection: database connection - :param package_base: package base name - :param status: new build status + + Args: + connection(Connection): database connection + package_base(str): package base name + status(BuildStatus): new build status """ connection.execute( """ @@ -126,8 +136,12 @@ class PackageOperations(Operations): def _packages_get_select_package_bases(connection: Connection) -> Dict[str, Package]: """ select package bases from the table - :param connection: database connection - :return: map of the package base to its descriptor (without packages themselves) + + Args: + connection(Connection): database connection + + Returns: + Dict[str, Package]: map of the package base to its descriptor (without packages themselves) """ return { row["package_base"]: Package(row["package_base"], row["version"], row["aur_url"], {}) @@ -138,9 +152,13 @@ class PackageOperations(Operations): def _packages_get_select_packages(connection: Connection, packages: Dict[str, Package]) -> Dict[str, Package]: """ select packages from the table - :param connection: database connection - :param packages: packages descriptor map - :return: map of the package base to its descriptor including individual packages + + Args: + connection(Connection): database connection + packages(Dict[str, Package]): packages descriptor map + + Returns: + Dict[str, Package]: map of the package base to its descriptor including individual packages """ for row in connection.execute("""select * from packages"""): if row["package_base"] not in packages: @@ -152,8 +170,12 @@ class PackageOperations(Operations): def _packages_get_select_statuses(connection: Connection) -> Dict[str, BuildStatus]: """ select package build statuses from the table - :param connection: database connection - :return: map of the package base to its status + + Args: + connection(Connection): database connection + + Returns: + Dict[str, BuildStatus]: map of the package base to its status """ return { row["package_base"]: BuildStatus.from_json({"status": row["status"], "timestamp": row["last_updated"]}) @@ -163,7 +185,9 @@ class PackageOperations(Operations): def package_remove(self, package_base: str) -> None: """ remove package from database - :param package_base: package base name + + Args: + package_base(str): package base name """ def run(connection: Connection) -> None: self._package_remove_packages(connection, package_base, []) @@ -174,8 +198,10 @@ class PackageOperations(Operations): def package_update(self, package: Package, status: BuildStatus) -> None: """ update package status - :param package: package properties - :param status: new build status + + Args: + package(Package): package properties + status(BuildStatus): new build status """ def run(connection: Connection) -> None: self._package_update_insert_base(connection, package) @@ -188,7 +214,9 @@ class PackageOperations(Operations): def packages_get(self) -> List[Tuple[Package, BuildStatus]]: """ get package list and their build statuses from database - :return: list of package properties and their statuses + + Return: + List[Tuple[Package, BuildStatus]]: list of package properties and their statuses """ def run(connection: Connection) -> Generator[Tuple[Package, BuildStatus], None, None]: packages = self._packages_get_select_package_bases(connection) diff --git a/src/ahriman/core/database/operations/patch_operations.py b/src/ahriman/core/database/operations/patch_operations.py index a55ea8f5..c18d569e 100644 --- a/src/ahriman/core/database/operations/patch_operations.py +++ b/src/ahriman/core/database/operations/patch_operations.py @@ -31,16 +31,22 @@ class PatchOperations(Operations): def patches_get(self, package_base: str) -> Optional[str]: """ retrieve patches for the package - :param package_base: package base to search for patches - :return: plain text patch for the package + + Args: + package_base(str): package base to search for patches + + Returns: + Optional[str]: plain text patch for the package """ return self.patches_list(package_base).get(package_base) def patches_insert(self, package_base: str, patch: str) -> None: """ insert or update patch in database - :param package_base: package base to insert - :param patch: patch content + + Args: + package_base(str): package base to insert + patch(str): patch content """ def run(connection: Connection) -> None: connection.execute( @@ -59,8 +65,12 @@ class PatchOperations(Operations): def patches_list(self, package_base: Optional[str]) -> Dict[str, str]: """ extract all patches - :param package_base: optional filter by package base - :return: map of package base to patch content + + Args: + package_base(Optional[str]): optional filter by package base + + Returns: + Dict[str, str]: map of package base to patch content """ def run(connection: Connection) -> Dict[str, str]: return { @@ -75,7 +85,9 @@ class PatchOperations(Operations): def patches_remove(self, package_base: str) -> None: """ remove patch set - :param package_base: package base to clear patches + + Args: + package_base(str): package base to clear patches """ def run(connection: Connection) -> None: connection.execute( diff --git a/src/ahriman/core/database/sqlite.py b/src/ahriman/core/database/sqlite.py index 433bab1d..1d3505dd 100644 --- a/src/ahriman/core/database/sqlite.py +++ b/src/ahriman/core/database/sqlite.py @@ -44,8 +44,12 @@ class SQLite(AuthOperations, BuildOperations, PackageOperations, PatchOperations def load(cls: Type[SQLite], configuration: Configuration) -> SQLite: """ construct instance from configuration - :param configuration: configuration instance - :return: fully initialized instance of the database + + Args: + configuration(Configuration): configuration instance + + Returns: + SQLite: fully initialized instance of the database """ path = cls.database_path(configuration) database = cls(path) @@ -56,15 +60,21 @@ class SQLite(AuthOperations, BuildOperations, PackageOperations, PatchOperations def database_path(configuration: Configuration) -> Path: """ read database from configuration - :param configuration: configuration instance - :return: database path according to the configuration + + Args: + configuration(Configuration): configuration instance + + Returns: + Path: database path according to the configuration """ return configuration.getpath("settings", "database") def init(self, configuration: Configuration) -> None: """ perform database migrations - :param configuration: configuration instance + + Args: + configuration(Configuration): configuration instance """ # custom types support sqlite3.register_adapter(dict, json.dumps) diff --git a/src/ahriman/core/exceptions.py b/src/ahriman/core/exceptions.py index b4419cb1..8baf67f2 100644 --- a/src/ahriman/core/exceptions.py +++ b/src/ahriman/core/exceptions.py @@ -29,7 +29,9 @@ class BuildFailed(RuntimeError): def __init__(self, package_base: str) -> None: """ default constructor - :param package_base: package base raised exception + + Args: + package_base(str): package base raised exception """ RuntimeError.__init__(self, f"Package {package_base} build failed, check logs for details") @@ -61,7 +63,9 @@ class InitializeException(RuntimeError): def __init__(self, details: str) -> None: """ default constructor - :param details: details of the exception + + Args: + details(str): details of the exception """ RuntimeError.__init__(self, f"Could not load service: {details}") @@ -74,7 +78,9 @@ class InvalidOption(ValueError): def __init__(self, value: Any) -> None: """ default constructor - :param value: option value + + Args: + value(Any): option value """ ValueError.__init__(self, f"Invalid or unknown option value `{value}`") @@ -87,8 +93,10 @@ class InvalidPath(ValueError): def __init__(self, path: Path, root: Path) -> None: """ default constructor - :param path: path which raised an exception - :param root: repository root (i.e. ahriman home) + + Args: + path(Path): path which raised an exception + root(Path): repository root (i.e. ahriman home) """ ValueError.__init__(self, f"Path `{path}` does not belong to repository root `{root}`") @@ -101,7 +109,9 @@ class InvalidPackageInfo(RuntimeError): def __init__(self, details: Any) -> None: """ default constructor - :param details: error details + + Args: + details(Any): error details """ RuntimeError.__init__(self, f"There are errors during reading package information: `{details}`") @@ -114,7 +124,9 @@ class MigrationError(RuntimeError): def __init__(self, details: str) -> None: """ default constructor - :param details: error details + + Args: + details(str): error details """ RuntimeError.__init__(self, details) @@ -127,7 +139,9 @@ class MissingArchitecture(ValueError): def __init__(self, command: str) -> None: """ default constructor - :param command: command name which throws exception + + Args: + command(str): command name which throws exception """ ValueError.__init__(self, f"Architecture required for subcommand {command}, but missing") @@ -140,7 +154,9 @@ class MultipleArchitectures(ValueError): def __init__(self, command: str) -> None: """ default constructor - :param command: command name which throws exception + + Args: + command(str): command name which throws exception """ ValueError.__init__(self, f"Multiple architectures are not supported by subcommand {command}") @@ -165,7 +181,9 @@ class SuccessFailed(ValueError): def __init__(self, package_base: str) -> None: """ default constructor - :param package_base: package base name + + Args: + package_base(str): package base name """ ValueError.__init__(self, f"Package base {package_base} had status failed, but new status is success") @@ -190,7 +208,9 @@ class UnknownPackage(ValueError): def __init__(self, package_base: str) -> None: """ default constructor - :param package_base: package base name + + Args: + package_base(str): package base name """ ValueError.__init__(self, f"Package base {package_base} is unknown") @@ -203,8 +223,10 @@ class UnsafeRun(RuntimeError): def __init__(self, current_uid: int, root_uid: int) -> None: """ default constructor - :param current_uid: current user ID - :param root_uid: ID of the owner of root directory + + Args: + current_uid(int): current user ID + root_uid(int): ID of the owner of root directory """ RuntimeError.__init__(self, f"Current UID {current_uid} differs from root owner {root_uid}. " f"Note that for the most actions it is unsafe to run application as different user." diff --git a/src/ahriman/core/formatters/aur_printer.py b/src/ahriman/core/formatters/aur_printer.py index dc7d411f..cafb389f 100644 --- a/src/ahriman/core/formatters/aur_printer.py +++ b/src/ahriman/core/formatters/aur_printer.py @@ -28,13 +28,17 @@ from ahriman.models.property import Property class AurPrinter(StringPrinter): """ print content of the AUR package - :ivar package: AUR package description + + Attributes: + package(AURPackage): AUR package description """ def __init__(self, package: AURPackage) -> None: """ default constructor - :param package: AUR package description + + Args: + package(AURPackage): AUR package description """ StringPrinter.__init__(self, f"{package.name} {package.version} ({package.num_votes})") self.package = package @@ -42,7 +46,9 @@ class AurPrinter(StringPrinter): def properties(self) -> List[Property]: """ convert content into printable data - :return: list of content properties + + Returns: + List[Property]: list of content properties """ return [ Property("Package base", self.package.package_base), diff --git a/src/ahriman/core/formatters/build_printer.py b/src/ahriman/core/formatters/build_printer.py index dad9e2de..e510c1e5 100644 --- a/src/ahriman/core/formatters/build_printer.py +++ b/src/ahriman/core/formatters/build_printer.py @@ -29,9 +29,11 @@ class BuildPrinter(StringPrinter): def __init__(self, package: Package, is_success: bool, use_utf: bool) -> None: """ default constructor - :param package: built package - :param is_success: True in case if build has success status and False otherwise - :param use_utf: use utf instead of normal symbols + + Args: + package(Package): built package + is_success(bool): True in case if build has success status and False otherwise + use_utf(bool): use utf instead of normal symbols """ StringPrinter.__init__(self, f"{self.sign(is_success, use_utf)} {package.base}") @@ -39,9 +41,13 @@ class BuildPrinter(StringPrinter): def sign(is_success: bool, use_utf: bool) -> str: """ generate sign according to settings - :param use_utf: use utf instead of normal symbols - :param is_success: True in case if build has success status and False otherwise - :return: sign symbol according to current settings + + Args: + is_success(bool): True in case if build has success status and False otherwise + use_utf(bool): use utf instead of normal symbols + + Returns: + str: sign symbol according to current settings """ if is_success: return "[✔]" if use_utf else "[x]" diff --git a/src/ahriman/core/formatters/configuration_printer.py b/src/ahriman/core/formatters/configuration_printer.py index 98a161ee..e975949e 100644 --- a/src/ahriman/core/formatters/configuration_printer.py +++ b/src/ahriman/core/formatters/configuration_printer.py @@ -26,14 +26,18 @@ from ahriman.models.property import Property class ConfigurationPrinter(StringPrinter): """ print content of the configuration section - :ivar values: configuration values dictionary + + Attributes: + values(Dict[str, str]): configuration values dictionary """ def __init__(self, section: str, values: Dict[str, str]) -> None: """ default constructor - :param section: section name - :param values: configuration values dictionary + + Args: + section(str): section name + values(Dict[str, str]): configuration values dictionary """ StringPrinter.__init__(self, f"[{section}]") self.values = values @@ -41,7 +45,9 @@ class ConfigurationPrinter(StringPrinter): def properties(self) -> List[Property]: """ convert content into printable data - :return: list of content properties + + Returns: + List[Property]: list of content properties """ return [ Property(key, value, is_required=True) diff --git a/src/ahriman/core/formatters/package_printer.py b/src/ahriman/core/formatters/package_printer.py index ea9397e5..f27090e1 100644 --- a/src/ahriman/core/formatters/package_printer.py +++ b/src/ahriman/core/formatters/package_printer.py @@ -28,15 +28,19 @@ from ahriman.models.property import Property class PackagePrinter(StringPrinter): """ print content of the internal package object - :ivar package: package description - :ivar status: build status + + Attributes: + package(Package): package description + status(BuildStatus): build status """ def __init__(self, package: Package, status: BuildStatus) -> None: """ default constructor - :param package: package description - :param status: build status + + Args: + package(Package): package description + status(BuildStatus): build status """ StringPrinter.__init__(self, package.pretty_print()) self.package = package @@ -45,7 +49,9 @@ class PackagePrinter(StringPrinter): def properties(self) -> List[Property]: """ convert content into printable data - :return: list of content properties + + Returns: + List[Property]: list of content properties """ return [ Property("Version", self.package.version, is_required=True), diff --git a/src/ahriman/core/formatters/printer.py b/src/ahriman/core/formatters/printer.py index 7975326a..ab950528 100644 --- a/src/ahriman/core/formatters/printer.py +++ b/src/ahriman/core/formatters/printer.py @@ -30,9 +30,12 @@ class Printer: def print(self, verbose: bool, log_fn: Callable[[str], None] = print, separator: str = ": ") -> None: """ print content - :param verbose: print all fields - :param log_fn: logger function to log data - :param separator: separator for property name and property value + + Args: + verbose(bool): print all fields + log_fn(Callable[[str]): logger function to log data + None]: (Default value = print) + separator(str, optional): separator for property name and property value (Default value = ": ") """ if (title := self.title()) is not None: log_fn(title) @@ -44,12 +47,16 @@ class Printer: def properties(self) -> List[Property]: # pylint: disable=no-self-use """ convert content into printable data - :return: list of content properties + + Returns: + List[Property]: list of content properties """ return [] def title(self) -> Optional[str]: """ generate entry title from content - :return: content title if it can be generated and None otherwise + + Returns: + Optional[str]: content title if it can be generated and None otherwise """ diff --git a/src/ahriman/core/formatters/status_printer.py b/src/ahriman/core/formatters/status_printer.py index b8f5e910..6c754fd9 100644 --- a/src/ahriman/core/formatters/status_printer.py +++ b/src/ahriman/core/formatters/status_printer.py @@ -29,6 +29,8 @@ class StatusPrinter(StringPrinter): def __init__(self, status: BuildStatus) -> None: """ default constructor - :param status: build status + + Args: + status(BuildStatus): build status """ StringPrinter.__init__(self, status.pretty_print()) diff --git a/src/ahriman/core/formatters/string_printer.py b/src/ahriman/core/formatters/string_printer.py index 782bfff1..8c32af86 100644 --- a/src/ahriman/core/formatters/string_printer.py +++ b/src/ahriman/core/formatters/string_printer.py @@ -30,13 +30,17 @@ class StringPrinter(Printer): def __init__(self, content: str) -> None: """ default constructor - :param content: any content string + + Args: + content(str): any content string """ self.content = content def title(self) -> Optional[str]: """ generate entry title from content - :return: content title if it can be generated and None otherwise + + Returns: + Optional[str]: content title if it can be generated and None otherwise """ return self.content diff --git a/src/ahriman/core/formatters/update_printer.py b/src/ahriman/core/formatters/update_printer.py index 35d4f6ca..d43b1006 100644 --- a/src/ahriman/core/formatters/update_printer.py +++ b/src/ahriman/core/formatters/update_printer.py @@ -27,15 +27,19 @@ from ahriman.models.property import Property class UpdatePrinter(StringPrinter): """ print content of the package update - :ivar package: remote (new) package object - :ivar local_version: local version of the package if any + + Attributes: + package(Package): remote (new) package object + local_version(Optional[str]): local version of the package if any """ def __init__(self, remote: Package, local_version: Optional[str]) -> None: """ default constructor - :param remote: remote (new) package object - :param local_version: local version of the package if any + + Args: + remote(Package): remote (new) package object + local_version(Optional[str]): local version of the package if any """ StringPrinter.__init__(self, remote.base) self.package = remote @@ -44,6 +48,8 @@ class UpdatePrinter(StringPrinter): def properties(self) -> List[Property]: """ convert content into printable data - :return: list of content properties + + Returns: + List[Property]: list of content properties """ return [Property(self.local_version, self.package.version, is_required=True)] diff --git a/src/ahriman/core/formatters/user_printer.py b/src/ahriman/core/formatters/user_printer.py index 6a2f930d..c7c46fd1 100644 --- a/src/ahriman/core/formatters/user_printer.py +++ b/src/ahriman/core/formatters/user_printer.py @@ -27,13 +27,17 @@ from ahriman.models.user import User class UserPrinter(StringPrinter): """ print properties of user - :ivar user: stored user + + Attributes: + user(User): stored user """ def __init__(self, user: User) -> None: """ default constructor - :param user: user to print + + Args: + user(User): user to print """ StringPrinter.__init__(self, user.username) self.user = user @@ -41,6 +45,8 @@ class UserPrinter(StringPrinter): def properties(self) -> List[Property]: """ convert content into printable data - :return: list of content properties + + Returns: + List[Property]: list of content properties """ return [Property("role", self.user.access.value, is_required=True)] diff --git a/src/ahriman/core/report/console.py b/src/ahriman/core/report/console.py index d628ab00..f8cd9681 100644 --- a/src/ahriman/core/report/console.py +++ b/src/ahriman/core/report/console.py @@ -29,15 +29,19 @@ from ahriman.models.result import Result class Console(Report): """ html report generator - :ivar use_utf: print utf8 symbols instead of ASCII + + Attributes: + use_utf(bool): print utf8 symbols instead of ASCII """ def __init__(self, architecture: str, configuration: Configuration, section: str) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance - :param section: settings section name + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + section(str): settings section name """ Report.__init__(self, architecture, configuration) self.use_utf = configuration.getboolean(section, "use_utf", fallback=True) @@ -45,8 +49,10 @@ class Console(Report): def generate(self, packages: Iterable[Package], result: Result) -> None: """ generate report for the specified packages - :param packages: list of packages to generate report - :param result: build result + + Args: + packages(Iterable[Package]): list of packages to generate report + result(Result): build result """ for package in result.success: BuildPrinter(package, is_success=True, use_utf=self.use_utf).print(verbose=True) diff --git a/src/ahriman/core/report/email.py b/src/ahriman/core/report/email.py index 73187e7e..1b624437 100644 --- a/src/ahriman/core/report/email.py +++ b/src/ahriman/core/report/email.py @@ -36,24 +36,28 @@ from ahriman.models.smtp_ssl_settings import SmtpSSLSettings class Email(Report, JinjaTemplate): """ email report generator - :ivar full_template_path: path to template for full package list - :ivar host: SMTP host to connect - :ivar no_empty_report: skip empty report generation - :ivar password: password to authenticate via SMTP - :ivar port: SMTP port to connect - :ivar receivers: list of receivers emails - :ivar sender: sender email address - :ivar ssl: SSL mode for SMTP connection - :ivar template_path: path to template for built packages - :ivar user: username to authenticate via SMTP + + Attributes: + full_template_path(Path): path to template for full package list + host(str): SMTP host to connect + no_empty_report(bool): skip empty report generation + password(Optional[str]): password to authenticate via SMTP + port(int): SMTP port to connect + receivers(List[str]): list of receivers emails + sender(str): sender email address + ssl(SmtpSSLSettings): SSL mode for SMTP connection + template_path(Path): path to template for built packages + user(Optional[str]): username to authenticate via SMTP """ def __init__(self, architecture: str, configuration: Configuration, section: str) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance - :param section: settings section name + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + section(str): settings section name """ Report.__init__(self, architecture, configuration) JinjaTemplate.__init__(self, section, configuration) @@ -74,8 +78,10 @@ class Email(Report, JinjaTemplate): def _send(self, text: str, attachment: Dict[str, str]) -> None: """ send email callback - :param text: email body text - :param attachment: map of attachment filename to attachment content + + Args: + text(str): email body text + attachment(Dict[str, str]): map of attachment filename to attachment content """ message = MIMEMultipart() message["From"] = self.sender @@ -102,8 +108,10 @@ class Email(Report, JinjaTemplate): def generate(self, packages: Iterable[Package], result: Result) -> None: """ generate report for the specified packages - :param packages: list of packages to generate report - :param result: build result + + Args: + packages(Iterable[Package]): list of packages to generate report + result(Result): build result """ if self.no_empty_report and not result.success: return diff --git a/src/ahriman/core/report/html.py b/src/ahriman/core/report/html.py index 36a67949..8162acdf 100644 --- a/src/ahriman/core/report/html.py +++ b/src/ahriman/core/report/html.py @@ -29,16 +29,20 @@ from ahriman.models.result import Result class HTML(Report, JinjaTemplate): """ html report generator - :ivar report_path: output path to html report - :ivar template_path: path to template for full package list + + Attributes: + report_path(Path): output path to html report + template_path(Path): path to template for full package list """ def __init__(self, architecture: str, configuration: Configuration, section: str) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance - :param section: settings section name + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + section(str): settings section name """ Report.__init__(self, architecture, configuration) JinjaTemplate.__init__(self, section, configuration) @@ -49,8 +53,10 @@ class HTML(Report, JinjaTemplate): def generate(self, packages: Iterable[Package], result: Result) -> None: """ generate report for the specified packages - :param packages: list of packages to generate report - :param result: build result + + Args: + packages(Iterable[Package]): list of packages to generate report + result(Result): build result """ html = self.make_html(Result(success=packages), self.template_path) self.report_path.write_text(html) diff --git a/src/ahriman/core/report/jinja_template.py b/src/ahriman/core/report/jinja_template.py index d2823b65..1beb499c 100644 --- a/src/ahriman/core/report/jinja_template.py +++ b/src/ahriman/core/report/jinja_template.py @@ -35,38 +35,41 @@ class JinjaTemplate: It uses jinja2 templates for report generation, the following variables are allowed: - homepage - link to homepage, string, optional - link_path - prefix fo packages to download, string, required - has_package_signed - True in case if package sign enabled, False otherwise, required - has_repo_signed - True in case if repository database sign enabled, False otherwise, required - packages - sorted list of packages properties, required - * architecture, string - * archive_size, pretty printed size, string - * build_date, pretty printed datetime, string - * depends, sorted list of strings - * description, string - * filename, string, - * groups, sorted list of strings - * installed_size, pretty printed datetime, string - * licenses, sorted list of strings - * name, string - * url, string - * version, string - pgp_key - default PGP key ID, string, optional - repository - repository name, string, required + * homepage - link to homepage, string, optional + * link_path - prefix fo packages to download, string, required + * has_package_signed - True in case if package sign enabled, False otherwise, required + * has_repo_signed - True in case if repository database sign enabled, False otherwise, required + * packages - sorted list of packages properties, required + * architecture, string + * archive_size, pretty printed size, string + * build_date, pretty printed datetime, string + * depends, sorted list of strings + * description, string + * filename, string, + * groups, sorted list of strings + * installed_size, pretty printed datetime, string + * licenses, sorted list of strings + * name, string + * url, string + * version, string + * pgp_key - default PGP key ID, string, optional + * repository - repository name, string, required - :ivar homepage: homepage link if any (for footer) - :ivar link_path: prefix fo packages to download - :ivar name: repository name - :ivar default_pgp_key: default PGP key - :ivar sign_targets: targets to sign enabled in configuration + Attributes: + homepage(Optional[str]): homepage link if any (for footer) + link_path(str): prefix fo packages to download + name(str): repository name + default_pgp_key(Optional[str]): default PGP key + sign_targets(Set[SignSettings]): targets to sign enabled in configuration """ def __init__(self, section: str, configuration: Configuration) -> None: """ default constructor - :param section: settings section name - :param configuration: configuration instance + + Args: + section(str): settings section name + configuration(Configuration): configuration instance """ self.link_path = configuration.get(section, "link_path") @@ -79,8 +82,10 @@ class JinjaTemplate: def make_html(self, result: Result, template_path: Path) -> str: """ generate report for the specified packages - :param result: build result - :param template_path: path to jinja template + + Args: + result(Result): build result + template_path(Path): path to jinja template """ # idea comes from https://stackoverflow.com/a/38642558 loader = jinja2.FileSystemLoader(searchpath=template_path.parent) diff --git a/src/ahriman/core/report/report.py b/src/ahriman/core/report/report.py index 0298c9f1..a744a6fa 100644 --- a/src/ahriman/core/report/report.py +++ b/src/ahriman/core/report/report.py @@ -33,16 +33,20 @@ from ahriman.models.result import Result class Report: """ base report generator - :ivar architecture: repository architecture - :ivar configuration: configuration instance - :ivar logger: class logger + + Attributes: + architecture(str): repository architecture + configuration(Configuration): configuration instance + logger(logging.Logger): class logger """ def __init__(self, architecture: str, configuration: Configuration) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance """ self.logger = logging.getLogger("root") self.architecture = architecture @@ -52,10 +56,14 @@ class Report: def load(cls: Type[Report], architecture: str, configuration: Configuration, target: str) -> Report: """ load client from settings - :param architecture: repository architecture - :param configuration: configuration instance - :param target: target to generate report aka section name (e.g. html) - :return: client according to current settings + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + target(str): target to generate report aka section name (e.g. html) + + Returns: + Report: client according to current settings """ section, provider_name = configuration.gettype(target, architecture) provider = ReportSettings.from_option(provider_name) @@ -76,15 +84,22 @@ class Report: def generate(self, packages: Iterable[Package], result: Result) -> None: """ generate report for the specified packages - :param packages: list of packages to generate report - :param result: build result + + Args: + packages(Iterable[Package]): list of packages to generate report + result(Result): build result """ def run(self, packages: Iterable[Package], result: Result) -> None: """ run report generation - :param packages: list of packages to generate report - :param result: build result + + Args: + packages(Iterable[Package]): list of packages to generate report + result(Result): build result + + Raises: + ReportFailed: in case of any report unmatched exception """ try: self.generate(packages, result) diff --git a/src/ahriman/core/report/telegram.py b/src/ahriman/core/report/telegram.py index ff301d6e..7e17a0b1 100644 --- a/src/ahriman/core/report/telegram.py +++ b/src/ahriman/core/report/telegram.py @@ -33,12 +33,14 @@ from ahriman.models.result import Result class Telegram(Report, JinjaTemplate): """ telegram report generator - :cvar TELEGRAM_API_URL: telegram api base url - :cvar TELEGRAM_MAX_CONTENT_LENGTH: max content length of the message - :ivar api_key: bot api key - :ivar chat_id: chat id to post message, either string with @ or integer - :ivar template_path: path to template for built packages - :ivar template_type: template message type to be used in parse mode, one of MarkdownV2, HTML, Markdown + + Attributes: + TELEGRAM_API_URL(str): (class attribute) telegram api base url + TELEGRAM_MAX_CONTENT_LENGTH(int): (class attribute) max content length of the message + api_key(str): bot api key + chat_id(str): chat id to post message, either string with @ or integer + template_path(Path): path to template for built packages + template_type(str): template message type to be used in parse mode, one of MarkdownV2, HTML, Markdown """ TELEGRAM_API_URL = "https://api.telegram.org" @@ -47,9 +49,11 @@ class Telegram(Report, JinjaTemplate): def __init__(self, architecture: str, configuration: Configuration, section: str) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance - :param section: settings section name + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + section(str): settings section name """ Report.__init__(self, architecture, configuration) JinjaTemplate.__init__(self, section, configuration) @@ -62,7 +66,9 @@ class Telegram(Report, JinjaTemplate): def _send(self, text: str) -> None: """ send message to telegram channel - :param text: message body text + + Args: + text(str): message body text """ try: response = requests.post( @@ -79,8 +85,10 @@ class Telegram(Report, JinjaTemplate): def generate(self, packages: Iterable[Package], result: Result) -> None: """ generate report for the specified packages - :param packages: list of packages to generate report - :param result: build result + + Args: + packages(Iterable[Package]): list of packages to generate report + result(Result): build result """ if not result.success: return diff --git a/src/ahriman/core/repository/cleaner.py b/src/ahriman/core/repository/cleaner.py index 838644f0..13dd51b5 100644 --- a/src/ahriman/core/repository/cleaner.py +++ b/src/ahriman/core/repository/cleaner.py @@ -33,7 +33,12 @@ class Cleaner(Properties): def packages_built(self) -> List[Path]: """ get list of files in built packages directory - :return: list of filenames from the directory + + Returns: + List[Path]: list of filenames from the directory + + Raises: + NotImplementedError: not implemented method """ raise NotImplementedError diff --git a/src/ahriman/core/repository/executor.py b/src/ahriman/core/repository/executor.py index 371fbb76..d4efb884 100644 --- a/src/ahriman/core/repository/executor.py +++ b/src/ahriman/core/repository/executor.py @@ -39,23 +39,39 @@ class Executor(Cleaner): def load_archives(self, packages: Iterable[Path]) -> List[Package]: """ load packages from list of archives - :param packages: paths to package archives - :return: list of read packages + + Args: + packages(Iterable[Path]): paths to package archives + + Returns: + List[Package]: list of read packages + + Raises: + NotImplementedError: not implemented method """ raise NotImplementedError def packages(self) -> List[Package]: """ generate list of repository packages - :return: list of packages properties + + Returns: + List[Package]: list of packages properties + + Raises: + NotImplementedError: not implemented method """ raise NotImplementedError def process_build(self, updates: Iterable[Package]) -> Result: """ build packages - :param updates: list of packages properties to build - :return: `packages_built` + + Args: + updates(Iterable[Package]): list of packages properties to build + + Returns: + Result: build result """ def build_single(package: Package, local_path: Path) -> None: self.reporter.set_building(package.base) @@ -82,8 +98,12 @@ class Executor(Cleaner): def process_remove(self, packages: Iterable[str]) -> Path: """ remove packages from list - :param packages: list of package names or bases to remove - :return: path to repository database + + Args: + packages(Iterable[str]): list of package names or bases to remove + + Returns: + Path: path to repository database """ def remove_base(package_base: str) -> None: try: @@ -126,8 +146,11 @@ class Executor(Cleaner): def process_report(self, targets: Optional[Iterable[str]], result: Result) -> None: """ generate reports - :param targets: list of targets to generate reports. Configuration option will be used if it is not set - :param result: build result + + Args: + targets(Optional[Iterable[str]]): list of targets to generate reports. Configuration option will be used + if it is not set + result(Result): build result """ if targets is None: targets = self.configuration.getlist("report", "target") @@ -138,8 +161,11 @@ class Executor(Cleaner): def process_sync(self, targets: Optional[Iterable[str]], built_packages: Iterable[Package]) -> None: """ process synchronization to remote servers - :param targets: list of targets to sync. Configuration option will be used if it is not set - :param built_packages: list of packages which has just been built + + Args: + targets(Optional[Iterable[str]]): list of targets to sync. Configuration option will be used + if it is not set + built_packages(Iterable[Package]): list of packages which has just been built """ if targets is None: targets = self.configuration.getlist("upload", "target") @@ -150,8 +176,12 @@ class Executor(Cleaner): def process_update(self, packages: Iterable[Path]) -> Result: """ sign packages, add them to repository and update repository database - :param packages: list of filenames to run - :return: path to repository database + + Args: + packages(Iterable[Path]): list of filenames to run + + Returns: + Result: path to repository database """ def update_single(name: Optional[str], base: str) -> None: if name is None: diff --git a/src/ahriman/core/repository/properties.py b/src/ahriman/core/repository/properties.py index 724a038c..b6a919b4 100644 --- a/src/ahriman/core/repository/properties.py +++ b/src/ahriman/core/repository/properties.py @@ -32,29 +32,33 @@ from ahriman.core.util import check_user class Properties: """ repository internal objects holder - :ivar architecture: repository architecture - :ivar aur_url: base AUR url - :ivar configuration: configuration instance - :ivar database: database instance - :ivar ignore_list: package bases which will be ignored during auto updates - :ivar logger: class logger - :ivar name: repository name - :ivar pacman: alpm wrapper instance - :ivar paths: repository paths instance - :ivar repo: repo commands wrapper instance - :ivar reporter: build status reporter instance - :ivar sign: GPG wrapper instance + + Attributes: + architecture(str): repository architecture + aur_url(str): base AUR url + configuration(Configuration): configuration instance + database(SQLite): database instance + ignore_list(List[str]): package bases which will be ignored during auto updates + logger(logging.Logger): class logger + name(str): repository name + pacman(Pacman): alpm wrapper instance + paths(RepositoryPaths): repository paths instance + repo(Repo): repo commands wrapper instance + reporter(Client): build status reporter instance + sign(GPG): GPG wrapper instance """ def __init__(self, architecture: str, configuration: Configuration, database: SQLite, no_report: bool, unsafe: bool) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance - :param database: database instance - :param no_report: force disable reporting - :param unsafe: if set no user check will be performed before path creation + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + database(SQLite): database instance + no_report(bool): force disable reporting + unsafe(bool): if set no user check will be performed before path creation """ self.logger = logging.getLogger("root") self.architecture = architecture diff --git a/src/ahriman/core/repository/repository.py b/src/ahriman/core/repository/repository.py index 65a9783f..8b64dcde 100644 --- a/src/ahriman/core/repository/repository.py +++ b/src/ahriman/core/repository/repository.py @@ -35,8 +35,12 @@ class Repository(Executor, UpdateHandler): def load_archives(self, packages: Iterable[Path]) -> List[Package]: """ load packages from list of archives - :param packages: paths to package archives - :return: list of read packages + + Args: + packages(Iterable[Path]): paths to package archives + + Returns: + List[Package]: list of read packages """ result: Dict[str, Package] = {} # we are iterating over bases, not single packages @@ -58,22 +62,30 @@ class Repository(Executor, UpdateHandler): def packages(self) -> List[Package]: """ generate list of repository packages - :return: list of packages properties + + Returns: + List[Package]: list of packages properties """ return self.load_archives(filter(package_like, self.paths.repository.iterdir())) def packages_built(self) -> List[Path]: """ get list of files in built packages directory - :return: list of filenames from the directory + + Returns: + List[Path]: list of filenames from the directory """ return list(filter(package_like, self.paths.packages.iterdir())) def packages_depends_on(self, depends_on: Optional[Iterable[str]]) -> List[Package]: """ extract list of packages which depends on specified package - :param: depends_on: dependencies of the packages - :return: list of repository packages which depend on specified packages + + Args: + depends_on(Optional[Iterable[str]]): dependencies of the packages + + Returns: + List[Package]: list of repository packages which depend on specified packages """ packages = self.packages() if depends_on is None: diff --git a/src/ahriman/core/repository/update_handler.py b/src/ahriman/core/repository/update_handler.py index 5681ee8c..c9280d50 100644 --- a/src/ahriman/core/repository/update_handler.py +++ b/src/ahriman/core/repository/update_handler.py @@ -33,16 +33,25 @@ class UpdateHandler(Cleaner): def packages(self) -> List[Package]: """ generate list of repository packages - :return: list of packages properties + + Returns: + List[Package]: list of packages properties + + Raises: + NotImplementedError: not implemented method """ raise NotImplementedError def updates_aur(self, filter_packages: Iterable[str], no_vcs: bool) -> List[Package]: """ check AUR for updates - :param filter_packages: do not check every package just specified in the list - :param no_vcs: do not check VCS packages - :return: list of packages which are out-of-dated + + Args: + filter_packages(Iterable[str]): do not check every package just specified in the list + no_vcs(bool): do not check VCS packages + + Returns: + List[Package]: list of packages which are out-of-dated """ result: List[Package] = [] @@ -70,7 +79,9 @@ class UpdateHandler(Cleaner): def updates_local(self) -> List[Package]: """ check local packages for updates - :return: list of local packages which are out-of-dated + + Returns: + List[Package]: list of local packages which are out-of-dated """ result: List[Package] = [] packages = {local.base: local for local in self.packages()} @@ -97,7 +108,9 @@ class UpdateHandler(Cleaner): def updates_manual(self) -> List[Package]: """ check for packages for which manual update has been requested - :return: list of packages which are out-of-dated + + Returns: + List[Package]: list of packages which are out-of-dated """ result: List[Package] = [] known_bases = {package.base for package in self.packages()} diff --git a/src/ahriman/core/sign/gpg.py b/src/ahriman/core/sign/gpg.py index d67f1d93..4351afd2 100644 --- a/src/ahriman/core/sign/gpg.py +++ b/src/ahriman/core/sign/gpg.py @@ -32,11 +32,13 @@ from ahriman.models.sign_settings import SignSettings class GPG: """ gnupg wrapper - :ivar architecture: repository architecture - :ivar configuration: configuration instance - :ivar default_key: default PGP key ID to use - :ivar logger: class logger - :ivar targets: list of targets to sign (repository, package etc) + + Attributes: + architecture(str): repository architecture + configuration(Configuration): configuration instance + default_key(Optional[str]): default PGP key ID to use + logger(logging.Logger): class logger + targets(Set[SignSettings]): list of targets to sign (repository, package etc) """ _check_output = check_output @@ -44,8 +46,10 @@ class GPG: def __init__(self, architecture: str, configuration: Configuration) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance """ self.logger = logging.getLogger("build_details") self.architecture = architecture @@ -55,7 +59,10 @@ class GPG: @property def repository_sign_args(self) -> List[str]: """ - :return: command line arguments for repo-add command to sign database + get command line arguments based on settings + + Returns: + List[str]: command line arguments for repo-add command to sign database """ if SignSettings.Repository not in self.targets: return [] @@ -68,9 +75,13 @@ class GPG: def sign_command(path: Path, key: str) -> List[str]: """ gpg command to run - :param path: path to file to sign - :param key: PGP key ID - :return: gpg command with all required arguments + + Args: + path(Path): path to file to sign + key(str): PGP key ID + + Returns: + List[str]: gpg command with all required arguments """ return ["gpg", "-u", key, "-b", str(path)] @@ -78,22 +89,32 @@ class GPG: def sign_options(configuration: Configuration) -> Tuple[Set[SignSettings], Optional[str]]: """ extract default sign options from configuration - :param configuration: configuration instance - :return: tuple of sign targets and default PGP key + + Args: + configuration(Configuration): configuration instance + + Returns: + Tuple[Set[SignSettings], Optional[str]]: tuple of sign targets and default PGP key """ - targets = { - SignSettings.from_option(option) - for option in configuration.getlist("sign", "target") - } + targets: Set[SignSettings] = set() + for option in configuration.getlist("sign", "target"): + target = SignSettings.from_option(option) + if target == SignSettings.Disabled: + continue + targets.add(target) default_key = configuration.get("sign", "key") if targets else None return targets, default_key def key_download(self, server: str, key: str) -> str: """ download key from public PGP server - :param server: public PGP server which will be used to download the key - :param key: key ID to download - :return: key as plain text + + Args: + server(str): public PGP server which will be used to download the key + key(str): key ID to download + + Returns: + str: key as plain text """ key = key if key.startswith("0x") else f"0x{key}" try: @@ -111,8 +132,10 @@ class GPG: def key_import(self, server: str, key: str) -> None: """ import key to current user and sign it locally - :param server: public PGP server which will be used to download the key - :param key: key ID to import + + Args: + server(str): public PGP server which will be used to download the key + key(str): key ID to import """ key_body = self.key_download(server, key) GPG._check_output("gpg", "--import", input_data=key_body, exception=None, logger=self.logger) @@ -120,9 +143,13 @@ class GPG: def process(self, path: Path, key: str) -> List[Path]: """ gpg command wrapper - :param path: path to file to sign - :param key: PGP key ID - :return: list of generated files including original file + + Args: + path(Path): path to file to sign + key(str): PGP key ID + + Returns: + List[Path]: list of generated files including original file """ GPG._check_output( *GPG.sign_command(path, key), @@ -133,9 +160,13 @@ class GPG: def process_sign_package(self, path: Path, base: str) -> List[Path]: """ sign package if required by configuration - :param path: path to file to sign - :param base: package base required to check for key overrides - :return: list of generated files including original file + + Args: + path(Path): path to file to sign + base(str): package base required to check for key overrides + + Returns: + List[Path]: list of generated files including original file """ if SignSettings.Packages not in self.targets: return [path] @@ -149,8 +180,12 @@ class GPG: """ sign repository if required by configuration :note: more likely you just want to pass `repository_sign_args` to repo wrapper - :param path: path to repository database - :return: list of generated files including original file + + Args: + path(Path): path to repository database + + Returns: + List[Path]: list of generated files including original file """ if SignSettings.Repository not in self.targets: return [path] diff --git a/src/ahriman/core/spawn.py b/src/ahriman/core/spawn.py index da094b56..f5032080 100644 --- a/src/ahriman/core/spawn.py +++ b/src/ahriman/core/spawn.py @@ -35,19 +35,23 @@ class Spawn(Thread): """ helper to spawn external ahriman process MUST NOT be used directly, the only one usage allowed is to spawn process from web services - :ivar active: map of active child processes required to avoid zombies - :ivar architecture: repository architecture - :ivar configuration: configuration instance - :ivar logger: spawner logger - :ivar queue: multiprocessing queue to read updates from processes + + Attributes: + active(Dict[str, Process]): map of active child processes required to avoid zombies + architecture(str): repository architecture + configuration(Configuration): configuration instance + logger(logging.Logger): spawner logger + queue(Queue[Tuple[str, bool]]): multiprocessing queue to read updates from processes """ def __init__(self, args_parser: argparse.ArgumentParser, architecture: str, configuration: Configuration) -> None: """ default constructor - :param args_parser: command line parser for the application - :param architecture: repository architecture - :param configuration: configuration instance + + Args: + args_parser(argparse.ArgumentParser): command line parser for the application + architecture(str): repository architecture + configuration(Configuration): configuration instance """ Thread.__init__(self, name="spawn") self.architecture = architecture @@ -65,11 +69,13 @@ class Spawn(Thread): process_id: str, queue: Queue[Tuple[str, bool]]) -> None: # pylint: disable=unsubscriptable-object """ helper to run external process - :param callback: application run function (i.e. Handler.run method) - :param args: command line arguments - :param architecture: repository architecture - :param process_id: process unique identifier - :param queue: output queue + + Args: + callback(Callable[[argparse.Namespace, str], bool]): application run function (i.e. Handler.run method) + args(argparse.Namespace): command line arguments + architecture(str): repository architecture + process_id(str): process unique identifier + queue(Queue[Tuple[str, bool]]): output queue """ result = callback(args, architecture) queue.put((process_id, result)) @@ -77,8 +83,10 @@ class Spawn(Thread): def packages_add(self, packages: Iterable[str], now: bool) -> None: """ add packages - :param packages: packages list to add - :param now: build packages now + + Args: + packages(Iterable[str]): packages list to add + now(bool): build packages now """ kwargs = {"source": PackageSource.AUR.value} # avoid abusing by building non-aur packages if now: @@ -88,16 +96,20 @@ class Spawn(Thread): def packages_remove(self, packages: Iterable[str]) -> None: """ remove packages - :param packages: packages list to remove + + Args: + packages(Iterable[str]): packages list to remove """ self.spawn_process("remove", *packages) def spawn_process(self, command: str, *args: str, **kwargs: str) -> None: """ spawn external ahriman process with supplied arguments - :param command: subcommand to run - :param args: positional command arguments - :param kwargs: named command arguments + + Args: + command(str): subcommand to run + *args(str): positional command arguments + **kwargs(str): named command arguments """ # default arguments arguments = ["--architecture", self.architecture] diff --git a/src/ahriman/core/status/client.py b/src/ahriman/core/status/client.py index de752b70..60737148 100644 --- a/src/ahriman/core/status/client.py +++ b/src/ahriman/core/status/client.py @@ -36,8 +36,12 @@ class Client: def load(cls: Type[Client], configuration: Configuration) -> Client: """ load client from settings - :param configuration: configuration instance - :return: client according to current settings + + Args: + configuration(Configuration): configuration instance + + Returns: + Client: client according to current settings """ address = configuration.get("web", "address", fallback=None) host = configuration.get("web", "host", fallback=None) @@ -50,15 +54,21 @@ class Client: def add(self, package: Package, status: BuildStatusEnum) -> None: """ add new package with status - :param package: package properties - :param status: current package build status + + Args: + package(Package): package properties + status(BuildStatusEnum): current package build status """ def get(self, base: Optional[str]) -> List[Tuple[Package, BuildStatus]]: # pylint: disable=no-self-use """ get package status - :param base: package base to get - :return: list of current package description and status if it has been found + + Args: + base(Optional[str]): package base to get + + Returns: + List[Tuple[Package, BuildStatus]]: list of current package description and status if it has been found """ del base return [] @@ -66,67 +76,87 @@ class Client: def get_internal(self) -> InternalStatus: # pylint: disable=no-self-use """ get internal service status - :return: current internal (web) service status + + Returns: + InternalStatus: current internal (web) service status """ return InternalStatus() def get_self(self) -> BuildStatus: # pylint: disable=no-self-use """ get ahriman status itself - :return: current ahriman status + + Returns: + BuildStatus: current ahriman status """ return BuildStatus() def remove(self, base: str) -> None: """ remove packages from watcher - :param base: package base to remove + + Args: + base(str): package base to remove """ def update(self, base: str, status: BuildStatusEnum) -> None: """ update package build status. Unlike `add` it does not update package properties - :param base: package base to update - :param status: current package build status + + Args: + base(str): package base to update + status(BuildStatusEnum): current package build status """ def update_self(self, status: BuildStatusEnum) -> None: """ update ahriman status itself - :param status: current ahriman status + + Args: + status(BuildStatusEnum): current ahriman status """ def set_building(self, base: str) -> None: """ set package status to building - :param base: package base to update + + Args: + base(str): package base to update """ return self.update(base, BuildStatusEnum.Building) def set_failed(self, base: str) -> None: """ set package status to failed - :param base: package base to update + + Args: + base(str): package base to update """ return self.update(base, BuildStatusEnum.Failed) def set_pending(self, base: str) -> None: """ set package status to pending - :param base: package base to update + + Args: + base(str): package base to update """ return self.update(base, BuildStatusEnum.Pending) def set_success(self, package: Package) -> None: """ set package status to success - :param package: current package properties + + Args: + package(Package): current package properties """ return self.add(package, BuildStatusEnum.Success) def set_unknown(self, package: Package) -> None: """ set package status to unknown - :param package: current package properties + + Args: + package(Package): current package properties """ return self.add(package, BuildStatusEnum.Unknown) diff --git a/src/ahriman/core/status/watcher.py b/src/ahriman/core/status/watcher.py index 42a3ac4e..651a503a 100644 --- a/src/ahriman/core/status/watcher.py +++ b/src/ahriman/core/status/watcher.py @@ -32,20 +32,24 @@ from ahriman.models.package import Package class Watcher: """ package status watcher - :ivar architecture: repository architecture - :ivar database: database instance - :ivar known: list of known packages. For the most cases `packages` should be used instead - :ivar logger: class logger - :ivar repository: repository object - :ivar status: daemon status + + Attributes: + architecture(str): repository architecture + database(SQLite): database instance + known(Dict[str, Tuple[Package, BuildStatus]]): list of known packages. For the most cases `packages` should be used instead + logger(logging.Logger): class logger + repository(Repository): repository object + status(BuildStatus): daemon status """ def __init__(self, architecture: str, configuration: Configuration, database: SQLite) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance - :param database: database instance + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + database(SQLite): database instance """ self.logger = logging.getLogger("http") @@ -59,14 +63,25 @@ class Watcher: @property def packages(self) -> List[Tuple[Package, BuildStatus]]: """ - :return: list of packages together with their statuses + get current known packages list + + Returns: + List[Tuple[Package, BuildStatus]]: list of packages together with their statuses """ return list(self.known.values()) def get(self, base: str) -> Tuple[Package, BuildStatus]: """ get current package base build status - :return: package and its status + + Args: + base(str): package base + + Returns: + Tuple[Package, BuildStatus]: package and its status + + Raises: + UnknownPackage: if no package found """ try: return self.known[base] @@ -92,7 +107,9 @@ class Watcher: def remove(self, package_base: str) -> None: """ remove package base from known list if any - :param package_base: package base + + Args: + package_base(str): package base """ self.known.pop(package_base, None) self.database.package_remove(package_base) @@ -100,9 +117,14 @@ class Watcher: def update(self, package_base: str, status: BuildStatusEnum, package: Optional[Package]) -> None: """ update package status and description - :param package_base: package base to update - :param status: new build status - :param package: optional new package description. In case if not set current properties will be used + + Args: + package_base(str): package base to update + status(BuildStatusEnum): new build status + package(Optional[Package]): optional new package description. In case if not set current properties will be used + + Raises: + UnknownPackage: if no package found """ if package is None: try: @@ -116,6 +138,8 @@ class Watcher: def update_self(self, status: BuildStatusEnum) -> None: """ update service status - :param status: new service status + + Args: + status(BuildStatusEnum): new service status """ self.status = BuildStatus(status) diff --git a/src/ahriman/core/status/web_client.py b/src/ahriman/core/status/web_client.py index c99a81fd..6ba79f72 100644 --- a/src/ahriman/core/status/web_client.py +++ b/src/ahriman/core/status/web_client.py @@ -34,15 +34,19 @@ from ahriman.models.user import User class WebClient(Client): """ build status reporter web client - :ivar address: address of the web service - :ivar logger: class logger - :ivar user: web service user descriptor + + Attributes: + address(str): address of the web service + logger(logging.Logger): class logger + user(Optional[User]): web service user descriptor """ def __init__(self, configuration: Configuration) -> None: """ default constructor - :param configuration: configuration instance + + Args: + configuration(Configuration): configuration instance """ self.logger = logging.getLogger("http") self.address = self.parse_address(configuration) @@ -56,21 +60,30 @@ class WebClient(Client): @property def _ahriman_url(self) -> str: """ - :return: full url for web service for ahriman service itself + get url for the service status api + + Returns: + str: full url for web service for ahriman service itself """ return f"{self.address}/status-api/v1/ahriman" @property def _login_url(self) -> str: """ - :return: full url for web service to login + get url for the login api + + Returns: + str: full url for web service to login """ return f"{self.address}/user-api/v1/login" @property def _status_url(self) -> str: """ - :return: full url for web service for status + get url for the status api + + Returns: + str: full url for web service for status """ return f"{self.address}/status-api/v1/status" @@ -78,8 +91,12 @@ class WebClient(Client): def parse_address(configuration: Configuration) -> str: """ parse address from configuration - :param configuration: configuration instance - :return: valid http address + + Args: + configuration(Configuration): configuration instance + + Returns: + str: valid http address """ address = configuration.get("web", "address", fallback=None) if not address: @@ -112,16 +129,22 @@ class WebClient(Client): def _package_url(self, base: str = "") -> str: """ url generator - :param base: package base to generate url - :return: full url of web service for specific package base + + Args: + base(str, optional): package base to generate url (Default value = "") + + Returns: + str: full url of web service for specific package base """ return f"{self.address}/status-api/v1/packages/{base}" def add(self, package: Package, status: BuildStatusEnum) -> None: """ add new package with status - :param package: package properties - :param status: current package build status + + Args: + package(Package): package properties + status(BuildStatusEnum): current package build status """ payload = { "status": status.value, @@ -139,8 +162,12 @@ class WebClient(Client): def get(self, base: Optional[str]) -> List[Tuple[Package, BuildStatus]]: """ get package status - :param base: package base to get - :return: list of current package description and status if it has been found + + Args: + base(Optional[str]): package base to get + + Returns: + List[Tuple[Package, BuildStatus]]: list of current package description and status if it has been found """ try: response = self.__session.get(self._package_url(base or "")) @@ -160,7 +187,9 @@ class WebClient(Client): def get_internal(self) -> InternalStatus: """ get internal service status - :return: current internal (web) service status + + Returns: + InternalStatus: current internal (web) service status """ try: response = self.__session.get(self._status_url) @@ -177,7 +206,9 @@ class WebClient(Client): def get_self(self) -> BuildStatus: """ get ahriman status itself - :return: current ahriman status + + Returns: + BuildStatus: current ahriman status """ try: response = self.__session.get(self._ahriman_url) @@ -194,7 +225,9 @@ class WebClient(Client): def remove(self, base: str) -> None: """ remove packages from watcher - :param base: basename to remove + + Args: + base(str): basename to remove """ try: response = self.__session.delete(self._package_url(base)) @@ -207,8 +240,10 @@ class WebClient(Client): def update(self, base: str, status: BuildStatusEnum) -> None: """ update package build status. Unlike `add` it does not update package properties - :param base: package base to update - :param status: current package build status + + Args: + base(str): package base to update + status(BuildStatusEnum): current package build status """ payload = {"status": status.value} @@ -223,7 +258,9 @@ class WebClient(Client): def update_self(self, status: BuildStatusEnum) -> None: """ update ahriman status itself - :param status: current ahriman status + + Args: + status(BuildStatusEnum): current ahriman status """ payload = {"status": status.value} diff --git a/src/ahriman/core/tree.py b/src/ahriman/core/tree.py index 21f18ca9..eb2c5fcb 100644 --- a/src/ahriman/core/tree.py +++ b/src/ahriman/core/tree.py @@ -30,15 +30,19 @@ from ahriman.models.package import Package class Leaf: """ tree leaf implementation - :ivar dependencies: list of package dependencies - :ivar package: leaf package properties + + Attributes: + dependencies(Set[str]): list of package dependencies + package(Package): leaf package properties """ def __init__(self, package: Package, dependencies: Set[str]) -> None: """ default constructor - :param package: package properties - :param dependencies: package dependencies + + Args: + package(Package): package properties + dependencies(Set[str]): package dependencies """ self.package = package self.dependencies = dependencies @@ -46,7 +50,10 @@ class Leaf: @property def items(self) -> Iterable[str]: """ - :return: packages containing in this leaf + extract all packages from the leaf + + Returns: + Iterable[str]: packages containing in this leaf """ return self.package.packages.keys() @@ -54,9 +61,13 @@ class Leaf: def load(cls: Type[Leaf], package: Package, database: SQLite) -> Leaf: """ load leaf from package with dependencies - :param package: package properties - :param database: database instance - :return: loaded class + + Args: + package(Package): package properties + database(SQLite): database instance + + Returns: + Leaf: loaded class """ with tmpdir() as clone_dir: Sources.load(clone_dir, package.git_url, database.patches_get(package.base)) @@ -66,8 +77,12 @@ class Leaf: def is_root(self, packages: Iterable[Leaf]) -> bool: """ check if package depends on any other package from list of not - :param packages: list of known leaves - :return: True if any of packages is dependency of the leaf, False otherwise + + Args: + packages(Iterable[Leaf]): list of known leaves + + Returns: + bool: True if any of packages is dependency of the leaf, False otherwise """ for leaf in packages: if self.dependencies.intersection(leaf.items): @@ -78,13 +93,17 @@ class Leaf: class Tree: """ dependency tree implementation - :ivar leaves: list of tree leaves + + Attributes: + leaves[List[Leaf]): list of tree leaves """ def __init__(self, leaves: List[Leaf]) -> None: """ default constructor - :param leaves: leaves to build the tree + + Args: + leaves(List[Leaf]): leaves to build the tree """ self.leaves = leaves @@ -92,16 +111,22 @@ class Tree: def load(cls: Type[Tree], packages: Iterable[Package], database: SQLite) -> Tree: """ load tree from packages - :param packages: packages list - :param database: database instance - :return: loaded class + + Args: + packages(Iterable[Package]): packages list + database(SQLite): database instance + + Returns: + Tree: loaded class """ return cls([Leaf.load(package, database) for package in packages]) def levels(self) -> List[List[Package]]: """ get build levels starting from the packages which do not require any other package to build - :return: list of packages lists + + Returns: + List[List[Package]]: list of packages lists """ result: List[List[Package]] = [] diff --git a/src/ahriman/core/upload/github.py b/src/ahriman/core/upload/github.py index 7ec67a06..afeb6e0f 100644 --- a/src/ahriman/core/upload/github.py +++ b/src/ahriman/core/upload/github.py @@ -32,26 +32,32 @@ from ahriman.models.package import Package class Github(HttpUpload): """ upload files to github releases - :ivar gh_owner: github repository owner - :ivar gh_repository: github repository name + + Attributes: + github_owner(str): github repository owner + github_repository(str): github repository name """ def __init__(self, architecture: str, configuration: Configuration, section: str) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance - :param section: settings section name + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + section(str): settings section name """ HttpUpload.__init__(self, architecture, configuration, section) - self.gh_owner = configuration.get(section, "owner") - self.gh_repository = configuration.get(section, "repository") + self.github_owner = configuration.get(section, "owner") + self.github_repository = configuration.get(section, "repository") def asset_remove(self, release: Dict[str, Any], name: str) -> None: """ remove asset from the release by name - :param release: release object - :param name: asset name + + Args: + release(Dict[str, Any]): release object + name(str): asset name """ try: asset = next(asset for asset in release["assets"] if asset["name"] == name) @@ -62,8 +68,10 @@ class Github(HttpUpload): def asset_upload(self, release: Dict[str, Any], path: Path) -> None: """ upload asset to the release - :param release: release object - :param path: path to local file + + Args: + release(Dict[str, Any]): release object + path(Path): path to local file """ exists = any(path.name == asset["name"] for asset in release["assets"]) if exists: @@ -76,8 +84,12 @@ class Github(HttpUpload): def get_local_files(self, path: Path) -> Dict[Path, str]: """ get all local files and their calculated checksums - :param path: local path to sync - :return: map of path objects to its checksum + + Args: + path(Path): local path to sync + + Returns: + Dict[Path, str]: map of path objects to its checksum """ return { local_file: self.calculate_hash(local_file) @@ -87,9 +99,11 @@ class Github(HttpUpload): def files_remove(self, release: Dict[str, Any], local_files: Dict[Path, str], remote_files: Dict[str, str]) -> None: """ remove files from github - :param release: release object - :param local_files: map of local file paths to its checksum - :param remote_files: map of the remote files and its checksum + + Args: + release(Dict[str, Any]): release object + local_files(Dict[Path, str]): map of local file paths to its checksum + remote_files(Dict[str, str]): map of the remote files and its checksum """ local_filenames = {local_file.name for local_file in local_files} for remote_file in remote_files: @@ -100,9 +114,11 @@ class Github(HttpUpload): def files_upload(self, release: Dict[str, Any], local_files: Dict[Path, str], remote_files: Dict[str, str]) -> None: """ upload files to github - :param release: release object - :param local_files: map of local file paths to its checksum - :param remote_files: map of the remote files and its checksum + + Args: + release(Dict[str, Any]): release object + local_files(Dict[Path, str]): map of local file paths to its checksum + remote_files(Dict[str, str]): map of the remote files and its checksum """ for local_file, checksum in local_files.items(): remote_checksum = remote_files.get(local_file.name) @@ -113,22 +129,25 @@ class Github(HttpUpload): def release_create(self) -> Dict[str, Any]: """ create empty release - :return: github API release object for the new release + + Returns: + Dict[str, Any]: github API release object for the new release """ - response = self._request("POST", f"https://api.github.com/repos/{self.gh_owner}/{self.gh_repository}/releases", - json={"tag_name": self.architecture, "name": self.architecture}) + url = f"https://api.github.com/repos/{self.github_owner}/{self.github_repository}/releases" + response = self._request("POST", url, json={"tag_name": self.architecture, "name": self.architecture}) release: Dict[str, Any] = response.json() return release def release_get(self) -> Optional[Dict[str, Any]]: """ get release object if any - :return: github API release object if release found and None otherwise + + Returns: + Optional[Dict[str, Any]]: github API release object if release found and None otherwise """ + url = f"https://api.github.com/repos/{self.github_owner}/{self.github_repository}/releases/tags/{self.architecture}" try: - response = self._request( - "GET", - f"https://api.github.com/repos/{self.gh_owner}/{self.gh_repository}/releases/tags/{self.architecture}") + response = self._request("GET", url) release: Dict[str, Any] = response.json() return release except requests.HTTPError as e: @@ -140,16 +159,20 @@ class Github(HttpUpload): def release_update(self, release: Dict[str, Any], body: str) -> None: """ update release - :param release: release object - :param body: new release body + + Args: + release(Dict[str, Any]): release object + body(str): new release body """ self._request("POST", release["url"], json={"body": body}) def sync(self, path: Path, built_packages: Iterable[Package]) -> None: """ sync data to remote server - :param path: local path to sync - :param built_packages: list of packages which has just been built + + Args: + path(Path): local path to sync + built_packages(Iterable[Package]): list of packages which has just been built """ release = self.release_get() if release is None: diff --git a/src/ahriman/core/upload/http_upload.py b/src/ahriman/core/upload/http_upload.py index 2b9a81d6..134d06a2 100644 --- a/src/ahriman/core/upload/http_upload.py +++ b/src/ahriman/core/upload/http_upload.py @@ -31,15 +31,19 @@ from ahriman.core.util import exception_response_text class HttpUpload(Upload): """ helper for the http based uploads - :ivar auth: HTTP auth object + + Attributes: + auth(Tuple[str, str]): HTTP auth object """ def __init__(self, architecture: str, configuration: Configuration, section: str) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance - :param section: configuration section name + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + section(str): configuration section name """ Upload.__init__(self, architecture, configuration) password = configuration.get(section, "password") @@ -50,8 +54,12 @@ class HttpUpload(Upload): def calculate_hash(path: Path) -> str: """ calculate file checksum - :param path: path to local file - :return: calculated checksum of the file + + Args: + path(Path): path to local file + + Returns: + str: calculated checksum of the file """ with path.open("rb") as local_file: md5 = hashlib.md5(local_file.read()) # nosec @@ -61,8 +69,12 @@ class HttpUpload(Upload): def get_body(local_files: Dict[Path, str]) -> str: """ generate release body from the checksums as returned from HttpUpload.get_hashes method - :param local_files: map of the paths to its checksum - :return: body to be inserted into release + + Args: + local_files(Dict[Path, str]): map of the paths to its checksum + + Returns: + str: body to be inserted into release """ return "\n".join(f"{file.name} {md5}" for file, md5 in sorted(local_files.items())) @@ -70,8 +82,12 @@ class HttpUpload(Upload): def get_hashes(body: str) -> Dict[str, str]: """ get checksums of the content from the repository - :param body: release string body object - :return: map of the filename to its checksum as it is written in body + + Args: + body(str): release string body object + + Returns: + Dict[str, str]: map of the filename to its checksum as it is written in body """ files = {} for line in body.splitlines(): @@ -82,10 +98,14 @@ class HttpUpload(Upload): def _request(self, method: str, url: str, **kwargs: Any) -> requests.Response: """ request wrapper - :param method: request method - :param url: request url - :param kwargs: request parameters to be passed as is - :return: request response object + + Args: + method(str): request method + url(str): request url + **kwargs(Any): request parameters to be passed as is + + Returns: + requests.Response: request response object """ try: response = requests.request(method, url, auth=self.auth, **kwargs) diff --git a/src/ahriman/core/upload/rsync.py b/src/ahriman/core/upload/rsync.py index c2ed61f2..942f3084 100644 --- a/src/ahriman/core/upload/rsync.py +++ b/src/ahriman/core/upload/rsync.py @@ -29,8 +29,10 @@ from ahriman.models.package import Package class Rsync(Upload): """ rsync wrapper - :ivar command: command arguments for sync - :ivar remote: remote address to sync + + Attributes: + command(List[str]): command arguments for sync + remote(str): remote address to sync """ _check_output = check_output @@ -38,9 +40,11 @@ class Rsync(Upload): def __init__(self, architecture: str, configuration: Configuration, section: str) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance - :param section: settings section name + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + section(str): settings section name """ Upload.__init__(self, architecture, configuration) self.command = configuration.getlist(section, "command") @@ -49,7 +53,9 @@ class Rsync(Upload): def sync(self, path: Path, built_packages: Iterable[Package]) -> None: """ sync data to remote server - :param path: local path to sync - :param built_packages: list of packages which has just been built + + Args: + path(Path): local path to sync + built_packages(Iterable[Package]): list of packages which has just been built """ Rsync._check_output(*self.command, str(path), self.remote, exception=None, logger=self.logger) diff --git a/src/ahriman/core/upload/s3.py b/src/ahriman/core/upload/s3.py index 7eff083c..c1783f69 100644 --- a/src/ahriman/core/upload/s3.py +++ b/src/ahriman/core/upload/s3.py @@ -32,16 +32,21 @@ from ahriman.models.package import Package class S3(Upload): """ - aws-cli wrapper - :ivar bucket: boto3 S3 bucket object - :ivar chunk_size: chunk size for calculating checksums + boto3 wrapper + + Attributes + bucket(Any): boto3 S3 bucket object + chunk_size(int): chunk size for calculating checksums """ def __init__(self, architecture: str, configuration: Configuration, section: str) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + section(str): settings section name """ Upload.__init__(self, architecture, configuration) self.bucket = self.get_bucket(configuration, section) @@ -53,9 +58,13 @@ class S3(Upload): calculate amazon s3 etag credits to https://teppen.io/2018/10/23/aws_s3_verify_etags/ For this method we have to define nosec because it is out of any security context and provided by AWS - :param path: path to local file - :param chunk_size: read chunk size, which depends on client settings - :return: calculated entity tag for local file + + Args: + path(Path): path to local file + chunk_size(int): read chunk size, which depends on client settings + + Returns: + str: calculated entity tag for local file """ md5s = [] with path.open("rb") as local_file: @@ -73,9 +82,13 @@ class S3(Upload): def get_bucket(configuration: Configuration, section: str) -> Any: """ create resource client from configuration - :param configuration: configuration instance - :param section: settings section name - :return: amazon client + + Args: + configuration(Configuration): configuration instance + section(str): settings section name + + Returns: + Any: amazon client """ client = boto3.resource(service_name="s3", region_name=configuration.get(section, "region"), @@ -87,8 +100,10 @@ class S3(Upload): def files_remove(local_files: Dict[Path, str], remote_objects: Dict[Path, Any]) -> None: """ remove files which have been removed locally - :param local_files: map of local path object to its checksum - :param remote_objects: map of remote path object to the remote s3 object + + Args: + local_files(Dict[Path, str]): map of local path object to its checksum + remote_objects(Dict[Path, Any]): map of remote path object to the remote s3 object """ for local_file, remote_object in remote_objects.items(): if local_file in local_files: @@ -98,9 +113,11 @@ class S3(Upload): def files_upload(self, path: Path, local_files: Dict[Path, str], remote_objects: Dict[Path, Any]) -> None: """ upload changed files to s3 - :param path: local path to sync - :param local_files: map of local path object to its checksum - :param remote_objects: map of remote path object to the remote s3 object + + Args: + path(Path): local path to sync + local_files(Dict[Path, str]): map of local path object to its checksum + remote_objects(Dict[Path, Any]): map of remote path object to the remote s3 object """ for local_file, checksum in local_files.items(): remote_object = remote_objects.get(local_file) @@ -119,8 +136,12 @@ class S3(Upload): def get_local_files(self, path: Path) -> Dict[Path, str]: """ get all local files and their calculated checksums - :param path: local path to sync - :return: map of path object to its checksum + + Args: + path(Path): local path to sync + + Returns: + Dict[Path, str]: map of path object to its checksum """ return { local_file.relative_to(path): self.calculate_etag(local_file, self.chunk_size) @@ -130,7 +151,9 @@ class S3(Upload): def get_remote_objects(self) -> Dict[Path, Any]: """ get all remote objects and their checksums - :return: map of path object to the remote s3 object + + Returns: + Dict[Path, Any]: map of path object to the remote s3 object """ objects = self.bucket.objects.filter(Prefix=self.architecture) return {Path(item.key).relative_to(self.architecture): item for item in objects} @@ -138,8 +161,10 @@ class S3(Upload): def sync(self, path: Path, built_packages: Iterable[Package]) -> None: """ sync data to remote server - :param path: local path to sync - :param built_packages: list of packages which has just been built + + Args: + path(Path): local path to sync + built_packages(Iterable[Package]): list of packages which has just been built """ remote_objects = self.get_remote_objects() local_files = self.get_local_files(path) diff --git a/src/ahriman/core/upload/upload.py b/src/ahriman/core/upload/upload.py index dc6a9f66..3ea3e5bf 100644 --- a/src/ahriman/core/upload/upload.py +++ b/src/ahriman/core/upload/upload.py @@ -33,16 +33,20 @@ from ahriman.models.upload_settings import UploadSettings class Upload: """ base remote sync class - :ivar architecture: repository architecture - :ivar configuration: configuration instance - :ivar logger: application logger + + Attributes: + architecture(str): repository architecture + configuration(Configuration): configuration instance + logger(logging.Logger): application logger """ def __init__(self, architecture: str, configuration: Configuration) -> None: """ default constructor - :param architecture: repository architecture - :param configuration: configuration instance + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance """ self.logger = logging.getLogger("root") self.architecture = architecture @@ -52,10 +56,14 @@ class Upload: def load(cls: Type[Upload], architecture: str, configuration: Configuration, target: str) -> Upload: """ load client from settings - :param architecture: repository architecture - :param configuration: configuration instance - :param target: target to run sync (e.g. s3) - :return: client according to current settings + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + target(str): target to run sync (e.g. s3) + + Returns: + Upload: client according to current settings """ section, provider_name = configuration.gettype(target, architecture) provider = UploadSettings.from_option(provider_name) @@ -73,8 +81,13 @@ class Upload: def run(self, path: Path, built_packages: Iterable[Package]) -> None: """ run remote sync - :param path: local path to sync - :param built_packages: list of packages which has just been built + + Args: + path(Path): local path to sync + built_packages(Iterable[Package]): list of packages which has just been built + + Raises: + SyncFailed: in case of any synchronization unmatched exception """ try: self.sync(path, built_packages) @@ -85,6 +98,8 @@ class Upload: def sync(self, path: Path, built_packages: Iterable[Package]) -> None: """ sync data to remote server - :param path: local path to sync - :param built_packages: list of packages which has just been built + + Args: + path(Path): local path to sync + built_packages(Iterable[Package]): list of packages which has just been built """ diff --git a/src/ahriman/core/util.py b/src/ahriman/core/util.py index 70bde8f7..2ac0810b 100644 --- a/src/ahriman/core/util.py +++ b/src/ahriman/core/util.py @@ -37,13 +37,20 @@ def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path] input_data: Optional[str] = None, logger: Optional[Logger] = None, user: Optional[int] = None) -> str: """ subprocess wrapper - :param args: command line arguments - :param exception: exception which has to be reraised instead of default subprocess exception - :param cwd: current working directory - :param input_data: data which will be written to command stdin - :param logger: logger to log command result if required - :param user: run process as specified user - :return: command output + + Args: + *args(str): command line arguments + exception(Optional[Exception]): exception which has to be reraised instead of default subprocess exception + cwd(Optional[Path], optional): current working directory (Default value = None) + input_data(Optional[str], optional): data which will be written to command stdin (Default value = None) + logger(Optional[Logger], optional): logger to log command result if required (Default value = None) + user(Optional[int], optional): run process as specified user (Default value = None) + + Returns: + str: command output + + Raises: + subprocess.CalledProcessError: if subprocess ended with status code different from 0 and no exception supplied """ def log(single: str) -> None: if logger is not None: @@ -83,8 +90,13 @@ def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path] def check_user(paths: RepositoryPaths, unsafe: bool) -> None: """ check if current user is the owner of the root - :param paths: repository paths object - :param unsafe: if set no user check will be performed before path creation + + Args: + paths(RepositoryPaths): repository paths object + unsafe(bool): if set no user check will be performed before path creation + + Raises: + UnsafeRun: if root uid differs from current uid and check is enabled """ if not paths.root.exists(): return # no directory found, skip check @@ -99,8 +111,12 @@ def check_user(paths: RepositoryPaths, unsafe: bool) -> None: def exception_response_text(exception: requests.exceptions.HTTPError) -> str: """ safe response exception text generation - :param exception: exception raised - :return: text of the response if it is not None and empty string otherwise + + Args: + exception(requests.exceptions.HTTPError): exception raised + + Returns: + str: text of the response if it is not None and empty string otherwise """ result: str = exception.response.text if exception.response is not None else "" return result @@ -109,9 +125,13 @@ def exception_response_text(exception: requests.exceptions.HTTPError) -> str: def filter_json(source: Dict[str, Any], known_fields: Iterable[str]) -> Dict[str, Any]: """ filter json object by fields used for json-to-object conversion - :param source: raw json object - :param known_fields: list of fields which have to be known for the target object - :return: json object without unknown and empty fields + + Args: + source(Dict[str, Any]): raw json object + known_fields(Iterable[str]): list of fields which have to be known for the target object + + Returns: + Dict[str, Any]: json object without unknown and empty fields """ return {key: value for key, value in source.items() if key in known_fields and value is not None} @@ -119,10 +139,14 @@ def filter_json(source: Dict[str, Any], known_fields: Iterable[str]) -> Dict[str def full_version(epoch: Union[str, int, None], pkgver: str, pkgrel: str) -> str: """ generate full version from components - :param epoch: package epoch if any - :param pkgver: package version - :param pkgrel: package release version (arch linux specific) - :return: generated version + + Args: + epoch(Union[str, int, None]): package epoch if any + pkgver(str): package version + pkgrel(str): package release version (arch linux specific) + + Returns: + str: generated version """ prefix = f"{epoch}:" if epoch else "" return f"{prefix}{pkgver}-{pkgrel}" @@ -131,8 +155,12 @@ def full_version(epoch: Union[str, int, None], pkgver: str, pkgrel: str) -> str: def package_like(filename: Path) -> bool: """ check if file looks like package - :param filename: name of file to check - :return: True in case if name contains `.pkg.` and not signature, False otherwise + + Args: + filename(Path): name of file to check + + Returns: + bool: True in case if name contains `.pkg.` and not signature, False otherwise """ name = filename.name return ".pkg." in name and not name.endswith(".sig") @@ -141,8 +169,12 @@ def package_like(filename: Path) -> bool: def pretty_datetime(timestamp: Optional[Union[datetime.datetime, float, int]]) -> str: """ convert datetime object to string - :param timestamp: datetime to convert - :return: pretty printable datetime as string + + Args: + timestamp(Optional[Union[datetime.datetime, float, int]]): datetime to convert + + Returns: + str: pretty printable datetime as string """ if timestamp is None: return "" @@ -154,9 +186,16 @@ def pretty_datetime(timestamp: Optional[Union[datetime.datetime, float, int]]) - def pretty_size(size: Optional[float], level: int = 0) -> str: """ convert size to string - :param size: size to convert - :param level: represents current units, 0 is B, 1 is KiB etc - :return: pretty printable size as string + + Args: + size(Optional[float]): size to convert + level(int, optional): represents current units, 0 is B, 1 is KiB etc (Default value = 0) + + Returns: + str: pretty printable size as string + + Raises: + InvalidOption: if size is more than 1TiB """ def str_level() -> str: if level == 0: @@ -180,7 +219,9 @@ def pretty_size(size: Optional[float], level: int = 0) -> str: def tmpdir() -> Generator[Path, None, None]: """ wrapper for tempfile to remove directory after all - :return: path to the created directory + + Yields: + Path: path to the created directory """ path = Path(tempfile.mkdtemp()) try: @@ -193,8 +234,12 @@ def walk(directory_path: Path) -> Generator[Path, None, None]: """ list all file paths in given directory Credits to https://stackoverflow.com/a/64915960 - :param directory_path: root directory path - :return: all found files in given directory with full path + + Args: + directory_path(Path): root directory path + + Yields: + Path: all found files in given directory with full path """ for element in directory_path.iterdir(): if element.is_dir(): diff --git a/src/ahriman/models/action.py b/src/ahriman/models/action.py index c1756b92..cc4cff28 100644 --- a/src/ahriman/models/action.py +++ b/src/ahriman/models/action.py @@ -23,9 +23,11 @@ from enum import Enum class Action(Enum): """ base action enumeration - :cvar List: list available values - :cvar Remove: remove everything from local storage - :cvar Update: update local storage or add to + + Attributes: + List(Action): (class attribute) list available values + Remove(Action): (class attribute) remove everything from local storage + Update(Action): (class attribute) update local storage or add to """ List = "list" diff --git a/src/ahriman/models/aur_package.py b/src/ahriman/models/aur_package.py index de2514ff..5cd01d3b 100644 --- a/src/ahriman/models/aur_package.py +++ b/src/ahriman/models/aur_package.py @@ -32,26 +32,28 @@ from ahriman.core.util import filter_json, full_version class AURPackage: """ AUR package descriptor - :ivar id: package ID - :ivar name: package name - :ivar package_base_id: package base ID - :ivar version: package base version - :ivar description: package base description - :ivar url: package upstream URL - :ivar num_votes: number of votes for the package - :ivar polularity: package popularity - :ivar out_of_date: package out of date timestamp if any - :ivar maintainer: package maintainer - :ivar first_submitted: timestamp of the first package submission - :ivar last_modified: timestamp of the last package submission - :ivar url_path: AUR package path - :ivar depends: list of package dependencies - :ivar make_depends: list of package make dependencies - :ivar opt_depends: list of package optional dependencies - :ivar conflicts: conflicts list for the package - :ivar provides: list of packages which this package provides - :ivar license: list of package licenses - :ivar keywords: list of package keywords + + Attributes: + id(int): package ID + name(str): package name + package_base_id(int): package base ID + version(str): package base version + description(str): package base description + url(Optional[str]): package upstream URL + num_votes(int): number of votes for the package + polularity(float): package popularity + out_of_date(Optional[datetime.datetime]): package out of date timestamp if any + maintainer(Optional[str]): package maintainer + first_submitted(datetime.datetime): timestamp of the first package submission + last_modified(datetime.datetime): timestamp of the last package submission + url_path(str): AUR package path + depends(List[str]): list of package dependencies + make_depends(List[str]): list of package make dependencies + opt_depends(List[str]): list of package optional dependencies + conflicts(List[str]): conflicts list for the package + provides(List[str]): list of packages which this package provides + license(List[str]): list of package licenses + keywords(List[str]): list of package keywords """ id: int @@ -80,8 +82,12 @@ class AURPackage: def from_json(cls: Type[AURPackage], dump: Dict[str, Any]) -> AURPackage: """ construct package descriptor from RPC properties - :param dump: json dump body - :return: AUR package descriptor + + Args: + dump(Dict[str, Any]): json dump body + + Returns: + AURPackage: AUR package descriptor """ # filter to only known fields known_fields = [pair.name for pair in fields(cls)] @@ -92,8 +98,12 @@ class AURPackage: def from_repo(cls: Type[AURPackage], dump: Dict[str, Any]) -> AURPackage: """ construct package descriptor from official repository RPC properties - :param dump: json dump body - :return: AUR package descriptor + + Args: + dump(Dict[str, Any]): json dump body + + Returns: + AURPackage: AUR package descriptor """ return cls( id=0, @@ -125,8 +135,12 @@ class AURPackage: def convert(descriptor: Dict[str, Any]) -> Dict[str, Any]: """ covert AUR RPC key names to package keys - :param descriptor: RPC package descriptor - :return: package descriptor with names converted to snake case + + Args: + descriptor(Dict[str, Any]): RPC package descriptor + + Returns: + Dict[str, Any]: package descriptor with names converted to snake case """ identity_mapper: Callable[[Any], Any] = lambda value: value value_mapper: Dict[str, Callable[[Any], Any]] = { diff --git a/src/ahriman/models/auth_settings.py b/src/ahriman/models/auth_settings.py index 8d008206..d698b91e 100644 --- a/src/ahriman/models/auth_settings.py +++ b/src/ahriman/models/auth_settings.py @@ -22,15 +22,15 @@ from __future__ import annotations from enum import Enum from typing import Type -from ahriman.core.exceptions import InvalidOption - class AuthSettings(Enum): """ web authorization type - :cvar Disabled: authorization is disabled - :cvar Configuration: configuration based authorization - :cvar OAuth: OAuth based provider + + Attributes: + Disabled(AuthSettings): (class attribute) authorization is disabled + Configuration(AuthSettings): (class attribute) configuration based authorization + OAuth(AuthSettings): (class attribute) OAuth based provider """ Disabled = "disabled" @@ -41,21 +41,26 @@ class AuthSettings(Enum): def from_option(cls: Type[AuthSettings], value: str) -> AuthSettings: """ construct value from configuration - :param value: configuration value - :return: parsed value + + Args: + value(str): configuration value + + Returns: + AuthSettings: parsed value """ - if value.lower() in ("disabled", "no"): - return cls.Disabled if value.lower() in ("configuration", "mapping"): return cls.Configuration if value.lower() in ('oauth', 'oauth2'): return cls.OAuth - raise InvalidOption(value) + return cls.Disabled @property def is_enabled(self) -> bool: """ - :return: False in case if authorization is disabled and True otherwise + get enabled flag + + Returns: + bool: False in case if authorization is disabled and True otherwise """ if self == AuthSettings.Disabled: return False diff --git a/src/ahriman/models/build_status.py b/src/ahriman/models/build_status.py index 82b12e25..dad122a9 100644 --- a/src/ahriman/models/build_status.py +++ b/src/ahriman/models/build_status.py @@ -31,11 +31,13 @@ from ahriman.core.util import filter_json, pretty_datetime class BuildStatusEnum(Enum): """ build status enumeration - :cvar Unknown: build status is unknown - :cvar Pending: package is out-of-dated and will be built soon - :cvar Building: package is building right now - :cvar Failed: package build failed - :cvar Success: package has been built without errors + + Attributes: + Unknown(BuildStatusEnum): (class attribute) build status is unknown + Pending(BuildStatusEnum): (class attribute) package is out-of-dated and will be built soon + Building(BuildStatusEnum): (class attribute) package is building right now + Failed(BuildStatusEnum): (class attribute) package build failed + Success(BuildStatusEnum): (class attribute) package has been built without errors """ Unknown = "unknown" @@ -47,7 +49,9 @@ class BuildStatusEnum(Enum): def badges_color(self) -> str: """ convert itself to shield.io badges color - :return: shields.io color + + Returns: + str: shields.io color """ if self == BuildStatusEnum.Pending: return "yellow" @@ -62,7 +66,9 @@ class BuildStatusEnum(Enum): def bootstrap_color(self) -> str: """ converts itself to bootstrap color - :return: bootstrap color + + Returns: + str: bootstrap color """ if self == BuildStatusEnum.Pending: return "warning" @@ -79,8 +85,10 @@ class BuildStatusEnum(Enum): class BuildStatus: """ build status holder - :ivar status: build status - :ivar timestamp: build status update time + + Attributes: + status(BuildStatusEnum): build status + timestamp(int): build status update time """ status: BuildStatusEnum = BuildStatusEnum.Unknown @@ -96,8 +104,12 @@ class BuildStatus: def from_json(cls: Type[BuildStatus], dump: Dict[str, Any]) -> BuildStatus: """ construct status properties from json dump - :param dump: json dump body - :return: status properties + + Args: + dump(Dict[str, Any]): json dump body + + Returns: + BuildStatus: status properties """ known_fields = [pair.name for pair in fields(cls)] return cls(**filter_json(dump, known_fields)) @@ -105,14 +117,18 @@ class BuildStatus: def pretty_print(self) -> str: """ generate pretty string representation - :return: print-friendly string + + Returns: + str: print-friendly string """ return f"{self.status.value} ({pretty_datetime(self.timestamp)})" def view(self) -> Dict[str, Any]: """ generate json status view - :return: json-friendly dictionary + + Returns: + Dict[str, Any]: json-friendly dictionary """ return { "status": self.status.value, diff --git a/src/ahriman/models/counters.py b/src/ahriman/models/counters.py index c6828d38..318676d5 100644 --- a/src/ahriman/models/counters.py +++ b/src/ahriman/models/counters.py @@ -31,12 +31,14 @@ from ahriman.models.package import Package class Counters: """ package counters - :ivar total: total packages count - :ivar unknown: packages in unknown status count - :ivar pending: packages in pending status count - :ivar building: packages in building status count - :ivar failed: packages in failed status count - :ivar success: packages in success status count + + Attributes: + total(int): total packages count + unknown(int): packages in unknown status count + pending(int): packages in pending status count + building(int): packages in building status count + failed(int): packages in failed status count + success(int): packages in success status count """ total: int @@ -50,8 +52,12 @@ class Counters: def from_json(cls: Type[Counters], dump: Dict[str, Any]) -> Counters: """ construct counters from json dump - :param dump: json dump body - :return: status counters + + Args: + dump(Dict[str, Any]): json dump body + + Returns: + Counters: status counters """ # filter to only known fields known_fields = [pair.name for pair in fields(cls)] @@ -61,8 +67,12 @@ class Counters: def from_packages(cls: Type[Counters], packages: List[Tuple[Package, BuildStatus]]) -> Counters: """ construct counters from packages statuses - :param packages: list of package and their status as per watcher property - :return: status counters + + Args: + packages(List[Tuple[Package, BuildStatus]]): list of package and their status as per watcher property + + Returns: + Counters: status counters """ per_status = {"total": len(packages)} for _, status in packages: diff --git a/src/ahriman/models/internal_status.py b/src/ahriman/models/internal_status.py index 6f983c28..a021cb2d 100644 --- a/src/ahriman/models/internal_status.py +++ b/src/ahriman/models/internal_status.py @@ -29,10 +29,12 @@ from ahriman.models.counters import Counters class InternalStatus: """ internal server status - :ivar architecture: repository architecture - :ivar packages: packages statuses counter object - :ivar repository: repository name - :ivar version: service version + + Attributes: + architecture(Optional[str]): repository architecture + packages(Counters): packages statuses counter object + repository(Optional[str]): repository name + version(Optional[str]): service version """ architecture: Optional[str] = None @@ -44,8 +46,12 @@ class InternalStatus: def from_json(cls: Type[InternalStatus], dump: Dict[str, Any]) -> InternalStatus: """ construct internal status from json dump - :param dump: json dump body - :return: internal status + + Args: + dump(Dict[str, Any]): json dump body + + Returns: + InternalStatus: internal status """ counters = Counters.from_json(dump["packages"]) if "packages" in dump else Counters(total=0) return cls(architecture=dump.get("architecture"), @@ -56,6 +62,8 @@ class InternalStatus: def view(self) -> Dict[str, Any]: """ generate json status view - :return: json-friendly dictionary + + Returns: + Dict[str, Any]: json-friendly dictionary """ return asdict(self) diff --git a/src/ahriman/models/migration.py b/src/ahriman/models/migration.py index ab482c99..c7726dad 100644 --- a/src/ahriman/models/migration.py +++ b/src/ahriman/models/migration.py @@ -25,9 +25,11 @@ from typing import List class Migration: """ migration implementation - :ivar index: migration position - :ivar name: migration name - :ivar steps: migration steps + + Attributes: + index(int): migration position + name(str): migration name + steps(List[str]): migration steps """ index: int diff --git a/src/ahriman/models/migration_result.py b/src/ahriman/models/migration_result.py index c8feb046..16178992 100644 --- a/src/ahriman/models/migration_result.py +++ b/src/ahriman/models/migration_result.py @@ -26,8 +26,10 @@ from ahriman.core.exceptions import MigrationError class MigrationResult: """ migration result implementation model - :ivar old_version: old schema version before migrations - :ivar new_version: new schema version after migrations + + Attributes: + old_version(int): old schema version before migrations + new_version(int): new schema version after migrations """ old_version: int @@ -36,7 +38,10 @@ class MigrationResult: @property def is_outdated(self) -> bool: """ - :return: True in case if it requires migrations and False otherwise + check migration and check if there are pending migrations + + Returns: + bool: True in case if it requires migrations and False otherwise """ self.validate() return self.new_version > self.old_version @@ -44,6 +49,9 @@ class MigrationResult: def validate(self) -> None: """ perform version validation + + Raises: + MigrationError: if old version is newer than new one or negative """ if self.old_version < 0 or self.old_version > self.new_version: raise MigrationError(f"Invalid current schema version, expected less or equal to {self.new_version}, " diff --git a/src/ahriman/models/package.py b/src/ahriman/models/package.py index cdfd440b..0e80ed50 100644 --- a/src/ahriman/models/package.py +++ b/src/ahriman/models/package.py @@ -42,10 +42,12 @@ from ahriman.models.repository_paths import RepositoryPaths class Package: """ package properties representation - :ivar aur_url: AUR root url - :ivar base: package base name - :ivar packages: map of package names to their properties. Filled only on load from archive - :ivar version: package full version + + Attributes: + aur_url(str): AUR root url + base(str): package base name + packages(Dict[str, PackageDescription): map of package names to their properties. Filled only on load from archive + version(str): package full version """ base: str @@ -58,35 +60,50 @@ class Package: @property def depends(self) -> List[str]: """ - :return: sum of dependencies per arch package + get package base dependencies + + Returns: + List[str]: sum of dependencies per each package """ return sorted(set(sum([package.depends for package in self.packages.values()], start=[]))) @property def git_url(self) -> str: """ - :return: package git url to clone + get git clone url + + Returns: + str: package git url to clone """ return f"{self.aur_url}/{self.base}.git" @property def groups(self) -> List[str]: """ - :return: sum of groups per each package + get package base groups + + Returns: + List[str]: sum of groups per each package """ return sorted(set(sum([package.groups for package in self.packages.values()], start=[]))) @property def is_single_package(self) -> bool: """ - :return: true in case if this base has only one package with the same name + is it possible to transform package base to single package or not + + Returns: + bool: true in case if this base has only one package with the same name """ return self.base in self.packages and len(self.packages) == 1 @property def is_vcs(self) -> bool: """ - :return: True in case if package base looks like VCS package and false otherwise + get VCS flag based on the package base + + Returns: + bool: True in case if package base looks like VCS package and False otherwise """ return self.base.endswith("-bzr") \ or self.base.endswith("-csv")\ @@ -98,14 +115,20 @@ class Package: @property def licenses(self) -> List[str]: """ - :return: sum of licenses per each package + get package base licenses + + Returns: + List[str]: sum of licenses per each package """ return sorted(set(sum([package.licenses for package in self.packages.values()], start=[]))) @property def web_url(self) -> str: """ - :return: package AUR url + get package url which can be used to see package in web + + Returns: + str: package AUR url """ return f"{self.aur_url}/packages/{self.base}" @@ -113,10 +136,14 @@ class Package: def from_archive(cls: Type[Package], path: Path, pacman: Pacman, aur_url: str) -> Package: """ construct package properties from package archive - :param path: path to package archive - :param pacman: alpm wrapper instance - :param aur_url: AUR root url - :return: package properties + + Args: + path(Path): path to package archive + pacman(Pacman): alpm wrapper instance + aur_url(str): AUR root url + + Returns: + Package: package properties """ package = pacman.handle.load_pkg(str(path)) return cls(package.base, package.version, aur_url, @@ -126,9 +153,13 @@ class Package: def from_aur(cls: Type[Package], name: str, aur_url: str) -> Package: """ construct package properties from AUR page - :param name: package name (either base or normal name) - :param aur_url: AUR root url - :return: package properties + + Args: + name(str): package name (either base or normal name) + aur_url(str): AUR root url + + Returns: + Package: package properties """ package = AUR.info(name) return cls(package.package_base, package.version, aur_url, {package.name: PackageDescription()}) @@ -137,9 +168,16 @@ class Package: def from_build(cls: Type[Package], path: Path, aur_url: str) -> Package: """ construct package properties from sources directory - :param path: path to package sources directory - :param aur_url: AUR root url - :return: package properties + + Args: + path(Path): path to package sources directory + aur_url(str): AUR root url + + Returns: + Package: package properties + + Raises: + InvalidPackageInfo: if there are parsing errors """ srcinfo, errors = parse_srcinfo((path / ".SRCINFO").read_text()) if errors: @@ -153,8 +191,12 @@ class Package: def from_json(cls: Type[Package], dump: Dict[str, Any]) -> Package: """ construct package properties from json dump - :param dump: json dump body - :return: package properties + + Args: + dump(Dict[str, Any]): json dump body + + Returns: + Package: package properties """ packages = { key: PackageDescription.from_json(value) @@ -170,9 +212,13 @@ class Package: def from_official(cls: Type[Package], name: str, aur_url: str) -> Package: """ construct package properties from official repository page - :param name: package name (either base or normal name) - :param aur_url: AUR root url - :return: package properties + + Args: + name(str): package name (either base or normal name) + aur_url(str): AUR root url + + Returns: + Package: package properties """ package = Official.info(name) return cls(package.package_base, package.version, aur_url, {package.name: PackageDescription()}) @@ -181,11 +227,18 @@ class Package: def load(cls: Type[Package], package: str, source: PackageSource, pacman: Pacman, aur_url: str) -> Package: """ package constructor from available sources - :param package: one of path to sources directory, path to archive or package name/base - :param source: source of the package required to define the load method - :param pacman: alpm wrapper instance (required to load from archive) - :param aur_url: AUR root url - :return: package properties + + Args: + package(str): one of path to sources directory, path to archive or package name/base + source(PackageSource): source of the package required to define the load method + pacman(Pacman): alpm wrapper instance (required to load from archive) + aur_url(str): AUR root url + + Returns: + Package: package properties + + Raises: + InvalidPackageInfo: if supplied package source is not valid """ try: resolved_source = source.resolve(package) @@ -207,8 +260,15 @@ class Package: def dependencies(path: Path) -> Set[str]: """ load dependencies from package sources - :param path: path to package sources directory - :return: list of package dependencies including makedepends array, but excluding packages from this base + + Args: + path(Path): path to package sources directory + + Returns: + Set[str]: list of package dependencies including makedepends array, but excluding packages from this base + + Raises: + InvalidPackageInfo: if there are parsing errors """ # additional function to remove versions from dependencies def extract_packages(raw_packages_list: List[str]) -> Set[str]: @@ -234,8 +294,15 @@ class Package: def actual_version(self, paths: RepositoryPaths) -> str: """ additional method to handle VCS package versions - :param paths: repository paths instance - :return: package version if package is not VCS and current version according to VCS otherwise + + Args: + paths(RepositoryPaths): repository paths instance + + Returns: + str: package version if package is not VCS and current version according to VCS otherwise + + Raises: + InvalidPackageInfo: if there are parsing errors """ if not self.is_vcs: return self.version @@ -265,9 +332,13 @@ class Package: def full_depends(self, pacman: Pacman, packages: Iterable[Package]) -> List[str]: """ generate full dependencies list including transitive dependencies - :param pacman: alpm wrapper instance - :param packages: repository package list - :return: all dependencies of the package + + Args: + pacman(Pacman): alpm wrapper instance + packages(Iterable[Package]): repository package list + + Returns: + List[str]: all dependencies of the package """ dependencies = {} # load own package dependencies @@ -295,10 +366,14 @@ class Package: def is_outdated(self, remote: Package, paths: RepositoryPaths, calculate_version: bool = True) -> bool: """ check if package is out-of-dated - :param remote: package properties from remote source - :param paths: repository paths instance. Required for VCS packages cache - :param calculate_version: expand version to actual value (by calculating git versions) - :return: True if the package is out-of-dated and False otherwise + + Args: + remote(Package): package properties from remote source + paths(RepositoryPaths): repository paths instance. Required for VCS packages cache + calculate_version(bool, optional): expand version to actual value (by calculating git versions) (Default value = True) + + Returns: + bool: True if the package is out-of-dated and False otherwise """ remote_version = remote.actual_version(paths) if calculate_version else remote.version result: int = vercmp(self.version, remote_version) @@ -307,7 +382,9 @@ class Package: def pretty_print(self) -> str: """ generate pretty string representation - :return: print-friendly string + + Returns: + str: print-friendly string """ details = "" if self.is_single_package else f""" ({" ".join(sorted(self.packages.keys()))})""" return f"{self.base}{details}" @@ -315,6 +392,8 @@ class Package: def view(self) -> Dict[str, Any]: """ generate json package view - :return: json-friendly dictionary + + Returns: + Dict[str, Any]: json-friendly dictionary """ return asdict(self) diff --git a/src/ahriman/models/package_description.py b/src/ahriman/models/package_description.py index b8636014..534b6e68 100644 --- a/src/ahriman/models/package_description.py +++ b/src/ahriman/models/package_description.py @@ -31,17 +31,19 @@ from ahriman.core.util import filter_json class PackageDescription: """ package specific properties - :ivar architecture: package architecture - :ivar archive_size: package archive size - :ivar build_date: package build date - :ivar depends: package dependencies list - :ivar description: package description - :ivar filename: package archive name - :ivar groups: package groups - :ivar installed_size: package installed size - :ivar licenses: package licenses list - :ivar provides: list of provided packages - :ivar url: package url + + Attributes: + architecture(Optional[str]): package architecture + archive_size(Optional[int]): package archive size + build_date(Optional[int]): package build date + depends(List[str]): package dependencies list + description(Optional[str]): package description + filename(Optional[str]): package archive name + groups(List[str]): package groups + installed_size(Optional[int]): package installed size + licenses(List[str]): package licenses list + provides(List[str]): list of provided packages + url(Optional[str]): package url """ architecture: Optional[str] = None @@ -59,7 +61,10 @@ class PackageDescription: @property def filepath(self) -> Optional[Path]: """ - :return: path object for current filename + wrapper for filename, convert it to Path object + + Returns: + Optional[Path]: path object for current filename """ return Path(self.filename) if self.filename is not None else None @@ -67,8 +72,12 @@ class PackageDescription: def from_json(cls: Type[PackageDescription], dump: Dict[str, Any]) -> PackageDescription: """ construct package properties from json dump - :param dump: json dump body - :return: package properties + + Args: + dump(Dict[str, Any]): json dump body + + Returns: + PackageDescription: package properties """ # filter to only known fields known_fields = [pair.name for pair in fields(cls)] @@ -78,9 +87,13 @@ class PackageDescription: def from_package(cls: Type[PackageDescription], package: Package, path: Path) -> PackageDescription: """ construct class from alpm package class - :param package: alpm generated object - :param path: path to package archive - :return: package properties based on tarball + + Args: + package(Package): alpm generated object + path(Path): path to package archive + + Returns: + PackageDescription: package properties based on tarball """ return cls( architecture=package.arch, @@ -98,6 +111,8 @@ class PackageDescription: def view(self) -> Dict[str, Any]: """ generate json package view - :return: json-friendly dictionary + + Returns: + Dict[str, Any]: json-friendly dictionary """ return asdict(self) diff --git a/src/ahriman/models/package_source.py b/src/ahriman/models/package_source.py index 34b3b446..4b27adb0 100644 --- a/src/ahriman/models/package_source.py +++ b/src/ahriman/models/package_source.py @@ -29,13 +29,15 @@ from ahriman.core.util import package_like class PackageSource(Enum): """ package source for addition enumeration - :cvar Auto: automatically determine type of the source - :cvar Archive: source is a package archive - :cvar AUR: source is an AUR package for which it should search - :cvar Directory: source is a directory which contains packages - :cvar Local: source is locally stored PKGBUILD - :cvar Remote: source is remote (http, ftp etc) link - :cvar Repository: source is official repository + + Attributes: + Auto(PackageSource): (class attribute) automatically determine type of the source + Archive(PackageSource): (class attribute) source is a package archive + AUR(PackageSource): (class attribute) source is an AUR package for which it should search + Directory(PackageSource): (class attribute) source is a directory which contains packages + Local(PackageSource): (class attribute) source is locally stored PKGBUILD + Remote(PackageSource): (class attribute) source is remote (http, ftp etc) link + Repository(PackageSource): (class attribute) source is official repository """ Auto = "auto" @@ -49,8 +51,12 @@ class PackageSource(Enum): def resolve(self, source: str) -> PackageSource: """ resolve auto into the correct type - :param source: source of the package - :return: non-auto type of the package source + + Args: + source(str): source of the package + + Returns: + PackageSource: non-auto type of the package source """ if self != PackageSource.Auto: return self diff --git a/src/ahriman/models/property.py b/src/ahriman/models/property.py index 72e6515b..4042ee53 100644 --- a/src/ahriman/models/property.py +++ b/src/ahriman/models/property.py @@ -25,9 +25,11 @@ from typing import Any class Property: """ holder of object properties descriptor - :ivar name: name of the property - :ivar value: property value - :ivar is_required: if set to True then this property is required + + Attributes: + name(str): name of the property + value(Any): property value + is_required(bool): if set to True then this property is required """ name: str diff --git a/src/ahriman/models/report_settings.py b/src/ahriman/models/report_settings.py index 1047c377..e06e11f0 100644 --- a/src/ahriman/models/report_settings.py +++ b/src/ahriman/models/report_settings.py @@ -22,17 +22,17 @@ from __future__ import annotations from enum import Enum from typing import Type -from ahriman.core.exceptions import InvalidOption - class ReportSettings(Enum): """ report targets enumeration - :cvar Disabled: option which generates no report for testing purpose - :cvar HTML: html report generation - :cvar Email: email report generation - :cvar Console: print result to console - :cvar Telegram: markdown report to telegram channel + + Attributes: + Disabled(ReportSettings): (class attribute) option which generates no report for testing purpose + HTML(ReportSettings): (class attribute) html report generation + Email(ReportSettings): (class attribute) email report generation + Console(ReportSettings): (class attribute) print result to console + Telegram(ReportSettings): (class attribute) markdown report to telegram channel """ Disabled = "disabled" # for testing purpose @@ -45,8 +45,12 @@ class ReportSettings(Enum): def from_option(cls: Type[ReportSettings], value: str) -> ReportSettings: """ construct value from configuration - :param value: configuration value - :return: parsed value + + Args: + value(str): configuration value + + Returns: + ReportSettings: parsed value """ if value.lower() in ("html",): return cls.HTML @@ -56,4 +60,4 @@ class ReportSettings(Enum): return cls.Console if value.lower() in ("telegram",): return cls.Telegram - raise InvalidOption(value) + return cls.Disabled diff --git a/src/ahriman/models/repository_paths.py b/src/ahriman/models/repository_paths.py index 146450e8..7d5dc2e1 100644 --- a/src/ahriman/models/repository_paths.py +++ b/src/ahriman/models/repository_paths.py @@ -33,8 +33,10 @@ from ahriman.core.exceptions import InvalidPath class RepositoryPaths: """ repository paths holder. For the most operations with paths you want to use this object - :ivar root: repository root (i.e. ahriman home) - :ivar architecture: repository architecture + + Attributes: + root(Path): repository root (i.e. ahriman home) + architecture(str): repository architecture """ root: Path @@ -43,14 +45,20 @@ class RepositoryPaths: @property def cache(self) -> Path: """ - :return: directory for packages cache (mainly used for VCS packages) + get directory for packages cache (mainly used for VCS packages) + + Returns: + Path: full path to cache directory """ return self.root / "cache" @property def chroot(self) -> Path: """ - :return: directory for devtools chroot + get directory for devtools chroot + + Returns: + Path: full patch to devtools chroot directory """ # for the chroot directory devtools will create own tree, and we don"t have to specify architecture here return self.root / "chroot" @@ -58,21 +66,30 @@ class RepositoryPaths: @property def packages(self) -> Path: """ - :return: directory for built packages + get directory for built packages + + Returns: + Path: full path to built packages directory """ return self.root / "packages" / self.architecture @property def repository(self) -> Path: """ - :return: repository directory + get repository directory + + Returns: + Path: full path to the repository directory """ return self.root / "repository" / self.architecture @property def root_owner(self) -> Tuple[int, int]: """ - :return: owner user and group of the root directory + get UID and GID of the root directory + + Returns: + Tuple[int, int]: owner user and group of the root directory """ return self.owner(self.root) @@ -80,8 +97,12 @@ class RepositoryPaths: def known_architectures(cls: Type[RepositoryPaths], root: Path) -> Set[str]: """ get known architectures - :param root: repository root - :return: list of architectures for which tree is created + + Args: + root(Path): repository root + + Returns: + Set[str]: list of architectures for which tree is created """ paths = cls(root, "") return { @@ -94,8 +115,12 @@ class RepositoryPaths: def owner(path: Path) -> Tuple[int, int]: """ retrieve owner information by path - :param path: path for which extract ids - :return: owner user and group ids of the directory + + Args: + path(Path): path for which extract ids + + Returns: + Tuple[int, int]: owner user and group ids of the directory """ stat = path.stat() return stat.st_uid, stat.st_gid @@ -103,21 +128,26 @@ class RepositoryPaths: def cache_for(self, package_base: str) -> Path: """ get path to cached PKGBUILD and package sources for the package base - :param package_base: package base name - :return: full path to directory for specified package base cache + + Args: + package_base(str): package base name + + Returns: + Path: full path to directory for specified package base cache """ return self.cache / package_base def chown(self, path: Path) -> None: """ set owner of path recursively (from root) to root owner - :param path: path to be chown + + Args: + path(Path): path to be chown + + Raises: + InvalidPath: if path does not belong to root """ def set_owner(current: Path) -> None: - """ - set owner to the specified path - :param current: path to set - """ uid, gid = self.owner(current) if uid == root_uid and gid == root_gid: return @@ -133,7 +163,9 @@ class RepositoryPaths: def tree_clear(self, package_base: str) -> None: """ clear package specific files - :param package_base: package base name + + Args: + package_base(str): package base name """ for directory in ( self.cache_for(package_base), diff --git a/src/ahriman/models/result.py b/src/ahriman/models/result.py index 3f1e443d..557f93a3 100644 --- a/src/ahriman/models/result.py +++ b/src/ahriman/models/result.py @@ -33,8 +33,10 @@ class Result: def __init__(self, success: Optional[Iterable[Package]] = None, failed: Optional[Iterable[Package]] = None) -> None: """ default constructor - :param success: initial list of successes packages - :param failed: initial list of failed packages + + Args: + success(Optional[Iterable[Package]], optional): initial list of successes packages (Default value = None) + failed(Optional[Iterable[Package]], optional): initial list of failed packages (Default value = None) """ success = success or [] self._success = {package.base: package for package in success} @@ -44,35 +46,48 @@ class Result: @property def failed(self) -> List[Package]: """ - :return: list of packages which were failed + get list of failed packages + + Returns: + List[Package]: list of packages which were failed """ return list(self._failed.values()) @property def is_empty(self) -> bool: """ - :return: True in case if success list is empty and False otherwise + get if build result is empty or not + + Returns: + bool: True in case if success list is empty and False otherwise """ return not bool(self._success) @property def success(self) -> List[Package]: """ - :return: list of packages with success result + get list of success builds + + Returns: + List[Package]: list of packages with success result """ return list(self._success.values()) def add_failed(self, package: Package) -> None: """ add new package to failed built - :param package: package with errors during build + + Args: + package(Package): package with errors during build """ self._failed[package.base] = package def add_success(self, package: Package) -> None: """ add new package to success built - :param package: package built + + Args: + package(Package): package built """ self._success[package.base] = package @@ -80,8 +95,15 @@ class Result: def merge(self, other: Result) -> Result: """ merge other result into this one. This method assumes that other has fresh info about status and override it - :param other: instance of the newest result - :return: updated instance + + Args: + other(Result): instance of the newest result + + Returns: + Result: updated instance + + Raises: + SuccessFailed: if there is previously failed package which is masked as success """ for base, package in other._failed.items(): if base in self._success: @@ -97,8 +119,12 @@ class Result: def __eq__(self, other: Any) -> bool: """ check if other is the same object - :param other: other object instance - :return: True if the other object is the same and False otherwise + + Args: + other(Any): other object instance + + Returns: + bool: True if the other object is the same and False otherwise """ if not isinstance(other, Result): return False diff --git a/src/ahriman/models/sign_settings.py b/src/ahriman/models/sign_settings.py index 98bbfa8f..93a55537 100644 --- a/src/ahriman/models/sign_settings.py +++ b/src/ahriman/models/sign_settings.py @@ -22,16 +22,18 @@ from __future__ import annotations from enum import Enum from typing import Type -from ahriman.core.exceptions import InvalidOption - class SignSettings(Enum): """ sign targets enumeration - :cvar Packages: sign each package - :cvar Repository: sign repository database file + + Attributes: + Disabled(SignSettings): (class attribute) option which generates no report for testing purpose + Packages(SignSettings): (class attribute) sign each package + Repository(SignSettings): (class attribute) sign repository database file """ + Disabled = "disabled" Packages = "pacakges" Repository = "repository" @@ -39,11 +41,15 @@ class SignSettings(Enum): def from_option(cls: Type[SignSettings], value: str) -> SignSettings: """ construct value from configuration - :param value: configuration value - :return: parsed value + + Args: + value(str): configuration value + + Returns: + SignSettings: parsed value """ if value.lower() in ("package", "packages", "sign-package"): return cls.Packages if value.lower() in ("repository", "sign-repository"): return cls.Repository - raise InvalidOption(value) + return cls.Disabled diff --git a/src/ahriman/models/smtp_ssl_settings.py b/src/ahriman/models/smtp_ssl_settings.py index 96255d45..fb700495 100644 --- a/src/ahriman/models/smtp_ssl_settings.py +++ b/src/ahriman/models/smtp_ssl_settings.py @@ -26,9 +26,11 @@ from typing import Type class SmtpSSLSettings(Enum): """ SMTP SSL mode enumeration - :cvar Disabled: no SSL enabled - :cvar SSL: use SMTP_SSL instead of normal SMTP client - :cvar STARTTLS: use STARTTLS in normal SMTP client + + Attributes: + Disabled(SmtpSSLSettings): (class attribute) no SSL enabled + SSL(SmtpSSLSettings): (class attribute) use SMTP_SSL instead of normal SMTP client + STARTTLS(SmtpSSLSettings): (class attribute) use STARTTLS in normal SMTP client """ Disabled = "disabled" @@ -39,8 +41,12 @@ class SmtpSSLSettings(Enum): def from_option(cls: Type[SmtpSSLSettings], value: str) -> SmtpSSLSettings: """ construct value from configuration - :param value: configuration value - :return: parsed value + + Args: + value(str): configuration value + + Returns: + SmtpSSLSettings: parsed value """ if value.lower() in ("ssl", "ssl/tls"): return cls.SSL diff --git a/src/ahriman/models/upload_settings.py b/src/ahriman/models/upload_settings.py index cdc11d6f..408e391d 100644 --- a/src/ahriman/models/upload_settings.py +++ b/src/ahriman/models/upload_settings.py @@ -22,16 +22,16 @@ from __future__ import annotations from enum import Enum from typing import Type -from ahriman.core.exceptions import InvalidOption - class UploadSettings(Enum): """ remote synchronization targets enumeration - :cvar Disabled: no sync will be performed, required for testing purpose - :cvar Rsync: sync via rsync - :cvar S3: sync to Amazon S3 - :cvar Github: sync to github releases page + + Attributes: + Disabled(UploadSettings): (class attribute) no sync will be performed, required for testing purpose + Rsync(UploadSettings): (class attribute) sync via rsync + S3(UploadSettings): (class attribute) sync to Amazon S3 + Github(UploadSettings): (class attribute) sync to github releases page """ Disabled = "disabled" # for testing purpose @@ -43,8 +43,12 @@ class UploadSettings(Enum): def from_option(cls: Type[UploadSettings], value: str) -> UploadSettings: """ construct value from configuration - :param value: configuration value - :return: parsed value + + Args: + value(str): configuration value + + Returns: + UploadSettings: parsed value """ if value.lower() in ("rsync",): return cls.Rsync @@ -52,4 +56,4 @@ class UploadSettings(Enum): return cls.S3 if value.lower() in ("github",): return cls.Github - raise InvalidOption(value) + return cls.Disabled diff --git a/src/ahriman/models/user.py b/src/ahriman/models/user.py index ca855cad..b736483f 100644 --- a/src/ahriman/models/user.py +++ b/src/ahriman/models/user.py @@ -31,9 +31,11 @@ from ahriman.models.user_access import UserAccess class User: """ authorized web user model - :ivar username: username - :ivar password: hashed user password with salt - :ivar access: user role + + Attributes: + username(str): username + password(str): hashed user password with salt + access(UserAccess): user role """ username: str @@ -47,10 +49,14 @@ class User: access: UserAccess = UserAccess.Read) -> Optional[User]: """ build user descriptor from configuration options - :param username: username - :param password: password as string - :param access: optional user access - :return: generated user descriptor if all options are supplied and None otherwise + + Args: + username(Optional[str]): username + password(Optional[str]): password as string + access(UserAccess, optional): optional user access (Default value = UserAccess.Read) + + Returns: + Optional[User]: generated user descriptor if all options are supplied and None otherwise """ if username is None or password is None: return None @@ -60,8 +66,12 @@ class User: def generate_password(length: int) -> str: """ generate password with specified length - :param length: password length - :return: random string which contains letters and numbers + + Args: + length(int): password length + + Returns: + str: random string which contains letters and numbers """ password: str = generate_password(length=length) return password @@ -69,9 +79,13 @@ class User: def check_credentials(self, password: str, salt: str) -> bool: """ validate user password - :param password: entered password - :param salt: salt for hashed password - :return: True in case if password matches, False otherwise + + Args: + password(str): entered password + salt(str): salt for hashed password + + Returns: + bool: True in case if password matches, False otherwise """ try: verified: bool = self._HASHER.verify(password + salt, self.password) @@ -82,8 +96,12 @@ class User: def hash_password(self, salt: str) -> User: """ generate hashed password from plain text - :param salt: salt for hashed password - :return: user with hashed password to store in configuration + + Args: + salt(str): salt for hashed password + + Returns: + User: user with hashed password to store in configuration """ if not self.password: # in case of empty password we leave it empty. This feature is used by any external (like OAuth) provider @@ -95,8 +113,12 @@ class User: def verify_access(self, required: UserAccess) -> bool: """ validate if user has access to requested resource - :param required: required access level - :return: True in case if user is allowed to do this request and False otherwise + + Args: + required(UserAccess): required access level + + Returns: + bool: True in case if user is allowed to do this request and False otherwise """ if self.access == UserAccess.Write: return True # everything is allowed @@ -105,6 +127,8 @@ class User: def __repr__(self) -> str: """ generate string representation of object - :return: unique string representation + + Returns: + str: unique string representation """ return f"User(username={self.username}, access={self.access})" diff --git a/src/ahriman/models/user_access.py b/src/ahriman/models/user_access.py index 630eaf2f..7e013f27 100644 --- a/src/ahriman/models/user_access.py +++ b/src/ahriman/models/user_access.py @@ -23,9 +23,12 @@ from enum import Enum class UserAccess(Enum): """ web user access enumeration - :cvar Safe: user can access the page without authorization, should not be user for user configuration - :cvar Read: user can read the page - :cvar Write: user can modify task and package list + + Attributes: + Safe(UserAccess): (class attribute) user can access the page without authorization, + should not be used for user configuration + Read(UserAccess): (class attribute) user can read the page + Write(UserAccess): (class attribute) user can modify task and package list """ Safe = "safe" diff --git a/src/ahriman/models/user_identity.py b/src/ahriman/models/user_identity.py index 5d8d20a6..449edcf4 100644 --- a/src/ahriman/models/user_identity.py +++ b/src/ahriman/models/user_identity.py @@ -29,8 +29,10 @@ from typing import Optional, Type class UserIdentity: """ user identity used inside web service - :ivar username: username - :ivar expire_at: identity expiration timestamp + + Attributes: + username(str): username + expire_at(int): identity expiration timestamp """ username: str @@ -40,8 +42,12 @@ class UserIdentity: def from_identity(cls: Type[UserIdentity], identity: str) -> Optional[UserIdentity]: """ parse identity into object - :param identity: identity from session data - :return: user identity object if it can be parsed and not expired and None otherwise + + Args: + identity(str): identity from session data + + Returns: + Optional[UserIdentity]: user identity object if it can be parsed and not expired and None otherwise """ try: username, expire_at = identity.split() @@ -54,9 +60,13 @@ class UserIdentity: def from_username(cls: Type[UserIdentity], username: Optional[str], max_age: int) -> Optional[UserIdentity]: """ generate identity from username - :param username: username - :param max_age: time to expire, seconds - :return: constructed identity object + + Args: + username(Optional[str]): username + max_age(int): time to expire, seconds + + Returns: + Optional[UserIdentity]: constructed identity object """ return cls(username, cls.expire_when(max_age)) if username is not None else None @@ -64,21 +74,29 @@ class UserIdentity: def expire_when(max_age: int) -> int: """ generate expiration time using delta - :param max_age: time delta to generate. Must be usually TTE - :return: expiration timestamp + + Args: + max_age(int): time delta to generate. Must be usually TTE + + Returns: + int: expiration timestamp """ return int(time.time()) + max_age def is_expired(self) -> bool: """ compare timestamp with current timestamp and return True in case if identity is expired - :return: True in case if identity is expired and False otherwise + + Returns: + bool: True in case if identity is expired and False otherwise """ return self.expire_when(0) > self.expire_at def to_identity(self) -> str: """ convert object to identity representation - :return: web service identity + + Returns: + str: web service identity """ return f"{self.username} {self.expire_at}" diff --git a/src/ahriman/web/middlewares/auth_handler.py b/src/ahriman/web/middlewares/auth_handler.py index cc136653..ad4d4ca5 100644 --- a/src/ahriman/web/middlewares/auth_handler.py +++ b/src/ahriman/web/middlewares/auth_handler.py @@ -39,21 +39,29 @@ from ahriman.web.middlewares import HandlerType, MiddlewareType class AuthorizationPolicy(aiohttp_security.AbstractAuthorizationPolicy): # type: ignore """ authorization policy implementation - :ivar validator: validator instance + + Attributes: + validator(Auth): validator instance """ def __init__(self, validator: Auth) -> None: """ default constructor - :param validator: authorization module instance + + Args: + validator(Auth): authorization module instance """ self.validator = validator async def authorized_userid(self, identity: str) -> Optional[str]: """ retrieve authenticated username - :param identity: username - :return: user identity (username) in case if user exists and None otherwise + + Args: + identity(str): username + + Returns: + Optional[str]: user identity (username) in case if user exists and None otherwise """ user = UserIdentity.from_identity(identity) if user is None: @@ -63,10 +71,14 @@ class AuthorizationPolicy(aiohttp_security.AbstractAuthorizationPolicy): # type async def permits(self, identity: str, permission: UserAccess, context: Optional[str] = None) -> bool: """ check user permissions - :param identity: username - :param permission: requested permission level - :param context: URI request path - :return: True in case if user is allowed to perform this request and False otherwise + + Args: + identity(str): username + permission(UserAccess): requested permission level + context(Optional[str], optional): URI request path (Default value = None) + + Returns: + bool: True in case if user is allowed to perform this request and False otherwise """ user = UserIdentity.from_identity(identity) if user is None: @@ -77,7 +89,9 @@ class AuthorizationPolicy(aiohttp_security.AbstractAuthorizationPolicy): # type def auth_handler() -> MiddlewareType: """ authorization and authentication middleware - :return: built middleware + + Returns: + MiddlewareType: built middleware """ @middleware async def handle(request: Request, handler: HandlerType) -> StreamResponse: @@ -99,9 +113,13 @@ def auth_handler() -> MiddlewareType: def setup_auth(application: web.Application, validator: Auth) -> web.Application: """ setup authorization policies for the application - :param application: web application instance - :param validator: authorization module instance - :return: configured web application + + Args: + application(web.Application): web application instance + validator(Auth): authorization module instance + + Returns: + web.Application: configured web application """ fernet_key = fernet.Fernet.generate_key() secret_key = base64.urlsafe_b64decode(fernet_key) diff --git a/src/ahriman/web/middlewares/exception_handler.py b/src/ahriman/web/middlewares/exception_handler.py index 0bbcc899..dcd803f6 100644 --- a/src/ahriman/web/middlewares/exception_handler.py +++ b/src/ahriman/web/middlewares/exception_handler.py @@ -28,8 +28,12 @@ from ahriman.web.middlewares import HandlerType, MiddlewareType def exception_handler(logger: Logger) -> MiddlewareType: """ exception handler middleware. Just log any exception (except for client ones) - :param logger: class logger - :return: built middleware + + Args: + logger(Logger): class logger + + Returns: + MiddlewareType: built middleware """ @middleware async def handle(request: Request, handler: HandlerType) -> StreamResponse: @@ -40,8 +44,8 @@ def exception_handler(logger: Logger) -> MiddlewareType: except HTTPServerError as e: logger.exception("server exception during performing request to %s", request.path) return json_response(data={"error": e.reason}, status=e.status_code) - except HTTPException: - raise # just raise 2xx and 3xx codes + except HTTPException: # just raise 2xx and 3xx codes + raise except Exception as e: logger.exception("unknown exception during performing request to %s", request.path) return json_response(data={"error": str(e)}, status=500) diff --git a/src/ahriman/web/routes.py b/src/ahriman/web/routes.py index 0996a216..4229d489 100644 --- a/src/ahriman/web/routes.py +++ b/src/ahriman/web/routes.py @@ -39,37 +39,38 @@ def setup_routes(application: Application, static_path: Path) -> None: Available routes are: - GET / get build status page - GET /index.html same as above + * GET / get build status page + * GET /index.html same as above - POST /service-api/v1/add add new packages to repository + * POST /service-api/v1/add add new packages to repository - POST /service-api/v1/remove remove existing package from repository + * POST /service-api/v1/remove remove existing package from repository - POST /service-api/v1/request request to add new packages to repository + * POST /service-api/v1/request request to add new packages to repository - GET /service-api/v1/search search for substring in AUR + * GET /service-api/v1/search search for substring in AUR - POST /service-api/v1/update update packages in repository, actually it is just alias for add + * POST /service-api/v1/update update packages in repository, actually it is just alias for add - GET /status-api/v1/ahriman get current service status - POST /status-api/v1/ahriman update service status + * GET /status-api/v1/ahriman get current service status + * POST /status-api/v1/ahriman update service status - GET /status-api/v1/packages get all known packages - POST /status-api/v1/packages force update every package from repository + * GET /status-api/v1/packages get all known packages + * POST /status-api/v1/packages force update every package from repository - DELETE /status-api/v1/package/:base delete package base from status page - GET /status-api/v1/package/:base get package base status - POST /status-api/v1/package/:base update package base status + * DELETE /status-api/v1/package/:base delete package base from status page + * GET /status-api/v1/package/:base get package base status + * POST /status-api/v1/package/:base update package base status - GET /status-api/v1/status get web service status itself + * GET /status-api/v1/status get web service status itself - GET /user-api/v1/login OAuth2 handler for login - POST /user-api/v1/login login to service - POST /user-api/v1/logout logout from service + * GET /user-api/v1/login OAuth2 handler for login + * POST /user-api/v1/login login to service + * POST /user-api/v1/logout logout from service - :param application: web application instance - :param static_path: path to static files directory + Args: + application(Application): web application instance + static_path(Path): path to static files directory """ application.router.add_get("/", IndexView, allow_head=True) application.router.add_get("/index.html", IndexView, allow_head=True) diff --git a/src/ahriman/web/views/base.py b/src/ahriman/web/views/base.py index 17ac2ff7..1b29acf7 100644 --- a/src/ahriman/web/views/base.py +++ b/src/ahriman/web/views/base.py @@ -38,7 +38,10 @@ class BaseView(View): @property def configuration(self) -> Configuration: """ - :return: configuration instance + get configuration instance + + Returns: + Configuration: configuration instance """ configuration: Configuration = self.request.app["configuration"] return configuration @@ -46,7 +49,10 @@ class BaseView(View): @property def database(self) -> SQLite: """ - :return: database instance + get database instance + + Returns: + SQLite: database instance """ database: SQLite = self.request.app["database"] return database @@ -54,7 +60,10 @@ class BaseView(View): @property def service(self) -> Watcher: """ - :return: build status watcher instance + get status watcher instance + + Returns: + Watcher: build status watcher instance """ watcher: Watcher = self.request.app["watcher"] return watcher @@ -62,7 +71,10 @@ class BaseView(View): @property def spawner(self) -> Spawn: """ - :return: external process spawner instance + get process spawner instance + + Returns: + Spawn: external process spawner instance """ spawner: Spawn = self.request.app["spawn"] return spawner @@ -70,7 +82,10 @@ class BaseView(View): @property def validator(self) -> Auth: """ - :return: authorization service instance + get authorization instance + + Returns: + Auth: authorization service instance """ validator: Auth = self.request.app["validator"] return validator @@ -79,8 +94,12 @@ class BaseView(View): async def get_permission(cls: Type[BaseView], request: Request) -> UserAccess: """ retrieve user permission from the request - :param request: request object - :return: extracted permission + + Args: + request(Request): request object + + Returns: + UserAccess: extracted permission """ permission: UserAccess = getattr(cls, f"{request.method.upper()}_PERMISSION", UserAccess.Write) return permission @@ -88,8 +107,13 @@ class BaseView(View): async def extract_data(self, list_keys: Optional[List[str]] = None) -> Dict[str, Any]: """ extract json data from either json or form data - :param list_keys: optional list of keys which must be forced to list from form data - :return: raw json object or form data converted to json + + Args: + list_keys(Optional[List[str]], optional): optional list of keys which must be forced to list from form data + (Default value = None) + + Returns: + Dict[str, Any]: raw json object or form data converted to json """ try: json: Dict[str, Any] = await self.request.json() @@ -100,8 +124,13 @@ class BaseView(View): async def data_as_json(self, list_keys: List[str]) -> Dict[str, Any]: """ extract form data and convert it to json object - :param list_keys: list of keys which must be forced to list from form data - :return: form data converted to json. In case if a key is found multiple times it will be returned as list + + Args: + list_keys(List[str]): list of keys which must be forced to list from form data + + Returns: + Dict[str, Any]: form data converted to json. In case if a key is found multiple times + it will be returned as list """ raw = await self.request.post() json: Dict[str, Any] = {} diff --git a/src/ahriman/web/views/index.py b/src/ahriman/web/views/index.py index 9dd9e51d..ddb6ab4b 100644 --- a/src/ahriman/web/views/index.py +++ b/src/ahriman/web/views/index.py @@ -31,35 +31,37 @@ from ahriman.web.views.base import BaseView class IndexView(BaseView): """ root view - :cvar GET_PERMISSION: get permissions of self - :cvar HEAD_PERMISSION: head permissions of self It uses jinja2 templates for report generation, the following variables are allowed: - architecture - repository architecture, string, required - auth - authorization descriptor, required - * authenticated - alias to check if user can see the page, boolean, required - * control - HTML to insert for login control, HTML string, required - * enabled - whether authorization is enabled by configuration or not, boolean, required - * username - authenticated username if any, string, null means not authenticated - index_url - url to the repository index, string, optional - packages - sorted list of packages properties, required - * base, string - * depends, sorted list of strings - * groups, sorted list of strings - * licenses, sorted list of strings - * packages, sorted list of strings - * status, string based on enum value - * status_color, string based on enum value - * timestamp, pretty printed datetime, string - * version, string - * web_url, string - repository - repository name, string, required - service - service status properties, required - * status, string based on enum value - * status_color, string based on enum value - * timestamp, pretty printed datetime, string - version - ahriman version, string, required + * architecture - repository architecture, string, required + * auth - authorization descriptor, required + * authenticated - alias to check if user can see the page, boolean, required + * control - HTML to insert for login control, HTML string, required + * enabled - whether authorization is enabled by configuration or not, boolean, required + * username - authenticated username if any, string, null means not authenticated + * index_url - url to the repository index, string, optional + * packages - sorted list of packages properties, required + * base, string + * depends, sorted list of strings + * groups, sorted list of strings + * licenses, sorted list of strings + * packages, sorted list of strings + * status, string based on enum value + * status_color, string based on enum value + * timestamp, pretty printed datetime, string + * version, string + * web_url, string + * repository - repository name, string, required + * service - service status properties, required + * status, string based on enum value + * status_color, string based on enum value + * timestamp, pretty printed datetime, string + * version - ahriman version, string, required + + Attributes: + GET_PERMISSION(UserAccess): (class attribute) get permissions of self + HEAD_PERMISSION(UserAccess): (class attribute) head permissions of self """ GET_PERMISSION = HEAD_PERMISSION = UserAccess.Safe @@ -68,7 +70,9 @@ class IndexView(BaseView): async def get(self) -> Dict[str, Any]: """ process get request. No parameters supported here - :return: parameters for jinja template + + Returns: + Dict[str, Any]: parameters for jinja template """ # some magic to make it jinja-friendly packages = [ diff --git a/src/ahriman/web/views/service/add.py b/src/ahriman/web/views/service/add.py index e07e013f..1a75f6ea 100644 --- a/src/ahriman/web/views/service/add.py +++ b/src/ahriman/web/views/service/add.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -from aiohttp.web import HTTPBadRequest, HTTPFound, Response +from aiohttp.web import HTTPBadRequest, HTTPFound from ahriman.models.user_access import UserAccess from ahriman.web.views.base import BaseView @@ -26,21 +26,26 @@ from ahriman.web.views.base import BaseView class AddView(BaseView): """ add package web view - :cvar POST_PERMISSION: post permissions of self + + Attributes: + POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ POST_PERMISSION = UserAccess.Write - async def post(self) -> Response: + async def post(self) -> None: """ add new package JSON body must be supplied, the following model is used: - { - "packages": "ahriman" # either list of packages or package name as in AUR - } - :return: redirect to main page on success + >>> { + >>> "packages": "ahriman" # either list of packages or package name as in AUR + >>> } + + Raises: + HTTPBadRequest: if bad data is supplied + HTTPFound: in case of success response """ try: data = await self.extract_data(["packages"]) diff --git a/src/ahriman/web/views/service/remove.py b/src/ahriman/web/views/service/remove.py index bf4e32a3..baf6e2cb 100644 --- a/src/ahriman/web/views/service/remove.py +++ b/src/ahriman/web/views/service/remove.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -from aiohttp.web import HTTPBadRequest, HTTPFound, Response +from aiohttp.web import HTTPBadRequest, HTTPFound from ahriman.models.user_access import UserAccess from ahriman.web.views.base import BaseView @@ -26,21 +26,26 @@ from ahriman.web.views.base import BaseView class RemoveView(BaseView): """ remove package web view - :cvar POST_PERMISSION: post permissions of self + + Attributes: + POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ POST_PERMISSION = UserAccess.Write - async def post(self) -> Response: + async def post(self) -> None: """ remove existing packages JSON body must be supplied, the following model is used: - { - "packages": "ahriman", # either list of packages or package name - } - :return: redirect to main page on success + >>> { + >>> "packages": "ahriman", # either list of packages or package name + >>> } + + Raises: + HTTPBadRequest: if bad data is supplied + HTTPFound: in case of success response """ try: data = await self.extract_data(["packages"]) diff --git a/src/ahriman/web/views/service/request.py b/src/ahriman/web/views/service/request.py index e9df733c..4ae03adf 100644 --- a/src/ahriman/web/views/service/request.py +++ b/src/ahriman/web/views/service/request.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -from aiohttp.web import HTTPBadRequest, HTTPFound, Response +from aiohttp.web import HTTPBadRequest, HTTPFound from ahriman.models.user_access import UserAccess from ahriman.web.views.base import BaseView @@ -26,21 +26,26 @@ from ahriman.web.views.base import BaseView class RequestView(BaseView): """ request package web view. It is actually the same as AddView, but without now - :cvar POST_PERMISSION: post permissions of self + + Attributes: + POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ POST_PERMISSION = UserAccess.Read - async def post(self) -> Response: + async def post(self) -> None: """ request to add new package JSON body must be supplied, the following model is used: - { - "packages": "ahriman" # either list of packages or package name as in AUR - } - :return: redirect to main page on success + >>> { + >>> "packages": "ahriman" # either list of packages or package name as in AUR + >>> } + + Raises: + HTTPBadRequest: if bad data is supplied + HTTPFound: in case of success response """ try: data = await self.extract_data(["packages"]) diff --git a/src/ahriman/web/views/service/search.py b/src/ahriman/web/views/service/search.py index 3d222e67..dbb5fe62 100644 --- a/src/ahriman/web/views/service/search.py +++ b/src/ahriman/web/views/service/search.py @@ -29,8 +29,10 @@ from ahriman.web.views.base import BaseView class SearchView(BaseView): """ AUR search web view - :cvar GET_PERMISSION: get permissions of self - :cvar HEAD_PERMISSION: head permissions of self + + Attributes: + GET_PERMISSION(UserAccess): (class attribute) get permissions of self + HEAD_PERMISSION(UserAccess): (class attribute) head permissions of self """ GET_PERMISSION = HEAD_PERMISSION = UserAccess.Read @@ -41,7 +43,11 @@ class SearchView(BaseView): search string (non empty) must be supplied as `for` parameter - :return: 200 with found package bases and descriptions sorted by base + Returns: + Response: 200 with found package bases and descriptions sorted by base + + Raises: + HTTPNotFound: if no packages found """ search: List[str] = self.request.query.getall("for", default=[]) packages = AUR.multisearch(*search) diff --git a/src/ahriman/web/views/status/ahriman.py b/src/ahriman/web/views/status/ahriman.py index a7327639..a1ca5256 100644 --- a/src/ahriman/web/views/status/ahriman.py +++ b/src/ahriman/web/views/status/ahriman.py @@ -27,9 +27,11 @@ from ahriman.web.views.base import BaseView class AhrimanView(BaseView): """ service status web view - :cvar GET_PERMISSION: get permissions of self - :cvar HEAD_PERMISSION: head permissions of self - :cvar POST_PERMISSION: post permissions of self + + Attributes: + GET_PERMISSION(UserAccess): (class attribute) get permissions of self + HEAD_PERMISSION(UserAccess): (class attribute) head permissions of self + POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ GET_PERMISSION = HEAD_PERMISSION = UserAccess.Read @@ -38,20 +40,25 @@ class AhrimanView(BaseView): async def get(self) -> Response: """ get current service status - :return: 200 with service status object + + Returns: + Response: 200 with service status object """ return json_response(self.service.status.view()) - async def post(self) -> Response: + async def post(self) -> None: """ update service status JSON body must be supplied, the following model is used: - { - "status": "unknown", # service status string, must be valid `BuildStatusEnum` - } - :return: 204 on success + >>> { + >>> "status": "unknown", # service status string, must be valid `BuildStatusEnum` + >>> } + + Raises: + HTTPBadRequest: if bad data is supplied + HTTPNoContent: in case of success response """ try: data = await self.extract_data() diff --git a/src/ahriman/web/views/status/package.py b/src/ahriman/web/views/status/package.py index 9f42c6ed..893a068b 100644 --- a/src/ahriman/web/views/status/package.py +++ b/src/ahriman/web/views/status/package.py @@ -29,10 +29,12 @@ from ahriman.web.views.base import BaseView class PackageView(BaseView): """ package base specific web view - :cvar DELETE_PERMISSION: delete permissions of self - :cvar GET_PERMISSION: get permissions of self - :cvar HEAD_PERMISSION: head permissions of self - :cvar POST_PERMISSION: post permissions of self + + Attributes: + DELETE_PERMISSION(UserAccess): (class attribute) delete permissions of self + GET_PERMISSION(UserAccess): (class attribute) get permissions of self + HEAD_PERMISSION(UserAccess): (class attribute) head permissions of self + POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ DELETE_PERMISSION = POST_PERMISSION = UserAccess.Write @@ -41,7 +43,12 @@ class PackageView(BaseView): async def get(self) -> Response: """ get current package base status - :return: 200 with package description on success + + Returns: + Response: 200 with package description on success + + Raises: + HTTPNotFound: if no package was found """ base = self.request.match_info["package"] @@ -58,28 +65,33 @@ class PackageView(BaseView): ] return json_response(response) - async def delete(self) -> Response: + async def delete(self) -> None: """ delete package base from status page - :return: 204 on success + + Raises: + HTTPNoContent: on success response """ base = self.request.match_info["package"] self.service.remove(base) raise HTTPNoContent() - async def post(self) -> Response: + async def post(self) -> None: """ update package build status JSON body must be supplied, the following model is used: - { - "status": "unknown", # package build status string, must be valid `BuildStatusEnum` - "package": {} # package body (use `dataclasses.asdict` to generate one), optional. - # Must be supplied in case if package base is unknown - } - :return: 204 on success + >>> { + >>> "status": "unknown", # package build status string, must be valid `BuildStatusEnum` + >>> "package": {} # package body (use `dataclasses.asdict` to generate one), optional. + >>> # Must be supplied in case if package base is unknown + >>> } + + Raises: + HTTPBadRequest: if bad data is supplied + HTTPNoContent: in case of success response """ base = self.request.match_info["package"] data = await self.extract_data() diff --git a/src/ahriman/web/views/status/packages.py b/src/ahriman/web/views/status/packages.py index e758e88f..701a50a2 100644 --- a/src/ahriman/web/views/status/packages.py +++ b/src/ahriman/web/views/status/packages.py @@ -26,9 +26,11 @@ from ahriman.web.views.base import BaseView class PackagesView(BaseView): """ global watcher view - :cvar GET_PERMISSION: get permissions of self - :cvar HEAD_PERMISSION: head permissions of self - :cvar POST_PERMISSION: post permissions of self + + Attributes: + GET_PERMISSION(UserAccess): (class attribute) get permissions of self + HEAD_PERMISSION(UserAccess): (class attribute) head permissions of self + POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ GET_PERMISSION = HEAD_PERMISSION = UserAccess.Read @@ -37,7 +39,9 @@ class PackagesView(BaseView): async def get(self) -> Response: """ get current packages status - :return: 200 with package description on success + + Returns: + Response: 200 with package description on success """ response = [ { @@ -47,10 +51,12 @@ class PackagesView(BaseView): ] return json_response(response) - async def post(self) -> Response: + async def post(self) -> None: """ reload all packages from repository. No parameters supported here - :return: 204 on success + + Raises: + HTTPNoContent: on success response """ self.service.load() diff --git a/src/ahriman/web/views/status/status.py b/src/ahriman/web/views/status/status.py index 1a0fa8a2..32a37d58 100644 --- a/src/ahriman/web/views/status/status.py +++ b/src/ahriman/web/views/status/status.py @@ -29,8 +29,10 @@ from ahriman.web.views.base import BaseView class StatusView(BaseView): """ web service status web view - :cvar GET_PERMISSION: get permissions of self - :cvar HEAD_PERMISSION: head permissions of self + + Attributes: + GET_PERMISSION(UserAccess): (class attribute) get permissions of self + HEAD_PERMISSION(UserAccess): (class attribute) head permissions of self """ GET_PERMISSION = HEAD_PERMISSION = UserAccess.Read @@ -38,7 +40,9 @@ class StatusView(BaseView): async def get(self) -> Response: """ get current service status - :return: 200 with service status object + + Returns: + Response: 200 with service status object """ counters = Counters.from_packages(self.service.packages) status = InternalStatus( diff --git a/src/ahriman/web/views/user/login.py b/src/ahriman/web/views/user/login.py index 637295a9..9f571398 100644 --- a/src/ahriman/web/views/user/login.py +++ b/src/ahriman/web/views/user/login.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -from aiohttp.web import HTTPFound, HTTPMethodNotAllowed, HTTPUnauthorized, Response +from aiohttp.web import HTTPFound, HTTPMethodNotAllowed, HTTPUnauthorized from ahriman.core.auth.helpers import remember from ahriman.models.user_access import UserAccess @@ -28,20 +28,25 @@ from ahriman.web.views.base import BaseView class LoginView(BaseView): """ login endpoint view - :cvar GET_PERMISSION: get permissions of self - :cvar POST_PERMISSION: post permissions of self + + Attributes: + GET_PERMISSION(UserAccess): (class attribute) get permissions of self + POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ GET_PERMISSION = POST_PERMISSION = UserAccess.Safe - async def get(self) -> Response: + async def get(self) -> None: """ OAuth2 response handler In case if code provided it will do a request to get user email. In case if no code provided it will redirect to authorization url provided by OAuth client - :return: redirect to main page + Raises: + HTTPFound: on success response + HTTPMethodNotAllowed: in case if method is used, but OAuth is disabled + HTTPUnauthorized: if case of authorization error """ from ahriman.core.auth.oauth import OAuth @@ -62,17 +67,20 @@ class LoginView(BaseView): raise HTTPUnauthorized() - async def post(self) -> Response: + async def post(self) -> None: """ login user to service either JSON body or form data must be supplied the following fields are required: - { - "username": "username" # username to use for login - "password": "pa55w0rd" # password to use for login - } - :return: redirect to main page + >>> { + >>> "username": "username" # username to use for login + >>> "password": "pa55w0rd" # password to use for login + >>> } + + Raises: + HTTPFound: on success response + HTTPUnauthorized: if case of authorization error """ data = await self.extract_data() username = data.get("username") diff --git a/src/ahriman/web/views/user/logout.py b/src/ahriman/web/views/user/logout.py index 0edd1176..1e9ebbfe 100644 --- a/src/ahriman/web/views/user/logout.py +++ b/src/ahriman/web/views/user/logout.py @@ -17,7 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -from aiohttp.web import HTTPFound, Response +from aiohttp.web import HTTPFound from ahriman.core.auth.helpers import check_authorized, forget from ahriman.models.user_access import UserAccess @@ -27,15 +27,19 @@ from ahriman.web.views.base import BaseView class LogoutView(BaseView): """ logout endpoint view - :cvar POST_PERMISSION: post permissions of self + + Attributes: + POST_PERMISSION(UserAccess): (class attribute) post permissions of self """ POST_PERMISSION = UserAccess.Safe - async def post(self) -> Response: + async def post(self) -> None: """ logout user from the service. No parameters supported here - :return: redirect to main page + + Raises: + HTTPFound: on success response """ await check_authorized(self.request) await forget(self.request, HTTPFound("/")) diff --git a/src/ahriman/web/web.py b/src/ahriman/web/web.py index 273ca5be..233b7462 100644 --- a/src/ahriman/web/web.py +++ b/src/ahriman/web/web.py @@ -36,7 +36,9 @@ from ahriman.web.routes import setup_routes async def on_shutdown(application: web.Application) -> None: """ web application shutdown handler - :param application: web application instance + + Args: + application(web.Application): web application instance """ application.logger.warning("server terminated") @@ -44,7 +46,12 @@ async def on_shutdown(application: web.Application) -> None: async def on_startup(application: web.Application) -> None: """ web application start handler - :param application: web application instance + + Args: + application(web.Application): web application instance + + Raises: + InitializeException: in case if matched could not be loaded """ application.logger.info("server started") try: @@ -58,7 +65,9 @@ async def on_startup(application: web.Application) -> None: def run_server(application: web.Application) -> None: """ run web application - :param application: web application instance + + Args: + application(web.Application): web application instance """ application.logger.info("start server") @@ -73,10 +82,14 @@ def run_server(application: web.Application) -> None: def setup_service(architecture: str, configuration: Configuration, spawner: Spawn) -> web.Application: """ create web application - :param architecture: repository architecture - :param configuration: configuration instance - :param spawner: spawner thread - :return: web application instance + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + spawner(Spawn): spawner thread + + Returns: + web.Application: web application instance """ application = web.Application(logger=logging.getLogger("http")) application.on_shutdown.append(on_shutdown) diff --git a/tests/ahriman/application/application/conftest.py b/tests/ahriman/application/application/conftest.py index 4239c155..10b80151 100644 --- a/tests/ahriman/application/application/conftest.py +++ b/tests/ahriman/application/application/conftest.py @@ -13,10 +13,14 @@ from ahriman.core.database.sqlite import SQLite def application_packages(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Packages: """ fixture for application with package functions - :param configuration: configuration fixture - :param database: database fixture - :param mocker: mocker object - :return: application test instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + Packages: application test instance """ mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.core.database.sqlite.SQLite.load", return_value=database) @@ -27,10 +31,14 @@ def application_packages(configuration: Configuration, database: SQLite, mocker: def application_properties(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Properties: """ fixture for application with properties only - :param configuration: configuration fixture - :param database: database fixture - :param mocker: mocker object - :return: application test instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + Properties: application test instance """ mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.core.database.sqlite.SQLite.load", return_value=database) @@ -41,10 +49,14 @@ def application_properties(configuration: Configuration, database: SQLite, mocke def application_repository(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Repository: """ fixture for application with repository functions - :param configuration: configuration fixture - :param database: database fixture - :param mocker: mocker object - :return: application test instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + Repository: application test instance """ mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.core.database.sqlite.SQLite.load", return_value=database) diff --git a/tests/ahriman/application/conftest.py b/tests/ahriman/application/conftest.py index d8a44970..29e5b72a 100644 --- a/tests/ahriman/application/conftest.py +++ b/tests/ahriman/application/conftest.py @@ -14,10 +14,14 @@ from ahriman.core.database.sqlite import SQLite def application(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Application: """ fixture for application - :param configuration: configuration fixture - :param database: database fixture - :param mocker: mocker object - :return: application test instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + Application: application test instance """ mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.core.database.sqlite.SQLite.load", return_value=database) @@ -28,7 +32,9 @@ def application(configuration: Configuration, database: SQLite, mocker: MockerFi def args() -> argparse.Namespace: """ fixture for command line arguments - :return: command line arguments test instance + + Returns: + argparse.Namespace: command line arguments test instance """ return argparse.Namespace(architecture=None, lock=None, force=False, unsafe=False, no_report=True) @@ -37,9 +43,13 @@ def args() -> argparse.Namespace: def lock(args: argparse.Namespace, configuration: Configuration) -> Lock: """ fixture for file lock - :param args: command line arguments fixture - :param configuration: configuration fixture - :return: file lock test instance + + Args: + args(argparse.Namespace): command line arguments fixture + configuration(Configuration): configuration fixture + + Returns: + Lock: file lock test instance """ return Lock(args, "x86_64", configuration) @@ -48,6 +58,8 @@ def lock(args: argparse.Namespace, configuration: Configuration) -> Lock: def parser() -> argparse.ArgumentParser: """ fixture for command line arguments parser - :return: command line arguments parser test instance + + Returns: + argparse.ArgumentParser: command line arguments parser test instance """ return _parser() diff --git a/tests/ahriman/application/handlers/test_handler_add.py b/tests/ahriman/application/handlers/test_handler_add.py index 108ee9fc..adfb1170 100644 --- a/tests/ahriman/application/handlers/test_handler_add.py +++ b/tests/ahriman/application/handlers/test_handler_add.py @@ -13,8 +13,12 @@ from ahriman.models.result import Result def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.package = [] args.exit_code = False diff --git a/tests/ahriman/application/handlers/test_handler_backup.py b/tests/ahriman/application/handlers/test_handler_backup.py index 637aa666..61604ca3 100644 --- a/tests/ahriman/application/handlers/test_handler_backup.py +++ b/tests/ahriman/application/handlers/test_handler_backup.py @@ -12,8 +12,12 @@ from ahriman.models.repository_paths import RepositoryPaths def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.path = Path("result.tar.gz") return args diff --git a/tests/ahriman/application/handlers/test_handler_clean.py b/tests/ahriman/application/handlers/test_handler_clean.py index 719fac90..c271cf2f 100644 --- a/tests/ahriman/application/handlers/test_handler_clean.py +++ b/tests/ahriman/application/handlers/test_handler_clean.py @@ -9,8 +9,12 @@ from ahriman.core.configuration import Configuration def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.cache = False args.chroot = False diff --git a/tests/ahriman/application/handlers/test_handler_help.py b/tests/ahriman/application/handlers/test_handler_help.py index 69150c0e..24e0f027 100644 --- a/tests/ahriman/application/handlers/test_handler_help.py +++ b/tests/ahriman/application/handlers/test_handler_help.py @@ -10,8 +10,12 @@ from ahriman.core.configuration import Configuration def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.parser = _parser args.command = None diff --git a/tests/ahriman/application/handlers/test_handler_key_import.py b/tests/ahriman/application/handlers/test_handler_key_import.py index a51863ea..b10ed2c9 100644 --- a/tests/ahriman/application/handlers/test_handler_key_import.py +++ b/tests/ahriman/application/handlers/test_handler_key_import.py @@ -9,8 +9,12 @@ from ahriman.core.configuration import Configuration def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.key = "0xE989490C" args.key_server = "pgp.mit.edu" diff --git a/tests/ahriman/application/handlers/test_handler_patch.py b/tests/ahriman/application/handlers/test_handler_patch.py index 219707b6..5a100817 100644 --- a/tests/ahriman/application/handlers/test_handler_patch.py +++ b/tests/ahriman/application/handlers/test_handler_patch.py @@ -13,8 +13,12 @@ from ahriman.models.package import Package def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.package = "ahriman" args.exit_code = False diff --git a/tests/ahriman/application/handlers/test_handler_rebuild.py b/tests/ahriman/application/handlers/test_handler_rebuild.py index 9c450ce8..022a5d6c 100644 --- a/tests/ahriman/application/handlers/test_handler_rebuild.py +++ b/tests/ahriman/application/handlers/test_handler_rebuild.py @@ -14,8 +14,12 @@ from ahriman.models.result import Result def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.depends_on = [] args.dry_run = False diff --git a/tests/ahriman/application/handlers/test_handler_remove.py b/tests/ahriman/application/handlers/test_handler_remove.py index 3963821b..3aef5006 100644 --- a/tests/ahriman/application/handlers/test_handler_remove.py +++ b/tests/ahriman/application/handlers/test_handler_remove.py @@ -9,8 +9,12 @@ from ahriman.core.configuration import Configuration def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.package = [] return args diff --git a/tests/ahriman/application/handlers/test_handler_remove_unknown.py b/tests/ahriman/application/handlers/test_handler_remove_unknown.py index 25057731..8c99b00a 100644 --- a/tests/ahriman/application/handlers/test_handler_remove_unknown.py +++ b/tests/ahriman/application/handlers/test_handler_remove_unknown.py @@ -10,8 +10,12 @@ from ahriman.models.package import Package def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.dry_run = False args.info = False diff --git a/tests/ahriman/application/handlers/test_handler_report.py b/tests/ahriman/application/handlers/test_handler_report.py index 5c2ee75c..9306525f 100644 --- a/tests/ahriman/application/handlers/test_handler_report.py +++ b/tests/ahriman/application/handlers/test_handler_report.py @@ -10,8 +10,12 @@ from ahriman.models.result import Result def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.target = [] return args diff --git a/tests/ahriman/application/handlers/test_handler_restore.py b/tests/ahriman/application/handlers/test_handler_restore.py index 2539d888..af5c171a 100644 --- a/tests/ahriman/application/handlers/test_handler_restore.py +++ b/tests/ahriman/application/handlers/test_handler_restore.py @@ -11,8 +11,12 @@ from ahriman.core.configuration import Configuration def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.path = Path("result.tar.gz") args.output = Path.cwd() diff --git a/tests/ahriman/application/handlers/test_handler_search.py b/tests/ahriman/application/handlers/test_handler_search.py index d5996d60..ed70a5c9 100644 --- a/tests/ahriman/application/handlers/test_handler_search.py +++ b/tests/ahriman/application/handlers/test_handler_search.py @@ -14,8 +14,12 @@ from ahriman.models.aur_package import AURPackage def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.search = ["ahriman"] args.exit_code = False diff --git a/tests/ahriman/application/handlers/test_handler_setup.py b/tests/ahriman/application/handlers/test_handler_setup.py index 50aafd26..c7eab2fd 100644 --- a/tests/ahriman/application/handlers/test_handler_setup.py +++ b/tests/ahriman/application/handlers/test_handler_setup.py @@ -14,8 +14,12 @@ from ahriman.models.sign_settings import SignSettings def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.build_as_user = "ahriman" args.build_command = "ahriman" diff --git a/tests/ahriman/application/handlers/test_handler_sign.py b/tests/ahriman/application/handlers/test_handler_sign.py index a8e24a06..a2829350 100644 --- a/tests/ahriman/application/handlers/test_handler_sign.py +++ b/tests/ahriman/application/handlers/test_handler_sign.py @@ -9,8 +9,12 @@ from ahriman.core.configuration import Configuration def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.package = [] return args diff --git a/tests/ahriman/application/handlers/test_handler_status.py b/tests/ahriman/application/handlers/test_handler_status.py index 6fd2e22d..60887047 100644 --- a/tests/ahriman/application/handlers/test_handler_status.py +++ b/tests/ahriman/application/handlers/test_handler_status.py @@ -12,8 +12,12 @@ from ahriman.models.package import Package def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.ahriman = True args.exit_code = False diff --git a/tests/ahriman/application/handlers/test_handler_status_update.py b/tests/ahriman/application/handlers/test_handler_status_update.py index df1587a9..dda37521 100644 --- a/tests/ahriman/application/handlers/test_handler_status_update.py +++ b/tests/ahriman/application/handlers/test_handler_status_update.py @@ -12,8 +12,12 @@ from ahriman.models.package import Package def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.package = None args.action = Action.Update diff --git a/tests/ahriman/application/handlers/test_handler_sync.py b/tests/ahriman/application/handlers/test_handler_sync.py index c5221a0b..f7184451 100644 --- a/tests/ahriman/application/handlers/test_handler_sync.py +++ b/tests/ahriman/application/handlers/test_handler_sync.py @@ -9,8 +9,12 @@ from ahriman.core.configuration import Configuration def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.target = [] return args diff --git a/tests/ahriman/application/handlers/test_handler_unsafe_commands.py b/tests/ahriman/application/handlers/test_handler_unsafe_commands.py index 8e5a1279..dd6e77a2 100644 --- a/tests/ahriman/application/handlers/test_handler_unsafe_commands.py +++ b/tests/ahriman/application/handlers/test_handler_unsafe_commands.py @@ -6,14 +6,17 @@ from pytest_mock import MockerFixture from ahriman.application.ahriman import _parser from ahriman.application.handlers import UnsafeCommands from ahriman.core.configuration import Configuration -from ahriman.core.exceptions import ExitCode def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.parser = _parser args.command = None @@ -49,19 +52,22 @@ def test_run_check(args: argparse.Namespace, configuration: Configuration, mocke check_mock.assert_called_once_with("clean", ["command"], pytest.helpers.anyvar(int)) -def test_check_unsafe() -> None: +def test_check_unsafe(mocker: MockerFixture) -> None: """ must check if command is unsafe """ - with pytest.raises(ExitCode): - UnsafeCommands.check_unsafe("repo-clean", ["repo-clean"], _parser()) + check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_if_empty") + UnsafeCommands.check_unsafe("repo-clean", ["repo-clean"], _parser()) + check_mock.assert_called_once_with(True, True) -def test_check_unsafe_safe() -> None: +def test_check_unsafe_safe(mocker: MockerFixture) -> None: """ must check if command is safe """ + check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_if_empty") UnsafeCommands.check_unsafe("package-status", ["repo-clean"], _parser()) + check_mock.assert_called_once_with(True, False) def test_get_unsafe_commands() -> None: diff --git a/tests/ahriman/application/handlers/test_handler_update.py b/tests/ahriman/application/handlers/test_handler_update.py index 5aaa09f5..87f2c714 100644 --- a/tests/ahriman/application/handlers/test_handler_update.py +++ b/tests/ahriman/application/handlers/test_handler_update.py @@ -14,8 +14,12 @@ from ahriman.models.result import Result def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.package = [] args.dry_run = False diff --git a/tests/ahriman/application/handlers/test_handler_user.py b/tests/ahriman/application/handlers/test_handler_user.py index b75ab760..2f3394ac 100644 --- a/tests/ahriman/application/handlers/test_handler_user.py +++ b/tests/ahriman/application/handlers/test_handler_user.py @@ -16,8 +16,12 @@ from ahriman.models.user_access import UserAccess def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.username = "user" args.action = Action.Update diff --git a/tests/ahriman/application/handlers/test_handler_web.py b/tests/ahriman/application/handlers/test_handler_web.py index 8f42130c..170effbf 100644 --- a/tests/ahriman/application/handlers/test_handler_web.py +++ b/tests/ahriman/application/handlers/test_handler_web.py @@ -10,8 +10,12 @@ from ahriman.core.configuration import Configuration def _default_args(args: argparse.Namespace) -> argparse.Namespace: """ default arguments for these test cases - :param args: command line arguments fixture - :return: generated arguments for these test cases + + Args: + args(argparse.Namespace): command line arguments fixture + + Returns: + argparse.Namespace: generated arguments for these test cases """ args.parser = lambda: True return args diff --git a/tests/ahriman/conftest.py b/tests/ahriman/conftest.py index a02c633a..8e0891a2 100644 --- a/tests/ahriman/conftest.py +++ b/tests/ahriman/conftest.py @@ -30,20 +30,25 @@ T = TypeVar("T") def anyvar(cls: Type[T], strict: bool = False) -> T: """ any value helper for mocker calls check - :param cls: type class - :param strict: if True then check type of supplied argument - :return: any wrapper + + Args: + strict(bool, optional): if True then check type of supplied argument (Default value = False) + + Returns: + T: any wrapper """ class AnyVar(cls): - """ - any value wrapper - """ + """any value wrapper""" def __eq__(self, other: Any) -> bool: """ compare object to other - :param other: other object to compare - :return: True in case if objects are equal + + Args: + other(Any): other object to compare + + Returns: + bool: True in case if objects are equal """ return not strict or isinstance(other, cls) @@ -54,8 +59,12 @@ def anyvar(cls: Type[T], strict: bool = False) -> T: def get_package_status(package: Package) -> Dict[str, Any]: """ helper to extract package status from package - :param package: package object - :return: simplified package status map (with only status and view) + + Args: + package(Package): package object + + Returns: + Dict[str, Any]: simplified package status map (with only status and view) """ return {"status": BuildStatusEnum.Unknown.value, "package": package.view()} @@ -64,8 +73,12 @@ def get_package_status(package: Package) -> Dict[str, Any]: def get_package_status_extended(package: Package) -> Dict[str, Any]: """ helper to extract package status from package - :param package: package object - :return: full package status map (with timestamped build status and view) + + Args: + package(Package): package object + + Returns: + Dict[str, Any]: full package status map (with timestamped build status and view) """ return {"status": BuildStatus().view(), "package": package.view()} @@ -75,7 +88,9 @@ def get_package_status_extended(package: Package) -> Dict[str, Any]: def aur_package_ahriman() -> AURPackage: """ fixture for AUR package - :return: AUR package test instance + + Returns: + AURPackage: AUR package test instance """ return AURPackage( id=1009791, @@ -128,7 +143,9 @@ def aur_package_ahriman() -> AURPackage: def aur_package_akonadi() -> AURPackage: """ fixture for AUR package - :return: AUR package test instance + + Returns: + AURPackage: AUR package test instance """ return AURPackage( id=0, @@ -172,8 +189,12 @@ def aur_package_akonadi() -> AURPackage: def auth(configuration: Configuration) -> Auth: """ auth provider fixture - :param configuration: configuration fixture - :return: auth service instance + + Args: + configuration(Configuration): configuration fixture + + Returns: + Auth: auth service instance """ return Auth(configuration) @@ -182,8 +203,12 @@ def auth(configuration: Configuration) -> Auth: def configuration(resource_path_root: Path) -> Configuration: """ configuration fixture - :param resource_path_root: resource path root directory - :return: configuration test instance + + Args: + resource_path_root(Path): resource path root directory + + Returns: + Configuration: configuration test instance """ path = resource_path_root / "core" / "ahriman.ini" return Configuration.from_path(path=path, architecture="x86_64", quiet=False) @@ -193,8 +218,12 @@ def configuration(resource_path_root: Path) -> Configuration: def database(configuration: Configuration) -> SQLite: """ database fixture - :param: configuration: configuration fixture - :return: database test instance + + Args: + configuration(Configuration): configuration fixture + + Returns: + SQLite: database test instance """ database = SQLite.load(configuration) yield database @@ -205,8 +234,12 @@ def database(configuration: Configuration) -> SQLite: def package_ahriman(package_description_ahriman: PackageDescription) -> Package: """ package fixture - :param package_description_ahriman: description fixture - :return: package test instance + + Args: + package_description_ahriman(PackageDescription): description fixture + + Returns: + Package: package test instance """ packages = {"ahriman": package_description_ahriman} return Package( @@ -222,9 +255,13 @@ def package_python_schedule( package_description_python2_schedule: PackageDescription) -> Package: """ multi package fixture - :param package_description_python_schedule: description fixture - :param package_description_python2_schedule: description fixture - :return: multi package test instance + + Args: + package_description_python_schedule(PackageDescription): description fixture + package_description_python2_schedule(PackageDescription): description fixture + + Returns: + Package: multi package test instance """ packages = { "python-schedule": package_description_python_schedule, @@ -241,7 +278,9 @@ def package_python_schedule( def package_description_ahriman() -> PackageDescription: """ package description fixture - :return: package description test instance + + Returns: + PackageDescription: package description test instance """ return PackageDescription( architecture="x86_64", @@ -267,7 +306,9 @@ def package_description_ahriman() -> PackageDescription: def package_description_python_schedule() -> PackageDescription: """ package description fixture - :return: package description test instance + + Returns: + PackageDescription: package description test instance """ return PackageDescription( architecture="x86_64", @@ -286,7 +327,9 @@ def package_description_python_schedule() -> PackageDescription: def package_description_python2_schedule() -> PackageDescription: """ package description fixture - :return: package description test instance + + Returns: + PackageDescription: package description test instance """ return PackageDescription( architecture="x86_64", @@ -305,8 +348,12 @@ def package_description_python2_schedule() -> PackageDescription: def repository_paths(configuration: Configuration) -> RepositoryPaths: """ repository paths fixture - :param configuration: configuration fixture - :return: repository paths test instance + + Args: + configuration(Configuration): configuration fixture + + Returns: + RepositoryPaths: repository paths test instance """ return configuration.repository_paths @@ -315,8 +362,12 @@ def repository_paths(configuration: Configuration) -> RepositoryPaths: def result(package_ahriman: Package) -> Result: """ result fixture - :param package_ahriman: package fixture - :return: result test instance + + Args: + package_ahriman(Package): package fixture + + Returns: + Result: result test instance """ result = Result() result.add_success(package_ahriman) @@ -327,8 +378,12 @@ def result(package_ahriman: Package) -> Result: def spawner(configuration: Configuration) -> Spawn: """ spawner fixture - :param configuration: configuration fixture - :return: spawner fixture + + Args: + configuration(Configuration): configuration fixture + + Returns: + Spawn: spawner fixture """ return Spawn(MagicMock(), "x86_64", configuration) @@ -337,7 +392,9 @@ def spawner(configuration: Configuration) -> Spawn: def user() -> User: """ fixture for user descriptor - :return: user descriptor instance + + Returns: + User: user descriptor instance """ return User("user", "pa55w0rd", UserAccess.Read) @@ -346,10 +403,14 @@ def user() -> User: def watcher(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Watcher: """ package status watcher fixture - :param configuration: configuration fixture - :param database: database fixture - :param mocker: mocker object - :return: package status watcher test instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + Watcher: package status watcher test instance """ mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") return Watcher("x86_64", configuration, database) diff --git a/tests/ahriman/core/alpm/remote/conftest.py b/tests/ahriman/core/alpm/remote/conftest.py index d94a04ef..866bcaa5 100644 --- a/tests/ahriman/core/alpm/remote/conftest.py +++ b/tests/ahriman/core/alpm/remote/conftest.py @@ -9,7 +9,9 @@ from ahriman.core.alpm.remote.remote import Remote def aur() -> AUR: """ aur helper fixture - :return: aur helper instance + + Returns: + AUR: aur helper instance """ return AUR() @@ -18,7 +20,9 @@ def aur() -> AUR: def official() -> Official: """ official repository fixture - :return: official repository helper instance + + Returns: + Official: official repository helper instance """ return Official() @@ -27,6 +31,8 @@ def official() -> Official: def remote() -> Remote: """ official repository fixture - :return: official repository helper instance + + Returns: + Remote: official repository helper instance """ return Remote() diff --git a/tests/ahriman/core/alpm/remote/test_aur.py b/tests/ahriman/core/alpm/remote/test_aur.py index 2d5e14c9..4eab4873 100644 --- a/tests/ahriman/core/alpm/remote/test_aur.py +++ b/tests/ahriman/core/alpm/remote/test_aur.py @@ -14,8 +14,12 @@ from ahriman.models.aur_package import AURPackage def _get_response(resource_path_root: Path) -> str: """ load response from resource file - :param resource_path_root: path to resource root - :return: response text + + Args: + resource_path_root(Path): path to resource root + + Returns: + str: response text """ return (resource_path_root / "models" / "package_ahriman_aur").read_text() diff --git a/tests/ahriman/core/alpm/remote/test_official.py b/tests/ahriman/core/alpm/remote/test_official.py index e34376b7..c3a6fcb4 100644 --- a/tests/ahriman/core/alpm/remote/test_official.py +++ b/tests/ahriman/core/alpm/remote/test_official.py @@ -14,8 +14,12 @@ from ahriman.models.aur_package import AURPackage def _get_response(resource_path_root: Path) -> str: """ load response from resource file - :param resource_path_root: path to resource root - :return: response text + + Args: + resource_path_root(Path): path to resource root + + Returns: + str: response text """ return (resource_path_root / "models" / "package_akonadi_aur").read_text() diff --git a/tests/ahriman/core/auth/conftest.py b/tests/ahriman/core/auth/conftest.py index 6820964a..c8a5df20 100644 --- a/tests/ahriman/core/auth/conftest.py +++ b/tests/ahriman/core/auth/conftest.py @@ -10,9 +10,13 @@ from ahriman.core.database.sqlite import SQLite def mapping(configuration: Configuration, database: SQLite) -> Mapping: """ auth provider fixture - :param configuration: configuration fixture - :param database: database fixture - :return: auth service instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + + Returns: + Mapping: auth service instance """ return Mapping(configuration, database) @@ -21,9 +25,13 @@ def mapping(configuration: Configuration, database: SQLite) -> Mapping: def oauth(configuration: Configuration, database: SQLite) -> OAuth: """ OAuth provider fixture - :param configuration: configuration fixture - :param database: database fixture - :return: OAuth2 service instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + + Returns: + OAuth: OAuth2 service instance """ configuration.set("web", "address", "https://example.com") return OAuth(configuration, database) diff --git a/tests/ahriman/core/conftest.py b/tests/ahriman/core/conftest.py index 69447e16..abaac578 100644 --- a/tests/ahriman/core/conftest.py +++ b/tests/ahriman/core/conftest.py @@ -2,7 +2,6 @@ import pytest from ahriman.core.alpm.pacman import Pacman from ahriman.core.alpm.repo import Repo -from ahriman.core.auth.auth import Auth from ahriman.core.build_tools.task import Task from ahriman.core.configuration import Configuration from ahriman.core.tree import Leaf @@ -14,8 +13,12 @@ from ahriman.models.repository_paths import RepositoryPaths def leaf_ahriman(package_ahriman: Package) -> Leaf: """ fixture for tree leaf with package - :param package_ahriman: package fixture - :return: tree leaf test instance + + Args: + package_ahriman(Package): package fixture + + Returns: + Leaf: tree leaf test instance """ return Leaf(package_ahriman, set()) @@ -24,8 +27,12 @@ def leaf_ahriman(package_ahriman: Package) -> Leaf: def leaf_python_schedule(package_python_schedule: Package) -> Leaf: """ fixture for tree leaf with package - :param package_python_schedule: package fixture - :return: tree leaf test instance + + Args: + package_python_schedule(Package): package fixture + + Returns: + Leaf: tree leaf test instance """ return Leaf(package_python_schedule, set()) @@ -34,8 +41,12 @@ def leaf_python_schedule(package_python_schedule: Package) -> Leaf: def pacman(configuration: Configuration) -> Pacman: """ fixture for pacman wrapper - :param configuration: configuration fixture - :return: pacman wrapper test instance + + Args: + configuration(Configuration): configuration fixture + + Returns: + Pacman: pacman wrapper test instance """ return Pacman(configuration) @@ -44,9 +55,13 @@ def pacman(configuration: Configuration) -> Pacman: def repo(configuration: Configuration, repository_paths: RepositoryPaths) -> Repo: """ fixture for repository wrapper - :param configuration: configuration fixture - :param repository_paths: repository paths fixture - :return: repository wrapper test instance + + Args: + configuration(Configuration): configuration fixture + repository_paths(RepositoryPaths): repository paths fixture + + Returns: + Repo: repository wrapper test instance """ return Repo(configuration.get("repository", "name"), repository_paths, []) @@ -55,9 +70,13 @@ def repo(configuration: Configuration, repository_paths: RepositoryPaths) -> Rep def task_ahriman(package_ahriman: Package, configuration: Configuration, repository_paths: RepositoryPaths) -> Task: """ fixture for built task - :param package_ahriman: package fixture - :param configuration: configuration fixture - :param repository_paths: repository paths fixture - :return: built task test instance + + Args: + package_ahriman(Package): package fixture + configuration(Configuration): configuration fixture + repository_paths(RepositoryPaths): repository paths fixture + + Returns: + Task: built task test instance """ return Task(package_ahriman, configuration, repository_paths) diff --git a/tests/ahriman/core/database/conftest.py b/tests/ahriman/core/database/conftest.py index 86f68dde..a3ee2ac8 100644 --- a/tests/ahriman/core/database/conftest.py +++ b/tests/ahriman/core/database/conftest.py @@ -8,6 +8,8 @@ from unittest.mock import MagicMock def connection() -> Connection: """ mock object for sqlite3 connection - :return: sqlite3 connection test instance + + Returns: + Connection: sqlite3 connection test instance """ return MagicMock() diff --git a/tests/ahriman/core/database/migrations/conftest.py b/tests/ahriman/core/database/migrations/conftest.py index cfa0d6cf..3e86360d 100644 --- a/tests/ahriman/core/database/migrations/conftest.py +++ b/tests/ahriman/core/database/migrations/conftest.py @@ -9,7 +9,11 @@ from ahriman.core.database.migrations import Migrations def migrations(connection: Connection) -> Migrations: """ fixture for migrations object - :param connection: sqlite connection fixture - :return: migrations test instance + + Args: + connection(Connection): sqlite connection fixture + + Returns: + Migrations: migrations test instance """ return Migrations(connection) diff --git a/tests/ahriman/core/formatters/conftest.py b/tests/ahriman/core/formatters/conftest.py index c48c45e0..4ebfc5c4 100644 --- a/tests/ahriman/core/formatters/conftest.py +++ b/tests/ahriman/core/formatters/conftest.py @@ -17,8 +17,12 @@ from ahriman.models.user import User def aur_package_ahriman_printer(aur_package_ahriman: AURPackage) -> AurPrinter: """ fixture for AUR package printer - :param aur_package_ahriman: AUR package fixture - :return: AUR package printer test instance + + Args: + aur_package_ahriman(AURPackage): AUR package fixture + + Returns: + AurPrinter: AUR package printer test instance """ return AurPrinter(aur_package_ahriman) @@ -27,7 +31,9 @@ def aur_package_ahriman_printer(aur_package_ahriman: AURPackage) -> AurPrinter: def configuration_printer() -> ConfigurationPrinter: """ fixture for configuration printer - :return: configuration printer test instance + + Returns: + ConfigurationPrinter: configuration printer test instance """ return ConfigurationPrinter("section", {"key_one": "value_one", "key_two": "value_two"}) @@ -36,8 +42,12 @@ def configuration_printer() -> ConfigurationPrinter: def package_ahriman_printer(package_ahriman: Package) -> PackagePrinter: """ fixture for package printer - :param package_ahriman: package fixture - :return: package printer test instance + + Args: + package_ahriman(Package): package fixture + + Returns: + PackagePrinter: package printer test instance """ return PackagePrinter(package_ahriman, BuildStatus()) @@ -46,7 +56,9 @@ def package_ahriman_printer(package_ahriman: Package) -> PackagePrinter: def status_printer() -> StatusPrinter: """ fixture for build status printer - :return: build status printer test instance + + Returns: + StatusPrinter: build status printer test instance """ return StatusPrinter(BuildStatus()) @@ -55,7 +67,9 @@ def status_printer() -> StatusPrinter: def string_printer() -> StringPrinter: """ fixture for any string printer - :return: any string printer test instance + + Returns: + StringPrinter: any string printer test instance """ return StringPrinter("hello, world") @@ -64,7 +78,12 @@ def string_printer() -> StringPrinter: def update_printer(package_ahriman: Package) -> UpdatePrinter: """ fixture for build status printer - :return: build status printer test instance + + Args: + package_ahriman(Package): package fixture + + Returns: + UpdatePrinter: build status printer test instance """ return UpdatePrinter(package_ahriman, None) @@ -73,7 +92,11 @@ def update_printer(package_ahriman: Package) -> UpdatePrinter: def user_printer(user: User) -> UserPrinter: """ fixture for user printer - :param user: user fixture - :return: user printer test instance + + Args: + user(User): user fixture + + Returns: + UserPrinter: user printer test instance """ return UserPrinter(user) diff --git a/tests/ahriman/core/repository/conftest.py b/tests/ahriman/core/repository/conftest.py index 754fe023..8b8bce8e 100644 --- a/tests/ahriman/core/repository/conftest.py +++ b/tests/ahriman/core/repository/conftest.py @@ -15,10 +15,14 @@ from ahriman.core.repository.update_handler import UpdateHandler def cleaner(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Cleaner: """ fixture for cleaner - :param configuration: configuration fixture - :param database: database fixture - :param mocker: mocker object - :return: cleaner test instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + Cleaner: cleaner test instance """ mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") return Cleaner("x86_64", configuration, database, no_report=True, unsafe=False) @@ -28,10 +32,14 @@ def cleaner(configuration: Configuration, database: SQLite, mocker: MockerFixtur def executor(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Executor: """ fixture for executor - :param configuration: configuration fixture - :param database: database fixture - :param mocker: mocker object - :return: executor test instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + Executor: executor test instance """ mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_cache") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_chroot") @@ -45,10 +53,14 @@ def executor(configuration: Configuration, database: SQLite, mocker: MockerFixtu def repository(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Repository: """ fixture for repository - :param configuration: configuration fixture - :param database: database fixture - :param mocker: mocker object - :return: repository test instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + Repository: repository test instance """ mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") return Repository("x86_64", configuration, database, no_report=True, unsafe=False) @@ -58,9 +70,13 @@ def repository(configuration: Configuration, database: SQLite, mocker: MockerFix def properties(configuration: Configuration, database: SQLite) -> Properties: """ fixture for properties - :param configuration: configuration fixture - :param database: database fixture - :return: properties test instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + + Returns: + Properties: properties test instance """ return Properties("x86_64", configuration, database, no_report=True, unsafe=False) @@ -69,10 +85,14 @@ def properties(configuration: Configuration, database: SQLite) -> Properties: def update_handler(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> UpdateHandler: """ fixture for update handler - :param configuration: configuration fixture - :param database: database fixture - :param mocker: mocker object - :return: update handler test instance + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + UpdateHandler: update handler test instance """ mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_cache") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_chroot") diff --git a/tests/ahriman/core/repository/test_cleaner.py b/tests/ahriman/core/repository/test_cleaner.py index 2b7a06cb..60eb6189 100644 --- a/tests/ahriman/core/repository/test_cleaner.py +++ b/tests/ahriman/core/repository/test_cleaner.py @@ -11,7 +11,9 @@ from ahriman.core.repository.cleaner import Cleaner def _mock_clear(mocker: MockerFixture) -> None: """ mocker helper for clear function - :param mocker: mocker object + + Args: + mocker(MockerFixture): mocker object """ mocker.patch("pathlib.Path.iterdir", return_value=[Path("a"), Path("b"), Path("c")]) mocker.patch("shutil.rmtree") diff --git a/tests/ahriman/core/sign/conftest.py b/tests/ahriman/core/sign/conftest.py index 6fb578ab..6351b062 100644 --- a/tests/ahriman/core/sign/conftest.py +++ b/tests/ahriman/core/sign/conftest.py @@ -8,8 +8,12 @@ from ahriman.core.sign.gpg import GPG def gpg(configuration: Configuration) -> GPG: """ fixture for empty GPG - :param configuration: configuration fixture - :return: GPG test instance + + Args: + configuration(Configuration): configuration fixture + + Returns: + GPG: GPG test instance """ return GPG("x86_64", configuration) @@ -18,8 +22,12 @@ def gpg(configuration: Configuration) -> GPG: def gpg_with_key(gpg: GPG) -> GPG: """ fixture for correct GPG - :param gpg: empty GPG fixture - :return: GPG test instance + + Args: + gpg(GPG): empty GPG fixture + + Returns: + GPG: GPG test instance """ gpg.default_key = "key" return gpg diff --git a/tests/ahriman/core/sign/test_gpg.py b/tests/ahriman/core/sign/test_gpg.py index 41a83440..33e9399f 100644 --- a/tests/ahriman/core/sign/test_gpg.py +++ b/tests/ahriman/core/sign/test_gpg.py @@ -4,6 +4,7 @@ import requests from pathlib import Path from pytest_mock import MockerFixture +from ahriman.core.configuration import Configuration from ahriman.core.sign.gpg import GPG from ahriman.models.sign_settings import SignSettings @@ -63,6 +64,18 @@ def test_sign_command(gpg_with_key: GPG) -> None: assert gpg_with_key.sign_command(Path("a"), gpg_with_key.default_key) +def test_sign_options(configuration: Configuration) -> None: + """ + must correctly parse sign options + """ + configuration.set_option("sign", "target", "repository disabled") + configuration.set_option("sign", "key", "default-key") + + target, default_key = GPG.sign_options(configuration) + assert target == {SignSettings.Repository} + assert default_key == "default-key" + + def test_key_download(gpg: GPG, mocker: MockerFixture) -> None: """ must download the key from public server diff --git a/tests/ahriman/core/status/conftest.py b/tests/ahriman/core/status/conftest.py index 615f9586..1ec63f6c 100644 --- a/tests/ahriman/core/status/conftest.py +++ b/tests/ahriman/core/status/conftest.py @@ -5,12 +5,13 @@ from ahriman.core.status.client import Client from ahriman.core.status.web_client import WebClient -# fixtures @pytest.fixture def client() -> Client: """ fixture for dummy client - :return: dummy client test instance + + Returns: + Client: dummy client test instance """ return Client() @@ -19,8 +20,12 @@ def client() -> Client: def web_client(configuration: Configuration) -> WebClient: """ fixture for web client - :param configuration: configuration fixture - :return: web client test instance + + Args: + configuration(Configuration): configuration fixture + + Returns: + WebClient: web client test instance """ configuration.set("web", "port", "8080") return WebClient(configuration) diff --git a/tests/ahriman/core/upload/conftest.py b/tests/ahriman/core/upload/conftest.py index 3cf1f2a4..24de8b5d 100644 --- a/tests/ahriman/core/upload/conftest.py +++ b/tests/ahriman/core/upload/conftest.py @@ -17,8 +17,12 @@ _s3_object = namedtuple("s3_object", ["key", "e_tag", "delete"]) def github(configuration: Configuration) -> Github: """ fixture for github synchronization - :param configuration: configuration fixture - :return: github test instance + + Args: + configuration(Configuration): configuration fixture + + Returns: + Github: github test instance """ return Github("x86_64", configuration, "github:x86_64") @@ -27,7 +31,9 @@ def github(configuration: Configuration) -> Github: def github_release() -> Dict[str, Any]: """ fixture for the github release object - :return: github test release object + + Returns: + Dict[str, Any]: github test release object """ return { "url": "release_url", @@ -47,8 +53,12 @@ def github_release() -> Dict[str, Any]: def rsync(configuration: Configuration) -> Rsync: """ fixture for rsync synchronization - :param configuration: configuration fixture - :return: rsync test instance + + Args: + configuration(Configuration): configuration fixture + + Returns: + Rsync: rsync test instance """ return Rsync("x86_64", configuration, "rsync") @@ -57,8 +67,12 @@ def rsync(configuration: Configuration) -> Rsync: def s3(configuration: Configuration) -> S3: """ fixture for S3 synchronization - :param configuration: configuration fixture - :return: S3 test instance + + Args: + configuration(Configuration): configuration fixture + + Returns: + S3: S3 test instance """ return S3("x86_64", configuration, "customs3") @@ -67,7 +81,9 @@ def s3(configuration: Configuration) -> S3: def s3_remote_objects() -> List[_s3_object]: """ fixture for boto3 like S3 objects - :return: boto3 like S3 objects test instance + + Returns: + List[_s3_object]: boto3 like S3 objects test instance """ delete_mock = MagicMock() return list(map(lambda item: _s3_object(f"x86_64/{item}", f"\"{item}\"", delete_mock), ["a", "b", "c"])) diff --git a/tests/ahriman/models/conftest.py b/tests/ahriman/models/conftest.py index da18af31..8cc65cef 100644 --- a/tests/ahriman/models/conftest.py +++ b/tests/ahriman/models/conftest.py @@ -16,7 +16,9 @@ from ahriman.models.user_identity import UserIdentity def build_status_failed() -> BuildStatus: """ build result fixture with failed status - :return: failed build status test instance + + Returns: + BuildStatus: failed build status test instance """ return BuildStatus(BuildStatusEnum.Failed, 42) @@ -25,7 +27,9 @@ def build_status_failed() -> BuildStatus: def counters() -> Counters: """ counters fixture - :return: counters test instance + + Returns: + Counters: counters test instance """ return Counters(total=10, unknown=1, @@ -39,8 +43,12 @@ def counters() -> Counters: def internal_status(counters: Counters) -> InternalStatus: """ internal status fixture - :param counters: counters fixture - :return: internal status test instance + + Args: + counters(Counters): counters fixture + + Returns: + InternalStatus: internal status test instance """ return InternalStatus(architecture="x86_64", packages=counters, @@ -52,7 +60,9 @@ def internal_status(counters: Counters) -> InternalStatus: def package_tpacpi_bat_git() -> Package: """ git package fixture - :return: git package test instance + + Returns: + Package: git package test instance """ return Package( base="tpacpi-bat-git", @@ -65,8 +75,12 @@ def package_tpacpi_bat_git() -> Package: def pyalpm_handle(pyalpm_package_ahriman: MagicMock) -> MagicMock: """ mock object for pyalpm - :param pyalpm_package_ahriman: mock object for pyalpm package - :return: pyalpm mock + + Args: + pyalpm_package_ahriman(MagicMock): mock object for pyalpm package + + Returns: + MagicMock: pyalpm mock """ mock = MagicMock() mock.handle.load_pkg.return_value = pyalpm_package_ahriman @@ -77,8 +91,12 @@ def pyalpm_handle(pyalpm_package_ahriman: MagicMock) -> MagicMock: def pyalpm_package_ahriman(package_ahriman: Package) -> MagicMock: """ mock object for pyalpm package - :param package_ahriman: package fixture - :return: pyalpm package mock + + Args: + package_ahriman(Package): package fixture + + Returns: + MagicMock: pyalpm package mock """ mock = MagicMock() type(mock).base = PropertyMock(return_value=package_ahriman.base) @@ -93,8 +111,12 @@ def pyalpm_package_ahriman(package_ahriman: Package) -> MagicMock: def pyalpm_package_description_ahriman(package_description_ahriman: PackageDescription) -> MagicMock: """ mock object for pyalpm package description - :param package_description_ahriman: package description fixture - :return: pyalpm package description mock + + Args: + package_description_ahriman(PackageDescription): package description fixture + + Returns: + MagicMock: pyalpm package description mock """ mock = MagicMock() type(mock).arch = PropertyMock(return_value=package_description_ahriman.architecture) @@ -114,6 +136,8 @@ def pyalpm_package_description_ahriman(package_description_ahriman: PackageDescr def user_identity() -> UserIdentity: """ identity fixture - :return: user identity test instance + + Returns: + UserIdentity: user identity test instance """ return UserIdentity("username", int(time.time()) + 30) diff --git a/tests/ahriman/models/test_aur_package.py b/tests/ahriman/models/test_aur_package.py index c50dbee0..00a34896 100644 --- a/tests/ahriman/models/test_aur_package.py +++ b/tests/ahriman/models/test_aur_package.py @@ -12,8 +12,12 @@ from ahriman.models.aur_package import AURPackage def _get_aur_data(resource_path_root: Path) -> Dict[str, Any]: """ load package description from resource file - :param resource_path_root: path to resource root - :return: json descriptor + + Args: + resource_path_root(Path): path to resource root + + Returns: + Dict[str, Any]: json descriptor """ response = (resource_path_root / "models" / "package_ahriman_aur").read_text() return json.loads(response)["results"][0] @@ -22,8 +26,12 @@ def _get_aur_data(resource_path_root: Path) -> Dict[str, Any]: def _get_official_data(resource_path_root: Path) -> Dict[str, Any]: """ load package description from resource file - :param resource_path_root: path to resource root - :return: json descriptor + + Args: + resource_path_root(Path): path to resource root + + Returns: + Dict[str, Any]: json descriptor """ response = (resource_path_root / "models" / "package_akonadi_aur").read_text() return json.loads(response)["results"][0] diff --git a/tests/ahriman/models/test_auth_settings.py b/tests/ahriman/models/test_auth_settings.py index b3816cd3..9d46713c 100644 --- a/tests/ahriman/models/test_auth_settings.py +++ b/tests/ahriman/models/test_auth_settings.py @@ -1,15 +1,11 @@ -import pytest - -from ahriman.core.exceptions import InvalidOption from ahriman.models.auth_settings import AuthSettings def test_from_option_invalid() -> None: """ - must raise exception on invalid option + return disabled on invalid option """ - with pytest.raises(InvalidOption, match=".* `invalid`$"): - AuthSettings.from_option("invalid") + assert AuthSettings.from_option("invalid") == AuthSettings.Disabled def test_from_option_valid() -> None: diff --git a/tests/ahriman/models/test_package_source.py b/tests/ahriman/models/test_package_source.py index b22dc47d..a75ebe16 100644 --- a/tests/ahriman/models/test_package_source.py +++ b/tests/ahriman/models/test_package_source.py @@ -9,9 +9,13 @@ from ahriman.models.package_source import PackageSource def _is_file_mock(is_any_file: bool, is_pkgbuild: bool) -> Callable[[Path], bool]: """ helper to mock is_file method - :param is_any_file: value which will be return for any file - :param is_pkgbuild: value which will be return if PKGBUILD like path asked - :return: side effect function for the mocker object + + Args: + is_any_file(bool): value which will be return for any file + is_pkgbuild(bool): value which will be return if PKGBUILD like path asked + + Returns: + Callable[[Path], bool]: side effect function for the mocker object """ side_effect: Callable[[Path], bool] = lambda source: is_pkgbuild if source.name == "PKGBUILD" else is_any_file return side_effect diff --git a/tests/ahriman/models/test_report_settings.py b/tests/ahriman/models/test_report_settings.py index 3290866c..1b14caea 100644 --- a/tests/ahriman/models/test_report_settings.py +++ b/tests/ahriman/models/test_report_settings.py @@ -1,15 +1,11 @@ -import pytest - -from ahriman.core.exceptions import InvalidOption from ahriman.models.report_settings import ReportSettings def test_from_option_invalid() -> None: """ - must raise exception on invalid option + must return disabled on invalid option """ - with pytest.raises(InvalidOption, match=".* `invalid`$"): - ReportSettings.from_option("invalid") + assert ReportSettings.from_option("invalid") == ReportSettings.Disabled def test_from_option_valid() -> None: diff --git a/tests/ahriman/models/test_repository_paths.py b/tests/ahriman/models/test_repository_paths.py index b1109e7c..e3e621d6 100644 --- a/tests/ahriman/models/test_repository_paths.py +++ b/tests/ahriman/models/test_repository_paths.py @@ -14,9 +14,13 @@ from ahriman.models.repository_paths import RepositoryPaths def _get_owner(root: Path, same: bool) -> Callable[[Path], Tuple[int, int]]: """ mocker function for owner definition - :param root: root directory - :param same: if True then returns the same as root directory and different otherwise - :return: function which can define ownership + + Args: + root(Path): root directory + same(bool): if True then returns the same as root directory and different otherwise + + Returns: + Callable[[Path], Tuple[int, int]]: function which can define ownership """ root_owner = (42, 42) nonroot_owner = (42, 42) if same else (1, 1) diff --git a/tests/ahriman/models/test_sign_settings.py b/tests/ahriman/models/test_sign_settings.py index e282c93b..a4a5dfe8 100644 --- a/tests/ahriman/models/test_sign_settings.py +++ b/tests/ahriman/models/test_sign_settings.py @@ -1,15 +1,11 @@ -import pytest - -from ahriman.core.exceptions import InvalidOption from ahriman.models.sign_settings import SignSettings def test_from_option_invalid() -> None: """ - must raise exception on invalid option + must return disabled on invalid option """ - with pytest.raises(InvalidOption, match=".* `invalid`$"): - SignSettings.from_option("invalid") + assert SignSettings.from_option("invalid") == SignSettings.Disabled def test_from_option_valid() -> None: diff --git a/tests/ahriman/models/test_upload_settings.py b/tests/ahriman/models/test_upload_settings.py index bc50e480..d7748edc 100644 --- a/tests/ahriman/models/test_upload_settings.py +++ b/tests/ahriman/models/test_upload_settings.py @@ -1,15 +1,11 @@ -import pytest - -from ahriman.core.exceptions import InvalidOption from ahriman.models.upload_settings import UploadSettings def test_from_option_invalid() -> None: """ - must raise exception on invalid option + must return disabled on invalid option """ - with pytest.raises(InvalidOption, match=".* `invalid`$"): - UploadSettings.from_option("invalid") + assert UploadSettings.from_option("invalid") == UploadSettings.Disabled def test_from_option_valid() -> None: diff --git a/tests/ahriman/web/conftest.py b/tests/ahriman/web/conftest.py index 1a94fe19..29f6e532 100644 --- a/tests/ahriman/web/conftest.py +++ b/tests/ahriman/web/conftest.py @@ -21,12 +21,16 @@ _request = namedtuple("_request", ["app", "path", "method", "json", "post"]) def request(app: web.Application, path: str, method: str, json: Any = None, data: Any = None) -> _request: """ request generator helper - :param app: application fixture - :param path: path for the request - :param method: method for the request - :param json: json payload of the request - :param data: form data payload of the request - :return: dummy request object + + Args: + app(web.Application): application fixture + path(str): path for the request + method(str): method for the request + json(Any, optional): json payload of the request (Default value = None) + data(Any, optional): form data payload of the request (Default value = None) + + Returns: + _request: dummy request object """ return _request(app, path, method, json, data) @@ -36,11 +40,15 @@ def application(configuration: Configuration, spawner: Spawn, database: SQLite, mocker: MockerFixture) -> web.Application: """ application fixture - :param configuration: configuration fixture - :param spawner: spawner fixture - :param database: database fixture - :param mocker: mocker object - :return: application test instance + + Args: + configuration(Configuration): configuration fixture + spawner(Spawn): spawner fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + web.Application: application test instance """ mocker.patch("ahriman.core.database.sqlite.SQLite.load", return_value=database) mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") @@ -53,12 +61,16 @@ def application_with_auth(configuration: Configuration, user: User, spawner: Spa mocker: MockerFixture) -> web.Application: """ application fixture with auth enabled - :param configuration: configuration fixture - :param user: user descriptor fixture - :param spawner: spawner fixture - :param database: database fixture - :param mocker: mocker object - :return: application test instance + + Args: + configuration(Configuration): configuration fixture + user(User): user descriptor fixture + spawner(Spawn): spawner fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + web.Application: application test instance """ configuration.set_option("auth", "target", "configuration") mocker.patch("ahriman.core.database.sqlite.SQLite.load", return_value=database) @@ -77,12 +89,16 @@ def application_with_debug(configuration: Configuration, user: User, spawner: Sp mocker: MockerFixture) -> web.Application: """ application fixture with debug enabled - :param configuration: configuration fixture - :param user: user descriptor fixture - :param spawner: spawner fixture - :param database: database fixture - :param mocker: mocker object - :return: application test instance + + Args: + configuration(Configuration): configuration fixture + user(User): user descriptor fixture + spawner(Spawn): spawner fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + web.Application: application test instance """ configuration.set_option("web", "debug", "yes") mocker.patch("ahriman.core.database.sqlite.SQLite.load", return_value=database) diff --git a/tests/ahriman/web/middlewares/conftest.py b/tests/ahriman/web/middlewares/conftest.py index aa6ed604..549c959f 100644 --- a/tests/ahriman/web/middlewares/conftest.py +++ b/tests/ahriman/web/middlewares/conftest.py @@ -11,7 +11,14 @@ from ahriman.web.middlewares.auth_handler import AuthorizationPolicy def authorization_policy(configuration: Configuration, database: SQLite, user: User) -> AuthorizationPolicy: """ fixture for authorization policy - :return: authorization policy fixture + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + user(User): user fixture + + Returns: + AuthorizationPolicy: authorization policy fixture """ configuration.set_option("auth", "target", "configuration") validator = Auth.load(configuration, database) diff --git a/tests/ahriman/web/middlewares/test_auth_handler.py b/tests/ahriman/web/middlewares/test_auth_handler.py index 145b2f4f..b4715bef 100644 --- a/tests/ahriman/web/middlewares/test_auth_handler.py +++ b/tests/ahriman/web/middlewares/test_auth_handler.py @@ -14,8 +14,12 @@ from ahriman.web.middlewares.auth_handler import auth_handler, AuthorizationPoli def _identity(username: str) -> str: """ generate identity from user - :param username: name of the user - :return: user identity string + + Args: + username(str): name of the user + + Returns: + str: user identity string """ return f"{username} {UserIdentity.expire_when(60)}" diff --git a/tests/ahriman/web/middlewares/test_exception_handler.py b/tests/ahriman/web/middlewares/test_exception_handler.py index 69ecfafe..712c755a 100644 --- a/tests/ahriman/web/middlewares/test_exception_handler.py +++ b/tests/ahriman/web/middlewares/test_exception_handler.py @@ -13,8 +13,12 @@ from ahriman.web.middlewares.exception_handler import exception_handler def _extract_body(response: Any) -> Any: """ extract json body from given object - :param response: response (any actually) object - :return: body key from the object converted to json + + Args: + response(Any): response (any actually) object + + Returns: + Any: body key from the object converted to json """ return json.loads(getattr(response, "body")) diff --git a/tests/ahriman/web/views/conftest.py b/tests/ahriman/web/views/conftest.py index befa19ad..b3b40d6f 100644 --- a/tests/ahriman/web/views/conftest.py +++ b/tests/ahriman/web/views/conftest.py @@ -15,8 +15,12 @@ from ahriman.web.views.base import BaseView def base(application: web.Application) -> BaseView: """ base view fixture - :param application: application fixture - :return: generated base view fixture + + Args: + application(web.Application): application fixture + + Returns: + BaseView: generated base view fixture """ return BaseView(pytest.helpers.request(application, "", "")) @@ -26,11 +30,15 @@ def client(application: web.Application, event_loop: BaseEventLoop, aiohttp_client: Any, mocker: MockerFixture) -> TestClient: """ web client fixture - :param application: application fixture - :param event_loop: context event loop - :param aiohttp_client: aiohttp client fixture - :param mocker: mocker object - :return: web client test instance + + Args: + application(web.Application): application fixture + event_loop(BaseEventLoop): context event loop + aiohttp_client(Any): aiohttp client fixture + mocker(MockerFixture): mocker object + + Returns: + TestClient: web client test instance """ mocker.patch("pathlib.Path.iterdir", return_value=[]) return event_loop.run_until_complete(aiohttp_client(application)) @@ -41,11 +49,15 @@ def client_with_auth(application_with_auth: web.Application, event_loop: BaseEve aiohttp_client: Any, mocker: MockerFixture) -> TestClient: """ web client fixture with full authorization functions - :param application_with_auth: application fixture - :param event_loop: context event loop - :param aiohttp_client: aiohttp client fixture - :param mocker: mocker object - :return: web client test instance + + Args: + application_with_auth(web.Application): application fixture + event_loop(BaseEventLoop): context event loop + aiohttp_client(Any): aiohttp client fixture + mocker(MockerFixture): mocker object + + Returns: + TestClient: web client test instance """ mocker.patch("pathlib.Path.iterdir", return_value=[]) return event_loop.run_until_complete(aiohttp_client(application_with_auth)) @@ -56,11 +68,15 @@ def client_with_oauth_auth(application_with_auth: web.Application, event_loop: B aiohttp_client: Any, mocker: MockerFixture) -> TestClient: """ web client fixture with full authorization functions - :param application_with_auth: application fixture - :param event_loop: context event loop - :param aiohttp_client: aiohttp client fixture - :param mocker: mocker object - :return: web client test instance + + Args: + application_with_auth(web.Application): application fixture + event_loop(BaseEventLoop): context event loop + aiohttp_client(Any): aiohttp client fixture + mocker(MockerFixture): mocker object + + Returns: + TestClient: web client test instance """ mocker.patch("pathlib.Path.iterdir", return_value=[]) application_with_auth["validator"] = MagicMock(spec=OAuth)