Merge branch 'pylint-fixes' into 'ddd-intro'

Pylint fixes

See merge request domaindrivenarchitecture/dda-devops-build!11
This commit is contained in:
Pat Dyn 2023-04-28 13:35:06 +00:00
commit 7c4933c6d9
8 changed files with 67 additions and 72 deletions

View file

@ -27,7 +27,7 @@ pylint:
stage: lint&test stage: lint&test
script: script:
- pip install -r dev_requirements.txt - pip install -r dev_requirements.txt
- pylint -d C0301,W0614,C0114,C0115,C0116,similarities,W0702,W0702,R0913,R0902,R0914,R1732 src/main/python/ddadevops/ - pylint -d W0511,R0903,C0301,W0614,C0114,C0115,C0116,similarities,W1203,W0719,W0702,W0702,R0913,R0902,R0914,R1732 src/main/python/ddadevops/
pytest: pytest:
stage: lint&test stage: lint&test

View file

@ -1,5 +1,4 @@
from typing import Optional from typing import Optional
from subprocess import run, CalledProcessError
import deprecation import deprecation
from .domain import Devops from .domain import Devops
from .infrastructure import ProjectRepository, FileApi from .infrastructure import ProjectRepository, FileApi

View file

@ -1,6 +1,6 @@
import deprecation
import logging
from typing import List from typing import List
import logging
import deprecation
def filter_none(list_to_filter): def filter_none(list_to_filter):
return [x for x in list_to_filter if x is not None] return [x for x in list_to_filter if x is not None]
@ -10,7 +10,7 @@ class Validateable:
value = self.__dict__[field_name] value = self.__dict__[field_name]
if value is None or value == "": if value is None or value == "":
return [f"Field '{field_name}' must not be empty."] return [f"Field '{field_name}' must not be empty."]
else:
return [] return []
def validate(self) -> List[str]: def validate(self) -> List[str]:
@ -24,7 +24,6 @@ class Validateable:
issues = '\n'.join(self.validate()) issues = '\n'.join(self.validate())
raise ValueError(f"Invalid Validateable: {issues}") raise ValueError(f"Invalid Validateable: {issues}")
class DnsRecord(Validateable): class DnsRecord(Validateable):
def __init__(self, fqdn, ipv4=None, ipv6=None): def __init__(self, fqdn, ipv4=None, ipv6=None):
self.fqdn = fqdn self.fqdn = fqdn
@ -46,7 +45,7 @@ class Devops(Validateable):
self.stage = stage self.stage = stage
self.name = name self.name = name
self.project_root_path = project_root_path self.project_root_path = project_root_path
logging.warn(f"Set project root in DevOps {self.project_root_path}") logging.warning(f"Set project root in DevOps {self.project_root_path}")
self.module = module self.module = module
if not name: if not name:
self.name = module self.name = module
@ -56,22 +55,23 @@ class Devops(Validateable):
@deprecation.deprecated(deprecated_in="3.2") @deprecation.deprecated(deprecated_in="3.2")
# use .name instead # use .name instead
#pylint: disable=method-hidden
def name(self): def name(self):
return self.name return self.name
def build_path(self): def build_path(self):
path = [self.project_root_path, self.build_dir_name, self.name, self.module] path = [self.project_root_path, self.build_dir_name, self.name, self.module]
logging.warn(f"Set project build_path in Devops {path}") logging.warning(f"Set project build_path in Devops {path}")
return "/".join(filter_none(path)) return "/".join(filter_none(path))
def __put__(self, key, value): def __put__(self, key, value):
self.stack[key] = value self.stack[key] = value
def __get__(self, key): def __get(self, key):
return self.stack[key] return self.stack[key]
def __get_keys__(self, keys): def __get_keys__(self, keys):
result = {} result = {}
for key in keys: for key in keys:
result[key] = self.__get__(key) result[key] = self.__get(key)
return result return result

View file

@ -1,4 +1,3 @@
from typing import Optional
from .common import ( from .common import (
filter_none, filter_none,
Validateable, Validateable,
@ -11,7 +10,6 @@ class Image(Validateable):
dockerhub_user, dockerhub_user,
dockerhub_password, dockerhub_password,
devops: Devops, devops: Devops,
build_dir_name="target",
use_package_common_files=True, use_package_common_files=True,
build_commons_path=None, build_commons_path=None,
docker_build_commons_dir_name="docker", docker_build_commons_dir_name="docker",
@ -26,5 +24,5 @@ class Image(Validateable):
self.devops = devops self.devops = devops
def docker_build_commons_path(self): def docker_build_commons_path(self):
list = [self.build_commons_path, self.docker_build_commons_dir_name] commons_path = [self.build_commons_path, self.docker_build_commons_dir_name]
return "/".join(filter_none(list)) + "/" return "/".join(filter_none(commons_path)) + "/"

View file

@ -2,7 +2,6 @@ from enum import Enum
from typing import Optional from typing import Optional
from pathlib import Path from pathlib import Path
from .common import ( from .common import (
filter_none,
Validateable, Validateable,
Devops, Devops,
) )
@ -19,8 +18,8 @@ class EnvironmentKeys(Enum):
class Version(): class Version():
def __init__(self, id: Path, version_list: list): def __init__(self, path: Path, version_list: list):
self.id = id self.path = path
self.version_list = version_list self.version_list = version_list
self.version_string: Optional[str | None] = None self.version_string: Optional[str | None] = None
self.is_snapshot: Optional[bool | None] = None self.is_snapshot: Optional[bool | None] = None
@ -43,7 +42,7 @@ class Version():
self.version_list[ReleaseType.MINOR.value] = 0 self.version_list[ReleaseType.MINOR.value] = 0
self.version_list[ReleaseType.MAJOR.value] += 1 self.version_list[ReleaseType.MAJOR.value] += 1
case None: case None:
raise Exception("Release Type was not set!") raise RuntimeError("Release Type was not set!")
def get_version_string(self) -> str: def get_version_string(self) -> str:
self.version_string = ".".join([str(x) for x in self.version_list]) self.version_string = ".".join([str(x) for x in self.version_list])
@ -52,13 +51,13 @@ class Version():
return self.version_string return self.version_string
def create_release_version(self, release_type: ReleaseType | None): def create_release_version(self, release_type: ReleaseType | None):
release_version = Version(self.id, self.version_list.copy()) release_version = Version(self.path, self.version_list.copy())
release_version.is_snapshot = self.is_snapshot release_version.is_snapshot = self.is_snapshot
release_version.increment(release_type) release_version.increment(release_type)
return release_version return release_version
def create_bump_version(self): def create_bump_version(self):
bump_version = Version(self.id, self.version_list.copy()) bump_version = Version(self.path, self.version_list.copy())
bump_version.is_snapshot = self.is_snapshot bump_version.is_snapshot = self.is_snapshot
bump_version.increment(ReleaseType.BUMP) bump_version.increment(ReleaseType.BUMP)
return bump_version return bump_version

View file

@ -1,6 +1,5 @@
import json import json
import re import re
import subprocess as sub
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Optional from typing import Optional
from pathlib import Path from pathlib import Path
@ -26,7 +25,7 @@ class FileHandler(ABC):
case '.py': case '.py':
file_handler = PythonFileHandler() file_handler = PythonFileHandler()
case _: case _:
raise Exception( raise RuntimeError(
f'The file type "{config_file_type}" is not implemented') f'The file type "{config_file_type}" is not implemented')
# TODO: Attribute is only set in classmethod. Should this be initialized outside of this class? # TODO: Attribute is only set in classmethod. Should this be initialized outside of this class?
file_handler.config_file_path = file_path file_handler.config_file_path = file_path
@ -47,7 +46,7 @@ class JsonFileHandler(FileHandler):
def parse(self) -> tuple[list[int], bool]: def parse(self) -> tuple[list[int], bool]:
if self.config_file_path is None: if self.config_file_path is None:
raise ValueError("No file name given.") raise ValueError("No file name given.")
with open(self.config_file_path, 'r') as json_file: with open(self.config_file_path, 'r', encoding='utf-8') as json_file:
json_version = json.load(json_file)['version'] json_version = json.load(json_file)['version']
is_snapshot = False is_snapshot = False
if '-SNAPSHOT' in json_version: if '-SNAPSHOT' in json_version:
@ -57,7 +56,7 @@ class JsonFileHandler(FileHandler):
return version, is_snapshot return version, is_snapshot
def write(self, version_string): def write(self, version_string):
with open(self.config_file_path, 'r+') as json_file: with open(self.config_file_path, 'r+', encoding='utf-8') as json_file:
json_data = json.load(json_file) json_data = json.load(json_file)
json_data['version'] = version_string json_data['version'] = version_string
json_file.seek(0) json_file.seek(0)
@ -70,7 +69,7 @@ class GradleFileHandler(FileHandler):
def parse(self) -> tuple[list[int], bool]: def parse(self) -> tuple[list[int], bool]:
if self.config_file_path is None: if self.config_file_path is None:
raise ValueError("No file name given.") raise ValueError("No file name given.")
with open(self.config_file_path, 'r') as gradle_file: with open(self.config_file_path, 'r', encoding='utf-8') as gradle_file:
contents = gradle_file.read() contents = gradle_file.read()
version_line = re.search("\nversion = .*", contents) version_line = re.search("\nversion = .*", contents)
exception = Exception("Version not found in gradle file") exception = Exception("Version not found in gradle file")
@ -94,7 +93,7 @@ class GradleFileHandler(FileHandler):
return version, is_snapshot return version, is_snapshot
def write(self, version_string): def write(self, version_string):
with open(self.config_file_path, 'r+') as gradle_file: with open(self.config_file_path, 'r+', encoding='utf-8') as gradle_file:
contents = gradle_file.read() contents = gradle_file.read()
version_substitute = re.sub( version_substitute = re.sub(
'\nversion = "[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?"', f'\nversion = "{version_string}"', contents) '\nversion = "[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?"', f'\nversion = "{version_string}"', contents)
@ -108,7 +107,7 @@ class PythonFileHandler(FileHandler):
def parse(self) -> tuple[list[int], bool]: def parse(self) -> tuple[list[int], bool]:
if self.config_file_path is None: if self.config_file_path is None:
raise ValueError("No file name given.") raise ValueError("No file name given.")
with open(self.config_file_path, 'r') as python_file: with open(self.config_file_path, 'r', encoding='utf-8') as python_file:
contents = python_file.read() contents = python_file.read()
version_line = re.search("\nversion = .*\n", contents) version_line = re.search("\nversion = .*\n", contents)
exception = Exception("Version not found in gradle file") exception = Exception("Version not found in gradle file")
@ -132,7 +131,7 @@ class PythonFileHandler(FileHandler):
return version, is_snapshot return version, is_snapshot
def write(self, version_string): def write(self, version_string):
with open(self.config_file_path, 'r+') as python_file: with open(self.config_file_path, 'r+', encoding='utf-8') as python_file:
contents = python_file.read() contents = python_file.read()
version_substitute = re.sub( version_substitute = re.sub(
'\nversion = "[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?"', f'\nversion = "{version_string}"', contents) '\nversion = "[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?"', f'\nversion = "{version_string}"', contents)
@ -146,7 +145,7 @@ class ClojureFileHandler(FileHandler):
def parse(self) -> tuple[list[int], bool]: def parse(self) -> tuple[list[int], bool]:
if self.config_file_path is None: if self.config_file_path is None:
raise ValueError("No file name given.") raise ValueError("No file name given.")
with open(self.config_file_path, 'r') as clj_file: with open(self.config_file_path, 'r', encoding='utf-8') as clj_file:
contents = clj_file.read() contents = clj_file.read()
version_line = re.search("^\\(defproject .*\n", contents) version_line = re.search("^\\(defproject .*\n", contents)
exception = Exception("Version not found in clj file") exception = Exception("Version not found in clj file")
@ -170,7 +169,7 @@ class ClojureFileHandler(FileHandler):
return version, is_snapshot return version, is_snapshot
def write(self, version_string): def write(self, version_string):
with open(self.config_file_path, 'r+') as clj_file: with open(self.config_file_path, 'r+', encoding='utf-8') as clj_file:
clj_first = clj_file.readline() clj_first = clj_file.readline()
clj_rest = clj_file.read() clj_rest = clj_file.read()
version_substitute = re.sub( version_substitute = re.sub(
@ -186,6 +185,7 @@ class GitApi():
def __init__(self): def __init__(self):
self.execution_api = ExecutionApi() self.execution_api = ExecutionApi()
# pylint: disable=invalid-name
def get_latest_n_commits(self, n: int): def get_latest_n_commits(self, n: int):
return self.execution_api.execute( return self.execution_api.execute(
f'git log --oneline --format="%s %b" -n {n}') f'git log --oneline --format="%s %b" -n {n}')
@ -204,11 +204,10 @@ class GitApi():
return self.execution_api.execute('git describe --tags --abbrev=0') return self.execution_api.execute('git describe --tags --abbrev=0')
def get_current_branch(self): def get_current_branch(self):
self.execution_api.execute('git branch --show-current') return ''.join(self.execution_api.execute('git branch --show-current')).rstrip()
return ''.join(self.execution_api.stdout).rstrip()
def init(self, default_branch: str = "main"): def init(self, default_branch: str = "main"):
self.execution_api.execute(f'git init') self.execution_api.execute('git init')
self.execution_api.execute(f'git checkout -b {default_branch}') self.execution_api.execute(f'git checkout -b {default_branch}')
def set_user_config(self, email: str, name: str): def set_user_config(self, email: str, name: str):

View file

@ -1,11 +1,11 @@
from typing import Optional
from src.main.python.ddadevops.domain import ( from src.main.python.ddadevops.domain import (
ReleaseContext, ReleaseContext,
Version, Version,
ReleaseType, ReleaseType,
EnvironmentKeys, EnvironmentKeys,
) )
from src.main.python.ddadevops.infrastructure.release_mixin import ( from src.main.python.ddadevops.infrastructure.release_mixin.infrastructure_api import (
FileHandler, FileHandler,
GitApi, GitApi,
EnvironmentApi, EnvironmentApi,
@ -23,8 +23,7 @@ class VersionRepository:
def write_file(self, version_string): def write_file(self, version_string):
if self.file_handler is None: if self.file_handler is None:
raise Exception("Version was not created by load_file method.") raise RuntimeError("Version was not created by load_file method.")
else:
self.file_handler.write(version_string) self.file_handler.write(version_string)
def parse_file(self): def parse_file(self):
@ -53,28 +52,29 @@ class ReleaseTypeRepository:
@classmethod @classmethod
def from_git(cls, git_api: GitApi): def from_git(cls, git_api: GitApi):
releaseTypeRepo = cls(git_api=git_api) release_type_repo = cls(git_api=git_api)
releaseTypeRepo.get_from_git = True release_type_repo.get_from_git = True
return releaseTypeRepo return release_type_repo
@classmethod @classmethod
def from_environment(cls, environment_api: EnvironmentApi): def from_environment(cls, environment_api: EnvironmentApi):
releaseTypeRepo = cls(environment_api=environment_api) release_type_repo = cls(environment_api=environment_api)
releaseTypeRepo.get_from_env = True release_type_repo.get_from_env = True
return releaseTypeRepo return release_type_repo
def __get_release_type_git(self) -> ReleaseType | None: def __get_release_type_git(self) -> ReleaseType | None:
latest_commit = self.git_api.get_latest_commit() latest_commit = self.git_api.get_latest_commit()
if ReleaseType.MAJOR.name in latest_commit.upper(): match latest_commit.upper():
case ReleaseType.MAJOR.name:
return ReleaseType.MAJOR return ReleaseType.MAJOR
elif ReleaseType.MINOR.name in latest_commit.upper(): case ReleaseType.MINOR.name:
return ReleaseType.MINOR return ReleaseType.MINOR
elif ReleaseType.PATCH.name in latest_commit.upper(): case ReleaseType.PATCH.name:
return ReleaseType.PATCH return ReleaseType.PATCH
elif ReleaseType.SNAPSHOT.name in latest_commit.upper(): case ReleaseType.SNAPSHOT.name:
return ReleaseType.SNAPSHOT return ReleaseType.SNAPSHOT
else: case _:
return None return None
def __get_release_type_environment(self) -> ReleaseType | None: def __get_release_type_environment(self) -> ReleaseType | None:
@ -86,23 +86,24 @@ class ReleaseTypeRepository:
raise ValueError( raise ValueError(
"Release Name not found. Is the Environment correctly configured?" "Release Name not found. Is the Environment correctly configured?"
) )
elif ReleaseType.MAJOR.name in release_name.upper():
match release_name.upper():
case ReleaseType.MAJOR.name:
return ReleaseType.MAJOR return ReleaseType.MAJOR
elif ReleaseType.MINOR.name in release_name.upper(): case ReleaseType.MINOR.name:
return ReleaseType.MINOR return ReleaseType.MINOR
elif ReleaseType.PATCH.name in release_name.upper(): case ReleaseType.PATCH.name:
return ReleaseType.PATCH return ReleaseType.PATCH
elif ReleaseType.SNAPSHOT.name in release_name.upper(): case ReleaseType.SNAPSHOT.name:
return ReleaseType.SNAPSHOT return ReleaseType.SNAPSHOT
else: case _:
return None return None
def get_release_type(self) -> ReleaseType | None: def get_release_type(self) -> ReleaseType | None:
if self.get_from_git: if self.get_from_git:
return self.__get_release_type_git() return self.__get_release_type_git()
elif self.get_from_env: if self.get_from_env:
return self.__get_release_type_environment() return self.__get_release_type_environment()
else:
raise ValueError("No valid api passed to ReleaseTypeRepository") raise ValueError("No valid api passed to ReleaseTypeRepository")

View file

@ -1,4 +1,3 @@
from typing import Optional
from pybuilder.core import Project from pybuilder.core import Project
from src.main.python.ddadevops.devops_build import DevopsBuild from src.main.python.ddadevops.devops_build import DevopsBuild
from src.main.python.ddadevops.infrastructure.release_mixin import ReleaseContextRepository, ReleaseTypeRepository, VersionRepository, GitApi, EnvironmentApi from src.main.python.ddadevops.infrastructure.release_mixin import ReleaseContextRepository, ReleaseTypeRepository, VersionRepository, GitApi, EnvironmentApi