You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2012/03/05 10:25:33 UTC
svn commit: r1296975 [12/12] - in /subversion/branches/revprop-packing: ./
build/ build/ac-macros/ build/generator/ build/generator/templates/
build/win32/ notes/ notes/api-errata/1.7/
subversion/bindings/javahl/native/ subversion/bindings/javahl/tests...
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/%3C87sjik3m8q.fsf@stat.home.lan%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])