Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions pre_commit_hooks/shellcheck_run_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import argparse
import contextlib
import json
import os
import subprocess
import tempfile
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
Expand Down Expand Up @@ -74,7 +77,49 @@ 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
subprocess.run(
["docker", "pull", image],
check=True,
capture_output=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:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

personally, I'd prefer once a day since we typically don't worry too much about backwards compat in melange changes. It might be cool to make this a config option.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, I was thinking to not pull too often and add extra check runtime, but perhaps a week default? I'll see if I can make it configurable in pre-commit somehow

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WFM. I suppose if we do become aware of breaking melange changes that are breaking pre-commit, we can push a pre-commit change that checks the melange container version and pulls if too old.

# Pull updated image
subprocess.run(
["docker", "pull", image],
check=True,
capture_output=True,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option would be to make this melange_image_outdated() check that returns True if the image is missing or out of date. We can use that to decide if we should add --pull always to the docker run command below. I think that would avoid having the 2 different docker pull code paths here.

Or, if we made it docker_image_outdated(img, age), we could re-use it for the shellcheck image as well!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooo I like that!

)

except Exception as e:
# 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:
# Check and update melange image if needed
check_and_update_melange_image(MelangeImage)

Comment on lines 119 to +122
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By performing this before the argument parser checking, the melange image check happens even if one does shellcheck_run_steps.py --help which might be unexpected or take a bit to show the help information.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, it could definitely run later!

parser = argparse.ArgumentParser()
parser.add_argument(
"filenames",
Expand Down
Loading