159 lines
3.6 KiB
Bash
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"
|