#!/usr/bin/env bash set -e DEFAULT_RELEASE="latest" DEFAULT_MATCH="browser_download_url" main(){ echo if [ -z "$REPO" ] && [ -z "$DD_URL" ]; then usage exit 1 fi if [ -z "$DD_URL" ]; then RELEASE=$DEFAULT_RELEASE if [ ! -z "$TAG" ]; then RELEASE="tags/$TAG" fi echo "Query for $REPO" echo api_url="https://api.github.com/repos/$REPO/releases/$RELEASE" if $LIST_TAGS; then api_url="https://api.github.com/repos/$REPO/tags" fi if $VERBOSE; then echo "API: $api_url" echo fi candidates=$(curl $SET_AUTH $SET_PROXY -sSfL "$api_url") if $LIST_TAGS && [ ! -z "$TAG" ]; then candidates=$(echo "$candidates" | grep -P "$TAG") fi if [ ! -z "$MATCH_STAGE_1" ]; then candidates=$(echo "$candidates" | grep -P "$MATCH_STAGE_1") fi if [ ! -z "$MATCH_STAGE_2" ]; then candidates=$(echo "$candidates" | grep -P "$MATCH_STAGE_2") fi if $VERBOSE; then echo "Candidates:" echo "$candidates" echo fi dl_url=$(echo "$candidates" | cut -d '"' -f 4) else dl_url="$DD_URL" fi if [ $(echo -e "$dl_url" | wc -l) -ne 1 ] || [ -z "$dl_url" ]; then exit 0 fi echo "Download From:" echo "$dl_url" echo if [ -z "$PROG_PATH" ]; then exit 0 fi echo "Prepare tmp directory" pkgname=$(echo "$dl_url" | awk -F'/' '{print $NF}') if [ ! -z "$PKG_NAME" ]; then pkgname="$PKG_NAME" fi tmp_dir="/tmp/$pkgname-$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)" mkdir -p "$tmp_dir" pushd "$tmp_dir" >/dev/null ext=$(echo "$pkgname" | awk -F'.' '{print $NF}') ext_tar=$(echo "$pkgname" | awk -F'.' '{print $(NF-1)}') dirname= echo "Downloading..." if $NO_INFLATE; then curl $SET_AUTH $SET_PROXY -SfLo $pkgname "$dl_url" else if (echo $ext | grep -i zip) &>/dev/null; then curl $SET_AUTH $SET_PROXY -SfLo source_pkg.zip "$dl_url" unzip -o source_pkg.zip >/dev/null dirname=$(rev <<< "$pkgname" | cut -d '.' -f 2- | rev) elif (echo $ext | grep -i tar) || (echo $ext | grep -i tgz) &>/dev/null; then curl $SET_AUTH $SET_PROXY -SfLo source_pkg.$ext "$dl_url" tar -xvf source_pkg.$ext >/dev/null dirname=$(rev <<< "$pkgname" | cut -d '.' -f 2- | rev) elif (echo $ext_tar | grep -i tar) &>/dev/null; then curl $SET_AUTH $SET_PROXY -SfLo source_pkg.tar.$ext "$dl_url" tar -xvf source_pkg.tar.$ext >/dev/null dirname=$(rev <<< "$pkgname" | cut -d '.' -f 3- | rev) elif (echo $ext | grep -i deb) &>/dev/null; then if command -v dpkg &>/dev/null; then curl $SET_AUTH $SET_PROXY -SfLo source_pkg.deb "$dl_url" dpkg -i source_pkg.deb echo "Install Complete!" popd >/dev/null rm -rf "$tmp_dir" exit 0 else echo "ERROR: Not Debian System" popd >/dev/null rm -rf "$tmp_dir" exit 1 fi else echo "ERROR: Unknown Format $pkgname" popd >/dev/null rm -rf "$tmp_dir" exit 1 fi echo "Inflation complete" rm source_pkg.* fi if [ ! -z "$PKG_DIR" ]; then if $VERBOSE; then echo echo "Source dir:" fi if [ "$PKG_DIR" = "-" ]; then if [ -z $SED_EXP ]; then current_dir=$dirname else current_dir=$(echo $dirname | sed -E $SED_EXP) fi if [ -d "$current_dir" ]; then if $VERBOSE; then echo "$current_dir" fi cd "$current_dir" else echo "ERROR: Wrong dir inside package!" popd >/dev/null rm -rf "$tmp_dir" exit 1 fi else indices=($PKG_DIR) for index in ${indices[@]}; do if [ "$index" -ge 0 ] &>/dev/null; then dirs=$(ls -l|awk '/^d/ {print $NF}') arr_dirs=($dirs) current_dir=${arr_dirs[$index]} else current_dir=$index fi if [ -d "$current_dir" ]; then if $VERBOSE; then echo "$current_dir" fi cd "$current_dir" else echo "ERROR: Wrong dir inside package!" popd >/dev/null rm -rf "$tmp_dir" exit 1 fi done fi fi CWD=$(pwd) if [ ${CWD:0:5} != "/tmp/" ]; then echo "ERROR: Wrong dir inside package!" popd >/dev/null rm -rf "$tmp_dir" exit 1 fi PROG_PATH=$(realpath -m "$PROG_PATH"); echo echo "Installing..." echo "From: $CWD" echo "To: $PROG_PATH/" if [ ! -d "$PROG_PATH" ]; then if [ -e "$PROG_PATH" ]; then echo "ERROR: Program path is not directory!" popd >/dev/null rm -rf "$tmp_dir" exit 1 else mkdir -p "$PROG_PATH" fi fi if [ -z "$PROG_NAME" ]; then cp -fr * "$PROG_PATH/" else if [ ! -f "$PROG_NAME" ]; then echo "ERROR: $PROG_NAME not found!" popd >/dev/null rm -rf "$tmp_dir" exit 1 fi if command -v md5sum &>/dev/null; then echo "Version check" old_hash=$(md5sum -bz "$PROG_PATH/$PROG_NAME" | awk '{print $1}') new_hash=$(md5sum -bz "$PROG_NAME" | awk '{print $1}') if [ "$new_hash" = "$old_hash" ]; then echo "No need to update." popd >/dev/null rm -rf "$tmp_dir" exit 0 fi fi if $FILE_COPY; then cp -f "$PROG_NAME" "$PROG_PATH/" else cp -fr * "$PROG_PATH/" fi chmod +x "$PROG_PATH/$PROG_NAME" fi echo "Install Complete!" popd >/dev/null rm -rf "$tmp_dir" if [ ! -z "$CMD_RELOAD" ]; then $CMD_RELOAD fi } usage(){ echo "Usage: $0 [OPTIONS]"; echo "Options:"; echo " -r Github repo"; echo " -t Release tag (default: $DEFAULT_RELEASE)"; echo " -k Match stage 1 with regexp (default: $DEFAULT_MATCH)"; echo " -m Match stage 2 with regexp"; echo " -l List all tags"; echo " -u Direct download url (bypass Github repo)"; echo " -b Do not inflate"; echo " -p Program path"; echo " -n Program name"; echo " -f Copy program name file only (when -n is set)"; echo " -o Package name"; echo " -d Dir inside package:"; echo " '-' as packge name without extension"; echo " or space separated string, can mixed with:"; echo " number as index"; echo " string as name"; echo " -e Expression for sed (only for '-d -')"; echo " -c Command for reload"; echo " -v Verbose"; echo " -a Auth user[:pass]"; echo " -x Proxy [protocol://]host[:port]"; } REPO= TAG= MATCH_STAGE_1=$DEFAULT_MATCH MATCH_STAGE_2= LIST_TAGS=false DD_URL= NO_INFLATE=false PROG_PATH= PROG_NAME= FILE_COPY=false PKG_NAME= PKG_DIR= SED_EXP= CMD_RELOAD= VERBOSE=false SET_AUTH= SET_PROXY= while getopts ":r:t:k:m:lu:bp:n:fo:d:e:c:va:x:" OPT; do case $OPT in r) REPO=$OPTARG; ;; t) TAG=$OPTARG; ;; k) MATCH_STAGE_1=$OPTARG; ;; m) MATCH_STAGE_2=$OPTARG; ;; l) LIST_TAGS=true; ;; u) DD_URL=$OPTARG; ;; b) NO_INFLATE=true; ;; p) PROG_PATH=$OPTARG; ;; n) PROG_NAME=$OPTARG; ;; f) FILE_COPY=true; ;; o) PKG_NAME=$OPTARG; ;; d) PKG_DIR=$OPTARG; ;; e) SED_EXP=$OPTARG; ;; c) CMD_RELOAD=$OPTARG; ;; v) VERBOSE=true; ;; a) SET_AUTH="-u $OPTARG"; ;; x) SET_PROXY="-x $OPTARG"; ;; :) echo "Option -$OPTARG requires an argument."; exit 1;; ?) echo "Invalid Option: -$OPTARG"; usage; exit 1;; esac; done; main