]> git.xonotic.org Git - xonotic/xonotic.git/blob - all
new all function: ./all -c compile, does "make clean" too
[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 .                             |                                                   | master
112 data/xonotic-data.pk3dir      |                                                   | master
113 data/xonotic-maps.pk3dir      |                                                   | master
114 data/xonotic-music.pk3dir     |                                                   | master
115 data/xonotic-nexcompat.pk3dir |                                                   | master
116 darkplaces                    |                                                   | div0-stable
117 fteqcc                        | git://github.com/Blub/qclib.git                   | master
118 div0-gittools                 | git://git.icculus.org/divverent/div0-gittools.git | master
119 netradiant                    |                                                   | master
120 "
121 # todo: in darkplaces, change repobranch to div0-stable
122
123 repos=`echo "$repos_urls" | grep . | cut -d '|' -f 1 | tr -d ' '`
124
125 base=`git config remote.origin.url`
126 base=${base%xonotic.git}
127
128 repourl()
129 {
130         t=`echo "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
131         if [ -n "$t" ]; then
132                 echo "$t"
133         else
134                 if [ x"$1" = x"." ]; then
135                         echo "$base""xonotic.git"
136                 else
137                         echo "$base${1##*/}.git"
138                 fi
139         fi
140 }
141
142 repobranch()
143 {
144         t=`echo "$repos_urls" | grep "^$1 " | cut -d '|' -f 3 | tr -d ' '`
145         if [ -n "$t" ]; then
146                 echo "$t"
147         else
148                 echo "master"
149         fi
150 }
151
152 repos=`for d in $repos; do
153         p="${d%dir}"
154         if [ x"$p" = x"$d" ] || [ -d "$d" ] || ! [ -f "$p" ]; then
155                 echo "$d"
156         fi
157 done`
158
159 if [ "$#" = 0 ]; then
160         set -- help
161 fi
162 cmd=$1
163 shift
164
165 case "$cmd" in
166         update|pull)
167                 for d in $repos; do
168                         url=`repourl "$d"`
169                         branch=`repobranch "$d"`
170                         if [ -d "$d0/$d" ]; then
171                                 enter "$d0/$d" verbose
172                                 verbose git config remote.origin.url "$url"
173                                 verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
174                                         # TODO remove this line later
175
176                                 verbose git config core.autocrlf false
177                                 verbose git config core.safecrlf false # we don't NEED that...
178
179                                 r=`git symbolic-ref HEAD`
180                                 r=${r#refs/heads/}
181                                 if git config branch.$r.remote >/dev/null 2>&1; then
182                                         if ! verbose git pull; then
183                                                 check_mergeconflict "$d"
184                                                 echo "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
185                                                 read -r DUMMY
186                                         fi
187                                 fi
188
189                                 cd "$d00"
190                                 checkself "$cmd" "$@"
191                                 cd "$d0/$d"
192                                 verbose git remote prune origin
193                                 cd "$d0"
194                         else
195                                 verbose git clone "$url" "$d0/$d"
196                                 enter "$d0/$d" verbose
197                                 verbose git checkout "$branch"
198                                 cd "$d0"
199                         fi
200                 done
201                 ;;
202         checkout|switch)
203                 remote=$1
204                 branch=$2
205                 if [ -z "$branch" ]; then
206                         branch=$remote
207                         remote=origin
208                 fi
209                 exists=false
210                 for d in $repos; do
211                         enter "$d0/$d" verbose
212                         if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
213                                 exists=true
214                                 verbose git checkout "$branch"
215                         elif git rev-parse "refs/remotes/$remote/$branch" >/dev/null 2>&1; then
216                                 exists=true
217                                 verbose git checkout --track -b "$branch" "$remote/$branch"
218                         else
219                                 verbose git checkout "`repobranch "$d"`"
220                         fi
221                         cd "$d00"
222                         checkself "$cmd" "$@"
223                         cd "$d0"
224                 done
225                 if ! $exists; then
226                         echo "The requested branch was not found in any repository."
227                 fi
228                 exec "$SELF" branch
229                 ;;
230         branch)
231                 remote=$1
232                 branch=$2
233                 srcbranch=$3
234                 if [ -z "$branch" ]; then
235                         branch=$remote
236                         remote=origin
237                 fi
238                 if [ -z "$branch" ]; then
239                         for d in $repos; do
240                                 enter "$d0/$d"
241                                 r=`git symbolic-ref HEAD`
242                                 r=${r#refs/heads/}
243                                 echo "$d is at $r"
244                                 cd "$d0"
245                         done
246                 else
247                         for d in $repos; do
248                                 dv=`visible_repo_name "$d"`
249                                 enter "$d0/$d" verbose
250                                 a=
251                                 if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
252                                         echo "Already having this branch in $dv."
253                                 else
254                                         while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
255                                                 echo "Branch in $dv?"
256                                                 read -r a
257                                         done
258                                         if [ x"$a" = x"y" ]; then
259                                                 if [ -n "$srcbranch" ]; then
260                                                         b=$srcbranch
261                                                 else
262                                                         b="`repobranch "$d"`"
263                                                 fi
264                                                 # TODO do this without pushing
265                                                 verbose git push "$remote" "$b":"$branch"
266                                                 verbose git checkout --track -b "$branch" "$remote/$branch"
267                                         fi
268                                 fi
269                                 cd "$d0"
270                         done
271                         "$SELF" branch
272                 fi
273                 ;;
274         branches)
275                 for d in $repos; do
276                         enter "$d0/$d"
277                         echo "In $d:"
278                         git branch -a -v -v | cut -c 3- | while read -r BRANCH REV UPSTREAM TEXT; do
279                                 case "$UPSTREAM" in
280                                         \[*)
281                                                 UPSTREAM=${UPSTREAM#\[}
282                                                 UPSTREAM=${UPSTREAM%\]}
283                                                 UPSTREAM=${UPSTREAM%:*}
284                                                 ;;
285                                         *)
286                                                 TEXT="$UPSTREAM $TEXT"
287                                                 UPSTREAM=
288                                                 ;;
289                                 esac
290                                 if [ x"$REV" = x"->" ]; then
291                                         continue
292                                 fi
293                                 BRANCH=${BRANCH#remotes/}
294                                 echo -n "  $BRANCH"
295                                 if [ -n "$UPSTREAM" ]; then
296                                         echo -n " (tracking $UPSTREAM)"
297                                 fi
298                                 #echo " $TEXT"
299                                 echo
300                         done
301                 done
302                 ;;
303         branches_short)
304                 for d in $repos; do
305                         cd "$d0/$d" # am in a pipe, shouldn't use enter
306                         git branch -a -v -v | cut -c 3- | sed "s,^,$d ,"
307                         cd "$d0"
308                 done | {
309                         branches_list=
310                         # branches_repos_*=
311                         while read -r d BRANCH REV UPSTREAM TEXT; do
312                                 case "$UPSTREAM" in
313                                         \[*)
314                                                 UPSTREAM=${UPSTREAM#\[}
315                                                 UPSTREAM=${UPSTREAM%\]}
316                                                 UPSTREAM=${UPSTREAM%:*}
317                                                 ;;
318                                         *)
319                                                 TEXT="$UPSTREAM $TEXT"
320                                                 UPSTREAM=
321                                                 ;;
322                                 esac
323                                 if [ x"$REV" = x"->" ]; then
324                                         continue
325                                 fi
326                                 BRANCH=${BRANCH#remotes/}
327                                 ID=`echo "$BRANCH" | tr -c "A-Za-z0-9." "_"`
328                                 branches_list="$branches_list $BRANCH" # TEH SORT MAKEZ IT UNIEQ
329                                 eval "r=\$branches_repos_$ID"
330                                 r="$r $d:$UPSTREAM"
331                                 eval "branches_repos_$ID=\$r"
332                         done
333                         echo -n "$branches_list" | xargs -n 1 echo | sort -u | while IFS= read -r BRANCH; do
334                                 ID=`echo "$BRANCH" | tr -c "A-Za-z0-9." "_"`
335                                 eval "r=\$branches_repos_$ID"
336                                 echo "$BRANCH: $r"
337                         done
338                 }
339                 ;;
340         merge)
341                 for d in $repos; do
342                         dv=`visible_repo_name "$d"`
343                         enter "$d0/$d" verbose
344                         r=`git symbolic-ref HEAD`
345                         r=${r#refs/heads/}
346                         if git log HEAD..origin/"`repobranch "$d"`" | grep .; then
347                                 # we have uncommitted changes
348                                 a=
349                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
350                                         echo "Could merge from \"`repobranch "$d"`\" into \"$r\" in $dv. Do it?"
351                                         read -r a
352                                 done
353                                 if [ x"$a" = x"y" ]; then
354                                         if ! verbose git merge origin/"`repobranch "$d"`"; then
355                                                 check_mergeconflict "$d"
356                                                 exit 1 # this should ALWAYS be fatal
357                                         fi
358                                 fi
359                         fi
360                         cd "$d0"
361                 done
362                 ;;
363         push|commit)
364                 submit=$1
365                 for d in $repos; do
366                         dv=`visible_repo_name "$d"`
367                         enter "$d0/$d" verbose
368                         r=`git symbolic-ref HEAD`
369                         r=${r#refs/heads/}
370                         if git diff HEAD | grep .; then
371                                 # we have uncommitted changes
372                                 a=
373                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
374                                         echo "Uncommitted changes in \"$r\" in $dv. Commit?"
375                                         read -r a
376                                 done
377                                 if [ x"$a" = x"y" ]; then
378                                         verbose git commit -a
379                                 fi
380                         fi
381                         rem=`git config "branch.$r.remote" || echo origin`
382                         if { git log "$rem/$r".."$r" || git log origin/"`repobranch "$d"`".."$r"; } | grep .; then
383                                 a=
384                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
385                                         echo "Push \"$r\" in $dv?"
386                                         read -r a
387                                 done
388                                 if [ x"$a" = x"y" ]; then
389                                         verbose git push "$rem" HEAD
390                                 fi
391                         fi
392                         if [ x"$submit" = x"-s" ]; then
393                                 case "$r" in
394                                         */*)
395                                                 verbose git push "$rem" HEAD:"${r%%/*}/finished/${r#*/}"
396                                                 ;;
397                                 esac
398                         fi
399                         cd "$d0"
400                 done
401                 ;;
402         compile)
403                 if [ -n "$WE_HATE_OUR_USERS" ]; then
404                         TARGETS="sv-debug cl-debug"
405                 else
406                         TARGETS="sv-debug cl-debug sdl-debug"
407                 fi
408                 case "$1" in
409                         -c)
410                                 clean=true
411                                 shift
412                                 ;;
413                         *)
414                                 clean=false
415                                 ;;
416                 esac
417                 case "$1" in
418                         sdl)
419                                 TARGETS="sdl-debug"
420                                 shift
421                                 ;;
422                         glx|agl|wgl)
423                                 TARGETS="cl-debug"
424                                 shift
425                                 ;;
426                         dedicated)
427                                 TARGETS="sv-debug"
428                                 shift
429                                 ;;
430                 esac
431                 if [ -z "$MAKEFLAGS" ]; then
432                         if [ -f /proc/cpuinfo ]; then
433                                 ncpus=$((`grep -c '^processor   :' /proc/cpuinfo`+0))
434                                 if [ $ncpus -gt 1 ]; then
435                                         MAKEFLAGS=-j$ncpus
436                                 fi
437                         fi
438                         case "`uname`" in
439                                 Linux|*BSD)
440                                         MAKEFLAGS="$MAKEFLAGS DP_LINK_TO_LIBJPEG=1"
441                                         ;;
442                         esac
443                 fi
444                 enter "$d0/fteqcc" verbose
445                 if $clean; then
446                         verbose make $MAKEFLAGS clean
447                 fi
448                 verbose make $MAKEFLAGS
449                 enter "$d0/data/xonotic-data.pk3dir" verbose
450                 if $clean; then
451                         verbose make $MAKEFLAGS clean
452                 fi
453                 verbose make FTEQCC="$d0/fteqcc/fteqcc.bin" "$@" $MAKEFLAGS
454                 enter "$d0/darkplaces" verbose
455                 if $clean; then
456                         verbose make $MAKEFLAGS clean
457                 fi
458                 for T in $TARGETS; do
459                         verbose make $MAKEFLAGS "$@" "$T"
460                 done
461                 ;;
462         run)
463                 if [ -n "$WE_HATE_OUR_USERS" ]; then
464                         client=
465                         export PATH="$d0/misc/buildfiles/w32:$PATH"
466                 else
467                         client=-sdl
468                 fi
469                 case "$1" in
470                         sdl|glx|agl|dedicated)
471                                 client=-$1
472                                 shift
473                                 ;;
474                         wgl)
475                                 client=
476                                 shift
477                                 ;;
478                 esac
479                 if ! [ -x "darkplaces/darkplaces$client" ]; then
480                         if [ -x "darkplaces/darkplaces$client.exe" ]; then
481                                 client=$client.exe
482                         else
483                                 echo "Client darkplaces/darkplaces$client not found, aborting"
484                                 exit 1
485                         fi
486                 fi
487                 set -- "darkplaces/darkplaces$client" -nexuiz -customgamename Xonotic -customgamedirname1 data -customgamedirname2 "" -customgamescreenshotname xonotic -customgameuserdirname xonotic "$@"
488                 if [ -n "$USE_GDB" ]; then
489                         set -- gdb --args "$@"
490                 fi
491                 "$@"
492                 ;;
493         each|foreach)
494                 for d in $repos; do
495                         enter "$d0/$d" verbose
496                         verbose "$@"
497                         cd "$d0"
498                 done
499                 ;;
500         save-patches)
501                 outfile=$1
502                 patchdir=`mktemp -d -t save-patches.XXXXXX`
503                 for d in $repos; do
504                         enter "$d0/$d" verbose
505                         git branch -v -v | cut -c 3- | {
506                                 i=0
507                                 while read -r BRANCH REV UPSTREAM TEXT; do
508                                         case "$UPSTREAM" in
509                                                 \[*)
510                                                         UPSTREAM=${UPSTREAM#\[}
511                                                         UPSTREAM=${UPSTREAM%\]}
512                                                         UPSTREAM=${UPSTREAM%:*}
513                                                         TRACK=true
514                                                         ;;
515                                                 *)
516                                                         UPSTREAM=origin/"`repobranch "$d"`"
517                                                         TRACK=false
518                                                         ;;
519                                         esac
520                                         if [ x"$REV" = x"->" ]; then
521                                                 continue
522                                         fi
523                                         if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
524                                                 echo "$d" > "$patchdir/$i/info.txt"
525                                                 echo "$BRANCH" >> "$patchdir/$i/info.txt"
526                                                 echo "$UPSTREAM" >> "$patchdir/$i/info.txt"
527                                                 echo "$TRACK" >> "$patchdir/$i/info.txt"
528                                                 i=$(($i+1))
529                                         else
530                                                 rm -rf "$patchdir/$i"
531                                         fi
532                                 done
533                         }
534                 done
535                 ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
536                 rm -rf "$patchdir"
537                 ;;
538         restore-patches)
539                 infile=$1
540                 patchdir=`mktemp -d -t restore-patches.XXXXXX`
541                 ( cd "$patchdir" && tar xvzf - ) < "$infile"
542                 # detach the head
543                 for P in "$patchdir"/*/info.txt; do
544                         D=${P%/info.txt}
545                         exec 3<"$P"
546                         read -r d <&3
547                         read -r BRANCH <&3
548                         read -r UPSTREAM <&3
549                         read -r TRACK <&3
550                         verbose git checkout HEAD^0
551                         verbose git branch -D "$BRANCH"
552                         if [ x"$TRACK" = x"true" ]; then
553                                 verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
554                         else
555                                 verbose git branch -b "$BRANCH" "$UPSTREAM"
556                         fi
557                         verbose git am "$D"
558                 done
559                 rm -rf "$patchdir"
560                 ;;
561         admin-merge)
562                 for d in $repos; do
563                         enter "$d0/$d" verbose
564                         git rev-parse "$1/$2" || continue
565                         # 1. review
566                         {
567                                 git log HEAD.."$1/$2"
568                                 git diff HEAD..."$1/$2"
569                         } | less
570                         a=
571                         while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
572                                 echo "Merge \"$1/$2\" into `git symbolic-ref HEAD` of $d?"
573                                 read -r a
574                         done
575                         if [ x"$a" = x"y" ]; then
576                                 git merge "$1/$2"
577                                 cd "$d0"
578                                 a=
579                                 if ! "$SELF" compile; then
580                                         a=n
581                                 fi
582                                 cd "$d0/$d"
583                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
584                                         echo "Still merge \"$1/$2\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."
585                                         read -r a
586                                 done
587                                 if [ x"$a" = x"y" ]; then
588                                         git push origin HEAD
589                                         git push "$1" :"$2"
590                                 else
591                                         git reset --hard HEAD@{1}
592                                 fi
593                         fi
594                 done
595                 ;;
596         *)
597                 echo "Usage:"
598                 echo "  $SELF pull"
599                 echo "  $SELF merge"
600                 echo "  $SELF push [-s]"
601                 echo "  $SELF branches"
602                 echo "  $SELF branch [<remote>] <branchname>"
603                 echo "  $SELF branch <remote> <branchname> <srcbranchname>"
604                 echo "  $SELF checkout [<remote>] <branchname>"
605                 echo "  $SELF compile [-c] [<client>] <options>"
606                 echo "  $SELF run [<client>] <options>"
607                 echo "  $SELF each <command>"
608                 ;;
609 esac