Mercurial > hg > beaglert
changeset 436:e09c156e04f4 better_scripting
Attempt at unified script for all things bela
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Fri, 17 Jun 2016 18:40:04 +0100 |
parents | cea66c2af560 |
children | |
files | scripts/bela.sh |
diffstat | 1 files changed, 362 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/bela.sh Fri Jun 17 18:40:04 2016 +0100 @@ -0,0 +1,362 @@ +#/bin/ksh + +# set defaults unless variables are already set +[ -z "$BBB_ADDRESS" ] && BBB_ADDRESS="root@192.168.7.2" +[ -z "$BBB_BELA_HOME" ] && BBB_BELA_HOME="~/Bela/" +[ -z "$BBB_SCREEN_NAME" ] && BBB_SCREEN_NAME="Bela" +[ -z "$RUN_PROJECT" ] && RUN_PROJECT=1 +[ -z "$COMMAND_ARGS" ] && COMMAND_ARGS= +[ -z "$RUN_IN_FOREGROUND" ] && RUN_IN_FOREGROUND=1 +[ -z "$RUN_WITHOUT_SCREEN" ] && RUN_WITHOUT_SCREEN=0 +[ -z "$BBB_PROJECT_HOME" ] && BBB_PROJECT_HOME="${BBB_BELA_HOME}/projects/" +[ -z "$BBB_DEFAULT_PROJECT_NAME" ] && BBB_DEFAULT_PROJECT_NAME="scriptUploadedProject" +[ -z "$BBB_PROJECT_NAME" ] && BBB_PROJECT_NAME=$BBB_DEFAULT_PROJECT_NAME +[ -z "$BELA_SAFE_MODE" ] && BELA_SAFE_MODE=1 +#script folder SF +SF="./" + +trap "echo; exit" 2 +usage(){ + THIS_SCRIPT=`basename "$0"` + echo "Usage: $THIS_SCRIPT $*" + [ -z $* ] && SEARCH_STRING="^##bela " || SEARCH_STRING="^##[#]\?bela $*" + echo $SEARCH_STRING + grep "$SEARCH_STRING" $THIS_SCRIPT | sed s/^###/\ \ \.\\// | sed s/^##/\.\\// +} +FULL_INVOCATION="$0 $*" +MAKE_COMMAND="make --no-print-directory -C \"$BBB_BELA_HOME\"" + +beginswith() { case $2 in "$1"*) true;; *) false;; esac; } +contains() { case $2 in *"$1"*) true;; *) false;; esac; } +count_words(){ + [ -z "$1" ] && { echo "Count words requires one argument (string)"; exit 1; } + _RET1=`echo $1 | wc -w` + _RET1="${_RET1#"${_RET1%%[![:space:]]*}"}" + return 0 +} +folder_exists(){ + [ -z $1 ] && { echo "folder_exists requires one argument (folder)"; exit 1; } + ls $1 >/dev/null 2>&1 + return $? +} +find_project_folder(){ + [ -z $2 ] && { echo "find_project_folder requires two arguments (projectName, searchPath)"; exit 1; } +} + +find_project(){ +#find_project(projectName, breakFirst) sets globals _RET1 with the local paths and _RET2 with the remote paths and _RET3 with the total number of matches. If breakFirst==1 it puts at most one result in either _RET1 or _RET2 accordingly + [ -z $1 ] && { echo "find_project requires one argument (projectName)"; exit 1; } + PROJECT=$1; shift + [ -z $1 ] && BREAK=0 || { BREAK=$1; shift; } + + PRIORITY="../projects/ ../examples/" + LOCALS= + for F in "" $PRIORITY + do + FOLDER="${F}${PROJECT}" + folder_exists $FOLDER && { LOCALS="$LOCALS $FOLDER"; [ $BREAK -ne 0 ] && break; } + done + # do the same thing remotely + if [ $BREAK -eq 0 ] || [ -z $LOCALS ] + then + REMOTES=`ssh $BBB_ADDRESS ' + REMOTES= + PROJECT='$PROJECT' + for F in "" ~/Bela/projects/ ~/Bela/examples/ + do + FOLDER=${F}${PROJECT} + ls $FOLDER >/dev/null 2>&1 && { REMOTES="$REMOTES $FOLDER"; + [ '$BREAK' -ne 0 ] && break; } + done + echo $REMOTES'` + fi + count_words "$LOCALS $REMOTES" && FOUND=$_RET1 + echo $FOUND________ + [ $FOUND -eq 0 ] && return 1 + + STR= + n=0 + [ -z "$LOCALS" ] || STR="On your computer: \n" + for a in $LOCALS + do + n=$((n+1)) + STR="$STR($n) $a\n" + done + [ -z "$REMOTES" ] || STR="${STR}On Bela: \n" + for a in $REMOTES + do + n=$((n+1)) + STR="$STR($n) $a\n" + done + + _RET1=${LOCALS} + _RET2=${REMOTES} + _RET3=$FOUND + _RET4=$STR + return 0 +} + +sequential(){ + echo "ABORT" + exit 1 + if [ -z $1 ] || [ -z $1 ]; + then + echo "sequential should be called with two arguments (start, stop)" + fi + COUNTER=$1; shift + STOP=$1; shift + _RET1= + +} + +interactive(){ +#interactive(count=1) waits for user input, validates it and sets returned value in _RET1 + [ -z $1 ] && COUNT=1 || COUNT=$1 + STR= + [ $COUNT -eq 1 ] && STR="(y/n): " || STR="(enter a number between 1 and $COUNT): " + while { printf "$STR"; read REPLY; } + do + if [ $COUNT -eq 1 ] + then + case $REPLY in + y|Y) + REPLY=1 + break; + ;; + n|N) + REPLY=0 + break; + ;; + *) + echo "wrong value" + continue + ;; + esac + else + case $REPLY in + #check it is a string + ''|*[!0-9]*) + continue + ;; + *) + # check range + if [ $REPLY -lt 1 ] || [ $REPLY -gt $COUNT ] + then + continue + else + break + fi + ;; + esac + fi + done + _RET1=$REPLY + return 0 +} +get_one_project(){ +#getOneProject(projectName) returns true if it finds a project, false otherwise. Fills _RET1 with the project path and _RET2 with the project location (local or remote) + [ -z $1 ] && { echo "get_one_project() requires one argument (projectName)"; exit 1; } + PROJECT=$1; shift + + if [ $SAFE -eq 0 ]; + then + find_project $PROJECT 1 || return 1 + else + find_project $PROJECT 0 || return 1 + if [ $_RET3 -ge 1 ] # it is >= 1 + then + LOCALS=$_RET1 + REMOTES=$_RET2 + COUNT=$_RET3 + STR="There are $COUNT projects with this name:\n$_RET4\nWhich one do you want to build? " + printf "$STR" + interactive $COUNT + SELECTED=$_RET1 + LOCAL_COUNT=`echo $LOCALS | wc -w` + [ $SELECTED -le $LOCAL_COUNT ] &&\ + LOCATION=local||LOCATION=remote + set -- $LOCALS $REMOTES + eval "PROJECT_PATH=\$${SELECTED}" + fi + fi + _RET1=$PROJECT_PATH + _RET2=$LOCATION +} +copy_project(){ + printf "" +} + +build_project_remote(){ + printf "" +} + +run(){ +## run (project, runFolder, runMode, arguments) + [ -z $1 ] && { echo "run requires one argument (projectName)"; exit 1; } + PROJECT=$1; RUN_FOLDER=$2; MODE=$3; shift 3; CL=$* + PROJECT_NAME=`basename $PROJECT` + get_one_project $PROJECT || { echo "Could not find a project called \"$PROJECT\", try specifying the full path to it"; exit 1; } + PROJECT_PATH=$_RET1 + LOCATION=$_RET2 + case $LOCATION in + local) + echo ${SF}build_project.sh -p $PROJECT_NAME -c "$CL" $MODE $PROJECT_PATH + ${SF}build_project.sh -p $PROJECT_NAME -c "$CL" $MODE $PROJECT_PATH + ;; + remote) + ssh -t $BBB_ADDRESS $MAKE_COMMAND FULLPATH= + ;; + *) + echo "Invalid LOCATION" + exit 1 + ;; + esac + echo PROJECT_PATH=$PROJECT_PATH NAME=$PROJECT_NAME RUN_FOLDER=$RUN_FOLDER MODE=$MODE CL=$CL +} + +get_ip(){ +# get_ip (fullAddress) + [ -z $1 ] && { echo "get_ip requires one argument (fullAddress)"; return 1; } + _RET1=`echo $1 | sed s/.*@//` +} + +check_board_connected(){ +# Check if the board is alive and set the date + get_ip $BBB_ADDRESS && IP=$_RET1 || return 1 + printf "Checking that the board is running on $IP..." + ssh -o ConnectTimeout=5 $BBB_ADDRESS "date -s \"`date '+%Y%m%d %T'`\" > /dev/null" &&\ + echo ok || { printf "no\nBela does not respond on " get_ip $BBB_ADDRESS", check that the board is connected, up and running and the IP address is correct"; return 1; } +} + +#start from here +#create a shorthand alias for BELA_SAFE_MODE +SAFE=$BELA_SAFE_MODE +[ $SAFE -eq 1 ] && check_board_connected || exit +OPT=$1 +shift +case $OPT in +run) +##bela run ... -- runs the specified project. The project can be stored on the computer or on the board. +###bela run <projectName> <commandLineOptions> -- runs the project in a detachable screen + [ -z $1 ] && { usage run; echo "What project do you want to run?"; exit 1; } + PROJECT=$1 + shift + RUNMODE= + #find if the next argument is a run mode or a command line options + case $1 in + fg|foreground) +###bela run fg <projectName> <commandLineOptions> -- runs project in the foreground + RUNMODE=-f + shift + ;; + bg|background) +###bela run bg <projectName> <commandLineOptions> -- runs project in the background + RUNMODE=-b + shift + ;; + esac; + run $PROJECT "" "$RUNMODE" $* + exit $? +;; +heavy) +##bela heavy ... -- runs a Pd patch with heavy +###bela heavy <projectName> <commandLineOptions> -- runs <projectName> with <options> (optional) + [ -z $1 ] && { usage $OPT; echo "What project do you want to build with heavy?"; exit 1; } + echo TODO + exit 1; +;; +libpd | pyo) +##bela libpd ... -- runs a Pd patch with libpd +###bela libpd <projectName> <commandLineOptions> -- runs <projectName> with <options> (optional) +##bela pyo ... -- runs a python pyo project +###bela pyo <projectName> <commandLineOptions> -- runs <projectName> with <options> (optional) + [ -z $1 ] && { usage $OPT; echo "What project do you want to run with $OPT?"; exit 1; } + PD_PROJECT=$1 + shift + run basic_${OPT} $PD_PROJECT "" $* + exit $? +;; +info) +##bela info <projectName> -- gives info on a project + echo TODO + exit 1; +;; +ide) +##bela ide ... -- controls the bela IDE, which is accessible through a web browser + [ -z $1 ] && { usage ide; echo "What do you want to do with the ide?"; exit 1; } + OPT=$1 + shift + T= + case $OPT in + startup) +###bela ide startup -- activates the IDE when the board boots +###bela ide startup no -- disables the IDE at boot + [ -z $1 ] && MAKE_TARGET=idestartup ||\ + { [ no = $1 ] && MAKE_TARGET=idenostartup ||\ + { usage ide startup; echo "unknown option $1"; exit 1; } + } + ;; + start) +###bela ide start -- starts/restarts the IDE + MAKE_TARGET=idestart + ;; + connect) +###bela ide connect -- connects the terminal to the running IDE session. Useful for debugging + T=-t + MAKE_TARGET=ideconnect + ;; + stop) +###bela ide stop -- stops the IDE if it is currently running + MAKE_TARGET=idestop + ;; + + #TODO: open address + *) + usage ide; echo "What do you want to do with the ide?"; exit 1 + esac + ssh $T $BBB_ADDRESS $MAKE_COMMAND $MAKE_TARGET + exit $? +;; +startup) +##bela startup ... -- sets a project to run at boot +###bela startup <projectName> <commandLineOptions> -- sets a project to run at boot +###bela startup restart <projectName> <commandLineOptions> -- sets a project to run at boot and restarts it if it crashes. +###bela startup no -- disables the project at boot + # startup can take a projectName (either local or remote) or "no" + [ -z $1 ] && { usage startup; echo "What program do you want to run at startup?"; exit 1; } + [ $1 = no ] && { ssh -t $BBB_ADDRESS $MAKE_COMMAND nostartup ; exit $?; } + TARGET=startup + [ $1 = restart ] && { TARGET=startuploop; shift; } + PROJECT=$1; shift + CL=$* + #TODO: check if PROJECT exists remotely, otherwise copy it from here + ssh $BBB_ADDRESS $MAKE_COMMAND startup PROJECT=$PROJECT CL="$CL" + exit $? +;; +stop) +##bela stop -- stops the Bela project that is currently running (if any) + ssh $BBB_ADDRESS $MAKE_COMMAND stop + exit $? +;; +connect) +##bela connect -- connects to the Bela project that is currently running in the background (if any) + ssh -t $BBB_ADDRESS $MAKE_COMMAND connect + exit $? +;; +shutdown) +##bela shutdown -- safely shuts down the board + ssh $BBB_ADDRESS halt + exit $? +;; +date) +##bela date -- sets the date on the board + check_board_connected $BBB_ADDRESS &&\ + { echo "Date set correctly"; exit 0; } ||\ + { echo "Error while setting the date. Current date on the board is `ssh $BBB_ADDRESS date`"; exit 1; } +;; +esac +usage + +#bela options projectName +#bela update +#bela update ide