mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 07:17:17 +00:00
add shell and version parser
This commit is contained in:
parent
3a5268993e
commit
d7966e419d
10
.github/ISSUE_TEMPLATE/bug-report.md
vendored
10
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@ -11,9 +11,9 @@ assignees: ''
|
|||||||
|
|
||||||
A clear and concise description of what the bug is.
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
### Steps to Reproduce
|
### Steps to reproduce
|
||||||
|
|
||||||
Steps to reproduce the behavior (commands, environment etc)
|
Steps to reproduce the behavior (commands, environment etc).
|
||||||
|
|
||||||
### Expected behavior
|
### Expected behavior
|
||||||
|
|
||||||
@ -21,4 +21,8 @@ A clear and concise description of what you expected to happen.
|
|||||||
|
|
||||||
### Logs
|
### Logs
|
||||||
|
|
||||||
Add logs to help explain your problem. Logs to stderr can be generated by using `--no-log` command line option.
|
Add logs to help explain your problem. By default, the application writes logs into `/dev/log` which is usually default systemd journal and can be accessed by `journalctl` command.
|
||||||
|
|
||||||
|
You can also attach any additional information which can be helpful, e.g. configuration used by the application (be aware of passwords and other secrets if any); it can be generated by using `ahriman config` command.
|
||||||
|
|
||||||
|
It is also sometimes useful to have information about installed packages which can be accessed by `ahriman version` command.
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature-request.md
vendored
2
.github/ISSUE_TEMPLATE/feature-request.md
vendored
@ -13,7 +13,7 @@ Brief description of the feature required
|
|||||||
|
|
||||||
### Cause of the feature request
|
### Cause of the feature request
|
||||||
|
|
||||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
A clear and concise description of what the problem is. E.g. I'm always frustrated when [...]
|
||||||
|
|
||||||
### Proposed changes and/or features
|
### Proposed changes and/or features
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
ahriman
|
ahriman
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B ahriman
|
.B ahriman
|
||||||
[-h] [-a ARCHITECTURE] [-c CONFIGURATION] [--force] [-l LOCK] [--no-report] [-q] [--unsafe] [-v] {aur-search,search,help,help-commands-unsafe,key-import,package-add,add,package-update,package-remove,remove,package-status,status,package-status-remove,package-status-update,status-update,patch-add,patch-list,patch-remove,repo-backup,repo-check,check,repo-clean,clean,repo-config,config,repo-rebuild,rebuild,repo-remove-unknown,remove-unknown,repo-report,report,repo-restore,repo-setup,init,repo-init,setup,repo-sign,sign,repo-status-update,repo-sync,sync,repo-triggers,repo-update,update,user-add,user-list,user-remove,web} ...
|
[-h] [-a ARCHITECTURE] [-c CONFIGURATION] [--force] [-l LOCK] [--no-report] [-q] [--unsafe] [-V] {aur-search,search,help,help-commands-unsafe,key-import,package-add,add,package-update,package-remove,remove,package-status,status,package-status-remove,package-status-update,status-update,patch-add,patch-list,patch-remove,repo-backup,repo-check,check,repo-clean,clean,repo-config,config,repo-rebuild,rebuild,repo-remove-unknown,remove-unknown,repo-report,report,repo-restore,repo-setup,init,repo-init,setup,repo-sign,sign,repo-status-update,repo-sync,sync,repo-triggers,repo-update,update,shell,user-add,user-list,user-remove,version,web} ...
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
ArcH Linux ReposItory MANager
|
ArcH linux ReposItory MANager
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
@ -37,7 +37,7 @@ force disable any logging
|
|||||||
allow to run ahriman as non\-ahriman user. Some actions might be unavailable
|
allow to run ahriman as non\-ahriman user. Some actions might be unavailable
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-version\fR
|
\fB\-V\fR, \fB\-\-version\fR
|
||||||
show program's version number and exit
|
show program's version number and exit
|
||||||
|
|
||||||
.SH
|
.SH
|
||||||
@ -121,6 +121,9 @@ run triggers
|
|||||||
\fBahriman\fR \fI\,repo-update\/\fR
|
\fBahriman\fR \fI\,repo-update\/\fR
|
||||||
update packages
|
update packages
|
||||||
.TP
|
.TP
|
||||||
|
\fBahriman\fR \fI\,shell\/\fR
|
||||||
|
envoke python shell
|
||||||
|
.TP
|
||||||
\fBahriman\fR \fI\,user-add\/\fR
|
\fBahriman\fR \fI\,user-add\/\fR
|
||||||
create or update user
|
create or update user
|
||||||
.TP
|
.TP
|
||||||
@ -130,6 +133,9 @@ user known users and their access
|
|||||||
\fBahriman\fR \fI\,user-remove\/\fR
|
\fBahriman\fR \fI\,user-remove\/\fR
|
||||||
remove user
|
remove user
|
||||||
.TP
|
.TP
|
||||||
|
\fBahriman\fR \fI\,version\/\fR
|
||||||
|
application version
|
||||||
|
.TP
|
||||||
\fBahriman\fR \fI\,web\/\fR
|
\fBahriman\fR \fI\,web\/\fR
|
||||||
web server
|
web server
|
||||||
.SH COMMAND \fI\,'ahriman aur-search'\/\fR
|
.SH COMMAND \fI\,'ahriman aur-search'\/\fR
|
||||||
@ -544,6 +550,11 @@ do not include manual updates
|
|||||||
\fB\-\-no\-vcs\fR
|
\fB\-\-no\-vcs\fR
|
||||||
do not check VCS packages
|
do not check VCS packages
|
||||||
|
|
||||||
|
.SH COMMAND \fI\,'ahriman shell'\/\fR
|
||||||
|
usage: ahriman shell [-h]
|
||||||
|
|
||||||
|
drop into python shell while having created application
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman user-add'\/\fR
|
.SH COMMAND \fI\,'ahriman user-add'\/\fR
|
||||||
usage: ahriman user-add [-h] [--as-service] [-p PASSWORD]
|
usage: ahriman user-add [-h] [--as-service] [-p PASSWORD]
|
||||||
[-r {UserAccess.Unauthorized,UserAccess.Read,UserAccess.Reporter,UserAccess.Full}] [-s]
|
[-r {UserAccess.Unauthorized,UserAccess.Read,UserAccess.Reporter,UserAccess.Full}] [-s]
|
||||||
@ -606,6 +617,11 @@ username for web service
|
|||||||
\fB\-s\fR, \fB\-\-secure\fR
|
\fB\-s\fR, \fB\-\-secure\fR
|
||||||
set file permissions to user\-only
|
set file permissions to user\-only
|
||||||
|
|
||||||
|
.SH COMMAND \fI\,'ahriman version'\/\fR
|
||||||
|
usage: ahriman version [-h]
|
||||||
|
|
||||||
|
print application and its dependencies versions
|
||||||
|
|
||||||
.SH COMMAND \fI\,'ahriman web'\/\fR
|
.SH COMMAND \fI\,'ahriman web'\/\fR
|
||||||
usage: ahriman web [-h]
|
usage: ahriman web [-h]
|
||||||
|
|
||||||
|
@ -116,6 +116,14 @@ ahriman.application.handlers.setup module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.application.handlers.shell module
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.application.handlers.shell
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.application.handlers.sign module
|
ahriman.application.handlers.sign module
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
@ -172,6 +180,14 @@ ahriman.application.handlers.users module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.application.handlers.versions module
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.application.handlers.versions
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.application.handlers.web module
|
ahriman.application.handlers.web module
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
@ -76,6 +76,14 @@ ahriman.core.formatters.user\_printer module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
ahriman.core.formatters.version\_printer module
|
||||||
|
-----------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: ahriman.core.formatters.version_printer
|
||||||
|
:members:
|
||||||
|
:no-undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
Module contents
|
Module contents
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
@ -104,5 +104,4 @@ autodoc_member_order = "groupwise"
|
|||||||
|
|
||||||
autodoc_default_options = {
|
autodoc_default_options = {
|
||||||
"no-undoc-members": True,
|
"no-undoc-members": True,
|
||||||
"special-members": "__init__",
|
|
||||||
}
|
}
|
||||||
|
18
package/share/ahriman/templates/shell
Normal file
18
package/share/ahriman/templates/shell
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[00m
|
||||||
|
[38;5;60m▄[48;5;60;38;5;67m▄[49;38;5;60m▄[39m [38;5;60m▄▄▄▄▄▄[48;5;60m█[49m▀[39m [00m
|
||||||
|
[38;5;60m▄[48;5;60;38;5;67m▄[48;5;67;38;5;60m▄[48;5;60;38;5;103m▄[48;5;103;38;5;110m▄[48;5;60;38;5;103m▄[38;5;67m▄▄▄[48;5;67m██[38;5;60m▄▄▄[38;5;67m█[48;5;60m▄[49;38;5;60m▄[39m [00m
|
||||||
|
[48;5;60;38;5;60m█[48;5;67;38;5;67m█[48;5;60;38;5;103m▄[48;5;103;38;5;110m▄[48;5;110m██[48;5;103;38;5;103m█[48;5;60;38;5;67m▄▄▄▄[48;5;67;38;5;60m▄[38;5;67m██[48;5;60m▄[48;5;67;38;5;60m▄[38;5;67m█[48;5;60m▄[49;38;5;60m▄[39m [00m
|
||||||
|
[48;5;60;38;5;60m█[48;5;67m▄[48;5;103;38;5;103m█[48;5;110;38;5;110m█[48;5;103;38;5;103m█[48;5;110;38;5;110m██[48;5;103;38;5;103m█[48;5;60;38;5;110m▄▄[38;5;103m▄[48;5;110;38;5;110m█[48;5;60;38;5;60m█[48;5;67;38;5;67m██[48;5;60m▄[48;5;67;38;5;60m▄[38;5;67m█[48;5;60m▄[49;38;5;60m▄[39m [38;5;60m▄[39m[00m
|
||||||
|
[48;5;60;38;5;60m█[38;5;67m▄[48;5;103;38;5;60m▄[48;5;110;38;5;103m▄[38;5;110m█████████[48;5;60m▄▄[48;5;67;38;5;60m▄▄[49m▀[48;5;67m▄[38;5;67m█[48;5;60m▄[38;5;60m█[49m▀[39m[00m
|
||||||
|
[48;5;60;38;5;60m█[49m▄▀[48;5;67m▄[48;5;103;38;5;103m█[48;5;110;38;5;110m███[38;5;232m▄[38;5;110m█[38;5;232m▄▄▄▄[38;5;110m███[48;5;103m▄[49;38;5;103m▄[39m [38;5;60m▀▀[39m [00m
|
||||||
|
[48;5;60;38;5;60m█[48;5;67m▄[48;5;60;38;5;67m▄▄[48;5;103;38;5;103m█[48;5;110;38;5;110m███[38;5;232m▄[48;5;232m█[48;5;188;38;5;188m█[48;5;231;38;5;231m██[48;5;232;38;5;232m██[48;5;110;38;5;110m███[48;5;103;38;5;103m█[49;39m [00m
|
||||||
|
[38;5;60m▄▄[48;5;60;38;5;67m▄▄▄▄[49;38;5;60m▄▄▄[39m [38;5;60m▀[48;5;60m█[38;5;67m▄[48;5;103;38;5;103m█[48;5;110;38;5;110m████[48;5;232m▄[48;5;145;38;5;231m▄[48;5;232;38;5;145m▄[38;5;231m▄[38;5;232m█[38;5;231m▄[48;5;110;38;5;110m██[48;5;103;38;5;103m█[49m▄[39m [00m
|
||||||
|
[38;5;60m▄[48;5;60;38;5;67m▄[48;5;67m███[38;5;60m▄▄▄▄▄▄[48;5;60;38;5;67m▄▄[49;38;5;60m▄[39m [38;5;60m▀[39m [38;5;103m▀[48;5;110m▄[38;5;110m█████[48;5;188m▄▄[48;5;110m█[38;5;103m▄[38;5;110m██[48;5;103;38;5;103m█[49;39m [00m
|
||||||
|
[48;5;60;38;5;60m█[48;5;67;38;5;67m██[38;5;60m▄[48;5;60;38;5;67m▄[48;5;67m████[38;5;60m▄▄[48;5;60m█[48;5;67m▄[38;5;67m█[48;5;60;38;5;60m█[49;38;5;103m▄▄▄[39m [48;5;103;38;5;103m█[48;5;110;38;5;110m██[48;5;103m▄[48;5;110;38;5;103m▄▄▄▄▄[48;5;103m█[49m▀▀[39m [00m
|
||||||
|
[48;5;60;38;5;60m█[48;5;67;38;5;67m█[48;5;60;38;5;60m█[48;5;67;38;5;67m████[38;5;60m▄[49m▀[39m [48;5;60;38;5;103m▄[48;5;103;38;5;110m▄[48;5;110;38;5;179m▄[38;5;110m██[48;5;103m▄▄▄[48;5;110m████[48;5;103;38;5;103m█[49;39m [00m
|
||||||
|
[48;5;60;38;5;60m█[48;5;67;38;5;67m█[48;5;60m▄[48;5;67;38;5;60m▄[38;5;67m███[48;5;60;38;5;60m█[49;39m [48;5;103;38;5;103m█[48;5;185;38;5;110m▄[48;5;110m█[38;5;179m▄[48;5;179;38;5;110m▄[48;5;110m████████[48;5;103;38;5;103m█[49;39m [00m
|
||||||
|
[38;5;60m▄[48;5;60;38;5;67m▄[48;5;67m█[38;5;60m▄[48;5;60;38;5;67m▄[48;5;67m██[38;5;60m▄[49m▀[39m [38;5;103m▀[48;5;110m▄[38;5;110m████[38;5;103m▄[38;5;110m██[38;5;103m▄[38;5;110m██[38;5;103m▄[48;5;103;38;5;67m▄[49;39m [00m
|
||||||
|
[48;5;60;38;5;60m█[48;5;67;38;5;67m██[48;5;60;38;5;60m█[48;5;67;38;5;67m███[48;5;60;38;5;60m█[49;39m [38;5;103m▄[48;5;103m█[48;5;110;38;5;110m██[38;5;103m▄[48;5;103;38;5;110m▄[38;5;67m▄[38;5;103m█[38;5;110m▄[48;5;110m█[48;5;103;38;5;103m█[48;5;110;38;5;110m█[48;5;67;38;5;67m█[49;39m [00m
|
||||||
|
[38;5;60m▄[48;5;60;38;5;67m▄[48;5;67;38;5;60m▄[48;5;60;38;5;67m▄[48;5;67m███[38;5;60m▄[49m▀[39m [38;5;103m▄[48;5;103;38;5;110m▄[48;5;110m██[48;5;103;38;5;103m█[48;5;110;38;5;110m█[48;5;67;38;5;67m█[49;39m [48;5;103;38;5;103m█[48;5;110;38;5;110m██[48;5;103m▄[48;5;110;38;5;103m▄[48;5;67;38;5;110m▄[49;38;5;67m▄[39m [00m
|
||||||
|
[38;5;60m▄▄▄[48;5;60m█[48;5;67;38;5;67m█[38;5;60m▄[48;5;60;38;5;67m▄[48;5;67m█[38;5;60m▄▄▄[49m▀[39m [48;5;103;38;5;103m█[48;5;110;38;5;110m███[48;5;103;38;5;103m█[48;5;110;38;5;67m▄[48;5;67m█[49;39m [48;5;103;38;5;103m█[48;5;110;38;5;110m███[48;5;103;38;5;103m█[48;5;110;38;5;67m▄[48;5;67m█[49;39m [00m
|
||||||
|
[38;5;60m▀▀▀▀▀▀▀[39m [38;5;103m▀▀▀▀[39m [38;5;103m▀▀▀▀[39m [00m
|
1
setup.py
1
setup.py
@ -66,6 +66,7 @@ setup(
|
|||||||
"package/share/ahriman/templates/build-status.jinja2",
|
"package/share/ahriman/templates/build-status.jinja2",
|
||||||
"package/share/ahriman/templates/email-index.jinja2",
|
"package/share/ahriman/templates/email-index.jinja2",
|
||||||
"package/share/ahriman/templates/repo-index.jinja2",
|
"package/share/ahriman/templates/repo-index.jinja2",
|
||||||
|
"package/share/ahriman/templates/shell",
|
||||||
"package/share/ahriman/templates/telegram-index.jinja2",
|
"package/share/ahriman/templates/telegram-index.jinja2",
|
||||||
]),
|
]),
|
||||||
("share/ahriman/templates/build-status", [
|
("share/ahriman/templates/build-status", [
|
||||||
|
@ -26,6 +26,7 @@ from typing import List, TypeVar
|
|||||||
|
|
||||||
from ahriman import version
|
from ahriman import version
|
||||||
from ahriman.application import handlers
|
from ahriman.application import handlers
|
||||||
|
from ahriman.core.util import enum_values
|
||||||
from ahriman.models.action import Action
|
from ahriman.models.action import Action
|
||||||
from ahriman.models.build_status import BuildStatusEnum
|
from ahriman.models.build_status import BuildStatusEnum
|
||||||
from ahriman.models.package_source import PackageSource
|
from ahriman.models.package_source import PackageSource
|
||||||
@ -76,7 +77,7 @@ def _parser() -> argparse.ArgumentParser:
|
|||||||
parser.add_argument("-q", "--quiet", help="force disable any logging", action="store_true")
|
parser.add_argument("-q", "--quiet", help="force disable any logging", action="store_true")
|
||||||
parser.add_argument("--unsafe", help="allow to run ahriman as non-ahriman user. Some actions might be unavailable",
|
parser.add_argument("--unsafe", help="allow to run ahriman as non-ahriman user. Some actions might be unavailable",
|
||||||
action="store_true")
|
action="store_true")
|
||||||
parser.add_argument("-v", "--version", action="version", version=version.__version__)
|
parser.add_argument("-V", "--version", action="version", version=version.__version__)
|
||||||
|
|
||||||
subparsers = parser.add_subparsers(title="command", help="command to run", dest="command", required=True)
|
subparsers = parser.add_subparsers(title="command", help="command to run", dest="command", required=True)
|
||||||
|
|
||||||
@ -106,9 +107,11 @@ def _parser() -> argparse.ArgumentParser:
|
|||||||
_set_repo_sync_parser(subparsers)
|
_set_repo_sync_parser(subparsers)
|
||||||
_set_repo_triggers_parser(subparsers)
|
_set_repo_triggers_parser(subparsers)
|
||||||
_set_repo_update_parser(subparsers)
|
_set_repo_update_parser(subparsers)
|
||||||
|
_set_shell_parser(subparsers)
|
||||||
_set_user_add_parser(subparsers)
|
_set_user_add_parser(subparsers)
|
||||||
_set_user_list_parser(subparsers)
|
_set_user_list_parser(subparsers)
|
||||||
_set_user_remove_parser(subparsers)
|
_set_user_remove_parser(subparsers)
|
||||||
|
_set_version_parser(subparsers)
|
||||||
_set_web_parser(subparsers)
|
_set_web_parser(subparsers)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
@ -225,7 +228,7 @@ def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||||
parser.add_argument("-n", "--now", help="run update function after", action="store_true")
|
parser.add_argument("-n", "--now", help="run update function after", action="store_true")
|
||||||
parser.add_argument("-s", "--source", help="explicitly specify the package source for this command",
|
parser.add_argument("-s", "--source", help="explicitly specify the package source for this command",
|
||||||
type=PackageSource, choices=PackageSource, default=PackageSource.Auto)
|
type=PackageSource, choices=enum_values(PackageSource), default=PackageSource.Auto)
|
||||||
parser.add_argument("--without-dependencies", help="do not add dependencies", action="store_true")
|
parser.add_argument("--without-dependencies", help="do not add dependencies", action="store_true")
|
||||||
parser.set_defaults(handler=handlers.Add)
|
parser.set_defaults(handler=handlers.Add)
|
||||||
return parser
|
return parser
|
||||||
@ -267,7 +270,7 @@ def _set_package_status_parser(root: SubParserAction) -> argparse.ArgumentParser
|
|||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||||
parser.add_argument("-i", "--info", help="show additional package information", action="store_true")
|
parser.add_argument("-i", "--info", help="show additional package information", action="store_true")
|
||||||
parser.add_argument("-s", "--status", help="filter packages by status",
|
parser.add_argument("-s", "--status", help="filter packages by status",
|
||||||
type=BuildStatusEnum, choices=BuildStatusEnum)
|
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum))
|
||||||
parser.set_defaults(handler=handlers.Status, lock=None, no_report=True, quiet=True, unsafe=True)
|
parser.set_defaults(handler=handlers.Status, lock=None, no_report=True, quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@ -309,7 +312,7 @@ def _set_package_status_update_parser(root: SubParserAction) -> argparse.Argumen
|
|||||||
"If no packages supplied, service status will be updated",
|
"If no packages supplied, service status will be updated",
|
||||||
nargs="*")
|
nargs="*")
|
||||||
parser.add_argument("-s", "--status", help="new status",
|
parser.add_argument("-s", "--status", help="new status",
|
||||||
type=BuildStatusEnum, choices=BuildStatusEnum, default=BuildStatusEnum.Success)
|
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum), default=BuildStatusEnum.Success)
|
||||||
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Update, lock=None, no_report=True, quiet=True,
|
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Update, lock=None, no_report=True, quiet=True,
|
||||||
unsafe=True)
|
unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
@ -556,7 +559,7 @@ def _set_repo_setup_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
parser.add_argument("--repository", help="repository name", required=True)
|
parser.add_argument("--repository", help="repository name", required=True)
|
||||||
parser.add_argument("--sign-key", help="sign key id")
|
parser.add_argument("--sign-key", help="sign key id")
|
||||||
parser.add_argument("--sign-target", help="sign options", action="append",
|
parser.add_argument("--sign-target", help="sign options", action="append",
|
||||||
type=SignSettings.from_option, choices=SignSettings)
|
type=SignSettings.from_option, choices=enum_values(SignSettings))
|
||||||
parser.add_argument("--web-port", help="port of the web service", type=int)
|
parser.add_argument("--web-port", help="port of the web service", type=int)
|
||||||
parser.set_defaults(handler=handlers.Setup, lock=None, no_report=True, quiet=True, unsafe=True)
|
parser.set_defaults(handler=handlers.Setup, lock=None, no_report=True, quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
@ -594,7 +597,7 @@ def _set_repo_status_update_parser(root: SubParserAction) -> argparse.ArgumentPa
|
|||||||
parser = root.add_parser("repo-status-update", help="update repository status",
|
parser = root.add_parser("repo-status-update", help="update repository status",
|
||||||
description="update repository status on the status page", formatter_class=_formatter)
|
description="update repository status on the status page", formatter_class=_formatter)
|
||||||
parser.add_argument("-s", "--status", help="new status",
|
parser.add_argument("-s", "--status", help="new status",
|
||||||
type=BuildStatusEnum, choices=BuildStatusEnum, default=BuildStatusEnum.Success)
|
type=BuildStatusEnum, choices=enum_values(BuildStatusEnum), default=BuildStatusEnum.Success)
|
||||||
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Update, lock=None, no_report=True, package=[],
|
parser.set_defaults(handler=handlers.StatusUpdate, action=Action.Update, lock=None, no_report=True, package=[],
|
||||||
quiet=True, unsafe=True)
|
quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
@ -661,6 +664,24 @@ def _set_repo_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def _set_shell_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for shell subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("shell", help="envoke python shell",
|
||||||
|
description="drop into python shell while having created application",
|
||||||
|
formatter_class=_formatter)
|
||||||
|
parser.add_argument("-v", "--verbose", help=argparse.SUPPRESS, action="store_true")
|
||||||
|
parser.set_defaults(handler=handlers.Shell, lock=None, no_report=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def _set_user_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
def _set_user_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
"""
|
"""
|
||||||
add parser for create user subcommand
|
add parser for create user subcommand
|
||||||
@ -680,7 +701,7 @@ def _set_user_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
parser.add_argument("-p", "--password", help="user password. Blank password will be treated as empty password, "
|
parser.add_argument("-p", "--password", help="user password. Blank password will be treated as empty password, "
|
||||||
"which is in particular must be used for OAuth2 authorization type.")
|
"which is in particular must be used for OAuth2 authorization type.")
|
||||||
parser.add_argument("-r", "--role", help="user access level",
|
parser.add_argument("-r", "--role", help="user access level",
|
||||||
type=UserAccess, choices=UserAccess, default=UserAccess.Read)
|
type=UserAccess, choices=enum_values(UserAccess), default=UserAccess.Read)
|
||||||
parser.add_argument("-s", "--secure", help="set file permissions to user-only", action="store_true")
|
parser.add_argument("-s", "--secure", help="set file permissions to user-only", action="store_true")
|
||||||
parser.set_defaults(handler=handlers.Users, action=Action.Update, architecture=[""], lock=None, no_report=True,
|
parser.set_defaults(handler=handlers.Users, action=Action.Update, architecture=[""], lock=None, no_report=True,
|
||||||
quiet=True, unsafe=True)
|
quiet=True, unsafe=True)
|
||||||
@ -702,7 +723,7 @@ def _set_user_list_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
formatter_class=_formatter)
|
formatter_class=_formatter)
|
||||||
parser.add_argument("username", help="filter users by username", nargs="?")
|
parser.add_argument("username", help="filter users by username", nargs="?")
|
||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||||
parser.add_argument("-r", "--role", help="filter users by role", type=UserAccess, choices=UserAccess)
|
parser.add_argument("-r", "--role", help="filter users by role", type=UserAccess, choices=enum_values(UserAccess))
|
||||||
parser.set_defaults(handler=handlers.Users, action=Action.List, architecture=[""], lock=None, no_report=True, # nosec
|
parser.set_defaults(handler=handlers.Users, action=Action.List, architecture=[""], lock=None, no_report=True, # nosec
|
||||||
password="", quiet=True, unsafe=True)
|
password="", quiet=True, unsafe=True)
|
||||||
return parser
|
return parser
|
||||||
@ -728,6 +749,23 @@ def _set_user_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def _set_version_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
|
"""
|
||||||
|
add parser for version subcommand
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(SubParserAction): subparsers for the commands
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.ArgumentParser: created argument parser
|
||||||
|
"""
|
||||||
|
parser = root.add_parser("version", help="application version",
|
||||||
|
description="print application and its dependencies versions", formatter_class=_formatter)
|
||||||
|
parser.set_defaults(handler=handlers.Versions, architecture=[""], lock=None, no_report=True, quiet=True,
|
||||||
|
unsafe=True)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def _set_web_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
def _set_web_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||||
"""
|
"""
|
||||||
add parser for web subcommand
|
add parser for web subcommand
|
||||||
|
@ -32,6 +32,7 @@ from ahriman.application.handlers.remove_unknown import RemoveUnknown
|
|||||||
from ahriman.application.handlers.restore import Restore
|
from ahriman.application.handlers.restore import Restore
|
||||||
from ahriman.application.handlers.search import Search
|
from ahriman.application.handlers.search import Search
|
||||||
from ahriman.application.handlers.setup import Setup
|
from ahriman.application.handlers.setup import Setup
|
||||||
|
from ahriman.application.handlers.shell import Shell
|
||||||
from ahriman.application.handlers.sign import Sign
|
from ahriman.application.handlers.sign import Sign
|
||||||
from ahriman.application.handlers.status import Status
|
from ahriman.application.handlers.status import Status
|
||||||
from ahriman.application.handlers.status_update import StatusUpdate
|
from ahriman.application.handlers.status_update import StatusUpdate
|
||||||
@ -39,4 +40,5 @@ from ahriman.application.handlers.triggers import Triggers
|
|||||||
from ahriman.application.handlers.unsafe_commands import UnsafeCommands
|
from ahriman.application.handlers.unsafe_commands import UnsafeCommands
|
||||||
from ahriman.application.handlers.update import Update
|
from ahriman.application.handlers.update import Update
|
||||||
from ahriman.application.handlers.users import Users
|
from ahriman.application.handlers.users import Users
|
||||||
|
from ahriman.application.handlers.versions import Versions
|
||||||
from ahriman.application.handlers.web import Web
|
from ahriman.application.handlers.web import Web
|
||||||
|
59
src/ahriman/application/handlers/shell.py
Normal file
59
src/ahriman/application/handlers/shell.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2021-2022 ahriman team.
|
||||||
|
#
|
||||||
|
# This file is part of ahriman
|
||||||
|
# (see https://github.com/arcan1s/ahriman).
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
import argparse
|
||||||
|
import code
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Type
|
||||||
|
|
||||||
|
from ahriman.application.application import Application
|
||||||
|
from ahriman.application.handlers import Handler
|
||||||
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.formatters import StringPrinter
|
||||||
|
|
||||||
|
|
||||||
|
class Shell(Handler):
|
||||||
|
"""
|
||||||
|
python shell handler
|
||||||
|
"""
|
||||||
|
|
||||||
|
ALLOW_MULTI_ARCHITECTURE_RUN = False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
||||||
|
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
||||||
|
"""
|
||||||
|
callback for command line
|
||||||
|
|
||||||
|
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
|
||||||
|
"""
|
||||||
|
# pylint: disable=possibly-unused-variable
|
||||||
|
application = Application(architecture, configuration, no_report, unsafe)
|
||||||
|
if args.verbose:
|
||||||
|
# licensed by https://creativecommons.org/licenses/by-sa/3.0
|
||||||
|
path = Path(sys.prefix) / "share" / "ahriman" / "templates" / "shell"
|
||||||
|
StringPrinter(path.read_text(encoding="utf8")).print(verbose=False)
|
||||||
|
code.interact(local=locals())
|
87
src/ahriman/application/handlers/versions.py
Normal file
87
src/ahriman/application/handlers/versions.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2021-2022 ahriman team.
|
||||||
|
#
|
||||||
|
# This file is part of ahriman
|
||||||
|
# (see https://github.com/arcan1s/ahriman).
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
import argparse
|
||||||
|
import pkg_resources
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from typing import Dict, List, Tuple, Type
|
||||||
|
|
||||||
|
from ahriman import version
|
||||||
|
from ahriman.application.handlers import Handler
|
||||||
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.formatters import VersionPrinter
|
||||||
|
|
||||||
|
|
||||||
|
class Versions(Handler):
|
||||||
|
"""
|
||||||
|
version handler
|
||||||
|
"""
|
||||||
|
|
||||||
|
ALLOW_AUTO_ARCHITECTURE_RUN = False # it should be called only as "no-architecture"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
|
||||||
|
configuration: Configuration, no_report: bool, unsafe: bool) -> None:
|
||||||
|
"""
|
||||||
|
callback for command line
|
||||||
|
|
||||||
|
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
|
||||||
|
"""
|
||||||
|
VersionPrinter(f"Module version {version.__version__}",
|
||||||
|
{"Python": sys.version}).print(verbose=False, separator=" ")
|
||||||
|
packages = Versions.package_dependencies("ahriman", ("pacman", "s3", "web"))
|
||||||
|
VersionPrinter("Installed packages", packages).print(verbose=False, separator=" ")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def package_dependencies(root: str, root_extras: Tuple[str, ...] = ()) -> Dict[str, str]:
|
||||||
|
"""
|
||||||
|
extract list of ahriman package dependencies installed into system with their versions
|
||||||
|
|
||||||
|
Args:
|
||||||
|
root(str): root package name
|
||||||
|
root_extras(Tuple[str, ...]): extras for the root package (Default value = ())
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, str]: map of installed dependency to its version
|
||||||
|
"""
|
||||||
|
resources: Dict[str, pkg_resources.Distribution] = pkg_resources.working_set.by_key # type: ignore
|
||||||
|
|
||||||
|
def dependencies_by_key(key: str, extras: Tuple[str, ...] = ()) -> List[str]:
|
||||||
|
return [entry.key for entry in resources[key].requires(extras)]
|
||||||
|
|
||||||
|
keys: List[str] = []
|
||||||
|
portion = {key for key in dependencies_by_key(root, root_extras) if key in resources}
|
||||||
|
while portion:
|
||||||
|
keys.extend(portion)
|
||||||
|
portion = {
|
||||||
|
key
|
||||||
|
for key in sum([dependencies_by_key(key) for key in portion], start=[])
|
||||||
|
if key not in keys and key in resources
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
resource.project_name: resource.version
|
||||||
|
for resource in map(lambda key: resources[key], keys)
|
||||||
|
}
|
@ -27,3 +27,4 @@ from ahriman.core.formatters.package_printer import PackagePrinter
|
|||||||
from ahriman.core.formatters.status_printer import StatusPrinter
|
from ahriman.core.formatters.status_printer import StatusPrinter
|
||||||
from ahriman.core.formatters.update_printer import UpdatePrinter
|
from ahriman.core.formatters.update_printer import UpdatePrinter
|
||||||
from ahriman.core.formatters.user_printer import UserPrinter
|
from ahriman.core.formatters.user_printer import UserPrinter
|
||||||
|
from ahriman.core.formatters.version_printer import VersionPrinter
|
||||||
|
@ -25,6 +25,9 @@ from ahriman.core.formatters import Printer
|
|||||||
class StringPrinter(Printer):
|
class StringPrinter(Printer):
|
||||||
"""
|
"""
|
||||||
print content of the random string
|
print content of the random string
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
content(str): any content string
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, content: str) -> None:
|
def __init__(self, content: str) -> None:
|
||||||
|
55
src/ahriman/core/formatters/version_printer.py
Normal file
55
src/ahriman/core/formatters/version_printer.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2021-2022 ahriman team.
|
||||||
|
#
|
||||||
|
# This file is part of ahriman
|
||||||
|
# (see https://github.com/arcan1s/ahriman).
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
from ahriman.core.formatters import StringPrinter
|
||||||
|
from ahriman.models.property import Property
|
||||||
|
|
||||||
|
|
||||||
|
class VersionPrinter(StringPrinter):
|
||||||
|
"""
|
||||||
|
print content of the python package versions
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
packages(Dict[str, str]): map of package name to its version
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, title: str, packages: Dict[str, str]) -> None:
|
||||||
|
"""
|
||||||
|
default constructor
|
||||||
|
|
||||||
|
Args:
|
||||||
|
title(str): title of the message
|
||||||
|
packages(Dict[str, str]): map of package name to its version
|
||||||
|
"""
|
||||||
|
StringPrinter.__init__(self, title)
|
||||||
|
self.packages = packages
|
||||||
|
|
||||||
|
def properties(self) -> List[Property]:
|
||||||
|
"""
|
||||||
|
convert content into printable data
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[Property]: list of content properties
|
||||||
|
"""
|
||||||
|
return [
|
||||||
|
Property(package, version, is_required=True)
|
||||||
|
for package, version in sorted(self.packages.items())
|
||||||
|
]
|
@ -18,7 +18,10 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
import datetime
|
import datetime
|
||||||
|
import io
|
||||||
import os
|
import os
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
@ -27,14 +30,14 @@ import tempfile
|
|||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from logging import Logger
|
from logging import Logger
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, Generator, Iterable, List, Optional, Union
|
from typing import Any, Dict, Generator, IO, Iterable, List, Optional, Type, Union
|
||||||
|
|
||||||
from ahriman.core.exceptions import InvalidOption, UnsafeRun
|
from ahriman.core.exceptions import InvalidOption, UnsafeRun
|
||||||
from ahriman.models.repository_paths import RepositoryPaths
|
from ahriman.models.repository_paths import RepositoryPaths
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["check_output", "check_user", "exception_response_text", "filter_json", "full_version", "package_like",
|
__all__ = ["check_output", "check_user", "exception_response_text", "filter_json", "full_version", "enum_values",
|
||||||
"pretty_datetime", "pretty_size", "tmpdir", "walk"]
|
"package_like", "pretty_datetime", "pretty_size", "tmpdir", "walk"]
|
||||||
|
|
||||||
|
|
||||||
def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path] = None,
|
def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path] = None,
|
||||||
@ -73,6 +76,11 @@ def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path]
|
|||||||
|
|
||||||
>>> check_output("false", exception=RuntimeError("An exception occurred"))
|
>>> check_output("false", exception=RuntimeError("An exception occurred"))
|
||||||
"""
|
"""
|
||||||
|
# hack for Optional[IO[str]] handle
|
||||||
|
def get_io(proc: subprocess.Popen[str], channel_name: str) -> IO[str]:
|
||||||
|
channel: Optional[IO[str]] = getattr(proc, channel_name, None)
|
||||||
|
return channel if channel is not None else io.StringIO()
|
||||||
|
|
||||||
def log(single: str) -> None:
|
def log(single: str) -> None:
|
||||||
if logger is not None:
|
if logger is not None:
|
||||||
logger.debug(single)
|
logger.debug(single)
|
||||||
@ -80,14 +88,15 @@ def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path]
|
|||||||
# FIXME additional workaround for linter and type check which do not know that user arg is supported
|
# FIXME additional workaround for linter and type check which do not know that user arg is supported
|
||||||
# pylint: disable=unexpected-keyword-arg
|
# pylint: disable=unexpected-keyword-arg
|
||||||
with subprocess.Popen(args, cwd=cwd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
with subprocess.Popen(args, cwd=cwd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
user=user, text=True, encoding="utf8", bufsize=1) as process: # type: ignore
|
user=user, text=True, encoding="utf8", bufsize=1) as process:
|
||||||
if input_data is not None:
|
if input_data is not None:
|
||||||
process.stdin.write(input_data)
|
input_channel = get_io(process, "stdin")
|
||||||
process.stdin.close()
|
input_channel.write(input_data)
|
||||||
|
input_channel.close()
|
||||||
|
|
||||||
# read stdout and append to output result
|
# read stdout and append to output result
|
||||||
result: List[str] = []
|
result: List[str] = []
|
||||||
for line in iter(process.stdout.readline, ""):
|
for line in iter(get_io(process, "stdout").readline, ""):
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line: # skip empty lines
|
if not line: # skip empty lines
|
||||||
continue
|
continue
|
||||||
@ -95,7 +104,7 @@ def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path]
|
|||||||
log(line)
|
log(line)
|
||||||
|
|
||||||
# read stderr and write info to logs
|
# read stderr and write info to logs
|
||||||
for line in iter(process.stderr.readline, ""):
|
for line in iter(get_io(process, "stderr").readline, ""):
|
||||||
log(line.strip())
|
log(line.strip())
|
||||||
|
|
||||||
process.terminate() # make sure that process is terminated
|
process.terminate() # make sure that process is terminated
|
||||||
@ -134,6 +143,19 @@ def check_user(paths: RepositoryPaths, unsafe: bool) -> None:
|
|||||||
raise UnsafeRun(current_uid, root_uid)
|
raise UnsafeRun(current_uid, root_uid)
|
||||||
|
|
||||||
|
|
||||||
|
def enum_values(enum: Type[Enum]) -> List[str]:
|
||||||
|
"""
|
||||||
|
generate list of enumeration values from the source
|
||||||
|
|
||||||
|
Args:
|
||||||
|
enum(Type[Enum]): source enumeration class
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: available enumeration values as string
|
||||||
|
"""
|
||||||
|
return [key.value for key in enum]
|
||||||
|
|
||||||
|
|
||||||
def exception_response_text(exception: requests.exceptions.HTTPError) -> str:
|
def exception_response_text(exception: requests.exceptions.HTTPError) -> str:
|
||||||
"""
|
"""
|
||||||
safe response exception text generation
|
safe response exception text generation
|
||||||
|
48
tests/ahriman/application/handlers/test_handler_shell.py
Normal file
48
tests/ahriman/application/handlers/test_handler_shell.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import argparse
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
|
from ahriman.application.handlers import Shell
|
||||||
|
from ahriman.core.configuration import Configuration
|
||||||
|
|
||||||
|
|
||||||
|
def _default_args(args: argparse.Namespace) -> argparse.Namespace:
|
||||||
|
"""
|
||||||
|
default arguments for these test cases
|
||||||
|
|
||||||
|
Args:
|
||||||
|
args(argparse.Namespace): command line arguments fixture
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.Namespace: generated arguments for these test cases
|
||||||
|
"""
|
||||||
|
args.verbose = False
|
||||||
|
return args
|
||||||
|
|
||||||
|
|
||||||
|
def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must run command
|
||||||
|
"""
|
||||||
|
args = _default_args(args)
|
||||||
|
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
|
||||||
|
application_mock = mocker.patch("code.interact")
|
||||||
|
|
||||||
|
Shell.run(args, "x86_64", configuration, True, False)
|
||||||
|
application_mock.assert_called_once_with(local=pytest.helpers.anyvar(int))
|
||||||
|
|
||||||
|
|
||||||
|
def test_run_verbose(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must run command with verbose option
|
||||||
|
"""
|
||||||
|
args = _default_args(args)
|
||||||
|
args.verbose = True
|
||||||
|
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
|
||||||
|
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
|
application_mock = mocker.patch("code.interact")
|
||||||
|
|
||||||
|
Shell.run(args, "x86_64", configuration, True, False)
|
||||||
|
application_mock.assert_called_once_with(local=pytest.helpers.anyvar(int))
|
||||||
|
print_mock.assert_called_once_with(verbose=False)
|
38
tests/ahriman/application/handlers/test_handler_versions.py
Normal file
38
tests/ahriman/application/handlers/test_handler_versions.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import argparse
|
||||||
|
|
||||||
|
from pytest_mock import MockerFixture
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from ahriman.application.handlers import Versions
|
||||||
|
from ahriman.core.configuration import Configuration
|
||||||
|
|
||||||
|
|
||||||
|
def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must run command
|
||||||
|
"""
|
||||||
|
application_mock = mocker.patch("ahriman.application.handlers.Versions.package_dependencies")
|
||||||
|
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
||||||
|
|
||||||
|
Versions.run(args, "x86_64", configuration, True, False)
|
||||||
|
application_mock.assert_called_once_with("ahriman", ("pacman", "s3", "web"))
|
||||||
|
print_mock.assert_has_calls([mock.call(verbose=False, separator=" "), mock.call(verbose=False, separator=" ")])
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_dependencies() -> None:
|
||||||
|
"""
|
||||||
|
must extract package dependencies
|
||||||
|
"""
|
||||||
|
packages = Versions.package_dependencies("srcinfo")
|
||||||
|
assert packages
|
||||||
|
assert packages.get("parse") is not None
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_dependencies_missing() -> None:
|
||||||
|
"""
|
||||||
|
must extract package dependencies even if some of them are missing
|
||||||
|
"""
|
||||||
|
packages = Versions.package_dependencies("ahriman", ("docs", "pacman", "s3", "web"))
|
||||||
|
assert packages
|
||||||
|
assert packages.get("pyalpm") is not None
|
||||||
|
assert packages.get("Sphinx") is None
|
@ -492,6 +492,15 @@ def test_subparsers_repo_update_architecture(parser: argparse.ArgumentParser) ->
|
|||||||
assert args.architecture == ["x86_64"]
|
assert args.architecture == ["x86_64"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_subparsers_shell(parser: argparse.ArgumentParser) -> None:
|
||||||
|
"""
|
||||||
|
shell command must imply lock and no-report
|
||||||
|
"""
|
||||||
|
args = parser.parse_args(["shell"])
|
||||||
|
assert args.lock is None
|
||||||
|
assert args.no_report
|
||||||
|
|
||||||
|
|
||||||
def test_subparsers_user_add(parser: argparse.ArgumentParser) -> None:
|
def test_subparsers_user_add(parser: argparse.ArgumentParser) -> None:
|
||||||
"""
|
"""
|
||||||
user-add command must imply action, architecture, lock, no-report, quiet and unsafe
|
user-add command must imply action, architecture, lock, no-report, quiet and unsafe
|
||||||
@ -575,6 +584,26 @@ def test_subparsers_user_remove_architecture(parser: argparse.ArgumentParser) ->
|
|||||||
assert args.architecture == [""]
|
assert args.architecture == [""]
|
||||||
|
|
||||||
|
|
||||||
|
def test_subparsers_version(parser: argparse.ArgumentParser) -> None:
|
||||||
|
"""
|
||||||
|
version command must imply architecture, lock, no-report, quiet and unsafe
|
||||||
|
"""
|
||||||
|
args = parser.parse_args(["version"])
|
||||||
|
assert args.architecture == [""]
|
||||||
|
assert args.lock is None
|
||||||
|
assert args.no_report
|
||||||
|
assert args.quiet
|
||||||
|
assert args.unsafe
|
||||||
|
|
||||||
|
|
||||||
|
def test_subparsers_version_architecture(parser: argparse.ArgumentParser) -> None:
|
||||||
|
"""
|
||||||
|
version command must correctly parse architecture list
|
||||||
|
"""
|
||||||
|
args = parser.parse_args(["-a", "x86_64", "version"])
|
||||||
|
assert args.architecture == [""]
|
||||||
|
|
||||||
|
|
||||||
def test_subparsers_web(parser: argparse.ArgumentParser) -> None:
|
def test_subparsers_web(parser: argparse.ArgumentParser) -> None:
|
||||||
"""
|
"""
|
||||||
web command must imply lock, no_report and parser
|
web command must imply lock, no_report and parser
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from ahriman.core.formatters import AurPrinter, ConfigurationPrinter, PackagePrinter, StatusPrinter, StringPrinter, UpdatePrinter, UserPrinter
|
from ahriman.core.formatters import AurPrinter, ConfigurationPrinter, PackagePrinter, StatusPrinter, StringPrinter, \
|
||||||
|
UpdatePrinter, UserPrinter, VersionPrinter
|
||||||
from ahriman.models.aur_package import AURPackage
|
from ahriman.models.aur_package import AURPackage
|
||||||
from ahriman.models.build_status import BuildStatus
|
from ahriman.models.build_status import BuildStatus
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
@ -94,3 +95,17 @@ def user_printer(user: User) -> UserPrinter:
|
|||||||
UserPrinter: user printer test instance
|
UserPrinter: user printer test instance
|
||||||
"""
|
"""
|
||||||
return UserPrinter(user)
|
return UserPrinter(user)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def version_printer(package_ahriman: Package) -> VersionPrinter:
|
||||||
|
"""
|
||||||
|
fixture for version printer
|
||||||
|
|
||||||
|
Args:
|
||||||
|
package_ahriman(Package): package fixture
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
VersionPrinter: version printer test instance
|
||||||
|
"""
|
||||||
|
return VersionPrinter("package", {package_ahriman.base: package_ahriman.version})
|
||||||
|
15
tests/ahriman/core/formatters/test_version_printer.py
Normal file
15
tests/ahriman/core/formatters/test_version_printer.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from ahriman.core.formatters import VersionPrinter
|
||||||
|
|
||||||
|
|
||||||
|
def test_properties(version_printer: VersionPrinter) -> None:
|
||||||
|
"""
|
||||||
|
must return empty properties list
|
||||||
|
"""
|
||||||
|
assert version_printer.properties()
|
||||||
|
|
||||||
|
|
||||||
|
def test_title(version_printer: VersionPrinter) -> None:
|
||||||
|
"""
|
||||||
|
must return non empty title
|
||||||
|
"""
|
||||||
|
assert version_printer.title() is not None
|
@ -10,8 +10,9 @@ from unittest.mock import MagicMock
|
|||||||
|
|
||||||
from ahriman.core.exceptions import BuildFailed, InvalidOption, UnsafeRun
|
from ahriman.core.exceptions import BuildFailed, InvalidOption, UnsafeRun
|
||||||
from ahriman.core.util import check_output, check_user, exception_response_text, filter_json, full_version, \
|
from ahriman.core.util import check_output, check_user, exception_response_text, filter_json, full_version, \
|
||||||
package_like, pretty_datetime, pretty_size, tmpdir, walk
|
enum_values, package_like, pretty_datetime, pretty_size, tmpdir, walk
|
||||||
from ahriman.models.package import Package
|
from ahriman.models.package import Package
|
||||||
|
from ahriman.models.package_source import PackageSource
|
||||||
from ahriman.models.repository_paths import RepositoryPaths
|
from ahriman.models.repository_paths import RepositoryPaths
|
||||||
|
|
||||||
|
|
||||||
@ -177,6 +178,15 @@ def test_filter_json_empty_value(package_ahriman: Package) -> None:
|
|||||||
assert "base" not in filter_json(probe, probe.keys())
|
assert "base" not in filter_json(probe, probe.keys())
|
||||||
|
|
||||||
|
|
||||||
|
def test_enum_values() -> None:
|
||||||
|
"""
|
||||||
|
must correctly generate choices from enumeration classes
|
||||||
|
"""
|
||||||
|
values = enum_values(PackageSource)
|
||||||
|
for value in values:
|
||||||
|
assert PackageSource(value).value == value
|
||||||
|
|
||||||
|
|
||||||
def test_full_version() -> None:
|
def test_full_version() -> None:
|
||||||
"""
|
"""
|
||||||
must construct full version
|
must construct full version
|
||||||
@ -331,6 +341,7 @@ def test_walk(resource_path_root: Path) -> None:
|
|||||||
resource_path_root / "web" / "templates" / "build-status.jinja2",
|
resource_path_root / "web" / "templates" / "build-status.jinja2",
|
||||||
resource_path_root / "web" / "templates" / "email-index.jinja2",
|
resource_path_root / "web" / "templates" / "email-index.jinja2",
|
||||||
resource_path_root / "web" / "templates" / "repo-index.jinja2",
|
resource_path_root / "web" / "templates" / "repo-index.jinja2",
|
||||||
|
resource_path_root / "web" / "templates" / "shell",
|
||||||
resource_path_root / "web" / "templates" / "telegram-index.jinja2",
|
resource_path_root / "web" / "templates" / "telegram-index.jinja2",
|
||||||
])
|
])
|
||||||
local_files = list(sorted(walk(resource_path_root)))
|
local_files = list(sorted(walk(resource_path_root)))
|
||||||
|
Loading…
Reference in New Issue
Block a user