From 22d8ae6b8aecac19500b70488f3d8f269b7f0e96 Mon Sep 17 00:00:00 2001
From: welpo <welpo@users.noreply.github.com>
Date: Wed, 16 Aug 2023 00:11:38 +0200
Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A8=20feat:=20add=20pre-commit=20hook?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Updates the `updated` date of posts.

- Compresses PNG files.

- Creates font subsets.

- Updates multilanguage-related lines in README.md.
---
 .githooks/pre-commit | 138 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)
 create mode 100755 .githooks/pre-commit

diff --git a/.githooks/pre-commit b/.githooks/pre-commit
new file mode 100755
index 0000000..7f6718a
--- /dev/null
+++ b/.githooks/pre-commit
@@ -0,0 +1,138 @@
+#!/usr/bin/env bash
+
+#################################################################################
+# This script is run by git before a commit is made.                            #
+# Does some housekeeping tasks before a commit is made.                         #
+#                                                                               #
+#                                   FEATURES                                    #
+# Updates the "updated" field in the front matter of .md files.                 #
+# Compresses PNG files with either oxipng or optipng if available.              #
+# Runs subset_font if config.toml has been modified.                            #
+# Updates the README if the line numbers for the language section have changed. #
+#################################################################################
+
+# 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/ *$//'
+}
+
+##################################################################
+# Compress PNG files with either oxipng or optipng if available. #
+# Update the "updated" field in the front matter of .md files.   #
+#          https://osc.garden/blog/zola-date-git-hook/           #
+##################################################################
+
+# Check if oxipng is installed.
+png_compressor=""
+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
+
+# Get the modified .md and .png files, ignoring "_index.md" files.
+modified_files=$(git diff --cached --name-only --diff-filter=M | grep -E '\.(md|png)$' | grep -v '_index.md$')
+
+# Loop through each modified .md or .png file.
+for file in $modified_files; do
+    # If the file is a PNG and png_compressor is set, compress it and add it to the commit.
+    if [[ "$file" == *.png ]] && [[ -n "$png_compressor" ]]; then
+        $png_compressor "$file" || error_exit "Failed to compress PNG file $file"
+        git add --force "$file" || error_exit "Failed to add compressed PNG file $file"
+        continue
+    fi
+
+    # If the file is an .md file, update the "updated" field in the front matter.
+    if [[ "$file" == *.md ]]; then
+        # 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.
+        if ! 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"
+        then
+            error_exit "Failed to process $file with AWK"
+        fi
+
+        mv "${file}.tmp" "$file" || error_exit "Failed to overwrite $file with updated content"
+
+
+        # Stage the changes.
+        git add "$file"
+    fi
+done
+
+#########################################################
+# Run subset_font if config.toml has been modified.     #
+# https://welpo.github.io/tabi/blog/custom-font-subset/ #
+#########################################################
+if git diff --cached --name-only | grep -q "config.toml"; then
+    echo "config.toml modified. Running subset_font…"
+
+    # Call the subset_font script.
+    ~/bin/subset_font -c config.toml -f static/fonts/Inter4.woff2 -o static/
+
+    # Add the generated subset.css file to the commit.
+    git add static/custom_subset.css
+fi
+
+################################################################################
+# Update the README if the line numbers for the language section have changed. #
+################################################################################
+
+# File paths and names.
+config_file="config.toml"
+config_readme="README.md"
+
+# Ensure the required files are present.
+[ ! -f "$config_file" ] && error_exit "$config_file not found!"
+[ ! -f "$config_readme" ] && error_exit "$config_readme not found!"
+
+# Determine the line numbers for relevant sections in config.toml.
+lang_start_line=$(grep -n "^\[languages.es\]$" "$config_file" | cut -d: -f1)
+extra_start_line=$(grep -n "^\[extra\]$" "$config_file" | cut -d: -f1)
+lang_end_line=$((extra_start_line - 2))
+
+# Extract currently documented line numbers from README.
+documented_lines=$(grep -o 'https://github.com/welpo/tabi/blob/main/config.toml#L[0-9]*-L[0-9]*' "$config_readme" | grep -o 'L[0-9]*-L[0-9]*')
+doc_start_line=$(echo "$documented_lines" | cut -d'-' -f1 | tr -d 'L')
+doc_end_line=$(echo "$documented_lines" | cut -d'-' -f2 | tr -d 'L')
+
+# Ensure that the variables are set and are numbers.
+if [[ ! $lang_start_line =~ ^[0-9]+$ ]] || [[ ! $doc_start_line =~ ^[0-9]+$ ]] || [[ ! $lang_end_line =~ ^[0-9]+$ ]] || [[ ! $doc_end_line =~ ^[0-9]+$ ]]; then
+    error_exit "Line number variables are not set correctly."
+fi
+
+# Update the README if there's a discrepancy in the line numbers.
+if [ "$lang_start_line" -ne "$doc_start_line" ] || [ "$lang_end_line" -ne "$doc_end_line" ]; then
+    if ! perl -pi -e "s|https://github.com/welpo/tabi/blob/main/config.toml#L[0-9]*-L[0-9]*|https://github.com/welpo/tabi/blob/main/config.toml#L$lang_start_line-L$lang_end_line|g" "$config_readme"; then
+        error_exit "Perl processing failed for $config_readme"
+    fi
+    
+    # Add updated README to commit.
+    git add "$config_readme"
+fi