summaryrefslogtreecommitdiff
path: root/src/lib/config.source.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/config.source.sh')
-rw-r--r--src/lib/config.source.sh629
1 files changed, 0 insertions, 629 deletions
diff --git a/src/lib/config.source.sh b/src/lib/config.source.sh
index 35624b7..348f167 100644
--- a/src/lib/config.source.sh
+++ b/src/lib/config.source.sh
@@ -1,67 +1,3 @@
-print_shell_assignment() {
- local -r name="$1"; shift
- local -r value="$1"; shift
-
- printf '%s=%q\n' "$name" "$value"
-}
-
-print_shell_array_assignment() {
- local -r name="$1"; shift
- local value
-
- printf '%s=(' "$name"
- for value in "$@"; do
- printf ' %q' "$value"
- done
- printf ' )\n'
-}
-
-print_config() {
- local -a tar_opts=()
- local -a sync_destinations=()
-
- resolve_tar_opts tar_opts
- resolve_sync_destinations sync_destinations
-
- print_shell_assignment CONFIG_SOURCE "${SHURIKEN_CONFIG_SOURCE:-}"
- print_shell_assignment INCOMING_DIR "$INCOMING_DIR"
- print_shell_assignment DIST_DIR "$DIST_DIR"
- print_shell_assignment TEMPLATE_DIR "$TEMPLATE_DIR"
- print_shell_assignment TITLE "$TITLE"
- print_shell_assignment HEIGHT "${HEIGHT:-}"
- print_shell_assignment THUMBHEIGHT "$THUMBHEIGHT"
- print_shell_assignment MAXPREVIEWS "$MAXPREVIEWS"
- print_shell_assignment IMAGE_JOBS "$IMAGE_JOBS"
- print_shell_assignment IMAGEMAGICK_TIMEOUT "$IMAGEMAGICK_TIMEOUT"
- print_shell_assignment RANDOM_SEED "${RANDOM_SEED:-}"
- print_shell_assignment SHUFFLE "${SHUFFLE:-no}"
- print_shell_assignment SPLASH_PAGE "${SPLASH_PAGE:-yes}"
- print_shell_assignment TARBALL_INCLUDE "${TARBALL_INCLUDE:-no}"
- print_shell_assignment TARBALL_SUFFIX "${TARBALL_SUFFIX:-.tar}"
- print_shell_assignment TAR_TIMEOUT "$TAR_TIMEOUT"
- print_shell_array_assignment TAR_OPTS "${tar_opts[@]}"
- print_shell_assignment SYNC_DELETE "${SYNC_DELETE:-yes}"
- print_shell_array_assignment SYNC_DESTINATIONS "${sync_destinations[@]}"
- print_shell_assignment ORIGINAL_BASEPATH "${ORIGINAL_BASEPATH:-}"
-}
-
-sync_dist() {
- local destination
- local -a rsync_args=(-av)
- local -a sync_destinations=()
-
- resolve_sync_destinations sync_destinations
-
- if [ "${SYNC_DELETE:-yes}" = yes ]; then
- rsync_args+=(--delete)
- fi
-
- for destination in "${sync_destinations[@]}"; do
- log_info "Syncing $DIST_DIR/ to $destination"
- rsync "${rsync_args[@]}" "$DIST_DIR/" "$destination"
- done
-}
-
existing_parent_dir() {
local -r path="$1"; shift
local existing_parent
@@ -75,223 +11,6 @@ existing_parent_dir() {
printf '%s\n' "$existing_parent"
}
-generation_staging_dir() {
- local -r final_dist="$1"; shift
- local final_base
- local staging_parent
-
- final_base=$(basename "$final_dist")
- staging_parent=$(existing_parent_dir "$final_dist")
-
- mktemp -d "$staging_parent/.shuriken.$final_base.staging.XXXXXX"
-}
-
-prepare_generation_staging_dir() {
- local -r final_dist="$1"; shift
- local -r staging_dir="$1"; shift
- local cache_dir
-
- if [ "$SHURIKEN_FORCE_GENERATE" = yes ]; then
- log_verbose 'Force generation enabled; not reusing existing output cache'
- return
- fi
-
- for cache_dir in photos thumbs blurs .shuriken-cache; do
- if [ -d "$final_dist/$cache_dir" ]; then
- if ! mkdir -p "$staging_dir/$cache_dir"; then
- return 1
- fi
- if ! cp -a "$final_dist/$cache_dir/." "$staging_dir/$cache_dir/"; then
- return 1
- fi
- fi
- done
-}
-
-cleanup_generation_staging_dir() {
- if [ -n "${SHURIKEN_ACTIVE_STAGING_DIR:-}" ]; then
- rm -rf "$SHURIKEN_ACTIVE_STAGING_DIR"
- SHURIKEN_ACTIVE_STAGING_DIR=''
- fi
-}
-
-terminate_process_tree() {
- local -r signal="$1"; shift
- local -r pid="$1"; shift
- local child
-
- if [ -z "$pid" ]; then
- return
- fi
-
- while IFS= read -r child; do
- if [ -n "$child" ]; then
- terminate_process_tree "$signal" "$child"
- fi
- done < <(pgrep -P "$pid" 2>/dev/null || true)
-
- kill "-$signal" "$pid" 2>/dev/null || true
-}
-
-wait_for_process_exit() {
- local -r pid="$1"; shift
- local -i attempts=0
-
- while kill -0 "$pid" 2>/dev/null; do
- if (( attempts >= 20 )); then
- return 1
- fi
- (( ++attempts ))
- sleep 0.05
- done
-}
-
-terminate_active_generation() {
- local -r pid="${SHURIKEN_ACTIVE_GENERATION_PID:-}"
-
- if [ -z "$pid" ]; then
- return
- fi
-
- terminate_process_tree TERM "$pid"
- if ! wait_for_process_exit "$pid"; then
- terminate_process_tree KILL "$pid"
- fi
- wait "$pid" 2>/dev/null || true
- SHURIKEN_ACTIVE_GENERATION_PID=''
-}
-
-handle_generation_staging_signal() {
- local -r status="$1"; shift
-
- clear_generation_staging_traps
- terminate_active_generation
- cleanup_generation_staging_dir
- exit "$status"
-}
-
-clear_generation_staging_traps() {
- trap - EXIT INT TERM HUP PIPE
-}
-
-ignore_generation_staging_interrupts() {
- trap '' INT TERM HUP PIPE
-}
-
-replace_dist_with_staging() {
- local -r staging_dir="$1"; shift
- local -r final_dist="$1"; shift
- local backup_dist=''
- local backup_parent=''
- local final_base
- local final_parent
- local staging_parent
- local -i status=0
-
- final_base=$(basename "$final_dist")
- final_parent=$(dirname "$final_dist")
- staging_parent=$(existing_parent_dir "$final_dist")
-
- if ! mkdir -p "$final_parent"; then
- return 1
- fi
-
- if [ -e "$final_dist" ]; then
- if ! backup_parent=$(
- mktemp -d "$staging_parent/.shuriken.$final_base.backup.XXXXXX"
- ); then
- return 1
- fi
- backup_dist="$backup_parent/dist"
-
- if ! mv "$final_dist" "$backup_dist"; then
- rm -rf "$backup_parent"
- return 1
- fi
- fi
-
- if mv "$staging_dir" "$final_dist"; then
- if [ -n "$backup_parent" ]; then
- rm -rf "$backup_parent"
- fi
- return 0
- else
- status=$?
- fi
-
- if [ -n "$backup_dist" ] && [ -e "$backup_dist" ]; then
- if [ -e "$final_dist" ] && ! rm -rf "$final_dist"; then
- printf 'ERROR: Failed to restore %s from %s\n' \
- "$final_dist" "$backup_dist" >&2
- return "$status"
- fi
- if ! mv "$backup_dist" "$final_dist"; then
- printf 'ERROR: Failed to restore %s from %s\n' \
- "$final_dist" "$backup_dist" >&2
- return "$status"
- fi
- rm -rf "$backup_parent"
- fi
-
- return "$status"
-}
-
-generate_staged() {
- local -r final_dist="$DIST_DIR"
- local staging_dir
- local -i status=0
-
- staging_dir=$(generation_staging_dir "$final_dist")
- log_verbose "Effective output directory: $final_dist"
- log_verbose "Generation staging directory: $staging_dir"
- SHURIKEN_ACTIVE_STAGING_DIR="$staging_dir"
- trap cleanup_generation_staging_dir EXIT
- trap 'handle_generation_staging_signal 130' INT
- trap 'handle_generation_staging_signal 143' TERM
- trap 'handle_generation_staging_signal 129' HUP
- trap 'handle_generation_staging_signal 141' PIPE
-
- if ! prepare_generation_staging_dir "$final_dist" "$staging_dir"; then
- cleanup_generation_staging_dir
- clear_generation_staging_traps
- return 1
- fi
-
- set +e
- (
- set -e
- SHURIKEN_FINAL_DIST_DIR="$final_dist"
- export SHURIKEN_FINAL_DIST_DIR
- DIST_DIR="$staging_dir" generate
- ) &
- SHURIKEN_ACTIVE_GENERATION_PID=$!
- wait "$SHURIKEN_ACTIVE_GENERATION_PID"
- status=$?
- SHURIKEN_ACTIVE_GENERATION_PID=''
- set -e
-
- if (( status != 0 )); then
- cleanup_generation_staging_dir
- clear_generation_staging_traps
- return "$status"
- fi
-
- ignore_generation_staging_interrupts
- set +e
- replace_dist_with_staging "$staging_dir" "$final_dist"
- status=$?
- set -e
-
- if (( status != 0 )); then
- cleanup_generation_staging_dir
- clear_generation_staging_traps
- return "$status"
- fi
-
- SHURIKEN_ACTIVE_STAGING_DIR=''
- clear_generation_staging_traps
-}
-
resolve_config_file() {
local -r config_file="${1:-}"
@@ -329,351 +48,3 @@ apply_config_defaults() {
SYNC_DESTINATIONS=()
fi
}
-
-option_value() {
- local -r option="$1"; shift
- local -r argument="${CLI_OPTION_ARGUMENT[$option]:-value}"
-
- if (( $# == 0 )) || [ -z "$1" ]; then
- printf 'Error: %s requires a %s\n' "$option" "$argument" >&2
- usage
- exit 1
- fi
-
- printf '%s\n' "$1"
-}
-
-apply_cli_override() {
- local -r config_target="$1"; shift
-
- if [[ -v "cli_overrides[$config_target]" ]]; then
- printf -v "$config_target" '%s' "${cli_overrides[$config_target]}"
- fi
-}
-
-apply_cli_overrides() {
- local config_target
-
- for config_target in "${CLI_CONFIG_OVERRIDE_TARGETS[@]}"; do
- apply_cli_override "$config_target"
- done
-
- if (( ${#cli_sync_destinations[@]} > 0 )); then
- SYNC_DESTINATIONS=("${cli_sync_destinations[@]}")
- fi
-}
-
-config_error() {
- local -r message="$1"; shift
-
- printf 'ERROR: %s\n' "$message" >&2
- return 1
-}
-
-require_config_var() {
- local -r name="$1"; shift
-
- if [ -z "${!name+x}" ] || [ -z "${!name}" ]; then
- config_error "$name must be set in shuriken configuration"
- fi
-}
-
-validate_positive_integer_config_var() {
- local -r name="$1"; shift
- local -r value="${!name}"
-
- if [[ ! "$value" =~ ^[0-9]+$ ]] || (( value < 1 )); then
- config_error "$name must be a positive integer"
- fi
-}
-
-validate_optional_positive_integer_config_var() {
- local -r name="$1"; shift
-
- if [ -n "${!name}" ]; then
- validate_positive_integer_config_var "$name"
- fi
-}
-
-validate_yes_no_config_var() {
- local -r name="$1"; shift
- local -r value="${!name}"
-
- case "$value" in
- yes|no)
- ;;
- *)
- config_error "$name must be yes or no"
- ;;
- esac
-}
-
-validate_dist_dir() {
- local existing_parent
-
- if [ -e "$DIST_DIR" ]; then
- if [ ! -d "$DIST_DIR" ]; then
- config_error "DIST_DIR $DIST_DIR must be a directory"
- fi
- if [[ ! -w "$DIST_DIR" || ! -x "$DIST_DIR" ]]; then
- config_error "DIST_DIR $DIST_DIR must be writable"
- fi
-
- return
- fi
-
- existing_parent=$(existing_parent_dir "$DIST_DIR")
-
- if [ ! -d "$existing_parent" ]; then
- config_error "DIST_DIR parent $existing_parent must be a directory"
- fi
- if [[ ! -w "$existing_parent" || ! -x "$existing_parent" ]]; then
- config_error "DIST_DIR parent $existing_parent must be writable"
- fi
-}
-
-validate_template_dir_access() {
- if [[ ! -d "$TEMPLATE_DIR" || ! -r "$TEMPLATE_DIR" \
- || ! -x "$TEMPLATE_DIR" ]]; then
- config_error "TEMPLATE_DIR $TEMPLATE_DIR must be a readable directory"
- fi
-}
-
-validate_template_file() {
- local -r template_name="$1"; shift
-
- if [ ! -r "$TEMPLATE_DIR/$template_name.tmpl" ]; then
- config_error \
- "template file $TEMPLATE_DIR/$template_name.tmpl must be readable"
- fi
-}
-
-validate_template_dir() {
- local template_name
- local -a required_templates=(
- details
- footer
- header
- next
- prev
- preview
- redirect
- view
- )
-
- validate_template_dir_access
-
- if [ "${SPLASH_PAGE:-yes}" = yes ]; then
- required_templates+=(splash)
- fi
-
- for template_name in "${required_templates[@]}"; do
- validate_template_file "$template_name"
- done
-}
-
-validate_refresh_splash_config() {
- local required_var
- local -a required_vars=(
- TITLE
- DIST_DIR
- TEMPLATE_DIR
- )
-
- for required_var in "${required_vars[@]}"; do
- require_config_var "$required_var"
- done
-
- validate_yes_no_config_var SPLASH_PAGE
-
- if [ "${SPLASH_PAGE:-yes}" != yes ]; then
- config_error 'SPLASH_PAGE must be yes to refresh the splash page'
- fi
-
- validate_dist_dir
-
- validate_template_dir_access
- validate_template_file splash
-
- if [ ! -d "$DIST_DIR/photos" ]; then
- config_error "DIST_DIR photos directory $DIST_DIR/photos must exist"
- fi
-
- if [ ! -d "$DIST_DIR/blurs" ]; then
- config_error "DIST_DIR blurs directory $DIST_DIR/blurs must exist"
- fi
-}
-
-validate_imagemagick() {
- if command -v magick >/dev/null 2>&1; then
- return
- fi
- if command -v convert >/dev/null 2>&1; then
- return
- fi
-
- config_error 'ImageMagick is required; install magick or convert'
-}
-
-validate_common_config() {
- local required_var
- local -a required_vars=(
- TITLE
- THUMBHEIGHT
- MAXPREVIEWS
- IMAGE_JOBS
- INCOMING_DIR
- DIST_DIR
- TEMPLATE_DIR
- )
-
- for required_var in "${required_vars[@]}"; do
- require_config_var "$required_var"
- done
-
- validate_optional_positive_integer_config_var HEIGHT
- validate_positive_integer_config_var THUMBHEIGHT
- validate_positive_integer_config_var MAXPREVIEWS
- validate_positive_integer_config_var IMAGE_JOBS
- validate_positive_integer_config_var IMAGEMAGICK_TIMEOUT
- validate_positive_integer_config_var TAR_TIMEOUT
- validate_yes_no_config_var SHUFFLE
- validate_yes_no_config_var SPLASH_PAGE
- validate_yes_no_config_var TARBALL_INCLUDE
-}
-
-validate_generation_config() {
- local -r require_imagemagick="${1:-yes}"
-
- validate_common_config
-
- if [ ! -d "$INCOMING_DIR" ]; then
- config_error "You have to create $INCOMING_DIR first"
- fi
- if [[ ! -r "$INCOMING_DIR" || ! -x "$INCOMING_DIR" ]]; then
- config_error "INCOMING_DIR $INCOMING_DIR must be readable"
- fi
-
- validate_dist_dir
- validate_template_dir
- if [ "$require_imagemagick" = yes ]; then
- validate_imagemagick
- fi
-}
-
-validate_print_config() {
- local -a tar_opts=()
- local -a sync_destinations=()
-
- validate_common_config
- resolve_tar_opts tar_opts
- resolve_sync_destinations sync_destinations
- validate_yes_no_config_var SYNC_DELETE
-}
-
-validate_sync_destinations() {
- local -a sync_destinations=()
-
- resolve_sync_destinations sync_destinations
-
- if (( ${#sync_destinations[@]} == 0 )); then
- config_error 'SYNC_DESTINATIONS must contain at least one destination'
- fi
-}
-
-validate_rsync() {
- if command -v rsync >/dev/null 2>&1; then
- return
- fi
-
- config_error 'rsync is required to sync generated output'
-}
-
-validate_sync_config() {
- require_config_var DIST_DIR
- validate_yes_no_config_var SYNC_DELETE
- validate_sync_destinations
-
- if [[ ! -d "$DIST_DIR" || ! -r "$DIST_DIR" || ! -x "$DIST_DIR" ]]; then
- config_error "DIST_DIR $DIST_DIR must be a readable directory"
- fi
-
- validate_rsync
-}
-
-set_cli_option_value() {
- local -r option="$1"; shift
- local -r value="$1"; shift
- local config_target
-
- if [ "$option" = --sync-destination ]; then
- cli_sync_destinations+=("$value")
- has_config_overrides='yes'
- return
- fi
-
- config_target="${CLI_OPTION_CONFIG_TARGET[$option]:-}"
- if [ -n "$config_target" ]; then
- cli_overrides["$config_target"]="$value"
- has_config_overrides='yes'
- return
- fi
-
- printf -v "${CLI_OPTION_TARGET[$option]}" '%s' "$value"
-}
-
-set_cli_constant_option() {
- local -r option="$1"; shift
- local -r value="${CLI_OPTION_VALUE[$option]}"
- local config_target
-
- config_target="${CLI_OPTION_CONFIG_TARGET[$option]:-}"
- if [ -n "$config_target" ]; then
- cli_overrides["$config_target"]="$value"
- has_config_overrides='yes'
- return
- fi
-
- printf -v "${CLI_OPTION_TARGET[$option]}" '%s' "$value"
-}
-
-set_cli_action() {
- local -r selected_action="$1"; shift
-
- if [ -n "$action" ]; then
- usage
- exit 1
- fi
-
- action="$selected_action"
-}
-
-parse_cli_arguments() {
- local option_arg
- local option
- local option_kind
-
- while (( $# > 0 )); do
- option="$1"
- shift
-
- option_kind="${CLI_OPTION_KIND[$option]:-}"
- case "$option_kind" in
- value)
- option_arg=$(option_value "$option" "$@")
- set_cli_option_value "$option" "$option_arg"
- shift
- ;;
- flag|output)
- set_cli_constant_option "$option"
- ;;
- action)
- set_cli_action "$option"
- ;;
- *)
- usage
- exit 1
- ;;
- esac
- done
-}