From 67407a569e84b78083fbd6720791377680a0a5bb Mon Sep 17 00:00:00 2001 From: Patrick Ritter <7950125+patrit@users.noreply.github.com> Date: Sun, 5 Nov 2023 10:44:43 +0100 Subject: [PATCH] build: switch to ruff linter --- .dockerignore | 1 - .gitignore | 1 + .pylintrc | 502 ------------------ Makefile | 8 +- gitopscli/appconfig_api/app_tenant_config.py | 9 +- gitopscli/appconfig_api/root_repo.py | 11 +- gitopscli/cliparser.py | 76 ++- gitopscli/commands/__init__.py | 7 +- gitopscli/commands/add_pr_comment.py | 2 + gitopscli/commands/command_factory.py | 9 +- gitopscli/commands/create_pr_preview.py | 4 +- gitopscli/commands/create_preview.py | 44 +- gitopscli/commands/delete_pr_preview.py | 6 +- gitopscli/commands/delete_preview.py | 12 +- gitopscli/commands/deploy.py | 15 +- gitopscli/commands/sync_apps.py | 17 +- gitopscli/commands/version.py | 3 +- gitopscli/git_api/__init__.py | 4 +- .../git_api/bitbucket_git_repo_api_adapter.py | 33 +- gitopscli/git_api/git_api_config.py | 1 + gitopscli/git_api/git_repo.py | 18 +- gitopscli/git_api/git_repo_api.py | 17 +- gitopscli/git_api/git_repo_api_factory.py | 10 +- .../git_api/git_repo_api_logging_proxy.py | 23 +- .../git_api/github_git_repo_api_adapter.py | 28 +- .../git_api/gitlab_git_repo_api_adapter.py | 26 +- gitopscli/gitops_config.py | 75 +-- gitopscli/io_api/tmp_dir.py | 2 +- gitopscli/io_api/yaml_util.py | 3 +- poetry.lock | 455 ++++++---------- pyproject.toml | 60 ++- tests/commands/test_sync_apps.py | 16 +- 32 files changed, 545 insertions(+), 953 deletions(-) delete mode 100644 .pylintrc diff --git a/.dockerignore b/.dockerignore index b214b39e..48da24b6 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,7 +3,6 @@ !docs !gitopscli/ !tests/ -!.pylintrc !CONTRIBUTING.md !mkdocs.yml !Makefile diff --git a/.gitignore b/.gitignore index 28a78196..fa985dd9 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ testrepo/ site/ build/ .mypy_cache +.ruff_cache diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 68c7565f..00000000 --- a/.pylintrc +++ /dev/null @@ -1,502 +0,0 @@ -[MASTER] - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. -extension-pkg-whitelist= - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the blacklist. The -# regex matches against base names, not paths. -ignore-patterns= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. -jobs=0 - -# Control the amount of potential inferred values when inferring a single -# object. This can help the performance when dealing with large functions or -# complex, nested conditions. -limit-inference-results=100 - -# List of plugins (as comma separated values of python module names) to load, -# usually to register additional checkers. -load-plugins= - -# Pickle collected data for later comparisons. -persistent=yes - -# Specify a configuration file. -#rcfile= - -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode=yes - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once). You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable=missing-function-docstring, - missing-module-docstring, - missing-class-docstring, - too-many-arguments, - too-many-locals, - duplicate-code #check introduced in pylint 2.7.1, seem to usually show false-positives. There is a value in it - but not in automated pipeline usage. - - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable=c-extension-no-member - - -[REPORTS] - -# Python expression which should return a score less than or equal to 10. You -# have access to the variables 'error', 'warning', 'refactor', and 'convention' -# which contain the number of messages in each category, as well as 'statement' -# which is the total number of statements analyzed. This score is used by the -# global evaluation report (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. -output-format=colorized - -# Tells whether to display a full report or only the messages. -reports=no - -# Activate the evaluation score. -score=yes - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - -# Complete name of functions that never returns. When checking for -# inconsistent-return-statements if a never returning function is called then -# it will be considered as an explicit return statement and no message will be -# printed. -never-returning-functions=sys.exit - - -[SPELLING] - -# Limits count of emitted suggestions for spelling mistakes. -max-spelling-suggestions=4 - -# Spelling dictionary name. Available dictionaries: none. To make it work, -# install the python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains the private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to the private dictionary (see the -# --spelling-private-dict-file option) instead of raising a message. -spelling-store-unknown-words=no - - -[BASIC] - -# Naming style matching correct argument names. -argument-naming-style=snake_case - -# Regular expression matching correct argument names. Overrides argument- -# naming-style. -#argument-rgx= - -# Naming style matching correct attribute names. -attr-naming-style=snake_case - -# Regular expression matching correct attribute names. Overrides attr-naming- -# style. -#attr-rgx= - -# Bad variable names which should always be refused, separated by a comma. -bad-names=foo, - bar, - baz, - toto, - tutu, - tata - -# Naming style matching correct class attribute names. -class-attribute-naming-style=any - -# Regular expression matching correct class attribute names. Overrides class- -# attribute-naming-style. -#class-attribute-rgx= - -# Naming style matching correct class names. -class-naming-style=PascalCase - -# Regular expression matching correct class names. Overrides class-naming- -# style. -#class-rgx= - -# Naming style matching correct constant names. -const-naming-style=UPPER_CASE - -# Regular expression matching correct constant names. Overrides const-naming- -# style. -#const-rgx= - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - -# Naming style matching correct function names. -function-naming-style=snake_case - -# Regular expression matching correct function names. Overrides function- -# naming-style. -#function-rgx= - -# Good variable names which should always be accepted, separated by a comma. -good-names=i, - j, - k, - ex, - Run, - _ - -# Include a hint for the correct naming format with invalid-name. -include-naming-hint=no - -# Naming style matching correct inline iteration names. -inlinevar-naming-style=any - -# Regular expression matching correct inline iteration names. Overrides -# inlinevar-naming-style. -#inlinevar-rgx= - -# Naming style matching correct method names. -method-naming-style=snake_case - -# Regular expression matching correct method names. Overrides method-naming- -# style. -#method-rgx= - -# Naming style matching correct module names. -module-naming-style=snake_case - -# Regular expression matching correct module names. Overrides module-naming- -# style. -#module-rgx= - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -# These decorators are taken in consideration only for invalid-name. -property-classes=abc.abstractproperty - -# Naming style matching correct variable names. -variable-naming-style=snake_case - -# Regular expression matching correct variable names. Overrides variable- -# naming-style. -#variable-rgx= - - -[SIMILARITIES] - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - -# Minimum lines number of a similarity. -min-similarity-lines=4 - - -[FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. -max-line-length=120 - -# Maximum number of lines in a module. -max-module-lines=1000 - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid defining new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_, - _cb - -# A regular expression matching the name of dummy variables (i.e. expected to -# not be used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore. -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io - - -[LOGGING] - -# Format style used to check logging format string. `old` means using % -# formatting, `new` is for `{}` formatting,and `fstr` is for f-strings. -logging-format-style=old - -# Logging modules to check that the string format arguments are in logging -# function parameter format. -logging-modules=logging - - -[STRING] - -# This flag controls whether the implicit-str-concat-in-sequence should -# generate a warning on implicit string concatenation in sequences defined over -# several lines. -check-str-concat-over-line-jumps=no - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME, - XXX, - TODO - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# Tells whether to warn about missing members when the owner of the attribute -# is inferred to be None. -ignore-none=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis). It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - -# List of decorators that change the signature of a decorated function. -signature-mutators= - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__, - __new__, - setUp, - __post_init__ - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict, - _fields, - _replace, - _source, - _make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=cls - - -[DESIGN] - -# Maximum number of arguments for function / method. -max-args=5 - -# Maximum number of attributes for a class (see R0902). -max-attributes=14 - -# Maximum number of boolean expressions in an if statement (see R0916). -max-bool-expr=5 - -# Maximum number of branch for function / method body. -max-branches=12 - -# Maximum number of locals for function / method body. -max-locals=15 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body. -max-returns=6 - -# Maximum number of statements in function / method body. -max-statements=50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=1 - - -[IMPORTS] - -# List of modules that can be imported at any level, not just the top level -# one. -allow-any-import-level= - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma. -deprecated-modules=optparse,tkinter.tix - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled). -ext-import-graph= - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled). -import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled). -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - -# Couples of modules and preferred modules, separated by a comma. -preferred-modules= - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "BaseException, Exception". -overgeneral-exceptions=builtins.BaseException, - builtins.Exception diff --git a/Makefile b/Makefile index 0b2ef446..4c565100 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,15 @@ -BLACK_ARGS = -l 120 -t py310 gitopscli tests - init: poetry install pre-commit install format: - poetry run black $(BLACK_ARGS) + poetry run ruff format gitopscli tests format-check: - poetry run black $(BLACK_ARGS) --check + poetry run ruff format gitopscli tests --check lint: - poetry run pylint gitopscli + poetry run ruff gitopscli tests mypy: poetry run mypy --install-types --non-interactive . diff --git a/gitopscli/appconfig_api/app_tenant_config.py b/gitopscli/appconfig_api/app_tenant_config.py index 9252847e..07a0a151 100644 --- a/gitopscli/appconfig_api/app_tenant_config.py +++ b/gitopscli/appconfig_api/app_tenant_config.py @@ -1,12 +1,11 @@ import logging -from dataclasses import dataclass, field import os +from dataclasses import dataclass, field from typing import Any from gitopscli.git_api import GitRepo -from gitopscli.io_api.yaml_util import yaml_load, yaml_file_load - from gitopscli.gitops_exception import GitOpsException +from gitopscli.io_api.yaml_util import yaml_file_load, yaml_load @dataclass @@ -81,10 +80,10 @@ def __set_dirty(self) -> None: def __generate_config_from_tenant_repo( tenant_repo: GitRepo, -) -> Any: # TODO: supposed to be ruamel object than Any pylint: disable=fixme +) -> Any: # TODO: supposed to be ruamel object than Any tenant_app_dirs = __get_all_tenant_applications_dirs(tenant_repo) tenant_config_template = f""" - config: + config: repository: {tenant_repo.get_clone_url()} applications: {{}} """ diff --git a/gitopscli/appconfig_api/root_repo.py b/gitopscli/appconfig_api/root_repo.py index 4ffad422..9c70e38d 100644 --- a/gitopscli/appconfig_api/root_repo.py +++ b/gitopscli/appconfig_api/root_repo.py @@ -1,11 +1,10 @@ from dataclasses import dataclass -from typing import List, Any, Optional - -from gitopscli.git_api import GitRepo -from gitopscli.io_api.yaml_util import yaml_file_load +from typing import Any, Optional from gitopscli.appconfig_api.app_tenant_config import AppTenantConfig +from gitopscli.git_api import GitRepo from gitopscli.gitops_exception import GitOpsException +from gitopscli.io_api.yaml_util import yaml_file_load @dataclass @@ -54,7 +53,7 @@ def __load_tenants_from_bootstrap_values(root_repo: GitRepo) -> dict[str, AppTen return tenants -def __get_bootstrap_tenant_list(root_repo: GitRepo) -> List[Any]: +def __get_bootstrap_tenant_list(root_repo: GitRepo) -> list[Any]: root_repo.clone() try: boostrap_values_path = root_repo.get_full_file_path("bootstrap/values.yaml") @@ -70,7 +69,7 @@ def __get_bootstrap_tenant_list(root_repo: GitRepo) -> List[Any]: return bootstrap_tenants -def __validate_bootstrap_tenants(bootstrap_entries: Optional[List[Any]]) -> None: +def __validate_bootstrap_tenants(bootstrap_entries: Optional[list[Any]]) -> None: if not bootstrap_entries: raise GitOpsException("Cannot find key 'bootstrap' or 'config.bootstrap' in 'bootstrap/values.yaml'") for bootstrap_entry in bootstrap_entries: diff --git a/gitopscli/cliparser.py b/gitopscli/cliparser.py index 14473105..2c8ac715 100644 --- a/gitopscli/cliparser.py +++ b/gitopscli/cliparser.py @@ -1,23 +1,25 @@ -from argparse import ArgumentParser, ArgumentTypeError import os import sys -from typing import List, Tuple, Dict, Any, NoReturn, Callable +from argparse import ArgumentParser, ArgumentTypeError +from collections.abc import Callable +from typing import Any, NoReturn + from gitopscli.commands import ( - CommandArgs, - DeployCommand, - SyncAppsCommand, AddPrCommentCommand, + CommandArgs, CreatePreviewCommand, CreatePrPreviewCommand, DeletePreviewCommand, DeletePrPreviewCommand, + DeployCommand, + SyncAppsCommand, VersionCommand, ) from gitopscli.git_api import GitProvider -from gitopscli.io_api.yaml_util import yaml_load, YAMLException +from gitopscli.io_api.yaml_util import YAMLException, yaml_load -def parse_args(raw_args: List[str]) -> Tuple[bool, CommandArgs]: +def parse_args(raw_args: list[str]) -> tuple[bool, CommandArgs]: parser = __create_parser() if len(raw_args) == 0: @@ -36,7 +38,9 @@ def __create_parser() -> ArgumentParser: parser = ArgumentParser(prog="gitopscli", description="GitOps CLI") subparsers = parser.add_subparsers(title="commands", dest="command") subparsers.add_parser( - "deploy", help="Trigger a new deployment by changing YAML values", parents=[__create_deploy_parser()] + "deploy", + help="Trigger a new deployment by changing YAML values", + parents=[__create_deploy_parser()], ) subparsers.add_parser( "sync-apps", @@ -44,22 +48,34 @@ def __create_parser() -> ArgumentParser: parents=[__create_sync_apps_parser()], ) subparsers.add_parser( - "add-pr-comment", help="Create a comment on the pull request", parents=[__create_add_pr_comment_parser()] + "add-pr-comment", + help="Create a comment on the pull request", + parents=[__create_add_pr_comment_parser()], ) subparsers.add_parser( - "create-preview", help="Create a preview environment", parents=[__create_create_preview_parser()] + "create-preview", + help="Create a preview environment", + parents=[__create_create_preview_parser()], ) subparsers.add_parser( - "create-pr-preview", help="Create a preview environment", parents=[__create_create_pr_preview_parser()] + "create-pr-preview", + help="Create a preview environment", + parents=[__create_create_pr_preview_parser()], ) subparsers.add_parser( - "delete-preview", help="Delete a preview environment", parents=[__create_delete_preview_parser()] + "delete-preview", + help="Delete a preview environment", + parents=[__create_delete_preview_parser()], ) subparsers.add_parser( - "delete-pr-preview", help="Delete a pr preview environment", parents=[__create_delete_pr_preview_parser()] + "delete-pr-preview", + help="Delete a pr preview environment", + parents=[__create_delete_pr_preview_parser()], ) subparsers.add_parser( - "version", help="Show the GitOps CLI version information", parents=[__create_version_parser()] + "version", + help="Show the GitOps CLI version information", + parents=[__create_version_parser()], ) return parser @@ -82,14 +98,22 @@ def __create_deploy_parser() -> ArgumentParser: default=False, ) parser.add_argument( - "--commit-message", help="Specify exact commit message of deployment commit", type=str, default=None + "--commit-message", + help="Specify exact commit message of deployment commit", + type=str, + default=None, ) __add_git_credentials_args(parser) __add_git_commit_user_args(parser) __add_git_org_and_repo_args(parser) __add_git_provider_args(parser) parser.add_argument( - "--create-pr", help="Creates a Pull Request", type=__parse_bool, nargs="?", const=True, default=False + "--create-pr", + help="Creates a Pull Request", + type=__parse_bool, + nargs="?", + const=True, + default=False, ) parser.add_argument( "--auto-merge", @@ -113,7 +137,10 @@ def __create_deploy_parser() -> ArgumentParser: default=False, ) parser.add_argument( - "--pr-labels", help="JSON array pr labels (Gitlab, Github supported)", type=__parse_yaml, default=None + "--pr-labels", + help="JSON array pr labels (Gitlab, Github supported)", + type=__parse_yaml, + default=None, ) parser.add_argument( "--merge-parameters", @@ -258,7 +285,13 @@ def __add_expect_preview_exists_arg(parser: ArgumentParser) -> None: def __add_verbose_arg(parser: ArgumentParser) -> None: parser.add_argument( - "-v", "--verbose", help="Verbose exception logging", type=__parse_bool, nargs="?", const=True, default=False + "-v", + "--verbose", + help="Verbose exception logging", + type=__parse_bool, + nargs="?", + const=True, + default=False, ) @@ -293,8 +326,9 @@ def __print_help_and_exit(parser: ArgumentParser) -> NoReturn: def __deduce_empty_git_provider_from_git_provider_url( - args: Dict[str, Any], error: Callable[[str], NoReturn] -) -> Dict[str, Any]: + args: dict[str, Any], + error: Callable[[str], NoReturn], +) -> dict[str, Any]: if "git_provider" not in args or args["git_provider"] is not None: return args git_provider_url = args["git_provider_url"] @@ -312,7 +346,7 @@ def __deduce_empty_git_provider_from_git_provider_url( return updated_args -def __create_command_args(args: Dict[str, Any]) -> CommandArgs: +def __create_command_args(args: dict[str, Any]) -> CommandArgs: args = dict(args) command = args.pop("command") diff --git a/gitopscli/commands/__init__.py b/gitopscli/commands/__init__.py index 18982fe0..0d79d36a 100644 --- a/gitopscli/commands/__init__.py +++ b/gitopscli/commands/__init__.py @@ -1,11 +1,10 @@ +from .add_pr_comment import AddPrCommentCommand from .command import Command from .command_factory import CommandArgs, CommandFactory - -from .add_pr_comment import AddPrCommentCommand -from .create_preview import CreatePreviewCommand from .create_pr_preview import CreatePrPreviewCommand -from .delete_preview import DeletePreviewCommand +from .create_preview import CreatePreviewCommand from .delete_pr_preview import DeletePrPreviewCommand +from .delete_preview import DeletePreviewCommand from .deploy import DeployCommand from .sync_apps import SyncAppsCommand from .version import VersionCommand diff --git a/gitopscli/commands/add_pr_comment.py b/gitopscli/commands/add_pr_comment.py index c5945c1c..1fcc3746 100644 --- a/gitopscli/commands/add_pr_comment.py +++ b/gitopscli/commands/add_pr_comment.py @@ -1,6 +1,8 @@ from dataclasses import dataclass from typing import Optional + from gitopscli.git_api import GitApiConfig, GitRepoApiFactory + from .command import Command diff --git a/gitopscli/commands/command_factory.py b/gitopscli/commands/command_factory.py index 10fd4e53..ee67739f 100644 --- a/gitopscli/commands/command_factory.py +++ b/gitopscli/commands/command_factory.py @@ -1,10 +1,11 @@ -from typing import Union, Optional -from .command import Command +from typing import Optional, Union + from .add_pr_comment import AddPrCommentCommand -from .create_preview import CreatePreviewCommand +from .command import Command from .create_pr_preview import CreatePrPreviewCommand -from .delete_preview import DeletePreviewCommand +from .create_preview import CreatePreviewCommand from .delete_pr_preview import DeletePrPreviewCommand +from .delete_preview import DeletePreviewCommand from .deploy import DeployCommand from .sync_apps import SyncAppsCommand from .version import VersionCommand diff --git a/gitopscli/commands/create_pr_preview.py b/gitopscli/commands/create_pr_preview.py index d07e7dcb..f6a0fdc2 100644 --- a/gitopscli/commands/create_pr_preview.py +++ b/gitopscli/commands/create_pr_preview.py @@ -1,8 +1,10 @@ from dataclasses import dataclass from typing import Optional + from gitopscli.git_api import GitApiConfig, GitRepoApiFactory -from .create_preview import CreatePreviewCommand + from .command import Command +from .create_preview import CreatePreviewCommand class CreatePrPreviewCommand(Command): diff --git a/gitopscli/commands/create_preview.py b/gitopscli/commands/create_preview.py index 202ece1a..d3ba7d35 100644 --- a/gitopscli/commands/create_preview.py +++ b/gitopscli/commands/create_preview.py @@ -1,14 +1,17 @@ import logging import os import shutil +from collections.abc import Callable from dataclasses import dataclass -from typing import Any, Callable, Optional +from typing import Any, Optional + from gitopscli.git_api import GitApiConfig, GitRepo, GitRepoApi, GitRepoApiFactory -from gitopscli.io_api.yaml_util import update_yaml_file, YAMLException, yaml_file_dump from gitopscli.gitops_config import GitOpsConfig from gitopscli.gitops_exception import GitOpsException -from .common import load_gitops_config +from gitopscli.io_api.yaml_util import YAMLException, update_yaml_file, yaml_file_dump + from .command import Command +from .common import load_gitops_config class CreatePreviewCommand(Command): @@ -53,19 +56,25 @@ def execute(self) -> None: if gitops_config.is_preview_template_equal_target(): preview_template_repo = preview_target_git_repo created_new_preview = self.__create_preview_from_template_if_not_existing( - preview_template_repo, preview_target_git_repo, gitops_config + preview_template_repo, + preview_target_git_repo, + gitops_config, ) else: preview_template_git_repo_api = self.__create_preview_template_git_repo_api(gitops_config) with GitRepo(preview_template_git_repo_api) as preview_template_repo: preview_template_repo.clone(gitops_config.preview_template_branch) created_new_preview = self.__create_preview_from_template_if_not_existing( - preview_template_repo, preview_target_git_repo, gitops_config + preview_template_repo, + preview_target_git_repo, + gitops_config, ) any_values_replaced = self.__replace_values(preview_target_git_repo, gitops_config) context = GitOpsConfig.Replacement.PreviewContext( - gitops_config, self.__args.preview_id, self.__args.git_hash + gitops_config, + self.__args.preview_id, + self.__args.git_hash, ) if not created_new_preview and not any_values_replaced: @@ -99,16 +108,23 @@ def __get_gitops_config(self) -> GitOpsConfig: def __create_preview_template_git_repo_api(self, gitops_config: GitOpsConfig) -> GitRepoApi: return GitRepoApiFactory.create( - self.__args, gitops_config.preview_template_organisation, gitops_config.preview_template_repository + self.__args, + gitops_config.preview_template_organisation, + gitops_config.preview_template_repository, ) def __create_preview_target_git_repo_api(self, gitops_config: GitOpsConfig) -> GitRepoApi: return GitRepoApiFactory.create( - self.__args, gitops_config.preview_target_organisation, gitops_config.preview_target_repository + self.__args, + gitops_config.preview_target_organisation, + gitops_config.preview_target_repository, ) def __create_preview_from_template_if_not_existing( - self, template_git_repo: GitRepo, target_git_repo: GitRepo, gitops_config: GitOpsConfig + self, + template_git_repo: GitRepo, + target_git_repo: GitRepo, + gitops_config: GitOpsConfig, ) -> bool: preview_namespace = gitops_config.get_preview_namespace(self.__args.preview_id) full_preview_folder_path = target_git_repo.get_full_file_path(preview_namespace) @@ -133,12 +149,18 @@ def __replace_values(self, git_repo: GitRepo, gitops_config: GitOpsConfig) -> bo for replacement in replacements: replacement_value = replacement.get_value(context) value_replaced = self.__update_yaml_file( - git_repo, f"{preview_folder_name}/{file}", replacement.path, replacement_value + git_repo, + f"{preview_folder_name}/{file}", + replacement.path, + replacement_value, ) if value_replaced: any_value_replaced = True logging.info( - "Replaced property '%s' in '%s' with value: %s", replacement.path, file, replacement_value + "Replaced property '%s' in '%s' with value: %s", + replacement.path, + file, + replacement_value, ) else: logging.info("Keep property '%s' in '%s' value: %s", replacement.path, file, replacement_value) diff --git a/gitopscli/commands/delete_pr_preview.py b/gitopscli/commands/delete_pr_preview.py index de2ea678..927b9c79 100644 --- a/gitopscli/commands/delete_pr_preview.py +++ b/gitopscli/commands/delete_pr_preview.py @@ -1,8 +1,10 @@ from dataclasses import dataclass from typing import Optional + from gitopscli.git_api import GitApiConfig -from .delete_preview import DeletePreviewCommand + from .command import Command +from .delete_preview import DeletePreviewCommand class DeletePrPreviewCommand(Command): @@ -39,5 +41,5 @@ def execute(self) -> None: git_provider_url=args.git_provider_url, preview_id=args.branch, # use branch as preview id expect_preview_exists=args.expect_preview_exists, - ) + ), ).execute() diff --git a/gitopscli/commands/delete_preview.py b/gitopscli/commands/delete_preview.py index 6c870fa4..077028ef 100644 --- a/gitopscli/commands/delete_preview.py +++ b/gitopscli/commands/delete_preview.py @@ -1,13 +1,15 @@ import logging import os import shutil -from typing import Optional from dataclasses import dataclass -from gitopscli.git_api import GitApiConfig, GitRepo, GitRepoApiFactory, GitRepoApi +from typing import Optional + +from gitopscli.git_api import GitApiConfig, GitRepo, GitRepoApi, GitRepoApiFactory from gitopscli.gitops_config import GitOpsConfig from gitopscli.gitops_exception import GitOpsException -from .common import load_gitops_config + from .command import Command +from .common import load_gitops_config class DeletePreviewCommand(Command): @@ -60,7 +62,9 @@ def __get_gitops_config(self) -> GitOpsConfig: def __create_preview_target_git_repo_api(self, gitops_config: GitOpsConfig) -> GitRepoApi: return GitRepoApiFactory.create( - self.__args, gitops_config.preview_target_organisation, gitops_config.preview_target_repository + self.__args, + gitops_config.preview_target_organisation, + gitops_config.preview_target_repository, ) def __commit_and_push(self, git_repo: GitRepo, message: str) -> None: diff --git a/gitopscli/commands/deploy.py b/gitopscli/commands/deploy.py index e81b3c3c..03ef7820 100644 --- a/gitopscli/commands/deploy.py +++ b/gitopscli/commands/deploy.py @@ -2,15 +2,16 @@ import logging import uuid from dataclasses import dataclass -from typing import Any, Dict, Optional, Tuple, Literal, List +from typing import Any, Literal, Optional + from gitopscli.git_api import GitApiConfig, GitRepo, GitRepoApi, GitRepoApiFactory -from gitopscli.io_api.yaml_util import update_yaml_file, yaml_dump, YAMLException from gitopscli.gitops_exception import GitOpsException +from gitopscli.io_api.yaml_util import YAMLException, update_yaml_file, yaml_dump + from .command import Command class DeployCommand(Command): - # pylint: disable=too-many-instance-attributes @dataclass(frozen=True) class Args(GitApiConfig): git_user: str @@ -32,13 +33,13 @@ class Args(GitApiConfig): auto_merge: bool json: bool - pr_labels: Optional[List[str]] + pr_labels: Optional[list[str]] merge_parameters: Optional[Any] merge_method: Literal["squash", "rebase", "merge"] = "merge" def __init__(self, args: Args) -> None: self.__args = args - self.__commit_hashes: List[str] = [] + self.__commit_hashes: list[str] = [] def execute(self) -> None: git_repo_api = self.__create_git_repo_api() @@ -74,7 +75,7 @@ def execute(self) -> None: def __create_git_repo_api(self) -> GitRepoApi: return GitRepoApiFactory.create(self.__args, self.__args.organisation, self.__args.repository_name) - def __update_values(self, git_repo: GitRepo) -> Dict[str, Any]: + def __update_values(self, git_repo: GitRepo) -> dict[str, Any]: args = self.__args single_commit = args.single_commit or args.commit_message full_file_path = git_repo.get_full_file_path(args.file) @@ -113,7 +114,7 @@ def __update_values(self, git_repo: GitRepo) -> Dict[str, Any]: return updated_values - def __create_pull_request_title_and_description(self, updated_values: Dict[str, Any]) -> Tuple[str, str]: + def __create_pull_request_title_and_description(self, updated_values: dict[str, Any]) -> tuple[str, str]: updated_file_name = self.__args.file updates_count = len(updated_values) value_or_values = "values" if updates_count > 1 else "value" diff --git a/gitopscli/commands/sync_apps.py b/gitopscli/commands/sync_apps.py index 2d11da6f..fab651e9 100644 --- a/gitopscli/commands/sync_apps.py +++ b/gitopscli/commands/sync_apps.py @@ -1,12 +1,13 @@ import logging -from typing import Optional from dataclasses import dataclass +from typing import Optional + +from gitopscli.appconfig_api.app_tenant_config import create_app_tenant_config_from_repo +from gitopscli.appconfig_api.root_repo import create_root_repo +from gitopscli.commands.command import Command from gitopscli.git_api import GitApiConfig, GitRepo, GitRepoApiFactory from gitopscli.gitops_exception import GitOpsException from gitopscli.io_api.yaml_util import yaml_file_dump -from gitopscli.commands.command import Command -from gitopscli.appconfig_api.app_tenant_config import create_app_tenant_config_from_repo -from gitopscli.appconfig_api.root_repo import create_root_repo class SyncAppsCommand(Command): @@ -46,7 +47,7 @@ def _sync_apps_command(args: SyncAppsCommand.Args) -> None: ) -# TODO: BETTER NAMES FOR STUFF HERE pylint: disable=fixme +# TODO: BETTER NAMES FOR STUFF HERE def __sync_apps( tenant_git_repo: GitRepo, root_git_repo: GitRepo, @@ -97,6 +98,10 @@ def __commit_and_push( ) -> None: author = team_config_git_repo.get_author_from_last_commit() root_config_git_repo.commit( - git_user, git_email, git_author_name, git_author_email, f"{author} updated " + app_file_name + git_user, + git_email, + git_author_name, + git_author_email, + f"{author} updated " + app_file_name, ) root_config_git_repo.push() diff --git a/gitopscli/commands/version.py b/gitopscli/commands/version.py index 4a08dfe6..f9dc39e4 100644 --- a/gitopscli/commands/version.py +++ b/gitopscli/commands/version.py @@ -1,5 +1,6 @@ -from dataclasses import dataclass import importlib.metadata +from dataclasses import dataclass + from .command import Command diff --git a/gitopscli/git_api/__init__.py b/gitopscli/git_api/__init__.py index a145213f..204ba0fc 100644 --- a/gitopscli/git_api/__init__.py +++ b/gitopscli/git_api/__init__.py @@ -1,5 +1,5 @@ +from .git_api_config import GitApiConfig +from .git_provider import GitProvider from .git_repo import GitRepo from .git_repo_api import GitRepoApi from .git_repo_api_factory import GitRepoApiFactory -from .git_api_config import GitApiConfig -from .git_provider import GitProvider diff --git a/gitopscli/git_api/bitbucket_git_repo_api_adapter.py b/gitopscli/git_api/bitbucket_git_repo_api_adapter.py index 7f4af748..da04de2c 100644 --- a/gitopscli/git_api/bitbucket_git_repo_api_adapter.py +++ b/gitopscli/git_api/bitbucket_git_repo_api_adapter.py @@ -1,7 +1,8 @@ -from typing import List, Dict, Any, Optional, Literal -import requests +from typing import Any, Literal, Optional +import requests from atlassian import Bitbucket + from gitopscli.gitops_exception import GitOpsException from .git_repo_api import GitRepoApi @@ -52,13 +53,20 @@ def get_clone_url(self) -> str: return str(repo_url) def create_pull_request_to_default_branch( - self, from_branch: str, title: str, description: str + self, + from_branch: str, + title: str, + description: str, ) -> GitRepoApi.PullRequestIdAndUrl: to_branch = self.__get_default_branch() return self.create_pull_request(from_branch, to_branch, title, description) def create_pull_request( - self, from_branch: str, to_branch: str, title: str, description: str + self, + from_branch: str, + to_branch: str, + title: str, + description: str, ) -> GitRepoApi.PullRequestIdAndUrl: pull_request = self.__bitbucket.open_pull_request( self.__organisation, @@ -78,16 +86,23 @@ def merge_pull_request( self, pr_id: int, merge_method: Literal["squash", "rebase", "merge"] = "merge", - merge_parameters: Optional[Dict[str, Any]] = None, + merge_parameters: Optional[dict[str, Any]] = None, ) -> None: pull_request = self.__bitbucket.get_pullrequest(self.__organisation, self.__repository_name, pr_id) self.__bitbucket.merge_pull_request( - self.__organisation, self.__repository_name, pull_request["id"], pull_request["version"] + self.__organisation, + self.__repository_name, + pull_request["id"], + pull_request["version"], ) def add_pull_request_comment(self, pr_id: int, text: str, parent_id: Optional[int] = None) -> None: pull_request_comment = self.__bitbucket.add_pull_request_comment( - self.__organisation, self.__repository_name, pr_id, text, parent_id + self.__organisation, + self.__repository_name, + pr_id, + text, + parent_id, ) if "errors" in pull_request_comment: raise GitOpsException(pull_request_comment["errors"][0]["message"]) @@ -100,7 +115,7 @@ def delete_branch(self, branch: str) -> None: def get_branch_head_hash(self, branch: str) -> str: branches = list( - self.__bitbucket.get_branches(self.__organisation, self.__repository_name, filter=branch, limit=1) + self.__bitbucket.get_branches(self.__organisation, self.__repository_name, filter=branch, limit=1), ) if not branches: raise GitOpsException(f"Branch '{branch}' not found'") @@ -116,5 +131,5 @@ def __get_default_branch(self) -> str: default_branch = self.__bitbucket.get_default_branch(self.__organisation, self.__repository_name) return str(default_branch["id"]) - def add_pull_request_label(self, pr_id: int, pr_labels: List[str]) -> None: + def add_pull_request_label(self, pr_id: int, pr_labels: list[str]) -> None: pass diff --git a/gitopscli/git_api/git_api_config.py b/gitopscli/git_api/git_api_config.py index 234ce6c4..cdc1f3c4 100644 --- a/gitopscli/git_api/git_api_config.py +++ b/gitopscli/git_api/git_api_config.py @@ -1,5 +1,6 @@ from dataclasses import dataclass from typing import Optional + from .git_provider import GitProvider diff --git a/gitopscli/git_api/git_repo.py b/gitopscli/git_api/git_repo.py index d4b03381..bee12366 100644 --- a/gitopscli/git_api/git_repo.py +++ b/gitopscli/git_api/git_repo.py @@ -1,11 +1,14 @@ -import os -import logging import locale +import logging +import os from types import TracebackType -from typing import Optional, Type, Literal -from git import Repo, GitError, GitCommandError +from typing import Literal, Optional + +from git import GitCommandError, GitError, Repo + from gitopscli.gitops_exception import GitOpsException from gitopscli.io_api.tmp_dir import create_tmp_dir, delete_tmp_dir + from .git_repo_api import GitRepoApi @@ -20,7 +23,7 @@ def __enter__(self) -> "GitRepo": def __exit__( self, - exc_type: Optional[Type[BaseException]], + exc_type: Optional[type[BaseException]], exc_value: Optional[BaseException], traceback: Optional[TracebackType], ) -> Literal[False]: @@ -55,7 +58,10 @@ def clone(self, branch: Optional[str] = None) -> None: if branch: git_options.append(f"--branch {branch}") self.__repo = Repo.clone_from( - url=url, to_path=f"{self.__tmp_dir}/repo", multi_options=git_options, allow_unsafe_options=True + url=url, + to_path=f"{self.__tmp_dir}/repo", + multi_options=git_options, + allow_unsafe_options=True, ) except GitError as ex: if branch: diff --git a/gitopscli/git_api/git_repo_api.py b/gitopscli/git_api/git_repo_api.py index e9534e91..1cb0f97a 100644 --- a/gitopscli/git_api/git_repo_api.py +++ b/gitopscli/git_api/git_repo_api.py @@ -1,5 +1,5 @@ from abc import ABCMeta, abstractmethod -from typing import Any, List, Dict, NamedTuple, Optional, Literal +from typing import Any, Literal, NamedTuple, Optional class GitRepoApi(metaclass=ABCMeta): @@ -21,13 +21,20 @@ def get_clone_url(self) -> str: @abstractmethod def create_pull_request_to_default_branch( - self, from_branch: str, title: str, description: str + self, + from_branch: str, + title: str, + description: str, ) -> "PullRequestIdAndUrl": ... @abstractmethod def create_pull_request( - self, from_branch: str, to_branch: str, title: str, description: str + self, + from_branch: str, + to_branch: str, + title: str, + description: str, ) -> "PullRequestIdAndUrl": ... @@ -36,7 +43,7 @@ def merge_pull_request( self, pr_id: int, merge_method: Literal["squash", "rebase", "merge"] = "merge", - merge_parameters: Optional[Dict[str, Any]] = None, + merge_parameters: Optional[dict[str, Any]] = None, ) -> None: ... @@ -57,5 +64,5 @@ def get_pull_request_branch(self, pr_id: int) -> str: ... @abstractmethod - def add_pull_request_label(self, pr_id: int, pr_labels: List[str]) -> None: + def add_pull_request_label(self, pr_id: int, pr_labels: list[str]) -> None: ... diff --git a/gitopscli/git_api/git_repo_api_factory.py b/gitopscli/git_api/git_repo_api_factory.py index af6c3ddd..fdc1e14a 100644 --- a/gitopscli/git_api/git_repo_api_factory.py +++ b/gitopscli/git_api/git_repo_api_factory.py @@ -1,12 +1,14 @@ from typing import Optional + from gitopscli.gitops_exception import GitOpsException -from .git_repo_api import GitRepoApi -from .github_git_repo_api_adapter import GithubGitRepoApiAdapter + from .bitbucket_git_repo_api_adapter import BitbucketGitRepoApiAdapter -from .gitlab_git_repo_api_adapter import GitlabGitRepoApiAdapter -from .git_repo_api_logging_proxy import GitRepoApiLoggingProxy from .git_api_config import GitApiConfig from .git_provider import GitProvider +from .git_repo_api import GitRepoApi +from .git_repo_api_logging_proxy import GitRepoApiLoggingProxy +from .github_git_repo_api_adapter import GithubGitRepoApiAdapter +from .gitlab_git_repo_api_adapter import GitlabGitRepoApiAdapter class GitRepoApiFactory: diff --git a/gitopscli/git_api/git_repo_api_logging_proxy.py b/gitopscli/git_api/git_repo_api_logging_proxy.py index 47ed7e81..1985aa92 100644 --- a/gitopscli/git_api/git_repo_api_logging_proxy.py +++ b/gitopscli/git_api/git_repo_api_logging_proxy.py @@ -1,5 +1,6 @@ import logging -from typing import Any, List, Dict, Optional, Literal +from typing import Any, Literal, Optional + from .git_repo_api import GitRepoApi @@ -17,13 +18,20 @@ def get_clone_url(self) -> str: return self.__api.get_clone_url() def create_pull_request_to_default_branch( - self, from_branch: str, title: str, description: str + self, + from_branch: str, + title: str, + description: str, ) -> GitRepoApi.PullRequestIdAndUrl: logging.info("Creating pull request from '%s' to default branch with title: %s", from_branch, title) return self.__api.create_pull_request_to_default_branch(from_branch, title, description) def create_pull_request( - self, from_branch: str, to_branch: str, title: str, description: str + self, + from_branch: str, + to_branch: str, + title: str, + description: str, ) -> GitRepoApi.PullRequestIdAndUrl: logging.info("Creating pull request from '%s' to '%s' with title: %s", from_branch, to_branch, title) return self.__api.create_pull_request(from_branch, to_branch, title, description) @@ -32,7 +40,7 @@ def merge_pull_request( self, pr_id: int, merge_method: Literal["squash", "rebase", "merge"] = "merge", - merge_parameters: Optional[Dict[str, Any]] = None, + merge_parameters: Optional[dict[str, Any]] = None, ) -> None: logging.info("Merging pull request %s", pr_id) self.__api.merge_pull_request(pr_id, merge_method=merge_method) @@ -40,7 +48,10 @@ def merge_pull_request( def add_pull_request_comment(self, pr_id: int, text: str, parent_id: Optional[int] = None) -> None: if parent_id: logging.info( - "Creating comment for pull request %s as reply to comment %s with content: %s", pr_id, parent_id, text + "Creating comment for pull request %s as reply to comment %s with content: %s", + pr_id, + parent_id, + text, ) else: logging.info("Creating comment for pull request %s with content: %s", pr_id, text) @@ -56,6 +67,6 @@ def get_branch_head_hash(self, branch: str) -> str: def get_pull_request_branch(self, pr_id: int) -> str: return self.__api.get_pull_request_branch(pr_id) - def add_pull_request_label(self, pr_id: int, pr_labels: List[str]) -> None: + def add_pull_request_label(self, pr_id: int, pr_labels: list[str]) -> None: logging.info("Adding labels for pull request %s with content: %s", pr_id, pr_labels) self.__api.add_pull_request_label(pr_id, pr_labels) diff --git a/gitopscli/git_api/github_git_repo_api_adapter.py b/gitopscli/git_api/github_git_repo_api_adapter.py index af87abed..dfd4aff5 100644 --- a/gitopscli/git_api/github_git_repo_api_adapter.py +++ b/gitopscli/git_api/github_git_repo_api_adapter.py @@ -1,21 +1,26 @@ -from typing import Any, Dict, Union, Optional, Literal +from typing import Any, Literal, Optional, Union from github import ( - Github, - UnknownObjectException, BadCredentialsException, + Github, GitRef, PullRequest, Repository, + UnknownObjectException, ) from gitopscli.gitops_exception import GitOpsException + from .git_repo_api import GitRepoApi class GithubGitRepoApiAdapter(GitRepoApi): def __init__( - self, username: Optional[str], password: Optional[str], organisation: str, repository_name: str + self, + username: Optional[str], + password: Optional[str], + organisation: str, + repository_name: str, ) -> None: self.__github = Github(username, password) self.__username = username @@ -33,13 +38,20 @@ def get_clone_url(self) -> str: return self.__get_repo().clone_url def create_pull_request_to_default_branch( - self, from_branch: str, title: str, description: str + self, + from_branch: str, + title: str, + description: str, ) -> GitRepoApi.PullRequestIdAndUrl: to_branch = self.__get_repo().default_branch return self.create_pull_request(from_branch, to_branch, title, description) def create_pull_request( - self, from_branch: str, to_branch: str, title: str, description: str + self, + from_branch: str, + to_branch: str, + title: str, + description: str, ) -> GitRepoApi.PullRequestIdAndUrl: repo = self.__get_repo() pull_request = repo.create_pull(title=title, body=description, head=from_branch, base=to_branch) @@ -49,7 +61,7 @@ def merge_pull_request( self, pr_id: int, merge_method: Literal["squash", "rebase", "merge"] = "merge", - merge_parameters: Optional[Dict[str, Any]] = None, + merge_parameters: Optional[dict[str, Any]] = None, ) -> None: pull_request = self.__get_pull_request(pr_id) pull_request.merge(merge_method=merge_method) @@ -91,7 +103,7 @@ def __get_repo(self) -> Repository.Repository: raise GitOpsException("Bad credentials") from ex except UnknownObjectException as ex: raise GitOpsException( - f"Repository '{self.__organisation}/{self.__repository_name}' does not exist." + f"Repository '{self.__organisation}/{self.__repository_name}' does not exist.", ) from ex def add_pull_request_label(self, pr_id: int, pr_labels: Union[str, Any]) -> None: diff --git a/gitopscli/git_api/gitlab_git_repo_api_adapter.py b/gitopscli/git_api/gitlab_git_repo_api_adapter.py index 3ba686c8..1d4275b2 100644 --- a/gitopscli/git_api/gitlab_git_repo_api_adapter.py +++ b/gitopscli/git_api/gitlab_git_repo_api_adapter.py @@ -1,9 +1,10 @@ -from typing import Any, List, Dict, Optional, Literal import logging import time -import requests +from typing import Any, Literal, Optional import gitlab +import requests + from gitopscli.gitops_exception import GitOpsException from .git_repo_api import GitRepoApi @@ -46,16 +47,23 @@ def get_clone_url(self) -> str: return str(self.__project.http_url_to_repo) def create_pull_request_to_default_branch( - self, from_branch: str, title: str, description: str + self, + from_branch: str, + title: str, + description: str, ) -> GitRepoApi.PullRequestIdAndUrl: to_branch = self.__get_default_branch() return self.create_pull_request(from_branch, to_branch, title, description) def create_pull_request( - self, from_branch: str, to_branch: str, title: str, description: str + self, + from_branch: str, + to_branch: str, + title: str, + description: str, ) -> GitRepoApi.PullRequestIdAndUrl: merge_request = self.__project.mergerequests.create( - {"source_branch": from_branch, "target_branch": to_branch, "title": title, "description": description} + {"source_branch": from_branch, "target_branch": to_branch, "title": title, "description": description}, ) return GitRepoApi.PullRequestIdAndUrl(pr_id=merge_request.iid, url=merge_request.web_url) @@ -63,7 +71,7 @@ def merge_pull_request( self, pr_id: int, merge_method: Literal["squash", "rebase", "merge"] = "merge", - merge_parameters: Optional[Dict[str, Any]] = None, + merge_parameters: Optional[dict[str, Any]] = None, ) -> None: merge_request = self.__project.mergerequests.get(pr_id) @@ -80,7 +88,9 @@ def merge_pull_request( # is still processing the merge request internally max_retries -= 1 logging.warning( - "Retry merging pull request. Attempts: (%s/%s)", MAX_MERGE_RETRIES - max_retries, MAX_MERGE_RETRIES + "Retry merging pull request. Attempts: (%s/%s)", + MAX_MERGE_RETRIES - max_retries, + MAX_MERGE_RETRIES, ) if max_retries == 0: raise GitOpsException("Error merging pull request: 'Branch cannot be merged'") from ex @@ -108,7 +118,7 @@ def __get_default_branch(self) -> str: raise GitOpsException("Default branch does not exist") return str(default_branch.name) - def add_pull_request_label(self, pr_id: int, pr_labels: List[str]) -> None: + def add_pull_request_label(self, pr_id: int, pr_labels: list[str]) -> None: merge_request = self.__project.mergerequests.get(pr_id) merge_request.labels = pr_labels merge_request.save() diff --git a/gitopscli/gitops_config.py b/gitopscli/gitops_config.py index c7427ce0..a22f270e 100644 --- a/gitopscli/gitops_config.py +++ b/gitopscli/gitops_config.py @@ -1,8 +1,9 @@ -import re import hashlib +import re +from collections.abc import Callable from dataclasses import dataclass -from typing import List, Any, Optional, Dict, Callable, Set from string import Template +from typing import Any, Optional from gitopscli.gitops_exception import GitOpsException @@ -10,7 +11,7 @@ @dataclass(frozen=True) -class GitOpsConfig: # pylint: disable=too-many-instance-attributes +class GitOpsConfig: class Replacement: @dataclass(frozen=True) class PreviewContext: @@ -18,7 +19,7 @@ class PreviewContext: preview_id: str git_hash: str - __VARIABLE_MAPPERS: Dict[str, Callable[["GitOpsConfig.Replacement.PreviewContext"], str]] = { + __VARIABLE_MAPPERS: dict[str, Callable[["GitOpsConfig.Replacement.PreviewContext"], str]] = { "GIT_HASH": lambda context: context.git_hash, "PREVIEW_HOST": lambda context: context.gitops_config.get_preview_host(context.preview_id), "PREVIEW_NAMESPACE": lambda context: context.gitops_config.get_preview_namespace(context.preview_id), @@ -40,7 +41,7 @@ def __init__(self, path: str, value_template: str): if var not in variables: raise GitOpsException( f"Replacement value '{self.value_template}' for path '{self.path}' " - f"contains invalid variable: {var}" + f"contains invalid variable: {var}", ) def get_value(self, context: PreviewContext) -> str: @@ -69,7 +70,7 @@ def get_value(self, context: PreviewContext) -> str: preview_target_namespace_template: str preview_target_max_namespace_length: int - replacements: Dict[str, List[Replacement]] + replacements: dict[str, list[Replacement]] @property def preview_template_path(self) -> str: @@ -93,14 +94,16 @@ def __post_init__(self) -> None: if self.preview_target_branch is not None: assert isinstance(self.preview_target_branch, str), "preview_target_branch of wrong type!" assert isinstance( - self.preview_target_namespace_template, str + self.preview_target_namespace_template, + str, ), "preview_target_namespace_template of wrong type!" self.__assert_variables( self.preview_target_namespace_template, {"APPLICATION_NAME", "PREVIEW_ID_HASH", "PREVIEW_ID_HASH_SHORT", "PREVIEW_ID"}, ) assert isinstance( - self.preview_target_max_namespace_length, int + self.preview_target_max_namespace_length, + int, ), "preview_target_max_namespace_length of wrong type!" assert self.preview_target_max_namespace_length >= 1, "preview_target_max_namespace_length is < 1!" assert isinstance(self.replacements, dict), "replacements of wrong type!" @@ -123,7 +126,8 @@ def get_preview_namespace(self, preview_id: str) -> str: preview_namespace = preview_namespace.replace("${APPLICATION_NAME}", self.application_name) preview_namespace = preview_namespace.replace("${PREVIEW_ID_HASH}", self.create_preview_id_hash(preview_id)) preview_namespace = preview_namespace.replace( - "${PREVIEW_ID_HASH_SHORT}", self.create_preview_id_hash_short(preview_id) + "${PREVIEW_ID_HASH_SHORT}", + self.create_preview_id_hash_short(preview_id), ) current_length = len(preview_namespace) - len("${PREVIEW_ID}") @@ -133,7 +137,7 @@ def get_preview_namespace(self, preview_id: str) -> str: preview_namespace = preview_namespace.replace("${PREVIEW_ID}", "") raise GitOpsException( f"Preview namespace is too long (max {self.preview_target_max_namespace_length} chars): " - f"{preview_namespace} ({len(preview_namespace)} chars)" + f"{preview_namespace} ({len(preview_namespace)} chars)", ) sanitized_preview_id = self.__sanitize(preview_id, remaining_length) @@ -167,7 +171,7 @@ def fill_template(self, template: str, context: Replacement.PreviewContext) -> s ) @staticmethod - def __assert_variables(template: str, variables: Set[str]) -> None: + def __assert_variables(template: str, variables: set[str]) -> None: for var in _VARIABLE_REGEX.findall(template): if var not in variables: raise GitOpsException(f"GitOps config template '{template}' contains invalid variable: {var}") @@ -245,13 +249,13 @@ def __get_int_value_or_default(self, key: str, default: int) -> int: raise GitOpsException(f"Item '{key}' should be an integer in GitOps config!") return value - def __get_list_value(self, key: str) -> List[Any]: + def __get_list_value(self, key: str) -> list[Any]: value = self.__get_value(key) if not isinstance(value, list): raise GitOpsException(f"Item '{key}' should be a list in GitOps config!") return value - def __get_dict_value(self, key: str) -> Dict[str, Any]: + def __get_dict_value(self, key: str) -> dict[str, Any]: value = self.__get_value(key) if not isinstance(value, dict): raise GitOpsException(f"Item '{key}' should be an object in GitOps config!") @@ -268,7 +272,7 @@ def parse(self) -> GitOpsConfig: raise GitOpsException(f"GitOps config apiVersion '{api_version}' is not supported!") def __parse_v0(self) -> GitOpsConfig: - replacements: Dict[str, List[GitOpsConfig.Replacement]] = { + replacements: dict[str, list[GitOpsConfig.Replacement]] = { "Chart.yaml": [GitOpsConfig.Replacement("name", "${PREVIEW_NAMESPACE}")], "values.yaml": [], } @@ -284,11 +288,11 @@ def __parse_v0(self) -> GitOpsConfig: variable = replacement_dict["variable"] if not isinstance(path, str): raise GitOpsException( - f"Item 'previewConfig.replace.[{index}].path' should be a string in GitOps config!" + f"Item 'previewConfig.replace.[{index}].path' should be a string in GitOps config!", ) if not isinstance(variable, str): raise GitOpsException( - f"Item 'previewConfig.replace.[{index}].variable' should be a string in GitOps config!" + f"Item 'previewConfig.replace.[{index}].variable' should be a string in GitOps config!", ) if "{" in variable or "}" in variable: raise GitOpsException(f"Item 'previewConfig.replace.[{index}].variable' must not contain '{{' or '}}'!") @@ -305,13 +309,14 @@ def __parse_v0(self) -> GitOpsConfig: api_version=0, application_name=self.__get_string_value("deploymentConfig.applicationName"), messages_created_template="New preview environment created for version `${GIT_HASH}`. " - + "Access it here: https://${PREVIEW_HOST}", + "Access it here: https://${PREVIEW_HOST}", messages_updated_template="Preview environment updated to version `${GIT_HASH}`. " - + "Access it here: https://${PREVIEW_HOST}", + "Access it here: https://${PREVIEW_HOST}", messages_uptodate_template="The version `${GIT_HASH}` has already been deployed. " - + "Access it here: https://${PREVIEW_HOST}", + "Access it here: https://${PREVIEW_HOST}", preview_host_template=self.__get_string_value("previewConfig.route.host.template").replace( - "{SHA256_8CHAR_BRANCH_HASH}", "${PREVIEW_ID_HASH}" # backwards compatibility + "{SHA256_8CHAR_BRANCH_HASH}", + "${PREVIEW_ID_HASH}", # backwards compatibility ), preview_template_organisation=preview_target_organisation, preview_template_repository=preview_target_repository, @@ -332,7 +337,7 @@ def __parse_v1(self) -> GitOpsConfig: def add_var_dollar(template: str) -> str: return re.sub("(^|[^\\$])({(\\w+)})", "\\1$\\2", template) - replacements: Dict[str, List[GitOpsConfig.Replacement]] = {} + replacements: dict[str, list[GitOpsConfig.Replacement]] = {} for filename, file_replacements in config.replacements.items(): replacements[filename] = [ GitOpsConfig.Replacement(r.path, add_var_dollar(r.value_template)) for r in file_replacements @@ -341,11 +346,11 @@ def add_var_dollar(template: str) -> str: api_version=1, application_name=config.application_name, messages_created_template="New preview environment created for version `${GIT_HASH}`. " - + "Access it here: https://${PREVIEW_HOST}", + "Access it here: https://${PREVIEW_HOST}", messages_updated_template="Preview environment updated to version `${GIT_HASH}`. " - + "Access it here: https://${PREVIEW_HOST}", + "Access it here: https://${PREVIEW_HOST}", messages_uptodate_template="The version `${GIT_HASH}` has already been deployed. " - + "Access it here: https://${PREVIEW_HOST}", + "Access it here: https://${PREVIEW_HOST}", preview_host_template=add_var_dollar(config.preview_host_template), preview_template_organisation=config.preview_template_organisation, preview_template_repository=config.preview_template_repository, @@ -356,8 +361,9 @@ def add_var_dollar(template: str) -> str: preview_target_branch=config.preview_target_branch, preview_target_namespace_template=add_var_dollar( self.__get_string_value_or_default( - "previewConfig.target.namespace", "{APPLICATION_NAME}-{PREVIEW_ID}-{PREVIEW_ID_HASH}-preview" - ) + "previewConfig.target.namespace", + "{APPLICATION_NAME}-{PREVIEW_ID}-{PREVIEW_ID_HASH}-preview", + ), ), preview_target_max_namespace_length=63, replacements=replacements, @@ -368,12 +374,13 @@ def __parse_v2(self) -> GitOpsConfig: preview_target_repository = self.__get_string_value("previewConfig.target.repository") preview_target_branch = self.__get_string_value_or_none("previewConfig.target.branch") preview_target_max_namespace_length = self.__get_int_value_or_default( - "previewConfig.target.maxNamespaceLength", 53 + "previewConfig.target.maxNamespaceLength", + 53, ) if preview_target_max_namespace_length < 1: raise GitOpsException("Value 'maxNamespaceLength' should be at least 1 in GitOps config!") - replacements: Dict[str, List[GitOpsConfig.Replacement]] = {} + replacements: dict[str, list[GitOpsConfig.Replacement]] = {} for filename, file_replacements in self.__get_dict_value("previewConfig.replace").items(): replacements[filename] = [] escaped_filename = filename.replace(".", "\\.") @@ -413,13 +420,16 @@ def __parse_v2(self) -> GitOpsConfig: ), preview_host_template=self.__get_string_value("previewConfig.host"), preview_template_organisation=self.__get_string_value_or_default( - "previewConfig.template.organisation", preview_target_organisation + "previewConfig.template.organisation", + preview_target_organisation, ), preview_template_repository=self.__get_string_value_or_default( - "previewConfig.template.repository", preview_target_repository + "previewConfig.template.repository", + preview_target_repository, ), preview_template_path_template=self.__get_string_value_or_default( - "previewConfig.template.path", ".preview-templates/${APPLICATION_NAME}" + "previewConfig.template.path", + ".preview-templates/${APPLICATION_NAME}", ), preview_template_branch=self.__get_string_value_or_none("previewConfig.template.branch") or preview_target_branch, @@ -427,7 +437,8 @@ def __parse_v2(self) -> GitOpsConfig: preview_target_repository=preview_target_repository, preview_target_branch=preview_target_branch, preview_target_namespace_template=self.__get_string_value_or_default( - "previewConfig.target.namespace", "${APPLICATION_NAME}-${PREVIEW_ID}-${PREVIEW_ID_HASH_SHORT}-preview" + "previewConfig.target.namespace", + "${APPLICATION_NAME}-${PREVIEW_ID}-${PREVIEW_ID_HASH_SHORT}-preview", ), preview_target_max_namespace_length=preview_target_max_namespace_length, replacements=replacements, diff --git a/gitopscli/io_api/tmp_dir.py b/gitopscli/io_api/tmp_dir.py index d6ce8b67..4c9421f4 100644 --- a/gitopscli/io_api/tmp_dir.py +++ b/gitopscli/io_api/tmp_dir.py @@ -1,6 +1,6 @@ -import uuid import os import shutil +import uuid def create_tmp_dir() -> str: diff --git a/gitopscli/io_api/yaml_util.py b/gitopscli/io_api/yaml_util.py index d35776ca..167cd26e 100644 --- a/gitopscli/io_api/yaml_util.py +++ b/gitopscli/io_api/yaml_util.py @@ -1,9 +1,10 @@ import locale from io import StringIO from typing import Any -from ruamel.yaml import YAML, YAMLError + from jsonpath_ng.exceptions import JSONPathError from jsonpath_ng.ext import parse +from ruamel.yaml import YAML, YAMLError YAML_INSTANCE = YAML() YAML_INSTANCE.preserve_quotes = True diff --git a/poetry.lock b/poetry.lock index 617b5acc..6e9d5300 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,19 +1,5 @@ # This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. -[[package]] -name = "astroid" -version = "3.0.1" -description = "An abstract syntax tree for Python with inference support." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "astroid-3.0.1-py3-none-any.whl", hash = "sha256:7d5895c9825e18079c5aeac0572bc2e4c83205c95d416e0b4fee8bc361d2d9ca"}, - {file = "astroid-3.0.1.tar.gz", hash = "sha256:86b0bb7d7da0be1a7c4aedb7974e391b32d4ed89e33de6ed6902b4b15c97577e"}, -] - -[package.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} - [[package]] name = "atlassian-python-api" version = "3.41.3" @@ -37,59 +23,20 @@ kerberos = ["requests-kerberos"] [[package]] name = "babel" -version = "2.13.0" +version = "2.13.1" description = "Internationalization utilities" optional = false python-versions = ">=3.7" files = [ - {file = "Babel-2.13.0-py3-none-any.whl", hash = "sha256:fbfcae1575ff78e26c7449136f1abbefc3c13ce542eeb13d43d50d8b047216ec"}, - {file = "Babel-2.13.0.tar.gz", hash = "sha256:04c3e2d28d2b7681644508f836be388ae49e0cfe91465095340395b60d00f210"}, -] - -[package.extras] -dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] - -[[package]] -name = "black" -version = "23.10.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-23.10.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:f8dc7d50d94063cdfd13c82368afd8588bac4ce360e4224ac399e769d6704e98"}, - {file = "black-23.10.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:f20ff03f3fdd2fd4460b4f631663813e57dc277e37fb216463f3b907aa5a9bdd"}, - {file = "black-23.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3d9129ce05b0829730323bdcb00f928a448a124af5acf90aa94d9aba6969604"}, - {file = "black-23.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:960c21555be135c4b37b7018d63d6248bdae8514e5c55b71e994ad37407f45b8"}, - {file = "black-23.10.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:30b78ac9b54cf87bcb9910ee3d499d2bc893afd52495066c49d9ee6b21eee06e"}, - {file = "black-23.10.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:0e232f24a337fed7a82c1185ae46c56c4a6167fb0fe37411b43e876892c76699"}, - {file = "black-23.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31946ec6f9c54ed7ba431c38bc81d758970dd734b96b8e8c2b17a367d7908171"}, - {file = "black-23.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:c870bee76ad5f7a5ea7bd01dc646028d05568d33b0b09b7ecfc8ec0da3f3f39c"}, - {file = "black-23.10.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:6901631b937acbee93c75537e74f69463adaf34379a04eef32425b88aca88a23"}, - {file = "black-23.10.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:481167c60cd3e6b1cb8ef2aac0f76165843a374346aeeaa9d86765fe0dd0318b"}, - {file = "black-23.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74892b4b836e5162aa0452393112a574dac85e13902c57dfbaaf388e4eda37c"}, - {file = "black-23.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:47c4510f70ec2e8f9135ba490811c071419c115e46f143e4dce2ac45afdcf4c9"}, - {file = "black-23.10.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:76baba9281e5e5b230c9b7f83a96daf67a95e919c2dfc240d9e6295eab7b9204"}, - {file = "black-23.10.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:a3c2ddb35f71976a4cfeca558848c2f2f89abc86b06e8dd89b5a65c1e6c0f22a"}, - {file = "black-23.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db451a3363b1e765c172c3fd86213a4ce63fb8524c938ebd82919bf2a6e28c6a"}, - {file = "black-23.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:7fb5fc36bb65160df21498d5a3dd330af8b6401be3f25af60c6ebfe23753f747"}, - {file = "black-23.10.0-py3-none-any.whl", hash = "sha256:e223b731a0e025f8ef427dd79d8cd69c167da807f5710add30cdf131f13dd62e"}, - {file = "black-23.10.0.tar.gz", hash = "sha256:31b9f87b277a68d0e99d2905edae08807c007973eaa609da5f0c62def6b7c0bd"}, + {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"}, + {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"}, ] [package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} +setuptools = {version = "*", markers = "python_version >= \"3.12\""} [package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "certifi" @@ -179,101 +126,101 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.3.0" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.3.0.tar.gz", hash = "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-win32.whl", hash = "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-win32.whl", hash = "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-win32.whl", hash = "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dc45229747b67ffc441b3de2f3ae5e62877a282ea828a5bdb67883c4ee4a8810"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f4a0033ce9a76e391542c182f0d48d084855b5fcba5010f707c8e8c34663d77"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ada214c6fa40f8d800e575de6b91a40d0548139e5dc457d2ebb61470abf50186"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1121de0e9d6e6ca08289583d7491e7fcb18a439305b34a30b20d8215922d43c"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1063da2c85b95f2d1a430f1c33b55c9c17ffaf5e612e10aeaad641c55a9e2b9d"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70f1d09c0d7748b73290b29219e854b3207aea922f839437870d8cc2168e31cc"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:250c9eb0f4600361dd80d46112213dff2286231d92d3e52af1e5a6083d10cad9"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:750b446b2ffce1739e8578576092179160f6d26bd5e23eb1789c4d64d5af7dc7"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:588245972aca710b5b68802c8cad9edaa98589b1b42ad2b53accd6910dad3545"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e39c7eb31e3f5b1f88caff88bcff1b7f8334975b46f6ac6e9fc725d829bc35d4"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-win32.whl", hash = "sha256:abecce40dfebbfa6abf8e324e1860092eeca6f7375c8c4e655a8afb61af58f2c"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:24a91a981f185721542a0b7c92e9054b7ab4fea0508a795846bc5b0abf8118d4"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-win32.whl", hash = "sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-win32.whl", hash = "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884"}, - {file = "charset_normalizer-3.3.0-py3-none-any.whl", hash = "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2"}, + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] [[package]] @@ -367,34 +314,34 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "41.0.4" +version = "41.0.5" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:80907d3faa55dc5434a16579952ac6da800935cd98d14dbd62f6f042c7f5e839"}, - {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:35c00f637cd0b9d5b6c6bd11b6c3359194a8eba9c46d4e875a3660e3b400005f"}, - {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cecfefa17042941f94ab54f769c8ce0fe14beff2694e9ac684176a2535bf9714"}, - {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb"}, - {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:23a25c09dfd0d9f28da2352503b23e086f8e78096b9fd585d1d14eca01613e13"}, - {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2ed09183922d66c4ec5fdaa59b4d14e105c084dd0febd27452de8f6f74704143"}, - {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5a0f09cefded00e648a127048119f77bc2b2ec61e736660b5789e638f43cc397"}, - {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9eeb77214afae972a00dee47382d2591abe77bdae166bda672fb1e24702a3860"}, - {file = "cryptography-41.0.4-cp37-abi3-win32.whl", hash = "sha256:3b224890962a2d7b57cf5eeb16ccaafba6083f7b811829f00476309bce2fe0fd"}, - {file = "cryptography-41.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c880eba5175f4307129784eca96f4e70b88e57aa3f680aeba3bab0e980b0f37d"}, - {file = "cryptography-41.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:004b6ccc95943f6a9ad3142cfabcc769d7ee38a3f60fb0dddbfb431f818c3a67"}, - {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:86defa8d248c3fa029da68ce61fe735432b047e32179883bdb1e79ed9bb8195e"}, - {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:37480760ae08065437e6573d14be973112c9e6dcaf5f11d00147ee74f37a3829"}, - {file = "cryptography-41.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b5f4dfe950ff0479f1f00eda09c18798d4f49b98f4e2006d644b3301682ebdca"}, - {file = "cryptography-41.0.4-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7e53db173370dea832190870e975a1e09c86a879b613948f09eb49324218c14d"}, - {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5b72205a360f3b6176485a333256b9bcd48700fc755fef51c8e7e67c4b63e3ac"}, - {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:93530900d14c37a46ce3d6c9e6fd35dbe5f5601bf6b3a5c325c7bffc030344d9"}, - {file = "cryptography-41.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f"}, - {file = "cryptography-41.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c3391bd8e6de35f6f1140e50aaeb3e2b3d6a9012536ca23ab0d9c35ec18c8a91"}, - {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0d9409894f495d465fe6fda92cb70e8323e9648af912d5b9141d616df40a87b8"}, - {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ac4f9ead4bbd0bc8ab2d318f97d85147167a488be0e08814a37eb2f439d5cf6"}, - {file = "cryptography-41.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:047c4603aeb4bbd8db2756e38f5b8bd7e94318c047cfe4efeb5d715e08b49311"}, - {file = "cryptography-41.0.4.tar.gz", hash = "sha256:7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a"}, + {file = "cryptography-41.0.5-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:da6a0ff8f1016ccc7477e6339e1d50ce5f59b88905585f77193ebd5068f1e797"}, + {file = "cryptography-41.0.5-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:b948e09fe5fb18517d99994184854ebd50b57248736fd4c720ad540560174ec5"}, + {file = "cryptography-41.0.5-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d38e6031e113b7421db1de0c1b1f7739564a88f1684c6b89234fbf6c11b75147"}, + {file = "cryptography-41.0.5-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e270c04f4d9b5671ebcc792b3ba5d4488bf7c42c3c241a3748e2599776f29696"}, + {file = "cryptography-41.0.5-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ec3b055ff8f1dce8e6ef28f626e0972981475173d7973d63f271b29c8a2897da"}, + {file = "cryptography-41.0.5-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:7d208c21e47940369accfc9e85f0de7693d9a5d843c2509b3846b2db170dfd20"}, + {file = "cryptography-41.0.5-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:8254962e6ba1f4d2090c44daf50a547cd5f0bf446dc658a8e5f8156cae0d8548"}, + {file = "cryptography-41.0.5-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a48e74dad1fb349f3dc1d449ed88e0017d792997a7ad2ec9587ed17405667e6d"}, + {file = "cryptography-41.0.5-cp37-abi3-win32.whl", hash = "sha256:d3977f0e276f6f5bf245c403156673db103283266601405376f075c849a0b936"}, + {file = "cryptography-41.0.5-cp37-abi3-win_amd64.whl", hash = "sha256:73801ac9736741f220e20435f84ecec75ed70eda90f781a148f1bad546963d81"}, + {file = "cryptography-41.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3be3ca726e1572517d2bef99a818378bbcf7d7799d5372a46c79c29eb8d166c1"}, + {file = "cryptography-41.0.5-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e886098619d3815e0ad5790c973afeee2c0e6e04b4da90b88e6bd06e2a0b1b72"}, + {file = "cryptography-41.0.5-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:573eb7128cbca75f9157dcde974781209463ce56b5804983e11a1c462f0f4e88"}, + {file = "cryptography-41.0.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0c327cac00f082013c7c9fb6c46b7cc9fa3c288ca702c74773968173bda421bf"}, + {file = "cryptography-41.0.5-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:227ec057cd32a41c6651701abc0328135e472ed450f47c2766f23267b792a88e"}, + {file = "cryptography-41.0.5-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:22892cc830d8b2c89ea60148227631bb96a7da0c1b722f2aac8824b1b7c0b6b8"}, + {file = "cryptography-41.0.5-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:5a70187954ba7292c7876734183e810b728b4f3965fbe571421cb2434d279179"}, + {file = "cryptography-41.0.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:88417bff20162f635f24f849ab182b092697922088b477a7abd6664ddd82291d"}, + {file = "cryptography-41.0.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c707f7afd813478e2019ae32a7c49cd932dd60ab2d2a93e796f68236b7e1fbf1"}, + {file = "cryptography-41.0.5-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:580afc7b7216deeb87a098ef0674d6ee34ab55993140838b14c9b83312b37b86"}, + {file = "cryptography-41.0.5-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1e91467c65fe64a82c689dc6cf58151158993b13eb7a7f3f4b7f395636723"}, + {file = "cryptography-41.0.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0d2a6a598847c46e3e321a7aef8af1436f11c27f1254933746304ff014664d84"}, + {file = "cryptography-41.0.5.tar.gz", hash = "sha256:392cb88b597247177172e02da6b7a63deeff1937fa6fec3bbf902ebd75d97ec7"}, ] [package.dependencies] @@ -427,20 +374,6 @@ wrapt = ">=1.10,<2" [package.extras] dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] -[[package]] -name = "dill" -version = "0.3.7" -description = "serialize all of Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dill-0.3.7-py3-none-any.whl", hash = "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e"}, - {file = "dill-0.3.7.tar.gz", hash = "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03"}, -] - -[package.extras] -graph = ["objgraph (>=1.7.2)"] - [[package]] name = "distlib" version = "0.3.7" @@ -468,19 +401,19 @@ test = ["pytest (>=6)"] [[package]] name = "filelock" -version = "3.12.4" +version = "3.13.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.12.4-py3-none-any.whl", hash = "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4"}, - {file = "filelock-3.12.4.tar.gz", hash = "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd"}, + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, ] [package.extras] -docs = ["furo (>=2023.7.26)", "sphinx (>=7.1.2)", "sphinx-autodoc-typehints (>=1.24)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3)", "diff-cover (>=7.7)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-timeout (>=2.1)"] -typing = ["typing-extensions (>=4.7.1)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] [[package]] name = "ghp-import" @@ -532,13 +465,13 @@ test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre [[package]] name = "identify" -version = "2.5.30" +version = "2.5.31" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.30-py2.py3-none-any.whl", hash = "sha256:afe67f26ae29bab007ec21b03d4114f41316ab9dd15aa8736a167481e108da54"}, - {file = "identify-2.5.30.tar.gz", hash = "sha256:f302a4256a15c849b91cfcdcec052a8ce914634b2f77ae87dad29cd749f2d88d"}, + {file = "identify-2.5.31-py2.py3-none-any.whl", hash = "sha256:90199cb9e7bd3c5407a9b7e81b4abec4bb9d249991c79439ec8af740afc6293d"}, + {file = "identify-2.5.31.tar.gz", hash = "sha256:7736b3c7a28233637e3c36550646fc6389bedd74ae84cb788200cc8e2dd60b75"}, ] [package.extras] @@ -566,23 +499,6 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] -[[package]] -name = "isort" -version = "5.12.0" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, -] - -[package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] - [[package]] name = "jinja2" version = "3.1.2" @@ -616,13 +532,13 @@ ply = "*" [[package]] name = "markdown" -version = "3.5" +version = "3.5.1" description = "Python implementation of John Gruber's Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "Markdown-3.5-py3-none-any.whl", hash = "sha256:4afb124395ce5fc34e6d9886dab977fd9ae987fc6e85689f08278cf0c69d4bf3"}, - {file = "Markdown-3.5.tar.gz", hash = "sha256:a807eb2e4778d9156c8f07876c6e4d50b5494c5665c4834f67b06459dfd877b3"}, + {file = "Markdown-3.5.1-py3-none-any.whl", hash = "sha256:5874b47d4ee3f0b14d764324d2c94c03ea66bee56f2d929da9f2508d65e722dc"}, + {file = "Markdown-3.5.1.tar.gz", hash = "sha256:b65d7beb248dc22f2e8a31fb706d93798093c308dc1aba295aedeb9d41a813bd"}, ] [package.extras] @@ -715,17 +631,6 @@ files = [ {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, ] -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - [[package]] name = "mergedeep" version = "1.3.4" @@ -769,13 +674,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.4.6" +version = "9.4.7" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.4.6-py3-none-any.whl", hash = "sha256:78802035d5768a78139c84ad7dce0c6493e8f7dc4861727d36ed91d1520a54da"}, - {file = "mkdocs_material-9.4.6.tar.gz", hash = "sha256:09665e60df7ee9e5ff3a54af173f6d45be718b1ee7dd962bcff3102b81fb0c14"}, + {file = "mkdocs_material-9.4.7-py3-none-any.whl", hash = "sha256:4d698d52bb6a6a3c452ab854481c4cdb68453a0420956a6aee2de55fe15fe610"}, + {file = "mkdocs_material-9.4.7.tar.gz", hash = "sha256:e704e001c9ef17291e1d3462c202425217601653e18f68f85d28eff4690e662b"}, ] [package.dependencies] @@ -784,7 +689,7 @@ colorama = ">=0.4,<1.0" jinja2 = ">=3.0,<4.0" markdown = ">=3.2,<4.0" mkdocs = ">=1.5.3,<2.0" -mkdocs-material-extensions = ">=1.2,<2.0" +mkdocs-material-extensions = ">=1.3,<2.0" paginate = ">=0.5,<1.0" pygments = ">=2.16,<3.0" pymdown-extensions = ">=10.2,<11.0" @@ -1050,35 +955,6 @@ dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pyte docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] -[[package]] -name = "pylint" -version = "3.0.1" -description = "python code static checker" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "pylint-3.0.1-py3-none-any.whl", hash = "sha256:9c90b89e2af7809a1697f6f5f93f1d0e518ac566e2ac4d2af881a69c13ad01ea"}, - {file = "pylint-3.0.1.tar.gz", hash = "sha256:81c6125637be216b4652ae50cc42b9f8208dfb725cdc7e04c48f6902f4dbdf40"}, -] - -[package.dependencies] -astroid = ">=3.0.0,<=3.1.0-dev0" -colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -dill = [ - {version = ">=0.2", markers = "python_version < \"3.11\""}, - {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, - {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, -] -isort = ">=4.2.5,<6" -mccabe = ">=0.6,<0.8" -platformdirs = ">=2.2.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -tomlkit = ">=0.10.1" - -[package.extras] -spelling = ["pyenchant (>=3.2,<4.0)"] -testutils = ["gitpython (>3)"] - [[package]] name = "pymdown-extensions" version = "10.3.1" @@ -1125,13 +1001,13 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] [[package]] name = "pytest" -version = "7.4.2" +version = "7.4.3" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"}, - {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"}, + {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, + {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, ] [package.dependencies] @@ -1403,13 +1279,13 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "ruamel-yaml" -version = "0.17.40" +version = "0.18.5" description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" optional = false -python-versions = ">=3" +python-versions = ">=3.7" files = [ - {file = "ruamel.yaml-0.17.40-py3-none-any.whl", hash = "sha256:b16b6c3816dff0a93dca12acf5e70afd089fa5acb80604afd1ffa8b465b7722c"}, - {file = "ruamel.yaml-0.17.40.tar.gz", hash = "sha256:6024b986f06765d482b5b07e086cc4b4cd05dd22ddcbc758fa23d54873cf313d"}, + {file = "ruamel.yaml-0.18.5-py3-none-any.whl", hash = "sha256:a013ac02f99a69cdd6277d9664689eb1acba07069f912823177c5eced21a6ada"}, + {file = "ruamel.yaml-0.18.5.tar.gz", hash = "sha256:61917e3a35a569c1133a8f772e1226961bf5a1198bea7e23f06a0841dea1ab0e"}, ] [package.dependencies] @@ -1464,6 +1340,32 @@ files = [ {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"}, ] +[[package]] +name = "ruff" +version = "0.1.4" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.1.4-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:864958706b669cce31d629902175138ad8a069d99ca53514611521f532d91495"}, + {file = "ruff-0.1.4-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:9fdd61883bb34317c788af87f4cd75dfee3a73f5ded714b77ba928e418d6e39e"}, + {file = "ruff-0.1.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4eaca8c9cc39aa7f0f0d7b8fe24ecb51232d1bb620fc4441a61161be4a17539"}, + {file = "ruff-0.1.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a9a1301dc43cbf633fb603242bccd0aaa34834750a14a4c1817e2e5c8d60de17"}, + {file = "ruff-0.1.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e8db8ab6f100f02e28b3d713270c857d370b8d61871d5c7d1702ae411df683"}, + {file = "ruff-0.1.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:80fea754eaae06335784b8ea053d6eb8e9aac75359ebddd6fee0858e87c8d510"}, + {file = "ruff-0.1.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6bc02a480d4bfffd163a723698da15d1a9aec2fced4c06f2a753f87f4ce6969c"}, + {file = "ruff-0.1.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9862811b403063765b03e716dac0fda8fdbe78b675cd947ed5873506448acea4"}, + {file = "ruff-0.1.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58826efb8b3efbb59bb306f4b19640b7e366967a31c049d49311d9eb3a4c60cb"}, + {file = "ruff-0.1.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:fdfd453fc91d9d86d6aaa33b1bafa69d114cf7421057868f0b79104079d3e66e"}, + {file = "ruff-0.1.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e8791482d508bd0b36c76481ad3117987301b86072158bdb69d796503e1c84a8"}, + {file = "ruff-0.1.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:01206e361021426e3c1b7fba06ddcb20dbc5037d64f6841e5f2b21084dc51800"}, + {file = "ruff-0.1.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:645591a613a42cb7e5c2b667cbefd3877b21e0252b59272ba7212c3d35a5819f"}, + {file = "ruff-0.1.4-py3-none-win32.whl", hash = "sha256:99908ca2b3b85bffe7e1414275d004917d1e0dfc99d497ccd2ecd19ad115fd0d"}, + {file = "ruff-0.1.4-py3-none-win_amd64.whl", hash = "sha256:1dfd6bf8f6ad0a4ac99333f437e0ec168989adc5d837ecd38ddb2cc4a2e3db8a"}, + {file = "ruff-0.1.4-py3-none-win_arm64.whl", hash = "sha256:d98ae9ebf56444e18a3e3652b3383204748f73e247dea6caaf8b52d37e6b32da"}, + {file = "ruff-0.1.4.tar.gz", hash = "sha256:21520ecca4cc555162068d87c747b8f95e1e95f8ecfcbbe59e8dd00710586315"}, +] + [[package]] name = "setuptools" version = "68.2.2" @@ -1513,17 +1415,6 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -[[package]] -name = "tomlkit" -version = "0.12.1" -description = "Style preserving TOML library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"}, - {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"}, -] - [[package]] name = "typeguard" version = "2.13.3" @@ -1569,13 +1460,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.24.5" +version = "20.24.6" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.24.5-py3-none-any.whl", hash = "sha256:b80039f280f4919c77b30f1c23294ae357c4c8701042086e3fc005963e4e537b"}, - {file = "virtualenv-20.24.5.tar.gz", hash = "sha256:e8361967f6da6fbdf1426483bfe9fca8287c242ac0bc30429905721cefbff752"}, + {file = "virtualenv-20.24.6-py3-none-any.whl", hash = "sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381"}, + {file = "virtualenv-20.24.6.tar.gz", hash = "sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af"}, ] [package.dependencies] @@ -1713,4 +1604,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "84cf900519e76cbe193a586a54f626e7e78c9ed010a6c25d2a311dc8c414a07b" +content-hash = "2c921617c0e33c8061a14bae143877020bde00cefd268c0be4f0b53af530e968" diff --git a/pyproject.toml b/pyproject.toml index 9942d6c2..05997f36 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,9 +19,8 @@ pygithub = "*" python-gitlab = "^2.6.0" [tool.poetry.group.test.dependencies] -black = "*" +ruff = "*" coverage = "*" -pylint = "*" pytest = "*" mypy = "*" typeguard = "^2.13.3" @@ -40,3 +39,60 @@ build-backend = "poetry.core.masonry.api" [virtualenvs] in-project = true + +[tool.ruff] +line-length = 120 +target-version = "py311" + +[tool.ruff.lint] +select = ["ALL"] +ignore = ["ANN101", "ANN401", +"C901", "PLR0913", # ignore complexity +"D", +"COM812", "ISC001", +"EM101", "EM102", +"UP007", # Optional[T] is ok atm. later: move to T | None + "S101", "TD", "TRY003"] + +[tool.ruff.per-file-ignores] +"**/__init__.py" = ["F401"] +# the following exclusions have been introduced to prevent huge changes +# feel free to remove them and fix the code +"gitopscli/appconfig_api/app_tenant_config.py" = ["FIX002", "PLR5501", "PTH110", "PTH112", "PTH118", "RET504", "SIM118", "SIM401"] +"gitopscli/appconfig_api/root_repo.py" = ["SIM118"] +"gitopscli/commands/command_factory.py" = ["PYI016"] +"gitopscli/commands/create_preview.py" = ["PTH112", "S108"] +"gitopscli/commands/delete_preview.py" = ["PTH110"] +"gitopscli/commands/deploy.py" = ["PD011", "RUF015", "T201"] +"gitopscli/commands/sync_apps.py" = ["FIX002", "SIM117"] +"gitopscli/commands/version.py" = ["T201"] +"gitopscli/git_api/bitbucket_git_repo_api_adapter.py" = ["ARG002"] +"gitopscli/git_api/github_git_repo_api_adapter.py" = ["ARG002"] +"gitopscli/git_api/gitlab_git_repo_api_adapter.py" = ["ARG002", "PLR2004", "TRY300"] +"gitopscli/git_api/git_repo_api_logging_proxy.py" = ["ARG002"] +"gitopscli/git_api/git_repo.py" = ["FBT003", "PTH101", "PTH118", "PTH123"] +"gitopscli/gitops_config.py" = ["ANN204", "RET504", "RUF012"] +"gitopscli/gitops_exception.py" = ["N818"] +"gitopscli/io_api/tmp_dir.py" = ["PTH103", "S108"] +"gitopscli/io_api/yaml_util.py" = ["B007", "FBT003", "N818", "PLW2901", "PTH123", "SIM102", "UP015"] +"gitopscli/__main__.py" = ["TRY400", "TRY401"] +"tests/commands/common/test_gitops_config_loader.py" = ["ANN201", "I001", "INP001", "PT009", "S106"] +"tests/commands/mock_mixin.py" = ["B024", "I001"] +"tests/commands/test_add_pr_comment.py" = ["ANN201", "I001", "S106"] +"tests/commands/test_command_factory.py" = ["ANN201", "I001", "PT009"] +"tests/commands/test_create_preview.py" = ["ANN201", "ARG005", "I001", "PT009", "S106", "S108", "TRY002"] +"tests/commands/test_create_pr_preview.py" = ["ANN201", "I001", "S106"] +"tests/commands/test_delete_preview.py" = ["ANN201", "I001", "PT009", "S106", "S108"] +"tests/commands/test_delete_pr_preview.py" = ["ANN201", "I001", "S106"] +"tests/commands/test_deploy.py" = ["ANN001", "ANN201", "I001", "PT009", "S106", "S108"] +"tests/commands/test_sync_apps.py" = ["ANN001", "ANN201", "ANN202", "ARG005", "E501", "ERA001", "I001", "PT009", "RSE102", "S106", "S108", "TRY002"] +"tests/commands/test_version.py" = ["ANN201"] +"tests/git_api/test_git_repo_api_logging_proxy.py" = ["ANN001", "ANN201", "PT009"] +"tests/git_api/test_git_repo.py" = ["ANN001", "ANN201", "ANN202", "ARG002", "I001", "PT009", "PT018", "PTH101", "PTH103", "PTH110", "PTH123", "S108", "SIM117"] +"tests/git_api/test_repo_api_factory.py" = ["ANN001", "ANN201", "I001", "PT009", "S106"] +"tests/io_api/test_tmp_dir.py" = ["ANN201", "PT009", "PTH103", "PTH112", "S108"] +"tests/io_api/test_yaml_util.py" = ["ANN001", "ANN102", "ANN201", "ANN202", "ANN206", "I001", "PT009", "PTH103", "PTH123", "S108", "UP015"] +"tests/test_cliparser.py" = ["ANN001", "ANN102", "ANN201", "ANN202", "ANN205", "ANN206", "E501", "I001", "N802", "PT009", "S105"] +"tests/test_gitops_config_v0.py" = ["ANN201", "I001", "PT009"] +"tests/test_gitops_config_v1.py" = ["ANN201", "E501", "I001", "N802", "PLC0208", "PLR2004", "PT009"] +"tests/test_gitops_config_v2.py" = ["ANN201", "E501", "I001", "N802", "PLC0208", "PLR2004", "PT009"] diff --git a/tests/commands/test_sync_apps.py b/tests/commands/test_sync_apps.py index be469bfd..152d8a74 100644 --- a/tests/commands/test_sync_apps.py +++ b/tests/commands/test_sync_apps.py @@ -303,13 +303,15 @@ def test_sync_apps_missing_repository_element_in_team_yaml(self): self.assertEqual("Cannot find key 'repository' in /tmp/root-config-repo/apps/team-non-prod.yaml", str(ex)) def test_sync_apps_undefined_team_repo(self): - self.yaml_file_load_mock.side_effect = lambda file_path: { - "/tmp/root-config-repo/bootstrap/values.yaml": {"bootstrap": [{"name": "other-team-non-prod"}]}, - "/tmp/root-config-repo/apps/other-team-non-prod.yaml": { - "repository": "https://repository.url/other-team/other-team-non-prod.git", # there is no repo matching the command's team repo - "applications": {}, - }, - }[file_path] + self.yaml_file_load_mock.side_effect = ( + lambda file_path: { + "/tmp/root-config-repo/bootstrap/values.yaml": {"bootstrap": [{"name": "other-team-non-prod"}]}, + "/tmp/root-config-repo/apps/other-team-non-prod.yaml": { + "repository": "https://repository.url/other-team/other-team-non-prod.git", # there is no repo matching the command's team repo + "applications": {}, + }, + }[file_path] + ) try: SyncAppsCommand(ARGS).execute()