pk3dir handling: detect if the matching pk3 file exists, and then ignore the repo...
[xonotic/xonotic.git] / all
1 #!/bin/sh
2 # vim: filetype=zsh
3
4 set -e
5
6 d00=`pwd`
7 while ! [ -f ./all ]; do
8         if [ x"`pwd`" = x"/" ]; then
9                 echo "Cannot find myself."
10                 echo "Please run this script with the working directory inside a Xonotic checkout."
11                 exit 1
12         fi
13         cd ..
14 done
15 d0=`pwd`
16 SELF="$d0/all"
17
18 # If we are on WINDOWS:
19 case "$0" in
20         all|*/all)
21                 case "`uname`" in
22                         MINGW*|Win*)
23                                 # Windows hates users. So this script has to copy itself elsewhere first...
24                                 tname=
25                                 cp "$SELF" ../all.xonotic.sh
26                                 export WE_HATE_OUR_USERS=1
27                                 exec ../all.xonotic.sh "$@"
28                                 ;;
29                 esac
30                 ;;
31 esac
32
33 msg()
34 {
35         echo "\e[1m$*\e[m"
36 }
37
38 checksum()
39 {
40         if [ -x /usr/bin/md5sum ]; then
41                 /usr/bin/md5sum "$@"
42         elif [ -x /bin/md5sum ]; then
43                 /bin/md5sum "$@"
44         elif [ -x /usr/bin/cksum ]; then
45                 /usr/bin/cksum "$@"
46         else
47                 echo "NOCHECKSUM"
48         fi
49 }
50
51 self=`checksum "$SELF"`
52 checkself()
53 {
54         self_new=`checksum "$SELF"`
55         if [ x"$self" != x"$self_new" ]; then
56                 msg "./all has changed."
57                 if [ -z "$XONOTIC_FORBID_RERUN_ALL" ]; then
58                         msg "Rerunning the requested operation to make sure."
59                         export XONOTIC_FORBID_RERUN_ALL=1
60                         exec "$SELF" "$@"
61                 else
62                         msg "Please try $SELF update, and then retry your requested operation."
63                         exit 1
64                 fi
65         fi
66         return 0
67 }
68
69 verbose()
70 {
71         msg "+ $*"
72         "$@"
73 }
74
75 visible_repo_name()
76 {
77         case "$1" in
78                 .)
79                         echo "the root directory"
80                         ;;
81                 *)
82                         echo "\"$1\""
83                         ;;
84         esac
85 }
86
87 check_mergeconflict()
88 {
89         if git ls-files -u | grep ' 1   '; then
90                 echo
91                 echo "MERGE CONFLICT."
92                 echo "change into the \"$1\" project directory, and then:"
93                 echo "- edit the files mentioned above with your favorite editor,"
94                 echo "  and fix the conflicts (marked with <<<<<<< blocks)"
95                 echo "- for binary files, you can select the files using"
96                 echo "  git checkout --ours or git checkout --theirs"
97                 echo "- when done with a file, 'git add' the file"
98                 echo "- when done, 'git commit'"
99                 echo
100                 exit 1
101         fi
102 }
103
104 enter()
105 {
106         $2 cd "$1"
107         check_mergeconflict "$1"
108 }
109
110 repos_urls="
111         .
112         data/xonotic-data.pk3dir
113         data/xonotic-maps.pk3dir
114         data/xonotic-music.pk3dir
115         data/xonotic-nexcompat.pk3dir
116         darkplaces
117         fteqcc@git://github.com/Blub/qclib.git
118         div0-gittools@git://git.icculus.org/divverent/div0-gittools.git
119         netradiant
120 "
121
122 repos_urls=`
123         for X in $repos_urls; do 
124                 d="${X%%@*}"
125                 p="${d%dir}"
126                 if [ x"$p" = x"$d" ] || [ -d "$d" ] || ! [ -f "$p" ]; then
127                         echo "$X"
128                 fi
129         done
130 `
131
132 repos=`for X in $repos_urls; do echo "${X%%@*}"; done`
133
134 if [ "$#" = 0 ]; then
135         set -- help
136 fi
137 cmd=$1
138 shift
139
140 case "$cmd" in
141         update|pull)
142                 base=`git config remote.origin.url`
143                 base=${base%xonotic.git}
144                 for dcomplete in $repos_urls; do
145                         case "$dcomplete" in
146                                 *@*)
147                                         d=${dcomplete%%@*}
148                                         url=${dcomplete#*@}
149                                         switch=false
150                                         ;;
151                                 *)
152                                         d=${dcomplete%%@*}
153                                         url=$base${d##*/}.git
154                                         switch=true
155                                         ;;
156                         esac
157                         if [ -d "$d0/$d" ]; then
158                                 enter "$d0/$d" verbose
159                                 case "$d" in
160                                         .)
161                                                 ;;
162                                         *)
163                                                 if $switch; then
164                                                         verbose git config remote.origin.url "$url"
165                                                 fi
166                                                 ;;
167                                 esac
168                                 verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
169                                         # TODO remove this line later
170
171                                 verbose git config core.autocrlf false
172                                 verbose git config core.safecrlf false # we don't NEED that...
173
174                                 r=`git symbolic-ref HEAD`
175                                 r=${r#refs/heads/}
176                                 if git config branch.$r.remote >/dev/null 2>&1; then
177                                         if ! verbose git pull; then
178                                                 check_mergeconflict "$d"
179                                                 echo "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
180                                                 read -r DUMMY
181                                         fi
182                                 fi
183
184                                 cd "$d00"
185                                 checkself "$cmd" "$@"
186                                 cd "$d0/$d"
187                                 verbose git remote prune origin
188                                 cd "$d0"
189                         else
190                                 verbose git clone "$url" "$d0/$d"
191                         fi
192                 done
193                 ;;
194         checkout|switch)
195                 remote=$1
196                 branch=$2
197                 if [ -z "$branch" ]; then
198                         branch=$remote
199                         remote=origin
200                 fi
201                 exists=false
202                 for d in $repos; do
203                         enter "$d0/$d" verbose
204                         if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
205                                 exists=true
206                                 verbose git checkout "$branch"
207                         elif git rev-parse "refs/remotes/$remote/$branch" >/dev/null 2>&1; then
208                                 exists=true
209                                 verbose git checkout --track -b "$branch" "$remote/$branch"
210                         else
211                                 verbose git checkout master
212                         fi
213                         cd "$d00"
214                         checkself "$cmd" "$@"
215                         cd "$d0"
216                 done
217                 if ! $exists; then
218                         echo "The requested branch was not found in any repository."
219                 fi
220                 exec "$SELF" branch
221                 ;;
222         branch)
223                 remote=$1
224                 branch=$2
225                 srcbranch=$3
226                 if [ -z "$branch" ]; then
227                         branch=$remote
228                         remote=origin
229                 fi
230                 if [ -z "$srcbranch" ]; then
231                         srcbranch=master
232                 fi
233                 if [ -z "$branch" ]; then
234                         for d in $repos; do
235                                 enter "$d0/$d"
236                                 r=`git symbolic-ref HEAD`
237                                 r=${r#refs/heads/}
238                                 echo "$d is at $r"
239                                 cd "$d0"
240                         done
241                 else
242                         for d in $repos; do
243                                 dv=`visible_repo_name "$d"`
244                                 enter "$d0/$d" verbose
245                                 a=
246                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
247                                         echo "Branch in $dv?"
248                                         read -r a
249                                 done
250                                 if [ x"$a" = x"y" ]; then
251                                         verbose git push "$remote" "$srcbranch":"$branch"
252                                         verbose git checkout --track -b "$branch" "$remote/$branch"
253                                 fi
254                                 cd "$d0"
255                         done
256                         "$SELF" branch
257                 fi
258                 ;;
259         branches)
260                 for d in $repos; do
261                         enter "$d0/$d"
262                         echo "In $d:"
263                         git branch -a -v -v | cut -c 3- | while read -r BRANCH REV UPSTREAM TEXT; do
264                                 case "$UPSTREAM" in
265                                         \[*)
266                                                 UPSTREAM=${UPSTREAM#\[}
267                                                 UPSTREAM=${UPSTREAM%\]}
268                                                 UPSTREAM=${UPSTREAM%:*}
269                                                 ;;
270                                         *)
271                                                 TEXT="$UPSTREAM $TEXT"
272                                                 UPSTREAM=
273                                                 ;;
274                                 esac
275                                 if [ x"$REV" = x"->" ]; then
276                                         continue
277                                 fi
278                                 BRANCH=${BRANCH#remotes/}
279                                 echo -n "  $BRANCH"
280                                 if [ -n "$UPSTREAM" ]; then
281                                         echo -n " (tracking $UPSTREAM)"
282                                 fi
283                                 #echo " $TEXT"
284                                 echo
285                         done
286                 done
287                 ;;
288         merge)
289                 for d in $repos; do
290                         dv=`visible_repo_name "$d"`
291                         enter "$d0/$d" verbose
292                         r=`git symbolic-ref HEAD`
293                         r=${r#refs/heads/}
294                         if git log HEAD..origin/master | grep .; then
295                                 # we have uncommitted changes
296                                 a=
297                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
298                                         echo "Could merge from \"master\" into \"$r\" in $dv. Do it?"
299                                         read -r a
300                                 done
301                                 if [ x"$a" = x"y" ]; then
302                                         if ! verbose git merge origin/master; then
303                                                 check_mergeconflict "$d"
304                                                 exit 1 # this should ALWAYS be fatal
305                                         fi
306                                 fi
307                         fi
308                         cd "$d0"
309                 done
310                 ;;
311         push|commit)
312                 submit=$1
313                 for d in $repos; do
314                         dv=`visible_repo_name "$d"`
315                         enter "$d0/$d" verbose
316                         r=`git symbolic-ref HEAD`
317                         r=${r#refs/heads/}
318                         if git diff HEAD | grep .; then
319                                 # we have uncommitted changes
320                                 a=
321                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
322                                         echo "Uncommitted changes in \"$r\" in $dv. Commit?"
323                                         read -r a
324                                 done
325                                 if [ x"$a" = x"y" ]; then
326                                         verbose git commit -a
327                                 fi
328                         fi
329                         rem=`git config "branch.$r.remote" || echo origin`
330                         if git log "$rem/$r".."$r" | grep .; then
331                                 a=
332                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
333                                         echo "Push \"$r\" in $dv?"
334                                         read -r a
335                                 done
336                                 if [ x"$a" = x"y" ]; then
337                                         verbose git push "$rem" HEAD
338                                 fi
339                         fi
340                         if [ x"$submit" = x"-s" ]; then
341                                 case "$r" in
342                                         */*)
343                                                 verbose git push "$rem" HEAD:"${r%%/*}/finished/${r#*/}"
344                                                 ;;
345                                 esac
346                         fi
347                         cd "$d0"
348                 done
349                 ;;
350         compile)
351                 if [ -z "$MAKEFLAGS" ]; then
352                         if [ -f /proc/cpuinfo ]; then
353                                 ncpus=$((`grep -c '^processor   :' /proc/cpuinfo`+0))
354                                 if [ $ncpus -gt 1 ]; then
355                                         MAKEFLAGS=-j$ncpus
356                                 fi
357                         fi
358                 fi
359                 enter "$d0/fteqcc" verbose
360                 verbose make $MAKEFLAGS
361                 enter "$d0/data/xonotic-data.pk3dir" verbose
362                 verbose make FTEQCC="$d0/fteqcc/fteqcc.bin" $MAKEFLAGS
363                 enter "$d0/darkplaces" verbose
364                 verbose make $MAKEFLAGS sv-debug
365                 verbose make $MAKEFLAGS cl-debug
366                 if ! [ -n "$WE_HATE_OUR_USERS" ]; then
367                         verbose make $MAKEFLAGS sdl-debug
368                 fi
369                 ;;
370         run)
371                 if [ -n "$WE_HATE_OUR_USERS" ]; then
372                         client=
373                 else
374                         client=-sdl
375                 fi
376                 case "$1" in
377                         sdl|glx|agl|dedicated)
378                                 client=-$1
379                                 shift
380                                 ;;
381                         wgl)
382                                 client=
383                                 shift
384                                 ;;
385                 esac
386                 if ! [ -x "darkplaces/darkplaces$client" ]; then
387                         if [ -x "darkplaces/darkplaces$client.exe" ]; then
388                                 client=$client.exe
389                         else
390                                 echo "Client darkplaces/darkplaces$client not found, aborting"
391                                 exit 1
392                         fi
393                 fi
394                 #verbose "darkplaces/darkplaces$client" -xonotic "$@"
395                 verbose "darkplaces/darkplaces$client" -nexuiz -customgamename Xonotic -customgamedirname1 data -customgamedirname2 "" -customgamescreenshotname xonotic -customgameuserdirname xonotic "$@"
396                 ;;
397         each|foreach)
398                 for d in $repos; do
399                         enter "$d0/$d" verbose
400                         verbose "$@"
401                         cd "$d0"
402                 done
403                 ;;
404         save-patches)
405                 outfile=$1
406                 patchdir=`mktemp -d -t save-patches.XXXXXX`
407                 for d in $repos; do
408                         enter "$d0/$d" verbose
409                         git branch -v -v | cut -c 3- | {
410                                 i=0
411                                 while read -r BRANCH REV UPSTREAM TEXT; do
412                                         case "$UPSTREAM" in
413                                                 \[*)
414                                                         UPSTREAM=${UPSTREAM#\[}
415                                                         UPSTREAM=${UPSTREAM%\]}
416                                                         UPSTREAM=${UPSTREAM%:*}
417                                                         TRACK=true
418                                                         ;;
419                                                 *)
420                                                         UPSTREAM=origin/master
421                                                         TRACK=false
422                                                         ;;
423                                         esac
424                                         if [ x"$REV" = x"->" ]; then
425                                                 continue
426                                         fi
427                                         if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
428                                                 echo "$d" > "$patchdir/$i/info.txt"
429                                                 echo "$BRANCH" >> "$patchdir/$i/info.txt"
430                                                 echo "$UPSTREAM" >> "$patchdir/$i/info.txt"
431                                                 echo "$TRACK" >> "$patchdir/$i/info.txt"
432                                                 i=$(($i+1))
433                                         else
434                                                 rm -rf "$patchdir/$i"
435                                         fi
436                                 done
437                         }
438                 done
439                 ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
440                 rm -rf "$patchdir"
441                 ;;
442         restore-patches)
443                 infile=$1
444                 patchdir=`mktemp -d -t restore-patches.XXXXXX`
445                 ( cd "$patchdir" && tar xvzf - ) < "$infile"
446                 # detach the head
447                 for P in "$patchdir"/*/info.txt; do
448                         D=${P%/info.txt}
449                         exec 3<"$P"
450                         read -r d <&3
451                         read -r BRANCH <&3
452                         read -r UPSTREAM <&3
453                         read -r TRACK <&3
454                         verbose git checkout HEAD^0
455                         verbose git branch -D "$BRANCH"
456                         if [ x"$TRACK" = x"true" ]; then
457                                 verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
458                         else
459                                 verbose git branch -b "$BRANCH" "$UPSTREAM"
460                         fi
461                         verbose git am "$D"
462                 done
463                 rm -rf "$patchdir"
464                 ;;
465         admin-merge)
466                 for d in $repos; do
467                         enter "$d0/$d" verbose
468                         git rev-parse "$1/$2" || continue
469                         # 1. review
470                         {
471                                 git log HEAD.."$1/$2"
472                                 git diff HEAD..."$1/$2"
473                         } | less
474                         a=
475                         while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
476                                 echo "Merge \"$1/$2\" into `git symbolic-ref HEAD` of $d?"
477                                 read -r a
478                         done
479                         if [ x"$a" = x"y" ]; then
480                                 git merge "$1/$2"
481                                 cd "$d0"
482                                 a=
483                                 if ! "$SELF" compile; then
484                                         a=n
485                                 fi
486                                 cd "$d0/$d"
487                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
488                                         echo "Still merge \"$1/$2\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."
489                                         read -r a
490                                 done
491                                 if [ x"$a" = x"y" ]; then
492                                         git push origin HEAD
493                                         git push "$1" :"$2"
494                                 else
495                                         git reset --hard HEAD@{1}
496                                 fi
497                         fi
498                 done
499                 ;;
500         *)
501                 echo "Usage:"
502                 echo "  $SELF pull"
503                 echo "  $SELF merge"
504                 echo "  $SELF push [-s]"
505                 echo "  $SELF branches"
506                 echo "  $SELF branch [<remote>] <branchname>"
507                 echo "  $SELF branch <remote> <branchname> <srcbranchname>"
508                 echo "  $SELF checkout [<remote>] <branchname>"
509                 echo "  $SELF compile"
510                 echo "  $SELF run <client> <options>"
511                 echo "  $SELF each <command>"
512                 ;;
513 esac