Skip to content

Commit

Permalink
feat(dist): add installer script
Browse files Browse the repository at this point in the history
  • Loading branch information
SKalt committed Mar 30, 2022
1 parent 11684d2 commit 760be44
Show file tree
Hide file tree
Showing 2 changed files with 363 additions and 34 deletions.
178 changes: 144 additions & 34 deletions scripts/download_release.sh
Original file line number Diff line number Diff line change
@@ -1,20 +1,75 @@
#!/usr/bin/env sh
resp=/tmp/latest
# shellcheck disable=SC2016
releases=/tmp/latest
checksums=/tmp/checksums
log_file=/tmp/git-cc-download.log
repo=skalt/git-cc
usage_message="$0 [apk|deb|rpm|tar.gz|exe]
download a release of git-cc for your OS and chip.

# global script state
fmt=
dry_run=false # set to 'true' to for a dry run

usage_message="$0 [-h|--help] [--dry-run] [FMT]
download a release of git-cc for your OS and instruction set architecture.
ARGS:
-h|--help print this message and exit
--dry-run print rather than follow the download url for the binary
FMT The download format. Valid values are .apk, .deb, .rpm, .tar.gz,
and .exe; default .tar.gz.
"

usage() { echo "$usage_message"; }
is_installed() { command -v "$1" 1>/dev/null 2>&1; }

should_use_color() {
test -t 1 && # stdout (device 1) is a tty
test -z "${NO_COLOR:-}" && # the NO_COLOR variable isn't set
is_installed tput
}

if should_use_color; then
red="$(tput setaf 1)"
orange="$(tput setaf 3)"
blue="$(tput setaf 4)"
gray="$(tput setaf 7)"
reset="$(tput sgr0)"
else
red=""
orange=""
blue=""
gray=""
reset=""
fi

log_message() {
level="$1"; shift;
color="$1"; shift;
message="$*"
printf "%s\t%s\t%s\n" "$level" "$(date '+%Y-%m-%dT%H:%M:%S%z')" "$message" |
tee -a $log_file |
sed "s/^/${color}/g; s/\t/\t${gray}/1; s/\t/${reset}\t/2;" >&2
}

log_info() { log_message "INFO" "$blue" "$*"; }
log_warning() { log_message "WARN" "$orange" "$*"; }
log_error() { log_message "ERROR" "$red" "$*"; }
fail() { log_error "$1" && exit "${2:-1}"; }

dl_url() { echo "https://github.com/$repo/releases/download/$1/$2"; }
json_values() { cat - | grep -e "$1" | awk -F '"' '{ print $4 }'; }

download_metadata() {
curl -s https://api.github.com/repos/$repo/releases/latest | tee $resp \
| json_values "browser_download_url" \
| grep "checksums.txt" \
| xargs curl -sL | tee $checksums
url="https://api.github.com/repos/$repo/releases/latest"
# log_info "downloading release metadata to $releases"
curl -s "$url" |
tee $releases |
json_values "browser_download_url" |
grep "checksums.txt" |
xargs curl -Ls |
tee $checksums
}

get_arch() {
case "$(arch)" in
x86_64|x64|amd64) echo "amd64" ;;
Expand All @@ -28,50 +83,105 @@ get_os() {
case "$os" in
*linux) echo "linux";;
*darwin) echo "darwin";;
*windows) echo "windows";; # somehow
*) echo "unprocessable os '$os'" >/dev/stderr && return 1;;
*windows) echo "windows";; # if running from git bash, I guess
*) fail "unprocessable os '$os'";;
esac
}

get_fmt() {
case "$1" in
case "${1:-}" in
'') echo ".tar.gz";;
.tar.gz|tar.gz|gz|tar) echo ".tar.gz";;
.apk|apk) echo ".apk";;
.deb|deb) echo ".deb";;
.rpm|rpm) echo ".rpm";;
.exe|exe) echo ".exe";;
*) fail "invalid format: $1"
esac
}


get_name() {
arch="$1"; os="$2"; fmt="$3";
download_metadata | # prints the checksum file in `sum name` format
awk '{ print $2 }' | # extract the names
grep "$arch" | # search for a compatible release
grep -i "$os" |
grep "$fmt" |
tail -1
}

check_sha256() {
if is_installed sha256sum; then sha256sum --ignore-missing -c $checksums;
elif is_installed shasum; then shasum -a 256 --ignore-missing -c $checksums;
else return 127; fi
cmd=""
if is_installed sha256sum; then
cmd="sha256sum --ignore-missing -c $checksums";
elif is_installed shasum; then
cmd="shasum -a 256 --ignore-missing -c $checksums";
else
fail 'unable to find `sha256sum` or `shasum`' 127;
fi

if test "$dry_run" = "true"; then
log_info "would check shasums by running \`$cmd\` in /tmp"
else
log_info "checking shasums: running \`$cmd\` in /tmp"
(cd /tmp; eval "$cmd")
# need to cd into /tmp to run the check since the paths in the checksums file
#are relative
fi
}

download_git_cc() {
version="$1"
name="$2"
url=; url="$(dl_url "$version" "$name")"
if test "$dry_run" = "true"; then
log_info "would download $name into /tmp/"
else
log_info "downloading $name into /tmp/"
curl -sL "$url" > "/tmp/$name"
fi
}

main() {
case "$1" in
-h|--help) usage && return 0;
esac
set -eu
os="$(get_os)"; echo "os=$os"
arch="$(get_arch)"; echo "arch=$arch"
fmt="$(get_fmt "${1:-}")"; echo "format=$fmt"
name="$(
download_metadata \
| awk '{ print $2 }' \
| grep "$arch" \
| grep -i "$os" \
| grep "$fmt" \
| tail -1
)"
version="$(json_values 'tag_name' < $resp)";
echo "version=$version"
echo "name=$name"
while [ -n "${1:-}" ]; do
case "$1" in
-h|--help) usage && return 0;;
--dry-run) export dry_run=true; shift;;
*)
if test -n "$fmt"; then
log_error "FMT can only be passed once"
usage
exit 1
else
fmt="$(get_fmt "$1")"
shift
fi
;;
esac
done

os="$(get_os)";
arch="$(get_arch)";
if test -z "${fmt:-}"; then fmt="$(get_fmt "")"; fi

log_info "dry_run=$dry_run"
log_info "os=$os"
log_info "arch=$arch"
log_info "format=$fmt"

name="$(get_name "$arch" "$os" "$fmt")"
log_info "name=$name"

version="$(json_values 'tag_name' < $releases)";
log_info "version=$version"

if [ -z "${name:-}" ]; then
echo "unfortunately, there's no prebuilt release for $fmt and $arch" >&2;
echo 'try `go get github.com/skalt/git-cc` to compile it yourself.' >&2;
exit 1;
fail "unfortunately, there's no prebuilt release for $fmt and $arch. " \
'try `go get github.com/skalt/git-cc` to compile it yourself.'
fi
curl -sLO "$(dl_url "$version" "$name")"
download_git_cc "$version" "$name"
check_sha256
}

Expand Down
Loading

0 comments on commit 760be44

Please sign in to comment.