mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-28 17:27:17 +00:00
Compare commits
No commits in common. "3016a919c5e3b52dd664474febc57d963be3c3e3" and "5b6ba721feebcc7d08a37a0746658418fcaca088" have entirely different histories.
3016a919c5
...
5b6ba721fe
@ -42,9 +42,6 @@ class Packages(Properties):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
result(Result): build result
|
result(Result): build result
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: not implemented method
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@ -54,9 +51,6 @@ class Packages(Properties):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Set[str]: list of known packages
|
Set[str]: list of known packages
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: not implemented method
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@ -122,7 +116,7 @@ class Packages(Properties):
|
|||||||
add package from remote sources (e.g. HTTP)
|
add package from remote sources (e.g. HTTP)
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
source(str): remote URL of the package archive
|
source(str):
|
||||||
"""
|
"""
|
||||||
dst = self.repository.paths.packages / Path(source).name # URL is path, is not it?
|
dst = self.repository.paths.packages / Path(source).name # URL is path, is not it?
|
||||||
response = requests.get(source, stream=True)
|
response = requests.get(source, stream=True)
|
||||||
|
@ -41,9 +41,6 @@ class Repository(Properties):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
result(Result): build result
|
result(Result): build result
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: not implemented method
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@ -53,9 +53,6 @@ class Handler:
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[str]: list of architectures for which tree is created
|
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:
|
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
|
# for some parsers (e.g. config) we need to run with specific architecture
|
||||||
@ -108,9 +105,6 @@ class Handler:
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
int: 0 on success, 1 otherwise
|
int: 0 on success, 1 otherwise
|
||||||
|
|
||||||
Raises:
|
|
||||||
MultipleArchitectures: if more than one architecture supplied and no multi architecture supported
|
|
||||||
"""
|
"""
|
||||||
architectures = cls.architectures_extract(args)
|
architectures = cls.architectures_extract(args)
|
||||||
|
|
||||||
@ -139,9 +133,6 @@ class Handler:
|
|||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
no_report(bool): force disable reporting
|
no_report(bool): force disable reporting
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
unsafe(bool): if set no user check will be performed before path creation
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: not implemented method
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@ -153,9 +144,6 @@ class Handler:
|
|||||||
Args:
|
Args:
|
||||||
enabled(bool): if False no check will be performed
|
enabled(bool): if False no check will be performed
|
||||||
predicate(bool): indicates condition on which exception should be thrown
|
predicate(bool): indicates condition on which exception should be thrown
|
||||||
|
|
||||||
Raises:
|
|
||||||
ExitCode: if result is empty and check is enabled
|
|
||||||
"""
|
"""
|
||||||
if enabled and predicate:
|
if enabled and predicate:
|
||||||
raise ExitCode()
|
raise ExitCode()
|
||||||
|
@ -82,7 +82,7 @@ class Patch(Handler):
|
|||||||
Args:
|
Args:
|
||||||
application(Application): application instance
|
application(Application): application instance
|
||||||
package_base(Optional[str]): package base
|
package_base(Optional[str]): package base
|
||||||
exit_code(bool): exit with error on empty search result
|
exit_code(bool): raise ExitCode on empty search result
|
||||||
"""
|
"""
|
||||||
patches = application.database.patches_list(package_base)
|
patches = application.database.patches_list(package_base)
|
||||||
Patch.check_if_empty(exit_code, not patches)
|
Patch.check_if_empty(exit_code, not patches)
|
||||||
|
@ -75,9 +75,6 @@ class Search(Handler):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[AURPackage]: sorted list for packages
|
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:
|
if sort_by not in Search.SORT_FIELDS:
|
||||||
raise InvalidOption(sort_by)
|
raise InvalidOption(sort_by)
|
||||||
|
@ -24,6 +24,7 @@ from typing import List, Type
|
|||||||
|
|
||||||
from ahriman.application.handlers.handler import Handler
|
from ahriman.application.handlers.handler import Handler
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.exceptions import ExitCode
|
||||||
from ahriman.core.formatters.string_printer import StringPrinter
|
from ahriman.core.formatters.string_printer import StringPrinter
|
||||||
|
|
||||||
|
|
||||||
@ -66,7 +67,8 @@ class UnsafeCommands(Handler):
|
|||||||
parser(argparse.ArgumentParser): generated argument parser
|
parser(argparse.ArgumentParser): generated argument parser
|
||||||
"""
|
"""
|
||||||
args = parser.parse_args(shlex.split(command))
|
args = parser.parse_args(shlex.split(command))
|
||||||
UnsafeCommands.check_if_empty(True, args.command in unsafe_commands)
|
if args.command in unsafe_commands:
|
||||||
|
raise ExitCode()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_unsafe_commands(parser: argparse.ArgumentParser) -> List[str]:
|
def get_unsafe_commands(parser: argparse.ArgumentParser) -> List[str]:
|
||||||
|
@ -124,9 +124,6 @@ class Lock:
|
|||||||
def create(self) -> None:
|
def create(self) -> None:
|
||||||
"""
|
"""
|
||||||
create lock file
|
create lock file
|
||||||
|
|
||||||
Raises:
|
|
||||||
DuplicateRun: if lock exists and no force flag supplied
|
|
||||||
"""
|
"""
|
||||||
if self.path is None:
|
if self.path is None:
|
||||||
return
|
return
|
||||||
|
@ -63,9 +63,6 @@ class AUR(Remote):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[AURPackage]: list of parsed packages
|
List[AURPackage]: list of parsed packages
|
||||||
|
|
||||||
Raises:
|
|
||||||
InvalidPackageInfo: for error API response
|
|
||||||
"""
|
"""
|
||||||
response_type = response["type"]
|
response_type = response["type"]
|
||||||
if response_type == "error":
|
if response_type == "error":
|
||||||
|
@ -58,9 +58,6 @@ class Official(Remote):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[AURPackage]: list of parsed packages
|
List[AURPackage]: list of parsed packages
|
||||||
|
|
||||||
Raises:
|
|
||||||
InvalidPackageInfo: for error API response
|
|
||||||
"""
|
"""
|
||||||
if not response["valid"]:
|
if not response["valid"]:
|
||||||
raise InvalidPackageInfo("API validation error")
|
raise InvalidPackageInfo("API validation error")
|
||||||
|
@ -98,9 +98,6 @@ class Remote:
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
AURPackage: package which match the package name
|
AURPackage: package which match the package name
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: not implemented method
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@ -113,8 +110,5 @@ class Remote:
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[AURPackage]: list of packages which match the criteria
|
List[AURPackage]: list of packages which match the criteria
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: not implemented method
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -79,9 +79,6 @@ class OAuth(Mapping):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Type[aioauth_client.OAuth2Client]: loaded provider type
|
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)
|
provider: Type[aioauth_client.OAuth2Client] = getattr(aioauth_client, name)
|
||||||
try:
|
try:
|
||||||
|
@ -166,7 +166,7 @@ class Sources:
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
sources_dir(Path): local path to git repository
|
sources_dir(Path): local path to git repository
|
||||||
*pattern(str): glob patterns
|
*pattern(str):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: patch as plain text
|
str: patch as plain text
|
||||||
|
@ -115,9 +115,6 @@ class Configuration(configparser.RawConfigParser):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[str]: list of string from the parsed string
|
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]:
|
def generator() -> Generator[str, None, None]:
|
||||||
quote_mark = None
|
quote_mark = None
|
||||||
@ -173,9 +170,6 @@ class Configuration(configparser.RawConfigParser):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Tuple[Path, str]: configuration root path and architecture if loaded
|
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:
|
if self.path is None or self.architecture is None:
|
||||||
raise InitializeException("Configuration path and/or architecture are not set")
|
raise InitializeException("Configuration path and/or architecture are not set")
|
||||||
@ -210,9 +204,6 @@ class Configuration(configparser.RawConfigParser):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Tuple[str, str]: section name and found type name
|
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
|
group_type = self.get(section, "type", fallback=None) # new-style logic
|
||||||
if group_type is not None:
|
if group_type is not None:
|
||||||
|
@ -35,25 +35,25 @@ class JinjaTemplate:
|
|||||||
|
|
||||||
It uses jinja2 templates for report generation, the following variables are allowed:
|
It uses jinja2 templates for report generation, the following variables are allowed:
|
||||||
|
|
||||||
* homepage - link to homepage, string, optional
|
homepage - link to homepage, string, optional
|
||||||
* link_path - prefix fo packages to download, string, required
|
link_path - prefix fo packages to download, string, required
|
||||||
* has_package_signed - True in case if package sign enabled, False otherwise, 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
|
has_repo_signed - True in case if repository database sign enabled, False otherwise, required
|
||||||
* packages - sorted list of packages properties, required
|
packages - sorted list of packages properties, required
|
||||||
* architecture, string
|
* architecture, string
|
||||||
* archive_size, pretty printed size, string
|
* archive_size, pretty printed size, string
|
||||||
* build_date, pretty printed datetime, string
|
* build_date, pretty printed datetime, string
|
||||||
* depends, sorted list of strings
|
* depends, sorted list of strings
|
||||||
* description, string
|
* description, string
|
||||||
* filename, string,
|
* filename, string,
|
||||||
* groups, sorted list of strings
|
* groups, sorted list of strings
|
||||||
* installed_size, pretty printed datetime, string
|
* installed_size, pretty printed datetime, string
|
||||||
* licenses, sorted list of strings
|
* licenses, sorted list of strings
|
||||||
* name, string
|
* name, string
|
||||||
* url, string
|
* url, string
|
||||||
* version, string
|
* version, string
|
||||||
* pgp_key - default PGP key ID, string, optional
|
pgp_key - default PGP key ID, string, optional
|
||||||
* repository - repository name, string, required
|
repository - repository name, string, required
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
homepage(Optional[str]): homepage link if any (for footer)
|
homepage(Optional[str]): homepage link if any (for footer)
|
||||||
|
@ -97,9 +97,6 @@ class Report:
|
|||||||
Args:
|
Args:
|
||||||
packages(Iterable[Package]): list of packages to generate report
|
packages(Iterable[Package]): list of packages to generate report
|
||||||
result(Result): build result
|
result(Result): build result
|
||||||
|
|
||||||
Raises:
|
|
||||||
ReportFailed: in case of any report unmatched exception
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.generate(packages, result)
|
self.generate(packages, result)
|
||||||
|
@ -36,9 +36,6 @@ class Cleaner(Properties):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[Path]: list of filenames from the directory
|
List[Path]: list of filenames from the directory
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: not implemented method
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@ -45,9 +45,6 @@ class Executor(Cleaner):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[Package]: list of read packages
|
List[Package]: list of read packages
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: not implemented method
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@ -57,9 +54,6 @@ class Executor(Cleaner):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[Package]: list of packages properties
|
List[Package]: list of packages properties
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: not implemented method
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ class Repository(Executor, UpdateHandler):
|
|||||||
extract list of packages which depends on specified package
|
extract list of packages which depends on specified package
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
depends_on(Optional[Iterable[str]]): dependencies of the packages
|
depends_on(Optional[Iterable[str]]):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[Package]: list of repository packages which depend on specified packages
|
List[Package]: list of repository packages which depend on specified packages
|
||||||
|
@ -36,9 +36,6 @@ class UpdateHandler(Cleaner):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[Package]: list of packages properties
|
List[Package]: list of packages properties
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: not implemented method
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@ -94,12 +94,10 @@ class GPG:
|
|||||||
Returns:
|
Returns:
|
||||||
Tuple[Set[SignSettings], Optional[str]]: tuple of sign targets and default PGP key
|
Tuple[Set[SignSettings], Optional[str]]: tuple of sign targets and default PGP key
|
||||||
"""
|
"""
|
||||||
targets: Set[SignSettings] = set()
|
targets = {
|
||||||
for option in configuration.getlist("sign", "target"):
|
SignSettings.from_option(option)
|
||||||
target = SignSettings.from_option(option)
|
for option in configuration.getlist("sign", "target")
|
||||||
if target == SignSettings.Disabled:
|
}
|
||||||
continue
|
|
||||||
targets.add(target)
|
|
||||||
default_key = configuration.get("sign", "key") if targets else None
|
default_key = configuration.get("sign", "key") if targets else None
|
||||||
return targets, default_key
|
return targets, default_key
|
||||||
|
|
||||||
|
@ -73,13 +73,10 @@ class Watcher:
|
|||||||
get current package base build status
|
get current package base build status
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
base(str): package base
|
base(str):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Tuple[Package, BuildStatus]: package and its status
|
Tuple[Package, BuildStatus]: package and its status
|
||||||
|
|
||||||
Raises:
|
|
||||||
UnknownPackage: if no package found
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return self.known[base]
|
return self.known[base]
|
||||||
@ -120,9 +117,6 @@ class Watcher:
|
|||||||
package_base(str): package base to update
|
package_base(str): package base to update
|
||||||
status(BuildStatusEnum): new build status
|
status(BuildStatusEnum): new build status
|
||||||
package(Optional[Package]): optional new package description. In case if not set current properties will be used
|
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:
|
if package is None:
|
||||||
try:
|
try:
|
||||||
|
@ -102,7 +102,7 @@ class HttpUpload(Upload):
|
|||||||
Args:
|
Args:
|
||||||
method(str): request method
|
method(str): request method
|
||||||
url(str): request url
|
url(str): request url
|
||||||
**kwargs(Any): request parameters to be passed as is
|
**kwargs(Any):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
requests.Response: request response object
|
requests.Response: request response object
|
||||||
|
@ -46,7 +46,7 @@ class S3(Upload):
|
|||||||
Args:
|
Args:
|
||||||
architecture(str): repository architecture
|
architecture(str): repository architecture
|
||||||
configuration(Configuration): configuration instance
|
configuration(Configuration): configuration instance
|
||||||
section(str): settings section name
|
section(str):
|
||||||
"""
|
"""
|
||||||
Upload.__init__(self, architecture, configuration)
|
Upload.__init__(self, architecture, configuration)
|
||||||
self.bucket = self.get_bucket(configuration, section)
|
self.bucket = self.get_bucket(configuration, section)
|
||||||
|
@ -85,9 +85,6 @@ class Upload:
|
|||||||
Args:
|
Args:
|
||||||
path(Path): local path to sync
|
path(Path): local path to sync
|
||||||
built_packages(Iterable[Package]): list of packages which has just been built
|
built_packages(Iterable[Package]): list of packages which has just been built
|
||||||
|
|
||||||
Raises:
|
|
||||||
SyncFailed: in case of any synchronization unmatched exception
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.sync(path, built_packages)
|
self.sync(path, built_packages)
|
||||||
|
@ -48,9 +48,6 @@ def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path]
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: command output
|
str: command output
|
||||||
|
|
||||||
Raises:
|
|
||||||
subprocess.CalledProcessError: if subprocess ended with status code different from 0 and no exception supplied
|
|
||||||
"""
|
"""
|
||||||
def log(single: str) -> None:
|
def log(single: str) -> None:
|
||||||
if logger is not None:
|
if logger is not None:
|
||||||
@ -94,9 +91,6 @@ def check_user(paths: RepositoryPaths, unsafe: bool) -> None:
|
|||||||
Args:
|
Args:
|
||||||
paths(RepositoryPaths): repository paths object
|
paths(RepositoryPaths): repository paths object
|
||||||
unsafe(bool): if set no user check will be performed before path creation
|
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():
|
if not paths.root.exists():
|
||||||
return # no directory found, skip check
|
return # no directory found, skip check
|
||||||
@ -193,9 +187,6 @@ def pretty_size(size: Optional[float], level: int = 0) -> str:
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: pretty printable size as string
|
str: pretty printable size as string
|
||||||
|
|
||||||
Raises:
|
|
||||||
InvalidOption: if size is more than 1TiB
|
|
||||||
"""
|
"""
|
||||||
def str_level() -> str:
|
def str_level() -> str:
|
||||||
if level == 0:
|
if level == 0:
|
||||||
|
@ -22,6 +22,8 @@ from __future__ import annotations
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
|
from ahriman.core.exceptions import InvalidOption
|
||||||
|
|
||||||
|
|
||||||
class AuthSettings(Enum):
|
class AuthSettings(Enum):
|
||||||
"""
|
"""
|
||||||
@ -48,11 +50,13 @@ class AuthSettings(Enum):
|
|||||||
Returns:
|
Returns:
|
||||||
AuthSettings: parsed value
|
AuthSettings: parsed value
|
||||||
"""
|
"""
|
||||||
|
if value.lower() in ("disabled", "no"):
|
||||||
|
return cls.Disabled
|
||||||
if value.lower() in ("configuration", "mapping"):
|
if value.lower() in ("configuration", "mapping"):
|
||||||
return cls.Configuration
|
return cls.Configuration
|
||||||
if value.lower() in ('oauth', 'oauth2'):
|
if value.lower() in ('oauth', 'oauth2'):
|
||||||
return cls.OAuth
|
return cls.OAuth
|
||||||
return cls.Disabled
|
raise InvalidOption(value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_enabled(self) -> bool:
|
def is_enabled(self) -> bool:
|
||||||
|
@ -40,9 +40,6 @@ class MigrationResult:
|
|||||||
"""
|
"""
|
||||||
Returns:
|
Returns:
|
||||||
bool: True in case if it requires migrations and False otherwise
|
bool: True in case if it requires migrations and False otherwise
|
||||||
|
|
||||||
Raises:
|
|
||||||
MigrationError: if old version is newer than new one or negative
|
|
||||||
"""
|
"""
|
||||||
self.validate()
|
self.validate()
|
||||||
return self.new_version > self.old_version
|
return self.new_version > self.old_version
|
||||||
|
@ -161,9 +161,6 @@ class Package:
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Package: package properties
|
Package: package properties
|
||||||
|
|
||||||
Raises:
|
|
||||||
InvalidPackageInfo: if there are parsing errors
|
|
||||||
"""
|
"""
|
||||||
srcinfo, errors = parse_srcinfo((path / ".SRCINFO").read_text())
|
srcinfo, errors = parse_srcinfo((path / ".SRCINFO").read_text())
|
||||||
if errors:
|
if errors:
|
||||||
@ -222,9 +219,6 @@ class Package:
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Package: package properties
|
Package: package properties
|
||||||
|
|
||||||
Raises:
|
|
||||||
InvalidPackageInfo: if supplied package source is not valid
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
resolved_source = source.resolve(package)
|
resolved_source = source.resolve(package)
|
||||||
@ -252,9 +246,6 @@ class Package:
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Set[str]: list of package dependencies including makedepends array, but excluding packages from this base
|
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
|
# additional function to remove versions from dependencies
|
||||||
def extract_packages(raw_packages_list: List[str]) -> Set[str]:
|
def extract_packages(raw_packages_list: List[str]) -> Set[str]:
|
||||||
@ -286,9 +277,6 @@ class Package:
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: package version if package is not VCS and current version according to VCS otherwise
|
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:
|
if not self.is_vcs:
|
||||||
return self.version
|
return self.version
|
||||||
|
@ -22,6 +22,8 @@ from __future__ import annotations
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
|
from ahriman.core.exceptions import InvalidOption
|
||||||
|
|
||||||
|
|
||||||
class ReportSettings(Enum):
|
class ReportSettings(Enum):
|
||||||
"""
|
"""
|
||||||
@ -60,4 +62,4 @@ class ReportSettings(Enum):
|
|||||||
return cls.Console
|
return cls.Console
|
||||||
if value.lower() in ("telegram",):
|
if value.lower() in ("telegram",):
|
||||||
return cls.Telegram
|
return cls.Telegram
|
||||||
return cls.Disabled
|
raise InvalidOption(value)
|
||||||
|
@ -133,9 +133,6 @@ class RepositoryPaths:
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
path(Path): path to be chown
|
path(Path): path to be chown
|
||||||
|
|
||||||
Raises:
|
|
||||||
InvalidPath: if path does not belong to root
|
|
||||||
"""
|
"""
|
||||||
def set_owner(current: Path) -> None:
|
def set_owner(current: Path) -> None:
|
||||||
uid, gid = self.owner(current)
|
uid, gid = self.owner(current)
|
||||||
|
@ -95,9 +95,6 @@ class Result:
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Result: updated instance
|
Result: updated instance
|
||||||
|
|
||||||
Raises:
|
|
||||||
SuccessFailed: if there is previously failed package which is masked as success
|
|
||||||
"""
|
"""
|
||||||
for base, package in other._failed.items():
|
for base, package in other._failed.items():
|
||||||
if base in self._success:
|
if base in self._success:
|
||||||
|
@ -22,18 +22,18 @@ from __future__ import annotations
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
|
from ahriman.core.exceptions import InvalidOption
|
||||||
|
|
||||||
|
|
||||||
class SignSettings(Enum):
|
class SignSettings(Enum):
|
||||||
"""
|
"""
|
||||||
sign targets enumeration
|
sign targets enumeration
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
Disabled(SignSettings): (class attribute) option which generates no report for testing purpose
|
|
||||||
Packages(SignSettings): (class attribute) sign each package
|
Packages(SignSettings): (class attribute) sign each package
|
||||||
Repository(SignSettings): (class attribute) sign repository database file
|
Repository(SignSettings): (class attribute) sign repository database file
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Disabled = "disabled"
|
|
||||||
Packages = "pacakges"
|
Packages = "pacakges"
|
||||||
Repository = "repository"
|
Repository = "repository"
|
||||||
|
|
||||||
@ -47,12 +47,9 @@ class SignSettings(Enum):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
SignSettings: parsed value
|
SignSettings: parsed value
|
||||||
|
|
||||||
Raises:
|
|
||||||
InvalidOption: if unsupported option suppled
|
|
||||||
"""
|
"""
|
||||||
if value.lower() in ("package", "packages", "sign-package"):
|
if value.lower() in ("package", "packages", "sign-package"):
|
||||||
return cls.Packages
|
return cls.Packages
|
||||||
if value.lower() in ("repository", "sign-repository"):
|
if value.lower() in ("repository", "sign-repository"):
|
||||||
return cls.Repository
|
return cls.Repository
|
||||||
return cls.Disabled
|
raise InvalidOption(value)
|
||||||
|
@ -22,6 +22,8 @@ from __future__ import annotations
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
|
from ahriman.core.exceptions import InvalidOption
|
||||||
|
|
||||||
|
|
||||||
class UploadSettings(Enum):
|
class UploadSettings(Enum):
|
||||||
"""
|
"""
|
||||||
@ -56,4 +58,4 @@ class UploadSettings(Enum):
|
|||||||
return cls.S3
|
return cls.S3
|
||||||
if value.lower() in ("github",):
|
if value.lower() in ("github",):
|
||||||
return cls.Github
|
return cls.Github
|
||||||
return cls.Disabled
|
raise InvalidOption(value)
|
||||||
|
@ -44,8 +44,8 @@ def exception_handler(logger: Logger) -> MiddlewareType:
|
|||||||
except HTTPServerError as e:
|
except HTTPServerError as e:
|
||||||
logger.exception("server exception during performing request to %s", request.path)
|
logger.exception("server exception during performing request to %s", request.path)
|
||||||
return json_response(data={"error": e.reason}, status=e.status_code)
|
return json_response(data={"error": e.reason}, status=e.status_code)
|
||||||
except HTTPException: # just raise 2xx and 3xx codes
|
except HTTPException:
|
||||||
raise
|
raise # just raise 2xx and 3xx codes
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("unknown exception during performing request to %s", request.path)
|
logger.exception("unknown exception during performing request to %s", request.path)
|
||||||
return json_response(data={"error": str(e)}, status=500)
|
return json_response(data={"error": str(e)}, status=500)
|
||||||
|
@ -34,30 +34,30 @@ class IndexView(BaseView):
|
|||||||
|
|
||||||
It uses jinja2 templates for report generation, the following variables are allowed:
|
It uses jinja2 templates for report generation, the following variables are allowed:
|
||||||
|
|
||||||
* architecture - repository architecture, string, required
|
architecture - repository architecture, string, required
|
||||||
* auth - authorization descriptor, required
|
auth - authorization descriptor, required
|
||||||
* authenticated - alias to check if user can see the page, boolean, required
|
* authenticated - alias to check if user can see the page, boolean, required
|
||||||
* control - HTML to insert for login control, HTML string, required
|
* control - HTML to insert for login control, HTML string, required
|
||||||
* enabled - whether authorization is enabled by configuration or not, boolean, required
|
* enabled - whether authorization is enabled by configuration or not, boolean, required
|
||||||
* username - authenticated username if any, string, null means not authenticated
|
* username - authenticated username if any, string, null means not authenticated
|
||||||
* index_url - url to the repository index, string, optional
|
index_url - url to the repository index, string, optional
|
||||||
* packages - sorted list of packages properties, required
|
packages - sorted list of packages properties, required
|
||||||
* base, string
|
* base, string
|
||||||
* depends, sorted list of strings
|
* depends, sorted list of strings
|
||||||
* groups, sorted list of strings
|
* groups, sorted list of strings
|
||||||
* licenses, sorted list of strings
|
* licenses, sorted list of strings
|
||||||
* packages, sorted list of strings
|
* packages, sorted list of strings
|
||||||
* status, string based on enum value
|
* status, string based on enum value
|
||||||
* status_color, string based on enum value
|
* status_color, string based on enum value
|
||||||
* timestamp, pretty printed datetime, string
|
* timestamp, pretty printed datetime, string
|
||||||
* version, string
|
* version, string
|
||||||
* web_url, string
|
* web_url, string
|
||||||
* repository - repository name, string, required
|
repository - repository name, string, required
|
||||||
* service - service status properties, required
|
service - service status properties, required
|
||||||
* status, string based on enum value
|
* status, string based on enum value
|
||||||
* status_color, string based on enum value
|
* status_color, string based on enum value
|
||||||
* timestamp, pretty printed datetime, string
|
* timestamp, pretty printed datetime, string
|
||||||
* version - ahriman version, string, required
|
version - ahriman version, string, required
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
GET_PERMISSION(UserAccess): (class attribute) get permissions of self
|
GET_PERMISSION(UserAccess): (class attribute) get permissions of self
|
||||||
|
@ -38,14 +38,9 @@ class AddView(BaseView):
|
|||||||
add new package
|
add new package
|
||||||
|
|
||||||
JSON body must be supplied, the following model is used:
|
JSON body must be supplied, the following model is used:
|
||||||
|
{
|
||||||
>>> {
|
"packages": "ahriman" # either list of packages or package name as in AUR
|
||||||
>>> "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:
|
try:
|
||||||
data = await self.extract_data(["packages"])
|
data = await self.extract_data(["packages"])
|
||||||
|
@ -38,14 +38,9 @@ class RemoveView(BaseView):
|
|||||||
remove existing packages
|
remove existing packages
|
||||||
|
|
||||||
JSON body must be supplied, the following model is used:
|
JSON body must be supplied, the following model is used:
|
||||||
|
{
|
||||||
>>> {
|
"packages": "ahriman", # either list of packages or package name
|
||||||
>>> "packages": "ahriman", # either list of packages or package name
|
}
|
||||||
>>> }
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
HTTPBadRequest: if bad data is supplied
|
|
||||||
HTTPFound: in case of success response
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
data = await self.extract_data(["packages"])
|
data = await self.extract_data(["packages"])
|
||||||
|
@ -38,14 +38,9 @@ class RequestView(BaseView):
|
|||||||
request to add new package
|
request to add new package
|
||||||
|
|
||||||
JSON body must be supplied, the following model is used:
|
JSON body must be supplied, the following model is used:
|
||||||
|
{
|
||||||
>>> {
|
"packages": "ahriman" # either list of packages or package name as in AUR
|
||||||
>>> "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:
|
try:
|
||||||
data = await self.extract_data(["packages"])
|
data = await self.extract_data(["packages"])
|
||||||
|
@ -45,9 +45,6 @@ class SearchView(BaseView):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Response: 200 with found package bases and descriptions sorted by base
|
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=[])
|
search: List[str] = self.request.query.getall("for", default=[])
|
||||||
packages = AUR.multisearch(*search)
|
packages = AUR.multisearch(*search)
|
||||||
|
@ -51,14 +51,9 @@ class AhrimanView(BaseView):
|
|||||||
update service status
|
update service status
|
||||||
|
|
||||||
JSON body must be supplied, the following model is used:
|
JSON body must be supplied, the following model is used:
|
||||||
|
{
|
||||||
>>> {
|
"status": "unknown", # service status string, must be valid `BuildStatusEnum`
|
||||||
>>> "status": "unknown", # service status string, must be valid `BuildStatusEnum`
|
}
|
||||||
>>> }
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
HTTPBadRequest: if bad data is supplied
|
|
||||||
HTTPNoContent: in case of success response
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
data = await self.extract_data()
|
data = await self.extract_data()
|
||||||
|
@ -46,9 +46,6 @@ class PackageView(BaseView):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Response: 200 with package description on success
|
Response: 200 with package description on success
|
||||||
|
|
||||||
Raises:
|
|
||||||
HTTPNotFound: if no package was found
|
|
||||||
"""
|
"""
|
||||||
base = self.request.match_info["package"]
|
base = self.request.match_info["package"]
|
||||||
|
|
||||||
@ -68,9 +65,6 @@ class PackageView(BaseView):
|
|||||||
async def delete(self) -> None:
|
async def delete(self) -> None:
|
||||||
"""
|
"""
|
||||||
delete package base from status page
|
delete package base from status page
|
||||||
|
|
||||||
Raises:
|
|
||||||
HTTPNoContent: on success response
|
|
||||||
"""
|
"""
|
||||||
base = self.request.match_info["package"]
|
base = self.request.match_info["package"]
|
||||||
self.service.remove(base)
|
self.service.remove(base)
|
||||||
@ -82,16 +76,11 @@ class PackageView(BaseView):
|
|||||||
update package build status
|
update package build status
|
||||||
|
|
||||||
JSON body must be supplied, the following model is used:
|
JSON body must be supplied, the following model is used:
|
||||||
|
{
|
||||||
>>> {
|
"status": "unknown", # package build status string, must be valid `BuildStatusEnum`
|
||||||
>>> "status": "unknown", # package build status string, must be valid `BuildStatusEnum`
|
"package": {} # package body (use `dataclasses.asdict` to generate one), optional.
|
||||||
>>> "package": {} # package body (use `dataclasses.asdict` to generate one), optional.
|
# Must be supplied in case if package base is unknown
|
||||||
>>> # 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"]
|
base = self.request.match_info["package"]
|
||||||
data = await self.extract_data()
|
data = await self.extract_data()
|
||||||
|
@ -54,9 +54,6 @@ class PackagesView(BaseView):
|
|||||||
async def post(self) -> None:
|
async def post(self) -> None:
|
||||||
"""
|
"""
|
||||||
reload all packages from repository. No parameters supported here
|
reload all packages from repository. No parameters supported here
|
||||||
|
|
||||||
Raises:
|
|
||||||
HTTPNoContent: on success response
|
|
||||||
"""
|
"""
|
||||||
self.service.load()
|
self.service.load()
|
||||||
|
|
||||||
|
@ -42,11 +42,6 @@ class LoginView(BaseView):
|
|||||||
|
|
||||||
In case if code provided it will do a request to get user email. In case if no code provided it will redirect
|
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
|
to authorization url provided by OAuth client
|
||||||
|
|
||||||
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
|
from ahriman.core.auth.oauth import OAuth
|
||||||
|
|
||||||
@ -72,15 +67,10 @@ class LoginView(BaseView):
|
|||||||
login user to service
|
login user to service
|
||||||
|
|
||||||
either JSON body or form data must be supplied the following fields are required:
|
either JSON body or form data must be supplied the following fields are required:
|
||||||
|
{
|
||||||
>>> {
|
"username": "username" # username to use for login
|
||||||
>>> "username": "username" # username to use for login
|
"password": "pa55w0rd" # password 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()
|
data = await self.extract_data()
|
||||||
username = data.get("username")
|
username = data.get("username")
|
||||||
|
@ -37,9 +37,6 @@ class LogoutView(BaseView):
|
|||||||
async def post(self) -> None:
|
async def post(self) -> None:
|
||||||
"""
|
"""
|
||||||
logout user from the service. No parameters supported here
|
logout user from the service. No parameters supported here
|
||||||
|
|
||||||
Raises:
|
|
||||||
HTTPFound: on success response
|
|
||||||
"""
|
"""
|
||||||
await check_authorized(self.request)
|
await check_authorized(self.request)
|
||||||
await forget(self.request, HTTPFound("/"))
|
await forget(self.request, HTTPFound("/"))
|
||||||
|
@ -49,9 +49,6 @@ async def on_startup(application: web.Application) -> None:
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
application(web.Application): web application instance
|
application(web.Application): web application instance
|
||||||
|
|
||||||
Raises:
|
|
||||||
InitializeException: in case if matched could not be loaded
|
|
||||||
"""
|
"""
|
||||||
application.logger.info("server started")
|
application.logger.info("server started")
|
||||||
try:
|
try:
|
||||||
|
@ -6,6 +6,7 @@ from pytest_mock import MockerFixture
|
|||||||
from ahriman.application.ahriman import _parser
|
from ahriman.application.ahriman import _parser
|
||||||
from ahriman.application.handlers import UnsafeCommands
|
from ahriman.application.handlers import UnsafeCommands
|
||||||
from ahriman.core.configuration import Configuration
|
from ahriman.core.configuration import Configuration
|
||||||
|
from ahriman.core.exceptions import ExitCode
|
||||||
|
|
||||||
|
|
||||||
def _default_args(args: argparse.Namespace) -> argparse.Namespace:
|
def _default_args(args: argparse.Namespace) -> argparse.Namespace:
|
||||||
@ -52,22 +53,19 @@ def test_run_check(args: argparse.Namespace, configuration: Configuration, mocke
|
|||||||
check_mock.assert_called_once_with("clean", ["command"], pytest.helpers.anyvar(int))
|
check_mock.assert_called_once_with("clean", ["command"], pytest.helpers.anyvar(int))
|
||||||
|
|
||||||
|
|
||||||
def test_check_unsafe(mocker: MockerFixture) -> None:
|
def test_check_unsafe() -> None:
|
||||||
"""
|
"""
|
||||||
must check if command is unsafe
|
must check if command is unsafe
|
||||||
"""
|
"""
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_if_empty")
|
with pytest.raises(ExitCode):
|
||||||
UnsafeCommands.check_unsafe("repo-clean", ["repo-clean"], _parser())
|
UnsafeCommands.check_unsafe("repo-clean", ["repo-clean"], _parser())
|
||||||
check_mock.assert_called_once_with(True, True)
|
|
||||||
|
|
||||||
|
|
||||||
def test_check_unsafe_safe(mocker: MockerFixture) -> None:
|
def test_check_unsafe_safe() -> None:
|
||||||
"""
|
"""
|
||||||
must check if command is safe
|
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())
|
UnsafeCommands.check_unsafe("package-status", ["repo-clean"], _parser())
|
||||||
check_mock.assert_called_once_with(True, False)
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_unsafe_commands() -> None:
|
def test_get_unsafe_commands() -> None:
|
||||||
|
@ -220,7 +220,7 @@ def database(configuration: Configuration) -> SQLite:
|
|||||||
database fixture
|
database fixture
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
configuration(Configuration): configuration fixture
|
configuration(Configuration):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
SQLite: database test instance
|
SQLite: database test instance
|
||||||
|
@ -4,7 +4,6 @@ import requests
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
|
||||||
from ahriman.core.configuration import Configuration
|
|
||||||
from ahriman.core.sign.gpg import GPG
|
from ahriman.core.sign.gpg import GPG
|
||||||
from ahriman.models.sign_settings import SignSettings
|
from ahriman.models.sign_settings import SignSettings
|
||||||
|
|
||||||
@ -64,18 +63,6 @@ def test_sign_command(gpg_with_key: GPG) -> None:
|
|||||||
assert gpg_with_key.sign_command(Path("a"), gpg_with_key.default_key)
|
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:
|
def test_key_download(gpg: GPG, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must download the key from public server
|
must download the key from public server
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from ahriman.core.exceptions import InvalidOption
|
||||||
from ahriman.models.auth_settings import AuthSettings
|
from ahriman.models.auth_settings import AuthSettings
|
||||||
|
|
||||||
|
|
||||||
def test_from_option_invalid() -> None:
|
def test_from_option_invalid() -> None:
|
||||||
"""
|
"""
|
||||||
return disabled on invalid option
|
must raise exception on invalid option
|
||||||
"""
|
"""
|
||||||
assert AuthSettings.from_option("invalid") == AuthSettings.Disabled
|
with pytest.raises(InvalidOption, match=".* `invalid`$"):
|
||||||
|
AuthSettings.from_option("invalid")
|
||||||
|
|
||||||
|
|
||||||
def test_from_option_valid() -> None:
|
def test_from_option_valid() -> None:
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from ahriman.core.exceptions import InvalidOption
|
||||||
from ahriman.models.report_settings import ReportSettings
|
from ahriman.models.report_settings import ReportSettings
|
||||||
|
|
||||||
|
|
||||||
def test_from_option_invalid() -> None:
|
def test_from_option_invalid() -> None:
|
||||||
"""
|
"""
|
||||||
must return disabled on invalid option
|
must raise exception on invalid option
|
||||||
"""
|
"""
|
||||||
assert ReportSettings.from_option("invalid") == ReportSettings.Disabled
|
with pytest.raises(InvalidOption, match=".* `invalid`$"):
|
||||||
|
ReportSettings.from_option("invalid")
|
||||||
|
|
||||||
|
|
||||||
def test_from_option_valid() -> None:
|
def test_from_option_valid() -> None:
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from ahriman.core.exceptions import InvalidOption
|
||||||
from ahriman.models.sign_settings import SignSettings
|
from ahriman.models.sign_settings import SignSettings
|
||||||
|
|
||||||
|
|
||||||
def test_from_option_invalid() -> None:
|
def test_from_option_invalid() -> None:
|
||||||
"""
|
"""
|
||||||
must return disabled on invalid option
|
must raise exception on invalid option
|
||||||
"""
|
"""
|
||||||
assert SignSettings.from_option("invalid") == SignSettings.Disabled
|
with pytest.raises(InvalidOption, match=".* `invalid`$"):
|
||||||
|
SignSettings.from_option("invalid")
|
||||||
|
|
||||||
|
|
||||||
def test_from_option_valid() -> None:
|
def test_from_option_valid() -> None:
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from ahriman.core.exceptions import InvalidOption
|
||||||
from ahriman.models.upload_settings import UploadSettings
|
from ahriman.models.upload_settings import UploadSettings
|
||||||
|
|
||||||
|
|
||||||
def test_from_option_invalid() -> None:
|
def test_from_option_invalid() -> None:
|
||||||
"""
|
"""
|
||||||
must return disabled on invalid option
|
must raise exception on invalid option
|
||||||
"""
|
"""
|
||||||
assert UploadSettings.from_option("invalid") == UploadSettings.Disabled
|
with pytest.raises(InvalidOption, match=".* `invalid`$"):
|
||||||
|
UploadSettings.from_option("invalid")
|
||||||
|
|
||||||
|
|
||||||
def test_from_option_valid() -> None:
|
def test_from_option_valid() -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user