133 lines
3.4 KiB
Bash
133 lines
3.4 KiB
Bash
#!/usr/bin/env bash
|
||
# Changelog sync guard:比较 Godot 源码/配置与本会话起点、changelog 的 mtime。
|
||
|
||
emit_empty() {
|
||
printf '{}\n'
|
||
}
|
||
|
||
cat >/dev/null
|
||
|
||
if [ -n "${CURSOR_SKIP_CHANGELOG:-}" ]; then
|
||
emit_empty
|
||
exit 0
|
||
fi
|
||
|
||
script_dir=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)
|
||
cursor_dir=$(dirname -- "$script_dir")
|
||
repo_root=$(dirname -- "$cursor_dir")
|
||
changelog="$cursor_dir/changelog/changelog-headlines.md"
|
||
ack_file="$cursor_dir/changelog/.changelog-ack"
|
||
session_marker="$cursor_dir/changelog/.session-start"
|
||
|
||
if [ ! -f "$changelog" ]; then
|
||
emit_empty
|
||
exit 0
|
||
fi
|
||
|
||
get_mtime() {
|
||
stat -c %Y "$1" 2>/dev/null || stat -f %m "$1" 2>/dev/null
|
||
}
|
||
|
||
if [ -f "$ack_file" ]; then
|
||
changelog_mtime=$(get_mtime "$changelog")
|
||
ack_mtime=$(get_mtime "$ack_file")
|
||
if [ -n "$changelog_mtime" ] && [ -n "$ack_mtime" ] &&
|
||
[ "$ack_mtime" -ge "$changelog_mtime" ] 2>/dev/null; then
|
||
emit_empty
|
||
exit 0
|
||
fi
|
||
fi
|
||
|
||
comparison_file=$changelog
|
||
if [ -f "$session_marker" ]; then
|
||
changelog_mtime=$(get_mtime "$changelog")
|
||
session_mtime=$(get_mtime "$session_marker")
|
||
if [ -n "$changelog_mtime" ] && [ -n "$session_mtime" ] &&
|
||
[ "$session_mtime" -gt "$changelog_mtime" ] 2>/dev/null; then
|
||
comparison_file=$session_marker
|
||
fi
|
||
fi
|
||
|
||
newer_file=''
|
||
while IFS= read -r candidate; do
|
||
newer_file=$candidate
|
||
break
|
||
done < <(
|
||
find "$repo_root" \
|
||
\( -type d \( \
|
||
-name '.git' -o \
|
||
-name '.cursor' -o \
|
||
-name '.godot' -o \
|
||
-name 'node_modules' -o \
|
||
-name '__pycache__' -o \
|
||
-name 'venv' -o \
|
||
-name '.venv' -o \
|
||
-name 'dist' -o \
|
||
-name 'build' -o \
|
||
-name 'out' -o \
|
||
-name 'bin' -o \
|
||
-name 'obj' -o \
|
||
-name 'export' -o \
|
||
-name 'exports' -o \
|
||
-name 'coverage' -o \
|
||
-name 'tmp' -o \
|
||
-name 'temp' \
|
||
\) -prune \) -o \
|
||
\( -type f \( \
|
||
-iname 'project.godot' -o \
|
||
-iname '*.gd' -o \
|
||
-iname '*.tscn' -o \
|
||
-iname '*.tres' -o \
|
||
-iname '*.res' -o \
|
||
-iname '*.gdshader' -o \
|
||
-iname '*.cfg' -o \
|
||
-iname '*.json' -o \
|
||
-iname '*.cs' -o \
|
||
-iname '*.csproj' -o \
|
||
-iname '*.py' -o \
|
||
-iname '*.ps1' -o \
|
||
-iname '*.sh' \
|
||
\) -newer "$comparison_file" -print \) 2>/dev/null
|
||
)
|
||
|
||
if [ -z "$newer_file" ]; then
|
||
emit_empty
|
||
exit 0
|
||
fi
|
||
|
||
relative_file=${newer_file#"$repo_root"/}
|
||
message="[Hook] Godot source/config is newer than the changelog (e.g. $relative_file). Run dev-changelog Skill operation A now: add a fragment under .cursor/changelog/entries/ and rebuild the changelog views."
|
||
|
||
python_cmd=''
|
||
for candidate in python3 python; do
|
||
if command -v "$candidate" >/dev/null 2>&1 &&
|
||
"$candidate" -c 'import json' >/dev/null 2>&1; then
|
||
python_cmd=$candidate
|
||
break
|
||
fi
|
||
done
|
||
|
||
if [ -n "$python_cmd" ]; then
|
||
result=$(
|
||
printf '%s' "$message" | "$python_cmd" -c '
|
||
import json
|
||
import sys
|
||
|
||
print(json.dumps(
|
||
{"followup_message": sys.stdin.read()},
|
||
ensure_ascii=False,
|
||
separators=(",", ":"),
|
||
))
|
||
' 2>/dev/null
|
||
) || result='{}'
|
||
if [ -n "$result" ]; then
|
||
printf '%s\n' "$result"
|
||
else
|
||
emit_empty
|
||
fi
|
||
else
|
||
emit_empty
|
||
fi
|
||
|
||
exit 0
|