442 lines
11 KiB
Bash
442 lines
11 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
#
|
|
# bash >= 4.x required
|
|
#
|
|
|
|
#
|
|
# DEFINES
|
|
#
|
|
|
|
# boolean bash convention ( inverse )
|
|
declare -A J_OPT;
|
|
|
|
TRUE=0
|
|
FALSE=1
|
|
|
|
J_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
|
|
unamestr=`uname`
|
|
if [ -z "$J_PATH_MODULES" ]; then
|
|
if [[ "$unamestr" == 'Darwin' ]]; then
|
|
J_PATH_MODULES=$(greadlink -f "$J_PATH/../../")
|
|
else
|
|
J_PATH_MODULES=$(readlink -f "$J_PATH/../../")
|
|
fi
|
|
fi
|
|
|
|
for i in "$@"
|
|
do
|
|
case $i in
|
|
--parent=*) #internally used
|
|
J_OPT[parent]="${i#*=}"
|
|
shift
|
|
;;
|
|
--child=*) #internally used
|
|
J_OPT[child]="${i#*=}"
|
|
shift
|
|
;;
|
|
*)
|
|
# unknown option
|
|
;;
|
|
esac
|
|
done
|
|
|
|
J_PARAMS="$@"
|
|
|
|
function Joiner:is_submodule()
|
|
{
|
|
path=$1
|
|
(cd "$path" && cd "$(git rev-parse --show-toplevel 2>&1)/.."
|
|
git rev-parse --is-inside-work-tree 2>&1) | grep -q true
|
|
}
|
|
|
|
|
|
function Joiner:_help() {
|
|
hasReq=$1
|
|
firstParam=$2
|
|
msg=$3
|
|
|
|
if [ $hasReq = false ]; then
|
|
echo "Argument missing: $msg"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$firstParam" = "--help" || "$firstParam" = "-h" ]]; then
|
|
echo "Help: $msg"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
function Joiner:_searchFirstValiPath() {
|
|
path="$1"
|
|
until $(cd -- "$path")
|
|
do
|
|
case "$path" in(*[!/]/*)
|
|
path="${path%/*}"
|
|
;;
|
|
(*)
|
|
! break
|
|
esac
|
|
done 2>/dev/null
|
|
echo "$path"
|
|
}
|
|
|
|
#
|
|
# JOINER FUNCTIONS
|
|
#
|
|
|
|
function Joiner:add_repo() (
|
|
set -e
|
|
url="$1"
|
|
name=${2:-""}
|
|
branch=${3:-"master"}
|
|
basedir="${4:-""}"
|
|
|
|
[[ -z $url ]] && hasReq=false || hasReq=true
|
|
Joiner:_help $hasReq "$1" "Syntax: joiner.sh add-repo [-d] [-e] url name branch [basedir]"
|
|
|
|
# retrieving info from url if not set
|
|
if [[ -z $name ]]; then
|
|
basename=$(basename $url)
|
|
name=${basename%%.*}
|
|
|
|
if [[ -z "$basedir" ]]; then
|
|
dir=$(dirname "$url")
|
|
basedir=$(basename "$dir")
|
|
fi
|
|
|
|
name="${name,,}" #to lowercase
|
|
basedir="${basedir,,}" #to lowercase
|
|
fi
|
|
|
|
path="$J_PATH_MODULES/$basedir/$name"
|
|
changed="yes"
|
|
|
|
if [ -e "$path/.git/" ]; then
|
|
# if exists , update
|
|
git --git-dir="$path/.git/" rev-parse && git --git-dir="$path/.git/" pull origin $branch | grep 'Already up-to-date.' && changed="no" || true
|
|
else
|
|
# otherwise clone
|
|
git clone $url -c advice.detachedHead=0 -b $branch "$path"
|
|
fi
|
|
|
|
if [ "$?" -ne "0" ]; then
|
|
return $FALSE
|
|
fi
|
|
|
|
# parent/child to avoid redundancy
|
|
[[ -f $path/install.sh && "$changed" = "yes"
|
|
&& "${J_OPT[parent]}" != "$path" && "${J_OPT[child]}" != "$path" ]] && bash "$path/install.sh" --child="${J_OPT[parent]}" --parent="$path" $J_PARAMS
|
|
|
|
return $TRUE
|
|
)
|
|
|
|
function Joiner:add_git_submodule() (
|
|
set -e
|
|
url=$1
|
|
name=${2:-""}
|
|
branch=${3:-"master"}
|
|
basedir=${4:-""}
|
|
|
|
[[ -z $url ]] && hasReq=false || hasReq=true
|
|
Joiner:_help $hasReq "$1" "Syntax: joiner.sh add-git-submodule [-d] [-e] url name branch [basedir]"
|
|
|
|
# retrieving info from url if not set
|
|
if [[ -z $name ]]; then
|
|
basename=$(basename $url)
|
|
name=${basename%%.*}
|
|
|
|
if [[ -z $basedir ]]; then
|
|
dir=$(dirname $url)
|
|
basedir=$(basename $dir)
|
|
fi
|
|
|
|
name="${name,,}" #to lowercase
|
|
basedir="${basedir,,}" #to lowercase
|
|
fi
|
|
|
|
path="$J_PATH_MODULES/$basedir/$name"
|
|
valid_path=`Joiner:_searchFirstValiPath "$path"`
|
|
rel_path=${path#$valid_path}
|
|
rel_path=${rel_path#/}
|
|
|
|
if [ -e $path/ ]; then
|
|
# if exists , update
|
|
(cd "$path" && git pull origin $branch)
|
|
(cd "$valid_path" && git submodule update -f --init $rel_path)
|
|
else
|
|
# otherwise add
|
|
(cd "$valid_path" && git submodule add -f -b $branch $url $rel_path)
|
|
(cd "$valid_path" && git submodule update -f --init $rel_path)
|
|
fi
|
|
|
|
if [ "$?" -ne "0" ]; then
|
|
return $FALSE
|
|
fi
|
|
|
|
# parent/child to avoid redundancy
|
|
[[ -f $path/install.sh && "$changed" = "yes"
|
|
&& "${J_OPT[parent]}" != "$path" && "${J_OPT[child]}" != "$path" ]] && bash "$path/install.sh" --child="${J_OPT[parent]}" --parent="$path" $J_PARAMS
|
|
|
|
return $TRUE
|
|
)
|
|
|
|
function Joiner:add_file() (
|
|
set -e
|
|
declare -A _OPT;
|
|
for i in "$@"
|
|
do
|
|
case $i in
|
|
--unzip|-z)
|
|
_OPT[unzip]=true
|
|
shift
|
|
;;
|
|
*)
|
|
# unknown option
|
|
;;
|
|
esac
|
|
done
|
|
|
|
source=$1
|
|
destination="$J_PATH_MODULES/$2"
|
|
|
|
[[ -z $source ]] && hasReq=false || hasReq=true
|
|
Joiner:_help $hasReq "$1" "Syntax: joiner.sh add-file [-d] [-e] [-z] source [destination]"
|
|
|
|
if [[ "$destination" =~ '/'$ ]]; then
|
|
mkdir -p "$destination"
|
|
else
|
|
mkdir -p "$(dirname $destination)"
|
|
fi
|
|
|
|
[ ! -e $J_PATH_MODULES/$2 ] && curl -o "$destination" "$source"
|
|
|
|
if [ "${_OPT[unzip]}" = true ]; then
|
|
dir=$(dirname $destination)
|
|
unzip -d $dir $destination
|
|
rm $destination
|
|
|
|
filename=$(basename -- "$destination")
|
|
newpath="$dir${filename%%.*}"
|
|
|
|
# parent/child to avoid redundancy
|
|
[[ -f $newpath/install.sh && "$changed" = "yes"
|
|
&& "${J_OPT[parent]}" != "$newpath" && "${J_OPT[child]}" != "$newpath" ]] && bash "$newpath/install.sh" --child="${J_OPT[parent]}" --parent="$newpath" $J_PARAMS
|
|
fi
|
|
|
|
if [ "$?" -ne "0" ]; then
|
|
return $FALSE
|
|
fi
|
|
|
|
return $TRUE
|
|
)
|
|
|
|
function Joiner:upd_repo() (
|
|
set -e
|
|
url=$1
|
|
name=${2:-""}
|
|
branch=${3:-"master"}
|
|
basedir=${4:-""}
|
|
|
|
[[ -z $url ]] && hasReq=false || hasReq=true
|
|
Joiner:_help $hasReq "$1" "Syntax: joiner.sh upd-repo [-d] [-e] url name branch [basedir]"
|
|
|
|
# retrieving info from url if not set
|
|
if [[ -z $name ]]; then
|
|
basename=$(basename $url)
|
|
name=${basename%%.*}
|
|
|
|
if [[ -z $basedir ]]; then
|
|
dir=$(dirname $url)
|
|
basedir=$(basename $dir)
|
|
fi
|
|
|
|
name="${name,,}" #to lowercase
|
|
basedir="${basedir,,}" #to lowercase
|
|
fi
|
|
|
|
path="$J_PATH_MODULES/$basedir/$name"
|
|
|
|
if [[ -z $url ]]; then
|
|
url=`git --git-dir="$path/.git" remote get-url origin`
|
|
fi
|
|
|
|
if [[ `Joiner:is_submodule "$path"` = true ]]; then
|
|
Joiner:add_git_submodule $@
|
|
else
|
|
Joiner:add_repo $@
|
|
fi
|
|
|
|
if [ "$?" -ne "0" ]; then
|
|
return $FALSE
|
|
fi
|
|
|
|
return $TRUE
|
|
)
|
|
|
|
function Joiner:remove() (
|
|
set -e
|
|
name=$1
|
|
basedir=$2
|
|
|
|
[[ -z $name ]] && hasReq=false || hasReq=true
|
|
Joiner:_help $hasReq "$1" "Syntax: joiner.sh remove name [basedir]"
|
|
|
|
path="$J_PATH_MODULES/$basedir/$name"
|
|
|
|
if [ -d "$path" ]; then
|
|
rm -r --interactive=never "$path"
|
|
[[ -f $path/uninstall.sh ]] && bash "$path/uninstall.sh" $J_PARAMS
|
|
elif [ -f "$path" ]; then
|
|
rm --interactive=never "$path"
|
|
else
|
|
return $FALSE
|
|
fi
|
|
|
|
return $TRUE
|
|
)
|
|
|
|
function Joiner:with_dev() (
|
|
set -e
|
|
if [ "${J_OPT[dev]}" = true ]; then
|
|
return $TRUE;
|
|
else
|
|
return $FALSE;
|
|
fi
|
|
)
|
|
|
|
function Joiner:with_extras() (
|
|
set -e
|
|
if [ "${J_OPT[extra]}" = true ]; then
|
|
return $TRUE;
|
|
else
|
|
return $FALSE;
|
|
fi
|
|
)
|
|
|
|
#
|
|
# Parsing parameters
|
|
#
|
|
function Joiner:self_update() {
|
|
if [ -e "$J_PATH/.git/" ]; then
|
|
# self update
|
|
if [ ! -z "$J_VER_REQ" ]; then
|
|
# if J_VER_REQ is defined then update only if tag is different
|
|
_cur_branch=`git --git-dir="$J_PATH/.git/" --work-tree="$J_PATH/" rev-parse --abbrev-ref HEAD`
|
|
_cur_ver=`git --git-dir="$J_PATH/.git/" --work-tree="$J_PATH/" name-rev --tags --name-only $_cur_branch`
|
|
if [ "$_cur_ver" != "$J_VER_REQ" ]; then
|
|
git --git-dir="$J_PATH/.git/" --work-tree="$J_PATH/" rev-parse && git --git-dir="$J_PATH/.git/" fetch --tags origin "$_cur_branch" --quiet
|
|
git --git-dir="$J_PATH/.git/" --work-tree="$J_PATH/" checkout "tags/$J_VER_REQ" -b "$_cur_branch"
|
|
fi
|
|
else
|
|
# else always try to keep at latest available version (worst performances)
|
|
|
|
git --git-dir="$J_PATH/.git/" --work-tree="$J_PATH/" rev-parse && git --git-dir="$J_PATH/.git/" --work-tree="$J_PATH/" fetch origin "$_cur_branch" --quiet
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function Joiner:_checkOptions() {
|
|
for i in "$@"
|
|
do
|
|
case $i in
|
|
-e=*|--extras=*)
|
|
echo "Extras enabled"
|
|
J_OPT[extra]="${i#*=}"
|
|
shift
|
|
;;
|
|
--dev|-d)
|
|
echo "Development enabled"
|
|
J_OPT[dev]=true
|
|
shift
|
|
;;
|
|
*)
|
|
# unknown option
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
function Joiner:menu() {
|
|
PS3='[Please enter your choice]: '
|
|
options=(
|
|
"add-repo (a): download and install a module from git repository." # 1
|
|
"upd-repo (u): update a module." # 2
|
|
"add-git-submodule (s): download and install module from git repository as git submodule." # 3
|
|
"add-file (f): download and install a file or zipped folder." # 4
|
|
"remove (r): uninstall and remove a module." # 5
|
|
"self-update (j): Update joiner version to the latest stable (master branch)"
|
|
"quit: Exit from this menu"
|
|
)
|
|
|
|
function _switch() {
|
|
_reply="$1"
|
|
shift
|
|
|
|
Joiner:_checkOptions
|
|
|
|
_opt="$@"
|
|
|
|
case $_reply in
|
|
""|"a"|"add-repo"|"1")
|
|
Joiner:add_repo $_opt
|
|
;;
|
|
""|"u"|"upd-repo"|"2")
|
|
Joiner:upd_repo $_opt
|
|
;;
|
|
""|"s"|"add-git-submodule"|"3")
|
|
Joiner:add_git_submodule $_opt
|
|
;;
|
|
""|"f"|"add-file"|"4")
|
|
Joiner:add_file $_opt
|
|
;;
|
|
""|"r"|"remove"|"5")
|
|
Joiner:remove $_opt
|
|
;;
|
|
""|"j"|"self-update"|"6")
|
|
Joiner:self_update
|
|
;;
|
|
""|"quit"|"7")
|
|
echo "Goodbye!"
|
|
exit
|
|
;;
|
|
""|"--help")
|
|
echo "Available commands:"
|
|
printf '%s\n' "${options[@]}"
|
|
echo "Arguments:"
|
|
echo "-d, --dev: install also dev dependencies"
|
|
echo "-e, --extras: install extra dependencies (suggested by module)"
|
|
echo "-z, --unzip: extract a zipped file downloaded by add-file command"
|
|
;;
|
|
*) echo "invalid option, use --help option for the commands list";;
|
|
esac
|
|
}
|
|
|
|
while true
|
|
do
|
|
# run option directly if specified in argument
|
|
[ ! -z $1 ] && _switch $@
|
|
[ ! -z $1 ] && exit 0
|
|
|
|
echo ""
|
|
echo "==== JOINER MENU ===="
|
|
select opt in "${options[@]}"
|
|
do
|
|
echo ""
|
|
_switch $REPLY
|
|
break
|
|
done
|
|
done
|
|
}
|
|
|
|
# Call menu only when run from command line.
|
|
# if you wish to run joiner menu when sourced
|
|
# you must call the relative function
|
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
Joiner:menu $@
|
|
else
|
|
Joiner:_checkOptions $@
|
|
fi
|
|
|