mirror of
https://github.com/armbian/build.git
synced 2025-08-09 20:56:57 +02:00
196 lines
6.7 KiB
Bash
196 lines
6.7 KiB
Bash
# advanced_patch <dest> <family> <board> <target> <branch> <description>
|
|
#
|
|
# parameters:
|
|
# <dest>: u-boot, kernel, atf
|
|
# <family>: u-boot: u-boot, u-boot-neo; kernel: sun4i-default, sunxi-next, ...
|
|
# <board>: cubieboard, cubieboard2, cubietruck, ...
|
|
# <target>: optional subdirectory
|
|
# <description>: additional description text
|
|
#
|
|
# priority:
|
|
# $USERPATCHES_PATH/<dest>/<family>/target_<target>
|
|
# $USERPATCHES_PATH/<dest>/<family>/board_<board>
|
|
# $USERPATCHES_PATH/<dest>/<family>/branch_<branch>
|
|
# $USERPATCHES_PATH/<dest>/<family>
|
|
# $SRC/patch/<dest>/<family>/target_<target>
|
|
# $SRC/patch/<dest>/<family>/board_<board>
|
|
# $SRC/patch/<dest>/<family>/branch_<branch>
|
|
# $SRC/patch/<dest>/<family>
|
|
#
|
|
advanced_patch() {
|
|
local dest=$1
|
|
local family=$2
|
|
local board=$3
|
|
local target=$4
|
|
local branch=$5
|
|
local description=$6
|
|
|
|
display_alert "Started patching process for" "$dest $description" "info"
|
|
display_alert "Looking for user patches in" "userpatches/$dest/$family" "info"
|
|
|
|
local names=()
|
|
local dirs=(
|
|
"$USERPATCHES_PATH/$dest/$family/target_${target}:[\e[33mu\e[0m][\e[34mt\e[0m]"
|
|
"$USERPATCHES_PATH/$dest/$family/board_${board}:[\e[33mu\e[0m][\e[35mb\e[0m]"
|
|
"$USERPATCHES_PATH/$dest/$family/branch_${branch}:[\e[33mu\e[0m][\e[33mb\e[0m]"
|
|
"$USERPATCHES_PATH/$dest/$family:[\e[33mu\e[0m][\e[32mc\e[0m]"
|
|
"$SRC/patch/$dest/$family/target_${target}:[\e[32ml\e[0m][\e[34mt\e[0m]"
|
|
"$SRC/patch/$dest/$family/board_${board}:[\e[32ml\e[0m][\e[35mb\e[0m]"
|
|
"$SRC/patch/$dest/$family/branch_${branch}:[\e[32ml\e[0m][\e[33mb\e[0m]"
|
|
"$SRC/patch/$dest/$family:[\e[32ml\e[0m][\e[32mc\e[0m]"
|
|
)
|
|
local links=()
|
|
|
|
# required for "for" command
|
|
shopt -s nullglob dotglob
|
|
# get patch file names
|
|
for dir in "${dirs[@]}"; do
|
|
for patch in ${dir%%:*}/*.patch; do
|
|
names+=($(basename "${patch}"))
|
|
done
|
|
# add linked patch directories
|
|
if [[ -d ${dir%%:*} ]]; then
|
|
local findlinks
|
|
findlinks=$(find "${dir%%:*}" -maxdepth 1 -type l -print0 2>&1 | xargs -0)
|
|
[[ -n $findlinks ]] && readarray -d '' links < <(find "${findlinks}" -maxdepth 1 -type f -follow -print -iname "*.patch" -print | grep "\.patch$" | sed "s|${dir%%:*}/||g" 2>&1)
|
|
fi
|
|
done
|
|
# merge static and linked
|
|
names=("${names[@]}" "${links[@]}")
|
|
# remove duplicates
|
|
local names_s=($(echo "${names[@]}" | tr ' ' '\n' | LC_ALL=C sort -u | tr '\n' ' '))
|
|
# apply patches
|
|
for name in "${names_s[@]}"; do
|
|
for dir in "${dirs[@]}"; do
|
|
if [[ -f ${dir%%:*}/$name ]]; then
|
|
if [[ -s ${dir%%:*}/$name ]]; then
|
|
process_patch_file "${dir%%:*}/$name" "${dir##*:}"
|
|
else
|
|
display_alert "* ${dir##*:} $name" "skipped"
|
|
fi
|
|
break # next name
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
|
|
# process_patch_file <file> <description>
|
|
#
|
|
# parameters:
|
|
# <file>: path to patch file
|
|
# <status>: additional status text
|
|
#
|
|
process_patch_file() {
|
|
local patch=$1
|
|
local status=$2
|
|
|
|
# detect and remove files which patch will create
|
|
lsdiff -s --strip=1 "${patch}" | grep '^+' | awk '{print $2}' | xargs -I % sh -c 'rm -f %'
|
|
|
|
echo "Processing file $patch" >> "${DEST}"/${LOG_SUBPATH}/patching.log
|
|
patch --batch --silent -p1 -N < "${patch}" >> "${DEST}"/${LOG_SUBPATH}/patching.log 2>&1
|
|
|
|
if [[ $? -ne 0 ]]; then
|
|
display_alert "* $status $(basename "${patch}")" "failed" "wrn"
|
|
[[ $EXIT_PATCHING_ERROR == yes ]] && exit_with_error "Aborting due to" "EXIT_PATCHING_ERROR"
|
|
else
|
|
display_alert "* $status $(basename "${patch}")" "" "info"
|
|
fi
|
|
echo >> "${DEST}"/${LOG_SUBPATH}/patching.log
|
|
}
|
|
|
|
# apply_patch_series <target dir> <full path to series file>
|
|
apply_patch_series() {
|
|
local t_dir="${1}"
|
|
local series="${2}"
|
|
local bzdir="$(dirname $series)"
|
|
local flag
|
|
local err_pt=$(mktemp /tmp/apply_patch_series_XXXXX)
|
|
|
|
list=$(awk '$0 !~ /^#.*|^-.*|^$/' "${series}")
|
|
skiplist=$(awk '$0 ~ /^-.*/{print $NF}' "${series}")
|
|
|
|
display_alert "apply a series of " "[$(echo $list | wc -w)] patches"
|
|
display_alert "skip [$(echo $skiplist | wc -w)] patches"
|
|
|
|
cd "${t_dir}" || exit 1
|
|
for p in $list; do
|
|
# Detect and remove files as '*.patch' which patch will create.
|
|
# So we need to delete the file before applying the patch if it exists.
|
|
lsdiff -s --strip=1 "$bzdir/$p" |
|
|
awk '$0 ~ /^+.*patch$/{print $2}' |
|
|
xargs -I % sh -c 'rm -f %'
|
|
|
|
patch --batch --silent --no-backup-if-mismatch -p1 -N < $bzdir/"$p" >> $err_pt 2>&1
|
|
flag=$?
|
|
|
|
case $flag in
|
|
0)
|
|
printf "[\033[32m done \033[0m] %s\n" "${p}"
|
|
printf "[ done ] %s\n" "${p}" >> "${DEST}"/debug/patching.log
|
|
;;
|
|
1)
|
|
printf "[\033[33m FAILED \033[0m] %s\n" "${p}"
|
|
echo -e "[ FAILED ] For ${p} \t\tprocess exit [ $flag ]" >> "${DEST}"/debug/patching.log
|
|
cat $err_pt >> "${DEST}"/debug/patching.log
|
|
;;
|
|
2)
|
|
printf "[\033[31m Patch wrong \033[0m] %s\n" "${p}"
|
|
echo -e "Patch wrong ${p}\t\tprocess exit [ $flag ]" >> "${DEST}"/debug/patching.log
|
|
cat $err_pt >> "${DEST}"/debug/patching.log
|
|
;;
|
|
esac
|
|
echo "" > $err_pt
|
|
done
|
|
echo "" >> "${DEST}"/debug/patching.log
|
|
rm $err_pt
|
|
}
|
|
|
|
userpatch_create() {
|
|
# create commit to start from clean source
|
|
git add .
|
|
git -c user.name='Armbian User' -c user.email='user@example.org' commit -q -m "Cleaning working copy"
|
|
|
|
local patch="$DEST/patch/$1-$LINUXFAMILY-$BRANCH.patch"
|
|
|
|
# apply previous user debug mode created patches
|
|
if [[ -f $patch ]]; then
|
|
display_alert "Applying existing $1 patch" "$patch" "wrn" && patch --batch --silent -p1 -N < "${patch}"
|
|
# read title of a patch in case Git is configured
|
|
if [[ -n $(git config user.email) ]]; then
|
|
COMMIT_MESSAGE=$(cat "${patch}" | grep Subject | sed -n -e '0,/PATCH/s/.*PATCH]//p' | xargs)
|
|
display_alert "Patch name extracted" "$COMMIT_MESSAGE" "wrn"
|
|
fi
|
|
fi
|
|
|
|
# prompt to alter source
|
|
display_alert "Make your changes in this directory:" "$(pwd)" "wrn"
|
|
display_alert "Press <Enter> after you are done" "waiting" "wrn"
|
|
read -r < /dev/tty
|
|
tput cuu1
|
|
git add .
|
|
# create patch out of changes
|
|
if ! git diff-index --quiet --cached HEAD; then
|
|
# If Git is configured, create proper patch and ask for a name
|
|
if [[ -n $(git config user.email) ]]; then
|
|
display_alert "Add / change patch name" "$COMMIT_MESSAGE" "wrn"
|
|
read -e -p "Patch description: " -i "$COMMIT_MESSAGE" COMMIT_MESSAGE
|
|
[[ -z "$COMMIT_MESSAGE" ]] && COMMIT_MESSAGE="Patching something"
|
|
git commit -s -m "$COMMIT_MESSAGE"
|
|
git format-patch -1 HEAD --stdout --signature="Created with Armbian build tools $GITHUB_SOURCE/armbian/build" > "${patch}"
|
|
PATCHFILE=$(git format-patch -1 HEAD)
|
|
rm $PATCHFILE # delete the actual file
|
|
# create a symlink to have a nice name ready
|
|
find $DEST/patch/ -type l -delete # delete any existing
|
|
ln -sf $patch $DEST/patch/$PATCHFILE
|
|
else
|
|
git diff --staged > "${patch}"
|
|
fi
|
|
display_alert "You will find your patch here:" "$patch" "info"
|
|
else
|
|
display_alert "No changes found, skipping patch creation" "" "wrn"
|
|
fi
|
|
git reset --soft HEAD~
|
|
for i in {3..1..1}; do echo -n "$i." && sleep 1; done
|
|
}
|