From bd124204460c806d6561c7498e4faa53a132f9c2 Mon Sep 17 00:00:00 2001 From: Amber Arcadia Date: Thu, 26 Mar 2026 19:18:22 -0400 Subject: [PATCH 1/2] Add auto-update for melange image if older than 30 days Automatically checks the age of the local melange Docker image and pulls an updated version if it's older than 30 days. Gives users a 15-second window to abort with Ctrl+C before pulling. --- pre_commit_hooks/shellcheck_run_steps.py | 59 ++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/pre_commit_hooks/shellcheck_run_steps.py b/pre_commit_hooks/shellcheck_run_steps.py index 9b00aa1..862eeed 100644 --- a/pre_commit_hooks/shellcheck_run_steps.py +++ b/pre_commit_hooks/shellcheck_run_steps.py @@ -2,11 +2,16 @@ import argparse import contextlib +import json import os import subprocess +import sys import tempfile +import time from collections.abc import Mapping from collections.abc import Sequence +from datetime import datetime +from datetime import timezone from typing import Any import ruamel.yaml @@ -74,7 +79,61 @@ def do_shellcheck( return True +def check_and_update_melange_image(image: str) -> None: + """Check if melange image is older than 30 days and pull if needed.""" + try: + # Get image creation date + result = subprocess.run( + ["docker", "image", "inspect", image, "--format", "{{json .Created}}"], + capture_output=True, + text=True, + check=False, + ) + + if result.returncode != 0: + # Image doesn't exist locally, pull it + print( + f"Melange image not found locally, pulling {image}...", + file=sys.stderr, + ) + subprocess.run(["docker", "pull", image], check=True) + return + + # Parse the creation date + created_str = json.loads(result.stdout.strip()) + created_date = datetime.fromisoformat(created_str.replace("Z", "+00:00")) + now = datetime.now(timezone.utc) + age_days = (now - created_date).days + + if age_days > 30: + print( + f"⚠️ Melange image is {age_days} days old (created {created_date.strftime('%Y-%m-%d')})", + file=sys.stderr, + ) + print(f"⚠️ Pulling updated melange image: {image}", file=sys.stderr) + print( + "⚠️ Press Ctrl+C now to abort or wait 15 seconds to continue...", + file=sys.stderr, + ) + + # Give user 15 seconds to abort + time.sleep(15) + + print(f"Pulling {image}...", file=sys.stderr) + subprocess.run(["docker", "pull", image], check=True) + print("✓ Melange image updated successfully", file=sys.stderr) + + except KeyboardInterrupt: + print("\n⚠️ Update aborted by user, using existing image", file=sys.stderr) + except Exception as e: + print(f"Warning: Failed to check/update melange image: {e}", file=sys.stderr) + print("Continuing with existing image...", file=sys.stderr) + + def main(argv: Sequence[str] | None = None) -> int: + # Check and update melange image if needed + check_and_update_melange_image(MelangeImage) + parser = argparse.ArgumentParser() parser.add_argument( "filenames", From c10d026a9e17a2535c833285789d662c01a65b44 Mon Sep 17 00:00:00 2001 From: Amber Arcadia Date: Thu, 26 Mar 2026 21:19:32 -0400 Subject: [PATCH 2/2] Remove unused imports --- pre_commit_hooks/shellcheck_run_steps.py | 36 ++++++++---------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/pre_commit_hooks/shellcheck_run_steps.py b/pre_commit_hooks/shellcheck_run_steps.py index 862eeed..5d0e5e9 100644 --- a/pre_commit_hooks/shellcheck_run_steps.py +++ b/pre_commit_hooks/shellcheck_run_steps.py @@ -5,9 +5,7 @@ import json import os import subprocess -import sys import tempfile -import time from collections.abc import Mapping from collections.abc import Sequence from datetime import datetime @@ -92,11 +90,11 @@ def check_and_update_melange_image(image: str) -> None: if result.returncode != 0: # Image doesn't exist locally, pull it - print( - f"Melange image not found locally, pulling {image}...", - file=sys.stderr, + subprocess.run( + ["docker", "pull", image], + check=True, + capture_output=True, ) - subprocess.run(["docker", "pull", image], check=True) return # Parse the creation date @@ -106,28 +104,16 @@ def check_and_update_melange_image(image: str) -> None: age_days = (now - created_date).days if age_days > 30: - print( - f"⚠️ Melange image is {age_days} days old (created {created_date.strftime('%Y-%m-%d')})", - file=sys.stderr, + # Pull updated image + subprocess.run( + ["docker", "pull", image], + check=True, + capture_output=True, ) - print(f"⚠️ Pulling updated melange image: {image}", file=sys.stderr) - print( - "⚠️ Press Ctrl+C now to abort or wait 15 seconds to continue...", - file=sys.stderr, - ) - - # Give user 15 seconds to abort - time.sleep(15) - - print(f"Pulling {image}...", file=sys.stderr) - subprocess.run(["docker", "pull", image], check=True) - print("✓ Melange image updated successfully", file=sys.stderr) - except KeyboardInterrupt: - print("\n⚠️ Update aborted by user, using existing image", file=sys.stderr) except Exception as e: - print(f"Warning: Failed to check/update melange image: {e}", file=sys.stderr) - print("Continuing with existing image...", file=sys.stderr) + # Print warning to stdout (like epoch check does with echo) + print(f"Warning: Failed to check/update melange image: {e}") def main(argv: Sequence[str] | None = None) -> int: