Blob


1 #!/usr/bin/env bash
2 #
3 # Script to sync changes from upstream to -portable
4 #
5 # This script is under the same licence as gameoftrees itself.
7 PORTABLE_BRANCH="portable"
9 die()
10 {
11 echo "$@" >&2
12 exit 1
13 }
15 # Wrap the nproc command found on Linux, to return the number of CPU cores.
16 # On non-Linux systems, the same value can be found via sysctl. For
17 # everything else, just return "1".
18 nproc()
19 {
20 NPROCCMD="nproc"
22 command "$NPROCCMD" >/dev/null 2>&1 || {
23 NPROCCMD="sysctl -n hw.ncpu"
24 }
26 result="$(eval command $NPROCCMD)"
27 [ -z "$result" -o "$result" -le 0 ] && result="1"
29 echo "$result"
30 }
32 [ -z "$(git status --porcelain)" ] || die "Working tree is not clean"
34 echo "Updating main from origin..."
36 # Update our copy of main
37 git checkout -q main && \
38 git fetch -q -n gh >/dev/null 2>&1
39 git fetch -q -n upstream >/dev/null 2>&1 && \
40 git reset -q --hard upstream/main || {
41 die "Couldn't fetch from main and reset to that branch"
42 }
44 # Gather a list of commits to cherry-pick.
45 # Don't proceed with no commits.
46 commitc="$(git rev-list --count main...origin/main)"
47 [ -z "$commitc" -o "$commitc" -eq 0 ] && {
48 echo "All commits uptodate. Nothing to cherry-pick"
49 exit
50 }
52 # Create a branch from $PORTABLE_BRANCH (which is where the result of the
53 # cherry-picks will ultimately end up, but we do this work on a topic branch
54 # so that we can perform CI on it, and not break the $PORTABLE_BRANCH branch.
56 echo "Creating sync branch..."
57 git branch -q -D syncup >/dev/null 2>&1
58 git checkout -q "$PORTABLE_BRANCH" && git checkout -q -b syncup || {
59 die "Can't checkout syncup branch"
60 }
62 echo "The following ($commitc) commits will be cherry-picked..."
63 git log --oneline main...origin/main
65 read -p "Proceed? [Y/n]: " resp
67 [ "$resp" = "N" -o "$resp" = "n" ] && exit
69 # Pick the commits in reverse order.
70 git rev-list --reverse --first-parent main...origin/main | \
71 git cherry-pick --stdin --no-rerere-autoupdate -Xtheirs
73 [ $? -eq 0 ] && {
74 # Sanity-check header files which are found portably and remove them.
75 for h in 'sys\/queue.h' 'ssl\.h' 'endian\.h'
76 do
77 # Use git's pathspec notation to exclude matching on files
78 # where we *want* to keep those headers.
79 git grep -Li "$h" -- \
80 ':!maintscripts/**' \
81 ':!configure.ac' \
82 ':!gotweb/parse.y' \
83 ':!include/got_compat.h' | \
84 while read file
85 do
86 sed -i -e "/$h/d" "$file"
87 done
88 done
90 echo "Performing sanity build..."
91 ./autogen.sh >/dev/null 2>&1 && \
92 ./configure >/dev/null 2>&1 && \
93 make -j $(nproc) >/dev/null 2>&1 && {
94 echo " Passed!"
95 echo "Creating commit for portable changes..."
96 git commit -am "portable: remove include files found portably"
97 echo "...Merging branch to $PORTABLE_BRANCH"
98 git checkout "$PORTABLE_BRANCH" && git merge --ff-only - && {
99 echo "Pushing to GH..."
100 git push gh || die "Couldn't push $PORTABLE_BRANCH to GH"
101 git checkout main && \
102 git push gh || die "Couldn't push main to GH"
104 } || die "Build failed"
107 echo "Wait for Cirrus-CI..."
108 echo "Then push main and $PORTABLE_BRANCH to origin"