334 lines
9.7 KiB
Bash
Executable File
334 lines
9.7 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
die() {
|
|
echo "Error: $1" >&2
|
|
exit 1
|
|
}
|
|
|
|
script_dir=$(CDPATH="" cd -- "$(dirname -- "$0")" && pwd)
|
|
awk_dir="$script_dir/awk"
|
|
|
|
KEWT_TMPDIR=$(mktemp -d "/tmp/kewt_run.XXXXXX")
|
|
trap 'rm -rf "$KEWT_TMPDIR"' EXIT
|
|
trap 'exit 0' HUP INT TERM
|
|
|
|
. "$script_dir/lib/config.sh"
|
|
. "$script_dir/lib/commands.sh"
|
|
. "$script_dir/lib/generator.sh"
|
|
. "$script_dir/lib/builder.sh"
|
|
|
|
src=""
|
|
out=""
|
|
new_mode="false"
|
|
new_title=""
|
|
clean_mode="true"
|
|
post_mode="false"
|
|
post_title=""
|
|
positional_count=0
|
|
watch_mode="false"
|
|
serve_mode="false"
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--help|-h)
|
|
usage
|
|
exit 0
|
|
;;
|
|
--new|--init)
|
|
new_mode="true"
|
|
if [ $# -gt 1 ] && [ "${2#-}" = "$2" ]; then
|
|
new_title="$2"
|
|
shift
|
|
fi
|
|
;;
|
|
--no-clean)
|
|
clean_mode="false"
|
|
;;
|
|
--clean)
|
|
clean_mode="true"
|
|
;;
|
|
--version|-v)
|
|
echo "kewt version git"
|
|
exit 0
|
|
;;
|
|
--dump-zsh-completions)
|
|
cat <<'EOFCOMPS'
|
|
#compdef kewt
|
|
_kewt() {
|
|
local -a args
|
|
args=(
|
|
'--help[Show help message]'
|
|
'(-h)--help[Show help message]'
|
|
'(-)--new[Create a new site directory]'
|
|
'(-)--init[Create a new site directory (alias for --new)]'
|
|
'(-)--clean[Clean the output directory before building]'
|
|
'(-)--no-clean[Do not clean the output directory before building]'
|
|
'(-)--update[Update site.conf and template.html with latest defaults]'
|
|
'(-)--post[Create a new empty post file in the configured posts_dir]'
|
|
'(-)--generate-template[Generate a new template file]'
|
|
'(-v --version)'{-v,--version}'[Show version information]'
|
|
'--from[Source directory]:directory:_directories'
|
|
'--to[Output directory]:directory:_directories'
|
|
'(-w --watch)'{-w,--watch}'[Watch for file changes and rebuild automatically]'
|
|
'(-s --serve)'{-s,--serve}'[Start a local HTTP server after building]::port:'
|
|
)
|
|
|
|
_arguments -S -C $args '*: :_directories'
|
|
}
|
|
|
|
_kewt "$@"
|
|
EOFCOMPS
|
|
exit 0
|
|
;;
|
|
--post)
|
|
post_mode="true"
|
|
if [ $# -gt 1 ] && [ "${2#-}" = "$2" ]; then
|
|
post_title="$2"
|
|
shift
|
|
fi
|
|
;;
|
|
--generate-template)
|
|
generate_template_path="template.html"
|
|
if [ $# -gt 1 ] && [ "${2#-}" = "$2" ]; then
|
|
generate_template_path="$2"
|
|
shift
|
|
fi
|
|
generate_template "$generate_template_path"
|
|
;;
|
|
--update)
|
|
update_dir="."
|
|
if [ $# -gt 1 ] && [ "${2#-}" = "$2" ]; then
|
|
update_dir="$2"
|
|
shift
|
|
fi
|
|
update_site "$update_dir"
|
|
;;
|
|
--from)
|
|
[ $# -lt 2 ] && die "--from requires a value."
|
|
src="$2"
|
|
shift
|
|
;;
|
|
--to)
|
|
[ $# -lt 2 ] && die "--to requires a value."
|
|
out="$2"
|
|
shift
|
|
;;
|
|
--watch|-w)
|
|
watch_mode="true"
|
|
;;
|
|
--serve|-s)
|
|
serve_mode="true"
|
|
if [ $# -ge 2 ] && echo "$2" | grep -qE '^[0-9]+$'; then
|
|
serve_port="$2"
|
|
shift
|
|
fi
|
|
;;
|
|
--*)
|
|
die "Unknown option: $1"
|
|
;;
|
|
*)
|
|
positional_count=$((positional_count + 1))
|
|
if [ "$positional_count" -eq 1 ]; then
|
|
if [ -z "$src" ]; then src="$1"; else die "Source already set (use either positional or --from)."; fi
|
|
elif [ "$positional_count" -eq 2 ]; then
|
|
if [ -z "$out" ]; then out="$1"; else die "Output already set (use either positional or --to)."; fi
|
|
else
|
|
die "Too many positional arguments."
|
|
fi
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
[ "$new_mode" = "true" ] && create_new_site "$new_title"
|
|
|
|
if [ -z "$src" ]; then
|
|
if [ "$post_mode" = "true" ] && [ -f "./site.conf" ]; then
|
|
src="."
|
|
else
|
|
src="site"
|
|
fi
|
|
fi
|
|
[ -z "$out" ] && out="out"
|
|
|
|
src="${src%/}"
|
|
out="${out%/}"
|
|
|
|
if [ ! -d "$src" ]; then
|
|
if [ "$src" = "site" ]; then
|
|
usage
|
|
exit 1
|
|
else
|
|
die "Source directory '$src' does not exist."
|
|
fi
|
|
fi
|
|
|
|
IGNORE_ARGS="-name '.kewtignore' -o -path '$src/.*'"
|
|
|
|
if [ -f "$src/.kewtignore" ]; then
|
|
while IFS= read -r line || [ -n "$line" ]; do
|
|
case "$line" in
|
|
''|'#'*) continue ;;
|
|
esac
|
|
pattern=$(echo "$line" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
|
[ -z "$pattern" ] && continue
|
|
|
|
pattern_clean="${pattern#/}"
|
|
pattern_clean="${pattern_clean%/}"
|
|
|
|
if echo "$pattern" | grep -q "/"; then
|
|
IGNORE_ARGS="$IGNORE_ARGS -o -path '$src/$pattern_clean' -o -path '$src/$pattern_clean/*'"
|
|
else
|
|
IGNORE_ARGS="$IGNORE_ARGS -o -name '$pattern_clean'"
|
|
fi
|
|
done < "$src/.kewtignore"
|
|
fi
|
|
|
|
find "$src" -name .kewtignore > "$KEWT_TMPDIR/kewt_ignore"
|
|
while read -r ki; do
|
|
d="${ki%/.kewtignore}"
|
|
if [ "$d" != "$src" ] && [ "$d" != "." ]; then
|
|
IGNORE_ARGS="$IGNORE_ARGS -o -path '$d' -o -path '$d/*'"
|
|
fi
|
|
done < "$KEWT_TMPDIR/kewt_ignore"
|
|
rm -f "$KEWT_TMPDIR/kewt_ignore"
|
|
|
|
HIDE_ARGS="-name '.kewtignore' -o -name '.kewthide' -o -name '.kewtpreserve' -o -path '$src/.*'"
|
|
|
|
if [ -f "$src/.kewthide" ]; then
|
|
while IFS= read -r line || [ -n "$line" ]; do
|
|
case "$line" in
|
|
''|'#'*) continue ;;
|
|
esac
|
|
pattern=$(echo "$line" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
|
[ -z "$pattern" ] && continue
|
|
|
|
pattern_clean="${pattern#/}"
|
|
pattern_clean="${pattern_clean%/}"
|
|
|
|
if echo "$pattern" | grep -q "/"; then
|
|
HIDE_ARGS="$HIDE_ARGS -o -path '$src/$pattern_clean' -o -path '$src/$pattern_clean/*'"
|
|
else
|
|
HIDE_ARGS="$HIDE_ARGS -o -name '$pattern_clean'"
|
|
fi
|
|
done < "$src/.kewthide"
|
|
fi
|
|
|
|
find "$src" -name .kewthide > "$KEWT_TMPDIR/kewt_hide"
|
|
while read -r kh; do
|
|
d="${kh%/.kewthide}"
|
|
if [ "$d" != "$src" ] && [ "$d" != "." ]; then
|
|
HIDE_ARGS="$HIDE_ARGS -o -path '$d' -o -path '$d/*'"
|
|
fi
|
|
done < "$KEWT_TMPDIR/kewt_hide"
|
|
rm -f "$KEWT_TMPDIR/kewt_hide"
|
|
|
|
PRESERVE_ARGS="-false"
|
|
|
|
if [ -f "$src/.kewtpreserve" ]; then
|
|
while IFS= read -r line || [ -n "$line" ]; do
|
|
case "$line" in
|
|
''|'#'*) continue ;;
|
|
esac
|
|
pattern=$(echo "$line" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
|
[ -z "$pattern" ] && continue
|
|
|
|
pattern_clean="${pattern#/}"
|
|
pattern_clean="${pattern_clean%/}"
|
|
|
|
if echo "$pattern" | grep -q "/"; then
|
|
PRESERVE_ARGS="$PRESERVE_ARGS -o -path '$src/$pattern_clean' -o -path '$src/$pattern_clean/*'"
|
|
else
|
|
PRESERVE_ARGS="$PRESERVE_ARGS -o -name '$pattern_clean'"
|
|
fi
|
|
done < "$src/.kewtpreserve"
|
|
fi
|
|
|
|
find "$src" -name .kewtpreserve > "$KEWT_TMPDIR/kewt_preserve"
|
|
while read -r kp; do
|
|
d="${kp%/.kewtpreserve}"
|
|
if [ "$d" != "$src" ] && [ "$d" != "." ]; then
|
|
PRESERVE_ARGS="$PRESERVE_ARGS -o -path '$d' -o -path '$d/*'"
|
|
fi
|
|
done < "$KEWT_TMPDIR/kewt_preserve"
|
|
rm -f "$KEWT_TMPDIR/kewt_preserve"
|
|
|
|
load_config "./site.conf"
|
|
load_config "$src/site.conf"
|
|
|
|
if [ -n "$posts_dir" ]; then
|
|
HIDE_ARGS="$HIDE_ARGS -o -path '$src/$posts_dir/*'"
|
|
fi
|
|
|
|
[ "$post_mode" = "true" ] && create_new_post "$src" "$post_title"
|
|
|
|
asset_version=""
|
|
if [ "$versioning" = "true" ]; then
|
|
asset_version="?v=$(date +%s)"
|
|
fi
|
|
|
|
template="$src/template.html"
|
|
[ -f "$template" ] || template="./template.html"
|
|
if [ ! -f "$template" ]; then
|
|
template="$KEWT_TMPDIR/default_template.html"
|
|
printf '%s\n' "$DEFAULT_TMPL" > "$template"
|
|
fi
|
|
|
|
if [ "$clean_mode" = "true" ]; then
|
|
[ -d "$out" ] && rm -rf "$out"
|
|
fi
|
|
mkdir -p "$out"
|
|
|
|
nav=$(generate_nav "$src")
|
|
extra_links=$(nav_links_html)
|
|
if [ -n "$extra_links" ]; then
|
|
nav="$nav
|
|
$extra_links"
|
|
fi
|
|
if [ -n "$nav_extra" ]; then
|
|
nav="$nav
|
|
$nav_extra"
|
|
fi
|
|
|
|
build_site
|
|
|
|
if [ "$serve_mode" = "true" ]; then
|
|
port="${serve_port:-8000}"
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
python3 -m http.server "$port" -d "$out" >/dev/null 2>&1 &
|
|
server_pid=$!
|
|
echo "Serving '$out' on http://localhost:$port (python3)"
|
|
elif command -v busybox >/dev/null 2>&1; then
|
|
busybox httpd -f -p "$port" -h "$out" >/dev/null 2>&1 &
|
|
server_pid=$!
|
|
echo "Serving '$out' on http://localhost:$port (busybox)"
|
|
else
|
|
die "Neither python3 nor busybox httpd is available to serve."
|
|
fi
|
|
|
|
trap 'kill $server_pid 2>/dev/null; rm -rf "$KEWT_TMPDIR"' EXIT
|
|
trap 'kill $server_pid 2>/dev/null; exit 0' HUP INT TERM
|
|
fi
|
|
|
|
if [ "$watch_mode" = "true" ]; then
|
|
echo "Watching for changes in '$src'..."
|
|
touch "$KEWT_TMPDIR/watch_mark"
|
|
while true; do
|
|
sleep 1
|
|
changed="$(find "$src" -type f -newer "$KEWT_TMPDIR/watch_mark" 2>/dev/null | head -n 1)"
|
|
[ -z "$changed" ] && [ -f "site.conf" ] && [ "site.conf" -nt "$KEWT_TMPDIR/watch_mark" ] && changed="site.conf"
|
|
[ -z "$changed" ] && [ -f "$src/site.conf" ] && [ "$src/site.conf" -nt "$KEWT_TMPDIR/watch_mark" ] && changed="$src/site.conf"
|
|
[ -z "$changed" ] && [ -f "$template" ] && [ "$template" -nt "$KEWT_TMPDIR/watch_mark" ] && changed="$template"
|
|
[ -z "$changed" ] && [ -d "$script_dir/styles" ] && changed="$(find "$script_dir/styles" -type f -newer "$KEWT_TMPDIR/watch_mark" 2>/dev/null | head -n 1)"
|
|
|
|
if [ -n "$changed" ]; then
|
|
echo ""
|
|
echo "Change detected, rebuilding..."
|
|
build_site
|
|
touch "$KEWT_TMPDIR/watch_mark"
|
|
fi
|
|
done
|
|
elif [ "$serve_mode" = "true" ]; then
|
|
wait "$server_pid"
|
|
fi
|