#!/usr/bin/env bash # sign_posts.sh — Sign Hugo posts and insert a signature shortcode. # Usage: # ./scripts/sign_posts.sh -k "you@example.com" # Options: # -k, --key KeyID or email for gpg --local-user (optional; default = gpg default key) # -c, --content Content dir (default: content) # -i, --include Comma-separated subdirs under content to process (default: posts,PhD_journey) # -n, --dry-run Show actions without changing files set -euo pipefail KEYID="55A2A5DE84792BACC6CAEE3FB5882850E04C8D2A" CONTENT_DIR="content" INCLUDE_DIRS=("posts" "PhD_journey" "about") DRYRUN=0 usage() { sed -n '2,30p' "$0" | sed 's/^# \{0,1\}//' } while [[ $# -gt 0 ]]; do case "$1" in -k|--key) KEYID="${2:-}"; shift 2 ;; -c|--content) CONTENT_DIR="${2:-}"; shift 2 ;; -i|--include) IFS=',' read -r -a INCLUDE_DIRS <<< "${2:-}"; shift 2 ;; -n|--dry-run) DRYRUN=1; shift ;; -h|--help) usage; exit 0 ;; *) echo "Unknown arg: $1"; usage; exit 1 ;; esac done command -v gpg >/dev/null 2>&1 || { echo "gpg not found in PATH"; exit 1; } # Ensure shortcode exists (don’t overwrite if user customized it) SHORTCODE_PATH="layouts/shortcodes/sig.html" if [[ ! -f "$SHORTCODE_PATH" ]]; then echo "Creating $SHORTCODE_PATH" [[ $DRYRUN -eq 1 ]] || mkdir -p "$(dirname "$SHORTCODE_PATH")" [[ $DRYRUN -eq 1 ]] || cat > "$SHORTCODE_PATH" <<'EOF' {{- /* Usage: {{< sig >}} or {{< sig "name.asc" >}}. Reads from .Page.File.Dir */ -}} {{- $name := .Get 0 | default "signature.asc" -}} {{- $dir := .Page.File.Dir -}} {{- $sig := readFile (print $dir $name) | htmlEscape -}}
OpenPGP signature (.asc)
{{$sig}}

Verify: gpg --verify {{ $name }} {{ .Page.File.Path }}

EOF fi add_shortcode_if_missing() { local md="$1" local asc_basename="$2" # just the filename, not path if grep -q '{{< *sig' "$md"; then return 0 fi echo " + inserting shortcode into: $md" if [[ $DRYRUN -eq 0 ]]; then { printf "\n\n---\n\n{{< sig \"%s\" >}}\n" "$asc_basename" } >> "$md" fi } sign_file() { local md="$1" local asc="$2" echo " + signing -> $asc" if [[ $DRYRUN -eq 1 ]]; then return 0 fi if [[ -n "$KEYID" ]]; then gpg --batch --yes --local-user "$KEYID" --detach-sign --armor -o "$asc" "$md" else gpg --batch --yes --detach-sign --armor -o "$asc" "$md" fi } TOTAL=0 SIGNED=0 INSERTED=0 for sub in "${INCLUDE_DIRS[@]}"; do ROOT="$CONTENT_DIR/$sub" [[ -d "$ROOT" ]] || { echo "Skipping missing dir: $ROOT"; continue; } while IFS= read -r -d '' md; do TOTAL=$((TOTAL+1)) dir="$(dirname "$md")" base="$(basename "$md" .md)" asc="$dir/$base.asc" asc_base="$(basename "$asc")" echo "Processing: $md" if ! grep -q '{{< *sig' "$md"; then INSERTED=$((INSERTED+1)) add_shortcode_if_missing "$md" "$asc_base" else echo " = shortcode already present" fi sign_file "$md" "$asc" SIGNED=$((SIGNED+1)) done < <(find "$ROOT" -type f -name '*.md' -print0) done echo "Done. Files seen: $TOTAL, signatures written: $SIGNED, shortcodes inserted: $INSERTED." [[ $DRYRUN -eq 1 ]] && echo "(dry run; no files changed)"