diff --git a/README.md b/README.md index 757b439..ca510d8 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Requirements: Optional: - pixz/pigz (faster compression/decompression) +- shfmt (minimize zpkg on compile) ### Installing diff --git a/compile.sh b/compile.sh index bff27fd..6989eae 100755 --- a/compile.sh +++ b/compile.sh @@ -1,24 +1,6 @@ #!/bin/sh -# config -# no spaces in srcdir or ordered files -SRCDIR=src -ordered='env.sh options.sh config.sh main.sh' +cd "$(dirname "$(readlink -f "$0")")" -# process -COMMENTSCRIPT="/^\s*#/d;s/\s*#[^\"']*$//" - -# order list -unset namefind list -for I in $ordered -do - namefind="$namefind ! -name $I" - list="$list $SRCDIR/$I" -done - -findlist=$(find "$SRCDIR" -type f $namefind) - -# create file -echo '#!/bin/sh' > zpkg -sed $COMMENTSCRIPT $findlist $list >> zpkg +scripts/shcompile src/main.sh > zpkg chmod +x zpkg diff --git a/scripts/shcompile b/scripts/shcompile new file mode 100755 index 0000000..67426fa --- /dev/null +++ b/scripts/shcompile @@ -0,0 +1,72 @@ +#!/bin/sh + +fname=$(basename "$0") +usage() +{ + echo "$fname +Compile the target shell script into a single output +Resolves '%include' lines with shell capacity" +} + +# no arg +[ $# -lt 1 ] && usage && exit 1 + +[ -z "$TMPDIR" ] && TMPDIR=/tmp +tmpdir="$TMPDIR/shcompile_$(tr -dc '[:alnum:]' < /dev/urandom | head -c10)" +mkdir -p "$tmpdir" +tmpfile="$tmpdir/ret" +filelist="$tmpdir/list" +headfile="$tmpdir/head" +tailfile="$tmpdir/tail" + +stop() +{ + rm -rf "$tmpdir" + exit $1 +} + +infile=$1 +[ "$infile" = '-' ] && infile=/dev/stdin + +cat "$infile" >/dev/null 2>&1 || { echo "Error: cannot read '$infile'" >&2 && stop 2; } + +firstline=$(head -n1 "$infile" | grep '^#!/') +[ -z "$firstline" ] && firstline='#!/bin/sh' + +cp "$infile" "$tmpfile" + +get_include_line() +{ + grep -m1 -n '^%include ' "$1" | cut -d':' -f1 +} + +echo "$1" > "$filelist" + +n=$(get_include_line "$tmpfile") +while [ -n "$n" ] +do + pre=$(head -n $((n-1)) "$tmpfile" > "$headfile") + post=$(tail -n +$((n+1)) "$tmpfile" > "$tailfile") + incarg=$(sed "$n""q;d" "$tmpfile" | cut -d ' ' -f2-) + inc=$(echo "for I in $incarg ; do echo \$I ; done" | sh) + + cp "$headfile" "$tmpfile" + echo "$inc" | while read -r file + do + cat "$file" >/dev/null 2>&1 || { echo "Error when trying to include '$incarg': '$ln' could not be read" >&2 && stop 10; } + if ! grep -q "^$file\$" "$filelist" + then # not already included + cat "$file" >> "$tmpfile" + echo "$file" >> "$filelist" + fi + done + cat "$tailfile" >> "$tmpfile" + # get next include line + n=$(get_include_line "$tmpfile") +done + +which shfmt >/dev/null 2>&1 && shfmt -w -mn "$tmpfile" +echo "$firstline" +cat "$tmpfile" + +stop 0 diff --git a/src/main.sh b/src/main.sh index d751c96..1856195 100644 --- a/src/main.sh +++ b/src/main.sh @@ -1,5 +1,14 @@ #!/bin/sh +# ordered requirements +%include src/util.sh +%include src/env.sh +%include src/options.sh +%include src/config.sh + +# everything else +%include src/*.sh + case "$1" in list) awk '{print $1}' "$PKG_PATH/installed" 2>/dev/null | sort ;; list-all) awk '{print $1}' "$PKG_PATH/pkglist" 2>/dev/null | sort ;;