Created
April 10, 2020 20:17
-
-
Save OndraZizka/7f62508004ffa080618ed6a164c4b7b5 to your computer and use it in GitHub Desktop.
Switch - simple linux alternative to Alternatives. Switches between versions of apps.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
##################################################################################################### | |
# | |
# This script creates switches between the versions of various tools, | |
# found in /mnt/jqa/sw/tools/ (curently hard-coded). | |
# | |
# Usage: | |
# $ switch maven 2.1.0 | |
# $ mvn ... | |
# | |
# Installation: | |
# * Set PATH to begin with ~/sw/tools/.links (in ~/.bashrc) | |
# | |
# Tools directory structure: | |
# * .../<tool_name>/ | |
# * <tool_version>/ | |
# * <tool_version2>/ | |
# * onSwitch.sh | |
# * onRun.sh | |
# | |
# Callback scripts: | |
# | |
# * onSwitch.sh - called when the version switch is performed. | |
# * Called using: . onSwitch.sh <tool_name> <tool_version> | |
# | |
# * onRun.sh - if present, all tool's runnables will be called through a script, | |
# which will be re-created each time the versions are switched: | |
# | |
# TOOL_NAME=<tool_name> # Few variables are set at the top of the script. | |
# TOOL_VERSION=<...> # 1.2.3 | |
# TOOL_HOME=<...> # Tool home dir - i.e., the dir particular version. | |
# TOOL_RUNNABLE_PATH=<...> # Path to the runnable to be called. | |
# | |
# <content of onRun.sh> # The content is simply pasted here. | |
# <tool_runnable> $@ # Calls the current version of the tool runnable. | |
# | |
# Todo: | |
# * Upon switch, remove links created with previous switch. | |
# * All that belong to the tools/<tool_name> dir (parse the variables at the top of the scripts) | |
# | |
# History: | |
# 2009-12-22: | |
# * Runnables are now searched automatically in TOOL_HOME/bin if there's no runnables.txt. | |
# * Softlinks to executable files also count as runnables. | |
# * Home dir of this script is detected automatically. | |
# * Meta-dirs now start with a dot (.links, .homes, .template). | |
# | |
# | |
##################################################################################################### | |
## | |
## @param $1 Tool name | |
## @param $2 Tool version | |
## @param $3 Tool runnable path | |
## @param $4 TOOL_HOME - path to the home dir of the selected version of the tool. | |
## @param $5 ON_RUN - a script to execute before the runnable is run. | |
## | |
function createRunnableScript { | |
TOOL_RUNNABLE_PATH=$3 | |
TOOL_HOME=$4 | |
ON_RUN=$5 | |
TOOL_RUNNABLE_NAME=`basename $TOOL_RUNNABLE_PATH`; | |
MY_LINK=~/sw/tools/.links/$TOOL_RUNNABLE_NAME | |
if [ -e "$MY_LINK" ] ; then rm $MY_LINK; fi | |
if [ -z "$ON_RUN" ] ; then | |
echo "Creating link $MY_LINK -> $TOOL_RUNNABLE_PATH" | |
ln -s $TOOL_RUNNABLE_PATH $MY_LINK | |
else | |
echo "Creating bash script: $MY_LINK" | |
echo "TOOL_NAME=$1" > $MY_LINK; | |
echo "TOOL_VERSION=$2" >> $MY_LINK; | |
echo "TOOL_HOME=$TOOL_HOME" >> $MY_LINK; | |
echo "TOOL_RUNNABLE_PATH=$TOOL_RUNNABLE_PATH" >> $MY_LINK; | |
cat $ON_RUN >> $MY_LINK; | |
echo "" >> $MY_LINK | |
echo "exec $TOOL_RUNNABLE_PATH \"\$@\"" >> $MY_LINK; | |
fi | |
chmod +x $MY_LINK | |
} | |
## Return value. | |
RET=0 | |
## Determine this script's location ("Tools" home dir). | |
#TOOLS="/home/ondra/sw/tools" | |
#scriptPath=$(cd ${0%/*} && echo $PWD/${0##*/}) | |
scriptPath="$(cd "${0%/*}" 2>/dev/null; echo "$PWD"/"${0##*/}")" | |
# For the case when called through a symlink (eg. sw/tools/.links/switch -> ../switch.sh). | |
scriptPath=`readlink -f "$scriptPath"` | |
TOOLS=`dirname "$scriptPath"` | |
## Install - create the .links dir and a link to the switch.sh script. | |
## Assumes that user will put ~/sw/tools/.links at the beginning of his $PATH. | |
if [ "$1" == "install" ] ; then | |
if [ ! -x ~/sw/tools/.links/switch ] ; then | |
echo "Creating ~/sw/tools/.links/switch -> $scriptPath" | |
mkdir -p ~/sw/tools/.links | |
ln -s $scriptPath ~/sw/tools/.links/switch | |
else | |
echo "~/sw/tools/.links/switch already exists." | |
fi | |
exit; | |
fi | |
while true; do | |
if [ "on" == "$1" ] ; then | |
## No way to export a variable without sourcing this script :( | |
export PATH=~/sw/tools/.links:$PATH | |
fi | |
## No arguments: List available tools and versions. | |
if [ -z "$1" -o -z "$2" ] ; then | |
echo " Usage: switch <tool> <ver>"; | |
echo " Available tools and versions:" | |
for TOOL in `ls -1 --ignore=switch.* --ignore=.* --ignore=_* $TOOLS`; do | |
if [ ! -d "$TOOLS/$TOOL" ] ; then continue; fi | |
#echo " $TOOL `ls --ignore=*.path $TOOLS/$TOOL`"; | |
echo " "$(echo "$TOOL `find -L $TOOLS/$TOOL/ -mindepth 1 -maxdepth 1 -type d | sed 's#.*/##'`"); | |
#tree -diL 1 | |
#ls -l | grep ^d | awk '{print $9}' | |
done | |
break; | |
fi | |
## Has to be sourced for it sets variables into the environment (like M2_HOME). | |
if [ "$0" == "switch.sh" ] ; then | |
echo "This file (switch.sh) has to be source'd ('. switch.sh')."; | |
exit 666; | |
fi | |
## Tool's root dir (contains dirs with concrete versions). | |
TOOL_DIR="$TOOLS/$1" | |
if [ ! -d "$TOOL_DIR" ] ; then echo "Unknown tool: $1"; RET=1; break; fi | |
## Particular version's dir. | |
TOOL_HOME="$TOOL_DIR/$2" | |
if [ ! -d "$TOOL_HOME" ] ; then echo "$1 doesn't have a version: $2"; RET=2; break; fi | |
mkdir -p ~/sw/tools/.links | |
mkdir -p ~/sw/tools/.homes | |
## Commands to perform before running the tool (each time). | |
if [ -x "$TOOL_DIR/onRun.sh" ] ; then | |
ON_RUN=$TOOL_DIR/onRun.sh; | |
fi | |
## Create the HOME links. | |
echo "Creating link ~/sw/tools/.homes/$1 -> $TOOL_HOME" | |
rm ~/sw/tools/.homes/$1 | |
ln -s $TOOL_HOME ~/sw/tools/.homes/$1 | |
## Commands to run upon version switching. | |
if [ -x "$TOOL_DIR/onSwitch.sh" ] ; then | |
echo "Running '$TOOL_DIR/onSwitch.sh $TOOL_HOME'..."; | |
$TOOL_DIR/onSwitch.sh $TOOL_HOME; | |
fi | |
## Tool's runnable from the path. | |
## Check the symlink existence. | |
if [ ! -h $TOOL_DIR/runnable.path ] ; then | |
#echo "Every tool has to have an (invalid) symlink with the path from tool's HOME to the executable."; RET=3; break; | |
true; | |
else | |
TOOL_RUNNABLE_PATH=$TOOL_HOME/`readlink $TOOL_DIR/runnable.path` | |
if [ ! -e "$TOOL_RUNNABLE_PATH" ] ; then echo "Non-existent runnable: $TOOL_RUNNABLE_PATH"; RET=4; break; fi | |
if [ ! -x "$TOOL_RUNNABLE_PATH" ] ; then echo "Non-executable runnable: $TOOL_RUNNABLE_PATH"; RET=5; break; fi | |
## Create a link to the runnable in ~/sw/tools/.links/, named like the tool name. | |
createRunnableScript $1 $2 $TOOL_RUNNABLE_PATH $TOOL_HOME $ON_RUN | |
fi | |
if [ -x "$TOOL_DIR/runnables.txt" ] ; then | |
## Link runnables listed in a file /sw/tools/<tool>/runnables.txt . | |
## TODO: Find automatically all executables from the tool's dir. | |
## Upon creation of those, remove links pointing to the particular tool's dir. | |
for RUNNABLE_SUBPATH in `cat $TOOL_DIR/runnables.txt`; do | |
TOOL_RUNNABLE_PATH=$TOOL_HOME/$RUNNABLE_SUBPATH; | |
if [ ! -e "$TOOL_RUNNABLE_PATH" ] ; then echo "Non-existent runnable: $TOOL_RUNNABLE_PATH"; RET=4; break 2; fi | |
if [ ! -x "$TOOL_RUNNABLE_PATH" ] ; then echo "Non-executable runnable: $TOOL_RUNNABLE_PATH"; RET=5; break 2; fi | |
done | |
for RUNNABLE_SUBPATH in `cat $TOOL_DIR/runnables.txt`; do | |
TOOL_RUNNABLE_PATH=$TOOL_HOME/$RUNNABLE_SUBPATH; | |
createRunnableScript $1 $2 $TOOL_RUNNABLE_PATH $TOOL_HOME $ON_RUN | |
done | |
else | |
## runnables.txt does not exist, scan the dir for executable files and links. | |
#for RUNNABLE_SUBPATH in `ls -l $TOOL_HOME/bin | grep -e ^[-l]..x | cut -b47- | cut -d' ' -f1`; do | |
#TOOL_RUNNABLE_PATH=$TOOL_HOME/bin/$RUNNABLE_SUBPATH; | |
for TOOL_RUNNABLE_PATH in $TOOL_HOME/bin/* ; do if [ -x "$TOOL_RUNNABLE_PATH" -a -f "$TOOL_RUNNABLE_PATH" ] ; then | |
createRunnableScript $1 $2 $TOOL_RUNNABLE_PATH $TOOL_HOME $ON_RUN | |
fi ; done | |
fi | |
break; | |
done # while true | |
## Clear bash's cache. | |
hash -r | |
## If called without `source`, return an exit code. | |
if [ "$0" == "switch.sh" ] ; then exit $RET; fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment