198 lines
5.0 KiB
Bash
Executable File
198 lines
5.0 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
|
|
shopt -s nullglob
|
|
|
|
PROGRAM="$0"
|
|
MODULES=(tock libtock-rs)
|
|
|
|
success() {
|
|
echo -e "\r\e[1;32mDone:\e[m $1"
|
|
exit 0
|
|
}
|
|
|
|
fail() {
|
|
echo -e "\r\e[1;31mError:\e[m $1"
|
|
exit 1
|
|
}
|
|
|
|
commit() {
|
|
local message="$1"
|
|
git add .
|
|
git commit -qm"${message}"
|
|
}
|
|
|
|
get_root() {
|
|
local module="$1"
|
|
git ls-tree HEAD:third_party | sed -En 's/^.* ([^ ]+)\t'"${module}"'$/\1/p'
|
|
}
|
|
|
|
get_head() {
|
|
git rev-parse HEAD
|
|
}
|
|
|
|
help() {
|
|
local root="$(get_root)"
|
|
cat <<EOF
|
|
Usage: ${PROGRAM} {apply|save|restore|check}
|
|
|
|
apply Applies the patches to the submodules regardless of their state.
|
|
As a consequence this can always be called to get to a clean state
|
|
but may result in data loss if there are unsaved changes.
|
|
|
|
save Saves the submodules to the patches.
|
|
This should only be called after apply and when all changes have
|
|
been added to a commit. After saving, you can run ./setup.sh to
|
|
return to normal state. Otherwise you can continue editing the
|
|
submodules and calling save.
|
|
|
|
restore Restores the submodules to its normal state regardless of their
|
|
state. As a consequence this can always be called to get to a
|
|
clean state but may result in data loss if there are unsaved
|
|
changes.
|
|
|
|
check Checks whether the submodules and the patches are in sync. This
|
|
may fail in two cases:
|
|
- when the patches were updated but not restored/applied, and
|
|
- when the submodules have been modified but not saved.
|
|
|
|
Example:
|
|
|
|
1. Enter the edit state from the normal state:
|
|
|
|
${PROGRAM} apply
|
|
|
|
2. Edit files in the submodules:
|
|
|
|
cd third_party/<submodule>
|
|
edit <files>
|
|
|
|
3. For each edited submodule, create a fix commit per affected patch by
|
|
repeating the following commands until there are no more files to add:
|
|
|
|
git add -p
|
|
git commit -m'fix <patch#>'
|
|
|
|
4. For each edited submodule, merge the fixes into their patches by moving
|
|
their line below their patch and changing their "edit" into "fixup":
|
|
|
|
git rebase -i ${root}
|
|
|
|
5. Save the changes:
|
|
|
|
cd ../..
|
|
${PROGRAM} save
|
|
|
|
6. Either continue repeating steps 2 to 5, or return to the normal state:
|
|
|
|
${PROGRAM} restore
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
apply_module() {
|
|
local root="$1" module="$2" file
|
|
git checkout -q "${root}"
|
|
if [[ "${module}" == tock ]]; then
|
|
cp -a ../../boards .
|
|
commit '00-boards'
|
|
fi
|
|
for file in ../../patches/"${module}"/*; do
|
|
git apply "${file}"
|
|
commit "$(basename "${file}" .patch)"
|
|
echo -n .
|
|
done
|
|
}
|
|
|
|
apply() {
|
|
for module in "${MODULES[@]}"; do
|
|
local root="$(get_root "${module}")"
|
|
( set -e
|
|
cd third_party/"${module}"
|
|
git reset -q --hard
|
|
git clean -qfxd
|
|
apply_module "${root}" "${module}"
|
|
)
|
|
done
|
|
}
|
|
|
|
save() {
|
|
for module in "${MODULES[@]}"; do
|
|
local root="$(get_root "${module}")"
|
|
( set -e
|
|
cd third_party/"${module}"
|
|
[[ -z "$(git status -s)" ]] \
|
|
|| fail "The ${module} submodule is not clean."
|
|
rm -rf ../../patches/"${module}"
|
|
mkdir ../../patches/"${module}"
|
|
for file in $(git format-patch "${root}"); do
|
|
sed -n '/^diff/,$p' "${file}" \
|
|
| sed '/^-- $/,$d' > "../../patches/${module}/${file#*-}"
|
|
done
|
|
git clean -qfxd
|
|
local top="$(get_head)"
|
|
git checkout -q "${root}"
|
|
if [[ "${module}" == tock ]]; then
|
|
rm -r boards
|
|
git apply --whitespace=nowarn ../../patches/"${module}"/00-boards.patch
|
|
rm ../../patches/tock/00-boards.patch
|
|
rm -r ../../boards
|
|
cp -a boards ../..
|
|
fi
|
|
git reset -q --hard
|
|
git clean -qfxd
|
|
git checkout -q "${top}"
|
|
)
|
|
done
|
|
}
|
|
|
|
check() {
|
|
# Overwrite the commit function to do nothing.
|
|
commit() { true; }
|
|
for module in "${MODULES[@]}"; do
|
|
local root="$(get_root "${module}")"
|
|
( set -e
|
|
cd third_party/"${module}"
|
|
git commit --allow-empty -qmi
|
|
git add .
|
|
git commit --allow-empty -qmx
|
|
local top="$(get_head)"
|
|
apply_module "${root}" "${module}"
|
|
git add .
|
|
git commit --allow-empty -qmy
|
|
# We need to cleanup (and not exit) regardless of a diff.
|
|
local r; if git diff "${top}" --quiet; then r=0; else r=1; fi
|
|
git checkout -q "${top}"
|
|
git reset -q HEAD~
|
|
git reset -q --soft HEAD~
|
|
[[ "${r}" -eq 0 ]] \
|
|
|| fail "The ${module} submodule differs from its patches."
|
|
)
|
|
done
|
|
}
|
|
|
|
grep -q third_party/tock .gitmodules 2>/dev/null \
|
|
|| fail 'Not running from OpenSK directory.'
|
|
[[ $# -eq 1 ]] || help
|
|
case $1 in
|
|
apply)
|
|
apply
|
|
success 'Applied the patches to the submodules.'
|
|
;;
|
|
save)
|
|
save
|
|
success 'Saved the submodules to the patches.'
|
|
;;
|
|
restore)
|
|
# Overwrite the commit function to do nothing.
|
|
commit() { true; }
|
|
apply
|
|
success 'Restored the submodules.'
|
|
;;
|
|
check)
|
|
check
|
|
success 'The submodules and patches are in sync.'
|
|
;;
|
|
*) fail 'Unexpected argument. Run without argument for help.' ;;
|
|
esac
|