diff --git a/buildroot/bin/__init__.py b/buildroot/bin/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/buildroot/bin/build_all_examples b/buildroot/bin/build_all_examples index a6d6ede47d..d50937a732 100755 --- a/buildroot/bin/build_all_examples +++ b/buildroot/bin/build_all_examples @@ -2,29 +2,50 @@ # # Usage: # -# build_all_examples [-b|--branch=] - Branch to fetch from Configurations repo +# build_all_examples [-a|--archive] - Copy the binary to the export location +# [-B|--base] - Base path of configurations, overriding -b +# [-b|--branch=] - Branch to fetch from Configurations repo (import-2.1.x) # [-c|--continue] - Continue the paused build -# [-d|--debug] - Print extra debug output -# [-i|--ini] - Archive ini/json/yml files in the temp config folder +# [-d|-v|--debug] - Print extra debug output (after) +# [-e|--export=N] - Set CONFIG_EXPORT and export to the export location +# [-f|--nofail] - Don't stop on a failed build +# [-h|--help] - Print usage and exit # [-l|--limit=#] - Limit the number of builds in this run -# [-n|--nobuild] - Don't actually build anything. +# [-m|--many] - Build all the environments for each example +# [-n|--nobuild] - Don't actually build anything +# [-o|--output] - Redirect export / archiving to another location +# (By default export to origin config folders) +# [-p|--purge] - Purge the status file and start over # [-r|--resume=] - Start at some config in the filesystem order -# [-s|--skip] - Do the thing -# -# build_all_examples [...] branch [resume-from] +# [-s|--skip] - Continue the paused build, skipping one # +HERE=`dirname $0` +PATH="$HERE:$PATH" + . mfutil GITREPO=https://github.com/MarlinFirmware/Configurations.git STAT_FILE=./.pio/.buildall -usage() { echo " -Usage: $SELF [-b|--branch=] [-d|--debug] [-i|--ini] [-r|--resume=] - $SELF [-b|--branch=] [-d|--debug] [-i|--ini] [-c|--continue] - $SELF [-b|--branch=] [-d|--debug] [-i|--ini] [-s|--skip] - $SELF [-b|--branch=] [-d|--debug] [-n|--nobuild] - $SELF [...] branch [resume-point] +usage() { echo "Usage: + +build_all_examples [-a|--archive] - Copy the binary to the export location + [-B|--base] - Base path of configurations, overriding -b + [-b|--branch=] - Branch to fetch from Configurations repo (import-2.1.x) + [-c|--continue] - Continue the paused build + [-d|-v|--debug] - Print extra debug output (after) + [-e|--export=N] - Set CONFIG_EXPORT and export to the export location + [-f|--nofail] - Don't stop on a failed build + [-h|--help] - Print usage and exit + [-l|--limit=#] - Limit the number of builds in this run + [-m|--many] - Build all the environments for each example + [-n|--nobuild] - Don't actually build anything + [-o|--output] - Redirect export / archiving to another location + (By default export to origin config folders) + [-p|--purge] - Purge the status file and start over + [-r|--resume=] - Start at some config in the filesystem order + [-s|--skip] - Continue the paused build, skipping one " } @@ -34,50 +55,62 @@ unset FIRST_CONF EXIT_USAGE= LIMIT=1000 -while getopts 'b:cdhil:nqr:sv-:' OFLAG; do +while getopts 'aB:b:cde:fhl:mno:pr:sv-:' OFLAG; do case "${OFLAG}" in - b) BRANCH=$OPTARG ; bugout "Branch: $BRANCH" ;; - r) FIRST_CONF="$OPTARG" ; bugout "Resume: $FIRST_CONF" ;; - c) CONTINUE=1 ; bugout "Continue" ;; - s) CONTSKIP=1 ; bugout "Continue, skipping" ;; - i) COPY_INI=1 ; bugout "Archive INI/JSON/YML files" ;; + a) ARCHIVE=1 ; bugout "Archiving" ;; + B) CBASE=${OPTARG%/} ; bugout "Base: $CBASE" ;; + b) BRANCH=$OPTARG ; bugout "Branch: $BRANCH" ;; + c) CONTINUE=1 ; bugout "Continue" ;; + d|v) DEBUG=1 ; bugout "Debug ON" ;; + e) CEXPORT=$OPTARG ; bugout "Export $CEXPORT" ;; + f) NOFAIL=1 ; bugout "Continue on Fail" ;; h) EXIT_USAGE=1 ; break ;; - l) LIMIT=$OPTARG ; bugout "Limit to $LIMIT build(s)" ;; - d|v) DEBUG=1 ; bugout "Debug ON" ;; - n) DRYRUN=1 ; bugout "Dry Run" ;; - -) IFS="=" read -r ONAM OVAL <<< "$OPTARG" + l) LIMIT=$OPTARG ; bugout "Limit to $LIMIT build(s)" ;; + m) MANY=1 ; bugout "Many Envs" ;; + n) DRYRUN=1 ; bugout "Dry Run" ;; + o) OUTBASE="${OPTARG%/}" ; bugout "Archive to $OUTBASE" ;; + p) PURGE=1 ; bugout "Purge stat file" ;; + r) ISRES=1 ; FIRST_CONF=$OPTARG ; bugout "Resume: $FIRST_CONF" ;; + s) CONTSKIP=1 ; bugout "Continue, skipping" ;; + -) ONAM="${OPTARG%%=*}" ; OVAL="${OPTARG#*=}" case "$ONAM" in - branch) BRANCH=$OVAL ; bugout "Branch: $BRANCH" ;; - resume) FIRST_CONF="$OVAL" ; bugout "Resume: $FIRST_CONF" ;; - continue) CONTINUE=1 ; bugout "Continue" ;; - skip) CONTSKIP=2 ; bugout "Continue, skipping" ;; - limit) LIMIT=$OVAL ; bugout "Limit to $LIMIT build(s)" ;; - ini) COPY_INI=1 ; bugout "Archive INI/JSON/YML files" ;; + archive) ARCHIVE=1 ; bugout "Archiving" ;; + base) CBASE=${OVAL%/} ; bugout "Base: $CBASE" ;; + branch) BRANCH=$OVAL ; bugout "Branch: $BRANCH" ;; + many) MANY=1 ; bugout "Many Envs" ;; + nofail) NOFAIL=1 ; bugout "Continue on Fail" ;; + resume) ISRES=1 ; FIRST_CONF=$OVAL ; bugout "Resume: $FIRST_CONF" ;; + continue) CONTINUE=1 ; bugout "Continue" ;; + skip) CONTSKIP=1 ; bugout "Continue, skipping" ;; + export) CEXPORT=$OVAL ; bugout "Export $EXPORT" ;; + output) OUTBASE="${OVAL%/}" ; bugout "Archive to $OUTBASE" ;; + limit) LIMIT=$OVAL ; bugout "Limit to $LIMIT build(s)" ;; help) [[ -z "$OVAL" ]] || perror "option can't take value $OVAL" $ONAM ; EXIT_USAGE=1 ;; - debug) DEBUG=1 ; bugout "Debug ON" ;; - nobuild) DRYRUN=1 ; bugout "Dry Run" ;; + debug) DEBUG=1 ; bugout "Debug ON" ;; + nobuild) DRYRUN=1 ; bugout "Dry Run" ;; + purge) PURGE=1 ; bugout "Purge stat file" ;; *) EXIT_USAGE=2 ; echo "$SELF: unrecognized option \`--$ONAM'" ; break ;; esac ;; *) EXIT_USAGE=2 ; break ;; esac done - -# Extra arguments count as BRANCH, FIRST_CONF shift $((OPTIND - 1)) -[[ $# > 0 ]] && { BRANCH=$1 ; shift 1 ; bugout "BRANCH=$BRANCH" ; } -[[ $# > 0 ]] && { FIRST_CONF=$1 ; shift 1 ; bugout "FIRST_CONF=$FIRST_CONF" ; } -[[ $# > 0 ]] && { EXIT_USAGE=2 ; echo "too many arguments" ; } +# Check for mixed continue, skip, resume arguments. Only one should be used. +((CONTINUE + CONTSKIP + ISRES + PURGE > 1)) && { echo "Don't mix -c, -p, -s, and -r options" ; echo ; EXIT_USAGE=2 ; } + +# Exit with helpful usage information ((EXIT_USAGE)) && { usage ; let EXIT_USAGE-- ; exit $EXIT_USAGE ; } -echo "This script downloads each Configuration and attempts to build it." -echo "On failure the last-built configs will be left in your working copy." +echo +echo "This script downloads all example configs and attempts to build them." +echo "On failure the last-built configs are left in your working copy." echo "Restore your configs with 'git checkout -f' or 'git reset --hard HEAD'." +echo -if [[ -f "$STAT_FILE" ]]; then - IFS='*' read BRANCH FIRST_CONF <"$STAT_FILE" -fi +[[ -n $PURGE ]] && rm -f "$STAT_FILE" +[[ -z $FIRST_CONF && -f "$STAT_FILE" ]] && IFS='*' read BRANCH FIRST_CONF <"$STAT_FILE" # If -c is given start from the last attempted build if ((CONTINUE)); then @@ -95,77 +128,93 @@ elif ((CONTSKIP)); then fi # Check if the current repository has unmerged changes -if [[ $SKIP_CONF ]]; then +if ((SKIP_CONF)); then echo "Skipping $FIRST_CONF" -elif [[ $FIRST_CONF ]]; then +elif [[ -n $FIRST_CONF ]]; then echo "Resuming from $FIRST_CONF" else git diff --quiet || { echo "The working copy is modified. Commit or stash changes before proceeding."; exit ; } fi -# Create a temporary folder inside .pio -TMP=./.pio/build-$BRANCH -[[ -d "$TMP" ]] || mkdir -p $TMP - -# Download Configurations into the temporary folder -if [[ ! -e "$TMP/README.md" ]]; then - echo "Fetching Configurations from GitHub to $TMP" - git clone --depth=1 --single-branch --branch "$BRANCH" $GITREPO "$TMP" || { echo "Failed to clone the configuration repository"; exit ; } +# Check for the given base path +if [[ -n $CBASE ]]; then + CBASE="${CBASE/#\~/$HOME}" + [[ -d "$CBASE" ]] || { echo "Given base -B $CBASE not found." ; exit ; } else - echo "Using cached Configurations at $TMP" + # Make a Configurations temporary folder if needed + CBASE=./.pio/build-$BRANCH + [[ -d "$CBASE" ]] || mkdir -p "$CBASE" + # Download the specified Configurations branch if needed + if [[ ! -e "$CBASE/README.md" ]]; then + echo "Fetching Configurations from GitHub to $CBASE" + git clone --depth=1 --single-branch --branch "$BRANCH" $GITREPO "$CBASE" || { echo "Failed to clone the configuration repository"; exit ; } + fi fi -echo -e "Start build...\n=====================" +# Build +echo -e "=====================\nProceed with builds...\n=====================" shopt -s nullglob -IFS=' -' -CONF_TREE=$( ls -d "$TMP"/config/examples/*/ "$TMP"/config/examples/*/*/ "$TMP"/config/examples/*/*/*/ "$TMP"/config/examples/*/*/*/*/ | grep -vE ".+\.(\w+)$" ) -for CONF in $CONF_TREE ; do + +export PAUSE=1 + +# Get a list of all folders that contain a file matching "Configuration*.h" +find -ds "$CBASE"/config/examples -type d -name 'Configuration.h' -o -name 'Configuration_adv.h' -print0 | while IFS= read -r -d $'\0' CONF; do + + # Remove the file name and slash from the end of the path + CONF=${CONF%/*} # Get a config's directory name - DIR=$( echo $CONF | sed "s|$TMP/config/examples/||" ) + DIR=${CONF#$CBASE/config/examples/} # If looking for a config, skip others - [[ $FIRST_CONF ]] && [[ $FIRST_CONF != $DIR && "$FIRST_CONF/" != $DIR ]] && continue + [[ $FIRST_CONF ]] && [[ $FIRST_CONF != $DIR && "$FIRST_CONF/" != $DIR ]] && { ((DEBUG)) && echo "[SKIP] $DIR" ; continue ; } # Once found, stop looking unset FIRST_CONF # If skipping, don't build the found one [[ $SKIP_CONF ]] && { unset SKIP_CONF ; continue ; } - # ...if skipping, don't build this one - compgen -G "${CONF}Con*.h" > /dev/null || continue + # Either Configuration.h or Configuration_adv.h must exist + [[ -f "$CONF"/Configuration.h || -f "$CONF"/Configuration_adv.h ]] || { echo "[NONE] $DIR" ; continue ; } + + # Command arguments for 'build_example' + CARGS=("-b" "$CBASE" "-c" "$DIR") + + # Exporting? Add -e argument + ((CEXPORT)) && CARGS+=("-e" "$CEXPORT") + + # Build many environments? Add -m argument + ((MANY)) && CARGS+=("-m") + + # Continue on fail? Add -f argument + ((NOFAIL)) && CARGS+=("-f") + + # Archive the build? Add -a argument + ((ARCHIVE)) && CARGS+=("-a") + + # Redirecting the export/archive output? Add -o argument + [[ -n $OUTBASE ]] && CARGS+=("-o" "$OUTBASE") # Build or print build command for --nobuild - if [[ $DRYRUN ]]; then - echo -e "\033[0;32m[DRYRUN] build_example internal \"$TMP\" \"$DIR\"\033[0m" + if ((DRYRUN)); then + echo -e "\033[0;32m[DRYRUN] build_example ${CARGS[@]}\033[0m" else # Remember where we are in case of failure echo "${BRANCH}*${DIR}" >"$STAT_FILE" - # Build folder is unknown so delete all report files - if [[ $COPY_INI ]]; then - IFIND='find ./.pio/build/ -name "config.ini" -o -name "schema.json" -o -name "schema.yml"' - $IFIND -exec rm "{}" \; - fi - ((DEBUG)) && echo "\"$HERE/build_example\" internal \"$TMP\" \"$DIR\"" - "$HERE/build_example" internal "$TMP" "$DIR" || { echo "Failed to build $DIR"; exit ; } - # Build folder is unknown so copy all report files - [[ $COPY_INI ]] && $IFIND -exec cp "{}" "$CONF" \; + ((DEBUG)) && echo "build_example ${CARGS[@]}" + # Invoke build_example + build_example "${CARGS[@]}" || { echo "Failed to build $DIR" ; exit ; } fi - ((--LIMIT)) || { echo "Limit reached" ; PAUSE=1 ; break ; } + echo + ((--LIMIT)) || { echo "Specified limit reached" ; break ; } + echo + + export PAUSE=0 done -# Delete the build state if not paused early -[[ $PAUSE ]] || rm "$STAT_FILE" +echo "Exiting" -# Delete the temp folder if not preserving generated INI files -if [[ -e "$TMP/config/examples" ]]; then - if [[ $COPY_INI ]]; then - OPEN=$( which gnome-open xdg-open open | head -n1 ) - $OPEN "$TMP" - elif [[ ! $PAUSE ]]; then - rm -rf "$TMP" - fi -fi +# Delete the build state if not paused early +((PAUSE)) || rm -f "$STAT_FILE" diff --git a/buildroot/bin/build_example b/buildroot/bin/build_example index 34549769bb..133f3c4cc9 100755 --- a/buildroot/bin/build_example +++ b/buildroot/bin/build_example @@ -1,38 +1,290 @@ #!/usr/bin/env bash # -# build_example +# Usage: # -# Usage: build_example internal config-home config-folder +# build_example -b|--base= - Configurations root folder (e.g., ./.pio/build-BRANCH) +# -c|--config= - Sub-path of the configs to build (within config/examples) +# [-n|--index=N] - Which environment to build, by index (Based on pins.h comments) +# [-m|--many] - Build all the board's environments listed in pins.h +# [-e|--export=N] - Use CONFIG_EXPORT N to export the config to the export location +# [-a|--archive] - Archive the build (to the export location) +# [-o|--output] - Redirect export / archiving to another location +# (By default export to origin config folder) +# [-f|--nofail] - Don't stop on a failed build +# [-w|--nowarn] - Suppress warnings with extra config options +# [-r|--reveal] - Reveal the config/export folder after the build +# [-h|--help] - Print usage and exit +# [--allow] - Allow this script to run standalone # +usage() { echo "Usage: + +build_example -b|--base= - Configurations root folder (e.g., ./.pio/build-BRANCH) + -c|--config= - Sub-path of the configs to build (within config/examples) + [-n|--index=N] - Which environment to build, by index (Based on pins.h comments) + [-m|--many] - Build all the board's environments listed in pins.h + [-e|--export=N] - Use CONFIG_EXPORT N to export the config to the export location + [-a|--archive] - Archive the build (to the export location) + [-o|--output] - Redirect export / archiving to another location + (By default export to origin config folder) + [-f|--nofail] - Don't stop on a failed build + [-w|--nowarn] - Suppress warnings with extra config options + [-r|--reveal] - Reveal the config/export folder after the build + [-h|--help] - Print usage and exit + [--allow] - Allow this script to run standalone +" +} + +HERE=`dirname $0` +PATH="$HERE:$PATH" + . mfutil -# Require 'internal' as the first argument -[[ "$1" == "internal" ]] || { echo "Don't call this script directly, use build_all_examples instead." ; exit 1 ; } +annc() { echo -e "\033[0;32m$1\033[0m" ; } +alrt() { echo -e "\033[0;31m$1\033[0m" ; } -echo "Testing $3:" +# Get arguments +BUILD=./.pio/build +CLEANER= +ALLOW= +ARCHIVE= +BASE= +CONFIG= +REVEAL= +EXPNUM= +NOFAIL= +OUTBASE= +BUILDINDEX=1 +MANY= -SUB=$2/config/examples/$3 -[[ -d "$SUB" ]] || { echo "$SUB is not a good path" ; exit 1 ; } +while getopts 'ab:c:e:fhmn:o:r-:' OFLAG; do + case "${OFLAG}" in + a) ARCHIVE=1 ;; + b) BASE="${OPTARG%/}" ;; + c) CONFIG="${OPTARG%/}" ;; + e) EXPNUM="$OPTARG" ;; + f) NOFAIL=1 ;; + h) EXIT_USAGE=1 ; break ;; + m) MANY=1 ;; + n) BUILDINDEX="$OPTARG" ;; + o) OUTBASE="${OPTARG%/}" ;; + r) REVEAL=1 ;; + -) ONAM="${OPTARG%%=*}" ; OVAL="${OPTARG#*=}" + case "$ONAM" in + archive) ARCHIVE=1 ;; + allow) ALLOW=1 ;; + base) BASE="${OVAL%/}" ;; + config) CONFIG="${OVAL%/}" ;; + many) MANY=1 ;; + index) BUILDINDEX="$OVAL" ;; + export) EXPNUM="$OVAL" ;; + output) OUTBASE="${OVAL%/}" ;; + help) EXIT_USAGE=1 ; break ;; + nofail) NOFAIL=1 ;; + reveal) REVEAL=1 ;; + *) EXIT_USAGE=2 ; echo "$SELF: unrecognized option \`--$ONAM'" ; break ;; + esac + ;; + *) EXIT_USAGE=2 ; break ;; + esac +done +shift $((OPTIND - 1)) -compgen -G "${SUB}Con*.h" > /dev/null || { echo "No configuration files found in $SUB" ; exit 1 ; } +# Must be called from another script (or with --allow) +[[ $ALLOW || $SHLVL -gt 2 ]] || { echo "Don't call this script directly, use build_all_examples instead." ; exit 1 ; } +# Exit with helpful usage information +((EXIT_USAGE)) && { usage ; let EXIT_USAGE-- ; exit $EXIT_USAGE ; } + +# -b|--base and -c|--config are required +[[ -z $BASE ]] && { echo "-b|--base is required" ; exit 1 ; } +[[ -z $CONFIG ]] && { echo "-c|--config is required" ; exit 1 ; } + +# Expand ~ to $HOME in provided arguments +BASE=${BASE/#\~/$HOME} +CONFIG=${CONFIG/#\~/$HOME} + +# Make sure the examples exist +SUB1="$BASE/config/examples" +[[ -d "$SUB1" ]] || { echo "-b|--base $BASE doesn't contain config/examples" ; exit 1 ; } + +# Make sure the specific config folder exists +SUB="$SUB1/$CONFIG" +[[ -d "$SUB" ]] || { echo "-c|--config $CONFIG doesn't exist" ; exit 1 ; } + +# ...and contains Configuration.h or Configuration_adv.h +[[ -f "$SUB"/Configuration.h || -f "$SUB"/Configuration_adv.h ]] || { echo "No configuration files found in $SUB" ; exit 1 ; } + +# Get the location for exports and archives +if [[ -n $OUTBASE ]]; then + ARCSUB="${OUTBASE/#\~/$HOME}/$CONFIG" + mkdir -p "$ARCSUB" +else + ARCSUB="$SUB" +fi + +# Delete any config files from previous builds +rm -f Marlin/_Bootscreen.h Marlin/_Statusscreen.h + +# Copy configurations into the Marlin folder echo "Getting configuration files from $SUB" -cp "$2/config/default"/*.h Marlin/ -cp "$SUB"/Configuration.h Marlin/ 2>/dev/null -cp "$SUB"/Configuration_adv.h Marlin/ 2>/dev/null -cp "$SUB"/_Bootscreen.h Marlin/ 2>/dev/null -cp "$SUB"/_Statusscreen.h Marlin/ 2>/dev/null +cp "$BASE"/config/default/*.h Marlin/ +cp "$SUB"/*.h Marlin/ + +rm -f Marlin/Config.h Marlin/Config-export.h set -e -# Strip #error lines from Configuration.h -IFS=$'\n'; set -f -$SED -i~ -e "20,30{/#error/d}" Marlin/Configuration.h -rm Marlin/Configuration.h~ -unset IFS; set +f +# Strip #error lines from Configuration.h using +awk 'NR < 20 || NR > 30 || !/#error/' Marlin/Configuration.h > Marlin/Configuration.h~ +mv Marlin/Configuration.h~ Marlin/Configuration.h -echo "Building the firmware now..." -$HERE/mftest -s -a -n1 || { echo "Failed"; exit 1; } +# Hide several warnings when not exporting +[[ -z $EXPNUM ]] && CLEANER=1 -echo "Success" +# Suppress fatal warnings +if ((CLEANER)); then + opt_add NO_CONTROLLER_CUSTOM_WIRING_WARNING + opt_add NO_AUTO_ASSIGN_WARNING + opt_add NO_CREALITY_DRIVER_WARNING + opt_add DIAG_JUMPERS_REMOVED + opt_add DIAG_PINS_REMOVED + opt_add NO_MK3_FAN_PINS_WARNING + opt_add NO_USER_FEEDBACK_WARNING + opt_add NO_Z_SAFE_HOMING_WARNING + opt_add NO_LCD_CONTRAST_WARNING + opt_add NO_MICROPROBE_WARNING + opt_add NO_CONFIGURATION_EMBEDDING_WARNING + opt_add NO_HOMING_CURRENT_WARNING +fi + +# Possible exported file names (in the build folder) +ENAME=("-name" "marlin_config.json" \ + "-o" "-name" "config.ini" \ + "-o" "-name" "schema.json" \ + "-o" "-name" "schema.yml") + +# Possible built firmware names (in the build folder) +BNAME=("-name" "firmware*.hex" \ + "-o" "-name" "firmware*.bin" \ + "-o" "-name" "project*.bin" \ + "-o" "-name" "Robin*.bin" \ + "-o" "-name" "main_*.bin" \ + "-o" "-name" "MarlinSimulator*") + +mkdir -p "$BUILD" + +# If EXPNUM is set then apply to the config before build +if [[ $EXPNUM ]]; then + opt_set CONFIG_EXPORT $EXPNUM + # Clean up old exports + find "$BUILD" -type f \( "${ENAME[@]}" \) -exec rm "{}" \; +fi + +((ARCHIVE)) && find "$BUILD" -type f \( "${BNAME[@]}" \) -exec rm "{}" \; + +echo "Building example $CONFIG..." + +# If doing many builds get a list of all environment names, +# which also gives us the number of environments. +if ((MANY)); then + ENVLIST=$(mfenvs) # BOARD_NAME_STRING (1234): [ env1 env2 env3 ... ] + ENVLIST=${ENVLIST##*: [ } + ENVARRAY=(${ENVLIST% ]}) + ENVCOUNT=${#ENVARRAY[*]} + ((ENVCOUNT)) || { alrt "mfenvs failed for this board." ; exit 1 ; } + echo "Found $ENVCOUNT environment(s): ${ENVARRAY[*]}" +fi + +# Run one or more builds based on --many +# Build all from BUILDINDEX onward (usually 1) meaning ALL. +# MANY with a BUILDINDEX may be useful for continuing an interrupted build. + +while ((1)); do + set +e + + echo "Building example $CONFIG ($BUILDINDEX)..." + + # Run a build and record the error number + mftest -s -a -n$BUILDINDEX ; ERR=$? + + # "Index out of range" can fail without an error + ((MANY)) && ((ERR == 66)) && ERR=0 && break # "index out of range" + + set -e + + if [[ $ERR -gt 0 ]]; then + + alrt "Failed ($ERR)" + + # Error? For --nofail simply log. Otherwise return the error. + if [[ -n $NOFAIL ]]; then + date +"%F %T [FAIL] $CONFIG ($BUILDINDEX)" >>./.pio/error-log.txt + else + exit $ERR + fi + + else + + annc "Success" + + # Copy exports back to the configs + if [[ -n $EXPNUM ]]; then + annc "Exporting $EXPNUM" + [[ -f Marlin/Config-export.h ]] && { cp Marlin/Config-export.h "$ARCSUB"/Config.h ; } + find "$BUILD" -type f \( "${ENAME[@]}" \) -exec cp "{}" "$ARCSUB" \; + fi + + # When building many, create sub-folders for each build env name + if [[ -n $MANY && $ENVCOUNT -gt 1 ]]; then + ENV=${ENVARRAY[BUILDINDEX-1]} + ARCENVSUB="$ARCSUB/$ENV" + else + ARCENVSUB="$ARCSUB" + fi + + # Copy potential firmware files into the config folder + # TODO: Consider firmware that needs an STM32F4_UPDATE folder. + # Currently only BOARD_CREALITY_F401RE env:STM32F401RE_creality + if ((ARCHIVE)); then + annc "Archiving" + find "$BUILD" -type f \( "${BNAME[@]}" \) -exec sh -c ' + ARCDIR="$1" ; CONFIG="$2" ; FILE="$3" ; shift 3 + NAME=${FILE##*/} ; SHRT=${NAME%.*} ; DIR=${FILE%/*} + ZIPX= + if [[ $CONFIG == *Simulator* ]]; then + case $(uname | tr '[:upper:]' '[:lower:]') in + darwin) SUB="macOS" ; ZIPX="-X" ;; + *linux) SUB="Linux" ;; + win*) SUB="Windows" ;; + msys*) SUB="Windows" ;; + cygwin*) SUB="Windows" ;; + mingw*) SUB="Windows" ;; + *) SUB='Unix' ;; + esac + ARCH=$(uname -m | tr '[:lower:]' '[:upper:]') + ARCDIR="$ARCDIR/$SUB-$ARCH" + fi + mkdir -p "$ARCDIR" + rm -f "$ARCDIR"/*.zip "$ARCDIR"/*.sha256.txt + cd "$DIR" + SHASUM=$(sha256sum "$NAME" | cut -d" " -f1) + echo "$CONFIG\n$SHASUM" > "$ARCDIR/$NAME.sha256.txt" + zip $ZIPX "$ARCDIR/$SHRT.zip" "$NAME" && rm "$NAME" + cd - >/dev/null + ' sh "$ARCENVSUB" "$CONFIG" {} + + fi + + # Reveal the configs after the build, if requested + ((REVEAL)) && { annc "Revealing $ARCENVSUB" ; open "$ARCENVSUB" ; } + + fi + + ((MANY)) || break # Only one build if not --many + + # Set up for the next build, if there is one + ((++BUILDINDEX > ENVCOUNT)) && break + +done + +exit 0 diff --git a/buildroot/bin/ci_src_filter b/buildroot/bin/ci_src_filter index 928f492e69..1043e57d81 100755 --- a/buildroot/bin/ci_src_filter +++ b/buildroot/bin/ci_src_filter @@ -3,12 +3,10 @@ # exit on first failure set -e -SED=$(which gsed sed | head -n1) FN="platformio.ini" if [[ $1 == "-n" ]]; then - "${SED}" -i "s/default_src_filter/org_src_filter/" $FN - "${SED}" -i "/org_src_filter/ s/^/default_src_filter = +\n/" $FN + awk '/default_src_filter/ { sub("default_src_filter", "org_src_filter"); print "default_src_filter = +"; } 1' $FN > $FN~ && mv $FN~ $FN else git checkout $FN 2>/dev/null fi diff --git a/buildroot/bin/config.py b/buildroot/bin/config.py new file mode 100755 index 0000000000..b1a67ad965 --- /dev/null +++ b/buildroot/bin/config.py @@ -0,0 +1,96 @@ +''' +config.py - Helper functions for config manipulation +''' +import re + +FILES = ('Marlin/Configuration.h', 'Marlin/Configuration_adv.h') + +def set(file_path, define_name, value): + ''' + Replaces a define in a file with a new value. + Returns True if the define was found and replaced, False otherwise. + ''' + # Read the contents of the file + with open(file_path, 'r') as f: + content = f.readlines() + + modified = False + for i in range(len(content)): + # Regex to match the desired pattern + match = re.match(r'^(\s*)(/*)(\s*)(#define\s+{})\s+(.*)$'.format(re.escape(define_name)), content[i]) + if match: + new_line = f"{match[1]}{match[3]}{match[4]} {value} // {match[5]}\n" + content[i] = new_line + modified = True + + # Write the modified content back to the file only if changes were made + if modified: + with open(file_path, 'w') as f: + f.writelines(content) + return True + + return False + +def add(file_path, define_name, value=""): + ''' + Insert a define on the first blank line in a file. + Returns True if the define was found and replaced, False otherwise. + ''' + with open(file_path, 'r') as f: + content = f.readlines() + + # Prepend a space to the value if it's not empty + if value != "": + value = " " + value + + # Find the first blank line to insert the new define + for i in range(len(content)): + if content[i].strip() == '': + # Insert the define at the first blank line + content.insert(i, f"#define {define_name}{value}\n") + break + else: + # If no blank line is found, append to the end + content.append(f"#define {define_name}{value}\n") + + with open(file_path, 'w') as f: + f.writelines(content) + +def enable(file_path, define_name, enable=True): + ''' + Uncomment or comment the named defines in the given file path. + Returns True if the define was found, False otherwise. + ''' + # Read the contents of the file + with open(file_path, 'r') as f: + content = f.readlines() + + # Prepare the regex + regex = re.compile(r'^(\s*)(/*)(\s*)(#define\s+{}\b.*?)( *//.*)?$'.format(re.escape(define_name))) + + # Find the define in the file and uncomment or comment it + found = False + modified = False + for i in range(len(content)): + match = regex.match(content[i]) + if not match: continue + found = True + if enable: + if match[2]: + modified = True + comment = '' if match[5] is None else ' ' + match[5] + content[i] = f"{match[1]}{match[3]}{match[4]}{comment}\n" + else: + if not match[2]: + modified = True + comment = '' if match[5] is None else match[5] + if comment.startswith(' '): comment = comment[2:] + content[i] = f"{match[1]}//{match[3]}{match[4]}{comment}\n" + break + + # Write the modified content back to the file only if changes were made + if modified: + with open(file_path, 'w') as f: + f.writelines(content) + + return found diff --git a/buildroot/bin/generate_version b/buildroot/bin/generate_version index 70a108b1fe..ff85fe7ecf 100755 --- a/buildroot/bin/generate_version +++ b/buildroot/bin/generate_version @@ -19,6 +19,7 @@ VERSION="$(git -C "${DIR}" describe --tags --first-parent 2>/dev/null || true)" STRING_DISTRIBUTION_DATE="${STRING_DISTRIBUTION_DATE:-$(date '+%Y-%m-%d %H:%M')}" SHORT_BUILD_VERSION="${SHORT_BUILD_VERSION:-${BRANCH}}" DETAILED_BUILD_VERSION="${DETAILED_BUILD_VERSION:-${BRANCH}-${VERSION}}" +PROTOCOL_VERSION="1.0" # Gets some misc options from their defaults DEFAULT_MACHINE_UUID="${DEFAULT_MACHINE_UUID:-$(awk -F'"' \ @@ -65,68 +66,52 @@ cat > "${WRITE_FILE}" < "SHORT_NAME (###): [ env1 env2 env3 ... ]" +# + +[[ -d Marlin/src ]] || { echo "Please 'cd' to the Marlin repo root." ; exit 1 ; } +which pio >/dev/null || { echo "Make sure 'pio' is in your execution PATH." ; exit 1 ; } + +errout() { echo -e "\033[0;31m$1\033[0m" ; } + +case $(uname | tr '[:upper:]' '[:lower:]') in + darwin) SYS='mac' ;; + *linux) SYS='lin' ;; + win*) SYS='win' ;; + msys*) SYS='win' ;; + cygwin*) SYS='win' ;; + mingw*) SYS='win' ;; + *) SYS='uni' ;; +esac + +ACODE='/^[[:space:]]*#define[[:space:]]MOTHERBOARD[[:space:]]/ { sub(/^BOARD_/, "", $3); print $3 }' +MB=$(awk "$ACODE" Marlin/Configuration.h 2>/dev/null) +[[ -z $MB ]] && MB=$(awk "$ACODE" Marlin/Config.h 2>/dev/null) +[[ -z $MB ]] && { echo "Error - Can't read MOTHERBOARD setting." ; exit 1 ; } +BLINE=$( grep -E "define\s+BOARD_$MB\b" Marlin/src/core/boards.h ) +BNUM=$( sed -E 's/^.+BOARD_[^ ]+ +([0-9]+).+$/\1/' <<<"$BLINE" ) +[[ -z $BNUM ]] && { echo "Error - Can't find BOARD_$MB in core/boards.h." ; exit 1 ; } +ENVS=( $( grep -EA1 "MB\(.*\b$MB\b.*\)" Marlin/src/pins/pins.h | grep -E "#include.+//.+(env|$SYS):[^ ]+" | grep -oE "(env|$SYS):[^ ]+" | sed -E "s/(env|$SYS)://" ) ) +[[ -z $ENVS ]] && { errout "Error - Can't find target(s) for $MB ($BNUM)." ; exit 1 ; } +ECOUNT=${#ENVS[*]} +[[ $ECOUNT == 1 ]] && EOUT=$ENVS || EOUT="${ENVS[@]}" +echo "$MB ($BNUM): [ $EOUT ]" diff --git a/buildroot/bin/mftest b/buildroot/bin/mftest index 8a4f3afd4f..07601654aa 100755 --- a/buildroot/bin/mftest +++ b/buildroot/bin/mftest @@ -8,29 +8,32 @@ [[ -d Marlin/src ]] || { echo "Please 'cd' to the Marlin repo root." ; exit 1 ; } +which pio >/dev/null || { echo "Make sure 'pio' is in your execution PATH." ; exit 1 ; } + perror() { echo -e "$0: \033[0;31m$1 -- $2\033[0m" ; } errout() { echo -e "\033[0;31m$1\033[0m" ; } bugout() { ((DEBUG)) && echo -e "\033[0;32m$1\033[0m" ; } usage() { echo " -Usage: mftest [-t|--env=] [-n|--num=] [-m|--make] [-y|--build=] - mftest [-a|--autobuild] +Usage: mftest [-a|--autobuild] mftest [-r|--rebuild] mftest [-s|--silent] + mftest [-t|--env=] [-n|--num=] [-m|--make] [-y|--build=] mftest [-u|--autoupload] [-n|--num=] OPTIONS - -t --env The environment to apply / run, or the menu index number. - -n --num The index of the test to run. (In file order.) - -m --make Use the make / Docker method for the build. - -y --build Skip 'Do you want to build this test?' and assume YES. - -h --help Print this help. -a --autobuild PIO Build using the MOTHERBOARD environment. + -d --default Restore to defaults before applying configs. + -h --help Print this help. + -m --make Use the make / Docker method for the build. + -n --num The index of the test to run. (In file order.) + -r --rebuild Rebuild previous PIO Build. + -s --silent Silence build output from PlatformIO. + -t --env The environment to apply / run, or the menu index number. -u --autoupload PIO Upload using the MOTHERBOARD environment. -v --verbose Extra output for debugging. - -s --silent Silence build output from PlatformIO. - -d --default Restore to defaults before applying configs. + -y --build Skip 'Do you want to build this test?' and assume YES. env shortcuts: tree due esp lin lp8|lpc8 lp9|lpc9 m128 m256|mega stm|f1 f4 f7 s6 teensy|t31|t32 t35|t36 t40|t41 " @@ -39,7 +42,6 @@ env shortcuts: tree due esp lin lp8|lpc8 lp9|lpc9 m128 m256|mega stm|f1 f4 f7 s6 TESTPATH=buildroot/tests STATE_FILE="./.pio/.mftestrc" -SED=$(which gsed sed | head -n1) shopt -s extglob nocasematch @@ -55,7 +57,7 @@ TESTENV='-' CHOICE=0 DEBUG=0 -while getopts 'abdhmrsuvyn:t:-:' OFLAG; do +while getopts 'adhmn:rst:uvy-:' OFLAG; do case "${OFLAG}" in a) AUTO_BUILD=1 ; bugout "Auto-Build target..." ;; d) DL_DEFAULTS=1 ; bugout "Restore to defaults..." ;; @@ -72,7 +74,7 @@ while getopts 'abdhmrsuvyn:t:-:' OFLAG; do u) AUTO_BUILD=2 ; bugout "Auto-Upload target..." ;; v) DEBUG=1 ; bugout "Debug ON" ;; y) BUILD_YES='Y' ; bugout "Build will initiate..." ;; - -) IFS="=" read -r ONAM OVAL <<< "$OPTARG" + -) ONAM="${OPTARG%%=*}" ; OVAL="${OPTARG#*=}" case "$ONAM" in help) [[ -z "$OVAL" ]] || perror "option can't take value $OVAL" $ONAM ; EXIT_USAGE=1 ;; autobuild) AUTO_BUILD=1 ; bugout "Auto-Build target..." ;; @@ -105,6 +107,7 @@ debug|verbose) DEBUG=1 ; bugout "Debug ON" ;; *) EXIT_USAGE=2 ;; esac done +shift $((OPTIND - 1)) ((EXIT_USAGE)) && { usage ; let EXIT_USAGE-- ; exit $EXIT_USAGE ; } @@ -156,13 +159,19 @@ if ((AUTO_BUILD)); then *) SYS='uni' ;; esac echo ; echo -n "Auto " ; ((AUTO_BUILD == 2)) && echo "Upload..." || echo "Build..." - MB=$( grep -E "^\s*#define MOTHERBOARD" Marlin/Configuration.h | awk '{ print $3 }' | $SED 's/BOARD_//;s/\r//' ) + + # + # Get the MOTHERBOARD define value from the .h file and strip off the "BOARD_" prefix + # + ACODE='/^[[:space:]]*#define[[:space:]]MOTHERBOARD[[:space:]]/ { sub(/^BOARD_/, "", $3); print $3 }' + MB=$(awk "$ACODE" Marlin/Configuration.h 2>/dev/null) + [[ -z $MB ]] && MB=$(awk "$ACODE" Marlin/Config.h 2>/dev/null) [[ -z $MB ]] && { echo "Error - Can't read MOTHERBOARD setting." ; exit 1 ; } BLINE=$( grep -E "define\s+BOARD_$MB\b" Marlin/src/core/boards.h ) - BNUM=$( $SED -E 's/^.+BOARD_[^ ]+ +([0-9]+).+$/\1/' <<<"$BLINE" ) - BDESC=$( $SED -E 's/^.+\/\/ *(.+)$/\1/' <<<"$BLINE" ) + BNUM=$( sed -E 's/^.+BOARD_[^ ]+ +([0-9]+).+$/\1/' <<<"$BLINE" ) + BDESC=$( sed -E 's/^.+\/\/ *(.+)$/\1/' <<<"$BLINE" ) [[ -z $BNUM ]] && { echo "Error - Can't find BOARD_$MB in core/boards.h." ; exit 1 ; } - ENVS=( $( grep -EA1 "MB\(.*\b$MB\b.*\)" Marlin/src/pins/pins.h | grep -E "#include.+//.+(env|$SYS):[^ ]+" | grep -oE "(env|$SYS):[^ ]+" | $SED -E "s/(env|$SYS)://" ) ) + ENVS=( $( grep -EA1 "MB\(.*\b$MB\b.*\)" Marlin/src/pins/pins.h | grep -E "#include.+//.+(env|$SYS):[^ ]+" | grep -oE "(env|$SYS):[^ ]+" | sed -E "s/(env|$SYS)://" ) ) [[ -z $ENVS ]] && { errout "Error - Can't find target(s) for $MB ($BNUM)." ; exit 1 ; } ECOUNT=${#ENVS[*]} @@ -187,9 +196,12 @@ if ((AUTO_BUILD)); then fi else echo "Detected \"$BDESC\" | $MB ($BNUM)." - [[ $CHOICE > $ECOUNT ]] && { echo "Environment selection out of range." ; exit 1 ; } + [[ $CHOICE > $ECOUNT ]] && { echo "Environment selection out of range." ; exit 66 ; } fi TARGET="${ENVS[$CHOICE-1]}" + if [[ $MB == 'SIMULATED' && $TARGET == 'linux_native' ]]; then + TARGET="simulator_linux_release" # Skip the linux_native environment + fi echo "Selected $TARGET" fi @@ -202,7 +214,7 @@ if ((AUTO_BUILD)); then echo "Building environment $TARGET for board $MB ($BNUM)..." ; echo pio run $SILENT_FLAG -e $TARGET fi - exit 0 + exit $? fi # @@ -268,7 +280,7 @@ if [[ $CHOICE == 0 ]]; then while IFS= read -r LINE do if [[ $LINE =~ $ISEXEC ]]; then - DESC=$( "$SED" -E 's/^exec_test \$1 \$2 "([^"]+)".*$/\1/g' <<<"$LINE" ) + DESC=$( sed -E 's/^exec_test \$1 \$2 "([^"]+)".*$/\1/g' <<<"$LINE" ) (( ++IND < 10 )) && echo -n " " echo " $IND) $DESC" fi @@ -313,7 +325,7 @@ echo "$OUT" | { ((IND == CHOICE)) && { GOTX=1 [[ -n $DL_DEFAULTS && $LINE =~ $ISRST ]] && LINE="use_example_configs" - [[ $CMD == "" ]] && CMD="$LINE" || CMD=$( echo -e "$CMD$LINE" | $SED -e 's/\\//g' | $SED -E 's/ +/ /g' ) + [[ $CMD == "" ]] && CMD="$LINE" || CMD=$( echo -e "$CMD$LINE" | sed -e 's/\\//g' | sed -E 's/ +/ /g' ) [[ $LINE =~ $ISCONT ]] || { echo "$CMD" ; eval "$CMD" ; CMD="" ; } } fi diff --git a/buildroot/bin/mfutil b/buildroot/bin/mfutil index 75a2791cfe..e9ee57fb9e 100755 --- a/buildroot/bin/mfutil +++ b/buildroot/bin/mfutil @@ -4,16 +4,13 @@ # # Check dependencies -which curl 1>/dev/null 2>&1 || { echo "curl not found! Please install it."; exit ; } -which git 1>/dev/null 2>&1 || { echo "git not found! Please install it."; exit ; } - -SED=$(command -v gsed 2>/dev/null || command -v sed 2>/dev/null) -[[ -z "$SED" ]] && { echo "No sed found, please install sed" ; exit 1 ; } +which curl &>/dev/null || { echo "curl not found! Please install it."; exit 1 ; } +which git &>/dev/null || { echo "git not found! Please install it."; exit 1 ; } +which sed &>/dev/null || { echo "sed not found! Please install it."; exit 1 ; } OPEN=$( which gnome-open xdg-open open | head -n1 ) SELF=`basename "$0"` -HERE=`dirname "$0"` # Check if called in the right location [[ -e "Marlin/src" ]] || { echo -e "This script must be called from a Marlin working copy with:\n ./buildroot/bin/$SELF $1" ; exit ; } diff --git a/buildroot/bin/opt_add b/buildroot/bin/opt_add index 2306ebdaa1..3abe309ab6 100755 --- a/buildroot/bin/opt_add +++ b/buildroot/bin/opt_add @@ -1,3 +1,11 @@ -#!/usr/bin/env bash +#!/usr/bin/env python -eval "echo '#define ${@}' | cat - Marlin/Configuration.h > temp && mv temp Marlin/Configuration.h" +import sys, config + +def main(): + args = sys.argv[1:] + for name in args: + config.add(config.FILES[0], name) + +if __name__ == "__main__": + main() diff --git a/buildroot/bin/opt_disable b/buildroot/bin/opt_disable index 0444e1b773..ce0eaa4ee6 100755 --- a/buildroot/bin/opt_disable +++ b/buildroot/bin/opt_disable @@ -1,15 +1,21 @@ -#!/usr/bin/env bash +#!/usr/bin/env python -# exit on first failure -set -e +import sys, os, config -SED=$(which gsed sed | head -n1) +def main(): + args = sys.argv[1:] -for opt in "$@" ; do - DID=0 ; FOUND=0 - for FN in Configuration Configuration_adv; do - "${SED}" -i "/^\(\s*\)\(#define\s\+${opt}\b\s\?\)\(\s\s\)\?/{s//\1\/\/\2/;h};\${x;/./{x;q0};x;q9}" Marlin/$FN.h && DID=1 - ((DID||FOUND)) || { grep -E "^\s*//\s*#define\s+${opt}\b" Marlin/$FN.h >/dev/null && FOUND=1 ; } - done - ((DID||FOUND)) || (echo "ERROR: $(basename $0) Can't find ${opt}" >&2 && exit 9) -done + for name in args: + changed = False + + for file in config.FILES: + if os.path.exists(file): + if config.enable(file, name, False): + changed = True + + if not changed: + print(f"ERROR: Can't find {name}") + exit(1) + +if __name__ == "__main__": + main() diff --git a/buildroot/bin/opt_enable b/buildroot/bin/opt_enable index f9be82cbd1..644edb9a28 100755 --- a/buildroot/bin/opt_enable +++ b/buildroot/bin/opt_enable @@ -1,15 +1,21 @@ -#!/usr/bin/env bash +#!/usr/bin/env python -# exit on first failure -set -e +import sys, os, config -SED=$(which gsed sed | head -n1) +def main(): + args = sys.argv[1:] -for opt in "$@" ; do - DID=0 ; FOUND=0 - for FN in Configuration Configuration_adv; do - "${SED}" -i "/^\(\s*\)\/\/\(\s*\)\(#define\s\+${opt}\b\)\( \?\)/{s//\1\2\3\4\4\4/;h};\${x;/./{x;q0};x;q9}" Marlin/$FN.h && DID=1 - ((DID||FOUND)) || { grep -E "^\s*#define\s+${opt}\b" Marlin/$FN.h >/dev/null && FOUND=1 ; } - done - ((DID||FOUND)) || (echo "ERROR: $(basename $0) Can't find ${opt}" >&2 && exit 9) -done + for name in args: + changed = False + + for file in config.FILES: + if os.path.exists(file): + if config.enable(file, name): + changed = True + + if not changed: + print(f"ERROR: Can't find {name}") + exit(1) + +if __name__ == "__main__": + main() diff --git a/buildroot/bin/opt_find b/buildroot/bin/opt_find index a7c8fd9d71..bab9da0e46 100755 --- a/buildroot/bin/opt_find +++ b/buildroot/bin/opt_find @@ -23,8 +23,8 @@ esac while [[ $# > 0 ]]; do DID=0 - for FN in Configuration Configuration_adv; do - FOUND=$( grep -HEn "^\s*${COMM}#define\s+[A-Z0-9_]*${1}" "Marlin/$FN.h" 2>/dev/null ) + for FN in Marlin/Configuration.h Marlin/Configuration_adv.h; do + FOUND=$( grep -HEn "^\s*${COMM}#define\s+[A-Z0-9_]*${1}" $FN 2>/dev/null ) [[ -n "$FOUND" ]] && { echo "$FOUND" ; DID=1 ; } done ((DID)) || { echo "ERROR: ${MYNAME} - No ${TYPE}match for ${1}" ; exit 9; } diff --git a/buildroot/bin/opt_set b/buildroot/bin/opt_set index b9935512a4..cf8bbb9449 100755 --- a/buildroot/bin/opt_set +++ b/buildroot/bin/opt_set @@ -1,17 +1,25 @@ -#!/usr/bin/env bash +#!/usr/bin/env python -# exit on first failure -set -e +import sys, os, config -SED=$(which gsed sed | head -n1) +def main(): + args = sys.argv[1:] + if len(args) % 2 != 0: + print("ERROR: Please provide pairs of ") + return -while [[ $# > 1 ]]; do - DID=0 - for FN in Configuration Configuration_adv; do - "${SED}" -i "/^\(\s*\)\/*\s*\(#define\s\+${1}\b\) *\(.*\)$/{s//\1\2 ${2} \/\/ \3/;h};\${x;/./{x;q0};x;q9}" Marlin/$FN.h && DID=1 - done - ((DID)) || - eval "echo '#define ${1} ${2}' >>Marlin/Configuration.h" || - (echo "ERROR: opt_set Can't set or add ${1}" >&2 && exit 9) - shift 2 -done + for i in range(0, len(args), 2): + name = args[i] + value = args[i + 1] + changed = False + + for file in config.FILES: + if os.path.exists(file): + if config.set(file, name, value): + changed = True + + if not changed: + config.add(config.FILES[0], name, value) + +if __name__ == "__main__": + main() diff --git a/buildroot/bin/restore_configs b/buildroot/bin/restore_configs index ea998484c2..e1a601679b 100755 --- a/buildroot/bin/restore_configs +++ b/buildroot/bin/restore_configs @@ -7,5 +7,6 @@ if [[ $1 == '-d' || $1 == '--default' ]]; then else git checkout Marlin/Configuration.h 2>/dev/null git checkout Marlin/Configuration_adv.h 2>/dev/null - git checkout Marlin/src/pins/ramps/pins_RAMPS.h 2>/dev/null + git checkout Marlin/config.ini 2>/dev/null + git checkout Marlin/src/pins/*/pins_*.h 2>/dev/null fi diff --git a/buildroot/bin/run_tests b/buildroot/bin/run_tests index 26284fa693..9a03be3cc7 100755 --- a/buildroot/bin/run_tests +++ b/buildroot/bin/run_tests @@ -67,7 +67,7 @@ else printf "\033[0;32mMatching test \033[0m#$3\033[0;32m: '\033[0m$test_name\033[0;32m'\n" fi fi - $TESTS/$2 $1 $2 "$test_name" + "$TESTS/$2" $1 $2 "$test_name" if [[ $GIT_RESET_HARD == "true" ]]; then git reset --hard HEAD else diff --git a/buildroot/bin/uncrust b/buildroot/bin/uncrust index 7898f73c8c..db4c3fb03f 100755 --- a/buildroot/bin/uncrust +++ b/buildroot/bin/uncrust @@ -4,9 +4,10 @@ # TMPDIR=`mktemp -d` +HERE=`dirname "$0"` # Reformat a single file to tmp/ -if uncrustify -l CPP -c ./buildroot/share/extras/uncrustify.cfg -f "$1" >$TMPDIR/uncrustify.out ; then +if uncrustify -l CPP -c "$HERE/../share/uncrustify/uncrustify.cfg" -f "$1" >$TMPDIR/uncrustify.out ; then cp "$TMPDIR/uncrustify.out" "$1" ; # Replace the original file else echo "Something went wrong with uncrustify." diff --git a/buildroot/bin/use_example_configs b/buildroot/bin/use_example_configs index 1fdab1de6c..282e057dde 100755 --- a/buildroot/bin/use_example_configs +++ b/buildroot/bin/use_example_configs @@ -8,28 +8,37 @@ # use_example_configs release-2.0.9.4:Creality/CR-10/CrealityV1 # # If a configpath has spaces (or quotes) escape them or enquote the path +# If no branch: prefix is given use configs based on the current branch name. +# e.g., For `latest-2.1.x` name the working branch something like "my_work-2.1.x." +# The branch or tag must first exist at MarlinFirmware/Configurations. +# The fallback branch is bugfix-2.1.x. # which curl >/dev/null && TOOL='curl -L -s -S -f -o wgot' which wget >/dev/null && TOOL='wget -q -O wgot' CURR=$(git branch 2>/dev/null | grep ^* | sed 's/\* //g') -[[ $CURR == "bugfix-2.0.x" ]] && BRANCH=bugfix-2.0.x || BRANCH=bugfix-2.1.x - -REPO=$BRANCH +case "$CURR" in + bugfix-2.*.x ) BRANCH=$CURR ;; + *-2.1.x|2.1.x ) BRANCH=latest-2.1.x ;; + *-2.0.x|2.0.x ) BRANCH=latest-2.0.x ;; + *-1.1.x|1.1.x ) BRANCH=latest-1.1.x ;; + *-1.0.x|1.0.x ) BRANCH=latest-1.0.x ;; + * ) BRANCH=bugfix-2.1.x ;; +esac if [[ $# > 0 ]]; then IFS=: read -r PART1 PART2 <<< "$@" - [[ -n $PART2 ]] && { UDIR="$PART2" ; REPO="$PART1" ; } \ + [[ -n $PART2 ]] && { UDIR="$PART2" ; BRANCH="$PART1" ; } \ || { UDIR="$PART1" ; } RDIR="${UDIR// /%20}" - echo "Fetching $UDIR configurations from $REPO..." + echo "Fetching $UDIR configurations from $BRANCH..." EXAMPLES="examples/$RDIR" else EXAMPLES="default" fi -CONFIGS="https://raw.githubusercontent.com/MarlinFirmware/Configurations/$REPO/config/${EXAMPLES}" +CONFIGS="https://raw.githubusercontent.com/MarlinFirmware/Configurations/$BRANCH/config/${EXAMPLES}" restore_configs diff --git a/buildroot/share/git/mfhelp b/buildroot/share/git/mfhelp index 1afc4c686b..cd34926186 100755 --- a/buildroot/share/git/mfhelp +++ b/buildroot/share/git/mfhelp @@ -12,6 +12,7 @@ Marlin Firmware Commands: mfadd ....... Fetch a remote branch from any Marlin fork mfclean ..... Attempt to clean up merged and deleted branches mfdoc ....... Build the website, serve locally, and browse + mfenvs ...... Get current board SHORT_NAME (###): [ env1 env2 ... ] mffp ........ Push new commits directly to MarlinFirmware mfinfo ...... Provide branch information (for the other scripts) mfinit ...... Create an 'upstream' remote for 'MarlinFirmare'