Modified: subversion/branches/revprop-packing/subversion/tests/libsvn_subr/checksum-test.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/tests/libsvn_subr/checksum-test.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/tests/libsvn_subr/checksum-test.c (original) +++ subversion/branches/revprop-packing/subversion/tests/libsvn_subr/checksum-test.c Mon Mar 5 09:25:25 2012 @@ -59,11 +59,34 @@ test_checksum_parse(apr_pool_t *pool) return SVN_NO_ERROR; } +static svn_error_t * +test_checksum_empty(apr_pool_t *pool) +{ + svn_checksum_t *checksum; + char data = '\0'; + + checksum = svn_checksum_empty_checksum(svn_checksum_md5, pool); + SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum)); + + checksum = svn_checksum_empty_checksum(svn_checksum_sha1, pool); + SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum)); + + SVN_ERR(svn_checksum(&checksum, svn_checksum_md5, &data, 0, pool)); + SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum)); + + SVN_ERR(svn_checksum(&checksum, svn_checksum_sha1, &data, 0, pool)); + SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum)); + + return SVN_NO_ERROR; +} + /* An array of all test functions */ struct svn_test_descriptor_t test_funcs[] = { SVN_TEST_NULL, SVN_TEST_PASS2(test_checksum_parse, "checksum parse"), + SVN_TEST_PASS2(test_checksum_empty, + "checksum emptiness"), SVN_TEST_NULL };
Modified: subversion/branches/revprop-packing/subversion/tests/libsvn_subr/spillbuf-test.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/tests/libsvn_subr/spillbuf-test.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/tests/libsvn_subr/spillbuf-test.c (original) +++ subversion/branches/revprop-packing/subversion/tests/libsvn_subr/spillbuf-test.c Mon Mar 5 09:25:25 2012 @@ -112,7 +112,7 @@ test_spillbuf_callback(apr_pool_t *pool) SVN_ERR(svn_spillbuf__process(&exhausted, buf, read_callback, &counter, pool)); SVN_TEST_ASSERT(!exhausted); - + SVN_ERR(svn_spillbuf__process(&exhausted, buf, read_callback, &counter, pool)); SVN_TEST_ASSERT(exhausted); Modified: subversion/branches/revprop-packing/subversion/tests/libsvn_subr/stream-test.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/tests/libsvn_subr/stream-test.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/tests/libsvn_subr/stream-test.c (original) +++ subversion/branches/revprop-packing/subversion/tests/libsvn_subr/stream-test.c Mon Mar 5 09:25:25 2012 @@ -611,6 +611,165 @@ test_stream_copy(apr_pool_t *pool) return SVN_NO_ERROR; } +/* This test doesn't test much unless run under valgrind when it + triggers the problem reported here: + + http://mail-archives.apache.org/mod_mbox/subversion-dev/201202.mbox/%[email protected]%3E + + The two data writes caused the base 64 code to allocate a buffer + that was a byte short but exactly matched a stringbuf blocksize. + That meant the stringbuf didn't overallocate and a write beyond + the end of the buffer occured. + */ +static svn_error_t * +test_stream_base64_2(apr_pool_t *pool) +{ + const struct data_t { + const char *encoded1; + const char *encoded2; + } data[] = { + { + "MTI", + "123456789A123456789B123456789C123456789D123456789E" + "223456789A123456789B123456789C123456789D123456789E" + "323456789A123456789B123456789C123456789D123456789E" + "423456789A123456789B123456789C123456789D123456789E" + "523456789A123456789B123456789C123456789D123456789E" + "623456789A123456789B123456789C123456789D123456789E" + "723456789A123456789B123456789C123456789D123456789E" + "823456789A123456789B123456789C123456789D123456789E" + "923456789A123456789B123456789C123456789D123456789E" + "A23456789A123456789B123456789C123456789D123456789E" + "123456789A123456789B123456789C123456789D123456789E" + "223456789A123456789B123456789C123456789D123456789E" + "323456789A123456789B123456789C123456789D123456789E" + "423456789A123456789B123456789C123456789D123456789E" + "523456789A123456789B123456789C123456789D123456789E" + "623456789A123456789B123456789C123456789D123456789E" + "723456789A123456789B123456789C123456789D123456789E" + "823456789A123456789B123456789C123456789D123456789E" + "923456789A123456789B123456789C123456789D123456789E" + "B23456789A123456789B123456789C123456789D123456789E" + "123456789A123456789B123456789C123456789D123456789E" + "223456789A123456789B123456789C123456789D123456789E" + "323456789A123456789B123456789C123456789D123456789E" + "423456789A123456789B123456789C123456789D123456789E" + "523456789A123456789B123456789C123456789D123456789E" + "623456789A123456789B123456789C123456789D123456789E" + "723456789A123456789B123456789C123456789D123456789E" + "823456789A123456789B123456789C123456789D123456789E" + "923456789A123456789B123456789C123456789D123456789E" + "C23456789A123456789B123456789C123456789D123456789E" + "123456789A123456789B123456789C123456789D123456789E" + "223456789A123456789B123456789C123456789D123456789E" + "323456789A123456789B123456789C123456789D123456789E" + "423456789A123456789B123456789C123456789D123456789E" + "523456789A123456789B123456789C123456789D123456789E" + "623456789A123456789B123456789C123456789D123456789E" + "723456789A123456789B123456789C123456789D123456789E" + "823456789A123456789B123456789C123456789D123456789E" + "923456789A123456789B123456789C123456789D123456789E" + "D23456789A123456789B123456789C123456789D123456789E" + "123456789A123456789B123456789C123456789D123456789E" + "223456789A123456789B123456789C123456789D123456789E" + "323456789A123456789B123456789C123456789D123456789E" + "423456789A123456789B123456789C123456789D123456789E" + "523456789A123456789B123456789C123456789D123456789E" + "623456789A123456789B123456789C123456789D123456789E" + "723456789A123456789B123456789C123456789D123456789E" + "823456789A123456789B123456789C123456789D123456789E" + "923456789A123456789B123456789C123456789D123456789E" + "E23456789A123456789B123456789C123456789D123456789E" + "123456789A123456789B123456789C123456789D123456789E" + "223456789A123456789B123456789C123456789D123456789E" + "323456789A123456789B123456789C123456789D123456789E" + "423456789A123456789B123456789C123456789D123456789E" + "523456789A123456789B123456789C123456789D123456789E" + "623456789A123456789B123456789C123456789D123456789E" + "723456789A123456789B123456789C123456789D123456789E" + "823456789A123456789B123456789C123456789D123456789E" + "923456789A123456789B123456789C123456789D123456789E" + "F23456789A123456789B123456789C123456789D123456789E" + "123456789A123456789B123456789C123456789D123456789E" + "223456789A123456789B123456789C123456789D123456789E" + "323456789A123456789B123456789C123456789D123456789E" + "423456789A123456789B123456789C123456789D123456789E" + "523456789A123456789B123456789C123456789D123456789E" + "623456789A123456789B123456789C123456789D123456789E" + "723456789A123456789B123456789C123456789D123456789E" + "823456789A123456789B123456789C123456789D123456789E" + "923456789A123456789B123456789C123456789D123456789E" + "G23456789A123456789B123456789C123456789D123456789E" + "123456789A123456789B123456789C123456789D123456789E" + "223456789A123456789B123456789C123456789D123456789E" + "323456789A123456789B123456789C123456789D123456789E" + "423456789A123456789B123456789C123456789D123456789E" + "523456789A123456789B123456789C123456789D123456789E" + "623456789A123456789B123456789C123456789D123456789E" + "723456789A123456789B123456789C123456789D123456789E" + "823456789A123456789B123456789C123456789D123456789E" + "923456789A123456789B123456789C123456789D123456789E" + "H23456789A123456789B123456789C123456789D123456789E" + "123456789A123456789B123456789C123456789D123456789E" + "223456789A123456789B123456789C123456789D123456789E" + "323456789A123456789B123456789C123456789D123456789E" + "423456789A123456789B123456789C123456789D123456789E" + "523456789A123456789B123456789C123456789D123456789E" + "623456789A123456789B123456789C123456789D123456789E" + "723456789A123456789B123456789C123456789D123456789E" + "823456789A123456789B123456789C123456789D123456789E" + "923456789A123456789B123456789C123456789D123456789E" + "I23456789A123456789B123456789C123456789D123456789E" + "123456789A123456789B123456789C123456789D123456789E" + "223456789A123456789B123456789C123456789D123456789E" + "323456789A123456789B123456789C123456789D123456789E" + "423456789A123456789B123456789C123456789D123456789E" + "523456789A123456789B123456789C123456789D123456789E" + "623456789A123456789B123456789C123456789D123456789E" + "723456789A123456789B123456789C123456789D123456789E" + "823456789A123456789B123456789C123456789D123456789E" + "923456789A123456789B123456789C123456789D123456789E" + "J23456789A123456789B123456789C123456789D123456789E" + "123456789A123456789B123456789C123456789D123456789E" + "223456789A123456789B123456789C123456789D123456789E" + "323456789A123456789B123456789C123456789D123456789E" + "423456789A123456789B123456789C123456789D123456789E" + "523456789A123456789B123456789C123456789D12345" + }, + { + NULL, + NULL, + }, + }; + int i; + + for (i = 0; data[i].encoded1; i++) + { + apr_size_t len1 = strlen(data[i].encoded1); + + svn_stringbuf_t *actual = svn_stringbuf_create_empty(pool); + svn_stringbuf_t *expected = svn_stringbuf_create_empty(pool); + svn_stream_t *stream = svn_stream_from_stringbuf(actual, pool); + + stream = svn_base64_encode(stream, pool); + stream = svn_base64_decode(stream, pool); + + SVN_ERR(svn_stream_write(stream, data[i].encoded1, &len1)); + svn_stringbuf_appendbytes(expected, data[i].encoded1, len1); + + if (data[i].encoded2) + { + apr_size_t len2 = strlen(data[i].encoded2); + SVN_ERR(svn_stream_write(stream, data[i].encoded2, &len2)); + svn_stringbuf_appendbytes(expected, data[i].encoded2, len2); + } + + SVN_ERR(svn_stream_close(stream)); + } + + return SVN_NO_ERROR; +} + /* The test table. */ struct svn_test_descriptor_t test_funcs[] = @@ -636,5 +795,7 @@ struct svn_test_descriptor_t test_funcs[ "test base64 encoding/decoding streams"), SVN_TEST_PASS2(test_stream_copy, "test copying streams"), + SVN_TEST_PASS2(test_stream_base64_2, + "base64 decoding allocation problem"), SVN_TEST_NULL }; Modified: subversion/branches/revprop-packing/subversion/tests/libsvn_wc/op-depth-test.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/tests/libsvn_wc/op-depth-test.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/tests/libsvn_wc/op-depth-test.c (original) +++ subversion/branches/revprop-packing/subversion/tests/libsvn_wc/op-depth-test.c Mon Mar 5 09:25:25 2012 @@ -350,12 +350,12 @@ print_row(const nodes_row_t *row, moved_here_str = ", here"; else moved_here_str = ""; - + if (row->file_external) file_external_str = ", file-external"; else file_external_str = ""; - + if (row->repo_revnum == SVN_INVALID_REVNUM) return apr_psprintf(result_pool, "%d, %s, %s%s%s%s", row->op_depth, row->local_relpath, row->presence, @@ -3727,7 +3727,7 @@ incomplete_switch(const svn_test_opts_t {0} }; - nodes_row_t after_update[] = { + nodes_row_t after_update[] = { {0, "", "normal", 4, "X"}, {0, "B", "normal", 4, "A/B"}, {0, "B/C", "normal", 4, "A/B/C"}, @@ -4195,7 +4195,7 @@ move_to_swap(const svn_test_opts_t *opts SVN_ERR(wc_move(&b, "A/Y", "X/Y")); SVN_ERR(wc_move(&b, "X/B", "A/B")); - + { nodes_row_t nodes[] = { {0, "", "normal", 1, ""}, Modified: subversion/branches/revprop-packing/subversion/tests/libsvn_wc/wc-incomplete-tester.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/tests/libsvn_wc/wc-incomplete-tester.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/subversion/tests/libsvn_wc/wc-incomplete-tester.c (original) +++ subversion/branches/revprop-packing/subversion/tests/libsvn_wc/wc-incomplete-tester.c Mon Mar 5 09:25:25 2012 @@ -78,7 +78,7 @@ int main(int argc, const char *argv[]) "Mark WCPATH incomplete at REVISION [and REPOS_RELPATH]\n"); exit(EXIT_FAILURE); } - + if (apr_initialize()) { fprintf(stderr, "apr_initialize failed\n"); Modified: subversion/branches/revprop-packing/tools/buildbot/slaves/ubuntu-x64/svnbuild.sh URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/buildbot/slaves/ubuntu-x64/svnbuild.sh?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/buildbot/slaves/ubuntu-x64/svnbuild.sh (original) +++ subversion/branches/revprop-packing/tools/buildbot/slaves/ubuntu-x64/svnbuild.sh Mon Mar 5 09:25:25 2012 @@ -30,7 +30,7 @@ echo "========= autogen.sh" echo "========= configure" ./configure --enable-javahl --enable-maintainer-mode \ --without-berkeley-db \ - --with-jdk=/usr/lib/jvm/java-6-openjdk/ \ + --with-jdk=/usr/lib/jvm/java-7-openjdk-amd64/ \ --with-junit=/usr/share/java/junit.jar || exit $? echo "========= make" Modified: subversion/branches/revprop-packing/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd (original) +++ subversion/branches/revprop-packing/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd Mon Mar 5 09:25:25 2012 @@ -32,8 +32,6 @@ IF ERRORLEVEL 1 ( PATH %PATH%;%TESTDIR%\bin SET result=0 - -echo python win-tests.py -r -f fsfs --javahl "%TESTDIR%\tests" python win-tests.py -r -f fsfs --javahl "%TESTDIR%\tests" IF ERRORLEVEL 1 ( echo [python reported error %ERRORLEVEL%] @@ -44,10 +42,10 @@ IF EXIST "%TESTDIR%\swig" rmdir /s /q "% mkdir "%TESTDIR%\swig\py-release\libsvn" mkdir "%TESTDIR%\swig\py-release\svn" -xcopy "release\subversion\bindings\swig\python\*.pyd" "%TESTDIR%\swig\py-release\libsvn\*.pyd" -xcopy "release\subversion\bindings\swig\python\libsvn_swig_py\*.dll" "%TESTDIR%\swig\py-release\libsvn\*.dll" -xcopy "subversion\bindings\swig\python\*.py" "%TESTDIR%\swig\py-release\libsvn\*.py" -xcopy "subversion\bindings\swig\python\svn\*.py" "%TESTDIR%\swig\py-release\svn\*.py" +xcopy "release\subversion\bindings\swig\python\*.pyd" "%TESTDIR%\swig\py-release\libsvn\*.pyd" > nul: +xcopy "release\subversion\bindings\swig\python\libsvn_swig_py\*.dll" "%TESTDIR%\swig\py-release\libsvn\*.dll" > nul: +xcopy "subversion\bindings\swig\python\*.py" "%TESTDIR%\swig\py-release\libsvn\*.py" > nul: +xcopy "subversion\bindings\swig\python\svn\*.py" "%TESTDIR%\swig\py-release\svn\*.py" > nul: SET PYTHONPATH=%TESTDIR%\swig\py-release @@ -57,4 +55,25 @@ IF ERRORLEVEL 1 ( SET result=1 ) +mkdir "%TESTDIR%\swig\pl-release\SVN" +mkdir "%TESTDIR%\swig\pl-release\auto\SVN" +xcopy subversion\bindings\swig\perl\native\*.pm "%TESTDIR%\swig\pl-release\SVN" > nul: +pushd release\subversion\bindings\swig\perl\native +for %%i in (*.dll) do ( + set name=%%i + mkdir "%TESTDIR%\swig\pl-release\auto\SVN\!name:~0,-4!" + xcopy "!name:~0,-4!.*" "%TESTDIR%\swig\pl-release\auto\SVN\!name:~0,-4!" > nul: + xcopy /y "_Core.dll" "%TESTDIR%\swig\pl-release\auto\SVN\!name:~0,-4!" > nul: +) +popd + +SET PERL5LIB=%PERL5LIB%;%TESTDIR%\swig\pl-release; +pushd subversion\bindings\swig\perl\native +perl -MExtUtils::Command::MM -e test_harness() t\*.t +IF ERRORLEVEL 1 ( + echo [Perl reported error %ERRORLEVEL%] + REM SET result=1 +) +popd + exit /b %result% Modified: subversion/branches/revprop-packing/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd (original) +++ subversion/branches/revprop-packing/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd Mon Mar 5 09:25:25 2012 @@ -48,7 +48,9 @@ IF NOT ERRORLEVEL 1 ( ) POPD + taskkill /im svn.exe /f 2> nul: +taskkill /im svnlook.exe /f 2> nul: taskkill /im svnadmin.exe /f 2> nul: taskkill /im svnserve.exe /f 2> nul: taskkill /im svnrdump.exe /f 2> nul: @@ -58,6 +60,9 @@ taskkill /im op-depth-test.exe /f 2> nul IF EXIST "%TESTDIR%\tests\subversion\tests\cmdline\httpd\" ( rmdir /s /q "%TESTDIR%\tests\subversion\tests\cmdline\httpd" ) +IF EXIST "%TESTDIR%\swig\" ( + rmdir /s /q "%TESTDIR%\swig" +) del "%TESTDIR%\tests\*.log" 2> nul: Modified: subversion/branches/revprop-packing/tools/client-side/detach.py URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/client-side/detach.py?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/client-side/detach.py (original) +++ subversion/branches/revprop-packing/tools/client-side/detach.py Mon Mar 5 09:25:25 2012 @@ -67,7 +67,7 @@ def migrate_sqlite(wc_src, target, wcro src_c.execute('select count(*) from wc_lock') count = int(src_c.fetchone()[0]) assert count == 0 - + src_c.execute('select count(*) from work_queue') count = int(src_c.fetchone()[0]) assert count == 0 Modified: subversion/branches/revprop-packing/tools/client-side/mergeinfo-sanitizer.py URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/client-side/mergeinfo-sanitizer.py?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/client-side/mergeinfo-sanitizer.py (original) +++ subversion/branches/revprop-packing/tools/client-side/mergeinfo-sanitizer.py Mon Mar 5 09:25:25 2012 @@ -177,7 +177,7 @@ def sanitize_mergeinfo(parsed_original_m for entry in parsed_original_mergeinfo: get_new_location_segments(parsed_original_mergeinfo[entry], repo_root, wcpath, ctx) full_mergeinfo.update(parsed_original_mergeinfo[entry]) - + hasher(hash_file, newmergeinfo_file) diff_mergeinfo = core.svn_mergeinfo_diff(full_mergeinfo, mergeinfo, 1, temp_pool) @@ -200,7 +200,7 @@ def fix_sanitized_mergeinfo(parsed_origi ctx, hash_file, newmergeinfo_file, temp_pool): has_local_modification = check_local_modifications(wcpath, temp_pool) old_hash = '' - new_hash = '' + new_hash = '' try: with open(hash_file, "r") as f: old_hash = pickle.load(f) @@ -248,7 +248,7 @@ the working copy before running the scri sys.exit(1) def get_original_mergeinfo(wcpath, revision, depth, ctx, temp_pool): - propget_list = client.svn_client_propget3("svn:mergeinfo", wcpath, + propget_list = client.svn_client_propget3("svn:mergeinfo", wcpath, revision, revision, depth, None, ctx, temp_pool) Modified: subversion/branches/revprop-packing/tools/dev/merge-graph.py URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/dev/merge-graph.py?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/dev/merge-graph.py (original) +++ subversion/branches/revprop-packing/tools/dev/merge-graph.py Mon Mar 5 09:25:25 2012 @@ -23,260 +23,8 @@ args_message = 'GRAPH_CONFIG_FILE...' help_message = """Produce pretty graphs representing branches and merging. For each config file specified, construct a graph and write it as a PNG file.""" -# Config file format: -example = """ - [graph] - filename = merge-sync-1.png - title = Sync Merge: CC vs SVN - # Branches: (branch name, branched from node, first rev, last rev). - branches = [ - ('A', 'O0', 1, 4), - ('O', None, 0, 0), - ('B', 'O0', 1, 5) - ] - # Changes: nodes in which a change was committed; merge targets need not - # be listed here. - changes = [ - 'A1', 'A2', 'A3', 'A4', - 'B1', 'B2', 'B3', 'B4', 'B5' - ] - # Merges: (base node, source-right node, target node, label). - # Base is also known as source-left. - merges = [ - ('O0', 'A:1', 'B3', 'sync'), - ('A2', 'A:3', 'B5', 'sync'), - ] - # Annotations for nodes: (node, annotation text). - annotations = [ - ('A2', 'cc:YCA') - ] -""" - -# Notes about different kinds of merge. -# -# A basic 3-way merge is ... -# -# The ClearCase style of merge is a 3-way merge. -# -# The Subversion style of merge (that is, one phase of a Subversion merge) -# is a three-way merge with its base (typically the YCA) on the source branch. - - import sys -import pydot -from pydot import Node, Edge - - -def mergeinfo_to_node_list(mi): - """Convert a mergeinfo string such as '/foo:1,3-5*' into a list of - node names such as ['foo1', 'foo3', 'foo4', 'foo5'].""" - ### Doesn't yet strip the leading slash. - l = [] - if mi: - for mi_str in mi.split(' '): - path, ranges = mi_str.split(':') - for r in ranges.split(','): - if r.endswith('*'): - # TODO: store & use this 'non-inheritable' flag - # Remove the flag - r = r[:-1] - rlist = r.split('-') - r1 = int(rlist[0]) - if len(rlist) == 2: - r2 = int(rlist[1]) - else: - r2 = r1 - for rev in range(r1, r2 + 1): - l.append(path + str(rev)) - return l - - -class MergeGraph(pydot.Graph): - """Base class, not intended for direct use. Use MergeDot for the main - graph and MergeSubgraph for a subgraph.""" - - def mk_origin_node(graph, name, label): - """Add a node to the graph""" - graph.add_node(Node(name, label=label, shape='plaintext')) - - def mk_invis_node(graph, name): - """Add a node to the graph""" - graph.add_node(Node(name, style='invis')) - - def mk_node(graph, name, label=None): - """Add a node to the graph, if not already present""" - if not graph.get_node(name): - if not label: - label = name - if name in graph.changes: - graph.add_node(Node(name, label=label)) - else: - graph.add_node(Node(name, color='grey', label='')) - - def mk_merge_target(graph, target_node, important): - """Add a merge target node to the graph.""" - if important: - color = 'red' - else: - color = 'black' - graph.add_node(Node(target_node, color=color, fontcolor=color, style='bold')) - - def mk_edge(graph, name1, name2, **attrs): - """Add an ordinary edge to the graph""" - graph.add_edge(Edge(name1, name2, dir='none', style='dotted', color='grey', **attrs)) - - def mk_br_edge(graph, name1, name2): - """Add a branch-creation edge to the graph""" - # Constraint=false to avoid the Y-shape skewing the nice parallel branch lines - graph.mk_edge(name1, name2, constraint='false') - - def mk_merge_edge(graph, src_node, tgt_node, kind, label, important): - """Add a merge edge to the graph""" - if important: - color = 'red' - else: - color = 'grey' - e = Edge(src_node, tgt_node, constraint='false', - label='"' + label + '"', - color=color, fontcolor=color, - style='bold') - if kind == 'cherry': - e.set_style('dashed') - graph.add_edge(e) - - def mk_mergeinfo_edge(graph, base_node, src_node, important): - """""" - if important: - color = 'red' - else: - color = 'grey' - graph.add_edge(Edge(base_node, src_node, - dir='both', arrowtail='odot', arrowhead='tee', - color=color, constraint='false')) - - def mk_invis_edge(graph, name1, name2): - """Add an invisible edge to the graph""" - graph.add_edge(Edge(name1, name2, style='invis')) - - def add_merge(graph, merge, important): - """Add a merge""" - base_node, src_node, tgt_node, kind = merge - - if base_node and src_node: # and kind != 'cherry': - graph.mk_mergeinfo_edge(base_node, src_node, important) - - # Merge target node - graph.mk_merge_target(tgt_node, important) - - # Merge edge - graph.mk_merge_edge(src_node, tgt_node, kind, kind, important) - - def add_annotation(graph, node, label, color='red'): - """Add a graph node that serves as an annotation to a normal node. - More than one annotation can be added to the same normal node.""" - subg_name = node + '_annotations' - - def get_subgraph(graph, name): - """Equivalent to pydot.Graph.get_subgraph() when there is no more than - one subgraph of the given name, but working aroung a bug in - pydot.Graph.get_subgraph().""" - for subg in graph.get_subgraph_list(): - if subg.get_name() == name: - return subg - return None - - g = get_subgraph(graph, subg_name) - if not g: - g = pydot.Subgraph(subg_name, rank='same') - graph.add_subgraph(g) - - ann_node = node + '_' - while g.get_node(ann_node): - ann_node = ann_node + '_' - g.add_node(Node(ann_node, shape='box', color=color, label='"' + label + '"')) - g.add_edge(Edge(ann_node, node, style='dotted', color=color, dir='none', constraint='false')) - -class MergeSubgraph(MergeGraph, pydot.Subgraph): - """""" - def __init__(graph, **attrs): - """""" - MergeGraph.__init__(graph) - pydot.Subgraph.__init__(graph, **attrs) - -class MergeDot(MergeGraph, pydot.Dot): - """ - # TODO: In the 'merges' input, find the predecessor automatically. - """ - def __init__(graph, config_filename, **attrs): - """Return a new MergeDot graph generated from a config file.""" - MergeGraph.__init__(graph) - pydot.Dot.__init__(graph, **attrs) - - graph.read_config(config_filename) - - graph.construct() - - def read_config(graph, config_filename): - """Initialize a MergeDot graph's input data from a config file.""" - import ConfigParser - config = ConfigParser.SafeConfigParser() - files_read = config.read(config_filename) - if len(files_read) == 0: - print >> sys.stderr, 'graph: unable to read graph config from "' + config_filename + '"' - sys.exit(1) - graph.filename = config.get('graph', 'filename') - graph.title = config.get('graph', 'title') - graph.branches = eval(config.get('graph', 'branches')) - graph.changes = eval(config.get('graph', 'changes')) - graph.merges = eval(config.get('graph', 'merges')) - graph.annotations = eval(config.get('graph', 'annotations')) - - def construct(graph): - """""" - # Origin nodes (done first, in an attempt to set the order) - for br, orig, r1, head in graph.branches: - name = br + '0' - if r1 > 0: - graph.mk_origin_node(name, br) - else: - graph.mk_node(name, label=br) - - # Edges and target nodes for merges - for merge in graph.merges: - # Emphasize the last merge, as it's the important one - important = (merge == graph.merges[-1]) - graph.add_merge(merge, important) - - # Parallel edges for basic lines of descent - for br, orig, r1, head in graph.branches: - sub_g = MergeSubgraph(ordering='out') - for i in range(1, head + 1): - prev_n = br + str(i - 1) - this_n = br + str(i) - - # Normal edges and nodes - if i < r1: - graph.mk_invis_node(this_n) - else: - graph.mk_node(this_n) - if i <= r1: - graph.mk_invis_edge(prev_n, this_n) - else: - graph.mk_edge(prev_n, this_n) - - # Branch creation edges - if orig: - sub_g.mk_br_edge(orig, br + str(r1)) - - graph.add_subgraph(sub_g) - - # Annotations - for node, label in graph.annotations: - graph.add_annotation(node, label) - - # A title for the graph (added last so it goes at the top) - #if graph.title: - # graph.add_node(Node('title', shape='plaintext', label='"' + graph.title + '"')) +from mergegraph import MergeDot # If run as a program, process each input filename as a graph config file. Propchange: subversion/branches/revprop-packing/tools/dev/merge-graph.py ------------------------------------------------------------------------------ svn:eol-style = native Modified: subversion/branches/revprop-packing/tools/dev/unix-build/Makefile.svn URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/dev/unix-build/Makefile.svn?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/dev/unix-build/Makefile.svn (original) +++ subversion/branches/revprop-packing/tools/dev/unix-build/Makefile.svn Mon Mar 5 09:25:25 2012 @@ -70,7 +70,7 @@ SERF_VER = 1.0.0 SERF_OLD_VER = 0.3.1 CYRUS_SASL_VER = 2.1.23 SQLITE_VER = 3070603 -LIBMAGIC_VER = 5.07 +LIBMAGIC_VER = 5.11 RUBY_VER = 1.8.7-p334 BZ2_VER = 1.0.6 PYTHON_VER = 2.7.2 Modified: subversion/branches/revprop-packing/tools/dev/windows-build/Makefile URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/dev/windows-build/Makefile?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/dev/windows-build/Makefile (original) +++ subversion/branches/revprop-packing/tools/dev/windows-build/Makefile Mon Mar 5 09:25:25 2012 @@ -107,7 +107,7 @@ config: targetdir libsvn_auth_gnome_keyring libsvn_auth_kwallet libsvn_client libsvn_delta libsvn_diff libsvn_fs libsvn_fs_base libsvn_fs_fs libsvn_fs_util libsvn_ra libsvn_ra_local libsvn_ra_neon libsvn_ra_serf libsvn_ra_svn libsvn_repos libsvn_subr libsvn_wc: targetdir $(MSBUILD) /t:Libraries\$@ $(MAKE) package -svn svnadmin svndumpfilter svnlook svnmucc svnserve svnsync svnversion entries-dump: targetdir +svn svnadmin svndumpfilter svnlook svnmucc svnserve svnsync svnversion svnrdump entries-dump: targetdir $(MSBUILD) /t:Programs\$@ $(MAKE) package auth-test cache-test changes-test checksum-test client-test compat-test config-test db-test diff-diff3-test dir-delta-editor dirent_uri-test error-test fs-base-test fs-pack-test fs-test hashdump-test key-test locks-test mergeinfo-test opt-test path-test ra-local-test random-test repos-test revision-test skel-test stream-test string-test strings-reps-test svn_test_fs svn_test_main svndiff-test target-test time-test translate-test tree-conflict-data-test utf-test vdelta-test window-test: targetdir @@ -128,7 +128,7 @@ all2: targetdir package: test -d $(SVNDIR)\$(CONFIG)\Subversion\tests\cmdline || mkdir $(SVNDIR)\$(CONFIG)\Subversion\tests\cmdline test -d $(TARGETDIR)\bin || mkdir $(TARGETDIR)\bin - for %%i in (svn svnadmin svndumpfilter svnlook svnserve svnsync svnversion) do @$(CP) $(CONFIG)\subversion\%%i\%%i.exe $(TARGETDIR)\bin + for %%i in (svn svnadmin svndumpfilter svnlook svnserve svnsync svnversion svnrdump) do @$(CP) $(CONFIG)\subversion\%%i\%%i.exe $(TARGETDIR)\bin for %%i in (diff diff3 diff4) do @if exist $(CONFIG)\tools\diff\%%i.exe $(CP) $(CONFIG)\tools\diff\%%i.exe $(TARGETDIR)\bin $(CP) $(APRDIR)\$(CONFIG)/*.dll $(TARGETDIR)\bin $(CP) $(APRUTILDIR)\$(CONFIG)/*.dll $(TARGETDIR)\bin Modified: subversion/branches/revprop-packing/tools/diff/diff.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/diff/diff.c?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/diff/diff.c (original) +++ subversion/branches/revprop-packing/tools/diff/diff.c Mon Mar 5 09:25:25 2012 @@ -89,6 +89,8 @@ int main(int argc, const char *argv[]) options_array = apr_array_make(pool, 0, sizeof(const char *)); + diff_options = svn_diff_file_options_create(pool); + for (i = 1 ; i < argc ; i++) { if (!no_more_options && (argv[i][0] == '-')) @@ -105,6 +107,11 @@ int main(int argc, const char *argv[]) show_c_function = TRUE; continue; } + if (argv[i][1] == 'w' && !argv[i][2]) + { + diff_options->ignore_space = svn_diff_file_ignore_space_all; + continue; + } APR_ARRAY_PUSH(options_array, const char *) = argv[i]; } else @@ -127,8 +134,6 @@ int main(int argc, const char *argv[]) return 2; } - diff_options = svn_diff_file_options_create(pool); - svn_err = svn_diff_file_options_parse(diff_options, options_array, pool); if (svn_err) { Modified: subversion/branches/revprop-packing/tools/dist/backport.pl URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/dist/backport.pl?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/dist/backport.pl (original) +++ subversion/branches/revprop-packing/tools/dist/backport.pl Mon Mar 5 09:25:25 2012 @@ -22,18 +22,22 @@ use feature qw/switch say/; use Term::ReadKey qw/ReadMode ReadKey/; use File::Temp qw/tempfile/; - -$/ = ""; # paragraph mode +use POSIX qw/ctermid/; my $SVN = $ENV{SVN} || 'svn'; # passed unquoted to sh my $VIM = 'vim'; my $STATUS = './STATUS'; my $BRANCHES = '^/subversion/branches'; -my $YES = $ENV{YES}; # batch mode: assume 'yes' without asking +my $YES = $ENV{YES}; # batch mode: eliminate prompts, add sleeps my $WET_RUN = qw[false true][1]; # don't commit my $DEBUG = qw[false true][0]; # 'set -x', etc -my $SVNq = "$SVN -q "; + +# derived values +my $SVNq; + +$SVN .= " --non-interactive" if $YES or not defined ctermid; +$SVNq = "$SVN -q "; $SVNq =~ s/-q// if $DEBUG eq 'true'; sub usage { @@ -76,7 +80,7 @@ sub merge { # 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}; $mergeargs = "--reintegrate $BRANCHES/$entry{branch}"; - print $logmsg_fh "Reintergrate the $entry{header}:"; + print $logmsg_fh "Reintegrate the $entry{header}:"; print $logmsg_fh ""; } elsif (@{$entry{revisions}}) { $pattern = '^ [*] \V' . 'r' . $entry{revisions}->[0]; @@ -121,7 +125,10 @@ EOF $script .= <<"EOF" if $entry{branch}; reinteg_rev=\`$SVN info $STATUS | sed -ne 's/Last Changed Rev: //p'\` if $WET_RUN; then + # Sleep to avoid out-of-order commit notifications + if [ -n "$YES" ]; then sleep 15; fi $SVNq rm $BRANCHES/$entry{branch} -m "Remove the '$entry{branch}' branch, reintegrated in r\$reinteg_rev." + if [ -n "$YES" ]; then sleep 1; fi else echo "Removing reintegrated '$entry{branch}' branch" fi @@ -156,7 +163,7 @@ sub parse_entry { # revisions $branch = sanitize_branch $1 if $_[0] =~ /^(\S*) branch$/; while ($_[0] =~ /^r/) { - while ($_[0] =~ s/^r(\d+)(?:,\s*)?//) { + while ($_[0] =~ s/^r(\d+)(?:$|[,; ]+)//) { push @revisions, $1; } shift; @@ -222,22 +229,32 @@ sub main { usage, exit 0 if @ARGV; usage, exit 1 unless -r $STATUS; - my $sawapproved; @ARGV = $STATUS; + + # Skip most of the file while (<>) { - my @lines = split /\n/; + last if /^Approved changes/; + } + while (<>) { + last unless /^=+$/; + } + $/ = ""; # paragraph mode - # Skip most of the file - next unless $sawapproved ||= /^Approved changes/; + while (<>) { + my @lines = split /\n/; given ($lines[0]) { # Section header when (/^[A-Z].*:$/i) { print "\n\n=== $lines[0]" unless $YES; } + # Separator after section header + when (/^=+$/i) { + break; + } # Backport entry? when (/^ \*/) { - handle_entry @lines if $sawapproved; + handle_entry @lines; } default { warn "Unknown entry '$lines[0]' at $ARGV:$.\n"; Modified: subversion/branches/revprop-packing/tools/dist/release.py URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/dist/release.py?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/dist/release.py (original) +++ subversion/branches/revprop-packing/tools/dist/release.py Mon Mar 5 09:25:25 2012 @@ -396,9 +396,9 @@ def roll_tarballs(args): raise RuntimeError('Cannot find usable %s' % dep.label) if branch != 'trunk': - # Make sure CHANGES is sync'd. + # Make sure CHANGES is sync'd. compare_changes(repos, branch, args.revnum) - + # Ensure the output directory doesn't already exist if os.path.exists(get_deploydir(args.base_dir)): raise RuntimeError('output directory \'%s\' already exists' Modified: subversion/branches/revprop-packing/tools/examples/get-location-segments.py URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/examples/get-location-segments.py?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/examples/get-location-segments.py (original) +++ subversion/branches/revprop-packing/tools/examples/get-location-segments.py Mon Mar 5 09:25:25 2012 @@ -105,6 +105,9 @@ def prompt_func_simple_prompt(realm, use simple_cred.may_save = False return simple_cred +def prompt_func_gnome_keyring_prompt(keyring, pool): + return getpass.getpass(prompt="Password for '%s' GNOME keyring: " % keyring) + def main(): try: url, peg_revision, start_revision, end_revision = parse_args(sys.argv[1:]) @@ -125,7 +128,12 @@ ERROR: %s core.svn_config_ensure(None) ctx = client.svn_client_create_context() - providers = [ + ctx.config = core.svn_config_get_config(None) + + # Make sure that these are at the start of the list, so passwords from + # gnome-keyring / kwallet are checked before asking for new passwords. + providers = core.svn_auth_get_platform_specific_client_providers(ctx.config['config'], None) + providers.extend([ client.get_simple_provider(), core.svn_auth_get_ssl_server_trust_file_provider(), core.svn_auth_get_simple_prompt_provider(prompt_func_simple_prompt, 2), @@ -134,9 +142,12 @@ ERROR: %s client.get_ssl_server_trust_file_provider(), client.get_ssl_client_cert_file_provider(), client.get_ssl_client_cert_pw_file_provider(), - ] + ]) + ctx.auth_baton = core.svn_auth_open(providers) - ctx.config = core.svn_config_get_config(None) + + if hasattr(core, 'svn_auth_set_gnome_keyring_unlock_prompt_func'): + core.svn_auth_set_gnome_keyring_unlock_prompt_func(ctx.auth_baton, prompt_func_gnome_keyring_prompt) ra_callbacks = ra.callbacks_t() ra_callbacks.auth_baton = ctx.auth_baton Modified: subversion/branches/revprop-packing/tools/server-side/svnpredumpfilter.py URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/server-side/svnpredumpfilter.py?rev=1296975&r1=1296974&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/server-side/svnpredumpfilter.py (original) +++ subversion/branches/revprop-packing/tools/server-side/svnpredumpfilter.py Mon Mar 5 09:25:25 2012 @@ -114,12 +114,12 @@ def log(msg, min_verbosity): elif min_verbosity == 2: sys.stderr.write("[**] ") sys.stderr.write(msg + "\n") - + class DependencyTracker: def __init__(self, include_paths): self.include_paths = include_paths[:] self.dependent_paths = [] - + def path_included(self, path): for include_path in self.include_paths + self.dependent_paths: if subsumes(include_path, path): @@ -143,7 +143,7 @@ def readline(stream): def svn_log_stream_get_dependencies(stream, included_paths): import re - dt = DependencyTracker(included_paths) + dt = DependencyTracker(included_paths) header_re = re.compile(r'^r([0-9]+) \|.*$') action_re = re.compile(r'^ [ADMR] /(.*)$') @@ -153,7 +153,7 @@ def svn_log_stream_get_dependencies(stre eof = False path_copies = {} found_changed_path = False - + while not eof: try: line = line_buf is not None and line_buf or readline(stream) @@ -220,7 +220,7 @@ def svn_log_stream_get_dependencies(stre raise LogStreamError("No changed paths found; did you remember to run " "'svn log' with the --verbose (-v) option when " "generating the input to this script?") - + return dt def analyze_logs(included_paths): @@ -268,13 +268,13 @@ def usage_and_exit(errmsg=None): def main(): config_dir = None targets_file = None - + try: opts, args = getopt.getopt(sys.argv[1:], "hv", ["help", "verbose", "targets="]) except getopt.GetoptError, e: usage_and_exit(str(e)) - + for option, value in opts: if option in ['-h', '--help']: usage_and_exit() Modified: subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnpubsub/client.py URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnpubsub/client.py?rev=1296975&r1=1295003&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnpubsub/client.py (original) +++ subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnpubsub/client.py Mon Mar 5 09:25:25 2012 @@ -145,8 +145,8 @@ class XMLStreamHandler(xml.sax.handler.C class Revision(object): - def __init__(self, repos, rev): - self.repos = repos + def __init__(self, uuid, rev): + self.uuid = uuid self.rev = rev self.dirs_changed = [ ] self.author = None Modified: subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnpubsub/server.py URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnpubsub/server.py?rev=1296975&r1=1295003&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnpubsub/server.py (original) +++ subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnpubsub/server.py Mon Mar 5 09:25:25 2012 @@ -37,7 +37,7 @@ # URL is built into 3 parts: # /${type}/${optional_repo_uuid}/${format} # -# If the repository UUID is included in the URl, you will only recieve +# If the repository UUID is included in the URl, you will only receive # messages about that repository. # # Example Pub clients: @@ -88,7 +88,7 @@ class Revision: 'author': self.author, 'log': self.log, 'date': self.date}}) +"," - elif format == "xml": + elif format == "xml": c = ET.Element('commit', {'repository': self.repos, 'revision': "%d" % (self.rev)}) ET.SubElement(c, 'author').text = self.author ET.SubElement(c, 'date').text = self.date @@ -107,7 +107,7 @@ class Revision: return json.dumps({'commit': {'repository': self.repos, 'revision': self.rev, 'dirs_changed': self.dirs_changed}}) +"," - elif format == "xml": + elif format == "xml": c = ET.Element('commit', {'repository': self.repos, 'revision': "%d" % (self.rev)}) d = ET.SubElement(c, 'dirs_changed') for p in self.dirs_changed: @@ -133,7 +133,7 @@ class Client(object): def finished(self, reason): self.alive = False log.msg("CLOSE: %s:%d (%d clients online)"% (self.r.getClientIP(), self.r.client.port, self.pubsub.cc())) - try: + try: self.pubsub.remove(self) except ValueError: pass @@ -210,11 +210,11 @@ class SvnPubSub(resource.Resource): else: fmt = uri[3] uuid = uri[2] - + if type not in self.clients.keys(): request.setResponseCode(400) return "Invalid Reuqest Type\n" - + clients = {'json': JSONClient, 'xml': XMLClient} clientCls = clients.get(fmt) if clientCls == None: @@ -262,7 +262,7 @@ def svnpubsub_server(): root.putChild("commits", s) root.putChild("commit", s) return server.Site(root) - + if __name__ == "__main__": log.startLogging(sys.stdout) # Port 2069 "HTTP Event Port", whatever, sounds good to me Modified: subversion/branches/revprop-packing/tools/server-side/svnpubsub/svntweet.py URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/server-side/svnpubsub/svntweet.py?rev=1296975&r1=1295003&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/server-side/svnpubsub/svntweet.py (original) +++ subversion/branches/revprop-packing/tools/server-side/svnpubsub/svntweet.py Mon Mar 5 09:25:25 2012 @@ -21,7 +21,7 @@ # # Example: # svntweet.py my-config.json -# +# # With my-config.json containing stream paths and the twitter auth info: # {"stream": "http://svn-master.apache.org:2069/commits/xml", # "username": "asfcommits", @@ -90,9 +90,9 @@ class Revision: self.log = None self.date = None -class StreamHandler(handler.ContentHandler): +class StreamHandler(handler.ContentHandler): def __init__(self, bdec): - handler.ContentHandler.__init__(self) + handler.ContentHandler.__init__(self) self.bdec = bdec self.rev = None self.text_value = None @@ -115,7 +115,7 @@ class StreamHandler(handler.ContentHandl self.bdec.stillalive() def characters(self, data): if self.text_value is not None: - self.text_value = self.text_value + data + self.text_value = self.text_value + data else: self.text_value = data @@ -179,7 +179,7 @@ class BigDoEverythingClasss(object): def pageStart(self): log.msg("Stream Connection Established") self.failures = 0 - + def _restartStream(self): (self.stream, self.transport) = connectTo(self.url, self) self.stream.deferred.addBoth(self.streamDead) @@ -253,6 +253,6 @@ def main(config_file): if __name__ == "__main__": if len(sys.argv) != 2: print "invalid args, read source code" - sys.exit(0) + sys.exit(0) log.startLogging(sys.stdout) main(sys.argv[1]) Modified: subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnwcsub.py URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnwcsub.py?rev=1296975&r1=1295003&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnwcsub.py (original) +++ subversion/branches/revprop-packing/tools/server-side/svnpubsub/svnwcsub.py Mon Mar 5 09:25:25 2012 @@ -36,8 +36,9 @@ import os import re import ConfigParser import time -import logging +import logging.handlers import Queue +import optparse from twisted.internet import reactor, task, threads from twisted.internet.utils import getProcessOutput @@ -130,7 +131,7 @@ class WorkingCopy(object): uuid = info['Repository UUID'] relpath = url[len(repos):] # also has leading '/' return [relpath, url, repos, uuid] - + class HTTPStream(HTTPClientFactory): protocol = HTTPPageDownloader @@ -154,9 +155,9 @@ class Revision: self.rev = rev self.dirs_changed = [] -class StreamHandler(handler.ContentHandler): +class StreamHandler(handler.ContentHandler): def __init__(self, stream, bdec): - handler.ContentHandler.__init__(self) + handler.ContentHandler.__init__(self) self.stream = stream self.bdec = bdec self.rev = None @@ -167,7 +168,7 @@ class StreamHandler(handler.ContentHandl """ <commit revision="7"> <dirs_changed><path>/</path></dirs_changed> - </commit> + </commit> """ if name == "commit": self.rev = Revision(attrs['repository'], int(attrs['revision'])) @@ -175,7 +176,7 @@ class StreamHandler(handler.ContentHandl self.bdec.stillalive(self.stream) def characters(self, data): if self.text_value is not None: - self.text_value = self.text_value + data + self.text_value = self.text_value + data else: self.text_value = data @@ -230,7 +231,6 @@ class BigDoEverythingClasss(object): self.svnbin = config.get_value('svnbin') self.env = config.get_env() self.worker = BackgroundWorker(self.svnbin, self.env) - self.worker.start() self.service = service self.failures = 0 self.alive = time.time() @@ -333,12 +333,15 @@ class BackgroundWorker(threading.Thread) threading.Thread.__init__(self) # The main thread/process should not wait for this thread to exit. - self.daemon = True + ### compat with Python 2.5 + self.setDaemon(True) self.svnbin = svnbin self.env = env self.q = Queue.Queue() + self.has_started = False + def run(self): while True: if self.q.qsize() > BACKLOG_TOO_HIGH: @@ -360,6 +363,12 @@ class BackgroundWorker(threading.Thread) self.q.task_done() def add_work(self, operation, wc): + # Start the thread when work first arrives. Thread-start needs to + # be delayed in case the process forks itself to become a daemon. + if not self.has_started: + self.start() + self.has_started = True + self.q.put((operation, wc)) def _update(self, wc): @@ -443,21 +452,93 @@ class ReloadableConfig(ConfigParser.Safe return str(option) -def main(config_file): +def prepare_logging(logfile): + "Log to the specified file, or to stdout if None." + + if logfile: + # Rotate logs daily, keeping 7 days worth. + handler = logging.handlers.TimedRotatingFileHandler( + logfile, when='midnight', backupCount=7, + ) + else: + handler = logging.StreamHandler(sys.stdout) + + # Add a timestamp to the log records + formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s', + '%Y-%m-%d %H:%M:%S') + handler.setFormatter(formatter) + + # Apply the handler to the root logger + root = logging.getLogger() + root.addHandler(handler) + + ### use logging.INFO for now. switch to cmdline option or a config? + root.setLevel(logging.INFO) + + +def handle_options(options): + # Set up the logging, then process the rest of the options. + prepare_logging(options.logfile) + + if options.pidfile: + pid = os.getpid() + open(options.pidfile, 'w').write('%s\n' % pid) + logging.info('pid %d written to %s', pid, options.pidfile) + + if options.uid: + try: + uid = int(options.uid) + except ValueError: + import pwd + uid = pwd.getpwnam(options.uid)[2] + logging.info('setting uid %d', uid) + os.setuid(uid) + + if options.gid: + try: + gid = int(options.gid) + except ValueError: + import grp + gid = grp.getgrnam(options.gid)[2] + logging.info('setting gid %d', gid) + os.setgid(gid) + + if options.umask: + umask = int(options.umask, 8) + os.umask(umask) + logging.info('umask set to %03o', umask) + + +def main(args): + parser = optparse.OptionParser( + description='An SvnPubSub client to keep working copies synchronized ' + 'with a repository.', + usage='Usage: %prog [options] CONFIG_FILE', + ) + parser.add_option('--logfile', + help='filename for logging') + parser.add_option('--pidfile', + help="the process' PID will be written to this file") + parser.add_option('--uid', + help='switch to this UID before running') + parser.add_option('--gid', + help='switch to this GID before running') + parser.add_option('--umask', + help='set this (octal) umask before running') + + options, extra = parser.parse_args(args) + + if len(extra) != 1: + parser.error('CONFIG_FILE is required') + config_file = extra[0] + + # Process any provided options. + handle_options(options) + c = ReloadableConfig(config_file) big = BigDoEverythingClasss(c) reactor.run() if __name__ == "__main__": - if len(sys.argv) != 2: - print "invalid args, read source code" - sys.exit(0) - - ### use logging.INFO for now. review/adjust the calls above for the - ### proper logging level. then remove the level (to return to default). - ### future: switch to config for logfile and loglevel. - logging.basicConfig(level=logging.INFO, stream=sys.stdout, - datefmt='%Y-%m-%d %H:%M:%S', - format='%(asctime)s [%(levelname)s] %(message)s') - main(sys.argv[1]) + main(sys.argv[1:]) Modified: subversion/branches/revprop-packing/tools/server-side/svnpubsub/test.conf URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/server-side/svnpubsub/test.conf?rev=1296975&r1=1295003&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/server-side/svnpubsub/test.conf (original) +++ subversion/branches/revprop-packing/tools/server-side/svnpubsub/test.conf Mon Mar 5 09:25:25 2012 @@ -1,4 +1,9 @@ -# For use with testserver.py +# For use with connecting to testserver.py [DEFAULT] +svnbin: svn streams: http://127.0.0.1:2069/commits/xml + +[env] + +[track] Modified: subversion/branches/revprop-packing/tools/server-side/svnpubsub/watcher.py URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/tools/server-side/svnpubsub/watcher.py?rev=1296975&r1=1295003&r2=1296975&view=diff ============================================================================== --- subversion/branches/revprop-packing/tools/server-side/svnpubsub/watcher.py (original) +++ subversion/branches/revprop-packing/tools/server-side/svnpubsub/watcher.py Mon Mar 5 09:25:25 2012 @@ -53,5 +53,5 @@ def main(config_file): if __name__ == "__main__": if len(sys.argv) != 2: print "invalid args, read source code" - sys.exit(0) + sys.exit(0) main(sys.argv[1])
