2
0
mirror of https://github.com/bpkg/bpkg synced 2024-11-08 01:10:36 +00:00

Support for GHE and multiple remotes

Change-Id: I87cab44e86ccf35480a4db02f0e0e4089caf970b
This commit is contained in:
Chris Carpita 2014-10-07 15:36:53 -04:00
parent 8fa9a01def
commit 6c5079c099
2 changed files with 137 additions and 47 deletions

View File

@ -94,11 +94,18 @@ bpkg () {
if [ ! -z "${res}" ]; then if [ ! -z "${res}" ]; then
echo echo
echo >&2 "Did you mean one of these?" echo >&2 "Did you mean one of these?"
for r in ${res[@]}; do found=0
for r in "${res[@]}"; do
if [[ "$r" == *"${arg}"* ]]; then if [[ "$r" == *"${arg}"* ]]; then
echo " $ bpkg ${r}" echo " $ bpkg ${r}"
found=1
fi fi
done done
if [ "$found" == "0" ]; then
for r in "${res[@]}"; do
echo " $ bpkg ${r}"
done
fi
return 1 return 1
else else
usage usage

View File

@ -1,9 +1,26 @@
#!/bin/bash #!/bin/bash
BPKG_GIT_REMOTE="${BPKG_GIT_REMOTE:-"https://github.com"}" # Include config rc file if found
BPKG_REMOTE="${BPKG_REMOTE:-"https://raw.githubusercontent.com"}" CONFIG_FILE="$HOME/.bpkgrc"
[ -f "$CONFIG_FILE" ] && source "$CONFIG_FILE"
## set defaults
if [ ${#BPKG_REMOTES[@]} -eq 0 ]; then
BPKG_REMOTES=("${BPKG_REMOTE-https://raw.githubusercontent.com}")
BPKG_GIT_REMOTES=("${BPKG_GIT_REMOTE-https://github.com}")
fi
BPKG_USER="${BPKG_USER:-"bpkg"}" BPKG_USER="${BPKG_USER:-"bpkg"}"
## check parameter consistency
validate_parameters () {
if [ ${#BPKG_GIT_REMOTES[@]} -ne ${#BPKG_REMOTES[@]} ]; then
mesg=`printf "BPKG_GIT_REMOTES differs in size from BPKG_REMOTES array (%d vs %d elements)\n" "${#BPKG_GIT_REMOTES[@]}" "${#BPKG_REMOTES[@]}"`
error "$mesg"
return 1
fi
return 0
}
## outut usage ## outut usage
usage () { usage () {
echo "usage: bpkg-install [-h|--help]" echo "usage: bpkg-install [-h|--help]"
@ -11,6 +28,7 @@ usage () {
echo " or: bpkg-install [-g|--global] <user>/<package>" echo " or: bpkg-install [-g|--global] <user>/<package>"
} }
## format and output message
message () { message () {
if type -f bpkg-term > /dev/null 2>&1; then if type -f bpkg-term > /dev/null 2>&1; then
bpkg-term color "${1}" bpkg-term color "${1}"
@ -65,18 +83,7 @@ info () {
## Install a bash package ## Install a bash package
bpkg_install () { bpkg_install () {
local pkg="" local pkg=""
local cwd="`pwd`"
local user=""
local name=""
local url=""
local uri=""
local version=""
local status=""
local json=""
local let needs_global=0 local let needs_global=0
local let has_pkg_json=1
declare -a local parts=()
declare -a local scripts=()
declare -a args=( "${@}" ) declare -a args=( "${@}" )
for opt in "${@}"; do for opt in "${@}"; do
@ -101,7 +108,7 @@ bpkg_install () {
*) *)
if [ "-" = "${opt:0:1}" ]; then if [ "-" = "${opt:0:1}" ]; then
echo 2>&1 "error: Unknwon argument \`${1}'" echo 2>&1 "error: Unknown argument \`${1}'"
usage usage
return 1 return 1
fi fi
@ -117,29 +124,64 @@ bpkg_install () {
echo echo
## ensure remote is reachable ## Check each remote in order
{ local let i=0
curl -s "${BPKG_REMOTE}" for remote in "${BPKG_REMOTES[@]}"; do
if [ "0" != "$?" ]; then local git_remote=${BPKG_GIT_REMOTES[$i]}
error "Remote unreachable" bpkg_install_from_remote "$pkg" "$remote" "$git_remote" $needs_global
if [ "$?" == "0" ]; then
return 0
elif [ "$?" == "2" ]; then
error "fatal error occurred during install"
return 1 return 1
fi fi
} i=$((i+1))
done
error "package not found on any remote"
return 1
}
## try to install a package from a specific remote
## returns values:
## 0: success
## 1: the package was not found on the remote
## 2: a fatal error occurred
bpkg_install_from_remote () {
local pkg=$1
local remote=$2
local git_remote=$3
local let needs_global=$4
local cwd=$(pwd)
local url=""
local uri=""
local test_uri=""
local version=""
local status=""
local json=""
local user=""
local name=""
local version=""
local auth_param=""
local let has_pkg_json=1
declare -a local pkg_parts=()
declare -a local remote_parts=()
declare -a local scripts=()
## get version if available ## get version if available
{ {
OLDIFS="${IFS}" OLDIFS="${IFS}"
IFS="@" IFS="@"
parts=(${pkg}) pkg_parts=(${pkg})
IFS="${OLDIFS}" IFS="${OLDIFS}"
} }
if [ "1" = "${#parts[@]}" ]; then if [ ${#pkg_parts[@]} -eq 1 ]; then
version="master" version="master"
info "Using latest (master)" #info "Using latest (master)"
elif [ "2" = "${#parts[@]}" ]; then elif [ ${#pkg_parts[@]} -eq 2 ]; then
name="${parts[0]}" name="${pkg_parts[0]}"
version="${parts[1]}" version="${pkg_parts[1]}"
else else
error "Error parsing package version" error "Error parsing package version"
return 1 return 1
@ -149,16 +191,16 @@ bpkg_install () {
{ {
OLDIFS="${IFS}" OLDIFS="${IFS}"
IFS='/' IFS='/'
parts=(${pkg}) pkg_parts=(${pkg})
IFS="${OLDIFS}" IFS="${OLDIFS}"
} }
if [ "1" = "${#parts[@]}" ]; then if [ ${#pkg_parts[@]} -eq 1 ]; then
user="${BPKG_USER}" user="${BPKG_USER}"
name="${parts[0]}" name="${pkg_parts[0]}"
elif [ "2" = "${#parts[@]}" ]; then elif [ ${#pkg_parts[@]} -eq 2 ]; then
user="${parts[0]}" user="${pkg_parts[0]}"
name="${parts[1]}" name="${pkg_parts[1]}"
else else
error "Unable to determine package name" error "Unable to determine package name"
return 1 return 1
@ -169,26 +211,64 @@ bpkg_install () {
name=${name/@*//} name=${name/@*//}
name=${name////} name=${name////}
## build uri portion
uri="/${user}/${name}/${version}" ## check to see if remote is raw with oauth (GHE)
if [ "${remote:0:10}" == "raw-oauth|" ]; then
info "Using OAUTH basic with content requests"
OLDIFS="${IFS}"
IFS="|"
local remote_parts=($remote)
IFS="${OLDIFS}"
local token=${remote_parts[1]}
remote=${remote_parts[2]}
auth_param="-u $token:x-oauth-basic"
uri="/${user}/${name}/raw/${version}"
## If git remote is a URL, and doesn't contain token information, we
## inject it into the <user>@host field
if [[ "$git_remote" == https://* ]] && [[ "$git_remote" != *x-oauth-basic* ]] && [[ "$git_remote" != *${token}* ]]; then
git_remote=${git_remote/https:\/\//https:\/\/$token:x-oauth-basic@}
fi
else
uri="/${user}/${name}/${version}"
fi
## clean up extra slashes in uri ## clean up extra slashes in uri
uri=${uri/\/\///} uri=${uri/\/\///}
info "Install $uri from remote $remote [$git_remote]"
## Ensure remote is reachable
## If a remote is totally down, this will be considered a fatal
## error since the user may have intended to install the package
## from the broken remote.
{
status=$(curl $auth_param -s "${remote}" -w '%{http_code}' -o /dev/null)
if [ "0" != "$?" ] || (( status >= 400 )); then
error "Remote unreachable: $remote"
return 2
fi
}
## build url ## build url
url="${BPKG_REMOTE}${uri}" url="${remote}${uri}"
repo_url=$git_remote/$user/$name.git
## determine if `package.json' exists at url ## determine if `package.json' exists at url
{ {
status=$(curl -sL "${url}/package.json?`date +%s`" -w '%{http_code}' -o /dev/null) status=$(curl $auth_param -sL "${url}/package.json?`date +%s`" -w '%{http_code}' -o /dev/null)
if [ "0" != "$?" ] || (( status >= 400 )); then if [ "0" != "$?" ] || (( status >= 400 )); then
warn "Package doesn't exist" warn "package.json doesn't exist"
has_pkg_json=0 has_pkg_json=0
# check to see if there's a Makefile. If not, this is not a valid package
status=$(curl $auth_param -sL "${url}/Makefile?`date +%s`" -w '%{http_code}' -o /dev/null)
if [ "0" != "$?" ] || (( status >= 400 )); then
warn "Makefile not found, skipping remote: $url"
return 1
fi
fi fi
} }
## read package.json ## read package.json
json=$(curl -sL "${url}/package.json?`date +%s`") json=$(curl $auth_param -sL "${url}/package.json?`date +%s`")
if (( 1 == $has_pkg_json )); then if (( 1 == $has_pkg_json )); then
## check if forced global ## check if forced global
@ -212,7 +292,7 @@ bpkg_install () {
fi fi
## build global if needed ## build global if needed
if [ "1" = "${needs_global}" ]; then if (( 1 == $needs_global )); then
if (( 1 == $has_pkg_json )); then if (( 1 == $has_pkg_json )); then
## install bin if needed ## install bin if needed
build="$(echo -n ${json} | bpkg-json -b | grep '\["install"\]' | awk '{$1=""; print $0 }' | tr -d '\"')" build="$(echo -n ${json} | bpkg-json -b | grep '\["install"\]' | awk '{$1=""; print $0 }' | tr -d '\"')"
@ -225,19 +305,21 @@ bpkg_install () {
build="make install" build="make install"
fi fi
info "install: \`${build}'"
{( {(
## go to tmp dir ## go to tmp dir
cd $( [ ! -z $TMPDIR ] && echo $TMPDIR || echo /tmp) && cd $( [ ! -z $TMPDIR ] && echo $TMPDIR || echo /tmp) &&
## prune existing ## prune existing
rm -rf ${name}-${version} && rm -rf ${name}-${version} &&
## shallow clone ## shallow clone
git clone ${BPKG_GIT_REMOTE}/${user}/${name}.git ${name}-${version} > /dev/null 2>&1 && info "Cloning $repo_url to $name-$version"
git clone $repo_url ${name}-${version} &&
( (
## move into directory ## move into directory
cd ${name}-${version} && cd ${name}-${version} &&
## build ## build
eval "${build}" info "Performing install: \`${build}'"
build_output=$(eval "${build}")
echo "$build_output"
) && ) &&
## clean up ## clean up
rm -rf ${name}-${version} rm -rf ${name}-${version}
@ -257,7 +339,7 @@ bpkg_install () {
mkdir -p "${cwd}/deps/${name}" mkdir -p "${cwd}/deps/${name}"
## copy package.json over ## copy package.json over
curl -sL "${url}/package.json" -o "${cwd}/deps/${name}/package.json" curl $auth_param -sL "${url}/package.json" -o "${cwd}/deps/${name}/package.json"
## grab each script and place in deps directory ## grab each script and place in deps directory
for (( i = 0; i < ${#scripts[@]} ; ++i )); do for (( i = 0; i < ${#scripts[@]} ; ++i )); do
@ -265,7 +347,7 @@ bpkg_install () {
local script="$(echo ${scripts[$i]} | xargs basename )" local script="$(echo ${scripts[$i]} | xargs basename )"
info "fetch" "${url}/${script}" info "fetch" "${url}/${script}"
info "write" "${cwd}/deps/${name}/${script}" info "write" "${cwd}/deps/${name}/${script}"
curl -sL "${url}/${script}" -o "${cwd}/deps/${name}/${script}" curl $auth_param -sL "${url}/${script}" -o "${cwd}/deps/${name}/${script}"
) )
done done
fi fi
@ -273,9 +355,10 @@ bpkg_install () {
return 0 return 0
} }
## Use as lib or perform install
if [[ ${BASH_SOURCE[0]} != $0 ]]; then if [[ ${BASH_SOURCE[0]} != $0 ]]; then
export -f bpkg_install export -f bpkg_install
else elif validate_parameters; then
bpkg_install "${@}" bpkg_install "${@}"
exit $?
fi fi
exit $?