Skip to content

Instantly share code, notes, and snippets.

@xmoforf
Created November 10, 2024 01:18
Show Gist options
  • Save xmoforf/2321721123f30f95df5410eab6cdeb30 to your computer and use it in GitHub Desktop.
Save xmoforf/2321721123f30f95df5410eab6cdeb30 to your computer and use it in GitHub Desktop.
check-updates.py
from contextlib import contextmanager
from datetime import datetime, timedelta
import os
import subprocess
import sys
from yaspin import yaspin
LAST_UPDATED_FILE = ".last_updated"
BRANCH = sys.argv[1]
@contextmanager
def spinner(text):
"""
Create a spinner context manager.
:param text: The text to display with the spinner.
:return: The spinner object.
"""
with yaspin(text=text, color="cyan") as spin:
yield spin
def update_last_checked(directory):
with open(os.path.join(directory, LAST_UPDATED_FILE), 'w') as f:
f.write(datetime.now().isoformat())
def check_last_updated(directory):
last_updated_path = os.path.join(directory, LAST_UPDATED_FILE)
if not os.path.exists(last_updated_path):
update_last_checked(directory)
return True
with open(last_updated_path, 'r') as f:
last_updated_str = f.read().strip()
try:
last_updated = datetime.fromisoformat(last_updated_str)
except ValueError:
update_last_checked(directory)
return True
if datetime.now() - last_updated >= timedelta(hours=24):
return True
return False
def is_git_repo(directory):
return subprocess.run(["git", "-C", directory, "rev-parse", "--is-inside-work-tree"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE).returncode == 0
def get_latest_tag_or_commit(directory):
result = subprocess.run(["git", "-C", directory, "describe", "--tags", "--always"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
return result.stdout.strip() if result.returncode == 0 else None
def fetch_updates(directory):
subprocess.run(["git", "-C", directory, "fetch"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def has_new_commits(directory):
result = subprocess.run(["git", "-C", directory, "rev-list", "--count", f"HEAD..origin/{BRANCH}"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
return int(result.stdout.strip()) > 0 if result.returncode == 0 else False
def reattach_head_to_main(directory):
subprocess.run(["git", "-C", directory, "checkout", BRANCH], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def prompt_update(directory):
print(f"New commits are available on the {BRANCH} branch.")
response = input("Do you want to update to the latest commit? (y/n): ").strip().lower()
if response == 'y':
reattach_head_to_main(directory)
subprocess.run(["git", "-C", directory, "pull", "origin", BRANCH])
print(f"Updated to the latest commit on branch '{BRANCH}'.")
update_last_checked(directory)
else:
print("Update skipped.")
def main():
directory = os.path.dirname(os.path.abspath(__file__))
if not check_last_updated(directory):
return
with spinner("Checking for updates") as spin:
if not is_git_repo(directory):
spin.write("This directory is not a Git repository.")
spin.fail("✘")
return
# Check if HEAD is detached and reattach if necessary
result = subprocess.run(["git", "-C", directory, "symbolic-ref", "--short", "HEAD"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode != 0:
spin.write(f"HEAD is detached. Reattaching to '{BRANCH}' branch.")
reattach_head_to_main(directory)
fetch_updates(directory)
spin.ok("✔")
if has_new_commits(directory):
prompt_update(directory)
else:
print(f"No new commits on branch '{BRANCH}'. Latest version: {get_latest_tag_or_commit(directory)}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment