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 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

View file

@ -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

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
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
assert current_release.version is not None