🧑‍💻 Update helper scripts

This commit is contained in:
Scott Lahteine 2024-12-16 15:06:41 -06:00
parent a2d3cdde5a
commit c9044b401d
19 changed files with 696 additions and 234 deletions

View file

View file

@ -2,29 +2,50 @@
#
# Usage:
#
# build_all_examples [-b|--branch=<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>] - 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=<path>] - 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=<branch>] [-d|--debug] [-i|--ini] [-r|--resume=<path>]
$SELF [-b|--branch=<branch>] [-d|--debug] [-i|--ini] [-c|--continue]
$SELF [-b|--branch=<branch>] [-d|--debug] [-i|--ini] [-s|--skip]
$SELF [-b|--branch=<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>] - 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=<path>] - 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"

View file

@ -1,38 +1,290 @@
#!/usr/bin/env bash
#
# build_example
# Usage:
#
# Usage: build_example internal config-home config-folder
# build_example -b|--base=<path> - Configurations root folder (e.g., ./.pio/build-BRANCH)
# -c|--config=<rel> - 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=<path> - Configurations root folder (e.g., ./.pio/build-BRANCH)
-c|--config=<rel> - 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

View file

@ -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 = +<src\/*>\n/" $FN
awk '/default_src_filter/ { sub("default_src_filter", "org_src_filter"); print "default_src_filter = +<src/*>"; } 1' $FN > $FN~ && mv $FN~ $FN
else
git checkout $FN 2>/dev/null
fi

96
buildroot/bin/config.py Executable file
View file

@ -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

View file

@ -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}" <<EOF
*/
/**
* Marlin release version identifier
*/
#ifndef SHORT_BUILD_VERSION
#define SHORT_BUILD_VERSION "${SHORT_BUILD_VERSION}"
#endif
* Marlin release version identifier
*/
#define SHORT_BUILD_VERSION "${SHORT_BUILD_VERSION}"
/**
* Verbose version identifier which should contain a reference to the location
* from where the binary was downloaded or the source code was compiled.
*/
#ifndef DETAILED_BUILD_VERSION
#define DETAILED_BUILD_VERSION "${DETAILED_BUILD_VERSION}"
#endif
* Verbose version identifier which should contain a reference to the location
* from where the binary was downloaded or the source code was compiled.
*/
#define DETAILED_BUILD_VERSION "${DETAILED_BUILD_VERSION}"
/**
* The STRING_DISTRIBUTION_DATE represents when the binary file was built,
* here we define this default string as the date where the latest release
* version was tagged.
*/
#ifndef STRING_DISTRIBUTION_DATE
#define STRING_DISTRIBUTION_DATE "${STRING_DISTRIBUTION_DATE}"
#endif
* The STRING_DISTRIBUTION_DATE represents when the binary file was built,
* here we define this default string as the date where the latest release
* version was tagged.
*/
#define STRING_DISTRIBUTION_DATE "${STRING_DISTRIBUTION_DATE}"
/**
* The protocol for communication to the host. Protocol indicates communication
* standards such as the use of ASCII, "echo:" and "error:" line prefixes, etc.
* (Other behaviors are given by the firmware version and capabilities report.)
*/
#ifndef PROTOCOL_VERSION
#define PROTOCOL_VERSION "${PROTOCOL_VERSION}"
#endif
* The protocol for communication to the host. Protocol indicates communication
* standards such as the use of ASCII, "echo:" and "error:" line prefixes, etc.
* (Other behaviors are given by the firmware version and capabilities report.)
*/
#define PROTOCOL_VERSION "${PROTOCOL_VERSION}"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
*/
#ifndef MACHINE_NAME
#define MACHINE_NAME "${MACHINE_NAME}"
#endif
* Defines a generic printer name to be output to the LCD after booting Marlin.
*/
#define MACHINE_NAME "${MACHINE_NAME}"
/**
* The SOURCE_CODE_URL is the location where users will find the Marlin Source
* Code which is installed on the device. In most cases —unless the manufacturer
* has a distinct Github fork— the Source Code URL should just be the main
* Marlin repository.
*/
#ifndef SOURCE_CODE_URL
#define SOURCE_CODE_URL "${SOURCE_CODE_URL}"
#endif
* The SOURCE_CODE_URL is the location where users will find the Marlin Source
* Code which is installed on the device. In most cases —unless the manufacturer
* has a distinct Github fork— the Source Code URL should just be the main
* Marlin repository.
*/
#define SOURCE_CODE_URL "${SOURCE_CODE_URL}"
/**
* Default generic printer UUID.
*/
#ifndef DEFAULT_MACHINE_UUID
#define DEFAULT_MACHINE_UUID "${DEFAULT_MACHINE_UUID}"
#endif
* Default generic printer UUID.
*/
#define DEFAULT_MACHINE_UUID "${DEFAULT_MACHINE_UUID}"
/**
* The WEBSITE_URL is the location where users can get more information such as
* documentation about a specific Marlin release.
*/
#ifndef WEBSITE_URL
#define WEBSITE_URL "${WEBSITE_URL}"
#endif
* The WEBSITE_URL is the location where users can get more information such as
* documentation about a specific Marlin release.
*/
#define WEBSITE_URL "${WEBSITE_URL}"
EOF

33
buildroot/bin/mfenvs Executable file
View file

@ -0,0 +1,33 @@
#!/usr/bin/env bash
#
# mfenvs Print the current board and environment information
# Output -> "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 ]"

View file

@ -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=<env|index>] [-n|--num=<num>] [-m|--make] [-y|--build=<Y|n>]
mftest [-a|--autobuild]
Usage: mftest [-a|--autobuild]
mftest [-r|--rebuild]
mftest [-s|--silent]
mftest [-t|--env=<env|index>] [-n|--num=<num>] [-m|--make] [-y|--build=<Y|n>]
mftest [-u|--autoupload] [-n|--num=<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

View file

@ -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 ; }

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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; }

View file

@ -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 <name> <value>")
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()

View file

@ -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

View file

@ -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

View file

@ -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."

View file

@ -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

View file

@ -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'