96 lines
3.3 KiB
Bash
Executable file
96 lines
3.3 KiB
Bash
Executable file
#!/usr/bin/env sh
|
|
|
|
warn() { printf >&2 '\033[1m%s:\033[m %s\n' acquire "$*" ;}
|
|
die() { warn "$@"; exit 64 ;}
|
|
missing() { [ ${#3} != 0 ] || { warn "missing a required $1: $2"; ok=0 ;} ;}
|
|
|
|
argue()
|
|
{ : \
|
|
&& for arg in "$@" \
|
|
;do : \
|
|
&& rhs="${arg#*=}" \
|
|
&& a="${arg%"$rhs"}" \
|
|
&& b="${a%=}" \
|
|
&& if [ ${#a} = ${#b} ] \
|
|
|| [ ${#b} = 0 ] \
|
|
;then : \
|
|
&& warn "ignoring bare argument: $arg" \
|
|
&& continue \
|
|
;fi \
|
|
&& lhs="${b#*[!-0-9A-Z_a-z]}" \
|
|
&& if [ ${#lhs} != ${#b} ] \
|
|
;then : \
|
|
&& warn "ignoring invalid key: $b" \
|
|
&& warn "it became invalid at: ${b#"${b%?"$lhs"}"}" \
|
|
&& continue \
|
|
;fi \
|
|
&& case "$lhs" in \
|
|
(from) from="$rhs" ;; \
|
|
(repo) repo="$rhs" ;; \
|
|
(dest) dest="$rhs" ;; \
|
|
(commit) commit="$rhs" ;; \
|
|
(checksum) checksum="$rhs" ;; \
|
|
(env) env="${rhs%%[!A-Za-z0-9_]*}" ;; \
|
|
(*) warn "ignoring unknown key: $lhs" ;; \
|
|
esac \
|
|
|| exit \
|
|
;done \
|
|
&& { [ "${#from}" != 0 ] || die "missing a required key: from" ;} \
|
|
&& if [ -n "$env" ] && [ ".${env#[0-9]}" = ".$env" ] \
|
|
;then : \
|
|
"${commit:="$(printenv "${env}_COMMIT")"}" \
|
|
"${checksum:="$(printenv "${env}_SHA256")"}" \
|
|
;fi \
|
|
&& if [ "$from" = github ] || [ "$from" = sourcehut ] \
|
|
;then : \
|
|
&& missing key repo "$repo" \
|
|
&& missing key commit "$commit" \
|
|
&& missing key checksum "$checksum" \
|
|
&& { [ $ok = 1 ] || exit 64 ;} \
|
|
&& username="${repo%%/*}" && project="${repo##*/}" \
|
|
&& if [ ".$username/$project" != ".$repo" ] \
|
|
;then : \
|
|
&& warn "invalid value for key: repo=$repo" \
|
|
&& die "expected format: repo=username/project" \
|
|
;fi \
|
|
&& remote_fn="$commit.tar.gz" \
|
|
&& local_fn="$username!$project-$remote_fn" \
|
|
&& pathy="$repo/archive/$remote_fn" \
|
|
&& case "$from" in
|
|
(github) remote_url="https://github.com/$pathy" ;; \
|
|
(sourcehut) remote_url="https://git.sr.ht/~$pathy" ;; \
|
|
esac \
|
|
&& sha256="$checksum" \
|
|
&& { [ "${#dest}" != 0 ] || dest="${repo##*/}" ;} \
|
|
;else : \
|
|
&& die "unknown value specified for \"from\": $from" \
|
|
;fi \
|
|
|| exit \
|
|
;}
|
|
|
|
ok=1 from= repo= commit= checksum= env= \
|
|
&& { [ "$#" == 0 ] || argue "$@" ;} \
|
|
&& { [ -d "/tmp" ] || die '/tmp must be mounted (or just exist)' ;} \
|
|
&& missing variable dest "$dest" \
|
|
&& missing variable local_fn "$local_fn" \
|
|
&& missing variable remote_url "$remote_url" \
|
|
&& missing variable sha256 "$sha256" \
|
|
&& { [ $ok = 1 ] || exit 64 ;} \
|
|
&& { : \
|
|
&& printf '%s %s\n' "$sha256" "$local_fn" | sha256sum -c - >/dev/null 2>&1 \
|
|
|| wget -q "$remote_url" -O "$local_fn" \
|
|
&& printf '%s %s\n' "$sha256" "$local_fn" | sha256sum -c - \
|
|
|| { sha256sum "$local_fn"; exit 1 ;} \
|
|
;} \
|
|
&& temp="$(mktemp -d)" \
|
|
&& tar -axof "$local_fn" -C "$temp" \
|
|
&& find "$temp" -mindepth 1 -maxdepth 1 >/tmp/files \
|
|
&& find "$temp" -mindepth 1 -maxdepth 1 -type d >/tmp/dirs \
|
|
&& { [ -d "$dest" ] || mkdir "$dest" ;} \
|
|
&& if [ "$(wc -l </tmp/files)" = 1 ] && [ "$(wc -l </tmp/dirs)" = 1 ] \
|
|
;then : \
|
|
&& find "$temp" -mindepth 2 -maxdepth 2 -exec cp -rp {} "$dest" + \
|
|
;else : \
|
|
&& cp -rp "$temp" "$dest" \
|
|
;fi \
|
|
;
|