intitial commit

This commit is contained in:
2020-10-03 15:44:10 -05:00
commit 22089da821
1535 changed files with 1364139 additions and 0 deletions

View File

@ -0,0 +1,60 @@
## Marlin Github Helper Scripts
### Introduction
A Pull Request is often just the start of a longer process of patching and refining the code until it's ready to merge. In that process it's common to accumulate a lot of commits, some of which are non-functional. Before merging any PR, excess commits need to be "squashed" and sometimes rearranged or reworked to produce a well-packaged set of changes and keep the commit history relatively clean.
In addition, while a PR is being worked on other commits may be merged, leading to conflicts that need resolution. For this reason, it's a best practice to periodically refresh the PR so the working copy closely reflects the final merge into upstream `MarlinFirmware`.
#### Merge vs Rebase
If you plan to create PRs and work on them after submission I recommend not using Github Desktop to sync and merge. Use the command line instead. Github Desktop provides a "merge" option, but I've found that "`git rebase`" is much cleaner and easier to manage. Merge applies new work _after_ your commits, which buries them deeper in the commit history and makes it hard to bring them together as a final packaged unit. Rebase helpfully moves your commits to the tip of the branch, ensuring that your commits are adapted to the current code. This makes it easier to keep revising the commits in-place.
### The Scripts
The following scripts can be used on any system with a GNU environment to speed up the process of working with Marlin branches and submitting changes to the project.
#### Remotes
File|Description
----|-----------
mfadd [user]|Add and Fetch Remote - Add and fetch another user's Marlin fork. Optionally, check out one of their branches.
mfinit|Init Working Copy - Create a remote named '`upstream`' (for use by the other scripts) pointing to the '`MarlinFirmware`' fork. This only needs to be used once. Newer versions of Github Desktop may create `upstream` on your behalf.
#### Branches
File|Description
----|-----------
mfnew [branch]|New Branch - Creates a new branch based on `upstream/[PR-target]`. All new work should start with this command.
mffp|Fast Push - Push the HEAD or a commit ID to `upstream` immediately. Requires privileged access to the MarlinFirmware repo.
firstpush|Push the current branch to 'origin' -your fork on Github- and set it to track '`origin`'. The branch needs to reside on Github before you can use it to make a PR.
#### Making / Amending PRs
File|Description
----|-----------
mfpr|Pull Request - Open the Compare / Pull Request page on Github for the current branch.
mfrb|Do a `git rebase` then `git rebase -i` of the current branch onto `upstream/[PR-target]`. Use this to edit your commits anytime.
mfqp|Quick Patch - Commit all current changes as "patch", then do `mfrb`, followed by `git push -f` if no conflicts need resolution.
#### Documentation
File|Description
----|-----------
mfdoc|Build the documentation with Jekyll and preview it locally.
mfpub|Build and publish the documentation to marlinfw.org.
#### Utilities
File|Description
----|-----------
ghtp -[h/s]|Set the protocol to use for all remotes. -h for HTTPS, -s for SSL.
ghpc [-f]|Push current branch to 'origin' or to the remote indicated by the error.
mfinfo|This utility script is used by the other scripts to get:<br/>- The upstream project ('`MarlinFirmware`')<br/>- the '`origin`' project (i.e., your Github username),<br/>- the repository name ('`Marlin`'),<br/>- the PR target branch ('`bugfix-1.1.x`'), and<br/>- the current branch (or the first command-line argument).<br/><br/>By itself, `mfinfo` simply prints these values to the console.
mfclean&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|Prune your merged and remotely-deleted branches.
---
### Examples
For a demonstration of these scripts see the video [Marlin Live - May 9 2019](https://youtu.be/rwT4G0uVTIY). There is also an old write-up at [#3193](https://github.com/MarlinFirmware/Marlin/issues/3193).

View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
#
# firstpush
#
# Push a branch to 'origin' and open the
# commit log to watch Travis CI progress.
#
[[ $# == 0 ]] || { echo "usage: `basename $0`" 1>&2 ; exit 1; }
MFINFO=$(mfinfo) || exit 1
IFS=' ' read -a INFO <<< "$MFINFO"
FORK=${INFO[1]}
REPO=${INFO[2]}
BRANCH=${INFO[5]}
git push --set-upstream origin $BRANCH
which xdg-open >/dev/null && TOOL=xdg-open
which gnome-open >/dev/null && TOOL=gnome-open
which open >/dev/null && TOOL=open
URL="https://github.com/$FORK/$REPO/commits/$BRANCH"
if [ -z "$OPEN" ]; then
echo "Can't find a tool to open the URL:"
echo $URL
else
echo "Viewing commits on $BRANCH..."
"$OPEN" "$URL"
fi

68
buildroot/share/git/ghpc Normal file
View File

@ -0,0 +1,68 @@
#!/usr/bin/env bash
#
# ghpc (GitHub Push Current)
#
# - Push current branch to its remote. Try the following until it works:
# - Plain 'git push'
# - 'git push -f'
# - Try the 'git push' command from the 'git push' error message
# - Try adding '-f' to that command
#
yay() { echo "SUCCESS" ; }
boo() { echo "FAIL" ; }
FORCE=$([[ "$1" == "--force" || "$1" == "-f" ]] && echo 1)
if [[ ! $FORCE ]]; then
echo -n "trying 'git push' ...... "
git push >/dev/null 2>&1 && { yay ; exit ; }
boo
fi
echo -n "trying 'git push -f' ... "
# Get the error output from the failed push
# and get the recommended 'git push' line
git push -f 2>&1 | {
CMD=""
ltrim() {
[[ "$1" =~ [^[:space:]].* ]]
printf "%s" "$BASH_REMATCH"
}
while IFS= read -r line
do
#echo "$line"
if [[ -z "$CMD" && $line =~ "git push" ]]; then
CMD=$(ltrim "$line")
fi
done
# if a command was found try it
if [[ -n "$CMD" ]]; then
boo
if [[ ! $FORCE ]]; then
echo -n "trying '$CMD' ...... "
$CMD >/dev/null 2>&1 && { yay ; exit ; }
boo
fi
fCMD=${CMD/ push / push -f }
echo -n "trying '$fCMD' ... "
$fCMD >/dev/null 2>&1 && { yay ; exit ; }
boo
exit 1
else
yay
fi
}
[[ ${PIPESTATUS[1]} == 1 ]] && echo "Sorry! Failed to push current branch."

33
buildroot/share/git/ghtp Normal file
View File

@ -0,0 +1,33 @@
#!/usr/bin/env bash
#
# ghtp (GitHub Transport Protocol)
#
# Set all remotes in the current repo to HTTPS or SSH connection.
# Useful when switching environments, using public wifi, etc.
#
GH_SSH="git@github\.com:"
GH_HTTPS="https:\/\/github\.com\/"
case "$1" in
-[Hh]) TYPE=HTTPS ; MATCH="git@" ; FORMULA="$GH_SSH/$GH_HTTPS" ;;
-[Ss]) TYPE=SSH ; MATCH="https:" ; FORMULA="$GH_HTTPS/$GH_SSH" ;;
*)
echo "usage: `basename $0` -h | -s" 1>&2
echo -e " \e[0;92m-h\e[0m to switch to HTTPS" 1>&2
echo -e " \e[0;92m-s\e[0m to switch to SSH" 1>&2
exit 1
;;
esac
REMOTES=$(git remote -v | egrep "\t$MATCH" | gawk '{print $1 " " $2}' | sort -u | sed "s/$FORMULA/")
if [[ -z $REMOTES ]]; then
echo "Nothing to do." ; exit
fi
echo "$REMOTES" | xargs -n2 git remote set-url
echo -n "Remotes set to $TYPE: "
echo "$REMOTES" | gawk '{printf "%s ", $1}'
echo

36
buildroot/share/git/mfadd Normal file
View File

@ -0,0 +1,36 @@
#!/usr/bin/env bash
#
# mfadd user[:branch] [copyname]
#
# Add a remote and fetch it. Optionally copy a branch.
#
# Examples:
# mfadd thefork
# mfadd thefork:patch-1
# mfadd thefork:patch-1 the_patch_12345
#
[[ $# > 0 && $# < 3 && $1 != "-h" && $1 != "--help" ]] || { echo "usage: `basename $0` user[:branch] [copyname]" 1>&2 ; exit 1; }
# If a colon or slash is included, split the parts
if [[ $1 =~ ":" || $1 =~ "/" ]]; then
[[ $1 =~ ":" ]] && IFS=':' || IFS="/"
read -a DATA <<< "$1"
USER=${DATA[0]}
BRANCH=${DATA[1]}
NAME=${2:-$BRANCH}
else
USER=$1
fi
MFINFO=$(mfinfo) || exit 1
IFS=' ' read -a INFO <<< "$MFINFO"
REPO=${INFO[2]}
set -e
echo "Adding and fetching $USER..."
git remote add "$USER" "git@github.com:$USER/$REPO.git" >/dev/null 2>&1 || echo "Remote exists."
git fetch "$USER"
[[ ! -z "$BRANCH" && ! -z "$NAME" ]] && git checkout -b "$NAME" --track "$USER/$BRANCH"

View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
#
# mfclean
#
# Prune all your merged branches and any branches whose remotes are gone
# Great way to clean up your branches after messing around a lot
#
KEEP="RC|RCBugFix|dev|master|bugfix-1|bugfix-2"
echo "Fetching latest upstream and origin..."
git fetch upstream
git fetch origin
echo
echo "Pruning Merged Branches..."
git branch --merged | egrep -v "^\*|$KEEP" | xargs -n 1 git branch -d
echo
echo "Pruning Remotely-deleted Branches..."
git branch -vv | egrep -v "^\*|$KEEP" | grep ': gone]' | gawk '{print $1}' | xargs -n 1 git branch -D
echo
# List fork branches that don't match local branches
echo "You may want to remove (or checkout) these refs..."
comm -23 \
<(git branch --all | sed 's/^[\* ] //' | grep origin/ | grep -v "\->" | awk '{ print $1; }' | sed 's/remotes\/origin\///') \
<(git branch --all | sed 's/^[\* ] //' | grep -v remotes/ | awk '{ print $1; }') \
| awk '{ print "git branch -d -r origin/" $1; print "git checkout origin/" $1 " -b " $1; print ""; }'
echo

38
buildroot/share/git/mfdoc Normal file
View File

@ -0,0 +1,38 @@
#!/usr/bin/env bash
#
# mfdoc
#
# Start Jekyll in watch mode to work on Marlin Documentation and preview locally
#
[[ $# == 0 ]] || { echo "Usage: `basename $0`" 1>&2 ; exit 1; }
MFINFO=$(mfinfo "$@") || exit 1
IFS=' ' read -a INFO <<< "$MFINFO"
ORG=${INFO[0]}
REPO=${INFO[2]}
BRANCH=${INFO[5]}
[[ $ORG == "MarlinFirmware" && $REPO == "MarlinDocumentation" ]] || { echo "Wrong repository." 1>&2; exit 1; }
opensite() {
URL="http://127.0.0.1:4000/"
OPEN=$(echo $(which gnome-open xdg-open open) | awk '{ print $1 }')
if [ -z "$OPEN" ]; then
echo "Can't find a tool to open the URL:"
echo $URL
else
echo "Opening preview site in the browser..."
"$OPEN" "$URL"
fi
}
echo "Previewing MarlinDocumentation..."
bundle exec jekyll serve --watch --incremental | {
while IFS= read -r line
do
[[ $line =~ "Server running" ]] && opensite
echo "$line"
done
}

27
buildroot/share/git/mffp Normal file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env bash
#
# mffp [1|2|3] [commit-id]
#
# Push the given commit (or HEAD) upstream immediately.
# By default: `git push upstream HEAD:bugfix-1.1.x`
#
[[ $# < 3 && $1 != "-h" && $1 != "--help" ]] || { echo "usage: `basename $0` [1|2|3] [commit-id]" 1>&2 ; exit 1; }
if [[ $1 == '1' || $1 == '2' || $1 == '3' ]]; then
MFINFO=$(mfinfo "$1") || exit 1
REF=${2:-HEAD}
else
MFINFO=$(mfinfo) || exit 1
REF=${1:-HEAD}
fi
IFS=' ' read -a INFO <<< "$MFINFO"
ORG=${INFO[0]}
TARG=${INFO[3]}
if [[ $ORG == "MarlinFirmware" ]]; then
git push upstream $REF:$TARG
else
echo "Not a MarlinFirmware working copy."; exit 1
fi

View File

@ -0,0 +1,28 @@
#!/usr/bin/env bash
#
# mfhelp
#
cat <<THIS
Marlin Firmware Commands:
firstpush ... Push and set-upstream the current branch to 'origin'
ghpc ........ Push the current branch to its upstream branch
ghtp ........ Set the transfer protolcol for all your remotes
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
mffp ........ Push new commits directly to MarlinFirmware
mfinfo ...... Provide branch information (for the other scripts)
mfinit ...... Create an 'upstream' remote for 'MarlinFirmare'
mfnew ....... Create a new branch based on 'bugfix-...'
mfpr ........ Push the current branch and open the PR form
mfpub ....... Build and publish the marlinfw.org website
mfqp ........ Commit changes, do an interactive rebase, and push
mfrb ........ Interactively rebase the current branch on 'bugfix-...'
mftest ...... Run a platform test locally with PlatformIO
mfup ........ Fetch the latest 'upstream' and rebase on it
Enter [command] --help for more information.
THIS

View File

@ -0,0 +1,60 @@
#!/usr/bin/env bash
#
# mfinfo
#
# Provide the following info about the working directory:
#
# - Remote (upstream) Org name (MarlinFirmware)
# - Remote (origin) Org name (your Github username)
# - Repo Name (Marlin, MarlinDocumentation)
# - PR Target branch (bugfix-1.1.x, bugfix-2.0.x, dev-2.1.x, etc.)
# - Branch Arg (the branch argument or current branch)
# - Current Branch
#
CURR=$(git branch 2>/dev/null | grep ^* | sed 's/\* //g')
[[ -z $CURR ]] && { echo "No git repository here!" 1>&2 ; exit 1; }
[[ $CURR == "(no"* ]] && { echo "Git is busy with merge, rebase, etc." 1>&2 ; exit 1; }
REPO=$(git remote get-url upstream 2>/dev/null | sed -E 's/.*\/(.*)\.git/\1/')
[[ -z $REPO ]] && { echo "`basename $0`: No 'upstream' remote found. (Did you run mfinit?)" 1>&2 ; exit 1; }
ORG=$(git remote get-url upstream 2>/dev/null | sed -E 's/.*[\/:](.*)\/.*$/\1/')
[[ $ORG == MarlinFirmware ]] || { echo "`basename $0`: Not a Marlin repository." 1>&2 ; exit 1; }
FORK=$(git remote get-url origin 2>/dev/null | sed -E 's/.*[\/:](.*)\/.*$/\1/')
# Defaults if no arguments given
BRANCH=$CURR
INDEX=1
while [[ $# -gt 0 ]]; do
opt="$1" ; shift ; val="$1"
IFS='=' read -a PARTS <<<"$opt"
[[ "${PARTS[1]}" != "" ]] && { EQUALS=1 ; opt="${PARTS[0]}" ; val="${PARTS[1]}" ; }
GOODVAL=1
if [[ "$val" =~ ^-{1,2}.* || ! "$opt" =~ ^-{1,2}.* ]]; then
GOODVAL=0
val=""
fi
case "$opt" in
-*|--*) MORE="$MORE$opt " ; [[ $EQUALS == 1 ]] && MORE="$MORE=$val" ;;
1|2|3) INDEX=$opt ;;
*) BRANCH="$opt" ;;
esac
done
case "$REPO" in
Marlin ) TARG=bugfix-1.1.x ; [[ $INDEX == 2 ]] && TARG=bugfix-2.0.x ; [[ $INDEX == 3 ]] && TARG=dev-2.1.x ;;
MarlinDocumentation ) TARG=master ;;
esac
[[ $BRANCH =~ ^[123]$ ]] && USAGE=1
[[ $USAGE == 1 ]] && { echo "usage: `basename $0` [1|2|3] [branch]" 1>&2 ; exit 1 ; }
echo "$ORG $FORK $REPO $TARG $BRANCH $CURR $MORE"

View File

@ -0,0 +1,17 @@
#!/usr/bin/env bash
#
# mfinit
#
# Create the upstream remote for a forked repository
#
[[ $# == 0 ]] || { echo "usage: `basename $0`" 1>&2 ; exit 1; }
[[ -z $(git branch 2>/dev/null | grep ^* | sed 's/\* //g') ]] && { echo "No git repository here!" 1>&2 ; exit 1; }
REPO=$(git remote get-url origin 2>/dev/null | sed -E 's/.*\/(.*)\.git/\1/')
[[ -z $REPO ]] && { echo "`basename $0`: No 'origin' remote found." 1>&2 ; exit 1; }
echo "Adding 'upstream' remote for convenience."
git remote add upstream "git@github.com:MarlinFirmware/$REPO.git"
git fetch upstream

34
buildroot/share/git/mfnew Normal file
View File

@ -0,0 +1,34 @@
#!/usr/bin/env bash
#
# mfnew
#
# Create a new branch from the default target with the given name
#
usage() {
echo "usage: `basename $0` [1|2|3] [name]" 1>&2
}
[[ $# < 3 && $1 != "-h" && $1 != "--help" ]] || { usage; exit 1; }
MFINFO=$(mfinfo "$@") || exit 1
IFS=' ' read -a INFO <<< "$MFINFO"
TARG=${INFO[3]}
BRANCH=pr_for_$TARG-$(date +"%G-%m-%d_%H.%M.%S")
# BRANCH can be given as the last argument
case "$#" in
1 ) case "$1" in
1|2|3) ;;
*) BRANCH=$1 ;;
esac
;;
2 ) case "$1" in
1|2|3) BRANCH=$2 ;;
*) usage ; exit 1 ;;
esac
;;
esac
git fetch upstream
git checkout --no-track upstream/$TARG -b $BRANCH

39
buildroot/share/git/mfpr Normal file
View File

@ -0,0 +1,39 @@
#!/usr/bin/env bash
#
# mfpr [1|2|3]
#
# Make a PR against bugfix-1.1.x or bugfix-2.0.x
#
[[ $# < 2 && $1 != "-h" && $1 != "--help" ]] || { echo "usage: `basename $0` [1|2|3] [branch]" 1>&2 ; exit 1; }
MFINFO=$(mfinfo "$@") || exit 1
IFS=' ' read -a INFO <<< "$MFINFO"
ORG=${INFO[0]}
FORK=${INFO[1]}
REPO=${INFO[2]}
TARG=${INFO[3]}
BRANCH=${INFO[4]}
OLDBRANCH=${INFO[5]}
[[ $BRANCH == $TARG ]] && { echo "Can't create a PR from the PR Target ($BRANCH). Make a copy first." 1>&2 ; exit 1; }
[[ $BRANCH != $OLDBRANCH ]] && { git checkout $BRANCH || exit 1; }
# See if it's been pushed yet
if [ -z "$(git branch -vv | grep ^\* | grep \\[origin)" ]; then firstpush; fi
which xdg-open >/dev/null && TOOL=xdg-open
which gnome-open >/dev/null && TOOL=gnome-open
which open >/dev/null && TOOL=open
URL="https://github.com/$ORG/$REPO/compare/$TARG...$FORK:$BRANCH?expand=1"
if [ -z "$OPEN" ]; then
echo "Can't find a tool to open the URL:"
echo $URL
else
echo "Opening a New PR Form..."
"$OPEN" "$URL"
fi
[[ $BRANCH != $OLDBRANCH ]] && git checkout $OLDBRANCH

138
buildroot/share/git/mfpub Normal file
View File

@ -0,0 +1,138 @@
#!/usr/bin/env bash
#
# mfpub
#
# Use Jekyll to generate Marlin Documentation, which is then
# git-pushed to Github to publish it to the live site.
# This publishes the current branch, and doesn't force
# changes to be pushed to the 'master' branch. Be sure to
# push any permanent changes to 'master'.
#
[[ $# < 2 && $1 != "-h" && $1 != "--help" ]] || { echo "Usage: `basename $0` [branch]" 1>&2 ; exit 1; }
MFINFO=$(mfinfo "$@") || exit 1
IFS=' ' read -a INFO <<< "$MFINFO"
ORG=${INFO[0]}
FORK=${INFO[1]}
REPO=${INFO[2]}
TARG=${INFO[3]}
BRANCH=${INFO[4]}
CURR=${INFO[5]}
if [[ $ORG != "MarlinFirmware" || $REPO != "MarlinDocumentation" ]]; then
echo "Wrong repository."
exit
fi
if [[ $BRANCH == "gh-pages" ]]; then
echo "Can't build from 'gh-pages.' Only the Jekyll branches (based on 'master')."
exit
fi
# Check out the named branch (or stay in current)
if [[ $BRANCH != $CURR ]]; then
echo "Stashing any changes to files..."
[[ $(git stash) != "No local "* ]] && HAS_STASH=1
git checkout $BRANCH
fi
COMMIT=$( git log --format="%H" -n 1 )
# Clean out changes and other junk in the branch
git clean -d -f
opensite() {
URL="$1"
OPEN=$(echo $(which gnome-open xdg-open open) | awk '{ print $1 }')
if [ -z "$OPEN" ]; then
echo "Can't find a tool to open the URL:"
echo $URL
else
echo "Opening the site in the browser..."
"$OPEN" "$URL"
fi
}
# Push 'master' to the fork and make a proper PR...
if [[ $BRANCH == $TARG ]]; then
# Don't lose upstream changes!
git fetch upstream
# Rebase onto latest master
if git rebase upstream/$TARG; then
# Allow working directly with the main fork
echo
echo -n "Pushing to origin/$TARG... "
git push -f origin
echo
echo -n "Pushing to upstream/$TARG... "
git push -f upstream
else
echo "Merge conflicts? Stopping here."
exit
fi
else
if [ -z "$(git branch -vv | grep ^\* | grep \\\[origin)" ]; then
firstpush
else
echo
echo -n "Pushing to origin/$BRANCH... "
git push -f origin
fi
opensite "https://github.com/$ORG/$REPO/compare/$TARG...$FORK:$BRANCH?expand=1"
fi
# Uncomment to compress the final html files
# mv ./_plugins/jekyll-press.rb-disabled ./_plugins/jekyll-press.rb
# bundle install
echo
echo "Generating MarlinDocumentation..."
rm -rf build
# build the site statically and proof it
bundle exec jekyll build --profile --trace --no-watch
bundle exec htmlproofer ./build --only-4xx --allow-hash-href --check-favicon --check-html --url-swap ".*marlinfw.org/:/"
# Sync the built site into a temporary folder
TMPFOLDER=$( mktemp -d )
rsync -av build/ ${TMPFOLDER}/
# Clean out changes and other junk in the branch
git reset --hard
git clean -d -f
# Copy built-site into the gh-pages branch
git checkout gh-pages || { echo "Something went wrong!"; exit 1; }
rsync -av ${TMPFOLDER}/ ./
# Commit and push the new live site directly
git add --all
git commit --message "Built from ${COMMIT}"
git push -f origin
git push -f upstream | {
while IFS= read -r line
do
[[ $line =~ "gh-pages -> gh-pages" ]] && opensite "http://marlinfw.org/"
echo "$line"
done
}
# remove the temporary folder
rm -rf ${TMPFOLDER}
# Go back to the branch we started from
[[ $BRANCH != $CURR ]] && git checkout $BRANCH && [[ $HAS_STASH == 1 ]] && git stash pop

30
buildroot/share/git/mfqp Normal file
View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
#
# mfqp [1|2|3]
#
# - git add .
# - git commit --amend
# - ghpc
#
MFINFO=$(mfinfo "$@") || exit 1
IFS=' ' read -a INFO <<< "$MFINFO"
REPO=${INFO[2]}
TARG=${INFO[3]}
CURR=${INFO[5]}
IND=6
while [ $IND -lt ${#INFO[@]} ]; do
ARG=${INFO[$IND]}
case "$ARG" in
-h|--help ) USAGE=1 ;;
* ) USAGE=1 ; echo "unknown option: $ARG" ;;
esac
let IND+=1
done
[[ $USAGE == 1 ]] && { echo "usage: `basename $0` [1|2|3]" 1>&2 ; exit 1 ; }
[[ $CURR == $TARG && $REPO != "MarlinDocumentation" ]] && { echo "Don't alter the PR Target branch."; exit 1 ; }
git add . && git commit --amend && git push -f

30
buildroot/share/git/mfrb Normal file
View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
#
# mfrb
#
# Do "git rebase -i" against the "target" branch (bugfix-1.1.x, bugfix-2.0.x, dev-2.1.x, or master)
#
MFINFO=$(mfinfo "$@") || exit 1
IFS=' ' read -a INFO <<< "$MFINFO"
TARG=${INFO[3]}
CURR=${INFO[5]}
IND=6
while [ $IND -lt ${#INFO[@]} ]; do
ARG=${INFO[$IND]}
case "$ARG" in
-q|--quick ) QUICK=1 ;;
-h|--help ) USAGE=1 ;;
* ) USAGE=1 ; echo "unknown option: $ARG" ;;
esac
let IND+=1
done
[[ $USAGE == 1 ]] && { echo "usage: `basename $0` [1|2|3]" 1>&2 ; exit 1 ; }
# If the branch isn't currently the PR target
if [[ $TARG != $CURR ]]; then
[[ $QUICK ]] || git fetch upstream
git rebase upstream/$TARG && git rebase -i upstream/$TARG
fi

233
buildroot/share/git/mftest Normal file
View File

@ -0,0 +1,233 @@
#!/usr/bin/env bash
#
# 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
[[ -d Marlin/src ]] || { echo "Please 'cd' up to repo root." ; 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) pio run -d . -e include_tree ; exit 1 ;;
due) TESTENV='DUE' ;;
esp) TESTENV='esp32' ;;
lin*) TESTENV='linux_native' ;;
lpc?(8)) TESTENV='LPC1768' ;;
lpc9) TESTENV='LPC1769' ;;
m128) TESTENV='mega1280' ;;
m256) TESTENV='mega2560' ;;
mega) TESTENV='mega2560' ;;
stm) TESTENV='STM32F103RE' ;;
f1) TESTENV='STM32F103RE' ;;
f4) TESTENV='STM32F4' ;;
f7) TESTENV='STM32F7' ;;
s6) TESTENV='FYSETC_S6' ;;
teensy) TESTENV='teensy31' ;;
t31) TESTENV='teensy31' ;;
t32) TESTENV='teensy31' ;;
t35) TESTENV='teensy35' ;;
t36) TESTENV='teensy35' ;;
-h|--help) echo -e "$(basename $0) : Marlin Firmware test, build, and upload\n"
echo "Usage: $(basename $0) ................. Select env and test to apply / run"
echo " $(basename $0) [-y] env ........ Select a test for env to apply / run"
echo " $(basename $0) [-y] env test ... Apply / run the specified env test"
echo " $(basename $0) -b [variant] .... Auto-build the specified variant"
echo " $(basename $0) -u [variant] .... Auto-build and upload the specified variant"
echo
echo "env shortcuts: tree due esp lin lpc|lpc8 lpc9 m128 m256|mega stm|f1 f4 f7 s6 teensy|t31|t32 t35|t36"
exit
;;
# Build with the last-built env
-r) [[ -f "$STATE_FILE" ]] || { echo "No previous (-r) build state found." ; exit 1 ; }
read TESTENV <"$STATE_FILE"
pio run -d . -e $TESTENV
exit
;;
-[bu]) MB=$( grep -E "^\s*#define MOTHERBOARD" Marlin/Configuration.h | awk '{ print $3 }' | $SED 's/BOARD_//' )
[[ -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" )
[[ -z $BNUM ]] && { echo "Error - Can't find $MB in boards list." ; exit 1 ; }
readarray -t ENVS <<< $( grep -EA1 "MB\(.*\b$MB\b.*\)" Marlin/src/pins/pins.h | grep -E '#include.+//.+env:.+' | grep -oE 'env:[^ ]+' | $SED -E 's/env://' )
[[ -z $ENVS ]] && { echo "Error - Can't find target(s) for $MB ($BNUM)." ; exit 1 ; }
ECOUNT=${#ENVS[*]}
if [[ $ECOUNT == 1 ]]; then
TARGET=$ENVS
else
if [[ $CHOICE == 0 ]]; then
#
# List env names and numbers. Get selection.
#
echo "Available targets for \"$BDESC\" | $MB ($BNUM):"
IND=0 ; for ENV in "${ENVS[@]}"; do let IND++ ; 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 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
#
# List available tests and ask for selection
#
if [[ $TESTENV == '-' ]]; then
IND=0
NAMES=()
for FILE in $( ls -1 $TESTPATH/*-tests )
do
let IND++
TNAME=${FILE/-tests/}
TNAME=${TNAME/$TESTPATH\//}
NAMES+=($TNAME)
(( IND < 10 )) && echo -n " "
echo " $IND) $TNAME"
done
echo
for (( ; ; ))
do
read -p "Select a test to apply (1-$IND) : " NAMEIND
[[ -z "$NAMEIND" ]] && { echo '(canceled)' ; exit 1 ; }
[[ $NAMEIND =~ $ISNUM ]] && ((NAMEIND >= 1 && NAMEIND <= IND)) && { TESTENV=${NAMES[$NAMEIND-1]} ; echo ; break ; }
echo "Invalid selection."
done
fi
# Get the contents of the test file
OUT=$( cat $TESTPATH/$TESTENV-tests 2>/dev/null ) || { echo "Can't find test '$TESTENV'." ; exit 1 ; }
# Count up the number of tests
TESTCOUNT=$( awk "/$ISEXEC/{a++}END{print a}" <<<"$OUT" )
# User entered a number?
(( CHOICE && CHOICE > TESTCOUNT )) && { echo "Invalid test selection '$CHOICE' (1-$TESTCOUNT)." ; exit 1 ; }
if [[ $CHOICE == 0 ]]; then
#
# List test descriptions with numbers and get selection
#
echo "Available '$TESTENV' tests:" ; echo "$OUT" | {
IND=0
while IFS= read -r LINE
do
if [[ $LINE =~ $ISEXEC ]]; then
DESC=$( "$SED" -E 's/^.+"(.*)".*$/\1/g' <<<"$LINE" )
(( ++IND < 10 )) && echo -n " "
echo " $IND) $DESC"
fi
done
}
CHOICE=1
if [[ $TESTCOUNT > 1 ]]; then
for (( ; ; ))
do
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 selection '$CHOICE'."
done
fi
fi
#
# Run the specified test lines
#
echo "$OUT" | {
IND=0
GOTX=0
CMD=""
while IFS= read -r LINE
do
if [[ $LINE =~ $ISCMD || $GOTX == 1 ]]; then
((!IND)) && let IND++
if [[ $LINE =~ $ISEXEC ]]; then
((IND++ > CHOICE)) && break
else
((!HEADER)) && {
HEADER=1
echo -e "\n#\n# Test $TESTENV ($CHOICE) $DESC\n#"
}
((IND == CHOICE)) && {
GOTX=1
[[ $CMD == "" ]] && CMD="$LINE" || CMD=$( echo -e "$CMD$LINE" | $SED -e 's/\\//g' )
[[ $LINE =~ $ISCONT ]] || { echo $CMD ; eval "$CMD" ; CMD="" ; }
}
fi
fi
done
}
# Make clear it's a TEST
opt_set CUSTOM_MACHINE_NAME "\"$TESTENV-tests ($CHOICE)\""
# Get a -y parameter the lazy way
[[ "$2" == "-y" || "$3" == "-y" ]] && BUILD_YES='Y'
# Build the test too?
if [[ $BUILD_YES != 'Y' ]]; then
echo
read -p "Build $TESTENV test #$CHOICE (y/N) ? " BUILD_YES
fi
[[ $BUILD_YES == 'Y' || $BUILD_YES == 'Yes' ]] && {
pio run -d . -e $TESTENV
echo "$TESTENV" >"$STATE_FILE"
}

48
buildroot/share/git/mfup Normal file
View File

@ -0,0 +1,48 @@
#!/usr/bin/env bash
#
# mfup
#
# - Fetch latest upstream and replace the PR Target branch with
# - Rebase the (current or specified) branch on the PR Target
# - Force-push the branch to 'origin'
#
[[ $# < 3 && $1 != "-h" && $1 != "--help" ]] || { echo "usage: `basename $0` [1|2] [branch]" 1>&2 ; exit 1; }
MFINFO=$(mfinfo "$@") || exit 1
IFS=' ' read -a INFO <<< "$MFINFO"
ORG=${INFO[0]}
FORK=${INFO[1]}
REPO=${INFO[2]}
TARG=${INFO[3]}
BRANCH=${INFO[4]}
CURR=${INFO[5]}
set -e
# Prevent accidental loss of current changes
[[ $(git stash) != "No local "* ]] && HAS_STASH=1
echo "Fetching upstream ($ORG/$REPO)..."
git fetch upstream
if [[ $BRANCH != $TARG ]]; then
echo ; echo "Rebasing $BRANCH on $TARG..."
if [[ $BRANCH == $CURR ]] || git checkout $BRANCH; then
if git rebase upstream/$TARG; then
git push -f
else
echo "Looks like merge conflicts. Stopping here."
exit
fi
else
echo "No such branch!"
fi
else
git reset --hard upstream/$TARG
fi
echo
[[ $BRANCH != $CURR ]] && git checkout $CURR
[[ $HAS_STASH == 1 ]] && git stash pop