annotate scripts/bela.sh @ 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
children
rev   line source
giuliomoro@436 1 #/bin/ksh
giuliomoro@436 2
giuliomoro@436 3 # set defaults unless variables are already set
giuliomoro@436 4 [ -z "$BBB_ADDRESS" ] && BBB_ADDRESS="root@192.168.7.2"
giuliomoro@436 5 [ -z "$BBB_BELA_HOME" ] && BBB_BELA_HOME="~/Bela/"
giuliomoro@436 6 [ -z "$BBB_SCREEN_NAME" ] && BBB_SCREEN_NAME="Bela"
giuliomoro@436 7 [ -z "$RUN_PROJECT" ] && RUN_PROJECT=1
giuliomoro@436 8 [ -z "$COMMAND_ARGS" ] && COMMAND_ARGS=
giuliomoro@436 9 [ -z "$RUN_IN_FOREGROUND" ] && RUN_IN_FOREGROUND=1
giuliomoro@436 10 [ -z "$RUN_WITHOUT_SCREEN" ] && RUN_WITHOUT_SCREEN=0
giuliomoro@436 11 [ -z "$BBB_PROJECT_HOME" ] && BBB_PROJECT_HOME="${BBB_BELA_HOME}/projects/"
giuliomoro@436 12 [ -z "$BBB_DEFAULT_PROJECT_NAME" ] && BBB_DEFAULT_PROJECT_NAME="scriptUploadedProject"
giuliomoro@436 13 [ -z "$BBB_PROJECT_NAME" ] && BBB_PROJECT_NAME=$BBB_DEFAULT_PROJECT_NAME
giuliomoro@436 14 [ -z "$BELA_SAFE_MODE" ] && BELA_SAFE_MODE=1
giuliomoro@436 15 #script folder SF
giuliomoro@436 16 SF="./"
giuliomoro@436 17
giuliomoro@436 18 trap "echo; exit" 2
giuliomoro@436 19 usage(){
giuliomoro@436 20 THIS_SCRIPT=`basename "$0"`
giuliomoro@436 21 echo "Usage: $THIS_SCRIPT $*"
giuliomoro@436 22 [ -z $* ] && SEARCH_STRING="^##bela " || SEARCH_STRING="^##[#]\?bela $*"
giuliomoro@436 23 echo $SEARCH_STRING
giuliomoro@436 24 grep "$SEARCH_STRING" $THIS_SCRIPT | sed s/^###/\ \ \.\\// | sed s/^##/\.\\//
giuliomoro@436 25 }
giuliomoro@436 26 FULL_INVOCATION="$0 $*"
giuliomoro@436 27 MAKE_COMMAND="make --no-print-directory -C \"$BBB_BELA_HOME\""
giuliomoro@436 28
giuliomoro@436 29 beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
giuliomoro@436 30 contains() { case $2 in *"$1"*) true;; *) false;; esac; }
giuliomoro@436 31 count_words(){
giuliomoro@436 32 [ -z "$1" ] && { echo "Count words requires one argument (string)"; exit 1; }
giuliomoro@436 33 _RET1=`echo $1 | wc -w`
giuliomoro@436 34 _RET1="${_RET1#"${_RET1%%[![:space:]]*}"}"
giuliomoro@436 35 return 0
giuliomoro@436 36 }
giuliomoro@436 37 folder_exists(){
giuliomoro@436 38 [ -z $1 ] && { echo "folder_exists requires one argument (folder)"; exit 1; }
giuliomoro@436 39 ls $1 >/dev/null 2>&1
giuliomoro@436 40 return $?
giuliomoro@436 41 }
giuliomoro@436 42 find_project_folder(){
giuliomoro@436 43 [ -z $2 ] && { echo "find_project_folder requires two arguments (projectName, searchPath)"; exit 1; }
giuliomoro@436 44 }
giuliomoro@436 45
giuliomoro@436 46 find_project(){
giuliomoro@436 47 #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
giuliomoro@436 48 [ -z $1 ] && { echo "find_project requires one argument (projectName)"; exit 1; }
giuliomoro@436 49 PROJECT=$1; shift
giuliomoro@436 50 [ -z $1 ] && BREAK=0 || { BREAK=$1; shift; }
giuliomoro@436 51
giuliomoro@436 52 PRIORITY="../projects/ ../examples/"
giuliomoro@436 53 LOCALS=
giuliomoro@436 54 for F in "" $PRIORITY
giuliomoro@436 55 do
giuliomoro@436 56 FOLDER="${F}${PROJECT}"
giuliomoro@436 57 folder_exists $FOLDER && { LOCALS="$LOCALS $FOLDER"; [ $BREAK -ne 0 ] && break; }
giuliomoro@436 58 done
giuliomoro@436 59 # do the same thing remotely
giuliomoro@436 60 if [ $BREAK -eq 0 ] || [ -z $LOCALS ]
giuliomoro@436 61 then
giuliomoro@436 62 REMOTES=`ssh $BBB_ADDRESS '
giuliomoro@436 63 REMOTES=
giuliomoro@436 64 PROJECT='$PROJECT'
giuliomoro@436 65 for F in "" ~/Bela/projects/ ~/Bela/examples/
giuliomoro@436 66 do
giuliomoro@436 67 FOLDER=${F}${PROJECT}
giuliomoro@436 68 ls $FOLDER >/dev/null 2>&1 && { REMOTES="$REMOTES $FOLDER";
giuliomoro@436 69 [ '$BREAK' -ne 0 ] && break; }
giuliomoro@436 70 done
giuliomoro@436 71 echo $REMOTES'`
giuliomoro@436 72 fi
giuliomoro@436 73 count_words "$LOCALS $REMOTES" && FOUND=$_RET1
giuliomoro@436 74 echo $FOUND________
giuliomoro@436 75 [ $FOUND -eq 0 ] && return 1
giuliomoro@436 76
giuliomoro@436 77 STR=
giuliomoro@436 78 n=0
giuliomoro@436 79 [ -z "$LOCALS" ] || STR="On your computer: \n"
giuliomoro@436 80 for a in $LOCALS
giuliomoro@436 81 do
giuliomoro@436 82 n=$((n+1))
giuliomoro@436 83 STR="$STR($n) $a\n"
giuliomoro@436 84 done
giuliomoro@436 85 [ -z "$REMOTES" ] || STR="${STR}On Bela: \n"
giuliomoro@436 86 for a in $REMOTES
giuliomoro@436 87 do
giuliomoro@436 88 n=$((n+1))
giuliomoro@436 89 STR="$STR($n) $a\n"
giuliomoro@436 90 done
giuliomoro@436 91
giuliomoro@436 92 _RET1=${LOCALS}
giuliomoro@436 93 _RET2=${REMOTES}
giuliomoro@436 94 _RET3=$FOUND
giuliomoro@436 95 _RET4=$STR
giuliomoro@436 96 return 0
giuliomoro@436 97 }
giuliomoro@436 98
giuliomoro@436 99 sequential(){
giuliomoro@436 100 echo "ABORT"
giuliomoro@436 101 exit 1
giuliomoro@436 102 if [ -z $1 ] || [ -z $1 ];
giuliomoro@436 103 then
giuliomoro@436 104 echo "sequential should be called with two arguments (start, stop)"
giuliomoro@436 105 fi
giuliomoro@436 106 COUNTER=$1; shift
giuliomoro@436 107 STOP=$1; shift
giuliomoro@436 108 _RET1=
giuliomoro@436 109
giuliomoro@436 110 }
giuliomoro@436 111
giuliomoro@436 112 interactive(){
giuliomoro@436 113 #interactive(count=1) waits for user input, validates it and sets returned value in _RET1
giuliomoro@436 114 [ -z $1 ] && COUNT=1 || COUNT=$1
giuliomoro@436 115 STR=
giuliomoro@436 116 [ $COUNT -eq 1 ] && STR="(y/n): " || STR="(enter a number between 1 and $COUNT): "
giuliomoro@436 117 while { printf "$STR"; read REPLY; }
giuliomoro@436 118 do
giuliomoro@436 119 if [ $COUNT -eq 1 ]
giuliomoro@436 120 then
giuliomoro@436 121 case $REPLY in
giuliomoro@436 122 y|Y)
giuliomoro@436 123 REPLY=1
giuliomoro@436 124 break;
giuliomoro@436 125 ;;
giuliomoro@436 126 n|N)
giuliomoro@436 127 REPLY=0
giuliomoro@436 128 break;
giuliomoro@436 129 ;;
giuliomoro@436 130 *)
giuliomoro@436 131 echo "wrong value"
giuliomoro@436 132 continue
giuliomoro@436 133 ;;
giuliomoro@436 134 esac
giuliomoro@436 135 else
giuliomoro@436 136 case $REPLY in
giuliomoro@436 137 #check it is a string
giuliomoro@436 138 ''|*[!0-9]*)
giuliomoro@436 139 continue
giuliomoro@436 140 ;;
giuliomoro@436 141 *)
giuliomoro@436 142 # check range
giuliomoro@436 143 if [ $REPLY -lt 1 ] || [ $REPLY -gt $COUNT ]
giuliomoro@436 144 then
giuliomoro@436 145 continue
giuliomoro@436 146 else
giuliomoro@436 147 break
giuliomoro@436 148 fi
giuliomoro@436 149 ;;
giuliomoro@436 150 esac
giuliomoro@436 151 fi
giuliomoro@436 152 done
giuliomoro@436 153 _RET1=$REPLY
giuliomoro@436 154 return 0
giuliomoro@436 155 }
giuliomoro@436 156 get_one_project(){
giuliomoro@436 157 #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)
giuliomoro@436 158 [ -z $1 ] && { echo "get_one_project() requires one argument (projectName)"; exit 1; }
giuliomoro@436 159 PROJECT=$1; shift
giuliomoro@436 160
giuliomoro@436 161 if [ $SAFE -eq 0 ];
giuliomoro@436 162 then
giuliomoro@436 163 find_project $PROJECT 1 || return 1
giuliomoro@436 164 else
giuliomoro@436 165 find_project $PROJECT 0 || return 1
giuliomoro@436 166 if [ $_RET3 -ge 1 ] # it is >= 1
giuliomoro@436 167 then
giuliomoro@436 168 LOCALS=$_RET1
giuliomoro@436 169 REMOTES=$_RET2
giuliomoro@436 170 COUNT=$_RET3
giuliomoro@436 171 STR="There are $COUNT projects with this name:\n$_RET4\nWhich one do you want to build? "
giuliomoro@436 172 printf "$STR"
giuliomoro@436 173 interactive $COUNT
giuliomoro@436 174 SELECTED=$_RET1
giuliomoro@436 175 LOCAL_COUNT=`echo $LOCALS | wc -w`
giuliomoro@436 176 [ $SELECTED -le $LOCAL_COUNT ] &&\
giuliomoro@436 177 LOCATION=local||LOCATION=remote
giuliomoro@436 178 set -- $LOCALS $REMOTES
giuliomoro@436 179 eval "PROJECT_PATH=\$${SELECTED}"
giuliomoro@436 180 fi
giuliomoro@436 181 fi
giuliomoro@436 182 _RET1=$PROJECT_PATH
giuliomoro@436 183 _RET2=$LOCATION
giuliomoro@436 184 }
giuliomoro@436 185 copy_project(){
giuliomoro@436 186 printf ""
giuliomoro@436 187 }
giuliomoro@436 188
giuliomoro@436 189 build_project_remote(){
giuliomoro@436 190 printf ""
giuliomoro@436 191 }
giuliomoro@436 192
giuliomoro@436 193 run(){
giuliomoro@436 194 ## run (project, runFolder, runMode, arguments)
giuliomoro@436 195 [ -z $1 ] && { echo "run requires one argument (projectName)"; exit 1; }
giuliomoro@436 196 PROJECT=$1; RUN_FOLDER=$2; MODE=$3; shift 3; CL=$*
giuliomoro@436 197 PROJECT_NAME=`basename $PROJECT`
giuliomoro@436 198 get_one_project $PROJECT || { echo "Could not find a project called \"$PROJECT\", try specifying the full path to it"; exit 1; }
giuliomoro@436 199 PROJECT_PATH=$_RET1
giuliomoro@436 200 LOCATION=$_RET2
giuliomoro@436 201 case $LOCATION in
giuliomoro@436 202 local)
giuliomoro@436 203 echo ${SF}build_project.sh -p $PROJECT_NAME -c "$CL" $MODE $PROJECT_PATH
giuliomoro@436 204 ${SF}build_project.sh -p $PROJECT_NAME -c "$CL" $MODE $PROJECT_PATH
giuliomoro@436 205 ;;
giuliomoro@436 206 remote)
giuliomoro@436 207 ssh -t $BBB_ADDRESS $MAKE_COMMAND FULLPATH=
giuliomoro@436 208 ;;
giuliomoro@436 209 *)
giuliomoro@436 210 echo "Invalid LOCATION"
giuliomoro@436 211 exit 1
giuliomoro@436 212 ;;
giuliomoro@436 213 esac
giuliomoro@436 214 echo PROJECT_PATH=$PROJECT_PATH NAME=$PROJECT_NAME RUN_FOLDER=$RUN_FOLDER MODE=$MODE CL=$CL
giuliomoro@436 215 }
giuliomoro@436 216
giuliomoro@436 217 get_ip(){
giuliomoro@436 218 # get_ip (fullAddress)
giuliomoro@436 219 [ -z $1 ] && { echo "get_ip requires one argument (fullAddress)"; return 1; }
giuliomoro@436 220 _RET1=`echo $1 | sed s/.*@//`
giuliomoro@436 221 }
giuliomoro@436 222
giuliomoro@436 223 check_board_connected(){
giuliomoro@436 224 # Check if the board is alive and set the date
giuliomoro@436 225 get_ip $BBB_ADDRESS && IP=$_RET1 || return 1
giuliomoro@436 226 printf "Checking that the board is running on $IP..."
giuliomoro@436 227 ssh -o ConnectTimeout=5 $BBB_ADDRESS "date -s \"`date '+%Y%m%d %T'`\" > /dev/null" &&\
giuliomoro@436 228 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; }
giuliomoro@436 229 }
giuliomoro@436 230
giuliomoro@436 231 #start from here
giuliomoro@436 232 #create a shorthand alias for BELA_SAFE_MODE
giuliomoro@436 233 SAFE=$BELA_SAFE_MODE
giuliomoro@436 234 [ $SAFE -eq 1 ] && check_board_connected || exit
giuliomoro@436 235 OPT=$1
giuliomoro@436 236 shift
giuliomoro@436 237 case $OPT in
giuliomoro@436 238 run)
giuliomoro@436 239 ##bela run ... -- runs the specified project. The project can be stored on the computer or on the board.
giuliomoro@436 240 ###bela run <projectName> <commandLineOptions> -- runs the project in a detachable screen
giuliomoro@436 241 [ -z $1 ] && { usage run; echo "What project do you want to run?"; exit 1; }
giuliomoro@436 242 PROJECT=$1
giuliomoro@436 243 shift
giuliomoro@436 244 RUNMODE=
giuliomoro@436 245 #find if the next argument is a run mode or a command line options
giuliomoro@436 246 case $1 in
giuliomoro@436 247 fg|foreground)
giuliomoro@436 248 ###bela run fg <projectName> <commandLineOptions> -- runs project in the foreground
giuliomoro@436 249 RUNMODE=-f
giuliomoro@436 250 shift
giuliomoro@436 251 ;;
giuliomoro@436 252 bg|background)
giuliomoro@436 253 ###bela run bg <projectName> <commandLineOptions> -- runs project in the background
giuliomoro@436 254 RUNMODE=-b
giuliomoro@436 255 shift
giuliomoro@436 256 ;;
giuliomoro@436 257 esac;
giuliomoro@436 258 run $PROJECT "" "$RUNMODE" $*
giuliomoro@436 259 exit $?
giuliomoro@436 260 ;;
giuliomoro@436 261 heavy)
giuliomoro@436 262 ##bela heavy ... -- runs a Pd patch with heavy
giuliomoro@436 263 ###bela heavy <projectName> <commandLineOptions> -- runs <projectName> with <options> (optional)
giuliomoro@436 264 [ -z $1 ] && { usage $OPT; echo "What project do you want to build with heavy?"; exit 1; }
giuliomoro@436 265 echo TODO
giuliomoro@436 266 exit 1;
giuliomoro@436 267 ;;
giuliomoro@436 268 libpd | pyo)
giuliomoro@436 269 ##bela libpd ... -- runs a Pd patch with libpd
giuliomoro@436 270 ###bela libpd <projectName> <commandLineOptions> -- runs <projectName> with <options> (optional)
giuliomoro@436 271 ##bela pyo ... -- runs a python pyo project
giuliomoro@436 272 ###bela pyo <projectName> <commandLineOptions> -- runs <projectName> with <options> (optional)
giuliomoro@436 273 [ -z $1 ] && { usage $OPT; echo "What project do you want to run with $OPT?"; exit 1; }
giuliomoro@436 274 PD_PROJECT=$1
giuliomoro@436 275 shift
giuliomoro@436 276 run basic_${OPT} $PD_PROJECT "" $*
giuliomoro@436 277 exit $?
giuliomoro@436 278 ;;
giuliomoro@436 279 info)
giuliomoro@436 280 ##bela info <projectName> -- gives info on a project
giuliomoro@436 281 echo TODO
giuliomoro@436 282 exit 1;
giuliomoro@436 283 ;;
giuliomoro@436 284 ide)
giuliomoro@436 285 ##bela ide ... -- controls the bela IDE, which is accessible through a web browser
giuliomoro@436 286 [ -z $1 ] && { usage ide; echo "What do you want to do with the ide?"; exit 1; }
giuliomoro@436 287 OPT=$1
giuliomoro@436 288 shift
giuliomoro@436 289 T=
giuliomoro@436 290 case $OPT in
giuliomoro@436 291 startup)
giuliomoro@436 292 ###bela ide startup -- activates the IDE when the board boots
giuliomoro@436 293 ###bela ide startup no -- disables the IDE at boot
giuliomoro@436 294 [ -z $1 ] && MAKE_TARGET=idestartup ||\
giuliomoro@436 295 { [ no = $1 ] && MAKE_TARGET=idenostartup ||\
giuliomoro@436 296 { usage ide startup; echo "unknown option $1"; exit 1; }
giuliomoro@436 297 }
giuliomoro@436 298 ;;
giuliomoro@436 299 start)
giuliomoro@436 300 ###bela ide start -- starts/restarts the IDE
giuliomoro@436 301 MAKE_TARGET=idestart
giuliomoro@436 302 ;;
giuliomoro@436 303 connect)
giuliomoro@436 304 ###bela ide connect -- connects the terminal to the running IDE session. Useful for debugging
giuliomoro@436 305 T=-t
giuliomoro@436 306 MAKE_TARGET=ideconnect
giuliomoro@436 307 ;;
giuliomoro@436 308 stop)
giuliomoro@436 309 ###bela ide stop -- stops the IDE if it is currently running
giuliomoro@436 310 MAKE_TARGET=idestop
giuliomoro@436 311 ;;
giuliomoro@436 312
giuliomoro@436 313 #TODO: open address
giuliomoro@436 314 *)
giuliomoro@436 315 usage ide; echo "What do you want to do with the ide?"; exit 1
giuliomoro@436 316 esac
giuliomoro@436 317 ssh $T $BBB_ADDRESS $MAKE_COMMAND $MAKE_TARGET
giuliomoro@436 318 exit $?
giuliomoro@436 319 ;;
giuliomoro@436 320 startup)
giuliomoro@436 321 ##bela startup ... -- sets a project to run at boot
giuliomoro@436 322 ###bela startup <projectName> <commandLineOptions> -- sets a project to run at boot
giuliomoro@436 323 ###bela startup restart <projectName> <commandLineOptions> -- sets a project to run at boot and restarts it if it crashes.
giuliomoro@436 324 ###bela startup no -- disables the project at boot
giuliomoro@436 325 # startup can take a projectName (either local or remote) or "no"
giuliomoro@436 326 [ -z $1 ] && { usage startup; echo "What program do you want to run at startup?"; exit 1; }
giuliomoro@436 327 [ $1 = no ] && { ssh -t $BBB_ADDRESS $MAKE_COMMAND nostartup ; exit $?; }
giuliomoro@436 328 TARGET=startup
giuliomoro@436 329 [ $1 = restart ] && { TARGET=startuploop; shift; }
giuliomoro@436 330 PROJECT=$1; shift
giuliomoro@436 331 CL=$*
giuliomoro@436 332 #TODO: check if PROJECT exists remotely, otherwise copy it from here
giuliomoro@436 333 ssh $BBB_ADDRESS $MAKE_COMMAND startup PROJECT=$PROJECT CL="$CL"
giuliomoro@436 334 exit $?
giuliomoro@436 335 ;;
giuliomoro@436 336 stop)
giuliomoro@436 337 ##bela stop -- stops the Bela project that is currently running (if any)
giuliomoro@436 338 ssh $BBB_ADDRESS $MAKE_COMMAND stop
giuliomoro@436 339 exit $?
giuliomoro@436 340 ;;
giuliomoro@436 341 connect)
giuliomoro@436 342 ##bela connect -- connects to the Bela project that is currently running in the background (if any)
giuliomoro@436 343 ssh -t $BBB_ADDRESS $MAKE_COMMAND connect
giuliomoro@436 344 exit $?
giuliomoro@436 345 ;;
giuliomoro@436 346 shutdown)
giuliomoro@436 347 ##bela shutdown -- safely shuts down the board
giuliomoro@436 348 ssh $BBB_ADDRESS halt
giuliomoro@436 349 exit $?
giuliomoro@436 350 ;;
giuliomoro@436 351 date)
giuliomoro@436 352 ##bela date -- sets the date on the board
giuliomoro@436 353 check_board_connected $BBB_ADDRESS &&\
giuliomoro@436 354 { echo "Date set correctly"; exit 0; } ||\
giuliomoro@436 355 { echo "Error while setting the date. Current date on the board is `ssh $BBB_ADDRESS date`"; exit 1; }
giuliomoro@436 356 ;;
giuliomoro@436 357 esac
giuliomoro@436 358 usage
giuliomoro@436 359
giuliomoro@436 360 #bela options projectName
giuliomoro@436 361 #bela update
giuliomoro@436 362 #bela update ide