]> git.mxchange.org Git - flightgear.git/blob - scripts/tools/fg-submit
- escape '+' in awk pattern (gawk doesn't need it, but mawk does)
[flightgear.git] / scripts / tools / fg-submit
1 #!/bin/bash
2 #
3 # This script called in a CVS directory compares local files with
4 # the repository, and prepares an update package containing all
5 # changes and new files for submission to a CVS maintainer. If there
6 # are only changes in text files, then a compressed unified diff is
7 # made (foo.diff.bz2). If there are also changed binary or new files,
8 # then an archive is made instead (foo.tar.bz2). The base name ("foo")
9 # can be given as command line argument. Otherwise the directory name
10 # is used. The script also leaves a diff in uncompressed/unpackaged
11 # form. This is only for developer convenience -- for a quick check
12 # of the diff correctness. It is not to be submitted. The script will
13 # not overwrite any file, but rather rename conflicting files.
14 #
15 # Usage:  fg-submit [<basename>]
16 #
17 # Example:
18 #     $ cd $FG_ROOT/Aircraft/bo105
19 #     $ fg-submit                # -> bo105.diff.bz2 or bo105.tar.bz2
20 #
21 #     $ fg-submit update         # -> update.diff.bz2 or update.tar.bz2
22 #
23 #
24 # Spaces in the basename are replaced with "%20". People who prefer
25 # to have the date in the archive name can conveniently achieve this
26 # by defining a shell alias in ~/.bashrc:
27 #
28 #     alias submit='fg-submit "${PWD/#*\/}-$(date +%Y-%m-%d)"'
29 #
30 #
31 # If the script finds an application named "fg-upload", then it calls
32 # this at the end with two arguments:
33 #
34 #     $1 ... archive or compressed diff for submission
35 #     $2 ... accessory diff, *NOT* for submission!
36 #
37 # $1 and $2 are guaranteed not to contain spaces, only $1 is guaranteed
38 # to actually exist. Such as script can be used to upload the file to an
39 # ftp-/webserver, and/or to remove one or both files. Example using
40 # KDE's kfmclient for upload (alternatives: ncftpput, gnomevfs-copy, wput):
41 #
42 #     $ cat ~/bin/fg-upload
43 #     #!/bin/bash
44 #     echo "uploading $1"
45 #     if kfmclient copy $1 ftp://user:password@server.com; then
46 #             echo "deleting $1 $2"
47 #             rm -f $1 $2
48 #
49 #             echo "Done.  URL: ftp://server.com/$1"
50 #     else
51 #             echo "arghh ... HELP! HELP!"
52 #     fi
53
54
55 SELF=${0/#*\/}
56 DIR=${PWD/#*\/}
57 BASE=${1:-$DIR}
58 BASE=${BASE// /%20}
59
60 CVS=/usr/bin/cvs                 # avoid colorcvs wrapper from
61 [ -x $CVS ] || CVS=cvs           # http://www.hakubi.us/colorcvs/
62 UPLOAD=$(which fg-upload 2>/dev/null)
63
64 ARCHIVE=$BASE.tar.bz2
65 DIFF=$BASE.diff
66 CDIFF=$DIFF.bz2
67
68
69 function ERROR   { echo -e "\e[31;1m$*\e[m";   }
70 function LOG     { echo -e "\e[35m$*\e[m";     }
71 function NEW     { echo -e "\e[32m\t+ $*\e[m"; }
72 function CHANGED { echo -e "\e[36m\t+ $*\e[m"; }
73 function REJECT  { echo -e "\e[31m\t- $*\e[m"; }
74
75 function diffstat {
76         # output diff statistics, similar to the "diffstat" utility
77         awk '
78                 function line(a, r, c, f) {
79                         print "\t\033[32m"a"\033[m\t\033[31m"r"\033[m\t\033[34m"c"\033[m\t"f
80                 }
81                 function dofile() {
82                         if (!file) {
83                                 return
84                         }
85                         if (bin) {
86                                 print "\t. . . . binary  . . . . \033[36m"file"\033[m"
87                         } else {
88                                 line(a, r, c, file)
89                                 at += a; rt += r; ct += c
90                         }
91                         a = r = c = 0
92                 }
93                 BEGIN      {
94                         print "\tadded---removed-changed----------------------------------------"
95                         a = r = c = at = rt = ct = n = bin = 0
96                 }
97                 /^Index: / { dofile(); scan = bin = 0; file = $2; n++; next }
98                 /^@@/      { scan = 1; next }
99                 /^Binary/  { if (!scan) bin = 1; next }
100                 /^\+/       { if (scan) a++; next }
101                 /^-/       { if (scan) r++; next }
102                 /^!/       { if (scan) c++; next }
103                 END        {
104                         dofile()
105                         print "\t----------------------------------------total------------------"
106                         line(at, rt, ct, "\033[min "n" files")
107                 }
108         ' <$1
109 }
110
111
112 # create temporary dir that's automatically removed on exit
113 TMP=$(mktemp -d /tmp/$SELF.$BASE.XXXXXX) || (echo "$0: can't create temporary dir"; exit 1)
114 trap "rm -rf $TMP" 0 1 2 3 13 15
115
116
117 # move old files out of the way
118 for i in $DIFF $CDIFF $ARCHIVE; do
119         [ -f $i ] && mv $i $(mktemp $i.XXXXXX)
120 done
121
122
123 LOG "updating and checking for new files ..."
124 $CVS -q up -dP >$TMP/up
125
126
127 if grep "^C " $TMP/up &>/dev/null; then
128         ERROR "there are conflicts with the following files:"
129         grep "^C " $TMP/up
130         exit 1
131 fi
132
133
134 LOG "making diff ..."
135 if ! $CVS -q diff -up >$DIFF; then
136         LOG "diff statistics:"
137         diffstat $DIFF
138         echo
139
140         # add diff file itself
141         echo $DIFF >>$TMP/files
142
143         # add changed binary files
144         awk '
145                 /^Index: / { scan = 1; file = $2; next }
146                 /^@@/      { scan = 0; next }
147                 /^Binary/  { if (scan) { print file } }
148         ' <$DIFF >>$TMP/files
149 else
150         rm -f $DIFF
151 fi
152
153
154 LOG "checking for files to submit ..."
155 if [ -f $TMP/files ]; then
156         cat $TMP/files|while read i; do
157                 CHANGED "$i"
158         done
159 fi
160
161 grep "^? " $TMP/up|while read i; do
162         find ${i#? } -type f >>$TMP/check
163 done
164
165
166 # classify and filter files
167 if [ -f $TMP/check ]; then
168         for i in $(cat $TMP/check); do
169                 case "$i" in
170                 $ARCHIVE*|$DIFF*) # don't add files generated by the script
171                         ;;
172                 */.*|.*)          # silently drop hidden files
173                         ;;
174                 *~|*.|*.bak|*.orig)
175                         REJECT "$i\t\t(backup file)"
176                         ;;
177                 CVS/*|*/CVS/*)
178                         REJECT "$i\t\t(CVS file)"
179                         ;;
180                 *.tar.gz*|*.tar.bz2*|*.tgz|*.zip)
181                         REJECT "$i\t\t(archive)"
182                         ;;
183                 *.blend|*.blend[0-9]|*.blend[0-9][0-9])
184                         REJECT "$i\t\t(blender file)"
185                         ;;
186                 *.xcf|*.tga|*.bmp|*.BMP|*.png)
187                         REJECT "$i\t\t(graphics file)"
188                         ;;
189                 *)
190                         NEW "$i"
191                         echo "$i" >>$TMP/files
192                         ;;
193                 esac
194         done
195 fi
196
197
198 if ! [ -f $TMP/files ]; then
199         LOG "no changed or new files found"
200         exit 0
201 fi
202
203 echo
204 numfiles=$(awk '//{n++}END{print n}' <$TMP/files)
205 if [ -f $DIFF -a $numfiles == 1 ]; then
206         LOG "only changed non-binary files found"
207         LOG "creating compressed diff \e[1;37;40m$CDIFF\e[m\e[35m ..."
208         bzip2 -k $DIFF
209         RESULT=$CDIFF
210 else
211         LOG "changed and/or new files found"
212         LOG "creating archive \e[1;37;40m$ARCHIVE\e[m\e[35m ..."
213         tar -cjf $ARCHIVE --files-from $TMP/files
214         RESULT=$ARCHIVE
215 fi
216
217 [ -x "$UPLOAD" -a -f $RESULT ] && $UPLOAD "$PWD" $RESULT $DIFF
218
219 exit 0
220