You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/11/27 12:52:46 UTC
svn commit: r1546002 [38/39] - in /subversion/branches/verify-keep-going: ./
build/ build/ac-macros/ build/generator/ build/generator/swig/
build/generator/templates/ build/win32/ contrib/client-side/emacs/
contrib/server-side/ contrib/server-side/svnc...
Modified: subversion/branches/verify-keep-going/tools/dev/unix-build/Makefile.svn
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/tools/dev/unix-build/Makefile.svn?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/tools/dev/unix-build/Makefile.svn (original)
+++ subversion/branches/verify-keep-going/tools/dev/unix-build/Makefile.svn Wed Nov 27 11:52:35 2013
@@ -70,9 +70,9 @@ APR_VER = 1.4.6
APR_ICONV_VER = 1.2.1
GNU_ICONV_VER = 1.14
APR_UTIL_VER = 1.4.1
-HTTPD_VER = 2.2.22
+HTTPD_VER = 2.2.26
NEON_VER = 0.29.6
-SERF_VER = 1.2.1
+SERF_VER = 1.3.2
SERF_OLD_VER = 0.3.1
CYRUS_SASL_VER = 2.1.25
SQLITE_VER = 3071600
@@ -249,7 +249,7 @@ bdb-reset:
rm -f $(BDB_OBJDIR)/$(f);)
bdb-clean:
- -(cd $(BDB_SRCDIR)/build_unix/ && make clean)
+ -(cd $(BDB_SRCDIR)/build_unix/ && env MAKEFLAGS= make clean)
# fetch distfile for bdb
$(DISTDIR)/$(BDB_DIST):
@@ -272,12 +272,12 @@ $(BDB_OBJDIR)/.configured: $(BDB_OBJDIR)
# compile bdb
$(BDB_OBJDIR)/.compiled: $(BDB_OBJDIR)/.configured
- (cd $(BDB_SRCDIR)/build_unix && make)
+ (cd $(BDB_SRCDIR)/build_unix && env MAKEFLAGS= make)
touch $@
# install bdb
$(BDB_OBJDIR)/.installed: $(BDB_OBJDIR)/.compiled
- (cd $(BDB_SRCDIR)/build_unix && make install)
+ (cd $(BDB_SRCDIR)/build_unix && env MAKEFLAGS= make install)
touch $@
#######################################################################
@@ -293,7 +293,7 @@ apr-reset:
rm -f $(APR_OBJDIR)/$(f);)
apr-clean:
- -(cd $(APR_OBJDIR) && make clean)
+ -(cd $(APR_OBJDIR) && env MAKEFLAGS= make clean)
# retrieve apr if not present yet
$(APR_OBJDIR)/.retrieved:
@@ -314,7 +314,7 @@ POOL_DEBUG_FLAG=--enable-pool-debug=all
endif
# configure apr
-$(APR_OBJDIR)/.configured: $(APR_OBJDIR)/.retrieved
+$(APR_OBJDIR)/.configured: $(APR_OBJDIR)/.retrieved $(BDB_OBJDIR)/.installed
cd $(APR_SRCDIR) && ./buildconf
cd $(APR_OBJDIR) \
&& env CFLAGS="-O0 -g $(PROFILE_CFLAGS)" GREP="`which grep`" \
@@ -327,12 +327,12 @@ $(APR_OBJDIR)/.configured: $(APR_OBJDIR)
# compile apr
$(APR_OBJDIR)/.compiled: $(APR_OBJDIR)/.configured
- (cd $(APR_OBJDIR) && make)
+ (cd $(APR_OBJDIR) && env MAKEFLAGS= make)
touch $@
# install apr
$(APR_OBJDIR)/.installed: $(APR_OBJDIR)/.compiled
- (cd $(APR_OBJDIR) && make install)
+ (cd $(APR_OBJDIR) && env MAKEFLAGS= make install)
touch $@
#######################################################################
@@ -348,7 +348,7 @@ apr-iconv-reset:
rm -f $(APR_ICONV_OBJDIR)/$(f);)
apr-iconv-clean:
- -(cd $(APR_ICONV_OBJDIR) && make clean)
+ -(cd $(APR_ICONV_OBJDIR) && env MAKEFLAGS= make clean)
# fetch distfile for apr-iconv
$(DISTDIR)/$(APR_ICONV_DIST):
@@ -361,7 +361,8 @@ $(APR_ICONV_OBJDIR)/.retrieved: $(DISTDI
touch $@
# configure apr-iconv
-$(APR_ICONV_OBJDIR)/.configured: $(APR_ICONV_OBJDIR)/.retrieved
+$(APR_ICONV_OBJDIR)/.configured: $(APR_ICONV_OBJDIR)/.retrieved \
+ $(APR_OBJDIR)/.installed
cd $(APR_ICONV_OBJDIR) \
&& env CFLAGS="-g $(PROFILE_CFLAGS)" GREP="`which grep`" \
$(APR_ICONV_SRCDIR)/configure \
@@ -372,12 +373,12 @@ $(APR_ICONV_OBJDIR)/.configured: $(APR_I
# compile apr-iconv
$(APR_ICONV_OBJDIR)/.compiled: $(APR_ICONV_OBJDIR)/.configured
(cd $(APR_ICONV_OBJDIR) \
- && make CPPFLAGS="-D_OSD_POSIX" CFLAGS="-g -O0 $(PROFILE_CFLAGS)")
+ && env MAKEFLAGS= make CPPFLAGS="-D_OSD_POSIX" CFLAGS="-g -O0 $(PROFILE_CFLAGS)")
touch $@
# install apr-iconv
$(APR_ICONV_OBJDIR)/.installed: $(APR_ICONV_OBJDIR)/.compiled
- (cd $(APR_ICONV_OBJDIR) && make install)
+ (cd $(APR_ICONV_OBJDIR) && env MAKEFLAGS= make install)
touch $@
#######################################################################
@@ -393,7 +394,7 @@ gnu-iconv-reset:
rm -f $(GNU_ICONV_OBJDIR)/$(f);)
gnu-iconv-clean:
- -(cd $(GNU_ICONV_OBJDIR) && make clean)
+ -(cd $(GNU_ICONV_OBJDIR) && env MAKEFLAGS= make clean)
rm -f $(GNU_ICONV_OBJDIR)/lib_encodings.def.diff
rm -f $(GNU_ICONV_OBJDIR)/lib_aliases.gperf.diff
@@ -453,12 +454,12 @@ $(GNU_ICONV_OBJDIR)/.configured: $(GNU_I
# compile gnu-iconv
$(GNU_ICONV_OBJDIR)/.compiled: $(GNU_ICONV_OBJDIR)/.configured
- (cd $(GNU_ICONV_OBJDIR) && make)
+ (cd $(GNU_ICONV_OBJDIR) && env MAKEFLAGS= make)
touch $@
# install gnu-iconv
$(GNU_ICONV_OBJDIR)/.installed: $(GNU_ICONV_OBJDIR)/.compiled
- (cd $(GNU_ICONV_OBJDIR) && make install)
+ (cd $(GNU_ICONV_OBJDIR) && env MAKEFLAGS= make install)
touch $@
#######################################################################
@@ -490,7 +491,7 @@ apr-util-reset:
rm -f $(APR_UTIL_OBJDIR)/$(f);)
apr-util-clean:
- -(cd $(APR_UTIL_OBJDIR) && make clean)
+ -(cd $(APR_UTIL_OBJDIR) && env MAKEFLAGS= make clean)
# retrieve apr-util if not present yet
@@ -504,12 +505,15 @@ $(APR_UTIL_OBJDIR)/.retrieved:
ifeq ($(USE_APR_ICONV),yes)
ICONV_FLAG=--with-iconv=$(PREFIX)/apr
+ICONV_OBJDIR=$(APR_ICONV_OBJDIR)
else
ICONV_FLAG=--with-iconv=$(PREFIX)/iconv
+ICONV_OBJDIR=$(GNU_ICONV_OBJDIR)
endif
# configure apr-util
-$(APR_UTIL_OBJDIR)/.configured: $(APR_UTIL_OBJDIR)/.retrieved
+$(APR_UTIL_OBJDIR)/.configured: $(APR_UTIL_OBJDIR)/.retrieved \
+ $(APR_OBJDIR)/.installed $(ICONV_OBJDIR)/.installed
cd $(APR_UTIL_SRCDIR) && ./buildconf --with-apr=$(APR_SRCDIR)
cd $(APR_UTIL_OBJDIR) \
&& env LD_LIBRARY_PATH=$(PREFIX)/bdb/lib \
@@ -525,12 +529,12 @@ $(APR_UTIL_OBJDIR)/.configured: $(APR_UT
# compile apr-util
$(APR_UTIL_OBJDIR)/.compiled: $(APR_UTIL_OBJDIR)/.configured
- (cd $(APR_UTIL_OBJDIR) && make)
+ (cd $(APR_UTIL_OBJDIR) && env MAKEFLAGS= make)
touch $@
# install apr-util
$(APR_UTIL_OBJDIR)/.installed: $(APR_UTIL_OBJDIR)/.compiled
- (cd $(APR_UTIL_OBJDIR) && make install)
+ (cd $(APR_UTIL_OBJDIR) && env MAKEFLAGS= make install)
touch $@
#######################################################################
@@ -547,7 +551,7 @@ httpd-reset:
rm -f $(HTTPD_OBJDIR)/$(f);)
httpd-clean:
- -(cd $(HTTPD_OBJDIR) && make clean)
+ -(cd $(HTTPD_OBJDIR) && env MAKEFLAGS= make clean)
# fetch distfile for httpd
$(DISTDIR)/$(HTTPD_DIST):
@@ -560,7 +564,8 @@ $(HTTPD_OBJDIR)/.retrieved: $(DISTDIR)/$
touch $@
# configure httpd
-$(HTTPD_OBJDIR)/.configured: $(HTTPD_OBJDIR)/.retrieved
+$(HTTPD_OBJDIR)/.configured: $(HTTPD_OBJDIR)/.retrieved \
+ $(APR_UTIL_OBJDIR)/.installed
cd $(HTTPD_OBJDIR) \
&& env CFLAGS="-g $(PROFILE_CFLAGS)" GREP="`which grep`" \
$(HTTPD_SRCDIR)/configure \
@@ -575,12 +580,12 @@ $(HTTPD_OBJDIR)/.configured: $(HTTPD_OBJ
# compile httpd
$(HTTPD_OBJDIR)/.compiled: $(HTTPD_OBJDIR)/.configured
- (cd $(HTTPD_OBJDIR) && make)
+ (cd $(HTTPD_OBJDIR) && env MAKEFLAGS= make)
touch $@
# install httpd
$(HTTPD_OBJDIR)/.installed: $(HTTPD_OBJDIR)/.compiled
- (cd $(HTTPD_OBJDIR) && make install)
+ (cd $(HTTPD_OBJDIR) && env MAKEFLAGS= make install)
touch $@
# create a httpd.conf for mod_dav_svn
@@ -618,7 +623,7 @@ neon-reset:
rm -f $(NEON_OBJDIR)/$(f);)
neon-clean:
- -(cd $(NEON_OBJDIR) && make clean)
+ -(cd $(NEON_OBJDIR) && env MAKEFLAGS= make clean)
# fetch distfile for neon
$(DISTDIR)/$(NEON_DIST):
@@ -665,12 +670,12 @@ $(NEON_OBJDIR)/.configured: $(NEON_OBJDI
# compile neon
$(NEON_OBJDIR)/.compiled: $(NEON_OBJDIR)/.configured
- (cd $(NEON_OBJDIR) && make)
+ (cd $(NEON_OBJDIR) && env MAKEFLAGS= make)
touch $@
# install neon
$(NEON_OBJDIR)/.installed: $(NEON_OBJDIR)/.compiled
- (cd $(NEON_OBJDIR) && make install)
+ (cd $(NEON_OBJDIR) && env MAKEFLAGS= make install)
touch $@
@@ -687,7 +692,7 @@ serf-reset:
rm -f $(SERF_OBJDIR)/$(f);)
serf-clean:
- -(cd $(SERF_SRCDIR) && ./serfmake clean)
+ -(cd $(SERF_SRCDIR) && scons -c)
# fetch distfile for serf
@@ -711,21 +716,23 @@ $(SERF_OBJDIR)/.retrieved:
touch $@
# compile serf (serf won't compile outside its source tree)
-$(SERF_OBJDIR)/.compiled: $(SERF_OBJDIR)/.retrieved
+$(SERF_OBJDIR)/.compiled: $(SERF_OBJDIR)/.retrieved \
+ $(APR_UTIL_OBJDIR)/.installed
cd $(SERF_SRCDIR) && \
- env CFLAGS="-O0 -g $(PROFILE_CFLAGS)" \
- ./serfmake --with-apr=$(PREFIX)/apr \
- --prefix=$(PREFIX)/serf \
- build
+ scons DEBUG=1 CFLAGS="-O0 -g $(PROFILE_CFLAGS)" \
+ APR=$(PREFIX)/apr \
+ APU=$(PREFIX)/apr \
+ PREFIX=$(PREFIX)/serf
touch $@
# install serf
$(SERF_OBJDIR)/.installed: $(SERF_OBJDIR)/.compiled
+ rm -rf $(PREFIX)/serf # XXX scons cannot reinstall :(
cd $(SERF_SRCDIR) && \
- ./serfmake --with-apr=$(PREFIX)/apr \
- --with-apr-util=$(PREFIX)/apr \
- --prefix=$(PREFIX)/serf \
- install
+ scons install
+ # work around unportable scons shared lib support
+ -ln -s libserf-1.so.$(shell echo $(SERF_VER) | sed -e 's/[0-9]$$/0/') \
+ $(PREFIX)/serf/lib/libserf-1.so
touch $@
#######################################################################
@@ -752,7 +759,8 @@ $(SERF_OLD_OBJDIR)/.retrieved:
touch $@
# compile serf (serf won't compile outside its source tree)
-$(SERF_OLD_OBJDIR)/.compiled: $(SERF_OLD_OBJDIR)/.retrieved
+$(SERF_OLD_OBJDIR)/.compiled: $(SERF_OLD_OBJDIR)/.retrieved \
+ $(APR_UTIL_OBJDIR)/.installed
cd $(SERF_OLD_SRCDIR) && \
env CFLAGS="-O0 -g $(PROFILE_CFLAGS)" \
./serfmake --with-apr=$(PREFIX)/apr \
@@ -783,7 +791,7 @@ sqlite-reset:
rm -f $(SQLITE_OBJDIR)/$(f);)
sqlite-clean:
- -cd $(SQLITE_OBJDIR) && make clean
+ -cd $(SQLITE_OBJDIR) && env MAKEFLAGS= make clean
# fetch distfile for sqlite
$(DISTDIR)/$(SQLITE_DIST):
@@ -812,12 +820,12 @@ $(SQLITE_OBJDIR)/.configured: $(SQLITE_O
# compile sqlite
$(SQLITE_OBJDIR)/.compiled: $(SQLITE_OBJDIR)/.configured
- (cd $(SQLITE_OBJDIR) && make)
+ (cd $(SQLITE_OBJDIR) && env MAKEFLAGS= make)
touch $@
# install sqlite
$(SQLITE_OBJDIR)/.installed: $(SQLITE_OBJDIR)/.compiled
- (cd $(SQLITE_OBJDIR) && make install)
+ (cd $(SQLITE_OBJDIR) && env MAKEFLAGS= make install)
touch $@
#######################################################################
@@ -833,7 +841,7 @@ cyrus-sasl-reset:
rm -f $(CYRUS_SASL_OBJDIR)/$(f);)
cyrus-sasl-clean:
- -(cd $(CYRUS_SASL_OBJDIR) && make distclean)
+ -(cd $(CYRUS_SASL_OBJDIR) && env MAKEFLAGS= make distclean)
# fetch distfile for cyrus-sasl
$(DISTDIR)/$(CYRUS_SASL_DIST):
@@ -868,7 +876,8 @@ endif
touch $@
# configure cyrus-sasl
-$(CYRUS_SASL_OBJDIR)/.configured: $(CYRUS_SASL_OBJDIR)/.retrieved
+$(CYRUS_SASL_OBJDIR)/.configured: $(CYRUS_SASL_OBJDIR)/.retrieved \
+ $(BDB_OBJDIR)/.installed $(SQLITE_OBJDIR)/.installed
cd $(CYRUS_SASL_OBJDIR) \
&& env CFLAGS="-g $(PROFILE_CFLAGS)" \
CPPFLAGS="-I/usr/include/kerberosV" \
@@ -886,12 +895,12 @@ $(CYRUS_SASL_OBJDIR)/.configured: $(CYRU
# compile cyrus-sasl
$(CYRUS_SASL_OBJDIR)/.compiled: $(CYRUS_SASL_OBJDIR)/.configured
- (cd $(CYRUS_SASL_OBJDIR) && make)
+ (cd $(CYRUS_SASL_OBJDIR) && env MAKEFLAGS= make)
touch $@
# install cyrus-sasl
$(CYRUS_SASL_OBJDIR)/.installed: $(CYRUS_SASL_OBJDIR)/.compiled
- (cd $(CYRUS_SASL_OBJDIR) && make install)
+ (cd $(CYRUS_SASL_OBJDIR) && env MAKEFLAGS= make install)
touch $@
#######################################################################
@@ -907,7 +916,7 @@ libmagic-reset:
rm -f $(LIBMAGIC_OBJDIR)/$(f);)
libmagic-clean:
- -(cd $(LIBMAGIC_OBJDIR) && make distclean)
+ -(cd $(LIBMAGIC_OBJDIR) && env MAKEFLAGS= make distclean)
# fetch distfile for libmagic
$(DISTDIR)/$(LIBMAGIC_DIST):
@@ -930,12 +939,12 @@ $(LIBMAGIC_OBJDIR)/.configured: $(LIBMAG
# compile libmagic
$(LIBMAGIC_OBJDIR)/.compiled: $(LIBMAGIC_OBJDIR)/.configured
- (cd $(LIBMAGIC_OBJDIR) && make)
+ (cd $(LIBMAGIC_OBJDIR) && env MAKEFLAGS= make)
touch $@
# install libmagic
$(LIBMAGIC_OBJDIR)/.installed: $(LIBMAGIC_OBJDIR)/.compiled
- (cd $(LIBMAGIC_OBJDIR) && make install)
+ (cd $(LIBMAGIC_OBJDIR) && env MAKEFLAGS= make install)
touch $@
#######################################################################
@@ -951,7 +960,7 @@ ruby-reset:
rm -f $(RUBY_OBJDIR)/$(f);)
ruby-clean:
- -(cd $(RUBY_OBJDIR) && make distclean)
+ -(cd $(RUBY_OBJDIR) && env MAKEFLAGS= make distclean)
# fetch distfile for ruby
$(DISTDIR)/$(RUBY_DIST):
@@ -982,12 +991,12 @@ $(RUBY_OBJDIR)/.configured: $(RUBY_OBJDI
# compile ruby
$(RUBY_OBJDIR)/.compiled: $(RUBY_OBJDIR)/.configured
- (cd $(RUBY_OBJDIR) && make)
+ (cd $(RUBY_OBJDIR) && env MAKEFLAGS= make)
touch $@
# install ruby
$(RUBY_OBJDIR)/.installed: $(RUBY_OBJDIR)/.compiled
- (cd $(RUBY_OBJDIR) && make install)
+ (cd $(RUBY_OBJDIR) && env MAKEFLAGS= make install)
touch $@
#######################################################################
@@ -1002,7 +1011,7 @@ bz2-reset:
rm -f $(BZ2_OBJDIR)/$(f);)
bz2-clean:
- -(cd $(BZ2_SRCDIR) && make distclean)
+ -(cd $(BZ2_SRCDIR) && env MAKEFLAGS= make distclean)
# fetch distfile for bz2
$(DISTDIR)/$(BZ2_DIST):
@@ -1016,12 +1025,12 @@ $(BZ2_OBJDIR)/.retrieved: $(DISTDIR)/$(B
# compile bz2
$(BZ2_OBJDIR)/.compiled: $(BZ2_OBJDIR)/.retrieved
- (cd $(BZ2_SRCDIR) && make CFLAGS="-g $(PROFILE_CFLAGS) -fPIC")
+ (cd $(BZ2_SRCDIR) && env MAKEFLAGS= make CFLAGS="-g $(PROFILE_CFLAGS) -fPIC")
touch $@
# install bz2
$(BZ2_OBJDIR)/.installed: $(BZ2_OBJDIR)/.compiled
- (cd $(BZ2_SRCDIR) && make install PREFIX=$(PREFIX)/bz2)
+ (cd $(BZ2_SRCDIR) && env MAKEFLAGS= make install PREFIX=$(PREFIX)/bz2)
touch $@
@@ -1038,7 +1047,7 @@ python-reset:
rm -f $(PYTHON_OBJDIR)/$(f);)
python-clean:
- -(cd $(PYTHON_OBJDIR) && make distclean)
+ -(cd $(PYTHON_OBJDIR) && env MAKEFLAGS= make distclean)
# fetch distfile for python
$(DISTDIR)/$(PYTHON_DIST):
@@ -1075,7 +1084,8 @@ $(PYTHON_OBJDIR)/.retrieved: $(DISTDIR)/
ifdef PROFILE
PYTHON_PROFILING=--enable-profiling
endif
-$(PYTHON_OBJDIR)/.configured: $(PYTHON_OBJDIR)/.retrieved
+$(PYTHON_OBJDIR)/.configured: $(PYTHON_OBJDIR)/.retrieved \
+ $(BZ2_OBJDIR)/.installed
cd $(PYTHON_OBJDIR) \
&& env CFLAGS="-g $(PROFILE_CFLAGS)" GREP="`which grep`" \
CPPFLAGS="-I$(PREFIX)/bz2/include" \
@@ -1090,12 +1100,12 @@ $(PYTHON_OBJDIR)/.configured: $(PYTHON_O
# compile python
$(PYTHON_OBJDIR)/.compiled: $(PYTHON_OBJDIR)/.configured
- (cd $(PYTHON_OBJDIR) && make)
+ (cd $(PYTHON_OBJDIR) && env MAKEFLAGS= make)
touch $@
# install python
$(PYTHON_OBJDIR)/.installed: $(PYTHON_OBJDIR)/.compiled
- (cd $(PYTHON_OBJDIR) && make install)
+ (cd $(PYTHON_OBJDIR) && env MAKEFLAGS= make install)
touch $@
@@ -1130,7 +1140,7 @@ svn-reset: svn-bindings-reset
rm -f $(SVN_OBJDIR)/$(f);)
svn-clean:
- -(cd $(svn_builddir) && make distclean)
+ -(cd $(svn_builddir) && env MAKEFLAGS= make distclean)
# retrieve svn if not present yet
$(SVN_OBJDIR)/.retrieved:
@@ -1154,6 +1164,7 @@ $(SVN_OBJDIR)/.retrieved:
ifeq ($(BRANCH_MAJOR),1.7)
BDB_FLAG=db.h:$(PREFIX)/bdb/include:$(PREFIX)/bdb/lib:db-$(BDB_MAJOR_VER)
SERF_FLAG=--with-serf="$(PREFIX)/serf"
+SERF_LDFLAG=-Wl,-rpath,$(PREFIX)/serf/lib -Wl,-rpath,$(PREFIX)/bdb/lib
MOD_DAV_SVN=modules/svn-$(WC)/mod_dav_svn.so
MOD_AUTHZ_SVN=modules/svn-$(WC)/mod_authz_svn.so
LIBMAGIC_FLAG=--with-libmagic=$(PREFIX)/libmagic
@@ -1162,6 +1173,7 @@ JAVAHL_CHECK_TARGET=check-javahl
else ifeq ($(BRANCH_MAJOR),1.6)
BDB_FLAG=db.h:$(PREFIX)/bdb/include:$(PREFIX)/bdb/lib:db-$(BDB_MAJOR_VER)
SERF_FLAG=--with-serf="$(PREFIX)/serf"
+SERF_LDFLAG=-Wl,-rpath,$(PREFIX)/serf/lib -Wl,-rpath,$(PREFIX)/bdb/lib
MOD_DAV_SVN=modules/svn-$(WC)/mod_dav_svn.so
MOD_AUTHZ_SVN=modules/svn-$(WC)/mod_authz_svn.so
W_NO_SYSTEM_HEADERS=-Wno-system-headers
@@ -1179,6 +1191,9 @@ JAVAHL_CHECK_TARGET=check-javahl
else # 1.8
BDB_FLAG=db.h:$(PREFIX)/bdb/include:$(PREFIX)/bdb/lib:db-$(BDB_MAJOR_VER)
SERF_FLAG=--with-serf="$(PREFIX)/serf"
+# serf >= 1.3.0 is built with scons and no longer sets up rpath linker flags,
+# so we have to do that ourselves :(
+SERF_LDFLAG=-Wl,-rpath,$(PREFIX)/serf/lib -Wl,-rpath,$(PREFIX)/bdb/lib
MOD_DAV_SVN=modules/svn-$(WC)/mod_dav_svn.so
MOD_AUTHZ_SVN=modules/svn-$(WC)/mod_authz_svn.so
LIBMAGIC_FLAG=--with-libmagic=$(PREFIX)/libmagic
@@ -1201,11 +1216,16 @@ SVN_WITH_HTTPD=--with-apxs="$(PREFIX)/ht
SVN_WITH_SASL=--with-sasl="$(PREFIX)/cyrus-sasl"
endif
-# configure svn
-$(SVN_OBJDIR)/.configured: $(SVN_OBJDIR)/.retrieved $(DISTDIR)/$(JUNIT_DIST)
+$(SVN_OBJDIR)/.configured: $(SVN_OBJDIR)/.retrieved $(DISTDIR)/$(JUNIT_DIST) \
+ $(APR_OBJDIR)/.installed $(APR_UTIL_OBJDIR)/.installed \
+ $(BDB_OBJDIR)/.installed $(SQLITE_OBJDIR)/.installed \
+ $(HTTPD_OBJDIR)/.installed $(CYRUS_SASL_OBJDIR)/.installed \
+ $(LIBMAGIC_OBJDIR)/.installed $(NEON_OBJDIR)/.installed \
+ $(SERF_OBJDIR)/.installed $(SERF_OLD_OBJDIR)/.installed \
+ $(RUBY_OBJDIR)/.installed $(PYTHON_OBJDIR)/.installed
cd $(SVN_SRCDIR) && ./autogen.sh
cd $(svn_builddir) && \
- env LDFLAGS="-L$(PREFIX)/neon/lib -L$(PREFIX)/apr/lib" \
+ env LDFLAGS="-L$(PREFIX)/neon/lib -L$(PREFIX)/apr/lib $(SERF_LDFLAG)" \
LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):$$LD_LIBRARY_PATH" \
GREP="`which grep`" \
PATH=$(PREFIX)/ruby/bin:$(PREFIX)/python/bin:$$PATH \
@@ -1232,13 +1252,13 @@ $(SVN_OBJDIR)/.configured: $(SVN_OBJDIR)
# compile svn
$(SVN_OBJDIR)/.compiled: $(SVN_OBJDIR)/.configured
cd $(svn_builddir) \
- && make EXTRA_CFLAGS="$(PROFILE_CFLAGS) $(W_NO_SYSTEM_HEADERS)"
+ && env MAKEFLAGS= make EXTRA_CFLAGS="$(PROFILE_CFLAGS) $(W_NO_SYSTEM_HEADERS)"
touch $@
# install svn
$(SVN_OBJDIR)/.installed: $(SVN_OBJDIR)/.compiled
cd $(svn_builddir) \
- && make install
+ && env MAKEFLAGS= make install
touch $@
# SWIG 1.x and 2.x are not compatible. If SWIG 2.x is used to generated .swg
@@ -1248,44 +1268,44 @@ $(SVN_OBJDIR)/.installed: $(SVN_OBJDIR)/
# by the same version of SWIG.
$(SVN_OBJDIR)/.pre-generated-swig-cleaned:
-cd $(svn_builddir) \
- && make clean-swig
+ && env MAKEFLAGS= make clean-swig
touch $@
$(SVN_OBJDIR)/.bindings-compiled: $(SVN_OBJDIR)/.installed $(SVN_OBJDIR)/.pre-generated-swig-cleaned
cd $(svn_builddir) \
&& env LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) \
- make swig-py
+ env MAKEFLAGS= make swig-py
cd $(svn_builddir) && \
env PATH=$(PREFIX)/ruby/bin:$$PATH \
- LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) make swig-rb
+ LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) env MAKEFLAGS= make swig-rb
if [ $(ENABLE_PERL_BINDINGS) = yes ]; then \
cd $(svn_builddir) \
&& env LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) \
- make swig-pl; \
+ env MAKEFLAGS= make swig-pl; \
fi
if [ $(ENABLE_JAVA_BINDINGS) = yes ]; then \
cd $(svn_builddir) \
- && make javahl; \
+ && env MAKEFLAGS= make javahl; \
fi
touch $@
$(SVN_OBJDIR)/.bindings-installed: $(SVN_OBJDIR)/.bindings-compiled
cd $(svn_builddir) \
&& env LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) \
- make install-swig-py
+ env MAKEFLAGS= make install-swig-py
cd $(svn_builddir) && \
env PATH=$(PREFIX)/ruby/bin:$$PATH \
- LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) make install-swig-rb
+ LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) env MAKEFLAGS= make install-swig-rb
if [ $(ENABLE_PERL_BINDINGS) = yes ]; then \
cd $(svn_builddir) \
- && make install-swig-pl-lib; \
+ && env MAKEFLAGS= make install-swig-pl-lib; \
cd subversion/bindings/swig/perl/native \
&& perl Makefile.PL PREFIX="$(SVN_PREFIX)" \
- && make install; \
+ && env MAKEFLAGS= make install; \
fi
if [ $(ENABLE_JAVA_BINDINGS) = yes ]; then \
cd $(svn_builddir) \
- && make install-javahl; \
+ && env MAKEFLAGS= make install-javahl; \
fi
touch $@
@@ -1423,7 +1443,7 @@ define do_check
echo "Begin test: $(subst svn-check-,,$@) x $$fs"; \
test -d "$(RAMDISK)/tmp" && export TMPDIR="$(RAMDISK)/tmp"; \
env LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) $(LIB_PTHREAD_HACK) \
- make check PARALLEL=$(PARALLEL) CLEANUP=$(CLEANUP) \
+ env MAKEFLAGS= make check PARALLEL=$(PARALLEL) CLEANUP=$(CLEANUP) \
EXCLUSIVE_WC_LOCKS=$(EXCLUSIVE_WC_LOCKS) $1 FS_TYPE=$$fs; \
for log in tests.log fails.log; do \
test -f $$log && mv -f $$log $$log.$@-$$fs; \
@@ -1480,14 +1500,14 @@ svn-check-swig-pl:
(cd $(svn_builddir) && \
env LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) \
$(LIB_PTHREAD_HACK) \
- make check-swig-pl 2>&1) | \
+ env MAKEFLAGS= make check-swig-pl 2>&1) | \
tee $(svn_builddir)/tests.log.bindings.pl; \
fi
svn-check-swig-py:
-(cd $(svn_builddir) && \
env LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) \
- make check-swig-py 2>&1) | \
+ env MAKEFLAGS= make check-swig-py 2>&1) | \
tee $(svn_builddir)/tests.log.bindings.py
# We add the svn prefix to PATH here because the ruby tests
@@ -1498,14 +1518,14 @@ svn-check-swig-rb:
LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) \
PATH=$(SVN_PREFIX)/bin:$$PATH \
$(LIB_PTHREAD_HACK) \
- make check-swig-rb 2>&1) | \
+ env MAKEFLAGS= make check-swig-rb 2>&1) | \
tee $(svn_builddir)/tests.log.bindings.rb
svn-check-javahl:
-if [ $(ENABLE_JAVA_BINDINGS) = yes ]; then \
(cd $(svn_builddir) && \
env LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) \
- make $(JAVAHL_CHECK_TARGET) 2>&1) | \
+ env MAKEFLAGS= make $(JAVAHL_CHECK_TARGET) 2>&1) | \
tee $(svn_builddir)/tests.log.bindings.javahl; \
fi
Modified: subversion/branches/verify-keep-going/tools/dist/backport.pl
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/tools/dist/backport.pl?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/tools/dist/backport.pl (original)
+++ subversion/branches/verify-keep-going/tools/dist/backport.pl Wed Nov 27 11:52:35 2013
@@ -22,13 +22,17 @@ use feature qw/switch say/;
use Digest ();
use Term::ReadKey qw/ReadMode ReadKey/;
+use File::Basename qw/basename dirname/;
use File::Copy qw/copy move/;
use File::Temp qw/tempfile/;
-use POSIX qw/ctermid/;
+use POSIX qw/ctermid strftime/;
+use Text::Wrap qw/wrap/;
+use Tie::File ();
############### Start of reading values from environment ###############
# Programs we use.
+my $SVNAUTH = $ENV{SVNAUTH} // 'svnauth'; # optional dependency
my $SVN = $ENV{SVN} || 'svn'; # passed unquoted to sh
my $SHELL = $ENV{SHELL} // '/bin/sh';
my $VIM = 'vim';
@@ -39,7 +43,7 @@ my $PAGER = $ENV{PAGER} // 'less -F' //
# svn-role: YES=1 MAY_COMMIT=1
# conflicts-bot: YES=1 MAY_COMMIT=0
# interactive: YES=0 MAY_COMMIT=0 (default)
-my $YES = ($ENV{YES} // 0) ? 1 : 0; # batch mode: eliminate prompts, add sleeps
+my $YES = exists $ENV{YES}; # batch mode: eliminate prompts, add sleeps
my $MAY_COMMIT = 'false';
$MAY_COMMIT = 'true' if ($ENV{MAY_COMMIT} // "false") =~ /^(1|yes|true)$/i;
@@ -48,14 +52,15 @@ my $VERBOSE = 0;
my $DEBUG = (exists $ENV{DEBUG}) ? 'true' : 'false'; # 'set -x', etc
# Username for entering votes.
+my $SVN_A_O_REALM = '<https://svn.apache.org:443> ASF Committers';
my ($AVAILID) = $ENV{AVAILID} // do {
- my $SVN_A_O_REALM = 'd3c8a345b14f6a1b42251aef8027ab57';
- open USERNAME, '<', "$ENV{HOME}/.subversion/auth/svn.simple/$SVN_A_O_REALM";
- 1 until <USERNAME> eq "username\n";
- <USERNAME>;
- local $_ = <USERNAME>;
- chomp;
- $_
+ local $_ = `$SVNAUTH list 2>/dev/null`;
+ ($? == 0 && /Auth.*realm: \Q$SVN_A_O_REALM\E\nUsername: (.*)/) ? $1 : undef
+} // do {
+ local $/; # slurp mode
+ my $filename = Digest->new("MD5")->add($SVN_A_O_REALM)->hexdigest;
+ `cat $ENV{HOME}/.subversion/auth/svn.simple/$filename`
+ =~ /K 8\nusername\nV \d+\n(.*)/ and $1 or undef
}
// warn "Username for commits (of votes/merges) not found";
@@ -81,13 +86,31 @@ $SVNq = "$SVN -q ";
$SVNq =~ s/-q// if $DEBUG eq 'true';
-sub usage {
- my $basename = $0;
- $basename =~ s#.*/##;
+sub backport_usage {
+ my $basename = basename $0;
print <<EOF;
-backport.pl: a tool for reviewing and merging STATUS entries. Run this with
-CWD being the root of the stable branch (e.g., 1.8.x). The ./STATUS file
-should be at HEAD.
+backport.pl: a tool for reviewing, merging, and voting on STATUS entries.
+
+Normally, invoke this with CWD being the root of the stable branch (e.g.,
+1.8.x):
+
+ Usage: test -e \$d/STATUS && cd \$d && \\
+ backport.pl [PATTERN]
+ (where \$d is a working copy of branches/1.8.x)
+
+Alternatively, invoke this via a symlink named "b" placed at the same directory
+as the STATUS file, in which case the CWD doesn't matter (the script will cd):
+
+ Usage: ln -s /path/to/backport.pl \$d/b && \\
+ \$d/b [PATTERN]
+ (where \$d is a working copy of branches/1.8.x)
+
+In either case, the ./STATUS file should be at HEAD. If it has local mods,
+they will be preserved through 'revert' operations but included in 'commit'
+operations.
+
+If PATTERN is provided, only entries which match PATTERN are considered. The
+sense of "match" is either substring (fgrep) or Perl regexp (with /msi).
In interactive mode (the default), you will be prompted once per STATUS entry.
At a prompt, you have the following options:
@@ -116,29 +139,66 @@ y: Open a shell.
d: View a diff.
N: Move to the next entry.
-There is also a batch mode: when \$YES and \$MAY_COMMIT are defined to '1' i
+There is also a batch mode (normally used only by cron jobs and buildbot tasks,
+rather than interactively): when \$YES and \$MAY_COMMIT are defined to '1' in
the environment, this script will iterate the "Approved:" section, and merge
and commit each entry therein. If only \$YES is defined, the script will
merge every nomination (including unapproved and vetoed ones), and complain
-to stderr if it notices any conflicts. These mode are normally used by the
-'svn-role' cron job and/or buildbot, not by human users.
+to stderr if it notices any conflicts.
The 'svn' binary defined by the environment variable \$SVN, or otherwise the
'svn' found in \$PATH, will be used to manage the working copy.
EOF
}
+sub nominate_usage {
+ my $basename = basename $0;
+ print <<EOF;
+nominate.pl: a tool for adding entries to STATUS.
+
+Usage: $0 "foo r42 bar r43 qux 45." "\$Some_justification"
+
+Will add:
+ * r42, r43, r45
+ (log message of r42)
+ Justification:
+ \$Some_justification
+ Votes:
+ +1: $AVAILID
+to STATUS. Backport branches are detected automatically.
+
+The STATUS file in the current directory is used (unless argv[0] is "n", in
+which case the STATUS file in the directory of argv[0] is used; the intent
+is to create a symlink named "n" in the branch wc root).
+
+EOF
+# TODO: Optionally add a "Notes" section.
+# TODO: Look for backport branches named after issues.
+# TODO: Do a dry-run merge on added entries.
+# TODO: Do a dry-run merge on interactively-edited entries in backport.pl
+}
+
sub digest_string {
Digest->new("MD5")->add(@_)->hexdigest
}
+sub digest_entry($) {
+ # Canonicalize the number of trailing EOLs to two. This matters when there's
+ # on empty line after the last entry in Approved, for example.
+ local $_ = shift;
+ s/\n*\z// and $_ .= "\n\n";
+ digest_string($_)
+}
+
sub prompt {
print $_[0]; shift;
my %args = @_;
my $getchar = sub {
+ my $answer;
ReadMode 'cbreak';
- my $answer = (ReadKey 0);
+ eval { $answer = (ReadKey 0) };
ReadMode 'normal';
+ die $@ if $@;
print $answer;
return $answer;
};
@@ -160,29 +220,38 @@ sub merge {
my ($logmsg_fh, $logmsg_filename) = tempfile();
my ($mergeargs, $pattern);
- my $backupfile = "backport_pl.$$.tmp";
+ # Include the time so it's easier to find the interesting backups.
+ my $backupfile = strftime "backport_pl.%Y%m%d-%H%M%S.$$.tmp", localtime;
+ die if -s $backupfile;
if ($entry{branch}) {
- # NOTE: This doesn't escape the branch into the pattern.
- $pattern = sprintf '\V\(%s branch(es)?\|branches\/%s\|Branch\(es\)\?: \*\n\? \*%s\)', $entry{branch}, $entry{branch}, $entry{branch};
+ my $vim_escaped_branch =
+ join "",
+ map { sprintf '\[%s%s]', $_, ($_ x ($_ eq '\\')) }
+ split //,
+ $entry{branch};
+ $pattern = sprintf '\VBranch: \*\n\? \*\(\.\*\/branches\/\)\?%s',
+ $vim_escaped_branch;
if ($SVNvsn >= 1_008_000) {
$mergeargs = "$BRANCHES/$entry{branch}";
- say $logmsg_fh "Merge the $entry{header}:";
+ say $logmsg_fh "Merge $entry{header}:";
} else {
$mergeargs = "--reintegrate $BRANCHES/$entry{branch}";
- say $logmsg_fh "Reintegrate the $entry{header}:";
+ say $logmsg_fh "Reintegrate $entry{header}:";
}
say $logmsg_fh "";
} elsif (@{$entry{revisions}}) {
$pattern = '^ [*] \V' . 'r' . $entry{revisions}->[0];
- $mergeargs = join " ", (map { "-c$_" } @{$entry{revisions}}), '^/subversion/trunk';
- if (@{$entry{revisions}} > 1) {
- say $logmsg_fh "Merge the $entry{header} from trunk:";
- say $logmsg_fh "";
- } else {
- say $logmsg_fh "Merge r$entry{revisions}->[0] from trunk:";
- say $logmsg_fh "";
- }
+ $mergeargs = join " ",
+ ($entry{accept} ? "--accept=$entry{accept}" : ()),
+ (map { "-c$_" } @{$entry{revisions}}),
+ '--',
+ '^/subversion/trunk';
+ say $logmsg_fh
+ "Merge $entry{header} from trunk",
+ $entry{accept} ? ", with --accept=$entry{accept}" : "",
+ ":";
+ say $logmsg_fh "";
} else {
die "Don't know how to call $entry{header}";
}
@@ -219,7 +288,7 @@ fi
if $MAY_COMMIT; then
$VIM -e -s -n -N -i NONE -u NONE -c '/$pattern/normal! dap' -c wq $STATUS
$SVNq commit -F $logmsg_filename
-elif test 1 -ne $YES; then
+elif test -z "\$YES"; then
echo "Would have committed:"
echo '[[['
$SVN status -q
@@ -236,7 +305,7 @@ if $MAY_COMMIT; then
if [ -n "\$YES" ]; then sleep 15; fi
$SVNq rm $BRANCHES/$entry{branch} -m "Remove the '$entry{branch}' branch, $reintegrated_word in r\$reinteg_rev."
if [ -n "\$YES" ]; then sleep 1; fi
-elif test 1 -ne $YES; then
+elif test -z "\$YES"; then
echo "Would remove $reintegrated_word '$entry{branch}' branch"
fi
EOF
@@ -244,7 +313,7 @@ EOF
open SHELL, '|-', qw#/bin/sh# or die "$! (in '$entry{header}')";
print SHELL $script;
close SHELL or warn "$0: sh($?): $! (in '$entry{header}')";
- $ERRORS{$entry{id}} = "sh($?): $!" if $?;
+ $ERRORS{$entry{id}} = [\%entry, "sh($?): $!"] if $?;
if (-z $backupfile) {
unlink $backupfile;
@@ -257,17 +326,25 @@ EOF
sub sanitize_branch {
local $_ = shift;
- s#.*/##;
+ my $branches_re = quotemeta $BRANCHES;
+ s#.*$branches_re/##;
s/^\s*//;
s/\s*$//;
return $_;
}
+sub logsummarysummary {
+ my $entry = shift;
+ join "",
+ $entry->{logsummary}->[0], ('[...]' x (0 < $#{$entry->{logsummary}}))
+}
+
# TODO: may need to parse other headers too?
sub parse_entry {
my $raw = shift;
my @lines = @_;
my $depends;
+ my $accept;
my (@revisions, @logsummary, $branch, @votes);
# @lines = @_;
@@ -277,6 +354,7 @@ sub parse_entry {
# revisions
$branch = sanitize_branch $1
+ and shift
if $_[0] =~ /^(\S*) branch$/ or $_[0] =~ m#branches/(\S+)#;
while ($_[0] =~ /^r/) {
my $sawrevnum = 0;
@@ -290,41 +368,71 @@ sub parse_entry {
# summary
do {
push @logsummary, shift
- } until $_[0] =~ /^\s*\w+:/ or not defined $_[0];
+ } until $_[0] =~ /^\s*[][\w]+:/ or not defined $_[0];
# votes
unshift @votes, pop until $_[-1] =~ /^\s*Votes:/ or not defined $_[-1];
pop;
- # depends
- # TODO: parse the value of this.
- $depends = grep /^Depends:/, @_;
-
- # branch
+ # depends, branch, notes
+ # Ignored headers: Changes[*]
while (@_) {
- shift and next unless $_[0] =~ s/^\s*Branch(es)?:\s*//;
- $branch = sanitize_branch (shift || shift || die "Branch header found without value");
+ given (shift) {
+ when (/^Depends:/) {
+ $depends++;
+ }
+ if (s/^Branch:\s*//) {
+ $branch = sanitize_branch ($_ || shift || die "Branch header found without value");
+ }
+ if (s/^Notes:\s*//) {
+ my $notes = $_;
+ $notes .= shift while @_ and $_[0] !~ /^\w/;
+ my %accepts = map { $_ => 1 } ($notes =~ /--accept[ =]([a-z-]+)/g);
+ given (scalar keys %accepts) {
+ when (0) { }
+ when (1) { $accept = [keys %accepts]->[0]; }
+ default {
+ warn "Too many --accept values at '",
+ logsummarysummary({ logsummary => [@logsummary] }),
+ "'";
+ }
+ }
+ }
+ }
}
# Compute a header.
my ($header, $id);
- $header = "r$revisions[0] group" if @revisions;
- $id = "r$revisions[0]" if @revisions;
- $header = "$branch branch" if $branch;
- $id = $branch if $branch;
- warn "No header for [@lines]" unless $header;
+ if ($branch) {
+ $header = "the $branch branch";
+ $id = $branch;
+ } elsif (@revisions == 1) {
+ $header = "r$revisions[0]";
+ $id = "r$revisions[0]";
+ } elsif (@revisions) {
+ $header = "the r$revisions[0] group";
+ $id = "r$revisions[0]";
+ } else {
+ die "Entry '$raw' has neither revisions nor branch";
+ }
+ my $header_start = ($header =~ /^the/ ? ucfirst($header) : $header);
+
+ warn "Entry has both branch '$branch' and --accept=$accept specified\n"
+ if $branch and $accept;
return (
revisions => [@revisions],
logsummary => [@logsummary],
branch => $branch,
header => $header,
+ header_start => $header_start,
depends => $depends,
id => $id,
votes => [@votes],
entry => [@lines],
+ accept => $accept,
raw => $raw,
- digest => digest_string($raw),
+ digest => digest_entry($raw),
);
}
@@ -349,9 +457,10 @@ sub edit_string {
sub vote {
my ($state, $approved, $votes) = @_;
+ # TODO: use votesarray instead of votescheck
my (%approvedcheck, %votescheck);
my $raw_approved = "";
- my @votes;
+ my @votesarray;
return unless %$approved or %$votes;
my $had_empty_line;
@@ -361,21 +470,39 @@ sub vote {
open VOTES, ">", "$STATUS.$$.tmp";
while (<STATUS>) {
$had_empty_line = /\n\n\z/;
- my $key = digest_string $_;
+ my $key = digest_entry $_;
$approvedcheck{$key}++ if exists $approved->{$key};
$votescheck{$key}++ if exists $votes->{$key};
+ unless (exists $votes->{$key} or exists $approved->{$key}) {
+ print VOTES;
+ next;
+ }
+
unless (exists $votes->{$key}) {
- (exists $approved->{$key}) ? ($raw_approved .= $_) : (print VOTES);
+ push @votesarray, {
+ entry => $approved->{$key},
+ approval => 1,
+ digest => $key,
+ };
+ $raw_approved .= $_;
next;
}
+ # We have a vote, and potentially an approval.
+
my ($vote, $entry) = @{$votes->{$key}};
- push @votes, [$vote, $entry, undef]; # ->[2] later set to $digest
+ push @votesarray, {
+ entry => $entry,
+ vote => $vote,
+ approval => (exists $approved->{$key}),
+ digest => $key,
+ };
if ($vote eq 'edit') {
local $_ = $entry->{raw};
+ $votesarray[-1]->{digest} = digest_entry $_;
(exists $approved->{$key}) ? ($raw_approved .= $_) : (print VOTES);
next;
}
@@ -384,68 +511,86 @@ sub vote {
or s/(.*\w.*?\n)/"$1 $vote: $AVAILID\n"/se;
$_ = edit_string $_, $entry->{header}, trailing_eol => 2
if $vote ne '+1';
- $votes[$#votes]->[2] = digest_string $_;
+ $votesarray[-1]->{digest} = digest_entry $_;
(exists $approved->{$key}) ? ($raw_approved .= $_) : (print VOTES);
}
close STATUS;
print VOTES "\n" if $raw_approved and !$had_empty_line;
print VOTES $raw_approved;
close VOTES;
- die "Some vote chunks weren't found: ",
+ warn "Some vote chunks weren't found: ",
+ join ',',
map $votes->{$_}->[1]->{id},
grep { !$votescheck{$_} } keys %$votes
if scalar(keys %$votes) != scalar(keys %votescheck);
- die "Some approval chunks weren't found: ",
+ warn "Some approval chunks weren't found: ",
+ join ',',
map $approved->{$_}->{id},
grep { !$approvedcheck{$_} } keys %$approved
if scalar(keys %$approved) != scalar(keys %approvedcheck);
+ prompt "Press the 'any' key to continue...\n", dontprint => 1
+ if scalar(keys %$approved) != scalar(keys %approvedcheck)
+ or scalar(keys %$votes) != scalar(keys %votescheck);
move "$STATUS.$$.tmp", $STATUS;
my $logmsg = do {
- my %allkeys = map { $_ => 1 } keys(%$votes), keys(%$approved);
my @sentences = map {
- exists $votes->{$_}
+ my $words_vote = ", approving" x $_->{approval};
+ my $words_edit = " and approve" x $_->{approval};
+ exists $_->{vote}
? (
- ( $votes->{$_}->[0] eq 'edit'
- ? "Edit the $votes->{$_}->[1]->{id} entry"
- : "Vote $votes->{$_}->[0] on the $votes->{$_}->[1]->{header}"
+ ( $_->{vote} eq 'edit'
+ ? "Edit$words_edit the $_->{entry}->{id} entry"
+ : "Vote $_->{vote} on $_->{entry}->{header}$words_vote"
)
- . (exists $approved->{$_} ? ", approving" : "")
. "."
)
: # exists only in $approved
- "Approve the $approved->{$_}->{header}."
- } keys %allkeys;
+ "Approve $_->{entry}->{header}."
+ } @votesarray;
(@sentences == 1)
? $sentences[0]
: "* STATUS:\n" . join "", map " $_\n", @sentences;
};
system "$SVN diff -- $STATUS";
- say "Voting '$_->[0]' on $_->[1]->{id}." for @votes;
- # say $logmsg;
+ printf "[[[\n%s%s]]]\n", $logmsg, ("\n" x ($logmsg !~ /\n\z/));
if (prompt "Commit these votes? ") {
my ($logmsg_fh, $logmsg_filename) = tempfile();
print $logmsg_fh $logmsg;
close $logmsg_fh;
- warn "Tempfile name '$logmsg_filename' not shell-safe; "
- ."refraining from commit.\n"
+ warn("Tempfile name '$logmsg_filename' not shell-safe; "
+ ."refraining from commit.\n") and return
unless $logmsg_filename =~ /^([A-Z0-9._-]|\x2f)+$/i;
system("$SVN commit -F $logmsg_filename -- $STATUS") == 0
or warn("Committing the votes failed($?): $!") and return;
unlink $logmsg_filename;
- $state->{$approved->{$_}->{digest}}++ for keys %$approved;
- $state->{$_->[2]}++ for @votes;
+ # Add to state votes that aren't '+0' or 'edit'
+ $state->{$_->{digest}}++ for grep
+ +{ qw/-1 t -0 t +1 t/ }->{$_->{vote}},
+ @votesarray;
}
}
+sub check_local_mods_to_STATUS {
+ if (`$SVN status -q $STATUS`) {
+ die "Local mods to STATUS file $STATUS" if $YES;
+ warn "Local mods to STATUS file $STATUS";
+ system "$SVN diff -- $STATUS";
+ prompt "Press the 'any' key to continue...\n", dontprint => 1;
+ return 1;
+ }
+ return 0;
+}
+
sub revert {
copy $STATUS, "$STATUS.$$.tmp";
system "$SVN revert -q $STATUS";
system "$SVN revert -R ./" . ($YES && $MAY_COMMIT ne 'true'
? " -q" : "");
move "$STATUS.$$.tmp", $STATUS;
+ $MERGED_SOMETHING = 0;
}
sub maybe_revert {
@@ -456,14 +601,26 @@ sub maybe_revert {
(@_ ? exit : return);
}
+sub signal_handler {
+ my $sig = shift;
+
+ # Clean up after prompt()
+ ReadMode 'normal';
+
+ # Fall back to default action
+ delete $SIG{$sig};
+ kill $sig, $$;
+}
+
sub warning_summary {
return unless %ERRORS;
warn "Warning summary\n";
warn "===============\n";
warn "\n";
- for my $header (keys %ERRORS) {
- warn "$header: $ERRORS{$header}\n";
+ for my $id (keys %ERRORS) {
+ my $title = logsummarysummary $ERRORS{$id}->[0];
+ warn "$id ($title): $ERRORS{$id}->[1]\n";
}
}
@@ -505,9 +662,13 @@ sub handle_entry {
my $votes = shift;
my $state = shift;
my $raw = shift;
+ my $skip = shift;
my %entry = parse_entry $raw, @_;
my @vetoes = grep { /^ -1:/ } @{$entry{votes}};
+ my $match = defined($skip) ? ($raw =~ /\Q$skip\E/ or $raw =~ /$skip/msi) : 0
+ unless $YES;
+
if ($YES) {
# Run a merge if:
unless (@vetoes) {
@@ -519,34 +680,46 @@ sub handle_entry {
merge %entry;
my $output = `$SVN status`;
- my (@conflicts) = ($output =~ m#^(?:C|.C|...C).*/(.*)#mg);
+ my (@conflicts) = ($output =~ m#^(?:C...|.C..|...C)...\s(.*)#mg);
if (@conflicts and !$entry{depends}) {
- $ERRORS{$entry{id}} //= "Conflicts merging the $entry{header}: "
- . (join ', ', @conflicts);
- say STDERR "Conflicts merging the $entry{header}!";
+ $ERRORS{$entry{id}} //= [\%entry,
+ sprintf "Conflicts on %s%s%s",
+ '[' x !!$#conflicts,
+ (join ', ',
+ map { basename $_ }
+ @conflicts),
+ ']' x !!$#conflicts,
+ ];
+ say STDERR "Conflicts merging $entry{header}!";
say STDERR "";
say STDERR $output;
+ system "$SVN diff -- @conflicts";
} elsif (!@conflicts and $entry{depends}) {
- warn "No conflicts merging the $entry{header}, but conflicts were "
+ # Not a warning since svn-role may commit the dependency without
+ # also committing the dependent in the same pass.
+ print "No conflicts merging $entry{header}, but conflicts were "
."expected ('Depends:' header set)\n";
} elsif (@conflicts) {
- say "Conflicts found merging $entry{id}, as expected.";
+ say "Conflicts found merging $entry{header}, as expected.";
}
revert;
}
}
- } elsif ($state->{$entry{digest}}) {
+ } elsif (defined($skip) ? not $match : $state->{$entry{digest}}) {
print "\n\n";
- say "Skipping the $entry{header} (remove $STATEFILE to reset):";
- say $entry{logsummary}->[0], ('[...]' x (0 < $#{$entry{logsummary}}));
- } else {
+ my $reason = defined($skip) ? "doesn't match pattern"
+ : "remove $STATEFILE to reset";
+ say "Skipping $entry{header} ($reason):";
+ say logsummarysummary \%entry;
+ } elsif ($match or not defined $skip) {
# This loop is just a hack because 'goto' panics. The goto should be where
# the "next PROMPT;" is; there's a "last;" at the end of the loop body.
PROMPT: while (1) {
say "";
- say "\n>>> The $entry{header}:";
+ say "\n>>> $entry{header_start}:";
say join ", ", map { "r$_" } @{$entry{revisions}} if @{$entry{revisions}};
say "$BRANCHES/$entry{branch}" if $entry{branch};
+ say "--accept=$entry{accept}" if $entry{accept};
say "";
say for @{$entry{logsummary}};
say "";
@@ -572,6 +745,12 @@ sub handle_entry {
or warn "diff failed ($?): $!";
next;
}
+ when (/^N/i) {
+ # fall through.
+ }
+ default {
+ next;
+ }
}
revert;
next PROMPT;
@@ -580,7 +759,7 @@ sub handle_entry {
}
when (/^l/i) {
if ($entry{branch}) {
- system "$SVN log --stop-on-copy -v -r 0:HEAD -- "
+ system "$SVN log --stop-on-copy -v -g -r 0:HEAD -- "
."$BRANCHES/$entry{branch} "
."| $PAGER";
} elsif (@{$entry{revisions}}) {
@@ -602,6 +781,7 @@ sub handle_entry {
when (/^([+-][01])\s*$/i) {
$votes->{$key} = [$1, \%entry];
say "Your '$1' vote has been recorded." if $VERBOSE;
+ last PROMPT;
}
when (/^e/i) {
my $original = $entry{raw};
@@ -609,9 +789,11 @@ sub handle_entry {
trailing_eol => 2;
$votes->{$key} = ['edit', \%entry] # marker for the 2nd pass
if $original ne $entry{raw};
+ last PROMPT;
}
when (/^N/i) {
$state->{$entry{digest}}++;
+ last PROMPT;
}
when (/^\x20/) {
last PROMPT; # Fall off the end of the given/when block.
@@ -623,6 +805,9 @@ sub handle_entry {
}
last; } # QUESTION
last; } # PROMPT
+ } else {
+ # NOTREACHED
+ die "Unreachable code reached.";
}
# TODO: merge() changes ./STATUS, which we're reading below, but
@@ -632,14 +817,17 @@ sub handle_entry {
}
-sub main {
+sub backport_main {
my %approved;
my %votes;
my $state = read_state;
- usage, exit 0 if @ARGV;
+ backport_usage, exit 0 if @ARGV > ($YES ? 0 : 1) or grep /^--help$/, @ARGV;
+ backport_usage, exit 0 if grep /^(?:-h|-\?|--help|help)$/, @ARGV;
+ my $skip = shift; # maybe undef
+ # assert not defined $skip if $YES;
- open STATUS, "<", $STATUS or (usage, exit 1);
+ open STATUS, "<", $STATUS or (backport_usage, exit 1);
# Because we use the ':normal' command in Vim...
die "A vim with the +ex_extra feature is required for \$MAY_COMMIT mode"
@@ -652,12 +840,7 @@ sub main {
system("$SVN info $STATUS >/dev/null") == 0
or die "$0: svn error; point \$SVN to an appropriate binary";
- if (`$SVN status -q $STATUS`) {
- die "Local mods to STATUS file $STATUS" if $YES;
- warn "Local mods to STATUS file $STATUS";
- system "$SVN diff -- $STATUS";
- prompt "Press the 'any' key to continue...\n", dontprint => 1;
- }
+ check_local_mods_to_STATUS;
# Skip most of the file
$/ = ""; # paragraph mode
@@ -666,6 +849,7 @@ sub main {
}
$SIG{INT} = \&maybe_revert unless $YES;
+ $SIG{TERM} = \&signal_handler unless $YES;
my $in_approved = 0;
while (<STATUS>) {
@@ -690,7 +874,8 @@ sub main {
when (/^ \*/) {
warn "Too many bullets in $lines[0]" and next
if grep /^ \*/, @lines[1..$#lines];
- handle_entry $in_approved, \%approved, \%votes, $state, $lines, @lines;
+ handle_entry $in_approved, \%approved, \%votes, $state, $lines, $skip,
+ @lines;
}
default {
warn "Unknown entry '$lines[0]'";
@@ -701,4 +886,100 @@ sub main {
exit_stage_left $state, \%approved, \%votes;
}
-&main
+sub nominate_main {
+ my $had_local_mods;
+
+ local $Text::Wrap::columns = 79;
+
+ $had_local_mods = check_local_mods_to_STATUS;
+
+ # Argument parsing.
+ nominate_usage, exit 0 if @ARGV != 2;
+ my (@revnums) = (+shift) =~ /(\d+)/g;
+ my $justification = shift;
+
+ @revnums = sort { $a <=> $b } keys %{{ map { $_ => 1 } @revnums }};
+ die "No revision numbers specified" unless @revnums;
+
+ # Determine whether a backport branch exists
+ my ($URL) = `$SVN info` =~ /^URL: (.*)$/m;
+ die "Can't retrieve URL of cwd" unless $URL;
+
+ die if $URL !~ m%^[A-Za-z0-9:_.+/][A-Za-z0-9:_.+/-]*$%;
+ system "$SVN info -- $URL-r$revnums[0] 2>/dev/null";
+ my $branch = ($? == 0) ? basename("$URL-r$revnums[0]") : undef;
+
+ # Construct entry.
+ my $logmsg = `$SVN propget --revprop -r $revnums[0] --strict svn:log '^/'`;
+ die "Can't fetch log message of r$revnums[0]: $!" unless $logmsg;
+
+ unless ($logmsg =~ s/^(.*?)\n\n.*/$1/s) {
+ # "* file\n (symbol): Log message."
+
+ # Strip before and after the first symbol's log message.
+ $logmsg =~ s/^.*?: //s;
+ $logmsg =~ s/^ \x28.*//ms;
+
+ # Undo line wrapping. (We'll re-do it later.)
+ $logmsg =~ s/\s*\n\s+/ /g;
+ }
+
+ my @lines;
+ warn "Wrapping [$logmsg]\n";
+ push @lines, wrap " * ", ' 'x3, join ', ', map "r$_", @revnums;
+ push @lines, wrap ' 'x3, ' 'x3, split /\n/, $logmsg;
+ push @lines, " Justification:";
+ push @lines, wrap ' 'x5, ' 'x5, $justification;
+ push @lines, " Branch: $branch" if defined $branch;
+ push @lines, " Votes:";
+ push @lines, " +1: $AVAILID";
+ push @lines, "";
+ my $raw = join "", map "$_\n", @lines;
+
+ # Open the file in line-mode (not paragraph-mode).
+ my @STATUS;
+ tie @STATUS, "Tie::File", $STATUS, recsep => "\n";
+ my ($index) = grep { $STATUS[$_] =~ /^Veto/ } (0..$#STATUS);
+ die "Couldn't find where to add an entry" unless $index;
+
+ # Add an empty line if needed.
+ if ($STATUS[$index-1] =~ /\S/) {
+ splice @STATUS, $index, 0, "";
+ $index++;
+ }
+
+ # Add the entry.
+ splice @STATUS, $index, 0, @lines;
+
+ # Save.
+ untie @STATUS;
+
+ # Done!
+ system "$SVN diff -- $STATUS";
+ if (prompt "Commit this nomination? ") {
+ system "$SVN commit -m 'Nominate r$revnums[0].' -- $STATUS";
+ exit $?;
+ }
+ elsif (!$had_local_mods or prompt "Revert STATUS (destroying local mods)? ") {
+ # TODO: we could be smarter and just un-splice the lines we'd added.
+ system "$SVN revert -- $STATUS";
+ exit $?;
+ }
+
+ exit 0;
+}
+
+# Dispatch to the appropriate main().
+given (basename($0)) {
+ when (/^b$|backport/) {
+ chdir dirname $0 or die "Can't chdir: $!" if /^b$/;
+ &backport_main(@ARGV);
+ }
+ when (/^n$|nominate/) {
+ chdir dirname $0 or die "Can't chdir: $!" if /^n$/;
+ &nominate_main(@ARGV);
+ }
+ default {
+ &backport_main(@ARGV);
+ }
+}
Modified: subversion/branches/verify-keep-going/tools/dist/release.py
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/tools/dist/release.py?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/tools/dist/release.py (original)
+++ subversion/branches/verify-keep-going/tools/dist/release.py Wed Nov 27 11:52:35 2013
@@ -87,7 +87,12 @@ tool_versions = {
'trunk' : {
'autoconf' : '2.69',
'libtool' : '2.4.2',
- 'swig' : '2.0.9',
+ 'swig' : '2.0.11',
+ },
+ '1.9' : {
+ 'autoconf' : '2.69',
+ 'libtool' : '2.4.2',
+ 'swig' : '2.0.11'
},
'1.8' : {
'autoconf' : '2.69',
Modified: subversion/branches/verify-keep-going/tools/dist/templates/download.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/tools/dist/templates/download.ezt?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/tools/dist/templates/download.ezt (original)
+++ subversion/branches/verify-keep-going/tools/dist/templates/download.ezt Wed Nov 27 11:52:35 2013
@@ -1,4 +1,4 @@
-<p style="font-size: 150%; text-align: center;">Subversion [version]</p>
+<p style="font-size: 150%; text-align: center;">Apache Subversion [version]</p>
<table class="centered">
<tr>
<th>File</th>
Modified: subversion/branches/verify-keep-going/tools/examples/blame.py
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/tools/examples/blame.py?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/tools/examples/blame.py (original)
+++ subversion/branches/verify-keep-going/tools/examples/blame.py Wed Nov 27 11:52:35 2013
@@ -91,9 +91,9 @@ def blame(path, filename, rev=None):
# print ''.join(diffresult)
# print annotresult
for x in range(len(annotresult.keys())):
- sys.stdout.write("Line %d (rev %d):%s" % (x,
- annotresult[x][0],
- annotresult[x][1]))
+ sys.stdout.write("Line %d (r%d):%s" % (x,
+ annotresult[x][0],
+ annotresult[x][1]))
def usage():
print("USAGE: blame.py [-r REV] repos-path file")
Modified: subversion/branches/verify-keep-going/tools/examples/svnlook.py
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/tools/examples/svnlook.py?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/tools/examples/svnlook.py (original)
+++ subversion/branches/verify-keep-going/tools/examples/svnlook.py Wed Nov 27 11:52:35 2013
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# svnlook.py : a Python-based replacement for svnlook
+# svnlook.py : alternative svnlook in Python with library API
#
######################################################################
# Licensed to the Apache Software Foundation (ASF) under one
@@ -21,6 +21,34 @@
# under the License.
######################################################################
#
+# $HeadURL$
+# $LastChangedDate$
+# $LastChangedRevision$
+
+"""
+svnlook.py can also be used as a Python module::
+
+ >>> import svnlook
+ >>> svnlook = svnlook.SVNLook("/testrepo")
+ >>> svnlook.get_author()
+ 'randomjoe'
+
+
+Accessible API::
+
+[x] author
+[x] changed
+[x] date
+[ ] diff
+[x] dirs-changed
+[ ] ids
+[x] info
+[x] log
+[ ] tree
+---
+[ ] generator API to avoid passing lists
+"""
+
import sys
import time
@@ -28,86 +56,155 @@ import os
from svn import core, fs, delta, repos
-class SVNLook:
- def __init__(self, path, cmd, rev, txn):
+class SVNLook(object):
+ def __init__(self, path, rev=None, txn=None, cmd=None):
+ """
+ path - path to repository
+ rev - revision number
+ txn - name of transaction (usually the one about to be committed)
+ cmd - if set, specifies cmd_* method to execute
+
+ txn takes precedence over rev; if both are None, inspect the head revision
+ """
path = core.svn_path_canonicalize(path)
repos_ptr = repos.open(path)
self.fs_ptr = repos.fs(repos_ptr)
+ # if set, txn takes precendence
if txn:
self.txn_ptr = fs.open_txn(self.fs_ptr, txn)
else:
self.txn_ptr = None
if rev is None:
rev = fs.youngest_rev(self.fs_ptr)
+ else:
+ rev = int(rev)
self.rev = rev
- getattr(self, 'cmd_' + cmd)()
+ if cmd != None:
+ getattr(self, 'cmd_' + cmd)()
def cmd_default(self):
self.cmd_info()
self.cmd_tree()
def cmd_author(self):
- # get the author property, or empty string if the property is not present
- author = self._get_property(core.SVN_PROP_REVISION_AUTHOR) or ''
- print(author)
+ print(self.get_author() or '')
def cmd_changed(self):
- self._print_tree(ChangedEditor, pass_root=1)
+ for status, path in self.get_changed():
+ print("%-3s %s" % (status, path))
def cmd_date(self):
- if self.txn_ptr:
+ # duplicate original svnlook format, which is
+ # 2010-02-08 21:53:15 +0200 (Mon, 08 Feb 2010)
+ secs = self.get_date(unixtime=True)
+ if secs is None:
print("")
else:
- date = self._get_property(core.SVN_PROP_REVISION_DATE)
- if date:
- aprtime = core.svn_time_from_cstring(date)
- # ### convert to a time_t; this requires intimate knowledge of
- # ### the apr_time_t type
- secs = aprtime / 1000000 # aprtime is microseconds; make seconds
-
- # assume secs in local TZ, convert to tuple, and format
- ### we don't really know the TZ, do we?
- print(time.strftime('%Y-%m-%d %H:%M', time.localtime(secs)))
- else:
- print("")
+ # convert to tuple, detect time zone and format
+ stamp = time.localtime(secs)
+ isdst = stamp.tm_isdst
+ utcoffset = -(time.altzone if (time.daylight and isdst) else time.timezone) // 60
+
+ suffix = "%+03d%02d" % (utcoffset // 60, abs(utcoffset) % 60)
+ outstr = time.strftime('%Y-%m-%d %H:%M:%S ', stamp) + suffix
+ outstr += time.strftime(' (%a, %d %b %Y)', stamp)
+ print(outstr)
+
def cmd_diff(self):
self._print_tree(DiffEditor, pass_root=1)
def cmd_dirs_changed(self):
- self._print_tree(DirsChangedEditor)
+ for dir in self.get_changed_dirs():
+ print(dir)
def cmd_ids(self):
self._print_tree(Editor, base_rev=0, pass_root=1)
def cmd_info(self):
+ """print the author, data, log_size, and log message"""
self.cmd_author()
self.cmd_date()
- self.cmd_log(1)
-
- def cmd_log(self, print_size=0):
- # get the log property, or empty string if the property is not present
- log = self._get_property(core.SVN_PROP_REVISION_LOG) or ''
- if print_size:
- print(len(log))
+ log = self.get_log() or ''
+ print(len(log))
print(log)
+ def cmd_log(self):
+ print(self.get_log() or '')
+
def cmd_tree(self):
self._print_tree(Editor, base_rev=0)
+
+ # --- API getters
+ def get_author(self):
+ """return string with the author name or None"""
+ return self._get_property(core.SVN_PROP_REVISION_AUTHOR)
+
+ def get_changed(self):
+ """return list of tuples (status, path)"""
+ ret = []
+ def list_callback(status, path):
+ ret.append( (status, path) )
+ self._walk_tree(ChangedEditor, pass_root=1, callback=list_callback)
+ return ret
+
+ def get_date(self, unixtime=False):
+ """return commit timestamp in RFC 3339 format (2010-02-08T20:37:25.195000Z)
+ if unixtime is True, return unix timestamp
+ return None for a txn, or if date property is not set
+ """
+ if self.txn_ptr:
+ return None
+
+ date = self._get_property(core.SVN_PROP_REVISION_DATE)
+ if not unixtime or date == None:
+ return date
+
+ # convert to unix time
+ aprtime = core.svn_time_from_cstring(date)
+ # ### convert to a time_t; this requires intimate knowledge of
+ # ### the apr_time_t type
+ secs = aprtime / 1000000 # aprtime is microseconds; make seconds
+ return secs
+
+ def get_changed_dirs(self):
+ """return list of changed dirs
+ dir names end with trailing forward slash even on windows
+ """
+ dirlist = []
+ def list_callback(item):
+ dirlist.append(item)
+ self._walk_tree(DirsChangedEditor, callback=list_callback)
+ return dirlist
+
+ def get_log(self):
+ """return log message string or None if not present"""
+ return self._get_property(core.SVN_PROP_REVISION_LOG)
+
+
+ # --- Internal helpers
def _get_property(self, name):
if self.txn_ptr:
return fs.txn_prop(self.txn_ptr, name)
return fs.revision_prop(self.fs_ptr, self.rev, name)
def _print_tree(self, e_factory, base_rev=None, pass_root=0):
+ def print_callback(msg):
+ print(msg)
+ self._walk_tree(e_factory, base_rev, pass_root, callback=print_callback)
+
+ # svn fs, delta, repos calls needs review according to DeltaEditor documentation
+ def _walk_tree(self, e_factory, base_rev=None, pass_root=0, callback=None):
if base_rev is None:
# a specific base rev was not provided. use the transaction base,
# or the previous revision
if self.txn_ptr:
base_rev = fs.txn_base_revision(self.txn_ptr)
+ elif self.rev == 0:
+ base_rev = 0
else:
base_rev = self.rev - 1
@@ -120,10 +217,13 @@ class SVNLook:
# the base of the comparison
base_root = fs.revision_root(self.fs_ptr, base_rev)
+ if callback == None:
+ callback = lambda msg: None
+
if pass_root:
- editor = e_factory(root, base_root)
+ editor = e_factory(root, base_root, callback)
else:
- editor = e_factory()
+ editor = e_factory(callback=callback)
# construct the editor for printing these things out
e_ptr, e_baton = delta.make_editor(editor)
@@ -135,8 +235,17 @@ class SVNLook:
e_ptr, e_baton, authz_cb, 0, 1, 0, 0)
+# ---------------------------------------------------------
+# Delta Editors. For documentation see:
+# http://subversion.apache.org/docs/community-guide/#docs
+
+# this one doesn't process delete_entry, change_dir_prop, apply_text_delta,
+# change_file_prop, close_file, close_edit, abort_edit
+# ?set_target_revision
+# need review
class Editor(delta.Editor):
- def __init__(self, root=None, base_root=None):
+ def __init__(self, root=None, base_root=None, callback=None):
+ """callback argument is unused for this editor"""
self.root = root
# base_root ignored
@@ -172,7 +281,14 @@ class Editor(delta.Editor):
return ' <%s>' % fs.unparse_id(id)
return ''
+# doesn't process close_directory, apply_text_delta,
+# change_file_prop, close_file, close_edit, abort_edit
+# ?set_target_revision
class DirsChangedEditor(delta.Editor):
+ """print names of changed dirs, callback(dir) is a printer function"""
+ def __init__(self, callback):
+ self.callback = callback
+
def open_root(self, base_revision, dir_pool):
return [ 1, '' ]
@@ -201,13 +317,15 @@ class DirsChangedEditor(delta.Editor):
def _dir_changed(self, baton):
if baton[0]:
# the directory hasn't been printed yet. do it.
- print(baton[1] + '/')
+ self.callback(baton[1] + '/')
baton[0] = 0
class ChangedEditor(delta.Editor):
- def __init__(self, root, base_root):
+ def __init__(self, root, base_root, callback):
+ """callback(status, path) is a printer function"""
self.root = root
self.base_root = base_root
+ self.callback = callback
def open_root(self, base_revision, dir_pool):
return [ 1, '' ]
@@ -215,13 +333,13 @@ class ChangedEditor(delta.Editor):
def delete_entry(self, path, revision, parent_baton, pool):
### need more logic to detect 'replace'
if fs.is_dir(self.base_root, '/' + path):
- print('D ' + path + '/')
+ self.callback('D', path + '/')
else:
- print('D ' + path)
+ self.callback('D', path)
def add_directory(self, path, parent_baton,
copyfrom_path, copyfrom_revision, dir_pool):
- print('A ' + path + '/')
+ self.callback('A', path + '/')
return [ 0, path ]
def open_directory(self, path, parent_baton, base_revision, dir_pool):
@@ -230,12 +348,12 @@ class ChangedEditor(delta.Editor):
def change_dir_prop(self, dir_baton, name, value, pool):
if dir_baton[0]:
# the directory hasn't been printed yet. do it.
- print('_U ' + dir_baton[1] + '/')
+ self.callback('_U', dir_baton[1] + '/')
dir_baton[0] = 0
def add_file(self, path, parent_baton,
copyfrom_path, copyfrom_revision, file_pool):
- print('A ' + path)
+ self.callback('A', path)
return [ '_', ' ', None ]
def open_file(self, path, parent_baton, base_revision, file_pool):
@@ -257,11 +375,12 @@ class ChangedEditor(delta.Editor):
status = text_mod + prop_mod
# was there some kind of change?
if status != '_ ':
- print(status + ' ' + path)
+ self.callback(status.rstrip(), path)
class DiffEditor(delta.Editor):
- def __init__(self, root, base_root):
+ def __init__(self, root, base_root, callback=None):
+ """callback argument is unused for this editor"""
self.root = root
self.base_root = base_root
self.target_revision = 0
@@ -435,7 +554,7 @@ def main():
if not hasattr(SVNLook, 'cmd_' + cmd):
usage(1)
- SVNLook(sys.argv[1], cmd, rev, txn)
+ SVNLook(sys.argv[1], rev, txn, cmd)
if __name__ == '__main__':
main()
Propchange: subversion/branches/verify-keep-going/tools/examples/svnlook.py
------------------------------------------------------------------------------
svn:keywords = URL Date Revision
Modified: subversion/branches/verify-keep-going/tools/server-side/fsfs-stats.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/tools/server-side/fsfs-stats.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/tools/server-side/fsfs-stats.c (original)
+++ subversion/branches/verify-keep-going/tools/server-side/fsfs-stats.c Wed Nov 27 11:52:35 2013
@@ -28,6 +28,7 @@
#include <apr_file_io.h>
#include <apr_poll.h>
+#include "svn_private_config.h"
#include "svn_pools.h"
#include "svn_diff.h"
#include "svn_io.h"
@@ -270,6 +271,12 @@ typedef struct fs_fs_t
/* history of sizes of changed nodes */
histogram_t node_size_histogram;
+ /* history of representation sizes */
+ histogram_t added_rep_size_histogram;
+
+ /* history of sizes of changed nodes */
+ histogram_t added_node_size_histogram;
+
/* history of unused representations */
histogram_t unused_rep_histogram;
@@ -486,6 +493,7 @@ add_to_histogram(histogram_t *histogram,
/* Update data aggregators in FS with this representation of type KIND, on-
* disk REP_SIZE and expanded node size EXPANDED_SIZE for PATH in REVSION.
+ * PLAIN_ADDED indicates whether the node has a deltification predecessor.
*/
static void
add_change(fs_fs_t *fs,
@@ -493,7 +501,8 @@ add_change(fs_fs_t *fs,
apr_int64_t expanded_size,
svn_revnum_t revision,
const char *path,
- rep_kind_t kind)
+ rep_kind_t kind,
+ svn_boolean_t plain_added)
{
/* identify largest reps */
if (rep_size >= fs->largest_changes->min_size)
@@ -522,6 +531,12 @@ add_change(fs_fs_t *fs,
add_to_histogram(&fs->rep_size_histogram, rep_size);
add_to_histogram(&fs->node_size_histogram, expanded_size);
+ if (plain_added)
+ {
+ add_to_histogram(&fs->added_rep_size_histogram, rep_size);
+ add_to_histogram(&fs->added_node_size_histogram, expanded_size);
+ }
+
/* specific histograms by type */
switch (kind)
{
@@ -1120,8 +1135,8 @@ get_combined_window(svn_stringbuf_t **co
apr_array_header_t *windows;
svn_stringbuf_t *base_content, *result;
const char *source;
- apr_pool_t *sub_pool;
- apr_pool_t *iter_pool;
+ apr_pool_t *subpool;
+ apr_pool_t *iterpool;
/* special case: no un-deltification necessary */
if (representation->is_plain)
@@ -1138,16 +1153,16 @@ get_combined_window(svn_stringbuf_t **co
return SVN_NO_ERROR;
/* read the delta windows for this representation */
- sub_pool = svn_pool_create(pool);
- iter_pool = svn_pool_create(pool);
- SVN_ERR(read_windows(&windows, fs, representation, file_content, sub_pool));
+ subpool = svn_pool_create(pool);
+ iterpool = svn_pool_create(pool);
+ SVN_ERR(read_windows(&windows, fs, representation, file_content, subpool));
/* fetch the / create a base content */
if (representation->delta_base && representation->delta_base->revision)
SVN_ERR(get_combined_window(&base_content, fs,
- representation->delta_base, NULL, sub_pool));
+ representation->delta_base, NULL, subpool));
else
- base_content = svn_stringbuf_create_empty(sub_pool);
+ base_content = svn_stringbuf_create_empty(subpool);
/* apply deltas */
result = svn_stringbuf_create_empty(pool);
@@ -1158,7 +1173,7 @@ get_combined_window(svn_stringbuf_t **co
svn_txdelta_window_t *window
= APR_ARRAY_IDX(windows, i, svn_txdelta_window_t *);
svn_stringbuf_t *buf
- = svn_stringbuf_create_ensure(window->tview_len, iter_pool);
+ = svn_stringbuf_create_ensure(window->tview_len, iterpool);
buf->len = window->tview_len;
svn_txdelta_apply_instructions(window, window->src_ops ? source : NULL,
@@ -1167,15 +1182,15 @@ get_combined_window(svn_stringbuf_t **co
svn_stringbuf_appendbytes(result, buf->data, buf->len);
source += window->sview_len;
- svn_pool_clear(iter_pool);
+ svn_pool_clear(iterpool);
}
/* cache result and return it */
- SVN_ERR(set_cached_window(fs, representation, result, sub_pool));
+ SVN_ERR(set_cached_window(fs, representation, result, subpool));
*content = result;
- svn_pool_destroy(iter_pool);
- svn_pool_destroy(sub_pool);
+ svn_pool_destroy(iterpool);
+ svn_pool_destroy(subpool);
return SVN_NO_ERROR;
}
@@ -1204,7 +1219,7 @@ parse_dir(fs_fs_t *fs,
apr_pool_t *scratch_pool)
{
svn_stringbuf_t *text;
- apr_pool_t *iter_pool;
+ apr_pool_t *iterpool;
apr_pool_t *text_pool;
const char *current;
const char *revision_key;
@@ -1215,7 +1230,7 @@ parse_dir(fs_fs_t *fs,
return SVN_NO_ERROR;
/* get the directory as unparsed string */
- iter_pool = svn_pool_create(scratch_pool);
+ iterpool = svn_pool_create(scratch_pool);
text_pool = svn_pool_create(scratch_pool);
SVN_ERR(get_combined_window(&text, fs, representation, file_content,
@@ -1240,7 +1255,7 @@ parse_dir(fs_fs_t *fs,
next = current ? strchr(++current, '\n') : NULL;
if (next == NULL)
return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
- _("Corrupt directory representation in rev %ld at offset %ld"),
+ _("Corrupt directory representation in r%ld at offset %ld"),
representation->revision,
(long)representation->offset);
@@ -1256,14 +1271,14 @@ parse_dir(fs_fs_t *fs,
SVN_ERR(svn_cstring_strtoui64(&offset, current + key_len, 0,
APR_SIZE_MAX, 10));
SVN_ERR(read_noderev(fs, file_content, (apr_size_t)offset,
- revision_info, pool, iter_pool));
+ revision_info, pool, iterpool));
- svn_pool_clear(iter_pool);
+ svn_pool_clear(iterpool);
}
current = next+1;
}
- svn_pool_destroy(iter_pool);
+ svn_pool_destroy(iterpool);
svn_pool_destroy(text_pool);
return SVN_NO_ERROR;
}
@@ -1288,6 +1303,7 @@ read_noderev(fs_fs_t *fs,
representation_t *props = NULL;
apr_size_t start_offset = offset;
svn_boolean_t is_dir = FALSE;
+ svn_boolean_t has_predecessor = FALSE;
const char *path = "???";
scratch_pool = svn_pool_create(scratch_pool);
@@ -1348,15 +1364,17 @@ read_noderev(fs_fs_t *fs,
}
else if (key_matches(&key, "cpath"))
path = value.data;
+ else if (key_matches(&key, "pred"))
+ has_predecessor = TRUE;
}
/* record largest changes */
if (text && text->ref_count == 1)
add_change(fs, (apr_int64_t)text->size, (apr_int64_t)text->expanded_size,
- text->revision, path, text->kind);
+ text->revision, path, text->kind, !has_predecessor);
if (props && props->ref_count == 1)
add_change(fs, (apr_int64_t)props->size, (apr_int64_t)props->expanded_size,
- props->revision, path, props->kind);
+ props->revision, path, props->kind, !has_predecessor);
/* if this is a directory and has not been processed, yet, read and
* process it recursively */
@@ -1573,7 +1591,9 @@ read_revisions(fs_fs_t **fs,
svn_cache__get_global_membuffer_cache(),
NULL, NULL,
sizeof(window_cache_key_t),
- "", FALSE, pool));
+ "",
+ SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+ FALSE, pool));
/* read all packed revs */
for ( revision = start_revision
@@ -2043,6 +2063,7 @@ print_stats(fs_fs_t *fs,
printf(_("%20s bytes in %12s representations total\n"
"%20s bytes in %12s directory representations\n"
"%20s bytes in %12s file representations\n"
+ "%20s bytes in %12s representations of added file nodes\n"
"%20s bytes in %12s directory property representations\n"
"%20s bytes in %12s file property representations\n"
"%20s bytes in header & footer overhead\n"),
@@ -2052,6 +2073,8 @@ print_stats(fs_fs_t *fs,
svn__i64toa_sep(dir_rep_stats.total.count, ',', pool),
svn__i64toa_sep(file_rep_stats.total.packed_size, ',', pool),
svn__i64toa_sep(file_rep_stats.total.count, ',', pool),
+ svn__i64toa_sep(fs->added_rep_size_histogram.total.sum, ',', pool),
+ svn__i64toa_sep(fs->added_rep_size_histogram.total.count, ',', pool),
svn__i64toa_sep(dir_prop_rep_stats.total.packed_size, ',', pool),
svn__i64toa_sep(dir_prop_rep_stats.total.count, ',', pool),
svn__i64toa_sep(file_prop_rep_stats.total.packed_size, ',', pool),
Modified: subversion/branches/verify-keep-going/tools/server-side/mod_dontdothat/mod_dontdothat.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/tools/server-side/mod_dontdothat/mod_dontdothat.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/tools/server-side/mod_dontdothat/mod_dontdothat.c (original)
+++ subversion/branches/verify-keep-going/tools/server-side/mod_dontdothat/mod_dontdothat.c Wed Nov 27 11:52:35 2013
@@ -30,12 +30,15 @@
#include <util_filter.h>
#include <ap_config.h>
#include <apr_strings.h>
+#include <apr_uri.h>
#include <expat.h>
#include "mod_dav_svn.h"
#include "svn_string.h"
#include "svn_config.h"
+#include "svn_path.h"
+#include "private/svn_fspath.h"
module AP_MODULE_DECLARE_DATA dontdothat_module;
@@ -161,26 +164,71 @@ matches(const char *wc, const char *p)
}
}
+/* duplicate of dav_svn__log_err() from mod_dav_svn/util.c */
+static void
+log_dav_err(request_rec *r,
+ dav_error *err,
+ int level)
+{
+ dav_error *errscan;
+
+ /* Log the errors */
+ /* ### should have a directive to log the first or all */
+ for (errscan = err; errscan != NULL; errscan = errscan->prev) {
+ apr_status_t status;
+
+ if (errscan->desc == NULL)
+ continue;
+
+#if AP_MODULE_MAGIC_AT_LEAST(20091119,0)
+ status = errscan->aprerr;
+#else
+ status = errscan->save_errno;
+#endif
+
+ ap_log_rerror(APLOG_MARK, level, status, r,
+ "%s [%d, #%d]",
+ errscan->desc, errscan->status, errscan->error_id);
+ }
+}
+
static svn_boolean_t
is_this_legal(dontdothat_filter_ctx *ctx, const char *uri)
{
const char *relative_path;
const char *cleaned_uri;
const char *repos_name;
+ const char *uri_path;
int trailing_slash;
dav_error *derr;
- /* Ok, so we need to skip past the scheme, host, etc. */
- uri = ap_strstr_c(uri, "://");
- if (uri)
- uri = ap_strchr_c(uri + 3, '/');
+ /* uri can be an absolute uri or just a path, we only want the path to match
+ * against */
+ if (uri && svn_path_is_url(uri))
+ {
+ apr_uri_t parsed_uri;
+ apr_status_t rv = apr_uri_parse(ctx->r->pool, uri, &parsed_uri);
+ if (APR_SUCCESS != rv)
+ {
+ /* Error parsing the URI, log and reject request. */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, ctx->r,
+ "mod_dontdothat: blocked request after failing "
+ "to parse uri: '%s'", uri);
+ return FALSE;
+ }
+ uri_path = parsed_uri.path;
+ }
+ else
+ {
+ uri_path = uri;
+ }
- if (uri)
+ if (uri_path)
{
const char *repos_path;
derr = dav_svn_split_uri(ctx->r,
- uri,
+ uri_path,
ctx->cfg->base_path,
&cleaned_uri,
&trailing_slash,
@@ -194,7 +242,7 @@ is_this_legal(dontdothat_filter_ctx *ctx
if (! repos_path)
repos_path = "";
- repos_path = apr_psprintf(ctx->r->pool, "/%s", repos_path);
+ repos_path = svn_fspath__canonicalize(repos_path, ctx->r->pool);
/* First check the special cases that are always legal... */
for (idx = 0; idx < ctx->allow_recursive_ops->nelts; ++idx)
@@ -228,6 +276,19 @@ is_this_legal(dontdothat_filter_ctx *ctx
}
}
}
+ else
+ {
+ log_dav_err(ctx->r, derr, APLOG_ERR);
+ return FALSE;
+ }
+
+ }
+ else
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r,
+ "mod_dontdothat: empty uri passed to is_this_legal(), "
+ "module bug?");
+ return FALSE;
}
return TRUE;
Modified: subversion/branches/verify-keep-going/tools/server-side/svn-populate-node-origins-index.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/tools/server-side/svn-populate-node-origins-index.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/tools/server-side/svn-populate-node-origins-index.c (original)
+++ subversion/branches/verify-keep-going/tools/server-side/svn-populate-node-origins-index.c Wed Nov 27 11:52:35 2013
@@ -94,7 +94,9 @@ index_revision_adds(int *count, svn_fs_t
apr_hash_this(hi, &path, NULL, &val);
change = val;
if ((change->change_kind == svn_fs_path_change_add)
- || (change->change_kind == svn_fs_path_change_replace))
+ || (change->change_kind == svn_fs_path_change_replace)
+ || (change->change_kind == svn_fs_path_change_move)
+ || (change->change_kind == svn_fs_path_change_movereplace))
{
if (! (change->copyfrom_path
&& SVN_IS_VALID_REVNUM(change->copyfrom_rev)))
Modified: subversion/branches/verify-keep-going/tools/server-side/svn-rep-sharing-stats.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/tools/server-side/svn-rep-sharing-stats.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/tools/server-side/svn-rep-sharing-stats.c (original)
+++ subversion/branches/verify-keep-going/tools/server-side/svn-rep-sharing-stats.c Wed Nov 27 11:52:35 2013
@@ -33,6 +33,7 @@
#include "../../subversion/libsvn_fs_fs/fs_fs.h"
/* for svn_fs_fs__id_* (used in assertions only) */
#include "../../subversion/libsvn_fs_fs/id.h"
+#include "../../subversion/libsvn_fs_fs/cached_data.h"
#include "private/svn_cmdline_private.h"
@@ -78,7 +79,6 @@ help(const apr_getopt_option_t *options,
++options;
}
svn_error_clear(svn_cmdline_fprintf(stdout, pool, "\n"));
- exit(0);
}
@@ -95,7 +95,8 @@ check_lib_versions(void)
};
SVN_VERSION_DEFINE(my_version);
- return svn_error_trace(svn_ver_check_list(&my_version, checklist));
+ return svn_error_trace(svn_ver_check_list2(&my_version, checklist,
+ svn_ver_equal));
}
@@ -182,7 +183,8 @@ struct key_t
/* What we need to know about a rep. */
struct value_t
{
- svn_checksum_t *sha1_checksum;
+ svn_checksum_t checksum;
+ unsigned char sha1_digest[APR_SHA1_DIGESTSIZE];
apr_uint64_t refcount;
};
@@ -200,7 +202,7 @@ static svn_error_t *record(apr_hash_t *r
* exist or doesn't have the checksum we are after. (The latter case
* often corresponds to node_rev->kind == svn_node_dir.)
*/
- if (records == NULL || rep == NULL || rep->sha1_checksum == NULL)
+ if (records == NULL || rep == NULL || !rep->has_sha1)
return SVN_NO_ERROR;
/* Construct the key.
@@ -215,17 +217,19 @@ static svn_error_t *record(apr_hash_t *r
if ((value = apr_hash_get(records, key, sizeof(*key))))
{
/* Paranoia. */
- SVN_ERR_ASSERT(value->sha1_checksum != NULL);
- SVN_ERR_ASSERT(svn_checksum_match(value->sha1_checksum,
- rep->sha1_checksum));
+ SVN_ERR_ASSERT(memcmp(value->sha1_digest,
+ rep->sha1_digest,
+ sizeof(value->sha1_digest)));
/* Real work. */
value->refcount++;
}
else
{
value = apr_palloc(result_pool, sizeof(*value));
- value->sha1_checksum = svn_checksum_dup(rep->sha1_checksum, result_pool);
+ value->checksum.digest = value->sha1_digest;
+ value->checksum.kind = svn_checksum_sha1;
value->refcount = 1;
+ memcpy(value->sha1_digest, rep->sha1_digest, sizeof(value->sha1_digest));
}
/* Store them. */
@@ -340,7 +344,7 @@ pretty_print(const char *name,
SVN_ERR(svn_cmdline_printf(scratch_pool, "%s %" APR_UINT64_T_FMT " %s\n",
name, value->refcount,
svn_checksum_to_cstring_display(
- value->sha1_checksum,
+ &value->checksum,
scratch_pool)));
}
@@ -419,14 +423,17 @@ static svn_error_t *process(const char *
return SVN_NO_ERROR;
}
-int
-main(int argc, const char *argv[])
+/*
+ * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
+ * either return an error to be displayed, or set *EXIT_CODE to non-zero and
+ * return SVN_NO_ERROR.
+ */
+static svn_error_t *
+sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
{
const char *repos_path;
- apr_pool_t *pool;
svn_boolean_t prop = FALSE, data = FALSE;
svn_boolean_t quiet = FALSE;
- svn_error_t *err;
apr_getopt_t *os;
const apr_getopt_option_t options[] =
{
@@ -440,25 +447,12 @@ main(int argc, const char *argv[])
{0, 0, 0, 0}
};
- /* Initialize the app. */
- if (svn_cmdline_init("svn-rep-sharing-stats", stderr) != EXIT_SUCCESS)
- return EXIT_FAILURE;
-
- /* Create our top-level pool. Use a separate mutexless allocator,
- * given this application is single threaded.
- */
- pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
-
/* Check library versions */
- err = check_lib_versions();
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn-rep-sharing-stats: ");
+ SVN_ERR(check_lib_versions());
- err = svn_cmdline__getopt_init(&os, argc, argv, pool);
- if (err)
- return svn_cmdline_handle_exit_error(err, pool, "svn-rep-sharing-stats: ");
+ SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
- SVN_INT_ERR(check_experimental());
+ SVN_ERR(check_experimental());
os->interleave = 1;
while (1)
@@ -471,7 +465,8 @@ main(int argc, const char *argv[])
if (status != APR_SUCCESS)
{
usage(pool);
- return EXIT_FAILURE;
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
switch (opt)
{
@@ -491,14 +486,14 @@ main(int argc, const char *argv[])
break;
case 'h':
help(options, pool);
- break;
+ return SVN_NO_ERROR;
case OPT_VERSION:
- SVN_INT_ERR(version(pool));
- exit(0);
- break;
+ SVN_ERR(version(pool));
+ return SVN_NO_ERROR;
default:
usage(pool);
- return EXIT_FAILURE;
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
}
@@ -508,23 +503,51 @@ main(int argc, const char *argv[])
if (os->ind + 1 != argc || (!data && !prop))
{
usage(pool);
- return EXIT_FAILURE;
+ *exit_code = EXIT_FAILURE;
+ return SVN_NO_ERROR;
}
/* Grab REPOS_PATH from argv. */
- SVN_INT_ERR(svn_utf_cstring_to_utf8(&repos_path, os->argv[os->ind], pool));
+ SVN_ERR(svn_utf_cstring_to_utf8(&repos_path, os->argv[os->ind], pool));
repos_path = svn_dirent_internal_style(repos_path, pool);
set_up_cancellation();
/* Do something. */
- SVN_INT_ERR(process(repos_path, prop, data, quiet, pool));
+ SVN_ERR(process(repos_path, prop, data, quiet, pool));
/* We're done. */
+ return SVN_NO_ERROR;
+}
- svn_pool_destroy(pool);
- /* Flush stdout to make sure that the user will see any printing errors. */
- SVN_INT_ERR(svn_cmdline_fflush(stdout));
+int
+main(int argc, const char *argv[])
+{
+ apr_pool_t *pool;
+ int exit_code = EXIT_SUCCESS;
+ svn_error_t *err;
+
+ /* Initialize the app. */
+ if (svn_cmdline_init("svn-rep-sharing-stats", stderr) != EXIT_SUCCESS)
+ return EXIT_FAILURE;
+
+ /* Create our top-level pool. Use a separate mutexless allocator,
+ * given this application is single threaded.
+ */
+ pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
+
+ err = sub_main(&exit_code, argc, argv, pool);
+
+ /* Flush stdout and report if it fails. It would be flushed on exit anyway
+ but this makes sure that output is not silently lost if it fails. */
+ err = svn_error_compose_create(err, svn_cmdline_fflush(stdout));
- return EXIT_SUCCESS;
+ if (err)
+ {
+ exit_code = EXIT_FAILURE;
+ svn_cmdline_handle_exit_error(err, NULL, "svn-rep-sharing-stats: ");
+ }
+
+ svn_pool_destroy(pool);
+ return exit_code;
}