This commit is contained in:
jerger 2023-02-24 10:46:43 +01:00
parent 0551fe6bfe
commit a09eaa7521
3 changed files with 118 additions and 97 deletions

View file

@ -1,5 +1,5 @@
from domain import Release, Version, ReleaseType from domain import Release, Version, ReleaseType
from infrastructure_api import FileHandler, SystemAPI from infrastructure_api import FileHandler, SystemAPI, GitApi
from pathlib import Path from pathlib import Path
class VersionRepository(): class VersionRepository():
@ -39,69 +39,19 @@ class ReleaseRepository():
pass pass
class ReleaseTypeRepository(): class ReleaseTypeRepository():
def __init__(self): def __init__(self, git_api, environment_api=None):
pass self.git_api = git_api
class GitRepository(): def get_release_type(self):
latest_commit = self.git_api.get_latest_commit()
def __init__(self): if ReleaseType.MAJOR.name in latest_commit.upper():
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():
return ReleaseType.MAJOR return ReleaseType.MAJOR
elif ReleaseType.MINOR.name in self.latest_commit.upper(): elif ReleaseType.MINOR.name in latest_commit.upper():
return ReleaseType.MINOR return ReleaseType.MINOR
elif ReleaseType.PATCH.name in self.latest_commit.upper(): elif ReleaseType.PATCH.name in latest_commit.upper():
return ReleaseType.PATCH return ReleaseType.PATCH
elif ReleaseType.SNAPSHOT.name in self.latest_commit.upper(): elif ReleaseType.SNAPSHOT.name in latest_commit.upper():
return ReleaseType.SNAPSHOT return ReleaseType.SNAPSHOT
else: else:
return None 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

View file

@ -1,8 +1,10 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from pathlib import Path
import json import json
import re import re
import subprocess as sub import subprocess as sub
class FileHandler(ABC): class FileHandler(ABC):
@classmethod @classmethod
@ -18,7 +20,8 @@ class FileHandler(ABC):
case '.py': case '.py':
file_handler = PythonFileHandler() file_handler = PythonFileHandler()
case _: 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_path = file_path
file_handler.config_file_type = config_file_type file_handler.config_file_type = config_file_type
@ -32,6 +35,7 @@ class FileHandler(ABC):
def write(self, version_string): def write(self, version_string):
pass pass
class JsonFileHandler(FileHandler): class JsonFileHandler(FileHandler):
def parse(self) -> tuple[list[int], bool]: def parse(self) -> tuple[list[int], bool]:
@ -64,7 +68,8 @@ class GradleFileHandler(FileHandler):
raise exception raise exception
version_line = version_line.group() 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: if version_string is None:
raise exception raise exception
@ -81,7 +86,8 @@ class GradleFileHandler(FileHandler):
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+') as gradle_file:
contents = gradle_file.read() 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.seek(0)
gradle_file.write(version_substitute) gradle_file.write(version_substitute)
gradle_file.truncate() gradle_file.truncate()
@ -98,7 +104,8 @@ class PythonFileHandler(FileHandler):
raise exception raise exception
version_line = version_line.group() 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: if version_string is None:
raise exception raise exception
@ -115,11 +122,13 @@ class PythonFileHandler(FileHandler):
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+') as python_file:
contents = python_file.read() 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.seek(0)
python_file.write(version_substitute) python_file.write(version_substitute)
python_file.truncate() python_file.truncate()
class ClojureFileHandler(FileHandler): class ClojureFileHandler(FileHandler):
def parse(self) -> tuple[list[int], bool]: def parse(self) -> tuple[list[int], bool]:
@ -131,7 +140,8 @@ class ClojureFileHandler(FileHandler):
raise exception raise exception
version_line = version_line.group() 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: if version_string is None:
raise exception raise exception
@ -149,12 +159,14 @@ class ClojureFileHandler(FileHandler):
with open(self.config_file_path, 'r+') as clj_file: with open(self.config_file_path, 'r+') 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('[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.seek(0)
clj_file.write(version_substitute) clj_file.write(version_substitute)
clj_file.write(clj_rest) clj_file.write(clj_rest)
clj_file.truncate() clj_file.truncate()
class SystemAPI(): class SystemAPI():
def __init__(self): def __init__(self):
@ -175,3 +187,49 @@ class SystemAPI():
if len(self.stderr) > 0: if len(self.stderr) > 0:
raise Exception(f"Command failed with: {self.stderr}") 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

View file

@ -1,3 +1,6 @@
from domain import ReleaseType, Release
from infrastructure import GitRepository, VersionRepository, ReleaseRepository
from infrastructure_api import GitApi
from pathlib import Path from pathlib import Path
import sys import sys
import os import os
@ -17,8 +20,14 @@ sys.path.append(parent)
# now we can import the module in the parent # now we can import the module in the parent
# directory. # 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(): def test_git_repository():
@ -27,16 +36,15 @@ def test_git_repository():
repo = GitRepository.create_from_commit_string(commit_string) repo = GitRepository.create_from_commit_string(commit_string)
release_type = repo.get_release_type_from_latest_commit() release_type = repo.get_release_type_from_latest_commit()
#test # test
assert release_type == ReleaseType.MAJOR assert release_type == ReleaseType.MAJOR
# init # init
commit_string = "MINOR bla" commit_string = "MINOR bla"
repo = GitRepository.create_from_commit_string(commit_string) repo = GitRepository.create_from_commit_string(commit_string)
release_type = repo.get_release_type_from_latest_commit() release_type = repo.get_release_type_from_latest_commit()
#test # test
assert release_type == ReleaseType.MINOR assert release_type == ReleaseType.MINOR
# init # init
@ -52,7 +60,7 @@ def test_git_repository():
repo = GitRepository.create_from_commit_string(commit_string) repo = GitRepository.create_from_commit_string(commit_string)
release_type = repo.get_release_type_from_latest_commit() release_type = repo.get_release_type_from_latest_commit()
#test # test
assert release_type == ReleaseType.SNAPSHOT assert release_type == ReleaseType.SNAPSHOT
# init # init
@ -60,9 +68,10 @@ def test_git_repository():
repo = GitRepository.create_from_commit_string(commit_string) repo = GitRepository.create_from_commit_string(commit_string)
release_type = repo.get_release_type_from_latest_commit() release_type = repo.get_release_type_from_latest_commit()
#test # test
assert release_type == None assert release_type == None
def test_gradle(tmp_path): def test_gradle(tmp_path):
# init # init
file_name = 'config.gradle' file_name = 'config.gradle'
@ -81,6 +90,7 @@ def test_gradle(tmp_path):
# check # check
assert 'version = "12.4.678-SNAPSHOT"' in f.read_text() assert 'version = "12.4.678-SNAPSHOT"' in f.read_text()
def test_json(tmp_path): def test_json(tmp_path):
# init # init
file_name = 'config.json' file_name = 'config.json'
@ -99,6 +109,7 @@ def test_json(tmp_path):
# check # check
assert '"version": "123.123.456-SNAPSHOT"' in f.read_text() assert '"version": "123.123.456-SNAPSHOT"' in f.read_text()
def test_clojure(tmp_path): def test_clojure(tmp_path):
# init # init
file_name = 'config.clj' file_name = 'config.clj'
@ -117,6 +128,7 @@ def test_clojure(tmp_path):
# check # check
assert '1.1.3-SNAPSHOT' in f.read_text() assert '1.1.3-SNAPSHOT' in f.read_text()
def test_python(tmp_path): def test_python(tmp_path):
# init # init
file_name = 'config.py' file_name = 'config.py'
@ -135,6 +147,7 @@ def test_python(tmp_path):
# check # check
assert '3.1.3-SNAPSHOT' in f.read_text() assert '3.1.3-SNAPSHOT' in f.read_text()
def test_release_repository(tmp_path): def test_release_repository(tmp_path):
# init # init
file_name = 'config.json' file_name = 'config.json'