Make a status test pass against old servers.
[svn.git] / tools / dist / dist.sh
blob6d538200a05eb70b3bc5fdbbb510a204e037640b
1 #!/bin/sh
3 # USAGE: ./dist.sh -v VERSION -r REVISION -pr REPOS-PATH
4 # [-alpha ALPHA_NUM|-beta BETA_NUM|-rc RC_NUM]
5 # [-apr PATH-TO-APR ] [-apru PATH-TO-APR-UTIL]
6 # [-apri PATH-TO-APR-ICONV] [-neon PATH-TO-NEON]
7 # [-serf PATH-TO-SERF] [-zlib PATH-TO-ZLIB]
8 # [-zip] [-sign] [-nodeps]
10 # Create a distribution tarball, labelling it with the given VERSION.
11 # The tarball will be constructed from the root located at REPOS-PATH,
12 # in REVISION. For example, the command line:
14 # ./dist.sh -v 1.4.0 -r ????? -pr branches/1.4.x
16 # will create a 1.4.0 release tarball. Make sure you have apr,
17 # apr-util, neon, serf and zlib subdirectories in your current working
18 # directory or specify the path to them with the -apr, -apru, -neon or
19 # -zlib options. For example:
20 # ./dist.sh -v 1.4.0 -r ????? -pr branches/1.4.x \
21 # -apr ~/in-tree-libraries/apr-0.9.12 \
22 # -apru ~/in-tree-libraries/apr-util-0.9.12 \
23 # -neon ~/in-tree-libraries/neon-0.25.5 \
24 # -zlib ~/in-tree-libraries/zlib-1.2.3
26 # Note that there is _no_ need to run dist.sh from a Subversion
27 # working copy, so you may wish to create a dist-resources directory
28 # containing the apr/, apr-util/, neon/ serf/ and zlib/ dependencies, and
29 # run dist.sh from that.
31 # When building alpha, beta or rc tarballs pass the appropriate flag
32 # followed by a number. For example "-alpha 5", "-beta 3", "-rc 2".
34 # If neither an -alpha, -beta or -rc option is specified, a release
35 # tarball will be built.
37 # To build a Windows zip file package, additionally pass -zip and the
38 # path to apr-iconv with -apri.
41 USAGE="USAGE: ./dist.sh -v VERSION -r REVISION -pr REPOS-PATH \
42 [-alpha ALPHA_NUM|-beta BETA_NUM|-rc RC_NUM] \
43 [-apr APR_PATH ] [-apru APR_UTIL_PATH] [-apri APR_ICONV_PATH] \
44 [-neon NEON_PATH ] [-serf SERF_PATH] [-zlib ZLIB_PATH] [-zip] [-sign] \
45 [-nodeps]
46 EXAMPLES: ./dist.sh -v 0.36.0 -r 8278 -pr branches/foo
47 ./dist.sh -v 0.36.0 -r 8278 -pr trunk
48 ./dist.sh -v 0.36.0 -r 8282 -rs 8278 -pr tags/0.36.0
49 ./dist.sh -v 0.36.0 -r 8282 -rs 8278 -pr tags/0.36.0 -alpha 1
50 ./dist.sh -v 0.36.0 -r 8282 -rs 8278 -pr tags/0.36.0 -beta 1
51 ./dist.sh -v 0.36.0 -r 8282 -rs 8278 -pr tags/0.36.0 -nightly r8282"
53 # Let's check and set all the arguments
54 ARG_PREV=""
56 for ARG in $@
58 if [ -n "$ARG_PREV" ]; then
59 case $ARG_PREV in
60 -v) VERSION="$ARG" ;;
61 -r) REVISION="$ARG" ;;
62 -pr) REPOS_PATH="$ARG" ;;
63 -alpha) ALPHA="$ARG" ;;
64 -beta) BETA="$ARG" ;;
65 -nightly) NIGHTLY="$ARG" ;;
66 -rc) RC="$ARG" ;;
67 -apr) APR_PATH="$ARG" ;;
68 -apru) APRU_PATH="$ARG" ;;
69 -apri) APRI_PATH="$ARG" ;;
70 -zlib) ZLIB_PATH="$ARG" ;;
71 -neon) NEON_PATH="$ARG" ;;
72 -serf) SERF_PATH="$ARG" ;;
73 esac
74 ARG_PREV=""
75 else
76 case $ARG in
77 -v|-r|-rs|-pr|-alpha|-beta|-rc|-apr|-apru|-apri|-zlib|-neon|-serf|-nightly)
78 ARG_PREV=$ARG
80 -zip) ZIP=1 ;;
81 -nodeps) NODEPS=1 ;;
82 -sign) SIGN=1 ;;
84 echo " $USAGE"
85 exit 1
87 esac
89 done
91 if [ -n "$ALPHA" ] && [ -n "$BETA" ] && [ -n "$NIGHTLY" ] ||
92 [ -n "$ALPHA" ] && [ -n "$RC" ] && [ -n "$NIGHTLY" ] ||
93 [ -n "$BETA" ] && [ -n "$RC" ] && [ -n "$NIGHTLY" ] ||
94 [ -n "$ALPHA" ] && [ -n "$BETA" ] && [ -n "$RC" ]; then
95 echo " $USAGE"
96 exit 1
97 elif [ -n "$ALPHA" ] ; then
98 VER_TAG="Alpha $ALPHA"
99 VER_NUMTAG="-alpha$ALPHA"
100 elif [ -n "$BETA" ] ; then
101 VER_TAG="Beta $BETA"
102 VER_NUMTAG="-beta$BETA"
103 elif [ -n "$RC" ] ; then
104 VER_TAG="Release Candidate $RC"
105 VER_NUMTAG="-rc$RC"
106 elif [ -n "$NIGHTLY" ] ; then
107 VER_TAG="Nightly Build ($NIGHTLY)"
108 VER_NUMTAG="-nightly-$NIGHTLY"
109 else
110 VER_TAG="r$REVISION"
111 VER_NUMTAG=""
114 if [ -n "$ZIP" ] ; then
115 EXTRA_EXPORT_OPTIONS="--native-eol CRLF"
118 if [ -z "$VERSION" ] || [ -z "$REVISION" ] || [ -z "$REPOS_PATH" ]; then
119 echo " $USAGE"
120 exit 1
123 if [ -z "$APR_PATH" ]; then
124 APR_PATH='apr'
127 if [ -z "$APRU_PATH" ]; then
128 APRU_PATH='apr-util'
131 if [ -z "$NEON_PATH" ]; then
132 NEON_PATH='neon'
135 if [ -z "$SERF_PATH" ]; then
136 SERF_PATH='serf'
139 if [ -z "$APRI_PATH" ]; then
140 APRI_PATH='apr-iconv'
143 if [ -z "$ZLIB_PATH" ]; then
144 ZLIB_PATH='zlib'
147 REPOS_PATH="`echo $REPOS_PATH | sed 's/^\/*//'`"
149 # See comment when we 'roll' the tarballs as to why pax is required.
150 type pax > /dev/null 2>&1
151 if [ $? -ne 0 ] && [ -z "$ZIP" ]; then
152 echo "ERROR: pax could not be found"
153 exit 1
156 # Default to 'wget', but allow 'curl' to be used if available.
157 HTTP_FETCH=wget
158 HTTP_FETCH_OUTPUT="-O"
159 type wget > /dev/null 2>&1
160 if [ $? -ne 0 ]; then
161 type curl > /dev/null 2>&1
162 if [ $? -ne 0 ]; then
163 echo "Neither curl or wget found."
164 exit 2
166 HTTP_FETCH=curl
167 HTTP_FETCH_OUTPUT="-o"
170 DISTNAME="subversion-${VERSION}${VER_NUMTAG}"
171 DEPSNAME="subversion-deps-${VERSION}${VER_NUMTAG}"
172 DIST_SANDBOX=.dist_sandbox
173 DISTPATH="$DIST_SANDBOX/$DISTNAME"
174 DEPSPATH="$DIST_SANDBOX/deps/$DISTNAME"
176 echo "Distribution will be named: $DISTNAME"
177 echo " constructed from path: /$REPOS_PATH"
178 echo " constructed from revision: $REVISION"
180 rm -rf "$DIST_SANDBOX"
181 mkdir "$DIST_SANDBOX"
182 mkdir -p "$DEPSPATH"
183 echo "Removed and recreated $DIST_SANDBOX"
185 LC_ALL=C
186 LANG=C
187 TZ=UTC
188 export LC_ALL
189 export LANG
190 export TZ
192 echo "Exporting $REPOS_PATH r$REVISION into sandbox..."
193 (cd "$DIST_SANDBOX" && \
194 ${SVN:-svn} export -q $EXTRA_EXPORT_OPTIONS -r "$REVISION" \
195 "http://svn.collab.net/repos/svn/$REPOS_PATH" \
196 "$DISTNAME" --username none --password none)
198 rm -f "$DISTPATH/STATUS"
200 # Remove the www/ directory, and create an empty directory in it's place.
201 # Export hacking.html from trunk into that directory.
202 # (See http://svn.haxx.se/dev/archive-2008-02/0863.shtml for rationale.)
203 rm -rf "$DISTPATH/www"
204 mkdir "$DISTPATH/www"
205 ${SVN:-svn} export -q $EXTRA_EXPORT_OPTIONS -r "$REVISION" \
206 "http://svn.collab.net/repos/svn/trunk/www/hacking.html" \
207 --username none --password none "$DISTPATH/www/hacking.html"
209 install_dependency()
211 DEP_NAME=$1
212 if [ -z $2 ]; then
213 DEP_PATH=/dev/null
214 else
215 DEP_PATH=$2
218 if [ -d $DEP_PATH ]; then
219 if [ -d $DEP_PATH/.svn ]; then
220 echo "Exporting local $DEP_NAME into sandbox"
221 ${SVN:-svn} export -q $EXTRA_EXPORT_OPTIONS "$DEP_PATH" "$DISTPATH/$DEP_NAME"
222 else
223 echo "Copying local $DEP_NAME into sandbox"
224 cp -r "$DEP_PATH" "$DISTPATH/$DEP_NAME"
225 (cd "$DISTPATH/$DEP_NAME" && [ -f Makefile ] && make distclean)
226 echo "Removing all CVS/ and .cvsignore files from $DEP_NAME..."
227 find "$DISTPATH/$DEP_NAME" -name CVS -type d -print | xargs rm -fr
228 find "$DISTPATH/$DEP_NAME" -name .cvsignore -print | xargs rm -f
229 find "$DISTPATH/$DEP_NAME" -name '*.o' -print | xargs rm -f
231 else
232 # Not having the dependency directories isn't fatal if -nodeps passed.
233 if [ -z "$NODEPS" ]; then
234 echo "Missing dependency directory!"
235 exit 2
240 move_dependency()
242 DEP_NAME=$1
244 SOURCE_PATH="$DISTPATH/$DEP_NAME"
245 DEST_PATH="$DEPSPATH/$DEP_NAME"
247 rm -rf "$DEST_PATH"
248 mv "$SOURCE_PATH" "$DEST_PATH"
251 install_dependency apr "$APR_PATH"
252 install_dependency apr-util "$APRU_PATH"
254 if [ -n "$ZIP" ]; then
255 install_dependency apr-iconv "$APRI_PATH"
258 install_dependency neon "$NEON_PATH"
259 install_dependency serf "$SERF_PATH"
260 install_dependency zlib "$ZLIB_PATH"
262 find "$DISTPATH" -name config.nice -print | xargs rm -f
264 # Massage the new version number into svn_version.h. We need to do
265 # this before running autogen.sh --release on the subversion code,
266 # because otherwise svn_version.h's mtime makes SWIG files regenerate
267 # on end-user's systems, when they should just be compiled by the
268 # Release Manager and left at that.
270 ver_major=`echo $VERSION | cut -d '.' -f 1`
271 ver_minor=`echo $VERSION | cut -d '.' -f 2`
272 ver_patch=`echo $VERSION | cut -d '.' -f 3`
274 vsn_file="$DISTPATH/subversion/include/svn_version.h"
276 sed \
277 -e "/#define *SVN_VER_MAJOR/s/[0-9]\+/$ver_major/" \
278 -e "/#define *SVN_VER_MINOR/s/[0-9]\+/$ver_minor/" \
279 -e "/#define *SVN_VER_PATCH/s/[0-9]\+/$ver_patch/" \
280 -e "/#define *SVN_VER_TAG/s/\".*\"/\" ($VER_TAG)\"/" \
281 -e "/#define *SVN_VER_NUMTAG/s/\".*\"/\"$VER_NUMTAG\"/" \
282 -e "/#define *SVN_VER_REVISION/s/[0-9]\+/$REVISION/" \
283 < "$vsn_file" > "$vsn_file.tmp"
285 mv -f "$vsn_file.tmp" "$vsn_file"
287 echo "Creating svn_version.h.dist, for use in tagging matching tarball..."
288 cp "$vsn_file" "svn_version.h.dist"
290 # Don't run autogen.sh when we are building the Windows zip file.
291 # Windows users don't need the files generated by this command,
292 # especially not the generated projects or SWIG files.
293 if [ -z "$ZIP" ] ; then
294 echo "Running ./autogen.sh in sandbox, to create ./configure ..."
295 (cd "$DISTPATH" && ./autogen.sh --release) || exit 1
298 echo "Removing any autom4te.cache directories that might exist..."
299 find "$DISTPATH" -depth -type d -name 'autom4te*.cache' -exec rm -rf {} \;
301 # Now that the dependencies have been configured/cleaned properly,
302 # move them into their separate tree for packaging.
303 move_dependency apr
304 move_dependency apr-util
305 if [ -n "$ZIP" ]; then
306 move_dependency apr-iconv
308 move_dependency neon
309 move_dependency serf
310 move_dependency zlib
312 if [ -z "$ZIP" ]; then
313 # Do not use tar, it's probably GNU tar which produces tar files that are
314 # not compliant with POSIX.1 when including filenames longer than 100 chars.
315 # Platforms without a tar that understands the GNU tar extension will not
316 # be able to extract the resulting tar file. Use pax to produce POSIX.1
317 # tar files.
318 echo "Rolling $DISTNAME.tar ..."
319 (cd "$DIST_SANDBOX" > /dev/null && pax -x ustar -w "$DISTNAME") > \
320 "$DISTNAME.tar"
321 echo "Rolling $DEPSNAME.tar ..."
322 (cd "$DIST_SANDBOX/deps" > /dev/null && pax -x ustar -w "$DISTNAME") > \
323 "$DEPSNAME.tar"
325 echo "Compressing to $DISTNAME.tar.bz2 ..."
326 bzip2 -9fk "$DISTNAME.tar"
327 echo "Compressing to $DEPSNAME.tar.bz2 ..."
328 bzip2 -9fk "$DEPSNAME.tar"
330 # Use the gzip -n flag - this prevents it from storing the original name of
331 # the .tar file, and far more importantly, the mtime of the .tar file, in the
332 # produced .tar.gz file. This is important, because it makes the gzip
333 # encoding reproducable by anyone else who has an similar version of gzip,
334 # and also uses "gzip -9n". This means that committers who want to GPG-sign
335 # both the .tar.gz and the .tar.bz2 can download the .tar.bz2 (which is
336 # smaller), and locally generate an exact duplicate of the official .tar.gz
337 # file. This metadata is data on the temporary uncompressed tarball itself,
338 # not any of its contents, so there will be no effect on end-users.
339 echo "Compressing to $DISTNAME.tar.gz ..."
340 gzip -9nf "$DISTNAME.tar"
341 echo "Compressing to $DEPSNAME.tar.gz ..."
342 gzip -9nf "$DEPSNAME.tar"
343 else
344 echo "Rolling $DISTNAME.zip ..."
345 (cd "$DIST_SANDBOX" > /dev/null && zip -q -r - "$DISTNAME") > \
346 "$DISTNAME.zip"
347 echo "Rolling $DEPSNAME.zip ..."
348 (cd "$DIST_SANDBOX/deps" > /dev/null && zip -q -r - "$DISTNAME") > \
349 "$DEPSNAME.zip"
351 echo "Removing sandbox..."
352 rm -rf "$DIST_SANDBOX"
354 sign_file()
356 if [ -n "$SIGN" ]; then
357 type gpg > /dev/null 2>&1
358 if [ $? -eq 0 ]; then
359 if test -n "$user"; then
360 args="--default-key $user"
362 for ARG in $@
364 gpg --armor $args --detach-sign $ARG
365 done
366 else
367 type pgp > /dev/null 2>&1
368 if [ $? -eq 0 ]; then
369 if test -n "$user"; then
370 args="-u $user"
372 for ARG in $@
374 pgp -sba $ARG $args
375 done
381 echo ""
382 echo "Done:"
383 if [ -z "$ZIP" ]; then
384 ls -l "$DISTNAME.tar.bz2" "$DISTNAME.tar.gz" "$DEPSNAME.tar.bz2" "$DEPSNAME.tar.gz"
385 sign_file $DISTNAME.tar.gz $DISTNAME.tar.bz2 $DEPSNAME.tar.bz2 $DEPSNAME.tar.gz
386 echo ""
387 echo "md5sums:"
388 md5sum "$DISTNAME.tar.bz2" "$DISTNAME.tar.gz" "$DEPSNAME.tar.bz2" "$DEPSNAME.tar.gz"
389 type sha1sum > /dev/null 2>&1
390 if [ $? -eq 0 ]; then
391 echo ""
392 echo "sha1sums:"
393 sha1sum "$DISTNAME.tar.bz2" "$DISTNAME.tar.gz" "$DEPSNAME.tar.bz2" "$DEPSNAME.tar.gz"
395 else
396 ls -l "$DISTNAME.zip" "$DEPSNAME.zip"
397 sign_file $DISTNAME.zip $DEPSNAME.zip
398 echo ""
399 echo "md5sum:"
400 md5sum "$DISTNAME.zip" "$DEPSNAME.zip"
401 type sha1sum > /dev/null 2>&1
402 if [ $? -eq 0 ]; then
403 echo ""
404 echo "sha1sum:"
405 sha1sum "$DISTNAME.zip" "$DEPSNAME.zip"