1 |
#!/bin/sh |
2 |
|
3 |
# svn2cl.sh - front end shell script for svn2cl.xsl, calls xsltproc |
4 |
# with the correct parameters |
5 |
# |
6 |
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Arthur de Jong. |
7 |
# |
8 |
# Redistribution and use in source and binary forms, with or without |
9 |
# modification, are permitted provided that the following conditions |
10 |
# are met: |
11 |
# 1. Redistributions of source code must retain the above copyright |
12 |
# notice, this list of conditions and the following disclaimer. |
13 |
# 2. Redistributions in binary form must reproduce the above copyright |
14 |
# notice, this list of conditions and the following disclaimer in |
15 |
# the documentation and/or other materials provided with the |
16 |
# distribution. |
17 |
# 3. The name of the author may not be used to endorse or promote |
18 |
# products derived from this software without specific prior |
19 |
# written permission. |
20 |
# |
21 |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
22 |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
23 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
24 |
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
25 |
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
26 |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
27 |
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
28 |
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
29 |
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
30 |
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
31 |
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 |
|
33 |
# exit on any failures |
34 |
set -e |
35 |
# report unset variables |
36 |
set -u |
37 |
|
38 |
# svn2cl version |
39 |
VERSION="0.12" |
40 |
|
41 |
# set default parameters |
42 |
PWD=`pwd` |
43 |
STRIPPREFIX="AUTOMATICALLY-DETERMINED" |
44 |
LINELEN=75 |
45 |
GROUPBYDAY="no" |
46 |
INCLUDEREV="no" |
47 |
BREAKBEFOREMSG="no" |
48 |
REPARAGRAPH="no" |
49 |
SEPARATEDAYLOGS="no" |
50 |
ACTIONS="no" |
51 |
CHANGELOG="" |
52 |
OUTSTYLE="cl" |
53 |
SVNLOGCMD="svn --verbose --xml log" |
54 |
SVNINFOCMD="svn --non-interactive info" |
55 |
AUTHORSFILE="" |
56 |
IGNORE_MESSAGE_STARTING="" |
57 |
TITLE="ChangeLog" |
58 |
REVISION_LINK="#r" |
59 |
TMPFILES="" |
60 |
AWK="awk" |
61 |
|
62 |
# do command line checking |
63 |
prog=`basename $0` |
64 |
while [ $# -gt 0 ] |
65 |
do |
66 |
case "$1" in |
67 |
--strip-prefix) |
68 |
STRIPPREFIX="$2" |
69 |
shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } |
70 |
;; |
71 |
--strip-prefix=*) |
72 |
STRIPPREFIX=`echo "$1" | sed 's/^--[a-z-]*=//'` |
73 |
shift |
74 |
;; |
75 |
--linelen) |
76 |
LINELEN="$2"; |
77 |
shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } |
78 |
;; |
79 |
--linelen=*) |
80 |
LINELEN=`echo "$1" | sed 's/^--[a-z-]*=//'` |
81 |
shift |
82 |
;; |
83 |
--group-by-day) |
84 |
GROUPBYDAY="yes"; |
85 |
shift |
86 |
;; |
87 |
--separate-daylogs) |
88 |
SEPARATEDAYLOGS="yes" |
89 |
shift |
90 |
;; |
91 |
-i|--include-rev) |
92 |
INCLUDEREV="yes"; |
93 |
shift |
94 |
;; |
95 |
-a|--include-actions) |
96 |
ACTIONS="yes" |
97 |
shift |
98 |
;; |
99 |
--break-before-msg|--breaks-before-msg) |
100 |
# FIXME: if next argument is numeric use that as a parameter |
101 |
BREAKBEFOREMSG="yes" |
102 |
shift |
103 |
;; |
104 |
--break-before-msg=*|--breaks-before-msg=*) |
105 |
BREAKBEFOREMSG=`echo "$1" | sed 's/^--[a-z-]*=//'` |
106 |
shift |
107 |
;; |
108 |
--reparagraph) |
109 |
REPARAGRAPH="yes" |
110 |
shift |
111 |
;; |
112 |
--title) |
113 |
TITLE="$2" |
114 |
shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } |
115 |
;; |
116 |
--title=*) |
117 |
TITLE=`echo "$1" | sed 's/^--[a-z-]*=//'` |
118 |
shift |
119 |
;; |
120 |
--revision-link) |
121 |
REVISION_LINK="$2" |
122 |
shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } |
123 |
;; |
124 |
--revision-link=*) |
125 |
REVISION_LINK=`echo "$1" | sed 's/^--[a-z-]*=//'` |
126 |
shift |
127 |
;; |
128 |
--ignore-message-starting) |
129 |
IGNORE_MESSAGE_STARTING="$2" |
130 |
shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } |
131 |
;; |
132 |
--ignore-message-starting=*) |
133 |
IGNORE_MESSAGE_STARTING=`echo "$1" | sed 's/^--[a-z-]*=//'` |
134 |
shift |
135 |
;; |
136 |
-f|--file|-o|--output) |
137 |
CHANGELOG="$2" |
138 |
shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } |
139 |
;; |
140 |
--file=*|--output=*) |
141 |
CHANGELOG=`echo "$1" | sed 's/^--[a-z-]*=//'` |
142 |
shift |
143 |
;; |
144 |
--stdout) |
145 |
CHANGELOG="-" |
146 |
shift |
147 |
;; |
148 |
--authors) |
149 |
AUTHORSFILE="$2" |
150 |
shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } |
151 |
;; |
152 |
--authors=*) |
153 |
AUTHORSFILE=`echo "$1" | sed 's/^--[a-z-]*=//'` |
154 |
shift |
155 |
;; |
156 |
--html) |
157 |
OUTSTYLE="html" |
158 |
shift |
159 |
;; |
160 |
-r|--revision|--targets|--limit) |
161 |
# add these as extra options to the command (with argument) |
162 |
arg=`echo "$2" | sed "s/'/'\"'\"'/g"` |
163 |
SVNLOGCMD="$SVNLOGCMD $1 '$arg'" |
164 |
shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } |
165 |
;; |
166 |
--username|--password|--config-dir) |
167 |
# add these as extra options to the command (with argument) |
168 |
arg=`echo "$2" | sed "s/'/'\"'\"'/g"` |
169 |
SVNLOGCMD="$SVNLOGCMD $1 '$arg'" |
170 |
# also add to svn info command |
171 |
SVNINFOCMD="$SVNINFOCMD $1 '$arg'" |
172 |
shift 2 || { echo "$prog: option requires an argument -- $1";exit 1; } |
173 |
;; |
174 |
--revision=*|--targets=*|--limit=*) |
175 |
# these are single argument versions of the above |
176 |
arg=`echo "$1" | sed "s/'/'\"'\"'/g"` |
177 |
SVNLOGCMD="$SVNLOGCMD '$arg'" |
178 |
shift |
179 |
;; |
180 |
--username=*|--password=*|--config-dir=*) |
181 |
# these are single argument versions of the above |
182 |
arg=`echo "$1" | sed "s/'/'\"'\"'/g"` |
183 |
SVNLOGCMD="$SVNLOGCMD '$arg'" |
184 |
# also add to svn info command |
185 |
SVNINFOCMD="$SVNINFOCMD '$arg'" |
186 |
shift |
187 |
;; |
188 |
--stop-on-copy) |
189 |
# add these as simple options |
190 |
SVNLOGCMD="$SVNLOGCMD $1" |
191 |
shift |
192 |
;; |
193 |
--no-auth-cache|--non-interactive) |
194 |
# add these as simple options |
195 |
SVNLOGCMD="$SVNLOGCMD $1" |
196 |
# also add to svn info command |
197 |
SVNINFOCMD="$SVNINFOCMD $1" |
198 |
shift |
199 |
;; |
200 |
-V|--version) |
201 |
echo "$prog $VERSION"; |
202 |
echo "Written by Arthur de Jong." |
203 |
echo "" |
204 |
echo "Copyright (C) 2005, 2006, 2007, 2008, 2009 Arthur de Jong." |
205 |
echo "This is free software; see the source for copying conditions. There is NO" |
206 |
echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." |
207 |
exit 0 |
208 |
;; |
209 |
-h|--help) |
210 |
echo "Usage: $prog [OPTION]... [PATH]..." |
211 |
echo "Generate a ChangeLog from a subversion repository." |
212 |
echo "" |
213 |
echo " --strip-prefix=NAME prefix to strip from all entries, defaults" |
214 |
echo " path inside the repository" |
215 |
echo " --linelen=NUM maximum length of an output line" |
216 |
echo " --group-by-day group changelog entries by day" |
217 |
echo " --separate-daylogs put a blank line between grouped by day entries" |
218 |
echo " -i, --include-rev include revision numbers" |
219 |
echo " -a, --include-actions add [ADD], [DEL] and [CPY] tags to files" |
220 |
echo " --break-before-msg[=NUM] add a line break (or multiple breaks)" |
221 |
echo " between the paths and the log message" |
222 |
echo " --reparagraph rewrap lines inside a paragraph" |
223 |
echo " --title=NAME title used in html file" |
224 |
echo " --revision-link=NAME link revision numbers in html output" |
225 |
echo " --ignore-message-starting=STRING" |
226 |
echo " ignore messages starting with the string" |
227 |
echo " -o, --output=FILE output to FILE instead of ChangeLog" |
228 |
echo " -f, --file=FILE alias for -o, --output" |
229 |
echo " --stdout output to stdout instead of ChangeLog" |
230 |
echo " --authors=FILE file to read for authors" |
231 |
echo " --html output as html instead of plain text" |
232 |
echo " -h, --help display this help and exit" |
233 |
echo " -V, --version output version information and exit" |
234 |
echo "" |
235 |
echo "PATH arguments and the following options are passed to the svn log" |
236 |
echo "command: -r, --revision, --targets --stop-on-copy, --username," |
237 |
echo "--password, --no-auth-cache, --non-interactive, --config-dir and" |
238 |
echo "--limit (see 'svn help log' for more information)." |
239 |
exit 0 |
240 |
;; |
241 |
-*) |
242 |
echo "$prog: invalid option -- $1" |
243 |
echo "Try '$prog --help' for more information." |
244 |
exit 1 |
245 |
;; |
246 |
*) |
247 |
arg=`echo "$1" | sed "s/'/'\"'\"'/g"` |
248 |
SVNLOGCMD="$SVNLOGCMD '$arg'" |
249 |
SVNINFOCMD="$SVNINFOCMD '$arg'" |
250 |
shift |
251 |
;; |
252 |
esac |
253 |
done |
254 |
|
255 |
# find the directory that this script resides in |
256 |
prog="$0" |
257 |
while [ -h "$prog" ] |
258 |
do |
259 |
dir=`dirname "$prog"` |
260 |
prog=`ls -ld "$prog" | sed "s/^.*-> \(.*\)/\1/;/^[^/]/s,^,$dir/,"` |
261 |
done |
262 |
dir=`dirname "$prog"` |
263 |
dir=`cd "$dir" && pwd` |
264 |
XSL="$dir/svn2${OUTSTYLE}.xsl" |
265 |
|
266 |
# check if the authors file is formatted as a legacy |
267 |
# colon separated file |
268 |
if [ -n "$AUTHORSFILE" ] && \ |
269 |
egrep '^(#.*|[a-zA-Z0-9].*:)' "$AUTHORSFILE" > /dev/null 2>/dev/null |
270 |
then |
271 |
# create a temporary file |
272 |
tmpfile=`mktemp -t svn2cl.XXXXXX 2> /dev/null || tempfile -s .svn2cl 2> /dev/null || echo "$AUTHORSFILE.$$.xml"` |
273 |
arg=`echo "$tmpfile" | sed "s/'/'\"'\"'/g"` |
274 |
TMPFILES="$TMPFILES '$arg'" |
275 |
# generate an authors.xml file on the fly |
276 |
echo '<authors>' > "$tmpfile" |
277 |
sed -n 's/&/\&/g;s/</\</g;s/>/\>/g;s|^\([a-zA-Z0-9][^:]*\):\(.*\)$| <author uid="\1">\2</author>|p' \ |
278 |
< "$AUTHORSFILE" >> "$tmpfile" |
279 |
echo '</authors>' >> "$tmpfile" |
280 |
AUTHORSFILE="$tmpfile" |
281 |
fi |
282 |
|
283 |
# find the absolute path of the authors file |
284 |
# (otherwise xsltproc will find the file relative to svn2cl.xsl) |
285 |
pwd=`pwd` |
286 |
AUTHORSFILE=`echo "$AUTHORSFILE" | sed "/^[^/]/s|^|$pwd/|"` |
287 |
|
288 |
# if no filename was specified, make one up |
289 |
if [ -z "$CHANGELOG" ] |
290 |
then |
291 |
CHANGELOG="ChangeLog" |
292 |
if [ "$OUTSTYLE" != "cl" ] |
293 |
then |
294 |
CHANGELOG="$CHANGELOG.$OUTSTYLE" |
295 |
fi |
296 |
fi |
297 |
|
298 |
# try to determin a prefix to strip from all paths |
299 |
if [ "$STRIPPREFIX" = "AUTOMATICALLY-DETERMINED" ] |
300 |
then |
301 |
STRIPPREFIX=`LANG=C eval "$SVNINFOCMD" | $AWK '/^URL:/{url=$2} /^Repository Root:/{root=$3} END{if(root){print substr(url,length(root)+2)}else{n=split(url,u,"/");print u[n]}}'` |
302 |
STRIPPREFIX=`echo "$STRIPPREFIX" | sed 's/%20/ /g'` |
303 |
fi |
304 |
|
305 |
# redirect stdout to the changelog file if needed |
306 |
if [ "x$CHANGELOG" != "x-" ] |
307 |
then |
308 |
exec > "$CHANGELOG" |
309 |
fi |
310 |
|
311 |
# actually run the command we need |
312 |
eval "$SVNLOGCMD" | \ |
313 |
xsltproc --stringparam strip-prefix "$STRIPPREFIX" \ |
314 |
--stringparam linelen "$LINELEN" \ |
315 |
--stringparam groupbyday "$GROUPBYDAY" \ |
316 |
--stringparam separate-daylogs "$SEPARATEDAYLOGS" \ |
317 |
--stringparam include-rev "$INCLUDEREV" \ |
318 |
--stringparam include-actions "$ACTIONS" \ |
319 |
--stringparam breakbeforemsg "$BREAKBEFOREMSG" \ |
320 |
--stringparam reparagraph "$REPARAGRAPH" \ |
321 |
--stringparam authorsfile "$AUTHORSFILE" \ |
322 |
--stringparam title "$TITLE" \ |
323 |
--stringparam revision-link "$REVISION_LINK" \ |
324 |
--stringparam ignore-message-starting "$IGNORE_MESSAGE_STARTING" \ |
325 |
--nowrite \ |
326 |
--nomkdir \ |
327 |
--nonet \ |
328 |
"$XSL" - |
329 |
|
330 |
# clean up temporary files |
331 |
[ -n "$TMPFILES" ] && eval "rm -f $TMPFILES" |
332 |
|
333 |
# we're done (the previous command could return false) |
334 |
exit 0 |