diff --git a/infrastructure.py b/infrastructure.py index 528194e..8234a98 100644 --- a/infrastructure.py +++ b/infrastructure.py @@ -1,5 +1,5 @@ from domain import Release, Version, ReleaseType -from infrastructure_api import FileHandler, SystemAPI +from infrastructure_api import FileHandler, SystemAPI, GitApi from pathlib import Path class VersionRepository(): @@ -39,69 +39,19 @@ class ReleaseRepository(): pass class ReleaseTypeRepository(): - def __init__(self): - pass + def __init__(self, git_api, environment_api=None): + self.git_api = git_api -class GitRepository(): + def get_release_type(self): + latest_commit = self.git_api.get_latest_commit() - def __init__(self): - self.latest_commit = None - self.system_repository = SystemAPI() - - @classmethod - def create_from_commit_string(cls, commit_string): - inst = cls() - inst.latest_commit = commit_string - return inst - - def get_latest_n_commits(self, n: int): - self.system_repository.run_checked('git', 'log', '--oneline', '--format="%s %b"', f'-n {n}') - return self.system_repository.stdout - - def get_latest_commit(self): - output = self.get_latest_n_commits(1) - self.latest_commit = " ".join(output) # returns a list of strings otherwise - return self.latest_commit - - def get_release_type_from_latest_commit(self): - if self.latest_commit is None: - self.get_latest_commit() - - if ReleaseType.MAJOR.name in self.latest_commit.upper(): + if ReleaseType.MAJOR.name in latest_commit.upper(): return ReleaseType.MAJOR - elif ReleaseType.MINOR.name in self.latest_commit.upper(): + elif ReleaseType.MINOR.name in latest_commit.upper(): return ReleaseType.MINOR - elif ReleaseType.PATCH.name in self.latest_commit.upper(): + elif ReleaseType.PATCH.name in latest_commit.upper(): return ReleaseType.PATCH - elif ReleaseType.SNAPSHOT.name in self.latest_commit.upper(): + elif ReleaseType.SNAPSHOT.name in latest_commit.upper(): return ReleaseType.SNAPSHOT else: return None - - def tag_annotated(self, annotation: str, message: str): - self.system_repository.run_checked('git', 'tag', '-a', annotation, '-m', message) - return self.system_repository.stdout - - def tag_annotated(self, annotation: str, message: str, count: int): - self.system_repository.run_checked('git', 'tag', '-a', annotation, '-m', message, f'HEAD~{count}') - return self.system_repository.stdout - - def get_current_branch(self): - self.system_repository.run_checked('git', 'branch', '--show-current') - return ''.join(self.system_repository.stdout).rstrip() - - def add_file(self, file_path: Path): - self.system_repository.run_checked('git', 'add', file_path) - return self.system_repository.stdout - - def commit(self, commit_message: str): - self.system_repository.run_checked('git', 'commit', '-m', commit_message) - return self.system_repository.stdout - - def push(self): - self.system_repository.run_checked('git', 'push') - return self.system_repository.stdout - - def checkout(self, branch: str): - self.system_repository.run_checked('git', 'checkout', branch) - return self.system_repository.stdout \ No newline at end of file diff --git a/infrastructure_api.py b/infrastructure_api.py index aacaa08..06e2d17 100644 --- a/infrastructure_api.py +++ b/infrastructure_api.py @@ -1,8 +1,10 @@ -from abc import ABC, abstractmethod +from abc import ABC, abstractmethod +from pathlib import Path import json import re import subprocess as sub + class FileHandler(ABC): @classmethod @@ -18,7 +20,8 @@ class FileHandler(ABC): case '.py': file_handler = PythonFileHandler() case _: - raise Exception(f'The file type "{config_file_type}" is not implemented') + raise Exception( + f'The file type "{config_file_type}" is not implemented') file_handler.config_file_path = file_path file_handler.config_file_type = config_file_type @@ -27,11 +30,12 @@ class FileHandler(ABC): @abstractmethod def parse(self) -> tuple[list[int], bool]: pass - + @abstractmethod def write(self, version_string): pass + class JsonFileHandler(FileHandler): def parse(self) -> tuple[list[int], bool]: @@ -48,7 +52,7 @@ class JsonFileHandler(FileHandler): with open(self.config_file_path, 'r+') as json_file: json_data = json.load(json_file) json_data['version'] = version_string - json_file.seek(0) + json_file.seek(0) json.dump(json_data, json_file, indent=4) json_file.truncate() @@ -59,15 +63,16 @@ class GradleFileHandler(FileHandler): with open(self.config_file_path, 'r') as gradle_file: contents = gradle_file.read() version_line = re.search("\nversion = .*", contents) - exception = Exception("Version not found in gradle file") + exception = Exception("Version not found in gradle file") if version_line is None: raise exception - + version_line = version_line.group() - version_string = re.search('[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?', version_line) + version_string = re.search( + '[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?', version_line) if version_string is None: raise exception - + version_string = version_string.group() is_snapshot = False if '-SNAPSHOT' in version_string: @@ -81,7 +86,8 @@ class GradleFileHandler(FileHandler): def write(self, version_string): with open(self.config_file_path, 'r+') as gradle_file: contents = gradle_file.read() - version_substitute = re.sub('\nversion = "[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?"', f'\nversion = "{version_string}"', contents) + version_substitute = re.sub( + '\nversion = "[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?"', f'\nversion = "{version_string}"', contents) gradle_file.seek(0) gradle_file.write(version_substitute) gradle_file.truncate() @@ -93,15 +99,16 @@ class PythonFileHandler(FileHandler): with open(self.config_file_path, 'r') as python_file: contents = python_file.read() version_line = re.search("\nversion = .*\n", contents) - exception = Exception("Version not found in gradle file") + exception = Exception("Version not found in gradle file") if version_line is None: raise exception - + version_line = version_line.group() - version_string = re.search('[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?', version_line) + version_string = re.search( + '[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?', version_line) if version_string is None: raise exception - + version_string = version_string.group() is_snapshot = False if '-SNAPSHOT' in version_string: @@ -115,26 +122,29 @@ class PythonFileHandler(FileHandler): def write(self, version_string): with open(self.config_file_path, 'r+') as python_file: contents = python_file.read() - version_substitute = re.sub('\nversion = "[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?"', f'\nversion = "{version_string}"', contents) + version_substitute = re.sub( + '\nversion = "[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?"', f'\nversion = "{version_string}"', contents) python_file.seek(0) python_file.write(version_substitute) python_file.truncate() + class ClojureFileHandler(FileHandler): def parse(self) -> tuple[list[int], bool]: with open(self.config_file_path, 'r') as clj_file: contents = clj_file.read() version_line = re.search("^\\(defproject .*\n", contents) - exception = Exception("Version not found in clj file") + exception = Exception("Version not found in clj file") if version_line is None: raise exception - + version_line = version_line.group() - version_string = re.search('[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?', version_line) + version_string = re.search( + '[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?', version_line) if version_string is None: raise exception - + version_string = version_string.group() is_snapshot = False if '-SNAPSHOT' in version_string: @@ -149,12 +159,14 @@ class ClojureFileHandler(FileHandler): with open(self.config_file_path, 'r+') as clj_file: clj_first = clj_file.readline() clj_rest = clj_file.read() - version_substitute = re.sub('[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?', f'"{version_string}"\n', clj_first) + version_substitute = re.sub( + '[0-9]*\\.[0-9]*\\.[0-9]*(-SNAPSHOT)?', f'"{version_string}"\n', clj_first) clj_file.seek(0) clj_file.write(version_substitute) clj_file.write(clj_rest) clj_file.truncate() + class SystemAPI(): def __init__(self): @@ -175,3 +187,49 @@ class SystemAPI(): if len(self.stderr) > 0: raise Exception(f"Command failed with: {self.stderr}") + + +class GitApi(): + + def __init__(self): + self.system_repository = SystemAPI() + + def get_latest_n_commits(self, n: int): + self.system_repository.run_checked( + 'git', 'log', '--oneline', '--format="%s %b"', f'-n {n}') + return self.system_repository.stdout + + def get_latest_commit(self): + output = self.get_latest_n_commits(1) + return " ".join(output) + + def tag_annotated(self, annotation: str, message: str): + self.system_repository.run_checked( + 'git', 'tag', '-a', annotation, '-m', message) + return self.system_repository.stdout + + def tag_annotated(self, annotation: str, message: str, count: int): + self.system_repository.run_checked( + 'git', 'tag', '-a', annotation, '-m', message, f'HEAD~{count}') + return self.system_repository.stdout + + def get_current_branch(self): + self.system_repository.run_checked('git', 'branch', '--show-current') + return ''.join(self.system_repository.stdout).rstrip() + + def add_file(self, file_path: Path): + self.system_repository.run_checked('git', 'add', file_path) + return self.system_repository.stdout + + def commit(self, commit_message: str): + self.system_repository.run_checked( + 'git', 'commit', '-m', commit_message) + return self.system_repository.stdout + + def push(self): + self.system_repository.run_checked('git', 'push') + return self.system_repository.stdout + + def checkout(self, branch: str): + self.system_repository.run_checked('git', 'checkout', branch) + return self.system_repository.stdout diff --git a/test/test_infrastructure.py b/test/test_infrastructure.py index 6abf6ed..d7d28fd 100644 --- a/test/test_infrastructure.py +++ b/test/test_infrastructure.py @@ -1,3 +1,6 @@ +from domain import ReleaseType, Release +from infrastructure import GitRepository, VersionRepository, ReleaseRepository +from infrastructure_api import GitApi from pathlib import Path import sys import os @@ -5,20 +8,26 @@ import os # getting the name of the directory # where the this file is present. current = os.path.dirname(os.path.realpath(__file__)) - + # Getting the parent directory name # where the current directory is present. parent = os.path.dirname(current) - + # adding the parent directory to # the sys.path. sys.path.append(parent) - + # now we can import the module in the parent # directory. -from infrastructure import GitRepository, VersionRepository, ReleaseRepository -from domain import ReleaseType, Release + +def TestGitApi(GitApi): + def __init__(self, commit_string): + self.commit_string = commit_string + + def get_latest_commit(self): + return self.commit_string + def test_git_repository(): @@ -27,16 +36,15 @@ def test_git_repository(): repo = GitRepository.create_from_commit_string(commit_string) release_type = repo.get_release_type_from_latest_commit() - #test + # test assert release_type == ReleaseType.MAJOR - # init commit_string = "MINOR bla" repo = GitRepository.create_from_commit_string(commit_string) release_type = repo.get_release_type_from_latest_commit() - #test + # test assert release_type == ReleaseType.MINOR # init @@ -52,7 +60,7 @@ def test_git_repository(): repo = GitRepository.create_from_commit_string(commit_string) release_type = repo.get_release_type_from_latest_commit() - #test + # test assert release_type == ReleaseType.SNAPSHOT # init @@ -60,9 +68,10 @@ def test_git_repository(): repo = GitRepository.create_from_commit_string(commit_string) release_type = repo.get_release_type_from_latest_commit() - #test + # test assert release_type == None + def test_gradle(tmp_path): # init file_name = 'config.gradle' @@ -75,12 +84,13 @@ def test_gradle(tmp_path): # test repo = VersionRepository(f) version = repo.get_version() - version = version.create_release_version(ReleaseType.SNAPSHOT) + version = version.create_release_version(ReleaseType.SNAPSHOT) repo.write_file(version.get_version_string()) - + # check assert 'version = "12.4.678-SNAPSHOT"' in f.read_text() + def test_json(tmp_path): # init file_name = 'config.json' @@ -89,16 +99,17 @@ def test_json(tmp_path): f = tmp_path / file_name f.write_text(contents) - + # test repo = VersionRepository(f) version = repo.get_version() - version = version.create_release_version(ReleaseType.SNAPSHOT) + version = version.create_release_version(ReleaseType.SNAPSHOT) repo.write_file(version.get_version_string()) - + # check assert '"version": "123.123.456-SNAPSHOT"' in f.read_text() + def test_clojure(tmp_path): # init file_name = 'config.clj' @@ -113,10 +124,11 @@ def test_clojure(tmp_path): version = repo.get_version() version = version.create_release_version(ReleaseType.SNAPSHOT) repo.write_file(version.get_version_string()) - + # check assert '1.1.3-SNAPSHOT' in f.read_text() + def test_python(tmp_path): # init file_name = 'config.py' @@ -129,12 +141,13 @@ def test_python(tmp_path): # test repo = VersionRepository(f) version = repo.get_version() - version = version.create_release_version(ReleaseType.SNAPSHOT) + version = version.create_release_version(ReleaseType.SNAPSHOT) repo.write_file(version.get_version_string()) - + # check assert '3.1.3-SNAPSHOT' in f.read_text() + def test_release_repository(tmp_path): # init file_name = 'config.json' @@ -148,4 +161,4 @@ def test_release_repository(tmp_path): sut = ReleaseRepository(VersionRepository(f)) current_release = sut.get_current_release() - assert current_release.version is not None \ No newline at end of file + assert current_release.version is not None