113 lines
3.2 KiB
Bash
Executable file
113 lines
3.2 KiB
Bash
Executable file
#!/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 -}}
|
||
<details class="signature">
|
||
<summary>OpenPGP signature (.asc)</summary>
|
||
<pre style="font-size:0.85em; overflow-x:auto; padding:0.75rem;">{{$sig}}</pre>
|
||
</details>
|
||
<p><em>Verify:</em> <code>gpg --verify {{ $name }} {{ .Page.File.Path }}</code></p>
|
||
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)"
|
||
|