|
| 1 | +#!/usr/bin/env python3 |
| 2 | + |
| 3 | +# Purpose: |
| 4 | +# |
| 5 | +# - updates the version file "layouts/partials/version.txt" with the latest |
| 6 | +# available commit hash after committing |
| 7 | +# |
| 8 | +# Installation: |
| 9 | +# |
| 10 | +# Call this script from your ".git/hooks/post-commit" file like this (supporting |
| 11 | +# Linux, Windows and MacOS) |
| 12 | +# |
| 13 | +# ```sh |
| 14 | +# #!/bin/sh |
| 15 | +# python3 .githooks/post-commit.py |
| 16 | +# ``` |
| 17 | + |
| 18 | +from datetime import datetime |
| 19 | +import os |
| 20 | +import re |
| 21 | +import subprocess |
| 22 | + |
| 23 | +def is_special_git_operation(): |
| 24 | + git_dir = subprocess.check_output(['git', 'rev-parse', '--git-dir'], universal_newlines=True).strip() |
| 25 | + indicators = [ |
| 26 | + os.path.join(git_dir, 'rebase-merge'), |
| 27 | + os.path.join(git_dir, 'rebase-apply'), |
| 28 | + os.path.join(git_dir, 'CHERRY_PICK_HEAD'), |
| 29 | + os.path.join(git_dir, 'MERGE_HEAD'), |
| 30 | + os.path.join(git_dir, 'BISECT_LOG'), |
| 31 | + os.path.join(git_dir, 'REVERT_HEAD'), |
| 32 | + ] |
| 33 | + return any(os.path.exists(ind) for ind in indicators) |
| 34 | + |
| 35 | +def update_version(script_name, log_file, time, repo_name): |
| 36 | + if is_special_git_operation(): |
| 37 | + print(f'{time}: {repo_name} - {script_name} - Skipping during rebase/cherry-pick/merge', file=open(log_file, "a")) |
| 38 | + return |
| 39 | + |
| 40 | + file_path = 'layouts/partials/version.txt' |
| 41 | + try: |
| 42 | + f = open(file_path, 'r+') |
| 43 | + except OSError as e: |
| 44 | + print(f'{time}: {repo_name} - {script_name} - Could not open {file_path}: [{e.errno}] {e.strerror}', file=open(log_file, "a")) |
| 45 | + print(f'{script_name} - Could not open {file_path}: [{e.errno}] {e.strerror}') |
| 46 | + exit(1) |
| 47 | + |
| 48 | + with f: |
| 49 | + version = f.read().strip() |
| 50 | + new_version = '' |
| 51 | + match = re.match(r'(\d+\.\d+\.\d+)(?:\+([^+]+))?', version) |
| 52 | + if match: |
| 53 | + semver = match.group(1) |
| 54 | + old_hash = match.group(2) |
| 55 | + new_hash = subprocess.check_output(['git', 'rev-parse', 'HEAD~1']).decode('utf-8').strip() |
| 56 | + print(f'{time}: {repo_name} - {script_name} - old hash {old_hash} - new hash {new_hash}', file=open(log_file, "a")) |
| 57 | + if old_hash != new_hash: |
| 58 | + new_version = f'{semver}+{new_hash}' |
| 59 | + f.seek(0) |
| 60 | + f.write(new_version) |
| 61 | + f.truncate() |
| 62 | + f.close() |
| 63 | + subprocess.check_call(['git', 'add', file_path]) |
| 64 | + subprocess.check_call(['git', 'commit', '--amend', '--no-edit']) |
| 65 | + print(f'{time}: {repo_name} - {script_name} - New version {new_version} was written to {file_path}', file=open(log_file, "a")) |
| 66 | + else: |
| 67 | + print(f'{time}: {repo_name} - {script_name} - No change in hash, file {file_path} not updated', file=open(log_file, "a")) |
| 68 | + else: |
| 69 | + print(f'{time}: {repo_name} - {script_name} - Invalid version format in {file_path}', file=open(log_file, "a")) |
| 70 | + print(f'{script_name} - Invalid version format in {file_path}') |
| 71 | + exit(1) |
| 72 | + |
| 73 | +def main(): |
| 74 | + script_name = "POST-COMMIT" |
| 75 | + script_dir = os.path.dirname(os.path.abspath(__file__)) |
| 76 | + log_file = os.path.join(script_dir, "hooks.log") |
| 77 | + time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
| 78 | + repo_root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'], universal_newlines=True).strip() |
| 79 | + repo_name = os.path.basename(repo_root) |
| 80 | + |
| 81 | + update_version(script_name, log_file, time, repo_name) |
| 82 | + exit(0) |
| 83 | + |
| 84 | +if __name__ == "__main__": |
| 85 | + main() |
0 commit comments