appdwarf/appdwarf

150 lines
4.8 KiB
Bash
Executable File

#!/bin/sh
set -e # exit on failure
IFS=$(printf '\n\t') # smarter ifs
apprun() {
export PATH="$APPDIR"/bin:"$PATH"
export LD_LIBRARY_PATH="$APPDIR"/lib64:"$APPDIR"/lib:"$LD_LIBRARY_PATH"
exec "$APPDIR/$(basename "$ARGV0")" "$@"
}
# shellcheck disable=SC2086,SC2155
header() {
APPDIR="/tmp/dwarf_$(basename "$0")$(echo "$0"|md5sum|head -c5)"
export APPDIR APPIMAGE="$(realpath "$0")" ARGV0="$0" OWD="$PWD"
args="-o offset=auto -o tidy_strategy=swap -o workers=4"
[ ! -d "$APPDIR" ] && mkdir "$APPDIR" && dwarfs $args "$0" "$APPDIR" 2>/dev/null
"$APPDIR/AppRun" "$@"
res=$?
fusermount -quz "$APPDIR"
rmdir "$APPDIR" 2>/dev/null
exit $res
}
printfunc() {
echo '#!/bin/sh'
type "$1" | sed 's/^ *//' | tail -n+4 | head -n-1
}
unappimage() {
a=$(readelf -h "$1" | sed '13!d;s/[^0-9]//g')
b=$(readelf -h "$1" | sed '18!d;s/[^0-9]//g')
c=$(readelf -h "$1" | sed '19!d;s/[^0-9]//g')
o=$(echo "$a" + "$b" \* "$c" | bc)
unsquashfs -o "$o" "$1"
}
zzexe() {
[ "$1" = "-p" ] && p="$2" && shift 2 # save prefix if present
tmp=$(mktemp) # make tmp file to avoid io operations
printfunc zzexe_header | sed -e "2s/);$/${1##*[./]})/" -e "7s/^/$p /" > "$tmp"
zstdmt -cq19 "$@" >> "$tmp"
mv "$tmp" "$1"
chmod +x "$1"
exit
}
zzexe_header() {
dir=$(dirname "$0") out=$(mktemp -t .zzXXXX.)
awk 'f;/^exit \$res$/{f=1}' "$0" | head -c-1 | zstd -cd > "$out"
chmod +x "$out"
ln -s "$out" "$dir"
trap : 0 1 2 3 6 14 15
"$dir/$(basename "$out")" "$@"
res=$?
rm "$out" "$dir/$(basename "$out")"
exit $res
}
case "$1" in
-a )
printfunc apprun > "$2"
chmod +x "$2"
exit ;;
-b )
printfunc apprun | sed '4s#/#/bin/#' > "$2"
chmod +x "$2"
exit ;;
-d )
d=dwarfs-root # just to keep line shorter, extract if file is dwarfs
dwarfsck -d0 -i"$2" && mkdir $d && dwarfsextract -o $d -i "$2" && exit
tmp=$(mktemp) # make tmp file to avoid io operations
awk 'f;/^exit \$res$/{f=1}' "$2" | head -c-1 | zstd -cd > "$tmp"
mv "$tmp" "$2"
chmod +x "$2"
exit ;;
-p )
zzexe "$@" ;;
-z)
shift
zzexe "$@" ;;
--version | -v )
tput setaf 2; echo appdwarf 2022.07.24
tput setaf 6; echo Built by July 🏳️‍🌈; exit ;;
-* | '' )
echo "Usage: appdwarf [option] [APP/FILE/FOLDER/URL] [compression options]"
echo " -a [file] Write example AppRun to file and exit"
echo " -b [file] Write example AppRun with bin subdir to file and exit"
echo " -d [file] Decompress an appdwarf image or zzexe'd file"
echo
echo " -p [prefix] zzexe a file with prefix"
echo " -z zzexe a file"
echo
echo " -h, --help Print this help text"
echo " -v, --version Print the appdwarf version"; exit ;;
esac
if [ ! -d "$1" ]; then # directory doesn't exist, see if this is an appimage
if [ ! -f "$1" ]; then # file doesn't exist, see if this is a url
if ! echo "$1" | grep -q / ; then # AppImageHub
echo "Checking AppImageHub for this program..."
app=https://github.com/AppImage/appimage.github.io/raw/master/apps/$1.md
shift
set -- "$(curl -L "$app" | grep -o https.\*releases | sed 's|/releases$||')" "$@"
elif ! echo "$1" | grep https ; then # GitHub in Author/Repo format
app=$1
shift
set -- "https://github.com/$app" "$@"
fi
if echo "$1" | grep -q 'https://github.com/[^/]*/[^/]*/*$'; then # GitHub url
echo "Assuming this is a GitHub repo..."
app="$(echo "${1%/}"/releases | sed 's|github.com|api.github.com/repos|')"
shift
set -- "$(curl "$app" | grep -v arm | grep -om1 https.\*AppImage)" "$@"
fi
app=$(basename "$1") # actually try to get the appimage
if aria2c -x16 -s16 "$1" -o "$app" || wget "$1" -O "$app"; then
shift
set -- "$app" "$@"
else
tput setaf 1; echo "No valid remote or local input found. Exiting..." >&2
rm -f "$app"; exit 1
fi
fi
rm -rf squashfs-root
# this is a file, but it might be an existing dwarfs image
if dwarfsck -d0 -i"$1"; then
set -- "$@" --recompress=none
elif file "$1" | grep -q ELF && unappimage "$1"; then
echo "AppImage found. Converting..."
app="$(basename "$1" .AppImage)"
rm -rf "$1" "$app"
shift
set -- "$app" "$@"
mv squashfs-root "$1"
else
tput setaf 4; echo "$1 is not an AppImage, it will be zzexe'd"
zzexe "$@"
fi
fi
head="$(mktemp)"
printfunc header > "$head"
mkdwarfs -o "$(realpath "$1").sh" -B5 --header "$head" -i "$@"
rm "$head"
chmod +x "$(realpath "$1").sh"