Last active
July 10, 2024 23:34
-
-
Save welpo/f5563c3b82fe247ed0e473d940a005b7 to your computer and use it in GitHub Desktop.
git pre-commit script to update the date of Zola's posts and compress png files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Requires Bash 4.0 or newer. | |
# This script updates the 'updated' field in the front matter of modified .md | |
# files setting it to their last modified date. | |
# It also compresses PNG files with either oxipng or optipng if available. | |
# Function to exit the script with an error message. | |
function error_exit() { | |
echo "ERROR: $1" >&2 | |
exit "${2:-1}" | |
} | |
# Function to extract the date from the front matter. | |
function extract_date() { | |
local file="$1" | |
local field="$2" | |
grep -m 1 "^$field =" "$file" | sed -e "s/$field = //" -e 's/ *$//' | |
} | |
# Get the modified .md files, ignoring "_index.md" files. | |
mapfile -t modified_md_files < <(git diff --cached --name-only --diff-filter=M | grep -Ei '\.md$' | grep -v '_index.md$') | |
# Loop through each modified .md file. | |
for file in "${modified_md_files[@]}"; do | |
# Get the last modified date from the filesystem. | |
last_modified_date=$(date -r "$file" +'%Y-%m-%d') | |
# Extract the "date" field from the front matter. | |
date_value=$(extract_date "$file" "date") | |
# Skip the file if the last modified date is the same as the "date" field. | |
if [[ "$last_modified_date" == "$date_value" ]]; then | |
continue | |
fi | |
# Update the "updated" field with the last modified date. | |
# If the "updated" field doesn't exist, create it below the "date" field. | |
awk -v date_line="$last_modified_date" 'BEGIN{FS=OFS=" = "; first = 1} { if (/^date =/ && first) { print; getline; if (!/^updated =/) print "updated" OFS date_line; first=0 } if (/^updated =/ && !first) gsub(/[^ ]*$/, date_line, $2); print }' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file" || error_exit "Failed to update file $file" | |
# Stage the changes. | |
git add "$file" | |
done | |
# Check if oxipng or optipng are installed. | |
if command -v oxipng &> /dev/null; then | |
png_compressor="oxipng -o max" | |
elif command -v optipng &> /dev/null; then | |
png_compressor="optipng -o 7" | |
fi | |
# If either compressor is installed… | |
if [[ -n "$png_compressor" ]]; then | |
# Get the modified or added png files. | |
mapfile -t png_files < <(git diff --cached --name-only --diff-filter=d | grep -Ei '\.png$') | |
# Loop through each png file. | |
for file in "${png_files[@]}"; do | |
# Compress the png file. | |
$png_compressor -- "$file" || error_exit "Failed to compress file $file" | |
# Stage the changes. | |
git add -- "$file" | |
done | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For more context, see my blog post: Zola Git Pre-Commit Hook: Updating Post Dates.
This is a Git pre-commit script that updates the 'updated' field in the front matter of modified .md files to the last modified date and losslessly compresses modified PNG files using either oxipng or optipng (in that order of preference) if available. This script can be used with static site generators like Zola to keep your front matter up to date and optimise your images.
Whenever you commit markdown or PNG files in your Git repository (e.g. your Zola site), the script will automatically update any modified .md files to include the last modified date in the front matter 'updated' field, and it will compress any modified PNG files using the available PNG compressor (oxipng or optipng).
To use the script, copy and paste it into the
.git/hooks/pre-commit
file in your project's root directory. If the file doesn't exist, create it and make sure it's executable by runningchmod +x .git/hooks/pre-commit
.For a version without PNG compression, check out this gist which only updates the 'updated' field in the front matter of modified .md files.