#!/bin/bash #shellcheck disable=SC1090 . "$(sfpath)" || exit 3 shellfu import pretty # usage() { mkusage "$@" "[options] SCRIPT" \ -- \ "Run SCRIPT, see what it would load and print its 'portable'" \ "version, ie. with those modules embedded inside." \ -o \ "-v enable verbose output" \ "-d enable debugging output" \ -- \ "WARNING: sfembed is highly experimental, probably dangerous and" \ "does not always work (namely, if module loading is dynamic)." \ -- \ "Calling sfembed WILL RUN provided SCRIPT (with no arguments);" \ "currently that's how it finds out what the SCRIPT would need." } chk_applicable() { # # Check if script file is properly formed # # Not all scripts are applicable for embedding. Check # if the file is usable. # : #TODO: for starters, file must only contain shellfu header, imports, main() and nothing else } mkbody() { debug -v ScriptFullPath mkhead || return $? mkmodules || return $? mkpayload || return $? mkfoot || return $? } mkmodules() { # # Print each module body w/ header # local modlist=__shellfu_embed__modlist local Module local ModuleHash ( SHELLFU_EMBEDTMP="$modlist" "$ScriptFullPath" >&2 ) #shellcheck disable=SC2030 awk '!x[$0]++' "$modlist" \ | while read -r Module; do ModuleHash=$(md5sum "$Module") think "appending: $Module" mkmodule "$Module" done } mkpayload() { cat "$ScriptFullPath" } mkfoot() { echo "#" echo "# end of shellfu-embedded shell script" echo "#" } #shellcheck disable=SC2031 mkmodule() { # # Print single module body # echo "#" echo "# begin module: $ModuleHash" echo "#" echo cat "$Module" echo echo "#" echo "# end module: $ModuleHash" echo "#" echo } mkhead() { # # Print header of the final script # echo "#!/bin/bash" echo "#" echo "# shellfu embedded: $ScriptFullPath" echo "# shellfu version: $SHELLFU_VERSION" echo "#" echo echo "# neuter any shellfu and sfpath calls" echo "shellfu() { :; }" echo "sfpath() { echo /dev/null; }" #FIXME: assumes that shellfu and sfpath are not installed # I.e. beats the use case when embedding is done to # avoid conflict. echo } do_embed() { local tmp # temporary dir to run in local es=0 # exit status of this function local ScriptFullPath # full path to script to embed in tmp=$(mktemp -d -t shellfu_embed.XXXXXXXX) ScriptFullPath=$(readlink -f "$Script") pushd "$tmp" >/dev/null mkbody; es=$? popd >/dev/null rm -r "$tmp" return $es } main() { local Script # script to embed libraries into #shellcheck disable=SC2034 while true; do case "$1" in -d) PRETTY_DEBUG=true; shift ;; -v) PRETTY_VERBOSE=true; shift ;; -*) usage -w "unknown argument: $1" ;; *) break ;; esac done Script="$1" test -n "$Script" || usage -w "no SCRIPT?" test -f "$Script" || die "no such file: $Script" test -r "$Script" || die "cannot read: $Script" chk_applicable "$Script" || die "not applicable for embedding: $Script" debug -v Script do_embed } main "$@"