diff --git a/gitopscli/__main__.py b/gitopscli/__main__.py index ca17cb45..19c90708 100644 --- a/gitopscli/__main__.py +++ b/gitopscli/__main__.py @@ -14,10 +14,10 @@ def main() -> None: command.execute() except GitOpsException as ex: if verbose: - logging.exception(ex) + logging.exception(ex) # noqa: TRY401 else: - logging.error(ex) - logging.error("Provide verbose flag '-v' for more error details...") + logging.error(ex) # noqa: TRY400 + logging.error("Provide verbose flag '-v' for more error details...") # noqa: TRY400 sys.exit(1) diff --git a/gitopscli/appconfig_api/app_tenant_config.py b/gitopscli/appconfig_api/app_tenant_config.py index 07a0a151..7efc191f 100644 --- a/gitopscli/appconfig_api/app_tenant_config.py +++ b/gitopscli/appconfig_api/app_tenant_config.py @@ -17,10 +17,7 @@ class AppTenantConfig: dirty: bool = False def __post_init__(self) -> None: - if "config" in self.yaml: - self.tenant_config = self.yaml["config"] - else: - self.tenant_config = self.yaml + self.tenant_config = self.yaml.get("config", self.yaml) if "repository" not in self.tenant_config: raise GitOpsException("Cannot find key 'repository' in " + self.file_path) self.repo_url = str(self.tenant_config["repository"]) @@ -47,29 +44,28 @@ def __update_custom_app_config(self, desired_apps: dict[str, dict[str, Any]]) -> ) del existing_application_value["customAppConfig"] self.__set_dirty() - else: - if ( - "customAppConfig" not in existing_application_value - or existing_application_value["customAppConfig"] != desired_app_value["customAppConfig"] - ): - logging.info( - "Updating customAppConfig in for %s in %s applications", - existing_application_value, - self.file_path, - ) - existing_application_value["customAppConfig"] = desired_app_value["customAppConfig"] - self.__set_dirty() + elif ( + "customAppConfig" not in existing_application_value + or existing_application_value["customAppConfig"] != desired_app_value["customAppConfig"] + ): + logging.info( + "Updating customAppConfig in for %s in %s applications", + existing_application_value, + self.file_path, + ) + existing_application_value["customAppConfig"] = desired_app_value["customAppConfig"] + self.__set_dirty() def __add_new_applications(self, desired_apps: dict[str, Any]) -> None: for desired_app_name, desired_app_value in desired_apps.items(): - if desired_app_name not in self.list_apps().keys(): + if desired_app_name not in self.list_apps(): logging.info("Adding %s in %s applications", desired_app_name, self.file_path) self.tenant_config["applications"][desired_app_name] = desired_app_value self.__set_dirty() def __delete_removed_applications(self, desired_apps: dict[str, Any]) -> None: - for current_app in self.list_apps().keys(): - if current_app not in desired_apps.keys(): + for current_app in self.list_apps(): + if current_app not in desired_apps: logging.info("Removing %s from %s applications", current_app, self.file_path) del self.tenant_config["applications"][current_app] self.__set_dirty() @@ -80,7 +76,7 @@ def __set_dirty(self) -> None: def __generate_config_from_tenant_repo( tenant_repo: GitRepo, -) -> Any: # TODO: supposed to be ruamel object than Any +) -> Any: # TODO: supposed to be ruamel object than Any # noqa: FIX002 tenant_app_dirs = __get_all_tenant_applications_dirs(tenant_repo) tenant_config_template = f""" config: @@ -103,19 +99,17 @@ def __generate_config_from_tenant_repo( def __get_all_tenant_applications_dirs(tenant_repo: GitRepo) -> set[str]: repo_dir = tenant_repo.get_full_file_path(".") - applist = { + return { name for name in os.listdir(repo_dir) if os.path.isdir(os.path.join(repo_dir, name)) and not name.startswith(".") } - return applist def __get_custom_config(appname: str, tenant_config_git_repo: GitRepo) -> Any: custom_config_path = tenant_config_git_repo.get_full_file_path(f"{appname}/.config.yaml") if os.path.exists(custom_config_path): - custom_config_content = yaml_file_load(custom_config_path) - return custom_config_content + return yaml_file_load(custom_config_path) return {} diff --git a/gitopscli/appconfig_api/root_repo.py b/gitopscli/appconfig_api/root_repo.py index 67734a0f..ed916a3f 100644 --- a/gitopscli/appconfig_api/root_repo.py +++ b/gitopscli/appconfig_api/root_repo.py @@ -31,7 +31,7 @@ def validate_tenant(self, tenant_config: AppTenantConfig) -> None: for tenant in self.tenants.values(): if tenant.repo_url != tenant_config.repo_url: apps_from_other_tenants.extend(tenant.list_apps().keys()) - for app_name in tenant_config.list_apps().keys(): + for app_name in tenant_config.list_apps(): if app_name in apps_from_other_tenants: raise GitOpsException(f"Application '{app_name}' already exists in a different repository") diff --git a/gitopscli/commands/command_factory.py b/gitopscli/commands/command_factory.py index 9711c9c0..dc7ff2c5 100644 --- a/gitopscli/commands/command_factory.py +++ b/gitopscli/commands/command_factory.py @@ -10,7 +10,6 @@ CommandArgs = ( DeployCommand.Args - | DeployCommand.Args | AddPrCommentCommand.Args | CreatePreviewCommand.Args | CreatePrPreviewCommand.Args diff --git a/gitopscli/commands/create_preview.py b/gitopscli/commands/create_preview.py index 29059e3e..10606f7d 100644 --- a/gitopscli/commands/create_preview.py +++ b/gitopscli/commands/create_preview.py @@ -175,7 +175,7 @@ def __create_preview_info_file(self, gitops_config: GitOpsConfig) -> None: "routeHost": gitops_config.get_preview_host(preview_id), "namespace": gitops_config.get_preview_namespace(preview_id), }, - "/tmp/gitopscli-preview-info.yaml", + "/tmp/gitopscli-preview-info.yaml", # noqa: S108 ) @staticmethod diff --git a/gitopscli/commands/deploy.py b/gitopscli/commands/deploy.py index b87e7093..12b666c2 100644 --- a/gitopscli/commands/deploy.py +++ b/gitopscli/commands/deploy.py @@ -70,7 +70,7 @@ def execute(self) -> None: git_repo_api.delete_branch(pr_branch) if self.__args.json: - print(json.dumps({"commits": [{"hash": h} for h in self.__commit_hashes]}, indent=4)) + print(json.dumps({"commits": [{"hash": h} for h in self.__commit_hashes]}, indent=4)) # noqa: T201 def __create_git_repo_api(self) -> GitRepoApi: return GitRepoApiFactory.create(self.__args, self.__args.organisation, self.__args.repository_name) @@ -80,7 +80,7 @@ def __update_values(self, git_repo: GitRepo) -> dict[str, Any]: single_commit = args.single_commit or args.commit_message full_file_path = git_repo.get_full_file_path(args.file) updated_values = {} - for key, value in args.values.items(): + for key, value in args.values.items(): # noqa: PD011 try: updated_value = update_yaml_file(full_file_path, key, value) except (FileNotFoundError, IsADirectoryError) as ex: @@ -104,7 +104,7 @@ def __update_values(self, git_repo: GitRepo) -> dict[str, Any]: if args.commit_message: message = args.commit_message elif len(updated_values) == 1: - key, value = list(updated_values.items())[0] + key, value = next(iter(updated_values.items())) message = f"changed '{key}' to '{value}' in {args.file}" else: updates_count = len(updated_values) diff --git a/gitopscli/commands/sync_apps.py b/gitopscli/commands/sync_apps.py index 8929b623..7b290c2a 100644 --- a/gitopscli/commands/sync_apps.py +++ b/gitopscli/commands/sync_apps.py @@ -34,19 +34,20 @@ def execute(self) -> None: def _sync_apps_command(args: SyncAppsCommand.Args) -> None: team_config_git_repo_api = GitRepoApiFactory.create(args, args.organisation, args.repository_name) root_config_git_repo_api = GitRepoApiFactory.create(args, args.root_organisation, args.root_repository_name) - with GitRepo(team_config_git_repo_api) as team_config_git_repo: - with GitRepo(root_config_git_repo_api) as root_config_git_repo: - __sync_apps( - team_config_git_repo, - root_config_git_repo, - args.git_user, - args.git_email, - args.git_author_name, - args.git_author_email, - ) + with GitRepo(team_config_git_repo_api) as team_config_git_repo, GitRepo( + root_config_git_repo_api + ) as root_config_git_repo: + __sync_apps( + team_config_git_repo, + root_config_git_repo, + args.git_user, + args.git_email, + args.git_author_name, + args.git_author_email, + ) -# TODO: BETTER NAMES FOR STUFF HERE +# TODO: BETTER NAMES FOR STUFF HERE # noqa: FIX002 def __sync_apps( tenant_git_repo: GitRepo, root_git_repo: GitRepo, diff --git a/gitopscli/commands/version.py b/gitopscli/commands/version.py index f9dc39e4..75e00957 100644 --- a/gitopscli/commands/version.py +++ b/gitopscli/commands/version.py @@ -18,4 +18,4 @@ def execute(self) -> None: except importlib.metadata.PackageNotFoundError: # Handle the case where "gitopscli" is not installed version = None - print(f"GitOps CLI version {version}") + print(f"GitOps CLI version {version}") # noqa: T201 diff --git a/gitopscli/git_api/bitbucket_git_repo_api_adapter.py b/gitopscli/git_api/bitbucket_git_repo_api_adapter.py index 4bb4782e..4cd6c5b2 100644 --- a/gitopscli/git_api/bitbucket_git_repo_api_adapter.py +++ b/gitopscli/git_api/bitbucket_git_repo_api_adapter.py @@ -85,8 +85,8 @@ def create_pull_request( def merge_pull_request( self, pr_id: int, - merge_method: Literal["squash", "rebase", "merge"] = "merge", - merge_parameters: dict[str, Any] | None = None, + merge_method: Literal["squash", "rebase", "merge"] = "merge", # noqa: ARG002 + merge_parameters: dict[str, Any] | None = None, # noqa: ARG002 ) -> None: pull_request = self.__bitbucket.get_pullrequest(self.__organisation, self.__repository_name, pr_id) self.__bitbucket.merge_pull_request( diff --git a/gitopscli/git_api/git_repo.py b/gitopscli/git_api/git_repo.py index 61712db1..1caa3686 100644 --- a/gitopscli/git_api/git_repo.py +++ b/gitopscli/git_api/git_repo.py @@ -133,7 +133,7 @@ def __get_repo(self) -> Repo: def __create_credentials_file(self, username: str, password: str) -> str: file_path = f"{self.__tmp_dir}/credentials.sh" - with open(file_path, "w", encoding=locale.getpreferredencoding(False)) as text_file: + with open(file_path, "w", encoding=locale.getpreferredencoding(do_setlocale=False)) as text_file: text_file.write("#!/bin/sh\n") text_file.write(f"echo username='{username}'\n") text_file.write(f"echo password='{password}'\n") diff --git a/gitopscli/git_api/git_repo_api_logging_proxy.py b/gitopscli/git_api/git_repo_api_logging_proxy.py index 1c9362c8..a455d9f0 100644 --- a/gitopscli/git_api/git_repo_api_logging_proxy.py +++ b/gitopscli/git_api/git_repo_api_logging_proxy.py @@ -40,7 +40,7 @@ def merge_pull_request( self, pr_id: int, merge_method: Literal["squash", "rebase", "merge"] = "merge", - merge_parameters: dict[str, Any] | None = None, + merge_parameters: dict[str, Any] | None = None, # noqa: ARG002 ) -> None: logging.info("Merging pull request %s", pr_id) self.__api.merge_pull_request(pr_id, merge_method=merge_method) diff --git a/gitopscli/git_api/github_git_repo_api_adapter.py b/gitopscli/git_api/github_git_repo_api_adapter.py index ec85d85d..0b22bd73 100644 --- a/gitopscli/git_api/github_git_repo_api_adapter.py +++ b/gitopscli/git_api/github_git_repo_api_adapter.py @@ -61,12 +61,17 @@ def merge_pull_request( self, pr_id: int, merge_method: Literal["squash", "rebase", "merge"] = "merge", - merge_parameters: dict[str, Any] | None = None, + merge_parameters: dict[str, Any] | None = None, # noqa: ARG002 ) -> None: pull_request = self.__get_pull_request(pr_id) pull_request.merge(merge_method=merge_method) - def add_pull_request_comment(self, pr_id: int, text: str, parent_id: int | None = None) -> None: + def add_pull_request_comment( + self, + pr_id: int, + text: str, + parent_id: int | None = None, # noqa: ARG002 + ) -> None: pull_request = self.__get_pull_request(pr_id) pull_request.create_issue_comment(text) diff --git a/gitopscli/git_api/gitlab_git_repo_api_adapter.py b/gitopscli/git_api/gitlab_git_repo_api_adapter.py index 37a3821b..afa525b8 100644 --- a/gitopscli/git_api/gitlab_git_repo_api_adapter.py +++ b/gitopscli/git_api/gitlab_git_repo_api_adapter.py @@ -29,7 +29,7 @@ def __init__( except gitlab.exceptions.GitlabAuthenticationError as ex: raise GitOpsException("Bad Personal Access Token") from ex except gitlab.exceptions.GitlabGetError as ex: - if ex.response_code == 404: + if ex.response_code == 404: # noqa: PLR2004 raise GitOpsException(f"Repository '{organisation}/{repository_name}' does not exist") from ex raise GitOpsException(f"Error getting repository: '{ex.error_message}'") from ex @@ -82,7 +82,7 @@ def merge_pull_request( merge_request.rebase(merge_parameters) return merge_request.merge(merge_parameters) - return + return # noqa: TRY300 except gitlab.exceptions.GitlabMRClosedError as ex: # "Branch cannot be merged" error can occur if the server # is still processing the merge request internally @@ -96,7 +96,12 @@ def merge_pull_request( raise GitOpsException("Error merging pull request: 'Branch cannot be merged'") from ex time.sleep(2.5) - def add_pull_request_comment(self, pr_id: int, text: str, parent_id: int | None = None) -> None: + def add_pull_request_comment( + self, + pr_id: int, + text: str, + parent_id: int | None = None, # noqa:ARG002 + ) -> None: merge_request = self.__project.mergerequests.get(pr_id) merge_request.notes.create({"body": text}) diff --git a/gitopscli/gitops_config.py b/gitopscli/gitops_config.py index 8fb1db8c..0f30c61a 100644 --- a/gitopscli/gitops_config.py +++ b/gitopscli/gitops_config.py @@ -3,7 +3,7 @@ from collections.abc import Callable from dataclasses import dataclass from string import Template -from typing import Any +from typing import Any, ClassVar from gitopscli.gitops_exception import GitOpsException @@ -19,7 +19,7 @@ class PreviewContext: preview_id: str git_hash: str - __VARIABLE_MAPPERS: dict[str, Callable[["GitOpsConfig.Replacement.PreviewContext"], str]] = { + __VARIABLE_MAPPERS: ClassVar[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), @@ -29,7 +29,7 @@ class PreviewContext: "PREVIEW_ID_HASH_SHORT": lambda context: GitOpsConfig.create_preview_id_hash_short(context.preview_id), } - def __init__(self, path: str, value_template: str): + def __init__(self, path: str, value_template: str) -> None: assert isinstance(path, str), "path of wrong type!" assert isinstance(value_template, str), "value_template of wrong type!" @@ -118,8 +118,7 @@ def get_preview_host(self, preview_id: str) -> str: preview_host = preview_host.replace("${PREVIEW_ID_HASH}", self.create_preview_id_hash(preview_id)) preview_host = preview_host.replace("${PREVIEW_ID_HASH_SHORT}", self.create_preview_id_hash_short(preview_id)) preview_host = preview_host.replace("${PREVIEW_ID}", self.__sanitize(preview_id)) - preview_host = preview_host.replace("${PREVIEW_NAMESPACE}", self.get_preview_namespace(preview_id)) - return preview_host + return preview_host.replace("${PREVIEW_NAMESPACE}", self.get_preview_namespace(preview_id)) def get_preview_namespace(self, preview_id: str) -> str: preview_namespace = self.preview_target_namespace_template @@ -183,8 +182,7 @@ def __sanitize(preview_id: str, max_length: int | None = None) -> str: sanitized_preview_id = re.sub(r"-+", "-", sanitized_preview_id) if max_length is not None: sanitized_preview_id = sanitized_preview_id[0:max_length] - sanitized_preview_id = re.sub(r"-$", "", sanitized_preview_id) - return sanitized_preview_id + return re.sub(r"-$", "", sanitized_preview_id) def is_preview_template_equal_target(self) -> bool: return ( @@ -207,7 +205,7 @@ def from_yaml(yaml: Any) -> "GitOpsConfig": class _GitOpsConfigYamlParser: - def __init__(self, yaml: Any): + def __init__(self, yaml: Any) -> None: self.__yaml = yaml def __get_value(self, key: str) -> Any: diff --git a/gitopscli/gitops_exception.py b/gitopscli/gitops_exception.py index a2c43fed..de17f3ba 100644 --- a/gitopscli/gitops_exception.py +++ b/gitopscli/gitops_exception.py @@ -1,2 +1,2 @@ -class GitOpsException(Exception): +class GitOpsException(Exception): # noqa: N818 pass diff --git a/gitopscli/io_api/tmp_dir.py b/gitopscli/io_api/tmp_dir.py index 4c9421f4..964fe06e 100644 --- a/gitopscli/io_api/tmp_dir.py +++ b/gitopscli/io_api/tmp_dir.py @@ -4,7 +4,7 @@ def create_tmp_dir() -> str: - tmp_dir = f"/tmp/gitopscli/{uuid.uuid4()}" + tmp_dir = f"/tmp/gitopscli/{uuid.uuid4()}" # noqa: S108 os.makedirs(tmp_dir) return tmp_dir diff --git a/gitopscli/io_api/yaml_util.py b/gitopscli/io_api/yaml_util.py index 167cd26e..51536105 100644 --- a/gitopscli/io_api/yaml_util.py +++ b/gitopscli/io_api/yaml_util.py @@ -10,12 +10,12 @@ YAML_INSTANCE.preserve_quotes = True -class YAMLException(Exception): +class YAMLException(Exception): # noqa: N818 pass def yaml_file_load(file_path: str) -> Any: - with open(file_path, "r", encoding=locale.getpreferredencoding(False)) as stream: + with open(file_path, encoding=locale.getpreferredencoding(do_setlocale=False)) as stream: try: return YAML_INSTANCE.load(stream) except YAMLError as ex: @@ -23,7 +23,7 @@ def yaml_file_load(file_path: str) -> Any: def yaml_file_dump(yaml: Any, file_path: str) -> None: - with open(file_path, "w+", encoding=locale.getpreferredencoding(False)) as stream: + with open(file_path, "w+", encoding=locale.getpreferredencoding(do_setlocale=False)) as stream: YAML_INSTANCE.dump(yaml, stream) @@ -73,14 +73,13 @@ def merge_yaml_element(file_path: str, element_path: str, desired_value: Any) -> work_path = work_path[key] for key, value in desired_value.items(): - if key in work_path: - if work_path[key] is not None: - value = {**work_path[key], **value} + if key in work_path and work_path[key] is not None: + value = {**work_path[key], **value} # noqa: PLW2901 work_path[key] = value # delete missing key: current = work_path.copy().items() - for key, value in current: + for key, _ in current: if key not in desired_value: del work_path[key] diff --git a/pyproject.toml b/pyproject.toml index 42ee211e..aee27584 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,43 +55,15 @@ ignore = ["ANN101", "ANN401", [tool.ruff.per-file-ignores] "**/__init__.py" = ["F401"] +"tests/**/*.py" = ["S106", "S108", "ANN", "PT009"] # 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/appconfig_api/app_tenant_config.py" = ["PTH110", "PTH112", "PTH118"] +"gitopscli/commands/create_preview.py" = ["PTH112"] "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"] +"gitopscli/git_api/git_repo.py" = ["PTH101", "PTH118", "PTH123"] +"gitopscli/io_api/tmp_dir.py" = ["PTH103"] +"gitopscli/io_api/yaml_util.py" = ["PTH123"] +"tests/git_api/test_git_repo.py" = ["PTH101", "PTH103", "PTH110", "PTH123"] +"tests/io_api/test_tmp_dir.py" = ["PTH103", "PTH112"] +"tests/io_api/test_yaml_util.py" = ["PTH103", "PTH123"] diff --git a/tests/commands/common/__init__.py b/tests/commands/common/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/commands/common/test_gitops_config_loader.py b/tests/commands/common/test_gitops_config_loader.py index a23688b2..9b1c532e 100644 --- a/tests/commands/common/test_gitops_config_loader.py +++ b/tests/commands/common/test_gitops_config_loader.py @@ -1,11 +1,13 @@ import unittest from unittest.mock import call + import pytest -from gitopscli.gitops_exception import GitOpsException + +from gitopscli.commands.common.gitops_config_loader import load_gitops_config +from gitopscli.git_api import GitApiConfig, GitProvider, GitRepo, GitRepoApi, GitRepoApiFactory from gitopscli.gitops_config import GitOpsConfig +from gitopscli.gitops_exception import GitOpsException from gitopscli.io_api.yaml_util import yaml_file_load -from gitopscli.git_api import GitApiConfig, GitProvider, GitRepo, GitRepoApi, GitRepoApiFactory -from gitopscli.commands.common.gitops_config_loader import load_gitops_config from tests.commands.mock_mixin import MockMixin diff --git a/tests/commands/mock_mixin.py b/tests/commands/mock_mixin.py index 57d0a94d..323f4b94 100644 --- a/tests/commands/mock_mixin.py +++ b/tests/commands/mock_mixin.py @@ -1,9 +1,8 @@ from abc import ABC +from unittest.mock import MagicMock, patch, seal -from unittest.mock import patch, MagicMock, seal - -class MockMixin(ABC): +class MockMixin(ABC): # noqa: B024 def init_mock_manager(self, command_class: type) -> None: self.command_class = command_class self.mock_manager = MagicMock() diff --git a/tests/commands/test_add_pr_comment.py b/tests/commands/test_add_pr_comment.py index 99fa29ac..f9b71b76 100644 --- a/tests/commands/test_add_pr_comment.py +++ b/tests/commands/test_add_pr_comment.py @@ -1,7 +1,9 @@ import unittest from unittest.mock import call -from gitopscli.git_api import GitProvider, GitRepoApi, GitRepoApiFactory + from gitopscli.commands.add_pr_comment import AddPrCommentCommand +from gitopscli.git_api import GitProvider, GitRepoApi, GitRepoApiFactory + from .mock_mixin import MockMixin diff --git a/tests/commands/test_command_factory.py b/tests/commands/test_command_factory.py index 1155796c..615f14c1 100644 --- a/tests/commands/test_command_factory.py +++ b/tests/commands/test_command_factory.py @@ -1,11 +1,12 @@ import unittest from unittest.mock import Mock -from gitopscli.commands.command_factory import CommandFactory + from gitopscli.commands.add_pr_comment import AddPrCommentCommand -from gitopscli.commands.create_preview import CreatePreviewCommand +from gitopscli.commands.command_factory import CommandFactory from gitopscli.commands.create_pr_preview import CreatePrPreviewCommand -from gitopscli.commands.delete_preview import DeletePreviewCommand +from gitopscli.commands.create_preview import CreatePreviewCommand from gitopscli.commands.delete_pr_preview import DeletePrPreviewCommand +from gitopscli.commands.delete_preview import DeletePreviewCommand from gitopscli.commands.deploy import DeployCommand from gitopscli.commands.sync_apps import SyncAppsCommand from gitopscli.commands.version import VersionCommand diff --git a/tests/commands/test_create_pr_preview.py b/tests/commands/test_create_pr_preview.py index b6904c7b..439c0270 100644 --- a/tests/commands/test_create_pr_preview.py +++ b/tests/commands/test_create_pr_preview.py @@ -1,7 +1,9 @@ import unittest from unittest.mock import call + +from gitopscli.commands.create_pr_preview import CreatePreviewCommand, CreatePrPreviewCommand from gitopscli.git_api import GitProvider, GitRepoApi, GitRepoApiFactory -from gitopscli.commands.create_pr_preview import CreatePrPreviewCommand, CreatePreviewCommand + from .mock_mixin import MockMixin DUMMY_GIT_HASH = "5f65cfa04c66444fcb756d6d7f39304d1c18b199" diff --git a/tests/commands/test_create_preview.py b/tests/commands/test_create_preview.py index 99e2b30a..9a5361f4 100644 --- a/tests/commands/test_create_preview.py +++ b/tests/commands/test_create_preview.py @@ -1,13 +1,15 @@ +import logging import os -import unittest import shutil -import logging -from unittest.mock import call, Mock -from gitopscli.io_api.yaml_util import update_yaml_file, YAMLException, yaml_file_dump -from gitopscli.git_api import GitRepo, GitRepoApi, GitRepoApiFactory, GitProvider, GitApiConfig +import unittest +from unittest.mock import Mock, call + +from gitopscli.commands.create_preview import CreatePreviewCommand, load_gitops_config +from gitopscli.git_api import GitApiConfig, GitProvider, GitRepo, GitRepoApi, GitRepoApiFactory from gitopscli.gitops_config import GitOpsConfig from gitopscli.gitops_exception import GitOpsException -from gitopscli.commands.create_preview import CreatePreviewCommand, load_gitops_config +from gitopscli.io_api.yaml_util import YAMLException, update_yaml_file, yaml_file_dump + from .mock_mixin import MockMixin DUMMY_GIT_HASH = "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9" @@ -35,6 +37,10 @@ } +class UnreachableError(Exception): + pass + + class CreatePreviewCommandTest(MockMixin, unittest.TestCase): def setUp(self): self.init_mock_manager(CreatePreviewCommand) @@ -90,7 +96,7 @@ def git_repo_api_factory_create_mock(_: GitApiConfig, organisation: str, reposit return self.template_git_repo_api_mock if "TARGET" in organisation and "TARGET" in repository_name: return self.target_git_repo_api_mock - raise Exception(f"no mock for {organisation}/{repository_name}") + raise UnreachableError(f"no mock for {organisation}/{repository_name}") self.git_repo_api_factory_mock.create.side_effect = git_repo_api_factory_create_mock @@ -113,7 +119,7 @@ def git_repo_constructor_mock(git_repo_api: GitRepoApi) -> GitRepo: return self.template_git_repo_mock if git_repo_api == self.target_git_repo_api_mock: return self.target_git_repo_mock - raise Exception(f"no mock for {git_repo_api}") + raise UnreachableError(f"no mock for {git_repo_api}") self.monkey_patch(GitRepo).side_effect = git_repo_constructor_mock @@ -129,8 +135,8 @@ def test_create_new_preview(self): command = CreatePreviewCommand(ARGS) command.register_callbacks( - deployment_already_up_to_date_callback=lambda route_host: self.fail("should not be called"), - deployment_updated_callback=lambda route_host: self.fail("should not be called"), + deployment_already_up_to_date_callback=lambda _: self.fail("should not be called"), + deployment_updated_callback=lambda _: self.fail("should not be called"), deployment_created_callback=deployment_created_callback, ) command.execute() @@ -232,8 +238,8 @@ def test_create_new_preview_from_same_template_target_repo(self): command = CreatePreviewCommand(ARGS) command.register_callbacks( - deployment_already_up_to_date_callback=lambda route_host: self.fail("should not be called"), - deployment_updated_callback=lambda route_host: self.fail("should not be called"), + deployment_already_up_to_date_callback=lambda _: self.fail("should not be called"), + deployment_updated_callback=lambda _: self.fail("should not be called"), deployment_created_callback=deployment_created_callback, ) command.execute() @@ -313,9 +319,9 @@ def test_update_existing_preview(self): command = CreatePreviewCommand(ARGS) command.register_callbacks( - deployment_already_up_to_date_callback=lambda route_host: self.fail("should not be called"), + deployment_already_up_to_date_callback=lambda _: self.fail("should not be called"), deployment_updated_callback=deployment_updated_callback, - deployment_created_callback=lambda route_host: self.fail("should not be called"), + deployment_created_callback=lambda _: self.fail("should not be called"), ) command.execute() @@ -384,8 +390,8 @@ def test_preview_already_up_to_date(self): command = CreatePreviewCommand(ARGS) command.register_callbacks( deployment_already_up_to_date_callback=deployment_already_up_to_date_callback, - deployment_updated_callback=lambda route_host: self.fail("should not be called"), - deployment_created_callback=lambda route_host: self.fail("should not be called"), + deployment_updated_callback=lambda _: self.fail("should not be called"), + deployment_created_callback=lambda _: self.fail("should not be called"), ) command.execute() diff --git a/tests/commands/test_delete_pr_preview.py b/tests/commands/test_delete_pr_preview.py index d7f6f67f..c07605c1 100644 --- a/tests/commands/test_delete_pr_preview.py +++ b/tests/commands/test_delete_pr_preview.py @@ -1,6 +1,8 @@ import unittest + +from gitopscli.commands.delete_pr_preview import DeletePreviewCommand, DeletePrPreviewCommand from gitopscli.git_api import GitProvider -from gitopscli.commands.delete_pr_preview import DeletePrPreviewCommand, DeletePreviewCommand + from .mock_mixin import MockMixin diff --git a/tests/commands/test_delete_preview.py b/tests/commands/test_delete_preview.py index 0d5176a9..065e1213 100644 --- a/tests/commands/test_delete_preview.py +++ b/tests/commands/test_delete_preview.py @@ -1,13 +1,16 @@ +import logging import os import shutil import unittest -import logging from unittest.mock import call + import pytest + +from gitopscli.commands.delete_preview import DeletePreviewCommand, load_gitops_config +from gitopscli.git_api import GitProvider, GitRepo, GitRepoApi, GitRepoApiFactory from gitopscli.gitops_config import GitOpsConfig -from gitopscli.git_api import GitRepo, GitRepoApi, GitRepoApiFactory, GitProvider from gitopscli.gitops_exception import GitOpsException -from gitopscli.commands.delete_preview import DeletePreviewCommand, load_gitops_config + from .mock_mixin import MockMixin diff --git a/tests/commands/test_deploy.py b/tests/commands/test_deploy.py index 853249cb..97d24777 100644 --- a/tests/commands/test_deploy.py +++ b/tests/commands/test_deploy.py @@ -1,16 +1,19 @@ -from io import StringIO import logging -from textwrap import dedent -import uuid import unittest +import uuid +from io import StringIO +from textwrap import dedent from unittest import mock from unittest.mock import call from uuid import UUID + import pytest -from gitopscli.gitops_exception import GitOpsException + from gitopscli.commands.deploy import DeployCommand -from gitopscli.git_api import GitRepoApi, GitProvider, GitRepoApiFactory, GitRepo -from gitopscli.io_api.yaml_util import update_yaml_file, YAMLException +from gitopscli.git_api import GitProvider, GitRepo, GitRepoApi, GitRepoApiFactory +from gitopscli.gitops_exception import GitOpsException +from gitopscli.io_api.yaml_util import YAMLException, update_yaml_file + from .mock_mixin import MockMixin diff --git a/tests/commands/test_sync_apps.py b/tests/commands/test_sync_apps.py index 152d8a74..a040a1c0 100644 --- a/tests/commands/test_sync_apps.py +++ b/tests/commands/test_sync_apps.py @@ -1,14 +1,16 @@ -import posixpath import logging import os +import posixpath import unittest from unittest.mock import call, patch from ruamel.yaml.compat import ordereddict -from gitopscli.git_api import GitProvider, GitRepo, GitRepoApi, GitRepoApiFactory + from gitopscli.commands.sync_apps import SyncAppsCommand -from gitopscli.io_api.yaml_util import yaml_file_load, yaml_file_dump +from gitopscli.git_api import GitProvider, GitRepo, GitRepoApi, GitRepoApiFactory from gitopscli.gitops_exception import GitOpsException +from gitopscli.io_api.yaml_util import yaml_file_dump, yaml_file_load + from .mock_mixin import MockMixin ARGS = SyncAppsCommand.Args( @@ -27,6 +29,10 @@ ) +class UnreachableError(Exception): + pass + + class SyncAppsCommandTest(MockMixin, unittest.TestCase): def setUp(self): self.init_mock_manager(SyncAppsCommand) @@ -65,7 +71,7 @@ def setUp(self): self.root_config_git_repo_mock.push.return_value = None self.git_repo_api_factory_mock = self.monkey_patch(GitRepoApiFactory) - self.git_repo_api_factory_mock.create.side_effect = lambda config, org, repo: { + self.git_repo_api_factory_mock.create.side_effect = lambda _, org, repo: { ("TEAM_ORGA", "TEAM_REPO"): self.team_config_git_repo_api_mock, ("ROOT_ORGA", "ROOT_REPO"): self.root_config_git_repo_api_mock, }[(org, repo)] @@ -81,7 +87,6 @@ def setUp(self): self.yaml_file_load_mock = patcher.start() self.mock_manager.attach_mock(self.yaml_file_load_mock, "yaml_file_load") - # self.yaml_file_load_mock = self.monkey_patch(yaml_file_load) self.yaml_file_load_mock.side_effect = lambda file_path: { "/tmp/root-config-repo/bootstrap/values.yaml": { "bootstrap": [{"name": "team-non-prod"}, {"name": "other-team-non-prod"}], @@ -274,8 +279,8 @@ def file_load_mock_side_effect(file_path): "bootstrap": [{"name": "team-non-prod"}], } if file_path == "/tmp/root-config-repo/apps/team-non-prod.yaml": - raise FileNotFoundError() - raise Exception("test should not reach this") + raise FileNotFoundError + raise UnreachableError("test should not reach this") self.yaml_file_load_mock.side_effect = file_load_mock_side_effect @@ -303,15 +308,14 @@ 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": { + # there is no repo matching the command's team repo + "repository": "https://repository.url/other-team/other-team-non-prod.git", + "applications": {}, + }, + }[file_path] try: SyncAppsCommand(ARGS).execute() diff --git a/tests/git_api/test_git_repo.py b/tests/git_api/test_git_repo.py index cf4183e7..77087df6 100644 --- a/tests/git_api/test_git_repo.py +++ b/tests/git_api/test_git_repo.py @@ -1,10 +1,11 @@ -from os import path, makedirs, chmod import stat import unittest import uuid +from os import chmod, makedirs, path from unittest.mock import MagicMock, patch -from git import Repo + import pytest +from git import Repo from gitopscli.git_api import GitRepo, GitRepoApi from gitopscli.gitops_exception import GitOpsException @@ -264,7 +265,7 @@ def test_commit_with_custom_author(self, logging_mock): logging_mock.info.assert_called_once_with("Creating commit with message: %s", "new commit") @patch("gitopscli.git_api.git_repo.logging") - def test_commit_with_custom_author_name_but_no_email_returns_validation_error(self, logging_mock): + def test_commit_with_custom_author_name_but_no_email_returns_validation_error(self, logging_mock): # noqa: ARG002 with GitRepo(self.__mock_repo_api) as testee: with pytest.raises(GitOpsException) as ex: testee.commit( @@ -279,7 +280,7 @@ def test_commit_with_custom_author_name_but_no_email_returns_validation_error(se ) @patch("gitopscli.git_api.git_repo.logging") - def test_commit_with_custom_author_email_but_no_name_returns_validation_error(self, logging_mock): + def test_commit_with_custom_author_email_but_no_name_returns_validation_error(self, logging_mock): # noqa: ARG002 with GitRepo(self.__mock_repo_api) as testee: with pytest.raises(GitOpsException) as ex: testee.commit( @@ -389,7 +390,8 @@ def test_push_commit_hook_error_reason_is_shown(self, logging_mock): with pytest.raises(GitOpsException) as ex: testee.push("master") - assert "pre-receive" in str(ex.value) and "we reject this push" in str(ex.value) + assert "pre-receive" in str(ex.value) + assert "we reject this push" in str(ex.value) logging_mock.info.assert_called_once_with("Pushing branch: %s", "master") def test_get_author_from_last_commit(self): @@ -398,7 +400,6 @@ def test_get_author_from_last_commit(self): self.assertEqual("unit tester ", testee.get_author_from_last_commit()) def test_get_author_from_last_commit_not_cloned_yet(self): - with GitRepo(self.__mock_repo_api) as testee: - with pytest.raises(GitOpsException) as ex: - testee.get_author_from_last_commit() + with GitRepo(self.__mock_repo_api) as testee, pytest.raises(GitOpsException) as ex: + testee.get_author_from_last_commit() self.assertEqual("Repository not cloned yet!", str(ex.value)) diff --git a/tests/git_api/test_repo_api_factory.py b/tests/git_api/test_repo_api_factory.py index b309cf9e..29b5d7c2 100644 --- a/tests/git_api/test_repo_api_factory.py +++ b/tests/git_api/test_repo_api_factory.py @@ -1,8 +1,8 @@ import unittest -from unittest.mock import patch, MagicMock +from unittest.mock import MagicMock, patch +from gitopscli.git_api import GitApiConfig, GitProvider, GitRepoApiFactory from gitopscli.gitops_exception import GitOpsException -from gitopscli.git_api import GitRepoApiFactory, GitApiConfig, GitProvider class GitRepoApiFactoryTest(unittest.TestCase): diff --git a/tests/io_api/test_yaml_util.py b/tests/io_api/test_yaml_util.py index 8bea0fe6..0a92818a 100644 --- a/tests/io_api/test_yaml_util.py +++ b/tests/io_api/test_yaml_util.py @@ -2,16 +2,17 @@ import shutil import unittest import uuid + import pytest from gitopscli.io_api.yaml_util import ( - yaml_file_load, - yaml_file_dump, - yaml_load, - yaml_dump, YAMLException, - update_yaml_file, merge_yaml_element, + update_yaml_file, + yaml_dump, + yaml_file_dump, + yaml_file_load, + yaml_load, ) @@ -37,7 +38,7 @@ def _create_file(self, content): return path def _read_file(self, path): - with open(path, "r") as stream: + with open(path) as stream: return stream.read() def test_yaml_file_load(self): diff --git a/tests/test_cliparser.py b/tests/test_cliparser.py index 355730b7..4cd4c5b0 100644 --- a/tests/test_cliparser.py +++ b/tests/test_cliparser.py @@ -3,19 +3,20 @@ import unittest from contextlib import contextmanager from io import StringIO + import pytest +from gitopscli.cliparser import parse_args from gitopscli.commands import ( - DeployCommand, - SyncAppsCommand, AddPrCommentCommand, CreatePreviewCommand, CreatePrPreviewCommand, DeletePreviewCommand, DeletePrPreviewCommand, + DeployCommand, + SyncAppsCommand, VersionCommand, ) -from gitopscli.cliparser import parse_args from gitopscli.git_api import GitProvider EXPECTED_GITOPSCLI_HELP = """\ @@ -49,7 +50,7 @@ PR_ID [--parent-id PARENT_ID] [-v [VERBOSE]] --text TEXT gitopscli add-pr-comment: error: the following arguments are required: --username, --password, --organisation, --repository-name, --pr-id, --text -""" +""" # noqa: E501 EXPECTED_ADD_PR_COMMENT_HELP = """\ usage: gitopscli add-pr-comment [-h] --username USERNAME --password PASSWORD @@ -93,7 +94,7 @@ --git-hash GIT_HASH --preview-id PREVIEW_ID [-v [VERBOSE]] gitopscli create-preview: error: the following arguments are required: --username, --password, --organisation, --repository-name, --git-hash, --preview-id -""" +""" # noqa: E501 EXPECTED_CREATE_PR_PREVIEW_NO_ARGS_ERROR = """\ usage: gitopscli create-pr-preview [-h] --username USERNAME --password PASSWORD [--git-user GIT_USER] @@ -107,7 +108,7 @@ --pr-id PR_ID [--parent-id PARENT_ID] [-v [VERBOSE]] gitopscli create-pr-preview: error: the following arguments are required: --username, --password, --organisation, --repository-name, --pr-id -""" +""" # noqa: E501 EXPECTED_CREATE_PREVIEW_HELP = """\ usage: gitopscli create-preview [-h] --username USERNAME --password PASSWORD @@ -203,7 +204,7 @@ [--expect-preview-exists [EXPECT_PREVIEW_EXISTS]] [-v [VERBOSE]] gitopscli delete-preview: error: the following arguments are required: --username, --password, --organisation, --repository-name, --preview-id -""" +""" # noqa: E501 EXPECTED_DELETE_PR_PREVIEW_NO_ARGS_ERROR = """\ usage: gitopscli delete-pr-preview [-h] --username USERNAME --password @@ -219,7 +220,7 @@ [--expect-preview-exists [EXPECT_PREVIEW_EXISTS]] [-v [VERBOSE]] gitopscli delete-pr-preview: error: the following arguments are required: --username, --password, --organisation, --repository-name, --branch -""" +""" # noqa: E501 EXPECTED_DELETE_PREVIEW_HELP = """\ usage: gitopscli delete-preview [-h] --username USERNAME --password PASSWORD @@ -322,7 +323,7 @@ [--pr-labels PR_LABELS] [--merge-parameters MERGE_PARAMETERS] [-v [VERBOSE]] gitopscli deploy: error: the following arguments are required: --file, --values, --username, --password, --organisation, --repository-name -""" +""" # noqa: E501 EXPECTED_DEPLOY_HELP = """\ usage: gitopscli deploy [-h] --file FILE --values VALUES @@ -398,7 +399,7 @@ ROOT_ORGANISATION --root-repository-name ROOT_REPOSITORY_NAME gitopscli sync-apps: error: the following arguments are required: --username, --password, --organisation, --repository-name, --root-organisation, --root-repository-name -""" +""" # noqa: E501 EXPECTED_SYNC_APPS_HELP = """\ usage: gitopscli sync-apps [-h] --username USERNAME --password PASSWORD @@ -487,10 +488,10 @@ def _capture_parse_args(args): parse_args(args) return ex.value.code, stdout.getvalue(), stderr.getvalue() - def assertType(self, o: object, t: type): + def assert_type(self, o: object, t: type): self.assertTrue(isinstance(o, t)) - def assertEqualIgnoringWhitespaceAndNewlines(self, expected, actual): + def assert_equal_ignoring_whitespace_and_newlines(self, expected, actual): def normalize_string(s): return " ".join(s.split()) @@ -500,36 +501,36 @@ def test_no_args(self): exit_code, stdout, stderr = self._capture_parse_args([]) self.assertEqual(exit_code, 2) self.assertEqual("", stdout) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_GITOPSCLI_HELP, stderr) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_GITOPSCLI_HELP, stderr) def test_help(self): exit_code, stdout, stderr = self._capture_parse_args(["--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_GITOPSCLI_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_GITOPSCLI_HELP, stdout) self.assertEqual("", stderr) def test_help_shortcut(self): exit_code, stdout, stderr = self._capture_parse_args(["-h"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_GITOPSCLI_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_GITOPSCLI_HELP, stdout) self.assertEqual("", stderr) def test_add_pr_comment_no_args(self): exit_code, stdout, stderr = self._capture_parse_args(["add-pr-comment"]) self.assertEqual(exit_code, 2) self.assertEqual("", stdout) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_ADD_PR_COMMENT_NO_ARGS_ERROR, stderr) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_ADD_PR_COMMENT_NO_ARGS_ERROR, stderr) def test_add_pr_comment_help(self): exit_code, stdout, stderr = self._capture_parse_args(["add-pr-comment", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_ADD_PR_COMMENT_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_ADD_PR_COMMENT_HELP, stdout) self.assertEqual("", stderr) def test_add_pr_comment_help_shortcut(self): exit_code, stdout, stderr = self._capture_parse_args(["add-pr-comment", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_ADD_PR_COMMENT_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_ADD_PR_COMMENT_HELP, stdout) self.assertEqual("", stderr) def test_add_pr_comment_required_args(self): @@ -552,7 +553,7 @@ def test_add_pr_comment_required_args(self): "TEXT", ] ) - self.assertType(args, AddPrCommentCommand.Args) + self.assert_type(args, AddPrCommentCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -568,7 +569,7 @@ def test_add_pr_comment_required_args(self): def test_add_pr_comment_required_args_and_credentials_env_vars(self): os.environ["GITOPSCLI_USERNAME"] = "ENV_USER" - os.environ["GITOPSCLI_PASSWORD"] = "ENV_PASS" + os.environ["GITOPSCLI_PASSWORD"] = "ENV_PASS" # noqa: S105 verbose, args = parse_args( [ "add-pr-comment", @@ -584,7 +585,7 @@ def test_add_pr_comment_required_args_and_credentials_env_vars(self): "TEXT", ] ) - self.assertType(args, AddPrCommentCommand.Args) + self.assert_type(args, AddPrCommentCommand.Args) self.assertEqual(args.username, "ENV_USER") self.assertEqual(args.password, "ENV_PASS") @@ -623,7 +624,7 @@ def test_add_pr_comment_all_args(self): "--verbose", ] ) - self.assertType(args, AddPrCommentCommand.Args) + self.assert_type(args, AddPrCommentCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -640,18 +641,18 @@ def test_create_preview_no_args(self): exit_code, stdout, stderr = self._capture_parse_args(["create-preview"]) self.assertEqual(exit_code, 2) self.assertEqual("", stdout) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_CREATE_PREVIEW_NO_ARGS_ERROR, stderr) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_CREATE_PREVIEW_NO_ARGS_ERROR, stderr) def test_create_preview_help(self): exit_code, stdout, stderr = self._capture_parse_args(["create-preview", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_CREATE_PREVIEW_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_CREATE_PREVIEW_HELP, stdout) self.assertEqual("", stderr) def test_create_preview_help_shortcut(self): exit_code, stdout, stderr = self._capture_parse_args(["create-preview", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_CREATE_PREVIEW_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_CREATE_PREVIEW_HELP, stdout) self.assertEqual("", stderr) def test_create_preview_required_args(self): @@ -678,7 +679,7 @@ def test_create_preview_required_args(self): "abc123", ] ) - self.assertType(args, CreatePreviewCommand.Args) + self.assert_type(args, CreatePreviewCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -724,7 +725,7 @@ def test_create_preview_all_args(self): "-v", ] ) - self.assertType(args, CreatePreviewCommand.Args) + self.assert_type(args, CreatePreviewCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -745,18 +746,18 @@ def test_create_pr_preview_no_args(self): exit_code, stdout, stderr = self._capture_parse_args(["create-pr-preview"]) self.assertEqual(exit_code, 2) self.assertEqual("", stdout) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_CREATE_PR_PREVIEW_NO_ARGS_ERROR, stderr) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_CREATE_PR_PREVIEW_NO_ARGS_ERROR, stderr) def test_create_pr_preview_help(self): exit_code, stdout, stderr = self._capture_parse_args(["create-pr-preview", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_CREATE_PR_PREVIEW_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_CREATE_PR_PREVIEW_HELP, stdout) self.assertEqual("", stderr) def test_create_pr_preview_help_shortcut(self): exit_code, stdout, stderr = self._capture_parse_args(["create-pr-preview", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_CREATE_PR_PREVIEW_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_CREATE_PR_PREVIEW_HELP, stdout) self.assertEqual("", stderr) def test_create_pr_preview_required_args(self): @@ -781,7 +782,7 @@ def test_create_pr_preview_required_args(self): "4711", ] ) - self.assertType(args, CreatePrPreviewCommand.Args) + self.assert_type(args, CreatePrPreviewCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -827,7 +828,7 @@ def test_create_pr_preview_all_args(self): "-v", ] ) - self.assertType(args, CreatePrPreviewCommand.Args) + self.assert_type(args, CreatePrPreviewCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -848,18 +849,18 @@ def test_delete_preview_no_args(self): exit_code, stdout, stderr = self._capture_parse_args(["delete-preview"]) self.assertEqual(exit_code, 2) self.assertEqual("", stdout) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_DELETE_PREVIEW_NO_ARGS_ERROR, stderr) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_DELETE_PREVIEW_NO_ARGS_ERROR, stderr) def test_delete_preview_help(self): exit_code, stdout, stderr = self._capture_parse_args(["delete-preview", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_DELETE_PREVIEW_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_DELETE_PREVIEW_HELP, stdout) self.assertEqual("", stderr) def test_delete_preview_help_shortcut(self): exit_code, stdout, stderr = self._capture_parse_args(["delete-preview", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_DELETE_PREVIEW_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_DELETE_PREVIEW_HELP, stdout) self.assertEqual("", stderr) def test_delete_preview_required_args(self): @@ -884,7 +885,7 @@ def test_delete_preview_required_args(self): "abc123", ] ) - self.assertType(args, DeletePreviewCommand.Args) + self.assert_type(args, DeletePreviewCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -930,7 +931,7 @@ def test_delete_preview_all_args(self): "n", ] ) - self.assertType(args, DeletePreviewCommand.Args) + self.assert_type(args, DeletePreviewCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -951,18 +952,18 @@ def test_delete_pr_preview_no_args(self): exit_code, stdout, stderr = self._capture_parse_args(["delete-pr-preview"]) self.assertEqual(exit_code, 2) self.assertEqual("", stdout) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_DELETE_PR_PREVIEW_NO_ARGS_ERROR, stderr) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_DELETE_PR_PREVIEW_NO_ARGS_ERROR, stderr) def test_delete_pr_preview_help(self): exit_code, stdout, stderr = self._capture_parse_args(["delete-pr-preview", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_DELETE_PR_PREVIEW_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_DELETE_PR_PREVIEW_HELP, stdout) self.assertEqual("", stderr) def test_delete_pr_preview_help_shortcut(self): exit_code, stdout, stderr = self._capture_parse_args(["delete-pr-preview", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_DELETE_PR_PREVIEW_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_DELETE_PR_PREVIEW_HELP, stdout) self.assertEqual("", stderr) def test_delete_pr_preview_required_args(self): @@ -987,7 +988,7 @@ def test_delete_pr_preview_required_args(self): "BRANCH", ] ) - self.assertType(args, DeletePrPreviewCommand.Args) + self.assert_type(args, DeletePrPreviewCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -1033,7 +1034,7 @@ def test_delete_pr_preview_all_args(self): "n", ] ) - self.assertType(args, DeletePrPreviewCommand.Args) + self.assert_type(args, DeletePrPreviewCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -1054,18 +1055,18 @@ def test_deploy_no_args(self): exit_code, stdout, stderr = self._capture_parse_args(["deploy"]) self.assertEqual(exit_code, 2) self.assertEqual("", stdout) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_DEPLOY_NO_ARGS_ERROR, stderr) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_DEPLOY_NO_ARGS_ERROR, stderr) def test_deploy_help(self): exit_code, stdout, stderr = self._capture_parse_args(["deploy", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_DEPLOY_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_DEPLOY_HELP, stdout) self.assertEqual("", stderr) def test_deploy_help_shortcut(self): exit_code, stdout, stderr = self._capture_parse_args(["deploy", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_DEPLOY_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_DEPLOY_HELP, stdout) self.assertEqual("", stderr) def test_deploy_required_args(self): @@ -1092,7 +1093,7 @@ def test_deploy_required_args(self): '{"a.b": 42}', # json ] ) - self.assertType(args, DeployCommand.Args) + self.assert_type(args, DeployCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -1145,7 +1146,7 @@ def test_deploy_all_args(self): "yes", ] ) - self.assertType(args, DeployCommand.Args) + self.assert_type(args, DeployCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -1169,18 +1170,18 @@ def test_sync_apps_no_args(self): exit_code, stdout, stderr = self._capture_parse_args(["sync-apps"]) self.assertEqual(exit_code, 2) self.assertEqual("", stdout) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_SYNC_APPS_NO_ARGS_ERROR, stderr) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_SYNC_APPS_NO_ARGS_ERROR, stderr) def test_sync_apps_help(self): exit_code, stdout, stderr = self._capture_parse_args(["sync-apps", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_SYNC_APPS_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_SYNC_APPS_HELP, stdout) self.assertEqual("", stderr) def test_sync_apps_help_shortcut(self): exit_code, stdout, stderr = self._capture_parse_args(["sync-apps", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_SYNC_APPS_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_SYNC_APPS_HELP, stdout) self.assertEqual("", stderr) def test_sync_apps_required_args(self): @@ -1207,7 +1208,7 @@ def test_sync_apps_required_args(self): "ROOT_REPO", ] ) - self.assertType(args, SyncAppsCommand.Args) + self.assert_type(args, SyncAppsCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -1254,7 +1255,7 @@ def test_sync_apps_all_args(self): "false", ] ) - self.assertType(args, SyncAppsCommand.Args) + self.assert_type(args, SyncAppsCommand.Args) self.assertEqual(args.username, "USER") self.assertEqual(args.password, "PASS") @@ -1273,12 +1274,12 @@ def test_sync_apps_all_args(self): def test_version_args(self): _, args = parse_args(["version"]) - self.assertType(args, VersionCommand.Args) + self.assert_type(args, VersionCommand.Args) def test_version_help(self): exit_code, stdout, stderr = self._capture_parse_args(["version", "--help"]) self.assertEqual(exit_code, 0) - self.assertEqualIgnoringWhitespaceAndNewlines(EXPECTED_VERSION_HELP, stdout) + self.assert_equal_ignoring_whitespace_and_newlines(EXPECTED_VERSION_HELP, stdout) self.assertEqual("", stderr) def test_invalid_boolean(self): diff --git a/tests/test_gitops_config_v0.py b/tests/test_gitops_config_v0.py index 46f83074..af51638f 100644 --- a/tests/test_gitops_config_v0.py +++ b/tests/test_gitops_config_v0.py @@ -1,4 +1,5 @@ import unittest + import pytest from gitopscli.gitops_config import GitOpsConfig diff --git a/tests/test_gitops_config_v1.py b/tests/test_gitops_config_v1.py index 1cbf9de2..0fb4ff52 100644 --- a/tests/test_gitops_config_v1.py +++ b/tests/test_gitops_config_v1.py @@ -1,4 +1,5 @@ import unittest + import pytest from gitopscli.gitops_config import GitOpsConfig @@ -6,6 +7,8 @@ class GitOpsConfigV1Test(unittest.TestCase): + _max_namespace_length = 63 + def setUp(self): self.yaml = { "apiVersion": "v1", @@ -42,11 +45,11 @@ def assert_load_error(self, error_msg: str) -> None: self.load() self.assertEqual(error_msg, str(ex.value)) - def test_apiVersion(self): + def test_api_version(self): config = self.load() self.assertEqual(config.api_version, 1) - def test_invalid_apiVersion(self): + def test_invalid_api_version(self): self.yaml["apiVersion"] = "foo" self.assert_load_error("GitOps config apiVersion 'foo' is not supported!") @@ -183,10 +186,10 @@ def test_preview_target_branch_not_a_string(self): self.assert_load_error("Item 'previewConfig.target.branch' should be a string in GitOps config!") def test_is_preview_template_equal_target(self): - for x in {"organisation", "repository", "branch"}: + for x in ["organisation", "repository", "branch"]: self.yaml["previewConfig"]["template"][x] = self.yaml["previewConfig"]["target"][x] - for x in {"organisation", "repository", "branch"}: + for x in ["organisation", "repository", "branch"]: self.yaml["previewConfig"]["template"][x] = "custom-template-value" config = self.load() self.assertFalse(config.is_preview_template_equal_target(), x) @@ -214,7 +217,7 @@ def test_preview_target_namespace_default(self): "Very long preview ID. It will be cut to have max 63 chars of namespace in total!!" ) self.assertEqual(actual_namespace, "my-app-very-long-preview-id-it-will-be-cut-to-05d9825a-preview") - self.assertTrue(len(actual_namespace) <= 63) + self.assertTrue(len(actual_namespace) <= self._max_namespace_length) def test_preview_target_namespace_not_a_string(self): self.yaml["previewConfig"]["target"]["namespace"] = [] @@ -235,7 +238,8 @@ def test_preview_target_namespace_too_long(self): with pytest.raises(GitOpsException) as ex: config.get_preview_namespace("x") self.assertEqual( - "Preview namespace is too long (max 63 chars): veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeery-long--2d711642 (68 chars)", + "Preview namespace is too long (max 63 chars): " + "veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeery-long--2d711642 (68 chars)", str(ex.value), ) diff --git a/tests/test_gitops_config_v2.py b/tests/test_gitops_config_v2.py index 77deb3fd..d34ace55 100644 --- a/tests/test_gitops_config_v2.py +++ b/tests/test_gitops_config_v2.py @@ -1,4 +1,5 @@ import unittest + import pytest from gitopscli.gitops_config import GitOpsConfig @@ -6,6 +7,8 @@ class GitOpsConfigV2Test(unittest.TestCase): + _max_namespace_length = 50 + def setUp(self): self.yaml = { "apiVersion": "v2", @@ -43,11 +46,11 @@ def assert_load_error(self, error_msg: str) -> None: self.load() self.assertEqual(error_msg, str(ex.value)) - def test_apiVersion(self): + def test_api_version(self): config = self.load() self.assertEqual(config.api_version, 2) - def test_invalid_apiVersion(self): + def test_invalid_api_version(self): self.yaml["apiVersion"] = "foo" self.assert_load_error("GitOps config apiVersion 'foo' is not supported!") @@ -184,10 +187,10 @@ def test_preview_target_branch_not_a_string(self): self.assert_load_error("Item 'previewConfig.target.branch' should be a string in GitOps config!") def test_is_preview_template_equal_target(self): - for x in {"organisation", "repository", "branch"}: + for x in ["organisation", "repository", "branch"]: self.yaml["previewConfig"]["template"][x] = self.yaml["previewConfig"]["target"][x] - for x in {"organisation", "repository", "branch"}: + for x in ["organisation", "repository", "branch"]: self.yaml["previewConfig"]["template"][x] = "custom-template-value" config = self.load() self.assertFalse(config.is_preview_template_equal_target(), x) @@ -216,7 +219,7 @@ def test_preview_target_namespace_default(self): "Very long preview ID. It will be cut to have max 'maxNamespaceLength' chars of namespace in total!!" ) self.assertEqual(actual_namespace, "my-app-very-long-preview-id-it-will-be-c9f-preview") - self.assertTrue(len(actual_namespace) <= 50) + self.assertTrue(len(actual_namespace) <= self._max_namespace_length) def test_preview_target_namespace_not_a_string(self): self.yaml["previewConfig"]["target"]["namespace"] = [] @@ -237,7 +240,8 @@ def test_preview_target_namespace_too_long(self): with pytest.raises(GitOpsException) as ex: config.get_preview_namespace("x") self.assertEqual( - "Preview namespace is too long (max 50 chars): veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeery-long--2d711642 (55 chars)", + "Preview namespace is too long (max 50 chars): " + "veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeery-long--2d711642 (55 chars)", str(ex.value), )