Modified: subversion/branches/fsfs-format7/tools/dev/build-svn-deps-win.pl URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/tools/dev/build-svn-deps-win.pl?rev=1507012&r1=1507011&r2=1507012&view=diff ============================================================================== --- subversion/branches/fsfs-format7/tools/dev/build-svn-deps-win.pl (original) +++ subversion/branches/fsfs-format7/tools/dev/build-svn-deps-win.pl Thu Jul 25 15:29:49 2013 @@ -51,7 +51,6 @@ # Usage/help output from the usual flags/on error input. # Make SQLITE_VER friendly since we're using no dots right now. # Work out the fixes to the projects' sources and contribute them back. -# Allow selection of Release/Debug builds. # Allow selection of Arch (x86 and x64) # ZLib support for OpenSSL (have to patch openssl) # Use CMake zlib build instead. @@ -135,7 +134,8 @@ our $SRCDIR; # directory where we store # Some other options our $VS_VER; our $NEON; -our $SVN_VER = '1.8.x'; +our $SVN_VER = '1.9.x'; +our $DEBUG = 0; # Utility function to remove dots from a string sub remove_dots { @@ -351,6 +351,7 @@ sub clean_structure { rmtree($INCDIR); rmtree($LIBDIR); rmtree("$INSTDIR\\serf"); + rmtree("$INSTDIR\\neon"); rmtree("$INSTDIR\\sqlite-amalgamation"); # Dirs created indirectly by the install targets @@ -422,7 +423,7 @@ sub download_dependencies { download_file($PCRE_URL, "$SRCDIR\\pcre.zip", \$PCRE_FILE); download_file($SQLITE_URL, "$SRCDIR\\sqlite-amalgamation.zip", \$SQLITE_FILE); download_file($SERF_URL, "$SRCDIR\\serf.zip", \$SERF_FILE); - download_file($NEON_URL, "$SRCDIR\\neon.tar.gz", \$NEON_FILE) if defined($NEON); + download_file($NEON_URL, "$SRCDIR\\neon.tar.gz", \$NEON_FILE) if $NEON; } ############## @@ -488,7 +489,7 @@ sub extract_dependencies { extract_file($SERF_FILE, $INSTDIR, "$INSTDIR\\serf-$SERF_VER", "$INSTDIR\\serf"); extract_file($NEON_FILE, $INSTDIR, - "$INSTDIR\\neon-$NEON_VER", "$INSTDIR\\neon") if defined($NEON); + "$INSTDIR\\neon-$NEON_VER", "$INSTDIR\\neon") if $NEON; } ######### @@ -499,7 +500,7 @@ sub build_pcre { chdir_or_die("$SRCLIB\\pcre"); my $pcre_generator = 'NMake Makefiles'; # Have to use RelWithDebInfo since httpd looks for the pdb files - my $pcre_build_type = '-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo'; + my $pcre_build_type = '-DCMAKE_BUILD_TYPE:STRING=' . ($DEBUG ? 'Debug' : 'RelWithDebInfo'); my $pcre_shared_libs = '-DBUILD_SHARED_LIBS:BOOL=ON'; my $pcre_install_prefix = "-DCMAKE_INSTALL_PREFIX:PATH=$INSTDIR"; my $cmake_cmd = qq("$CMAKE" -G "$pcre_generator" "$pcre_build_type" "$pcre_shared_libs" "$pcre_install_prefix" .); @@ -514,7 +515,7 @@ sub build_pcre { # build generates, it it doesn't match that then Subversion will fail to build. sub build_zlib { chdir_or_die("$SRCLIB\\zlib"); - $ENV{CC_OPTS} = '/MD /02 /Zi'; + $ENV{CC_OPTS} = $DEBUG ? '/MDd /Gm /ZI /Od /GZ /D_DEBUG' : '/MD /02 /Zi'; $ENV{COMMON_CC_OPTS} = '/nologo /W3 /DWIN32 /D_WINDOWS'; system_or_die("Failure building zilb", qq("$NMAKE" /nologo -f win32\\Makefile.msc STATICLIB=zlibstat.lib all)); @@ -543,8 +544,9 @@ sub build_openssl { # The apache build docs suggest no-rc5 no-idea enable-mdc2 on top of what # is used below, the primary driver behind that is patents, but I believe # the rc5 and idea patents have expired. + my $platform = $DEBUG ? 'debug-VC-WIN32' : 'VC-WIN32'; system_or_die("Failure configuring openssl", - qq("$PERL" Configure no-asm "--prefix=$INSTDIR" VC-WIN32)); + qq("$PERL" Configure no-asm "--prefix=$INSTDIR" $platform)); system_or_die("Failure building openssl (bat)", 'ms\do_ms.bat'); system_or_die("Failure building openssl (nmake)", qq("$NMAKE" /f ms\\ntdll.mak)); system_or_die("Failure testing openssl", qq("$NMAKE" /f ms\\ntdll.mak test)); @@ -601,6 +603,9 @@ sub httpd_fix_makefile { modify_file_in_place($file, sub { s/\.vcproj/.vcxproj/i; + # below fixes that installd breaks when trying to install pcre because + # dll is named pcred.dll when a Debug build. + s/^(\s*copy srclib\\pcre\\pcre\.\$\(src_dll\)\s+"\$\(inst_dll\)"\s+<\s*\.y\s*)$/!IF EXISTS("srclib\\pcre\\pcre\.\$(src_dll)")\n$1!ENDIF\n!IF EXISTS("srclib\\pcre\\pcred\.\$(src_dll)")\n\tcopy srclib\\pcre\\pcred.\$(src_dll)\t\t\t"\$(inst_dll)" <.y\n!ENDIF\n/; }); } @@ -650,8 +655,9 @@ sub get_output_file { # Find the name of the bdb library we've installed in our LIBDIR. sub find_bdb_lib { my $result; + my $debug = $DEBUG ? 'd' : ''; find(sub { - if (not defined($result) and /^libdb\d+\.lib$/) { + if (not defined($result) and /^libdb\d+$debug\.lib$/) { $result = $_; } }, $LIBDIR); @@ -688,12 +694,25 @@ sub httpd_enable_bdb { insert_dependency_in_proj('support\htdbm.vcxproj', $bdb_lib, '.bdb'); } +# Apply the same fix as found in r1486937 on httpd 2.4.x branch. +sub httpd_fix_debug { + my ($httpd_major, $httpd_minor, $httpd_patch) = $HTTPD_VER =~ /^(\d+)\.(\d+)\.(.+)$/; + return unless ($httpd_major <= 2 && $httpd_minor <= 4 && $httpd_patch < 5); + + modify_file_in_place('libhttpd.dsp', sub { + s/^(!MESSAGE "libhttpd - Win32 Debug" \(based on "Win32 \(x86\) Dynamic-Link Library"\))$/$1\n!MESSAGE "libhttpd - Win32 Lexical" (based on "Win32 (x86) Dynamic-Link Library")/; + s/^(# Begin Group "headers")$/# Name "libhttpd - Win32 Lexical"\n$1/; + }, '.lexical'); +} + sub build_httpd { chdir_or_die($HTTPD); my $vs_2012 = $VS_VER eq '2012'; my $vs_2010 = $VS_VER eq '2010'; + httpd_fix_debug(); + # I don't think cvtdsp.pl is necessary with Visual Studio 2012 # but it shouldn't hurt anything either. Including it allows # for the possibility that this may work for older Visual Studio @@ -763,8 +782,9 @@ sub build_httpd { # configurations inside the project since we get them from the environment. # Once all that is done the BuildBin project should be buildable for you to # diagnose the problem. + my $target = $DEBUG ? "installd" : "installr"; system_or_die("Failed building/installing httpd/apr/apu/api", - qq("$NMAKE" /f Makefile.win installr "DBM_LIST=db" "INSTDIR=$INSTDIR")); + qq("$NMAKE" /f Makefile.win $target "DBM_LIST=db" "INSTDIR=$INSTDIR")); chdir_or_die($TOPDIR); } @@ -776,13 +796,15 @@ sub build_bdb { my $sln = 'build_windows\Berkeley_DB_vs2010.sln'; upgrade_solution($sln); + my $platform = $DEBUG ? 'Debug|Win32' : 'Release|Win32'; + # Build the db Project first since the full solution fails due to a broken # dependency with the current version of BDB if we don't. system_or_die("Failed building DBD (Project db)", - qq("$DEVENV" "$sln" /Build "Release|Win32" /Project db)); + qq("$DEVENV" "$sln" /Build "$platform" /Project db)); system_or_die("Failed building DBD", - qq("$DEVENV" "$sln" /Build "Release|Win32")); + qq("$DEVENV" "$sln" /Build "$platform")); # BDB doesn't seem to have it's own install routines so we'll do it ourselves copy_or_die('build_windows\db.h', $INCDIR); @@ -792,16 +814,31 @@ sub build_bdb { } elsif (/\.lib$/) { copy_or_die($_, $LIBDIR); } - }, 'build_windows\Win32\Release'); + }, 'build_windows\\Win32\\' . ($DEBUG ? 'Debug' : 'Release')); chdir_or_die($TOPDIR); } +# Right now this doesn't actually build serf but just patches it so that it +# can build against a debug build of OpenSSL. +sub build_serf { + chdir_or_die("$TOPDIR\\serf"); + + modify_file_in_place('serf.mak', sub { + s/^(INTDIR = Release)$/$1\nOPENSSL_OUT_SUFFIX =/; + s/^(INTDIR = Debug)$/$1\nOPENSSL_OUT_SUFFIX = .dbg/; + s/(\$\(OPENSSL_SRC\)\\out32(?:dll)?)/$1\$(OPENSSL_OUT_SUFFIX)/g; + }, '.debug'); + + chdir_or_die($TOPDIR); +} + sub build_dependencies { build_bdb(); build_zlib(); build_pcre(); build_openssl(); + build_serf(); build_httpd(); }
Modified: subversion/branches/fsfs-format7/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c?rev=1507012&r1=1507011&r2=1507012&view=diff ============================================================================== --- subversion/branches/fsfs-format7/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c (original) +++ subversion/branches/fsfs-format7/tools/dev/svnraisetreeconflict/svnraisetreeconflict.c Thu Jul 25 15:29:49 2013 @@ -187,7 +187,7 @@ raise_tree_conflict(int argc, const char { int i = 0; svn_wc_conflict_version_t *left, *right; - svn_wc_conflict_description2_t *c; + svn_wc_conflict_description3_t *c; svn_wc_context_t *wc_ctx; /* Conflict description parameters */ @@ -223,7 +223,7 @@ raise_tree_conflict(int argc, const char peg_rev1, kind1, pool); right = svn_wc_conflict_version_create2(repos_url2, NULL, path_in_repos2, peg_rev2, kind2, pool); - c = svn_wc_conflict_description_create_tree2(wc_abspath, kind, + c = svn_wc_conflict_description_create_tree3(wc_abspath, kind, operation, left, right, pool); c->action = (svn_wc_conflict_action_t)action; c->reason = (svn_wc_conflict_reason_t)reason; Modified: subversion/branches/fsfs-format7/tools/dev/unix-build/Makefile.svn URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/tools/dev/unix-build/Makefile.svn?rev=1507012&r1=1507011&r2=1507012&view=diff ============================================================================== --- subversion/branches/fsfs-format7/tools/dev/unix-build/Makefile.svn (original) +++ subversion/branches/fsfs-format7/tools/dev/unix-build/Makefile.svn Thu Jul 25 15:29:49 2013 @@ -70,7 +70,7 @@ 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.25 NEON_VER = 0.29.6 SERF_VER = 1.2.1 SERF_OLD_VER = 0.3.1 @@ -548,15 +548,35 @@ httpd-reset: httpd-clean: -(cd $(HTTPD_OBJDIR) && make clean) + rm -f $(HTTPD_OBJDIR)/no_ssl_v2.diff # fetch distfile for httpd $(DISTDIR)/$(HTTPD_DIST): cd $(DISTDIR) && $(FETCH_CMD) $(HTTPD_URL) +$(HTTPD_OBJDIR)/no_ssl_v2.diff: + mkdir -p $(dir $@) + echo > [email protected] '--- modules/ssl/ssl_engine_io.c.orig Sat Jul 13 16:49:52 2013' + echo >> [email protected] '+++ modules/ssl/ssl_engine_io.c Sat Jul 13 16:50:10 2013' + echo >> [email protected] '@@ -1079,7 +1079,9 @@' + echo >> [email protected] ' * IPv4 and IPv6 addresses are not permitted".)' + echo >> [email protected] ' */' + echo >> [email protected] ' if (hostname_note &&' + echo >> [email protected] '+#ifndef OPENSSL_NO_SSL2' + echo >> [email protected] ' sc->proxy->protocol != SSL_PROTOCOL_SSLV2 &&' + echo >> [email protected] '+#endif' + echo >> [email protected] ' sc->proxy->protocol != SSL_PROTOCOL_SSLV3 &&' + echo >> [email protected] ' apr_ipsubnet_create(&ip, hostname_note, NULL,' + echo >> [email protected] ' c->pool) != APR_SUCCESS) {' + mv -f [email protected] $@ + # retrieve httpd -$(HTTPD_OBJDIR)/.retrieved: $(DISTDIR)/$(HTTPD_DIST) +$(HTTPD_OBJDIR)/.retrieved: $(DISTDIR)/$(HTTPD_DIST) \ + $(HTTPD_OBJDIR)/no_ssl_v2.diff [ -d $(HTTPD_OBJDIR) ] || mkdir -p $(HTTPD_OBJDIR) tar -C $(SRCDIR) -jxf $(DISTDIR)/$(HTTPD_DIST) + cd $(SRCDIR)/httpd-$(HTTPD_VER) && \ + patch -p0 < $(HTTPD_OBJDIR)/no_ssl_v2.diff touch $@ # configure httpd Modified: subversion/branches/fsfs-format7/tools/dist/backport.pl URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/tools/dist/backport.pl?rev=1507012&r1=1507011&r2=1507012&view=diff ============================================================================== --- subversion/branches/fsfs-format7/tools/dist/backport.pl (original) +++ subversion/branches/fsfs-format7/tools/dist/backport.pl Thu Jul 25 15:29:49 2013 @@ -1,4 +1,4 @@ -#!/usr/bin/perl -l +#!/usr/bin/perl use warnings; use strict; use feature qw/switch say/; @@ -20,65 +20,142 @@ use feature qw/switch say/; # specific language governing permissions and limitations # under the License. +use Digest (); use Term::ReadKey qw/ReadMode ReadKey/; +use File::Copy qw/copy move/; use File::Temp qw/tempfile/; use POSIX qw/ctermid/; +############### Start of reading values from environment ############### + +# Programs we use. my $SVN = $ENV{SVN} || 'svn'; # passed unquoted to sh +my $SHELL = $ENV{SHELL} // '/bin/sh'; my $VIM = 'vim'; -my $STATUS = './STATUS'; -my $BRANCHES = '^/subversion/branches'; +my $EDITOR = $ENV{SVN_EDITOR} // $ENV{VISUAL} // $ENV{EDITOR} // 'ed'; +my $PAGER = $ENV{PAGER} // 'less -F' // 'cat'; -my $YES = $ENV{YES}; # batch mode: eliminate prompts, add sleeps -my $MAY_COMMIT = qw[false true][0]; -my $DEBUG = qw[false true][0]; # 'set -x', etc -$DEBUG = 'true' if exists $ENV{DEBUG}; +# Mode flags. +# 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 $MAY_COMMIT = 'false'; $MAY_COMMIT = 'true' if ($ENV{MAY_COMMIT} // "false") =~ /^(1|yes|true)$/i; -# derived values +# Other knobs. +my $VERBOSE = 0; +my $DEBUG = (exists $ENV{DEBUG}) ? 'true' : 'false'; # 'set -x', etc + +# Username for entering votes. +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; + $_ +} +// warn "Username for commits (of votes/merges) not found"; + +############## End of reading values from the environment ############## + +# Constants. +my $STATUS = './STATUS'; +my $STATEFILE = './.backports1'; +my $BRANCHES = '^/subversion/branches'; + +# Globals. +my %ERRORS = (); +my $MERGED_SOMETHING = 0; my $SVNq; + +# Derived values. my $SVNvsn = do { my ($major, $minor, $patch) = `$SVN --version -q` =~ /^(\d+)\.(\d+)\.(\d+)/; 1e6*$major + 1e3*$minor + $patch; }; - $SVN .= " --non-interactive" if $YES or not defined ctermid; $SVNq = "$SVN -q "; $SVNq =~ s/-q// if $DEBUG eq 'true'; + sub usage { my $basename = $0; $basename =~ s#.*/##; print <<EOF; -Run this from the root of your release branch (e.g., 1.6.x) working copy. Use -a working copy 'svn revert -R .' can be run on at any time, as this script -will run revert prior to every merge. - -For each entry in STATUS, you will be prompted whether to merge it. The -merge will not be committed. +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. + +In interactive mode (the default), you will be prompted once per STATUS entry. +At a prompt, you have the following options: + +y: Run a merge. It will not be committed. + WARNING: This will run 'update' and 'revert -R ./'. +l: Show logs for the entries being nominated. +q: Quit the "for each nomination" loop. +±1: Enter a +1 or -1 vote + You will be prompted to commit your vote at the end. +±0: Enter a +0 or -0 vote + You will be prompted to commit your vote at the end. +a: Move the entry to the "Approved changes" section. + When both approving and voting on an entry, approve first: for example, + to enter a third +1 vote, type "a" "+" "1". +e: Edit the entry in $EDITOR. + You will be prompted to commit your edits at the end. +N: Move to the next entry. Cache the entry in '$STATEFILE' and do not + prompt for it again (even across runs) until it is changed. + : Move to the next entry, without adding the current one to the cache. + (That's a space character, ASCII 0x20.) + +After running a merge, you have the following options: + +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 +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. 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 digest_string { + Digest->new("MD5")->add(@_)->hexdigest +} + sub prompt { - local $\; # disable 'perl -l' effects - print "$_[0] "; shift; + print $_[0]; shift; my %args = @_; + my $getchar = sub { + ReadMode 'cbreak'; + my $answer = (ReadKey 0); + ReadMode 'normal'; + print $answer; + return $answer; + }; die "$0: called prompt() in non-interactive mode!" if $YES; - ReadMode 'cbreak'; - my $answer = (ReadKey 0); - ReadMode 'restore'; - print $answer, "\n"; + my $answer = $getchar->(); + $answer .= $getchar->() if exists $args{extra} and $answer =~ $args{extra}; + say "" unless $args{dontprint}; return $args{verbose} ? $answer : ($answer =~ /^y/i) ? 1 : 0; } + sub merge { my %entry = @_; + $MERGED_SOMETHING++; my ($logmsg_fh, $logmsg_filename) = tempfile(); my ($mergeargs, $pattern); @@ -90,26 +167,26 @@ sub merge { $pattern = sprintf '\V\(%s branch(es)?\|branches\/%s\|Branch\(es\)\?: \*\n\? \*%s\)', $entry{branch}, $entry{branch}, $entry{branch}; if ($SVNvsn >= 1_008_000) { $mergeargs = "$BRANCHES/$entry{branch}"; - print $logmsg_fh "Merge the $entry{header}:"; + say $logmsg_fh "Merge the $entry{header}:"; } else { $mergeargs = "--reintegrate $BRANCHES/$entry{branch}"; - print $logmsg_fh "Reintegrate the $entry{header}:"; + say $logmsg_fh "Reintegrate the $entry{header}:"; } - print $logmsg_fh ""; + say $logmsg_fh ""; } elsif (@{$entry{revisions}}) { $pattern = '^ [*] \V' . 'r' . $entry{revisions}->[0]; $mergeargs = join " ", (map { "-c$_" } @{$entry{revisions}}), '^/subversion/trunk'; if (@{$entry{revisions}} > 1) { - print $logmsg_fh "Merge the $entry{header} from trunk:"; - print $logmsg_fh ""; + say $logmsg_fh "Merge the $entry{header} from trunk:"; + say $logmsg_fh ""; } else { - print $logmsg_fh "Merge r$entry{revisions}->[0] from trunk:"; - print $logmsg_fh ""; + say $logmsg_fh "Merge r$entry{revisions}->[0] from trunk:"; + say $logmsg_fh ""; } } else { die "Don't know how to call $entry{header}"; } - print $logmsg_fh $_ for @{$entry{entry}}; + say $logmsg_fh $_ for @{$entry{entry}}; close $logmsg_fh or die "Can't close $logmsg_filename: $!"; my $reintegrated_word = ($SVNvsn >= 1_008_000) ? "merged" : "reintegrated"; @@ -120,9 +197,11 @@ if $DEBUG; then set -x fi $SVN diff > $backupfile -cp STATUS STATUS.$$ +if ! $MAY_COMMIT ; then + cp STATUS STATUS.$$ +fi $SVNq revert -R . -if $MAY_COMMIT ; then +if ! $MAY_COMMIT ; then mv STATUS.$$ STATUS fi $SVNq up @@ -140,7 +219,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 -else +elif test 1 -ne $YES; then echo "Would have committed:" echo '[[[' $SVN status -q @@ -157,16 +236,22 @@ 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 -else - echo "Removing $reintegrated_word '$entry{branch}' branch" +elif test 1 -ne $YES; then + echo "Would remove $reintegrated_word '$entry{branch}' branch" fi 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 $?; + + if (-z $backupfile) { + unlink $backupfile; + } else { + warn "Local mods saved to '$backupfile'\n"; + } - unlink $backupfile if -z $backupfile; unlink $logmsg_filename unless $? or $!; } @@ -180,7 +265,9 @@ sub sanitize_branch { # TODO: may need to parse other headers too? sub parse_entry { + my $raw = shift; my @lines = @_; + my $depends; my (@revisions, @logsummary, $branch, @votes); # @lines = @_; @@ -209,6 +296,10 @@ sub parse_entry { unshift @votes, pop until $_[-1] =~ /^\s*Votes:/ or not defined $_[-1]; pop; + # depends + # TODO: parse the value of this. + $depends = grep /^Depends:/, @_; + # branch while (@_) { shift and next unless $_[0] =~ s/^\s*Branch(es)?:\s*//; @@ -216,9 +307,11 @@ sub parse_entry { } # Compute a header. - my $header; + my ($header, $id); $header = "r$revisions[0] group" if @revisions; - $header = "$branch branch" if $branch; + $id = "r$revisions[0]" if @revisions; + $header = "$branch branch" if $branch; + $id = $branch if $branch; warn "No header for [@lines]" unless $header; return ( @@ -226,49 +319,338 @@ sub parse_entry { logsummary => [@logsummary], branch => $branch, header => $header, + depends => $depends, + id => $id, votes => [@votes], entry => [@lines], + raw => $raw, + digest => digest_string($raw), ); } +sub edit_string { + # Edits $_[0] in an editor. + # $_[1] is used in error messages. + die "$0: called edit_string() in non-interactive mode!" if $YES; + my $string = shift; + my $name = shift; + my %args = @_; + my $trailing_eol = $args{trailing_eol}; + my ($fh, $fn) = tempfile; + print $fh $string; + $fh->flush or die $!; + system("$EDITOR -- $fn") == 0 + or warn "\$EDITOR failed editing $name: $! ($?); " + ."edit results ($fn) ignored."; + my $rv = `cat $fn`; + $rv =~ s/\n*\z// and $rv .= ("\n" x $trailing_eol) if defined $trailing_eol; + $rv; +} + +sub vote { + my ($state, $approved, $votes) = @_; + # TODO: use votesarray instead of votescheck + my (%approvedcheck, %votescheck); + my $raw_approved = ""; + my @votesarray; + return unless %$approved or %$votes; + + my $had_empty_line; + + $. = 0; + open STATUS, "<", $STATUS; + open VOTES, ">", "$STATUS.$$.tmp"; + while (<STATUS>) { + $had_empty_line = /\n\n\z/; + my $key = digest_string $_; + + $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}) { + 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 @votesarray, { + entry => $entry, + vote => $vote, + approval => (exists $approved->{$key}), + digest => $key, + }; + + if ($vote eq 'edit') { + local $_ = $entry->{raw}; + $votesarray[-1]->{digest} = digest_string $_; + (exists $approved->{$key}) ? ($raw_approved .= $_) : (print VOTES); + next; + } + + s/^(\s*\Q$vote\E:.*)/"$1, $AVAILID"/me + or s/(.*\w.*?\n)/"$1 $vote: $AVAILID\n"/se; + $_ = edit_string $_, $entry->{header}, trailing_eol => 2 + if $vote ne '+1'; + $votesarray[-1]->{digest} = digest_string $_; + (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; + warn "Some vote chunks weren't found: ", + join ',', + map $votes->{$_}->[1]->{id}, + grep { !$votescheck{$_} } keys %$votes + if scalar(keys %$votes) != scalar(keys %votescheck); + 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 @sentences = map { + my $words_vote = ", approving" x $_->{approval}; + my $words_edit = " and approve" x $_->{approval}; + exists $_->{vote} + ? ( + ( $_->{vote} eq 'edit' + ? "Edit$words_edit the $_->{entry}->{id} entry" + : "Vote $_->{vote} on the $_->{entry}->{header}$words_vote" + ) + . "." + ) + : # exists only in $approved + "Approve the $_->{entry}->{header}." + } @votesarray; + (@sentences == 1) + ? $sentences[0] + : "* STATUS:\n" . join "", map " $_\n", @sentences; + }; + + system "$SVN diff -- $STATUS"; + 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") 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->{$_->{digest}}++ for @votesarray; + } +} + +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; +} + +sub maybe_revert { + # This is both a SIGINT handler, and the tail end of main() in normal runs. + # @_ is 'INT' in the former case and () in the latter. + delete $SIG{INT} unless @_; + revert if !$YES and $MERGED_SOMETHING and prompt 'Revert? '; + (@_ ? exit : return); +} + +sub warning_summary { + return unless %ERRORS; + + warn "Warning summary\n"; + warn "===============\n"; + warn "\n"; + for my $header (keys %ERRORS) { + warn "$header: $ERRORS{$header}\n"; + } +} + +sub read_state { + # die "$0: called read_state() in non-interactive mode!" if $YES; + + open my $fh, '<', $STATEFILE or do { + return {} if $!{ENOENT}; + die "Can't read statefile: $!"; + }; + + my %rv; + while (<$fh>) { + chomp; + $rv{$_}++; + } + return \%rv; +} + +sub write_state { + my $state = shift; + open STATE, '>', $STATEFILE or warn("Can't write state: $!"), return; + say STATE for keys %$state; + close STATE; +} + +sub exit_stage_left { + my $state = shift; + maybe_revert; + warning_summary if $YES; + vote $state, @_; + write_state $state; + exit scalar keys %ERRORS; +} + sub handle_entry { my $in_approved = shift; - my %entry = parse_entry @_; + my $approved = shift; + my $votes = shift; + my $state = shift; + my $raw = shift; + my %entry = parse_entry $raw, @_; my @vetoes = grep { /^ -1:/ } @{$entry{votes}}; if ($YES) { - merge %entry if $in_approved and not @vetoes; + # Run a merge if: + unless (@vetoes) { + if ($MAY_COMMIT eq 'true' and $in_approved) { + # svn-role mode + merge %entry; + } elsif ($MAY_COMMIT ne 'true') { + # Scan-for-conflicts mode + merge %entry; + + my $output = `$SVN status`; + my (@conflicts) = ($output =~ m#^(?:C...|.C..|...C)...\s(.*)#mg); + if (@conflicts and !$entry{depends}) { + $ERRORS{$entry{id}} //= "Conflicts merging the $entry{header}: " + . (join ', ', map m#.*/(.*)#, @conflicts); + say STDERR "Conflicts merging the $entry{header}!"; + say STDERR ""; + say STDERR $output; + system "$SVN diff -- @conflicts"; + } elsif (!@conflicts and $entry{depends}) { + # Not a warning since svn-role may commit the dependency without + # also committing the dependent in hte same pass. + print "No conflicts merging $entry{id}, but conflicts were " + ."expected ('Depends:' header set)\n"; + } elsif (@conflicts) { + say "Conflicts found merging $entry{id}, as expected."; + } + revert; + } + } + } elsif ($state->{$entry{digest}}) { + print "\n\n"; + say "Skipping the $entry{header} (remove $STATEFILE to reset):"; + say $entry{logsummary}->[0], ('[...]' x (0 < $#{$entry{logsummary}})); } else { - print ""; - print "\n>>> The $entry{header}:"; - print join ", ", map { "r$_" } @{$entry{revisions}}; - print "$BRANCHES/$entry{branch}" if $entry{branch}; - print ""; - print for @{$entry{logsummary}}; - print ""; - print for @{$entry{votes}}; - print ""; - print "Vetoes found!" if @vetoes; - - if (prompt 'Go ahead?') { - merge %entry; - MAYBE_DIFF: while (1) { - given (prompt "Shall I open a subshell? [ydN]", verbose => 1) { - when (/^y/i) { - system($ENV{SHELL} // "/bin/sh") == 0 - or warn "Creating an interactive subshell failed ($?): $!" - } - when (/^d/) { - system($SVN, 'diff') == 0 - or warn "diff failed ($?): $!"; - next; + # 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 join ", ", map { "r$_" } @{$entry{revisions}} if @{$entry{revisions}}; + say "$BRANCHES/$entry{branch}" if $entry{branch}; + say ""; + say for @{$entry{logsummary}}; + say ""; + say for @{$entry{votes}}; + say ""; + say "Vetoes found!" if @vetoes; + + # See above for why the while(1). + QUESTION: while (1) { + my $key = $entry{digest}; + given (prompt 'Run a merge? [y,l,±1,±0,q,e,a, ,N] ', + verbose => 1, extra => qr/[+-]/) { + when (/^y/i) { + merge %entry; + while (1) { + given (prompt "Shall I open a subshell? [ydN] ", verbose => 1) { + when (/^y/i) { + system($SHELL) == 0 + or warn "Creating an interactive subshell failed ($?): $!" + } + when (/^d/) { + system("$SVN diff | $PAGER") == 0 + or warn "diff failed ($?): $!"; + next; + } } + revert; + next PROMPT; } - last; + # NOTREACHED + } + when (/^l/i) { + if ($entry{branch}) { + system "$SVN log --stop-on-copy -v -r 0:HEAD -- " + ."$BRANCHES/$entry{branch} " + ."| $PAGER"; + } elsif (@{$entry{revisions}}) { + system "$SVN log ".(join ' ', map { "-r$_" } @{$entry{revisions}}) + ." -- ^/subversion | $PAGER"; + } else { + die "Assertion failed: entry has neither branch nor revisions:\n", + '[[[', (join ';;', %entry), ']]]'; + } + next PROMPT; + } + when (/^q/i) { + exit_stage_left $state, $approved, $votes; + } + when (/^a/i) { + $approved->{$key} = \%entry; + next PROMPT; + } + 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}; + $entry{raw} = edit_string $entry{raw}, $entry{header}, + 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. + } + default { + say "Please use one of the options in brackets (q to quit)!"; + next QUESTION; } - # Don't revert. The next merge() call will do that anyway, or maybe the - # user did in his interactive shell. } + last; } # QUESTION + last; } # PROMPT } # TODO: merge() changes ./STATUS, which we're reading below, but @@ -277,43 +659,51 @@ sub handle_entry { 1; } -sub maybe_revert { - # This is both a SIGINT handler, and the tail end of main() in normal runs. - system $SVN, qw/revert -R ./ if !$YES and prompt 'Revert? '; - exit if @_; -} - + sub main { + my %approved; + my %votes; + my $state = read_state; + usage, exit 0 if @ARGV; open STATUS, "<", $STATUS or (usage, exit 1); # Because we use the ':normal' command in Vim... - die "A vim with the +ex_extra feature is required" - if `${VIM} --version` !~ /[+]ex_extra/; + die "A vim with the +ex_extra feature is required for \$MAY_COMMIT mode" + if $MAY_COMMIT eq 'true' and `${VIM} --version` !~ /[+]ex_extra/; # ### TODO: need to run 'revert' here # ### TODO: both here and in merge(), unlink files that previous merges added # When running from cron, there shouldn't be local mods. (For interactive # usage, we preserve local mods to STATUS.) - die "Local mods to STATUS file $STATUS" if $YES and `$SVN status -q $STATUS`; + 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; + } # Skip most of the file + $/ = ""; # paragraph mode while (<STATUS>) { last if /^Status of \d+\.\d+/; } - $/ = ""; # paragraph mode - $SIG{INT} = \&maybe_revert; + $SIG{INT} = \&maybe_revert unless $YES; my $in_approved = 0; while (<STATUS>) { + my $lines = $_; my @lines = split /\n/; given ($lines[0]) { # Section header when (/^[A-Z].*:$/i) { - print "\n\n=== $lines[0]" unless $YES; + say "\n\n=== $lines[0]" unless $YES; $in_approved = $lines[0] =~ /^Approved changes/; } # Comment @@ -328,15 +718,15 @@ sub main { when (/^ \*/) { warn "Too many bullets in $lines[0]" and next if grep /^ \*/, @lines[1..$#lines]; - handle_entry $in_approved, @lines; + handle_entry $in_approved, \%approved, \%votes, $state, $lines, @lines; } default { - warn "Unknown entry '$lines[0]' at line $.\n"; + warn "Unknown entry '$lines[0]'"; } } } - maybe_revert; + exit_stage_left $state, \%approved, \%votes; } &main Modified: subversion/branches/fsfs-format7/win-tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/win-tests.py?rev=1507012&r1=1507011&r2=1507012&view=diff ============================================================================== --- subversion/branches/fsfs-format7/win-tests.py (original) +++ subversion/branches/fsfs-format7/win-tests.py Thu Jul 25 15:29:49 2013 @@ -84,6 +84,8 @@ def _usage_exit(): print(" --disable-bulk-updates : Disable bulk updates on HTTP server") print(" --ssl-cert : Path to SSL server certificate to trust.") print(" --javahl : Run the javahl tests instead of the normal tests") + print(" --swig=language : Run the swig perl/python/ruby tests instead of") + print(" the normal tests") print(" --list : print test doc strings only") print(" --milestone-filter=RE : RE is a regular expression pattern that (when") print(" used with --list) limits the tests listed to") @@ -108,29 +110,24 @@ CMDLINE_TEST_SCRIPT_NATIVE_PATH = CMDLIN sys.path.insert(0, os.path.join('build', 'generator')) sys.path.insert(1, 'build') -import gen_win +import gen_win_dependencies +import gen_base version_header = os.path.join('subversion', 'include', 'svn_version.h') cp = configparser.ConfigParser() cp.read('gen-make.opts') -gen_obj = gen_win.GeneratorBase('build.conf', version_header, - cp.items('options')) +gen_obj = gen_win_dependencies.GenDependenciesBase('build.conf', version_header, + cp.items('options')) all_tests = gen_obj.test_progs + gen_obj.bdb_test_progs \ + gen_obj.scripts + gen_obj.bdb_scripts client_tests = [x for x in all_tests if x.startswith(CMDLINE_TEST_SCRIPT_PATH)] -svn_dlls = [] -for section in gen_obj.sections.values(): - if section.options.get("msvc-export"): - dll_basename = section.name + "-" + str(gen_obj.version) + ".dll" - svn_dlls.append(os.path.join("subversion", section.name, dll_basename)) - opts, args = my_getopt(sys.argv[1:], 'hrdvqct:pu:f:', ['release', 'debug', 'verbose', 'quiet', 'cleanup', 'test=', 'url=', 'svnserve-args=', 'fs-type=', 'asp.net-hack', 'httpd-dir=', 'httpd-port=', 'httpd-daemon', 'httpd-server', 'http-short-circuit', 'httpd-no-log', 'disable-http-v2', 'disable-bulk-updates', 'help', - 'fsfs-packing', 'fsfs-sharding=', 'javahl', + 'fsfs-packing', 'fsfs-sharding=', 'javahl', 'swig=', 'list', 'enable-sasl', 'bin=', 'parallel', 'config-file=', 'server-minor-version=', 'log-level=', 'log-to-stdout', 'mode-filter=', 'milestone-filter=', @@ -156,6 +153,7 @@ http_bulk_updates = True list_tests = None milestone_filter = None test_javahl = None +test_swig = None enable_sasl = None svn_bin = None parallel = None @@ -216,6 +214,11 @@ for opt, val in opts: fsfs_packing = 1 elif opt == '--javahl': test_javahl = 1 + elif opt == '--swig': + if val not in ['perl', 'python', 'ruby']: + sys.stderr.write('Running \'%s\' swig tests not supported (yet).\n' + % (val,)) + test_swig = val elif opt == '--list': list_tests = 1 elif opt == '--milestone-filter': @@ -289,12 +292,18 @@ def create_target_dir(dirname): print("mkdir: %s" % tgt_dir) os.makedirs(tgt_dir) -def copy_changed_file(src, tgt): +def copy_changed_file(src, tgt=None, to_dir=None, cleanup=True): if not os.path.isfile(src): print('Could not find ' + src) sys.exit(1) - if os.path.isdir(tgt): - tgt = os.path.join(tgt, os.path.basename(src)) + + if to_dir and not tgt: + tgt = os.path.join(to_dir, os.path.basename(src)) + elif not tgt or (tgt and to_dir): + raise RuntimeError("Using 'tgt' *or* 'to_dir' is required" % (tgt,)) + elif tgt and os.path.isdir(tgt): + raise RuntimeError("'%s' is a directory. Use to_dir=" % (tgt,)) + if os.path.exists(tgt): assert os.path.isfile(tgt) if filecmp.cmp(src, tgt): @@ -306,57 +315,35 @@ def copy_changed_file(src, tgt): print("copy: %s" % src) print(" to: %s" % tgt) shutil.copy(src, tgt) - return 1 -def copy_execs(baton, dirname, names): - copied_execs = baton - for name in names: - if not name.endswith('.exe'): - continue - src = os.path.join(dirname, name) - tgt = os.path.join(abs_builddir, dirname, name) - create_target_dir(dirname) - if copy_changed_file(src, tgt): - copied_execs.append(tgt) + if cleanup: + copied_execs.append(tgt) def locate_libs(): "Move DLLs to a known location and set env vars" - dlls = [] - - # look for APR 1.x dll's and use those if found - apr_test_path = os.path.join(gen_obj.apr_path, objdir, 'libapr-1.dll') - if os.path.exists(apr_test_path): - suffix = "-1" - else: - suffix = "" - - if cp.has_option('options', '--with-static-apr'): - dlls.append(os.path.join(gen_obj.apr_path, objdir, - 'libapr%s.dll' % (suffix))) - dlls.append(os.path.join(gen_obj.apr_util_path, objdir, - 'libaprutil%s.dll' % (suffix))) - - if gen_obj.libintl_path is not None: - dlls.append(os.path.join(gen_obj.libintl_path, 'bin', 'intl3_svn.dll')) + debug = (objdir == 'Debug') + + for lib in gen_obj._libraries.values(): + + if debug: + name, dir = lib.debug_dll_name, lib.debug_dll_dir + else: + name, dir = lib.dll_name, lib.dll_dir + + if name and dir: + src = os.path.join(dir, name) + if os.path.exists(src): + copy_changed_file(src, to_dir=abs_builddir, cleanup=False) - if gen_obj.bdb_lib is not None: - partial_path = os.path.join(gen_obj.bdb_path, 'bin', gen_obj.bdb_lib) - if objdir == 'Debug': - dlls.append(partial_path + 'd.dll') - else: - dlls.append(partial_path + '.dll') - - if gen_obj.sasl_path is not None: - dlls.append(os.path.join(gen_obj.sasl_path, 'lib', 'libsasl.dll')) - - for dll in dlls: - copy_changed_file(dll, abs_objdir) # Copy the Subversion library DLLs - if not cp.has_option('options', '--disable-shared'): - for svn_dll in svn_dlls: - copy_changed_file(os.path.join(abs_objdir, svn_dll), abs_objdir) + for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL): + if isinstance(i, gen_base.TargetLib) and i.msvc_export: + src = os.path.join(abs_objdir, i.filename) + if os.path.isfile(src): + copy_changed_file(src, to_dir=abs_builddir, + cleanup=False) # Copy the Apache modules if run_httpd and cp.has_option('options', '--with-httpd'): @@ -367,11 +354,11 @@ def locate_libs(): mod_dontdothat_path = os.path.join(abs_objdir, 'tools', 'server-side', 'mod_dontdothat', 'mod_dontdothat.so') - copy_changed_file(mod_dav_svn_path, abs_objdir) - copy_changed_file(mod_authz_svn_path, abs_objdir) - copy_changed_file(mod_dontdothat_path, abs_objdir) + copy_changed_file(mod_dav_svn_path, to_dir=abs_builddir, cleanup=False) + copy_changed_file(mod_authz_svn_path, to_dir=abs_builddir, cleanup=False) + copy_changed_file(mod_dontdothat_path, to_dir=abs_builddir, cleanup=False) - os.environ['PATH'] = abs_objdir + os.pathsep + os.environ['PATH'] + os.environ['PATH'] = abs_builddir + os.pathsep + os.environ['PATH'] def fix_case(path): path = os.path.normpath(path) @@ -688,21 +675,17 @@ class Httpd: print('Httpd.stop_daemon not implemented') # Move the binaries to the test directory +create_target_dir(abs_builddir) locate_libs() if create_dirs: - old_cwd = os.getcwd() - try: - os.chdir(abs_objdir) - baton = copied_execs - for dirpath, dirs, files in os.walk('subversion'): - copy_execs(baton, dirpath, files) - for dirpath, dirs, files in os.walk('tools/server-side'): - copy_execs(baton, dirpath, files) - except: - os.chdir(old_cwd) - raise - else: - os.chdir(old_cwd) + for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL): + if isinstance(i, gen_base.TargetExe): + src = os.path.join(abs_objdir, i.filename) + + if os.path.isfile(src): + dst = os.path.join(abs_builddir, i.filename) + create_target_dir(os.path.dirname(dst)) + copy_changed_file(src, dst) # Create the base directory for Python tests create_target_dir(CMDLINE_TEST_SCRIPT_NATIVE_PATH) @@ -760,7 +743,7 @@ else: print('Testing %s configuration on %s' % (objdir, repo_loc)) sys.path.insert(0, os.path.join(abs_srcdir, 'build')) -if not test_javahl: +if not test_javahl and not test_swig: import run_tests if log_to_stdout: log_file = None @@ -788,7 +771,7 @@ if not test_javahl: raise else: os.chdir(old_cwd) -else: +elif test_javahl: failed = False args = ( 'java.exe', @@ -826,6 +809,148 @@ else: if (r != 0): print('[Test runner reported failure]') failed = True +elif test_swig == 'perl': + failed = False + swig_dir = os.path.join(abs_builddir, 'swig') + swig_pl_dir = os.path.join(swig_dir, 'p5lib') + swig_pl_svn = os.path.join(swig_pl_dir, 'SVN') + swig_pl_auto_svn = os.path.join(swig_pl_dir, 'auto', 'SVN') + + create_target_dir(swig_pl_svn) + + for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL): + if isinstance(i, gen_base.TargetSWIG) and i.lang == 'perl': + mod_dir = os.path.join(swig_pl_auto_svn, '_' + i.name[5:].capitalize()) + create_target_dir(mod_dir) + copy_changed_file(os.path.join(abs_objdir, i.filename), to_dir=mod_dir) + + elif isinstance(i, gen_base.TargetSWIGLib) and i.lang == 'perl': + copy_changed_file(os.path.join(abs_objdir, i.filename), + to_dir=abs_builddir) + + pm_src = os.path.join(abs_srcdir, 'subversion', 'bindings', 'swig', 'perl', + 'native') + + tests = [] + + for root, dirs, files in os.walk(pm_src): + for name in files: + if name.endswith('.pm'): + fn = os.path.join(root, name) + copy_changed_file(fn, to_dir=swig_pl_svn) + elif name.endswith('.t'): + tests.append(os.path.relpath(os.path.join(root, name), pm_src)) + + perl5lib = swig_pl_dir + if 'PERL5LIB' in os.environ: + perl5lib += os.pathsep + os.environ['PERL5LIB'] + + perl_exe = 'perl.exe' + + print('-- Running Swig Perl tests --') + old_cwd = os.getcwd() + try: + os.chdir(pm_src) + + os.environ['PERL5LIB'] = perl5lib + os.environ["SVN_DBG_NO_ABORT_ON_ERROR_LEAK"] = 'YES' + + r = subprocess.call([ + perl_exe, + '-MExtUtils::Command::MM', + '-e', 'test_harness()' + ] + tests) + finally: + os.chdir(old_cwd) + + if (r != 0): + print('[Test runner reported failure]') + failed = True + +elif test_swig == 'python': + failed = False + swig_dir = os.path.join(abs_builddir, 'swig') + swig_py_dir = os.path.join(swig_dir, 'pylib') + swig_py_libsvn = os.path.join(swig_py_dir, 'libsvn') + swig_py_svn = os.path.join(swig_py_dir, 'svn') + + create_target_dir(swig_py_libsvn) + create_target_dir(swig_py_svn) + + for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL): + if (isinstance(i, gen_base.TargetSWIG) + or isinstance(i, gen_base.TargetSWIGLib)) and i.lang == 'python': + + src = os.path.join(abs_objdir, i.filename) + copy_changed_file(src, to_dir=swig_py_libsvn) + + py_src = os.path.join(abs_srcdir, 'subversion', 'bindings', 'swig', 'python') + + for py_file in os.listdir(py_src): + if py_file.endswith('.py'): + copy_changed_file(os.path.join(py_src, py_file), + to_dir=swig_py_libsvn) + + py_src_svn = os.path.join(py_src, 'svn') + for py_file in os.listdir(py_src_svn): + if py_file.endswith('.py'): + copy_changed_file(os.path.join(py_src_svn, py_file), + to_dir=swig_py_svn) + + print('-- Running Swig Python tests --') + + pythonpath = swig_py_dir + if 'PYTHONPATH' in os.environ: + pythonpath += os.pathsep + os.environ['PYTHONPATH'] + + python_exe = 'python.exe' + old_cwd = os.getcwd() + try: + os.environ['PYTHONPATH'] = pythonpath + + r = subprocess.call([ + python_exe, + os.path.join(py_src, 'tests', 'run_all.py') + ]) + finally: + os.chdir(old_cwd) + + if (r != 0): + print('[Test runner reported failure]') + failed = True + +elif test_swig == 'ruby': + failed = False + + if 'ruby' not in gen_obj._libraries: + print('Ruby not found. Skipping Ruby tests') + else: + ruby_lib = gen_obj._libraries['ruby'] + + ruby_exe = 'ruby.exe' + ruby_subdir = os.path.join('subversion', 'bindings', 'swig', 'ruby') + ruby_args = [ + '-I', os.path.join(abs_srcdir, ruby_subdir), + os.path.join(abs_srcdir, ruby_subdir, 'test', 'run-test.rb'), + '--verbose' + ] + + print('-- Running Swig Ruby tests --') + old_cwd = os.getcwd() + try: + os.chdir(ruby_subdir) + + os.environ["BUILD_TYPE"] = objdir + os.environ["SVN_DBG_NO_ABORT_ON_ERROR_LEAK"] = 'YES' + r = subprocess.call([ruby_exe] + ruby_args) + finally: + os.chdir(old_cwd) + + sys.stdout.flush() + sys.stderr.flush() + if (r != 0): + print('[Test runner reported failure]') + failed = True # Stop service daemon, if any if daemon:
