automate/utils/conf_print/conf_print_gen.sh

159 lines
3.6 KiB
Bash

#!/bin/bash
# Default values
DEFAULT_SOURCE_DIR="scripts"
DEFAULT_OUTPUT_FILE="output.txt"
DEFAULT_TEE_DEST="\$DEST/.config/qtile/scripts"
# Usage message
usage() {
cat <<USAGE_EOF
Usage: $(basename "$0") [OPTIONS]
Wraps non-binary files from a source directory into heredoc functions
and outputs them to a single file.
OPTIONS:
-s, --source DIR Source directory containing files (default: $DEFAULT_SOURCE_DIR)
-o, --output FILE Output file path (default: $DEFAULT_OUTPUT_FILE)
-t, --tee-dest PATH Destination path for tee commands (default: $DEFAULT_TEE_DEST)
-h, --help Show this help message
EXAMPLES:
$(basename "$0") -s ./my-scripts
$(basename "$0") -s ./my-scripts -o bundle.sh -t /home/user/config
USAGE_EOF
exit "${1:-0}"
}
# Show usage if no arguments provided
if [[ $# -eq 0 ]]; then
usage 0
fi
# Parse command-line arguments
SOURCE_DIR="$DEFAULT_SOURCE_DIR"
OUTPUT_FILE="$DEFAULT_OUTPUT_FILE"
TEE_DEST="$DEFAULT_TEE_DEST"
while [[ $# -gt 0 ]]; do
case "$1" in
-s | --source)
SOURCE_DIR="$2"
shift 2
;;
-o | --output)
OUTPUT_FILE="$2"
shift 2
;;
-t | --tee-dest)
TEE_DEST="$2"
shift 2
;;
-h | --help)
usage 0
;;
*)
echo "Error: Unknown option '$1'" >&2
usage 1
;;
esac
done
# Validate source directory
if [[ ! -d "$SOURCE_DIR" ]]; then
echo "Error: Source directory '$SOURCE_DIR' does not exist." >&2
exit 1
fi
# Check if source directory is empty
shopt -s nullglob
files=("$SOURCE_DIR"/*)
shopt -u nullglob
if [[ ${#files[@]} -eq 0 ]]; then
echo "Error: Source directory '$SOURCE_DIR' is empty." >&2
exit 1
fi
# Get absolute paths for comparison
OUTPUT_DIR=$(cd "$(dirname "$OUTPUT_FILE")" 2>/dev/null && pwd)
OUTPUT_FILE_ABS="${OUTPUT_DIR}/$(basename "$OUTPUT_FILE")"
# Function to check if file is binary
is_binary() {
local file="$1"
file --mime-encoding "$file" 2>/dev/null | grep -q "binary"
}
# Function to create safe identifier from filename
make_safe_identifier() {
local filename="$1"
local safe="${filename%.*}"
safe="${safe//[^a-zA-Z0-9]/_}"
safe=$(echo "$safe" | sed 's/_\+/_/g; s/^_//; s/_$//')
echo "$safe"
}
# Clear or create output file
>"$OUTPUT_FILE"
# Counters
processed=0
skipped=0
for filepath in "$SOURCE_DIR"/*; do
# Skip if not a regular file
[[ -f "$filepath" ]] || continue
# Get absolute path of current file
filepath_dir=$(cd "$(dirname "$filepath")" && pwd)
filepath_abs="${filepath_dir}/$(basename "$filepath")"
# Skip the output file if it is in the source directory
if [[ "$filepath_abs" == "$OUTPUT_FILE_ABS" ]]; then
echo "Skipping output file: $filepath"
((skipped++))
continue
fi
# Skip binary files
if is_binary "$filepath"; then
echo "Skipping binary file: $filepath"
((skipped++))
continue
fi
# Extract filename and create safe identifier
filename=$(basename "$filepath")
safe_id=$(make_safe_identifier "$filename")
# Create unique heredoc delimiter
heredoc_delim="EOF_${safe_id}_EOF"
# Function name
func_name="conf_print_${safe_id}"
# Write function definition
{
echo "${func_name}() {"
echo "cat <<'${heredoc_delim}'"
cat "$filepath"
echo ""
echo "${heredoc_delim}"
echo "}"
echo "${func_name} | tee \"${TEE_DEST}/${filename}\""
echo ""
} >>"$OUTPUT_FILE"
((processed++))
echo "Processed: $filename -> delimiter: $heredoc_delim"
done
echo "----------------------------------------"
echo "Processing complete!"
echo " Processed: $processed file(s)"
echo " Skipped: $skipped file(s)"
echo " Output: $OUTPUT_FILE"