Advertisement
devinteske

eval_spin9

Jan 4th, 2013
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 4.27 KB | None | 0 0
  1. #!/bin/sh
  2.  
  3. ############################################################ GLOBALS
  4.  
  5. #
  6. # Global exit status variables
  7. #
  8. export SUCCESS=0
  9. export FAILURE=1
  10.  
  11. # Status indicator message formats for task_begin/task_end
  12. export FMT_COLS=70
  13. export FMT_HEAD="%-${FMT_COLS}s"
  14. export FMT_STAT=" [$ANSI_BLD%s$ANSI_BLD_OFF]\n"
  15. export MSG_GOOD="${ANSI_GRN}  OK  $ANSI_NRM"
  16. export MSG_FAIL="${ANSI_RED}FAILED$ANSI_NRM"
  17.  
  18.  
  19. __cp=0 # reserved for internal use
  20.  
  21. ############################################################ FUNCTIONS
  22.  
  23. # strip_ansi $text ...
  24. #
  25. # Remove ANSI coloring from string arguments or stdin.
  26. #
  27. strip_ansi()
  28. {
  29.         if [ $# -gt 0 ]; then
  30.                 echo "$@" | sed -e 's/^[[^m]*m//g'
  31.         else
  32.                 sed -e 's/^[[^m]*m//g'
  33.         fi
  34. }
  35.  
  36. # task_begin [ $caption ]
  37. #
  38. # Inform the user that you have started a task.
  39. #
  40. task_begin()
  41. {
  42.         local caption="$1"
  43.         local colorless_caption="$( strip_ansi "$caption" )"
  44.  
  45.         task_end $SUCCESS # end the previous task
  46.  
  47.         # Padded strings in printf (e.g., "%-70s") do not work properly if the
  48.         # string contains invisibles, such as ANSI color codes. Compensate for
  49.         # ANSI color codes if any.
  50.         #
  51.         local color_gap=$(( ${#caption} - ${#colorless_caption} ))
  52.         local FMT_COLS2=$(( $FMT_COLS + $color_gap ))
  53.  
  54.         printf "%-${FMT_COLS2}s" "$caption"
  55.  
  56.         export __task_running=YES
  57.         export __cp=${#colorless_caption}
  58. }
  59.  
  60. # task_end [ $exit_status ]
  61. #
  62. # End the currently running task (if any) and display the given exit status.
  63. #
  64. task_end()
  65. {
  66.         local status="$1"
  67.  
  68.         [ "$__task_running" ] || return # nothing to do
  69.  
  70.         if [ "$status" ]; then
  71.                 #
  72.                 # If the caption last-used with task_begin is wider than our
  73.                 # preset-limit, output a new header with blank caption, vert-
  74.                 # ically aligning the cursor to the column where we need to
  75.                 # print the status.
  76.                 #
  77.                 if [ ${__cp:-0} -ge $FMT_COLS ]; then
  78.                         printf "\n$FMT_HEAD"
  79.                         export __cp=0
  80.                 fi
  81.  
  82.                 case "$status" in
  83.                 $SUCCESS) printf "$FMT_STAT" "$MSG_GOOD";;
  84.                        *) printf "$FMT_STAT" "$MSG_FAIL";;
  85.                 esac
  86.         fi
  87.  
  88.         export __task_running= # clear task state
  89. }
  90.  
  91. # spinner
  92. #
  93. # Throw up a spinner. Spin spin spin until we receive "EXIT:###:" on stdin.
  94. # Returns the exit status as specified in the "###" portion above.
  95. #
  96. spinner()
  97. {
  98.         local spin="/-\\|"
  99.         local init=${__task_running:+1} n=1 done=
  100.         local line_format="^[[A\n%s^[[K\n${__task_running:+$FMT_HEAD }"
  101.  
  102.         printf " "
  103.         while [ ! "$DONE" ]; do
  104.                 local LINE="$( /bin/sh -c 'IFS=;read -t0 L;echo "$L"' )"
  105.                 case "$LINE" in
  106.  
  107.                 *EXIT:*:*)
  108.                         DONE="$( echo "$LINE" | sed -e \
  109.                                "s/.*EXIT:\([[:digit:]]*\):.*/\1/" )"
  110.                         LINE="$( echo "$LINE" | sed -e \
  111.                                "s/EXIT:[[:digit:]]*://g" )"
  112.                 esac
  113.                 if [ "$LINE" ]; then
  114.                         printf "${init:+\b \n}$line_format" "$LINE"
  115.                         init=
  116.                 fi
  117.                 printf "\b%s" "$( echo "$spin" | sed -e \
  118.                        "s/.\{0,$(( $n % ${#spin} ))\}\(.\).*/\1/" )"
  119.                 n=$(( $n + 1 ))
  120.         done
  121.  
  122.         printf "\b \b"
  123.         return $DONE
  124. }
  125.  
  126. # eval_spin $command [ $args ... ]
  127. #
  128. # Execute a command while displaying a rotating spinner.
  129. #
  130. eval_spin()
  131. {
  132.         #
  133.         # Execute the command w/ spinner
  134.         #
  135.         (
  136.                 if [ $# -gt 0 ]; then
  137.                         # Take commands from positional arguments
  138.                         ( eval "$@" ) 2>&1
  139.                         echo EXIT:$?:
  140.                 else
  141.                         # Take commands from standard input
  142.                         ( eval "$( cat )" ) 2>&1
  143.                         echo EXIT:$?:
  144.                 fi
  145.         ) | spinner
  146. }
  147.  
  148. ############################################################ MAIN SOURCE
  149.  
  150. task_begin "Some task header..."
  151. eval_spin "$@"
  152. task_end $?
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement