from abc import ABC, abstractmethod import json import re class FileHandler(ABC): @classmethod def from_file_path(cls, file_path): config_file_type = file_path.suffix match config_file_type: case '.json': file_handler = JsonFileHandler() case '.gradle': file_handler = GradleFileHandler() case '.clj': file_handler = ClojureFileHandler() case '.py': file_handler = PythonFileHandler() case _: 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 return file_handler @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]: with open(self.config_file_path, 'r') as json_file: json_version = json.load(json_file)['version'] is_snapshot = False if '-SNAPSHOT' in json_version: is_snapshot = True json_version = json_version.replace('-SNAPSHOT', '') version = [int(x) for x in json_version.split('.')] return version, is_snapshot def write(self, version_string): 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.dump(json_data, json_file, indent=4) json_file.truncate() class GradleFileHandler(FileHandler): def parse(self) -> tuple[list[int], bool]: 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") 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) if version_string is None: raise exception version_string = version_string.group() is_snapshot = False if '-SNAPSHOT' in version_string: is_snapshot = True version_string = version_string.replace('-SNAPSHOT', '') version = [int(x) for x in version_string.split('.')] return version, is_snapshot 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) gradle_file.seek(0) gradle_file.write(version_substitute) gradle_file.truncate() class PythonFileHandler(FileHandler): def parse(self) -> tuple[list[int], bool]: 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") 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) if version_string is None: raise exception version_string = version_string.group() is_snapshot = False if '-SNAPSHOT' in version_string: is_snapshot = True version_string = version_string.replace('-SNAPSHOT', '') version = [int(x) for x in version_string.split('.')] return version, is_snapshot 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) 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") 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) if version_string is None: raise exception version_string = version_string.group() is_snapshot = False if '-SNAPSHOT' in version_string: is_snapshot = True version_string = version_string.replace('-SNAPSHOT', '') version = [int(x) for x in version_string.split('.')] return version, is_snapshot def write(self, version_string): 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) clj_file.seek(0) clj_file.write(version_substitute) clj_file.write(clj_rest) clj_file.truncate()