Files
bash-sfx/build_sfx.sh
Max P. 65f26e495a feat: add script for creating self-extracting archives
- Introduces a script to build self-extracting archives with validation
- Includes payload compression, placeholder replacement, and output creation
- Adds a header script to extract and execute the embedded entrypoint
2025-06-15 16:30:03 +02:00

79 lines
2.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
usage() {
echo "Usage: $0 --payload-dir DIR --entrypoint FILE [--output FILE]"
echo " $0 -p DIR -e FILE [-o FILE]"
exit 1
}
# 📥 Default values
HEADER="sfx_header.sh"
PAYLOAD_DIR=""
ENTRYPOINT=""
OUTPUT="sfx.run"
# 📋 Process arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--payload-dir|-p)
PAYLOAD_DIR="$2"
shift 2
;;
--entrypoint|-e)
ENTRYPOINT="$2"
shift 2
;;
--output|-o)
OUTPUT="$2"
shift 2
;;
*)
echo "❌ Unknown option: $1" >&2
usage
;;
esac
done
# ✅ Validation
[[ -z "$PAYLOAD_DIR" || -z "$ENTRYPOINT" ]] && usage
[[ ! -d "$PAYLOAD_DIR" ]] && { echo "❌ Payload directory not found: $PAYLOAD_DIR" >&2; exit 1; }
[[ ! -f "$PAYLOAD_DIR/$ENTRYPOINT" ]] && { echo "❌ Entrypoint not found in payload: $ENTRYPOINT" >&2; exit 1; }
# 🧊 Temporary directory
BUILD_TMP="$(mktemp -d "${TMPDIR:-/tmp}/sfxbuild.XXXXXX")"
PAYLOAD_ARCHIVE="$BUILD_TMP/payload.tar.zst"
HEADER_TMP="$BUILD_TMP/sfx_header.final"
cleanup() {
rm -rf "$BUILD_TMP"
}
trap cleanup EXIT
echo "📦 Creating payload (→ $PAYLOAD_ARCHIVE)..."
tar -cf - -C "$PAYLOAD_DIR" . | tee >(wc -c > "$BUILD_TMP/raw_size") | zstd -19 -T0 -o "$PAYLOAD_ARCHIVE"
RAW_SIZE=$(numfmt --to=iec < "$BUILD_TMP/raw_size")
# 🧭 Find marker
ARCHIVE_LINE=$(grep -n '^__ARCHIVE_BEGIN__$' "$HEADER" | cut -d: -f1)
[[ ! "$ARCHIVE_LINE" =~ ^[0-9]+$ ]] && {
echo "❌ Error: Marker __ARCHIVE_BEGIN__ not found!" >&2
exit 1
}
echo "🧮 Archive starts from line $ARCHIVE_LINE"
# 🛠️ Replace placeholders
sed "s|__ARCHIVE_LINE__|$ARCHIVE_LINE|" "$HEADER" | \
sed "s|__ENTRYPOINT__|$ENTRYPOINT|" | \
sed '/^__ARCHIVE_BEGIN__$/d' > "$HEADER_TMP"
# 🔗 Combine
cat "$HEADER_TMP" "$PAYLOAD_ARCHIVE" > "$OUTPUT"
chmod +x "$OUTPUT"
# 📊 Output
FINAL_SIZE=$(du -h "$OUTPUT" | cut -f1)
echo "✅ Done: $OUTPUT"
echo " 📁 Original size: $RAW_SIZE"
echo " 📦 Output file: $FINAL_SIZE"