From 10b4fa91eb32f436feb44d1387bc57cb6ae12eb4 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Sun, 9 Feb 2020 20:48:03 -0600
Subject: [PATCH] Add mftest -b (auto-build) and -u (upload)

- Implement the equivalent of auto-build for the shell environment by using the MOTHERBOARD setting to look up the env: entries.
---
 buildroot/share/git/mftest | 103 +++++++++++++++++++++++++++++--------
 1 file changed, 81 insertions(+), 22 deletions(-)

diff --git a/buildroot/share/git/mftest b/buildroot/share/git/mftest
index d80b9ed810f..6db44147867 100755
--- a/buildroot/share/git/mftest
+++ b/buildroot/share/git/mftest
@@ -1,10 +1,9 @@
 #!/usr/bin/env bash
 #
-# mftest [name] [index]
-#
-# Set configuration options based on a test
-# By default it will do megaatmega2560
-# Use 'mftest -' to pick from the list.
+#  mftest                             Select a test to apply and build
+#  mftest -b                          Build the auto-detected environment
+#  mftest -u                          Upload the auto-detected environment
+#  mftest [name] [index] [-y]         Set config options and optionally build a test
 #
 
 MFINFO=$(mfinfo) || exit 1
@@ -12,16 +11,24 @@ MFINFO=$(mfinfo) || exit 1
 
 TESTPATH=buildroot/share/tests
 STATE_FILE=$( echo ./.pio/.mftestrc )
+SED=$(which gsed || which sed)
 
 shopt -s extglob nocasematch
 
+# Matching patterns
+ISNUM='^[0-9]+$'
+ISCMD='^(restore|opt|exec|use|pins|env)_'
+ISEXEC='^exec_'
+ISCONT='\\ *$'
+
 # Get the environment and test number from the command
 TESTENV=${1:-'-'}
 CHOICE=${2:-0}
+AUTOENV=0
 
 # Allow shorthand for test name
 case $TESTENV in
-    tree) platformio run --project-dir . -e include_tree ; exit 1 ;;
+    tree) pio run -d . -e include_tree ; exit 1 ;;
      due) TESTENV='DUE' ;;
      esp) TESTENV='esp32' ;;
     lin*) TESTENV='linux_native' ;;
@@ -43,22 +50,72 @@ case $TESTENV in
           # Build with the last-built env
       -r) [[ -f "$STATE_FILE" ]] || { echo "No previous (-r) build state found." ; exit 1 ; }
           read TESTENV <"$STATE_FILE"
-          platformio run --project-dir . -e $TESTENV
+          pio run -d . -e $TESTENV
           exit
           ;;
-          # A -y may come first
+
+   -[bu]) MB=$( grep "define MOTHERBOARD" Marlin/Configuration.h | awk '{ print $3 }' | $SED 's/BOARD_//' )
+          [[ -z $MB ]] && { echo "Error - Unable to read MOTHERBOARD setting." ; exit 1 ; }
+          BLINE=$( grep "define BOARD_$MB" Marlin/src/core/boards.h )
+          BNUM=$( $SED -E 's/^.+BOARD_[^ ]+ +([0-9]+).+$/\1/' <<<"$BLINE" )
+          BDESC=$( $SED -E 's/^.+\/\/ *(.+)$/\1/' <<<"$BLINE" )
+          [[ -z $BNUM ]] && { echo "Error - Unable to $MB in boards list." ; exit 1 ; }
+          readarray -t ENVS <<< $( grep -A1 "MB($MB)" Marlin/src/pins/pins.h | $SED -n '2 p' | grep -oE 'env:[^ ]+' | $SED -E 's/env://' )
+          [[ -z $ENVS ]] && { echo "Error - Unable to find target(s) for $MB ($BNUM)." ; exit 1 ; }
+          ECOUNT=${#ENVS[*]}
+
+          if [[ $ECOUNT == 1 ]]; then
+            TARGET=$ENVS
+          else
+            #
+            # List env names and numbers. Get selection.
+            #
+            if [[ $CHOICE == 0 ]]; then
+              echo "Available targets for \"$BDESC\" | $MB ($BNUM):"
+
+              IND=0 ; for ENV in "${ENVS[@]}"; do echo " $IND) $ENV" ; done
+
+              if [[ $ECOUNT > 1 ]]; then
+                for (( ; ; ))
+                do
+                  read -p "Select a target for '$MB' (1-$ECOUNT) : " CHOICE
+                  [[ -z "$CHOICE" ]] && { echo '(canceled)' ; exit 1 ; }
+                  [[ $CHOICE =~ $ISNUM ]] && ((CHOICE >= 1 && CHOICE <= ECOUNT)) && break
+                  echo ">>> Invalid environment choice '$CHOICE'."
+                done
+                echo
+              fi
+            else
+              echo "Detected \"$BDESC\" | $MB ($BNUM)."
+              [[ $CHOICE > $ECOUNT ]] && { echo "Environment selection is out of range." ; exit 1 ; }
+            fi
+            TARGET="${ENVS[$CHOICE-1]}"
+            echo "Selected $TARGET"
+          fi
+
+          echo "$TARGET" >"$STATE_FILE"
+
+          if [[ $TESTENV == "-u" ]]; then
+            echo "Build/Uploading environment $TARGET for board $MB ($BNUM)..." ; echo
+            pio run -t upload -e $TARGET
+          else
+            echo "Building environment $TARGET for board $MB ($BNUM)..." ; echo
+            pio run -e $TARGET
+          fi
+          exit
+          ;;
+
+          # The -y flag may come first
       -y) TESTENV=${2:-'-'} ; CHOICE=${3:-0} ;;
+
   -[a-z]) echo "Unknown flag $TESTENV" ; exit 1 ;;
        -) ;;
 esac
 
-# Matching patterns
-ISNUM='^[0-9]+$'
-ISCMD='^(restore|opt|exec|use|pins|env)_'
-ISEXEC='^exec_'
-ISCONT='\\ *$'
-
+#
 # List available tests and ask for selection
+#
+
 if [[ $TESTENV == '-' ]]; then
   IND=0
   NAMES=()
@@ -86,17 +143,17 @@ fi
 OUT=$( cat $TESTPATH/$TESTENV-tests 2>/dev/null ) || { echo "Can't find test '$TESTENV'." ; exit 1 ; }
 
 # Count up the number of tests
-# TODO: List test descriptions with numbers
 TESTCOUNT=$( awk "/$ISEXEC/{a++}END{print a}" <<<"$OUT" )
 
 # User entered a number?
-(( CHOICE && CHOICE > TESTCOUNT )) && { echo "Invalid test index '$CHOICE' (1-$TESTCOUNT)." ; exit 1 ; }
+(( CHOICE && CHOICE > TESTCOUNT )) && { echo "Invalid test selection '$CHOICE' (1-$TESTCOUNT)." ; exit 1 ; }
 
 if [[ $CHOICE == 0 ]]; then
-  # List test descriptions with numbers
+  #
+  # List test descriptions with numbers and get selection
+  #
   echo "Available '$TESTENV' tests:" ; echo "$OUT" | {
     IND=0
-    SED=$(which gsed || which sed)
     while IFS= read -r LINE
     do
       if [[ $LINE =~ $ISEXEC ]]; then
@@ -113,12 +170,14 @@ if [[ $CHOICE == 0 ]]; then
       read -p "Select a '$TESTENV' test (1-$TESTCOUNT) : " CHOICE
       [[ -z "$CHOICE" ]] && { echo '(canceled)' ; exit 1 ; }
       [[ $CHOICE =~ $ISNUM ]] && ((CHOICE >= 1 && CHOICE <= TESTCOUNT)) && break
-      echo ">>> Invalid test index '$CHOICE'."
+      echo ">>> Invalid test selection '$CHOICE'."
     done
   fi
 fi
 
-# Finally, run the specified test lines
+#
+# Run the specified test lines
+#
 echo "$OUT" | {
   IND=0
   GOTX=0
@@ -136,7 +195,7 @@ echo "$OUT" | {
         }
         ((IND == CHOICE)) && {
           GOTX=1
-          [[ $CMD == "" ]] && CMD="$LINE" || CMD=$( echo -e "$CMD$LINE" | sed -e 's/\\//g' )
+          [[ $CMD == "" ]] && CMD="$LINE" || CMD=$( echo -e "$CMD$LINE" | $SED -e 's/\\//g' )
           [[ $LINE =~ $ISCONT ]] || { echo $CMD ; eval "$CMD" ; CMD="" ; }
         }
       fi
@@ -154,6 +213,6 @@ if [[ $BUILD_YES != 'Y' ]]; then
 fi
 
 [[ $BUILD_YES == 'Y' || $BUILD_YES == 'Yes' ]] && {
-  platformio run --project-dir . -e $TESTENV
+  pio run -d . -e $TESTENV
   echo "$TESTENV" >"$STATE_FILE"
 }