diff --git a/data/testing/0.9-alpha.1/meta-v1.json b/data/testing/0.9-alpha.1/meta-v1.json new file mode 100644 index 0000000..a7f21ae --- /dev/null +++ b/data/testing/0.9-alpha.1/meta-v1.json @@ -0,0 +1 @@ +{"label": "0.9-alpha.1", "id": 1, "timestamp": 1718613854, "file": "realweather-0.9-SNAPSHOT.jar", "sha256": "131f03c7f4407ee874f5a05419639fad8160a2975749916cdbbb185b62dd55c7"} \ No newline at end of file diff --git a/releases/0.9-alpha.1/realweather-0.9-SNAPSHOT.jar b/data/testing/0.9-alpha.1/realweather-0.9-SNAPSHOT.jar similarity index 100% rename from releases/0.9-alpha.1/realweather-0.9-SNAPSHOT.jar rename to data/testing/0.9-alpha.1/realweather-0.9-SNAPSHOT.jar diff --git a/data/testing/0.9-alpha.2/changelog.txt b/data/testing/0.9-alpha.2/changelog.txt new file mode 100644 index 0000000..bb09b88 --- /dev/null +++ b/data/testing/0.9-alpha.2/changelog.txt @@ -0,0 +1 @@ +no changes \ No newline at end of file diff --git a/data/testing/0.9-alpha.2/meta-v1.json b/data/testing/0.9-alpha.2/meta-v1.json new file mode 100644 index 0000000..8534252 --- /dev/null +++ b/data/testing/0.9-alpha.2/meta-v1.json @@ -0,0 +1 @@ +{"label": "0.9-alpha.2", "id": 2, "timestamp": 1718614497, "file": "realweather-0.9-SNAPSHOT.jar", "sha256": "131f03c7f4407ee874f5a05419639fad8160a2975749916cdbbb185b62dd55c7"} \ No newline at end of file diff --git a/data/testing/0.9-alpha.2/realweather-0.9-SNAPSHOT.jar b/data/testing/0.9-alpha.2/realweather-0.9-SNAPSHOT.jar new file mode 100644 index 0000000..05b2594 Binary files /dev/null and b/data/testing/0.9-alpha.2/realweather-0.9-SNAPSHOT.jar differ diff --git a/data/testing/latest/meta-v1.json b/data/testing/latest/meta-v1.json new file mode 100644 index 0000000..8534252 --- /dev/null +++ b/data/testing/latest/meta-v1.json @@ -0,0 +1 @@ +{"label": "0.9-alpha.2", "id": 2, "timestamp": 1718614497, "file": "realweather-0.9-SNAPSHOT.jar", "sha256": "131f03c7f4407ee874f5a05419639fad8160a2975749916cdbbb185b62dd55c7"} \ No newline at end of file diff --git a/latest/latest-v1.json b/latest/latest-v1.json deleted file mode 100644 index 31d6220..0000000 --- a/latest/latest-v1.json +++ /dev/null @@ -1 +0,0 @@ -{"label": "0.9-alpha.1", "id": 1, "timestamp": 1718539114, "file": "realweather-0.9-SNAPSHOT.jar"} \ No newline at end of file diff --git a/release.py b/release.py index a3352c5..637532c 100755 --- a/release.py +++ b/release.py @@ -1,20 +1,14 @@ #!/usr/bin/python3 -import json, os, time -from typing import Tuple +import json, os, time, tempfile, shutil +from hashlib import sha256 -meta_file_name = 'meta-v1.json' -latest_file_name = 'latest-v1.json' -latest_file_path = os.path.join('latest', latest_file_name) +META_FILENAME = 'meta-v1.json' +BASE_DIR = 'data' +WAITING_DIR = 'pending' +TEMP_DIR = tempfile.TemporaryDirectory() -def confirm(prompt: str) -> bool: - confirmed = input(prompt + ' (Y/N) ') - return confirmed.lower() == 'y' - -def load_latest_data() -> dict: - if os.path.isfile(latest_file_path): - return json.loads(open(latest_file_path).read()) - return {'id': 0} +# file scanner functions def match_name(filename: str, extension: str=None, exact_name: str=None): if exact_name is not None: @@ -23,7 +17,7 @@ def match_name(filename: str, extension: str=None, exact_name: str=None): return filename.lower().endswith(extension.lower()) return True -def scan_for_file(ask: bool=False, extension: str=None, exact_name: str=None) -> Tuple[str]: +def scan_for_file(ask: bool=False, extension: str=None, exact_name: str=None) -> tuple[str]: for file in os.scandir(): if file.is_dir(): continue if not match_name(file.name, extension, exact_name): continue @@ -35,7 +29,7 @@ def scan_for_file(ask: bool=False, extension: str=None, exact_name: str=None) -> return (file.path, file.name) return (None, None) -def wait_for_file(waiting_dir: str, extension: str=None, exact_name: str=None) -> Tuple[str]: +def wait_for_file(waiting_dir: str, extension: str=None) -> tuple[str]: print(f"Please put a {extension} file in {waiting_dir}") while True: files = [i for i in os.scandir(waiting_dir)] @@ -48,7 +42,7 @@ def wait_for_file(waiting_dir: str, extension: str=None, exact_name: str=None) - filepath = file.path filename = file.name - if match_name(filename, extension, exact_name): + if match_name(filename, extension): break else: os.remove(filepath) @@ -56,65 +50,123 @@ def wait_for_file(waiting_dir: str, extension: str=None, exact_name: str=None) - return (filepath, filename) -def write_metadata(metadata: dict): - dir = metadata['label'] +def just_find_file(name: str) -> tuple[str]: + spl = name.split('.') + extension = spl[-1] + exact_name = name[:-len(extension)-1] if len(spl) > 1 else None + + filepath, filename = scan_for_file(True, extension, exact_name) + if filepath is None: + try: + os.makedirs(WAITING_DIR, exist_ok=True) + filepath, filename = wait_for_file(WAITING_DIR, extension) + except KeyboardInterrupt: + os.rmdir(WAITING_DIR) + return + + if filepath is not None: + tpath = os.path.join(TEMP_DIR.name, filename) + shutil.move(filepath, tpath) + filepath = tpath + + return (filepath, filename) + +# directory util fnctions + +def make_path(channel: str, version: str=None, filename: str=None) -> str: + args = [channel, version, filename] + args = [i for i in args if i is not None] + return os.path.join(BASE_DIR, *args) + +def list_channels() -> list[str]: + return next(os.walk(BASE_DIR))[1] + +# verificatoin functions + +def channel_exists(channel: str) -> bool: + """Checks if channel exists""" + return os.path.isdir(make_path(channel)) + +def check_version_exists(version: str) -> str | None: + """ + Check if version exists in any channel. + If yes, returns that channel, otherwise None + """ + for channel in list_channels(): + if os.path.isdir(make_path(channel, version)): + return channel + +# metadata functions + +def load_latest_data(channel: str) -> dict: + path = make_path(channel, 'latest', META_FILENAME) + if os.path.isfile(path): + return json.loads(open(path).read()) + return {'id': 0} + +def write_metadata(channel: str, metadata: dict): + version = metadata['label'] metadata = json.dumps(metadata) - for filepath in [os.path.join('releases', dir, meta_file_name), latest_file_path]: - file = open(filepath, 'w') - file.write(metadata) - file.close() + for filepath in [make_path(channel, version, META_FILENAME), make_path(channel, 'latest', META_FILENAME)]: + with open(filepath, 'w') as file: + file.write(metadata) + +# other + +def confirm(prompt: str) -> bool: + confirmed = input(prompt + ' (Y/N) ') + return confirmed.lower() == 'y' + +def hash_file(filepath: str) -> str: + with open(filepath, 'rb') as file: + return sha256(file.read()).hexdigest() + +# main def main(): - latest_data = load_latest_data() - if latest_data['id'] > 0: - print(f"Current release: {latest_data['label']}") - print(f"Released {time.strftime('%d.%m.%Y %H:%M', time.localtime(latest_data['timestamp']))}") - print('') + channel = input('Channel? ({}) '.format(', '.join(list_channels()))) + if not channel_exists(channel): + print(f"Channel {channel} doesn't exist") + return version = input('New version? ') + exists_in = check_version_exists(version) + if exists_in is not None: + print(f"This version already exists in channel {exists_in}. Choose a different version.") + return - if os.path.isdir(version): - raise FileExistsError() - - filepath, filename = scan_for_file(ask=True, extension='jar') - - if filepath is None: - os.makedirs('pending', exist_ok=True) - try: - filepath, filename = wait_for_file('pending', 'jar') - except KeyboardInterrupt: - os.rmdir('pending') - return + jar_filepath, jar_filename = just_find_file('jar') changelog = confirm('Do you want to include a changelog?') if changelog: - cfilepath, cfilename = scan_for_file(ask=True, exact_name='changelog.txt') - if cfilepath is None: - try: - os.makedirs('pending', exist_ok=True) - cfilepath, cfilename = wait_for_file('pending', 'txt') - except KeyboardInterrupt: - os.rmdir('pending') - return + chlog_filepath, chlog_filename = just_find_file('changelog.txt') - version_dir = os.path.join('releases', version) + # + latest_data = load_latest_data(channel) + hash = hash_file(jar_filepath) + + version_dir = make_path(channel, version) + + os.makedirs(make_path(channel, 'latest'), exist_ok=True) os.mkdir(version_dir) - os.rename(filepath, os.path.join(version_dir, filename)) - if changelog: os.rename(cfilepath, os.path.join(version_dir, 'changelog.txt')) - - try: - os.rmdir('pending') - except FileNotFoundError: - pass + shutil.move(jar_filepath, os.path.join(version_dir, jar_filename)) + if changelog: shutil.move(chlog_filepath, os.path.join(version_dir, 'changelog.txt')) metadata = { 'label': version, 'id': latest_data['id'] + 1, 'timestamp': int(time.time()), - 'file': filename + 'file': jar_filename, + 'sha256': hash } - write_metadata(metadata) + + write_metadata(channel, metadata) + + try: + os.rmdir(WAITING_DIR) + except FileNotFoundError: + pass print("Done, don't forget to commit and push") diff --git a/releases/0.9-alpha.1/meta-v1.json b/releases/0.9-alpha.1/meta-v1.json deleted file mode 100644 index 31d6220..0000000 --- a/releases/0.9-alpha.1/meta-v1.json +++ /dev/null @@ -1 +0,0 @@ -{"label": "0.9-alpha.1", "id": 1, "timestamp": 1718539114, "file": "realweather-0.9-SNAPSHOT.jar"} \ No newline at end of file diff --git a/reset.py b/reset.py index c07b2e1..ff88b81 100755 --- a/reset.py +++ b/reset.py @@ -1,7 +1,10 @@ #!/usr/bin/python3 from shutil import rmtree -from os import remove, mkdir +from os import remove, mkdir, path + +BASE_DIR = 'data' +CHANNELS = ['release', 'testing'] confirmation = input('If you really want to delete all releases, type CONFIRM: ') @@ -9,8 +12,9 @@ if confirmation != 'CONFIRM': print('Cancelled') exit() -for dir in ['releases', 'latest']: - rmtree(dir) - mkdir(dir) +rmtree(BASE_DIR, ignore_errors=True) +mkdir(BASE_DIR) +for channel in CHANNELS: + mkdir(path.join(BASE_DIR, channel)) print('Reset complete')