Modified: subversion/branches/addremove/subversion/svnserve/serve.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/svnserve/serve.c?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/svnserve/serve.c (original) +++ subversion/branches/addremove/subversion/svnserve/serve.c Tue Aug 22 14:19:36 2017 @@ -2823,6 +2823,8 @@ static svn_error_t *file_rev_handler(voi /* If the connection does not support SVNDIFF1 or if we don't want to use * compression, use the non-compressing "version 0" implementation */ + /* ### TODO: Check SVN_RA_SVN_CAP_SVNDIFF2_ACCEPTED and decide between + * ### svndiff1[at compression_level] and svndiff2 */ if ( svn_ra_svn_compression_level(frb->conn) > 0 && svn_ra_svn_has_capability(frb->conn, SVN_RA_SVN_CAP_SVNDIFF1)) svn_txdelta_to_svndiff3(d_handler, d_baton, stream, 1, @@ -3804,6 +3806,7 @@ find_repos(const char *url, { const char *path, *full_path, *fs_path, *hooks_env; svn_stringbuf_t *url_buf; + svn_boolean_t sasl_requested; /* Skip past the scheme and authority part. */ path = skip_scheme_part(url); @@ -3877,14 +3880,16 @@ find_repos(const char *url, SVN_ERR(load_authz_config(repository, repository->repos_root, cfg, result_pool)); -#ifdef SVN_HAVE_SASL + /* Should we use Cyrus SASL? */ + SVN_ERR(svn_config_get_bool(cfg, &sasl_requested, + SVN_CONFIG_SECTION_SASL, + SVN_CONFIG_OPTION_USE_SASL, FALSE)); + if (sasl_requested) { +#ifdef SVN_HAVE_SASL const char *val; - /* Should we use Cyrus SASL? */ - SVN_ERR(svn_config_get_bool(cfg, &repository->use_sasl, - SVN_CONFIG_SECTION_SASL, - SVN_CONFIG_OPTION_USE_SASL, FALSE)); + repository->use_sasl = sasl_requested; svn_config_get(cfg, &val, SVN_CONFIG_SECTION_SASL, SVN_CONFIG_OPTION_MIN_SSF, "0"); @@ -3893,8 +3898,18 @@ find_repos(const char *url, svn_config_get(cfg, &val, SVN_CONFIG_SECTION_SASL, SVN_CONFIG_OPTION_MAX_SSF, "256"); SVN_ERR(svn_cstring_atoui(&repository->max_ssf, val)); +#else /* !SVN_HAVE_SASL */ + return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL, + _("SASL requested but not compiled in; " + "set '%s' to 'false' or recompile " + "svnserve with SASL support"), + SVN_CONFIG_OPTION_USE_SASL); +#endif /* SVN_HAVE_SASL */ + } + else + { + repository->use_sasl = FALSE; } -#endif /* Use the repository UUID as the default realm. */ SVN_ERR(svn_fs_get_uuid(repository->fs, &repository->realm, scratch_pool)); @@ -4122,10 +4137,11 @@ construct_server_baton(server_baton_t ** * send an empty mechlist. */ if (params->compression_level > 0) SVN_ERR(svn_ra_svn__write_cmd_response(conn, scratch_pool, - "nn()(wwwwwwwwwwww)", + "nn()(wwwwwwwwwwwww)", (apr_uint64_t) 2, (apr_uint64_t) 2, SVN_RA_SVN_CAP_EDIT_PIPELINE, SVN_RA_SVN_CAP_SVNDIFF1, + SVN_RA_SVN_CAP_SVNDIFF2_ACCEPTED, SVN_RA_SVN_CAP_ABSENT_ENTRIES, SVN_RA_SVN_CAP_COMMIT_REVPROPS, SVN_RA_SVN_CAP_DEPTH,
Modified: subversion/branches/addremove/subversion/tests/cmdline/davautocheck.sh URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/davautocheck.sh?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/cmdline/davautocheck.sh (original) +++ subversion/branches/addremove/subversion/tests/cmdline/davautocheck.sh Tue Aug 22 14:19:36 2017 @@ -313,6 +313,9 @@ if [ ${APACHE_MPM:+set} ]; then LOAD_MOD_MPM=$(get_loadmodule_config mod_mpm_$APACHE_MPM) \ || fail "MPM module not found" fi +if [ x"$APACHE_MPM" = x"event" ] && [ x"$FS_TYPE" = x"bdb" ]; then + fail "FS_TYPE=bdb and APACHE_MPM=event are mutually exclusive (see SVN-4157)" +fi if [ ${USE_SSL:+set} ]; then LOAD_MOD_SSL=$(get_loadmodule_config mod_ssl) \ || fail "SSL module not found" Modified: subversion/branches/addremove/subversion/tests/cmdline/externals_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/externals_tests.py?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/cmdline/externals_tests.py (original) +++ subversion/branches/addremove/subversion/tests/cmdline/externals_tests.py Tue Aug 22 14:19:36 2017 @@ -4365,6 +4365,39 @@ def external_externally_removed(sbox): sbox.simple_propdel('svn:externals', '') sbox.simple_update() # Should succeed +def invalid_uris_in_repo(sbox): + "invalid URIs in repo" + + sbox.build(empty=True), + + # Using a dump file because the client may not allow adding invalid URIs. + svntest.actions.load_repo(sbox, + os.path.join(os.path.dirname(sys.argv[0]), + 'externals_tests_data', + 'invalid_uris_in_repo.dump'), + create_wc=False) + + # 'foo://host:-/D X' + expected_output = svntest.wc.State(sbox.wc_dir, { + '' : Item(status=' U') + }) + expected_disk = svntest.wc.State('', { + }) + expected_error = ".*warning: W205011: Error handling externals definition.*" + + # A repository might have invalid URIs and the client used to SEGV. + # r1 has 'foo://host:-/D X' + # r2 has 'foo://host::/D X' + # r3 has 'foo://host:123xx/D X' + # r4 has 'foo://host:123:123/D X' + for revision in range(1,4): + svntest.actions.run_and_verify_checkout(sbox.repo_url, sbox.wc_dir, + expected_output, + expected_disk, + expected_error, + "-r", revision) + svntest.main.safe_rmtree(sbox.wc_dir) + ######################################################################## # Run the tests @@ -4440,6 +4473,7 @@ test_list = [ None, file_external_to_normal_file, file_external_recorded_info, external_externally_removed, + invalid_uris_in_repo, ] if __name__ == '__main__': Modified: subversion/branches/addremove/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout (original) +++ subversion/branches/addremove/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout Tue Aug 22 14:19:36 2017 @@ -209,15 +209,15 @@ Valid options: 'empty', 'files', 'immediates', or 'infinity') -q [--quiet] : print nothing, or only summary information --diff3-cmd ARG : use ARG as merge command - --relocate : relocate via URL-rewriting --ignore-externals : ignore externals definitions --ignore-ancestry : allow switching to a node with no common ancestor --force : handle unversioned obstructions as changes --accept ARG : specify automatic conflict resolution action ('postpone', 'working', 'base', 'mine-conflict', 'theirs-conflict', 'mine-full', 'theirs-full', - 'edit', 'launch') - (shorthand: 'p', 'mc', 'tc', 'mf', 'tf', 'e', 'l') + 'edit', 'launch', 'recommended') (shorthand: + 'p', 'mc', 'tc', 'mf', 'tf', 'e', 'l', 'r') + --relocate : deprecated; use 'svn relocate' Global options: --username ARG : specify a username ARG Modified: subversion/branches/addremove/subversion/tests/cmdline/merge_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/merge_tests.py?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/cmdline/merge_tests.py (original) +++ subversion/branches/addremove/subversion/tests/cmdline/merge_tests.py Tue Aug 22 14:19:36 2017 @@ -17395,7 +17395,8 @@ def merge_target_selection(sbox): ' U .\n', ] + svntest.main.summary_of_conflicts(tree_conflicts=1) svntest.actions.run_and_verify_svn(expected_output, [], - 'merge', '^/dir/binary-file', '-c', '4', '.') + 'merge', '^/dir/binary-file', + '-c', '4', '.', '--accept', 'postpone') svntest.main.run_svn(None, 'revert', '-R', '.') @@ -17407,7 +17408,8 @@ def merge_target_selection(sbox): ' U binary-file\n', ] + svntest.main.summary_of_conflicts(tree_conflicts=1) svntest.actions.run_and_verify_svn(expected_output, [], - 'merge', '^/dir', '-c', '4', 'binary-file') + 'merge', '^/dir', '-c', '4', 'binary-file', + '--accept', 'postpone') @SkipUnless(server_has_mergeinfo) @Issue(3405) # seems to be the wrong issue number Modified: subversion/branches/addremove/subversion/tests/cmdline/merge_tree_conflict_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/merge_tree_conflict_tests.py?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/cmdline/merge_tree_conflict_tests.py (original) +++ subversion/branches/addremove/subversion/tests/cmdline/merge_tree_conflict_tests.py Tue Aug 22 14:19:36 2017 @@ -1695,7 +1695,7 @@ def merge_replace_causes_tree_conflict(s ], target=A, two_url=True, tree_conflicts=4) actions.run_and_verify_svn2(expected_stdout, [], 0, 'merge', - url_A, url_branch, A) + url_A, url_branch, A, '--accept=postpone') # svn st expected_status.tweak('A', status=' M') @@ -1781,7 +1781,7 @@ def merge_replace_causes_tree_conflict2( ], target=A, two_url=True, tree_conflicts=1) actions.run_and_verify_svn2(expected_stdout, [], 0, 'merge', - url_A, url_branch, A, '--depth=files') + url_A, url_branch, A, '--depth=files', '--accept=postpone') # New mergeinfo describing the merge. expected_status.tweak('A', status=' M') # Currently this fails because the local status is 'D'eleted rather than @@ -1801,7 +1801,7 @@ def merge_replace_causes_tree_conflict2( ], target=A_B, two_url=True, tree_conflicts=1) actions.run_and_verify_svn2(expected_stdout, [], 0, 'merge', - url_A_B, url_branch_B, A_B) + url_A_B, url_branch_B, A_B, '--accept=postpone') # New mergeinfo describing the merge. expected_status.tweak('A/B', status=' M') # Currently this fails because the local status shows a property mod (and @@ -1821,7 +1821,7 @@ def merge_replace_causes_tree_conflict2( ], target=A_D, two_url=True, tree_conflicts=1) actions.run_and_verify_svn2(expected_stdout, [], 0, 'merge', - '--depth=immediates', url_A_D, url_branch_D, A_D) + '--depth=immediates', url_A_D, url_branch_D, A_D, '--accept=postpone') # New mergeinfo describing the merge. expected_status.tweak('A/D', 'A/D/G', status=' M') # Currently this fails because the local status is 'D'eleted rather than @@ -1841,7 +1841,7 @@ def merge_replace_causes_tree_conflict2( ], target=A_D_G, two_url=True, tree_conflicts=1) actions.run_and_verify_svn2(expected_stdout, [], 0, 'merge', - url_A_D_G, url_branch_D_G, A_D_G) + url_A_D_G, url_branch_D_G, A_D_G, '--accept=postpone') # New mergeinfo describing the merge. expected_status.tweak('A/D/G', status=' M') # Currently this fails because the local status shows a property mod (and @@ -1932,7 +1932,7 @@ def merge_replace_on_del_fails(sbox): # cmdline\svn-test-work\working_copies\merge_tree_conflict_tests-24\ # branch\C' was not found. actions.run_and_verify_svn2(expected_stdout, [], 0, 'merge', - sbox.repo_url + '/A', branch_path) + sbox.repo_url + '/A', branch_path, '--accept=postpone') def merge_conflict_details(sbox): "merge conflict details" Modified: subversion/branches/addremove/subversion/tests/cmdline/patch_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/patch_tests.py?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/cmdline/patch_tests.py (original) +++ subversion/branches/addremove/subversion/tests/cmdline/patch_tests.py Tue Aug 22 14:19:36 2017 @@ -4696,6 +4696,7 @@ def patch_apply_no_fuz(sbox): expected_status, expected_skip, [], True, True) +@Issue(4315) def patch_lacking_trailing_eol_on_context(sbox): "patch file lacking trailing eol on context" Modified: subversion/branches/addremove/subversion/tests/cmdline/stat_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/stat_tests.py?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/cmdline/stat_tests.py (original) +++ subversion/branches/addremove/subversion/tests/cmdline/stat_tests.py Tue Aug 22 14:19:36 2017 @@ -2224,7 +2224,8 @@ def status_missing_conflicts(sbox): sbox.simple_rm('A/B/E') - sbox.simple_update('A/B/E', revision=1) + svntest.main.run_svn(False, 'update', sbox.ospath('A/B/E'), '-r', '1', + '--accept=postpone') expected_status = svntest.actions.get_virginal_state(wc_dir, 1) expected_status.tweak('A/B/E', status='D ', treeconflict='C', wc_rev=1) @@ -2277,7 +2278,8 @@ def status_missing_conflicts(sbox): sbox.simple_move('A/B/E/beta', 'beta') sbox.simple_rm('A/B/E') - sbox.simple_update('A/B/E', revision=1) + svntest.main.run_svn(False, 'update', sbox.ospath('A/B/E'), '-r', '1', + '--accept=postpone') svntest.actions.run_and_verify_svn(None, [], 'resolve', '--accept=mine-conflict', '--depth=empty', sbox.ospath('A/B/E')) Modified: subversion/branches/addremove/subversion/tests/cmdline/svntest/main.py URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/svntest/main.py?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/cmdline/svntest/main.py (original) +++ subversion/branches/addremove/subversion/tests/cmdline/svntest/main.py Tue Aug 22 14:19:36 2017 @@ -1043,14 +1043,14 @@ def _post_create_repos(path, minor_versi shutil.copy(options.config_file, confpath) if options.memcached_server is not None or \ - options.fsfs_compression_level is not None and \ + options.fsfs_compression is not None and \ os.path.exists(confpath): with open(confpath, 'r') as conffile: newlines = [] for line in conffile.readlines(): - if line.startswith('# compression-level ') and \ - options.fsfs_compression_level is not None: - line = 'compression-level = %d\n' % options.fsfs_compression_level + if line.startswith('# compression ') and \ + options.fsfs_compression is not None: + line = 'compression = %s\n' % options.fsfs_compression newlines += line if options.memcached_server is not None and \ line == '[memcached-servers]\n': @@ -1737,8 +1737,8 @@ class TestSpawningThread(threading.Threa args.append('--fsfs-version=' + str(options.fsfs_version)) if options.dump_load_cross_check: args.append('--dump-load-cross-check') - if options.fsfs_compression_level: - args.append('--fsfs-compression=' + str(options.fsfs_compression_level)) + if options.fsfs_compression: + args.append('--fsfs-compression=' + options.fsfs_compression) result, stdout_lines, stderr_lines = spawn_process(command, 0, False, None, *args) @@ -2151,9 +2151,8 @@ def _create_parser(usage=None): help='Use sqlite exclusive locking for working copies') parser.add_option('--memcached-server', action='store', help='Use memcached server at specified URL (FSFS only)') - parser.add_option('--fsfs-compression', action='store', type='int', - dest="fsfs_compression_level", - help='Set compression level (for fsfs)') + parser.add_option('--fsfs-compression', action='store', type='str', + help='Set compression type (for fsfs)') # most of the defaults are None, but some are other values, set them here parser.set_defaults( @@ -2203,10 +2202,6 @@ def parse_options(arglist=sys.argv[1:], if options.fsfs_packing and not options.fsfs_sharding: parser.error("--fsfs-packing requires --fsfs-sharding") - if options.fsfs_compression_level is not None and\ - options.fsfs_compression_level not in range(0, 10): - parser.error("--fsfs-compression must be between 0 and 9") - if options.server_minor_version not in range(3, SVN_VER_MINOR+1): parser.error("test harness only supports server minor versions 3-%d" % SVN_VER_MINOR) Modified: subversion/branches/addremove/subversion/tests/cmdline/svntest/mergetrees.py URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/svntest/mergetrees.py?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/cmdline/svntest/mergetrees.py (original) +++ subversion/branches/addremove/subversion/tests/cmdline/svntest/mergetrees.py Tue Aug 22 14:19:36 2017 @@ -446,7 +446,8 @@ def svn_merge(rev_range, source, target, prop_resolved=prop_resolved, tree_resolved=tree_resolved) actions.run_and_verify_svn(exp_out, [], - 'merge', rev_arg, source, target, *args) + 'merge', rev_arg, source, target, + '--accept=postpone', *args) #---------------------------------------------------------------------- # Setup helper for issue #4056 and issue #4057 tests. Modified: subversion/branches/addremove/subversion/tests/cmdline/tree_conflict_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/tree_conflict_tests.py?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/cmdline/tree_conflict_tests.py (original) +++ subversion/branches/addremove/subversion/tests/cmdline/tree_conflict_tests.py Tue Aug 22 14:19:36 2017 @@ -463,7 +463,7 @@ def ensure_tree_conflict(sbox, operation if operation == 'update': logger.debug("--- Updating") run_and_verify_svn(expected_stdout, [], - 'update', target_path) + 'update', target_path, '--accept=postpone') elif operation == 'switch': logger.debug("--- Switching") run_and_verify_svn(expected_stdout, [], Modified: subversion/branches/addremove/subversion/tests/cmdline/update_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/cmdline/update_tests.py?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/cmdline/update_tests.py (original) +++ subversion/branches/addremove/subversion/tests/cmdline/update_tests.py Tue Aug 22 14:19:36 2017 @@ -6792,7 +6792,9 @@ def missing_tmp_update(sbox): svntest.actions.run_and_verify_svn(None, '.*Unable to create.*', 'up', wc_dir, '--set-depth', 'infinity') - svntest.actions.run_and_verify_svn(None, [], 'cleanup', wc_dir) + # This re-creates .svn/tmp as a side-effect. + svntest.actions.run_and_verify_svn(None, [], 'cleanup', + '--vacuum-pristines', wc_dir) svntest.actions.run_and_verify_update(wc_dir, None, None, None, [], False, wc_dir, '--set-depth', 'infinity') Modified: subversion/branches/addremove/subversion/tests/libsvn_client/conflicts-test.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/libsvn_client/conflicts-test.c?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/libsvn_client/conflicts-test.c (original) +++ subversion/branches/addremove/subversion/tests/libsvn_client/conflicts-test.c Tue Aug 22 14:19:36 2017 @@ -4578,6 +4578,89 @@ test_update_incoming_added_dir_merge2(co return SVN_NO_ERROR; } +static svn_error_t * +test_cherry_pick_post_move_edit(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b)); + const char *trunk_url; + svn_opt_revision_t peg_rev; + apr_array_header_t *ranges_to_merge; + svn_opt_revision_range_t merge_range; + svn_client_ctx_t *ctx; + svn_client_conflict_t *conflict; + svn_boolean_t tree_conflicted; + + SVN_ERR(svn_test__sandbox_create(b, + "test_cherry_pick_post_move_edit", + opts, pool)); + + SVN_ERR(sbox_add_and_commit_greek_tree(b)); /* r1 */ + /* Create a copy of node "A". */ + SVN_ERR(sbox_wc_copy(b, "A", "A1")); + SVN_ERR(sbox_wc_commit(b, "")); /* r2 */ + /* On "trunk", move the file mu. */ + SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-moved")); + SVN_ERR(sbox_wc_commit(b, "")); /* r3 */ + /* On "trunk", edit mu-moved. This will be r4, which we'll cherry-pick. */ + SVN_ERR(sbox_file_write(b, "A/mu-moved", "Modified content.\n")); + SVN_ERR(sbox_wc_commit(b, "")); /* r4 */ + SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM)); + + /* Perform a cherry-pick merge of r4 from A to A1. */ + SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool)); + trunk_url = apr_pstrcat(b->pool, b->repos_url, "/A", SVN_VA_NULL); + peg_rev.kind = svn_opt_revision_number; + peg_rev.value.number = 4; + merge_range.start.kind = svn_opt_revision_number; + merge_range.start.value.number = 3; + merge_range.end.kind = svn_opt_revision_number; + merge_range.end.value.number = 4; + ranges_to_merge = apr_array_make(b->pool, 1, + sizeof(svn_opt_revision_range_t *)); + APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = &merge_range; + /* This should raise a "local delete or move vs incoming edit" conflict. */ + SVN_ERR(svn_client_merge_peg5(trunk_url, ranges_to_merge, &peg_rev, + sbox_wc_path(b, "A1"), svn_depth_infinity, + FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, + NULL, ctx, b->pool)); + + SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu-moved"), + ctx, b->pool, b->pool)); + SVN_ERR(svn_client_conflict_get_conflicted(NULL, NULL, &tree_conflicted, + conflict, b->pool, b->pool)); + SVN_TEST_ASSERT(tree_conflicted); + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, + b->pool)); + } + + SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, b->pool)); + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + svn_client_conflict_option_local_move_file_text_merge, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, + b->pool)); + } + + /* Try to resolve the conflict. */ + SVN_ERR(svn_client_conflict_tree_resolve_by_id( + conflict, + svn_client_conflict_option_local_move_file_text_merge, + ctx, b->pool)); + + return SVN_NO_ERROR; +} + /* Regression test for chrash fixed in r1780259. */ static svn_error_t * test_cherry_pick_moved_file_with_propdel(const svn_test_opts_t *opts, @@ -4682,6 +4765,217 @@ test_cherry_pick_moved_file_with_propdel return SVN_NO_ERROR; } +static svn_error_t * +test_merge_incoming_move_file_text_merge_crlf(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b)); + svn_client_ctx_t *ctx; + svn_opt_revision_t opt_rev; + svn_client_conflict_t *conflict; + svn_boolean_t text_conflicted; + apr_array_header_t *props_conflicted; + svn_boolean_t tree_conflicted; + svn_stringbuf_t *buf; + + SVN_ERR(svn_test__sandbox_create( + b, "merge_incoming_move_file_text_merge_crlf", opts, pool)); + + SVN_ERR(sbox_add_and_commit_greek_tree(b)); + /* Edit the file to have CRLF line endings. */ + SVN_ERR(sbox_file_write(b, "A/mu", "Original content.\r\n")); + SVN_ERR(sbox_wc_commit(b, "")); + /* Create a copy of node "A". */ + SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM)); + SVN_ERR(sbox_wc_copy(b, "A", "A1")); + SVN_ERR(sbox_wc_commit(b, "")); + /* On "trunk", move the file. */ + SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-moved")); + SVN_ERR(sbox_wc_commit(b, "")); + /* On "branch", edit the file. */ + SVN_ERR(sbox_file_write(b, "A1/mu", "Modified content.\r\n")); + SVN_ERR(sbox_wc_commit(b, "")); + + SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM)); + opt_rev.kind = svn_opt_revision_head; + opt_rev.value.number = SVN_INVALID_REVNUM; + SVN_ERR(svn_test__create_client_ctx(&ctx, b, pool)); + + /* Merge "A" to "A1". */ + SVN_ERR(svn_client_merge_peg5(svn_path_url_add_component2(b->repos_url, "A", + pool), + NULL, &opt_rev, sbox_wc_path(b, "A1"), + svn_depth_infinity, + FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, + NULL, ctx, pool)); + + /* We should have a tree conflict in the file "mu". */ + SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu"), ctx, + pool, pool)); + SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted, + &props_conflicted, + &tree_conflicted, + conflict, pool, pool)); + SVN_TEST_ASSERT(!text_conflicted); + SVN_TEST_INT_ASSERT(props_conflicted->nelts, 0); + SVN_TEST_ASSERT(tree_conflicted); + + /* Check available tree conflict resolution options. */ + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + svn_client_conflict_option_incoming_delete_ignore, + svn_client_conflict_option_incoming_delete_accept, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool)); + } + + SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, pool)); + + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + svn_client_conflict_option_incoming_move_file_text_merge, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool)); + } + + /* Resolve the tree conflict by moving "mu" to "mu-moved". */ + SVN_ERR(svn_client_conflict_tree_resolve_by_id( + conflict, svn_client_conflict_option_incoming_move_file_text_merge, + ctx, pool)); + + /* The file should no longer be in conflict, and should not have a + * text conflict, because the contents are identical in "trunk" and + * in the "branch". */ + SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu-moved"), + ctx, pool, pool)); + SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted, + &props_conflicted, + &tree_conflicted, + conflict, pool, pool)); + SVN_TEST_ASSERT(!text_conflicted); + SVN_TEST_INT_ASSERT(props_conflicted->nelts, 0); + SVN_TEST_ASSERT(!tree_conflicted); + + /* And it should have expected contents. */ + SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, "A1/mu-moved"), + pool)); + SVN_TEST_STRING_ASSERT(buf->data, "Modified content.\r\n"); + + return SVN_NO_ERROR; +} + +static svn_error_t * +test_merge_incoming_move_file_text_merge_native_eol(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_test__sandbox_t *b = apr_palloc(pool, sizeof(*b)); + svn_client_ctx_t *ctx; + svn_opt_revision_t opt_rev; + svn_client_conflict_t *conflict; + svn_boolean_t text_conflicted; + apr_array_header_t *props_conflicted; + svn_boolean_t tree_conflicted; + svn_stringbuf_t *buf; + + SVN_ERR(svn_test__sandbox_create( + b, "merge_incoming_move_file_text_merge_native_eol", opts, pool)); + + SVN_ERR(sbox_add_and_commit_greek_tree(b)); + /* Set svn:eol-style on a file and edit it. */ + SVN_ERR(sbox_wc_propset(b, SVN_PROP_EOL_STYLE, "native", "A/mu"));; + SVN_ERR(sbox_file_write(b, "A/mu", "Original content.\n")); + SVN_ERR(sbox_wc_commit(b, "")); + /* Create a copy of node "A". */ + SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM)); + SVN_ERR(sbox_wc_copy(b, "A", "A1")); + SVN_ERR(sbox_wc_commit(b, "")); + /* On "trunk", move the file. */ + SVN_ERR(sbox_wc_move(b, "A/mu", "A/mu-moved")); + SVN_ERR(sbox_wc_commit(b, "")); + /* On "branch", edit the file. */ + SVN_ERR(sbox_file_write(b, "A1/mu", "Modified content.\n")); + SVN_ERR(sbox_wc_commit(b, "")); + + SVN_ERR(sbox_wc_update(b, "", SVN_INVALID_REVNUM)); + opt_rev.kind = svn_opt_revision_head; + opt_rev.value.number = SVN_INVALID_REVNUM; + SVN_ERR(svn_test__create_client_ctx(&ctx, b, pool)); + + /* Merge "A" to "A1". */ + SVN_ERR(svn_client_merge_peg5(svn_path_url_add_component2(b->repos_url, "A", + pool), + NULL, &opt_rev, sbox_wc_path(b, "A1"), + svn_depth_infinity, + FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, + NULL, ctx, pool)); + + /* We should have a tree conflict in the file "mu". */ + SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu"), ctx, + pool, pool)); + SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted, + &props_conflicted, + &tree_conflicted, + conflict, pool, pool)); + SVN_TEST_ASSERT(!text_conflicted); + SVN_TEST_INT_ASSERT(props_conflicted->nelts, 0); + SVN_TEST_ASSERT(tree_conflicted); + + /* Check available tree conflict resolution options. */ + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + svn_client_conflict_option_incoming_delete_ignore, + svn_client_conflict_option_incoming_delete_accept, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool)); + } + + SVN_ERR(svn_client_conflict_tree_get_details(conflict, ctx, pool)); + + { + svn_client_conflict_option_id_t expected_opts[] = { + svn_client_conflict_option_postpone, + svn_client_conflict_option_accept_current_wc_state, + svn_client_conflict_option_incoming_move_file_text_merge, + -1 /* end of list */ + }; + SVN_ERR(assert_tree_conflict_options(conflict, ctx, expected_opts, pool)); + } + + /* Resolve the tree conflict by moving "mu" to "mu-moved". */ + SVN_ERR(svn_client_conflict_tree_resolve_by_id( + conflict, svn_client_conflict_option_incoming_move_file_text_merge, + ctx, pool)); + + /* The file should no longer be in conflict, and should not have a + * text conflict, because the contents are identical in "trunk" and + * in the "branch". */ + SVN_ERR(svn_client_conflict_get(&conflict, sbox_wc_path(b, "A1/mu-moved"), + ctx, pool, pool)); + SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted, + &props_conflicted, + &tree_conflicted, + conflict, pool, pool)); + SVN_TEST_ASSERT(!text_conflicted); + SVN_TEST_INT_ASSERT(props_conflicted->nelts, 0); + SVN_TEST_ASSERT(!tree_conflicted); + + /* And it should have expected contents. */ + SVN_ERR(svn_stringbuf_from_file2(&buf, sbox_wc_path(b, "A1/mu-moved"), + pool)); + SVN_TEST_STRING_ASSERT(buf->data, "Modified content." APR_EOL_STR); + + return SVN_NO_ERROR; +} + /* ========================================================================== */ @@ -4764,6 +5058,12 @@ static struct svn_test_descriptor_t test "update incoming add dir merge with obstructions"), SVN_TEST_OPTS_PASS(test_cherry_pick_moved_file_with_propdel, "cherry-pick with moved file and propdel"), + SVN_TEST_OPTS_PASS(test_merge_incoming_move_file_text_merge_crlf, + "merge incoming move file merge with CRLF eols"), + SVN_TEST_OPTS_PASS(test_merge_incoming_move_file_text_merge_native_eol, + "merge incoming move file merge with native eols"), + SVN_TEST_OPTS_XFAIL(test_cherry_pick_post_move_edit, + "cherry-pick edit from moved file"), SVN_TEST_NULL }; Modified: subversion/branches/addremove/subversion/tests/libsvn_delta/random-test.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/libsvn_delta/random-test.c?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/libsvn_delta/random-test.c (original) +++ subversion/branches/addremove/subversion/tests/libsvn_delta/random-test.c Tue Aug 22 14:19:36 2017 @@ -515,6 +515,96 @@ random_combine_test(apr_pool_t *pool) } +/* (Note: *LAST_SEED is an output parameter.) */ +static svn_error_t * +do_random_txdelta_to_svndiff_stream_test(apr_pool_t *pool, + apr_uint32_t *last_seed) +{ + apr_uint32_t seed; + apr_uint32_t maxlen; + apr_size_t bytes_range; + int i; + int iterations; + int dump_files; + int print_windows; + const char *random_bytes; + apr_pool_t *iterpool; + + /* Initialize parameters and print out the seed in case we dump core + or something. */ + init_params(&seed, &maxlen, &iterations, &dump_files, &print_windows, + &random_bytes, &bytes_range, pool); + + iterpool = svn_pool_create(pool); + for (i = 0; i < iterations; i++) + { + apr_uint32_t subseed_base; + apr_file_t *source; + apr_file_t *target; + apr_file_t *source_copy; + apr_file_t *new_target; + svn_txdelta_stream_t *txstream; + svn_stream_t *delta_stream; + svn_txdelta_window_handler_t handler; + void *handler_baton; + svn_stream_t *push_stream; + + svn_pool_clear(iterpool); + + /* Generate source and target for the delta and its application. */ + *last_seed = seed; + subseed_base = svn_test_rand(&seed); + source = generate_random_file(maxlen, subseed_base, &seed, + random_bytes, bytes_range, + dump_files, iterpool); + target = generate_random_file(maxlen, subseed_base, &seed, + random_bytes, bytes_range, + dump_files, iterpool); + source_copy = copy_tempfile(source, iterpool); + new_target = open_tempfile(NULL, iterpool); + + /* Create a txdelta stream that turns the source into target; + turn it into a generic readable svn_stream_t. */ + svn_txdelta2(&txstream, + svn_stream_from_aprfile2(source, TRUE, iterpool), + svn_stream_from_aprfile2(target, TRUE, iterpool), + FALSE, iterpool); + delta_stream = svn_txdelta_to_svndiff_stream(txstream, i % 3, i % 10, + iterpool); + + /* Apply it to a copy of the source file to see if we get the + same target back. */ + svn_txdelta_apply(svn_stream_from_aprfile2(source_copy, TRUE, iterpool), + svn_stream_from_aprfile2(new_target, TRUE, iterpool), + NULL, NULL, iterpool, &handler, &handler_baton); + push_stream = svn_txdelta_parse_svndiff(handler, handler_baton, TRUE, + iterpool); + SVN_ERR(svn_stream_copy3(delta_stream, push_stream, NULL, NULL, + iterpool)); + + SVN_ERR(compare_files(target, new_target, dump_files)); + + apr_file_close(source); + apr_file_close(target); + apr_file_close(source_copy); + apr_file_close(new_target); + } + svn_pool_destroy(iterpool); + + return SVN_NO_ERROR; +} + +/* Implements svn_test_driver_t. */ +static svn_error_t * +random_txdelta_to_svndiff_stream_test(apr_pool_t *pool) +{ + apr_uint32_t seed; + svn_error_t *err = do_random_txdelta_to_svndiff_stream_test(pool, &seed); + if (err) + fprintf(stderr, "SEED: %lu\n", (unsigned long)seed); + return err; +} + /* Change to 1 to enable the unit test for the delta combiner's range index: */ #if 0 #include "range-index-test.h" @@ -533,6 +623,8 @@ static struct svn_test_descriptor_t test "random delta test"), SVN_TEST_PASS2(random_combine_test, "random combine delta test"), + SVN_TEST_PASS2(random_txdelta_to_svndiff_stream_test, + "random txdelta to svndiff stream test"), #ifdef SVN_RANGE_INDEX_TEST_H SVN_TEST_PASS2(random_range_index_test, "random range index test"), Propchange: subversion/branches/addremove/subversion/tests/libsvn_subr/ ------------------------------------------------------------------------------ --- svn:ignore (original) +++ svn:ignore Tue Aug 22 14:19:36 2017 @@ -10,6 +10,7 @@ Debug Release checksum-test compat-test +compress-test config-test crypto-test error-test Modified: subversion/branches/addremove/subversion/tests/libsvn_subr/checksum-test.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/libsvn_subr/checksum-test.c?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/libsvn_subr/checksum-test.c (original) +++ subversion/branches/addremove/subversion/tests/libsvn_subr/checksum-test.c Tue Aug 22 14:19:36 2017 @@ -296,6 +296,74 @@ test_checksum_parse_all_zero(apr_pool_t return SVN_NO_ERROR; } +static svn_error_t * +test_checksummed_stream_read(apr_pool_t *pool) +{ + const svn_string_t *str = svn_string_create("abcde", pool); + svn_checksum_kind_t kind; + + for (kind = svn_checksum_md5; kind <= svn_checksum_fnv1a_32x4; ++kind) + { + svn_stream_t *stream; + svn_checksum_t *expected_checksum; + svn_checksum_t *actual_checksum; + char buf[64]; + apr_size_t len; + + stream = svn_stream_from_string(str, pool); + stream = svn_stream_checksummed2(stream, &actual_checksum, NULL, + kind, TRUE, pool); + len = str->len; + SVN_ERR(svn_stream_read_full(stream, buf, &len)); + SVN_TEST_INT_ASSERT((int) len, str->len); + + SVN_ERR(svn_stream_close(stream)); + + SVN_ERR(svn_checksum(&expected_checksum, kind, + str->data, str->len, pool)); + SVN_TEST_ASSERT(svn_checksum_match(expected_checksum, actual_checksum)); + } + + return SVN_NO_ERROR; +} + +static svn_error_t * +test_checksummed_stream_reset(apr_pool_t *pool) +{ + const svn_string_t *str = svn_string_create("abcde", pool); + svn_checksum_kind_t kind; + + for (kind = svn_checksum_md5; kind <= svn_checksum_fnv1a_32x4; ++kind) + { + svn_stream_t *stream; + svn_checksum_t *expected_checksum; + svn_checksum_t *actual_checksum; + char buf[64]; + apr_size_t len; + + stream = svn_stream_from_string(str, pool); + stream = svn_stream_checksummed2(stream, &actual_checksum, NULL, + kind, TRUE, pool); + len = str->len; + SVN_ERR(svn_stream_read_full(stream, buf, &len)); + SVN_TEST_INT_ASSERT((int) len, str->len); + + SVN_ERR(svn_stream_reset(stream)); + + len = str->len; + SVN_ERR(svn_stream_read_full(stream, buf, &len)); + SVN_TEST_INT_ASSERT((int) len, str->len); + + SVN_ERR(svn_stream_close(stream)); + + SVN_ERR(svn_checksum(&expected_checksum, kind, + str->data, str->len, pool)); + SVN_TEST_ASSERT(svn_checksum_match(expected_checksum, actual_checksum)); + } + + return SVN_NO_ERROR; +} + /* An array of all test functions */ static int max_threads = 1; @@ -317,6 +385,10 @@ static struct svn_test_descriptor_t test "checksum (de-)serialization"), SVN_TEST_PASS2(test_checksum_parse_all_zero, "checksum parse all zero"), + SVN_TEST_PASS2(test_checksummed_stream_read, + "read from checksummed stream"), + SVN_TEST_PASS2(test_checksummed_stream_reset, + "reset checksummed stream"), SVN_TEST_NULL }; Modified: subversion/branches/addremove/subversion/tests/libsvn_subr/dirent_uri-test.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/libsvn_subr/dirent_uri-test.c?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/libsvn_subr/dirent_uri-test.c (original) +++ subversion/branches/addremove/subversion/tests/libsvn_subr/dirent_uri-test.c Tue Aug 22 14:19:36 2017 @@ -938,6 +938,13 @@ static const testcase_canonicalize_t uri /* Hostnames that look like non-canonical paths */ { "file://./foo", "file://./foo" }, { "http://./foo", "http://./foo" }, + /* Some invalid URLs, these still have a canonical form */ + { "http://server:81:81/", "http://server:81:81" }, + { "http://server:81foo/", "http://server:81foo" }, + { "http://server::/", "http://server::" }, + { "http://server:-/", "http://server:-" }, + { "http://hst:1.2.3.4.5/", "http://hst:1.2.3.4.5"}, + { "http://hst:1.2.999.4/", "http://hst:1.2.999.4"}, /* svn_uri_is_canonical() was a private function in the 1.6 API, and has since taken a MAJOR change of direction, namely that only absolute URLs are considered canonical uris now. */ @@ -1238,6 +1245,12 @@ test_uri_is_canonical(apr_pool_t *pool) t->path, canonical ? "TRUE" : "FALSE", t->result); + + if (t->result && !svn_uri_is_canonical(t->result, pool)) + return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, + "svn_uri_is_canonical(\"%s\") returned " + "FALSE on canonical form", + t->result); } return SVN_NO_ERROR; Modified: subversion/branches/addremove/subversion/tests/libsvn_subr/mergeinfo-test.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/libsvn_subr/mergeinfo-test.c?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/libsvn_subr/mergeinfo-test.c (original) +++ subversion/branches/addremove/subversion/tests/libsvn_subr/mergeinfo-test.c Tue Aug 22 14:19:36 2017 @@ -1770,10 +1770,96 @@ test_rangelist_merge_overlap(apr_pool_t return SVN_NO_ERROR; } +static svn_error_t * +test_rangelist_loop(apr_pool_t *pool) +{ + apr_pool_t *iterpool = svn_pool_create(pool); + int x, y; + + for (x = 0; x < 62; x++) + for (y = x + 1; y < 63; y++) + { + svn_rangelist_t *base_list; + svn_rangelist_t *change_list; + svn_merge_range_t *mrange; + svn_pool_clear(iterpool); + + SVN_ERR(svn_rangelist__parse(&base_list, + "2,4,7-9,12-15,18-20," + "22*,25*,28-30*,33-35*," + "38-40,43-45*,48-50,52-54,56-59*", + iterpool)); + + change_list = apr_array_make(iterpool, 1, sizeof(mrange)); + + mrange = apr_pcalloc(pool, sizeof(*mrange)); + mrange->start = x; + mrange->end = y; + APR_ARRAY_PUSH(change_list, svn_merge_range_t *) = mrange; + + { + svn_rangelist_t *bl = svn_rangelist_dup(base_list, iterpool); + svn_rangelist_t *cl = svn_rangelist_dup(change_list, iterpool); + + SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl)); + SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl)); + + SVN_ERR(svn_rangelist_merge2(bl, cl, iterpool, iterpool)); + + SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl)); + SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl)); + + /* TODO: Verify result */ + } + + { + svn_rangelist_t *bl = svn_rangelist_dup(base_list, iterpool); + svn_rangelist_t *cl = svn_rangelist_dup(change_list, iterpool); + + SVN_ERR(svn_rangelist_merge2(cl, bl, iterpool, iterpool)); + + SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl)); + SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl)); + + /* TODO: Verify result */ + } + + mrange->inheritable = TRUE; + + { + svn_rangelist_t *bl = svn_rangelist_dup(base_list, iterpool); + svn_rangelist_t *cl = svn_rangelist_dup(change_list, iterpool); + + SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl)); + SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl)); + + SVN_ERR(svn_rangelist_merge2(bl, cl, iterpool, iterpool)); + + SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl)); + SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl)); + + /* TODO: Verify result */ + } + + { + svn_rangelist_t *bl = svn_rangelist_dup(base_list, iterpool); + svn_rangelist_t *cl = svn_rangelist_dup(change_list, iterpool); + + SVN_ERR(svn_rangelist_merge2(cl, bl, iterpool, iterpool)); + + SVN_TEST_ASSERT(svn_rangelist__is_canonical(bl)); + SVN_TEST_ASSERT(svn_rangelist__is_canonical(cl)); + + /* TODO: Verify result */ + } + } + + return SVN_NO_ERROR; +} /* The test table. */ -static int max_threads = 1; +static int max_threads = 4; static struct svn_test_descriptor_t test_funcs[] = { @@ -1816,6 +1902,8 @@ static struct svn_test_descriptor_t test "removal of prefix paths from catalog keys"), SVN_TEST_XFAIL2(test_rangelist_merge_overlap, "merge of rangelists with overlaps (issue 4686)"), + SVN_TEST_XFAIL2(test_rangelist_loop, + "test rangelist edgecases via loop"), SVN_TEST_NULL }; Modified: subversion/branches/addremove/subversion/tests/libsvn_subr/utf-test.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/tests/libsvn_subr/utf-test.c?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/subversion/tests/libsvn_subr/utf-test.c (original) +++ subversion/branches/addremove/subversion/tests/libsvn_subr/utf-test.c Tue Aug 22 14:19:36 2017 @@ -664,11 +664,18 @@ test_utf_fuzzy_escape(apr_pool_t *pool) SVN_TEST_ASSERT(0 == strcmp(fuzzy, "Subversi{U+03BF}n")); fuzzy = svn_utf__fuzzy_escape(invalid, sizeof(invalid) - 1, pool); - /*fprintf(stderr, "%s\n", fuzzy);*/ + + /* utf8proc 1.1.15 produces {U?FDD1} while 2.x produces {U+FDD1} */ SVN_TEST_ASSERT(0 == strcmp(fuzzy, "Not Unicode: {U?FDD1};" "Out of range: ?\\F4?\\90?\\80?\\81;" "Not UTF-8: ?\\E6;" + "Null byte: \\0;") + || + 0 == strcmp(fuzzy, + "Not Unicode: {U+FDD1};" + "Out of range: ?\\F4?\\90?\\80?\\81;" + "Not UTF-8: ?\\E6;" "Null byte: \\0;")); return SVN_NO_ERROR; Modified: subversion/branches/addremove/tools/buildbot/slaves/svn-x64-macosx/svnbuild.sh URL: http://svn.apache.org/viewvc/subversion/branches/addremove/tools/buildbot/slaves/svn-x64-macosx/svnbuild.sh?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/tools/buildbot/slaves/svn-x64-macosx/svnbuild.sh (original) +++ subversion/branches/addremove/tools/buildbot/slaves/svn-x64-macosx/svnbuild.sh Tue Aug 22 14:19:36 2017 @@ -71,6 +71,11 @@ if [ ${svnminor} -gt 8 ]; then optimizeconfig=' --enable-optimize' fi +if [ ${svnminor} -ge 10 ]; then + lz4config='--with-lz4=internal' + utf8proconfig='--with-utf8proc=internal' +fi + # # Step 3: Configure # @@ -88,6 +93,8 @@ ${abssrc}/configure \ --with-berkeley-db=db.h:"${SVNBB_BDB}/include":${SVNBB_BDB}/lib:db \ --enable-javahl \ --without-jikes \ + ${lz4config} \ + ${utf8proconfig} \ --with-junit="${SVNBB_JUNIT}" test -f config.log && mv config.log "${abssrc}/.test-logs/config.log" Modified: subversion/branches/addremove/tools/dev/unix-build/Makefile.svn URL: http://svn.apache.org/viewvc/subversion/branches/addremove/tools/dev/unix-build/Makefile.svn?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/tools/dev/unix-build/Makefile.svn (original) +++ subversion/branches/addremove/tools/dev/unix-build/Makefile.svn Tue Aug 22 14:19:36 2017 @@ -100,6 +100,7 @@ BZ2_VER = 1.0.6 PYTHON_VER = 2.7.13 JUNIT_VER = 4.10 GETTEXT_VER = 0.19.8.1 +LZ4_VER = 1.7.5 BDB_DIST = db-$(BDB_VER).tar.gz APR_ICONV_DIST = apr-iconv-$(APR_ICONV_VER).tar.gz @@ -114,6 +115,7 @@ BZ2_DIST = bzip2-$(BZ2_VER).tar.gz PYTHON_DIST = Python-$(PYTHON_VER).tgz JUNIT_DIST = junit-${JUNIT_VER}.jar GETTEXT_DIST = gettext-$(GETTEXT_VER).tar.gz +LZ4_DIST = lz4-$(LZ4_VER).tar.gz SHA256_${BDB_DIST} = f14fd96dd38915a1d63dcb94a63fbb8092334ceba6b5060760427096f631263e SHA256_${APR_ICONV_DIST} = 19381959d50c4a5f3b9c84d594a5f9ffb3809786919b3058281f4c87e1f4b245 @@ -128,6 +130,7 @@ SHA256_${BZ2_DIST} = a2848f34fcd5d6cf47d SHA256_${PYTHON_DIST} = a4f05a0720ce0fd92626f0278b6b433eee9a6173ddf2bced7957dfb599a5ece1 SHA256_${JUNIT_DIST} = 36a747ca1e0b86f6ea88055b8723bb87030d627766da6288bf077afdeeb0f75a SHA256_${GETTEXT_DIST} = ff942af0e438ced4a8b0ea4b0b6e0d6d657157c5e2364de57baa279c1c125c43 +SHA256_${LZ4_DIST} = 0190cacd63022ccb86f44fa5041dc6c3804407ad61550ca21c382827319e7e7e define do_check_sha256 if [ -x /bin/sha256 ]; then \ @@ -176,6 +179,7 @@ BZ2_URL = http://bzip.org/$(BZ2_VER)/$( PYTHON_URL = https://python.org/ftp/python/$(PYTHON_VER)/$(PYTHON_DIST) JUNIT_URL = https://downloads.sourceforge.net/project/junit/junit/$(JUNIT_VER)/$(JUNIT_DIST) GETTEXT_URL = https://ftp.gnu.org/pub/gnu/gettext/$(GETTEXT_DIST) +LZ4_URL = https://github.com/lz4/lz4/archive/v$(LZ4_VER).tar.gz BDB_SRCDIR = $(SRCDIR)/db-$(BDB_VER) @@ -194,6 +198,7 @@ RUBY_SRCDIR = $(SRCDIR)/ruby-$(RUBY_VER) BZ2_SRCDIR = $(SRCDIR)/bzip2-$(BZ2_VER) PYTHON_SRCDIR = $(SRCDIR)/Python-$(PYTHON_VER) GETTEXT_SRCDIR = $(SRCDIR)/gettext-$(GETTEXT_VER) +LZ4_SRCDIR = ${SRCDIR}/lz4-$(LZ4_VER) SVN_SRCDIR = $(SVN_WC) BDB_OBJDIR = $(OBJDIR)/db-$(BDB_VER) @@ -212,6 +217,7 @@ RUBY_OBJDIR = $(OBJDIR)/ruby-$(RUBY_VER) BZ2_OBJDIR = $(OBJDIR)/bzip2-$(BZ2_VER) PYTHON_OBJDIR = $(OBJDIR)/python-$(PYTHON_VER) GETTEXT_OBJDIR = $(OBJDIR)/gettext-$(GETTEXT_VER) +LZ4_OBJDIR = ${OBJDIR}/lz4-$(LZ4_VER) SVN_OBJDIR = $(OBJDIR)/$(SVN_REL_WC) # Tweak this for out-of-tree builds. Note that running individual @@ -236,18 +242,19 @@ all: dirs-create bdb-install apr-install httpd-install neon-install serf-install serf-old-install \ sqlite-install cyrus-sasl-install libmagic-install \ ruby-install bz2-install python-install gettext-install \ - svn-install svn-bindings-install + lz4-install svn-install svn-bindings-install # Use these to start a build from the beginning. reset: dirs-reset bdb-reset apr-reset iconv-reset apr-util-reset \ httpd-reset neon-reset serf-reset serf-old-reset sqlite-reset \ cyrus-sasl-reset libmagic-reset ruby-reset python-reset \ - bz2-reset gettext-reset svn-reset + bz2-reset gettext-reset lz4-reset svn-reset # Use to save disk space. clean: bdb-clean apr-clean iconv-clean apr-util-clean httpd-clean \ neon-clean serf-clean serf-old-clean sqlite-clean cyrus-sasl-clean \ - libmagic-clean ruby-clean bz2-clean python-clean gettext-clean svn-clean + libmagic-clean ruby-clean bz2-clean python-clean gettext-clean \ + lz4-clean svn-clean # Nukes everything (including installed binaries!) # Use this to start ALL OVER AGAIN! Use with caution! @@ -1319,6 +1326,49 @@ $(GETTEXT_OBJDIR)/.installed: $(GETTEXT_ touch $@ ####################################################################### +# lz4 +####################################################################### + +lz4-retrieve: $(LZ4_OBJDIR)/.retrieved +lz4-configure: $(LZ4_OBJDIR)/.configured +lz4-compile: $(LZ4_OBJDIR)/.compiled +lz4-install: $(LZ4_OBJDIR)/.installed +lz4-reset: + $(foreach f, .retrieved .configured .compiled .installed, \ + rm -f $(LZ4_OBJDIR)/$(f);) + +lz4-clean: + -(cd $(LZ4_SRCDIR) && env MAKEFLAGS= $(MAKE) clean) + +# fetch distfile for lz4 +$(DISTDIR)/$(LZ4_DIST): + cd $(DISTDIR) && $(FETCH_CMD) -O $(LZ4_DIST) $(LZ4_URL) + +# retrieve lz4 +$(LZ4_OBJDIR)/.retrieved: $(DISTDIR)/$(LZ4_DIST) + $(call do_check_sha256,$(LZ4_DIST)) + [ -d $(LZ4_OBJDIR) ] || mkdir -p $(LZ4_OBJDIR) + tar -C $(SRCDIR) -zxf $(DISTDIR)/$(LZ4_DIST) + touch $@ + +# configure lz4 +$(LZ4_OBJDIR)/.configured: $(LZ4_OBJDIR)/.retrieved + touch $@ + +# compile lz4 +$(LZ4_OBJDIR)/.compiled: $(LZ4_OBJDIR)/.configured + (cd $(LZ4_SRCDIR)/lib && \ + env MAKEFLAGS= $(MAKE) PREFIX=$(PREFIX)/lz4) + touch $@ + +# install lz4 +$(LZ4_OBJDIR)/.installed: $(LZ4_OBJDIR)/.compiled + mkdir -p $(PREFIX)/lz4/lib + (cd $(LZ4_SRCDIR)/lib && \ + env MAKEFLAGS= $(MAKE) PREFIX=$(PREFIX)/lz4 install) + touch $@ + +####################################################################### # svn ####################################################################### @@ -1393,7 +1443,7 @@ DISABLE_NEON_VERSION_CHECK=--disable-neo W_NO_SYSTEM_HEADERS=-Wno-system-headers NEON_FLAG=--with-neon="$(PREFIX)/neon" JAVAHL_CHECK_TARGET=check-javahl -else # 1.8 +else ifeq ($(BRANCH_MAJOR), $(filter $(BRANCH_MAJOR), 1.8 1.9)) BDB_FLAG=db.h:$(PREFIX)/bdb/include:$(PREFIX)/bdb/lib:db-$(BDB_MAJOR_VER) SERF_FLAG=--with-serf="$(PREFIX)/serf" # serf >= 1.3.0 is built with scons and no longer sets up rpath linker flags, @@ -1404,6 +1454,19 @@ MOD_AUTHZ_SVN=modules/svn-$(WC)/mod_auth MOD_DONTDOTHAT=modules/svn-$(WC)/mod_dontdothat.so LIBMAGIC_FLAG=--with-libmagic=$(PREFIX)/libmagic JAVAHL_CHECK_TARGET=check-all-javahl +else # 1.10 +BDB_FLAG=db.h:$(PREFIX)/bdb/include:$(PREFIX)/bdb/lib:db-$(BDB_MAJOR_VER) +SERF_FLAG=--with-serf="$(PREFIX)/serf" +# serf >= 1.3.0 is built with scons and no longer sets up rpath linker flags, +# so we have to do that ourselves :( +SERF_LDFLAG=-Wl,-rpath,$(PREFIX)/serf/lib -Wl,-rpath,$(PREFIX)/bdb/lib +MOD_DAV_SVN=modules/svn-$(WC)/mod_dav_svn.so +MOD_AUTHZ_SVN=modules/svn-$(WC)/mod_authz_svn.so +MOD_DONTDOTHAT=modules/svn-$(WC)/mod_dontdothat.so +LIBMAGIC_FLAG=--with-libmagic=$(PREFIX)/libmagic +JAVAHL_CHECK_TARGET=check-all-javahl +LZ4_FLAG=--with-lz4=$(PREFIX)/lz4 +UTF8PROC_FLAG=--with-utf8proc=internal endif ifeq ($(ENABLE_JAVA_BINDINGS),yes) @@ -1454,6 +1517,8 @@ $(SVN_OBJDIR)/.configured: $(SVN_OBJDIR) --disable-mod-activation \ $(JAVAHL_FLAG) \ $(LIBMAGIC_FLAG) \ + $(LZ4_FLAG) \ + $(UTF8PROC_FLAG) \ $(SVN_STATIC_FLAG) \ $(DISABLE_NEON_VERSION_CHECK) touch $@ @@ -2019,6 +2084,9 @@ endif @echo "serf: $(SERF_VER)" @echo "cyrus-sasl: $(CYRUS_SASL_VER)" @echo "sqlite: $(SQLITE_VER)" +ifdef LZ4_FLAG + @echo "lz4: $(LZ4_VER)" +endif @echo "libssl: `openssl version`" @echo "swig: `swig -version | grep Version | cut -d' ' -f3`" @echo "python: $(PYTHON_VER)" Modified: subversion/branches/addremove/tools/dist/dist.sh URL: http://svn.apache.org/viewvc/subversion/branches/addremove/tools/dist/dist.sh?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/tools/dist/dist.sh (original) +++ subversion/branches/addremove/tools/dist/dist.sh Tue Aug 22 14:19:36 2017 @@ -57,6 +57,7 @@ # To build a Windows zip file package, additionally pass -zip and the # path to apr-iconv with -apri. +set -e USAGE="USAGE: ./dist.sh -v VERSION -r REVISION -pr REPOS-PATH \ [-alpha ALPHA_NUM|-beta BETA_NUM|-rc RC_NUM|-pre PRE_NUM] \ @@ -205,7 +206,7 @@ export TZ echo "Exporting $REPOS_PATH r$REVISION into sandbox..." (cd "$DIST_SANDBOX" && \ ${SVN:-svn} export -q $EXTRA_EXPORT_OPTIONS \ - "http://svn.apache.org/repos/asf/subversion/$REPOS_PATH"@"$REVISION" \ + "https://svn.apache.org/repos/asf/subversion/$REPOS_PATH"@"$REVISION" \ "$DISTNAME" --username none --password none) rm -f "$DISTPATH/STATUS" @@ -242,7 +243,7 @@ fi # Instead of attempting to deal with various line ending issues, just export # the find_python script manually. ${svn:-svn} export -q -r "$REVISION" \ - "http://svn.apache.org/repos/asf/subversion/$REPOS_PATH/build/find_python.sh" \ + "https://svn.apache.org/repos/asf/subversion/$REPOS_PATH/build/find_python.sh" \ --username none --password none "$DIST_SANDBOX/find_python.sh" PYTHON="`$DIST_SANDBOX/find_python.sh`" if test -z "$PYTHON"; then @@ -297,7 +298,7 @@ echo "Running po-update.sh in sandbox, t # Can't use the po-update.sh in the packaged export since it might have CRLF # line endings, in which case it won't run. So first we export it again. ${svn:-svn} export -q -r "$REVISION" \ - "http://svn.apache.org/repos/asf/subversion/$REPOS_PATH/tools/po/po-update.sh" \ + "https://svn.apache.org/repos/asf/subversion/$REPOS_PATH/tools/po/po-update.sh" \ --username none --password none "$DIST_SANDBOX/po-update.sh" (cd "$DISTPATH" && ../po-update.sh pot) || exit 1 Modified: subversion/branches/addremove/tools/dist/release.py URL: http://svn.apache.org/viewvc/subversion/branches/addremove/tools/dist/release.py?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/tools/dist/release.py (original) +++ subversion/branches/addremove/tools/dist/release.py Tue Aug 22 14:19:36 2017 @@ -166,6 +166,27 @@ class Version(object): else: return 'supported-releases' + def get_ver_tags(self, revnum): + # These get substituted into svn_version.h + ver_tag = '' + ver_numtag = '' + if self.pre == 'alpha': + ver_tag = '" (Alpha %d)"' % self.pre_num + ver_numtag = '"-alpha%d"' % self.pre_num + elif self.pre == 'beta': + ver_tag = '" (Beta %d)"' % args.version.pre_num + ver_numtag = '"-beta%d"' % self.pre_num + elif self.pre == 'rc': + ver_tag = '" (Release Candidate %d)"' % self.pre_num + ver_numtag = '"-rc%d"' % self.pre_num + elif self.pre == 'nightly': + ver_tag = '" (Nightly Build r%d)"' % revnum + ver_numtag = '"-nightly-r%d"' % revnum + else: + ver_tag = '" (r%d)"' % revnum + ver_numtag = '""' + return (ver_tag, ver_numtag) + def __serialize(self): return (self.major, self.minor, self.patch, self.pre, self.pre_num) @@ -199,7 +220,7 @@ class Version(object): return self.pre_num < that.pre_num def __str__(self): - "Return an SVN_VER_NUMBER-formattes string, or 'nightly'." + "Return an SVN_VER_NUMBER-formatted string, or 'nightly'." if self.pre: if self.pre == 'nightly': return 'nightly' @@ -220,6 +241,18 @@ def get_prefix(base_dir): def get_tempdir(base_dir): return os.path.join(base_dir, 'tempdir') +def get_workdir(base_dir): + return os.path.join(get_tempdir(base_dir), 'working') + +# The name of this directory is also used to name the tarball and for +# the root of paths within the tarball, e.g. subversion-1.9.5 or +# subversion-nightly-r1800000 +def get_exportdir(base_dir, version, revnum): + if version.pre != 'nightly': + return os.path.join(get_tempdir(base_dir), 'subversion-'+str(version)) + return os.path.join(get_tempdir(base_dir), + 'subversion-%s-r%d' % (version, revnum)) + def get_deploydir(base_dir): return os.path.join(base_dir, 'deploy') @@ -243,13 +276,14 @@ def get_tmplfile(filename): def get_nullfile(): return open(os.path.devnull, 'w') -def run_script(verbose, script): +def run_script(verbose, script, hide_stderr=False): + stderr = None if verbose: stdout = None - stderr = None else: stdout = get_nullfile() - stderr = subprocess.STDOUT + if hide_stderr: + stderr = get_nullfile() for l in script.split('\n'): subprocess.check_call(l.split(), stdout=stdout, stderr=stderr) @@ -484,6 +518,16 @@ def check_copyright_year(repos, branch, check_file('NOTICE') check_file('subversion/libsvn_subr/version.c') +def replace_lines(path, actions): + with open(path, 'r') as old_content: + lines = old_content.readlines() + with open(path, 'w') as new_content: + for line in lines: + for start, pattern, repl in actions: + if line.startswith(start): + line = re.sub(pattern, repl, line) + new_content.write(line) + def roll_tarballs(args): 'Create the release artifacts.' @@ -524,43 +568,163 @@ def roll_tarballs(args): os.mkdir(get_deploydir(args.base_dir)) - # For now, just delegate to dist.sh to create the actual artifacts - extra_args = '' - if args.version.is_prerelease(): - if args.version.pre == 'nightly': - extra_args = '-nightly' + logging.info('Preparing working copy source') + shutil.rmtree(get_workdir(args.base_dir), True) + run_script(args.verbose, 'svn checkout %s %s' + % (repos + '/' + branch + '@' + str(args.revnum), + get_workdir(args.base_dir))) + + # Exclude stuff we don't want in the tarball, it will not be present + # in the exported tree. + exclude = ['contrib', 'notes'] + if branch != 'trunk': + exclude += ['STATUS'] + if args.version.minor < 7: + exclude += ['packages', 'www'] + cwd = os.getcwd() + os.chdir(get_workdir(args.base_dir)) + run_script(args.verbose, + 'svn update --set-depth exclude %s' % " ".join(exclude)) + os.chdir(cwd) + + if args.patches: + # Assume patches are independent and can be applied in any + # order, no need to sort. + majmin = '%d.%d' % (args.version.major, args.version.minor) + for name in os.listdir(args.patches): + if name.find(majmin) != -1 and name.endswith('patch'): + logging.info('Applying patch %s' % name) + run_script(args.verbose, + '''svn patch %s %s''' + % (os.path.join(args.patches, name), + get_workdir(args.base_dir))) + + # Massage the new version number into svn_version.h. + ver_tag, ver_numtag = args.version.get_ver_tags(args.revnum) + replacements = [('#define SVN_VER_TAG', + '".*"', ver_tag), + ('#define SVN_VER_NUMTAG', + '".*"', ver_numtag), + ('#define SVN_VER_REVISION', + '[0-9][0-9]*', str(args.revnum))] + if args.version.pre != 'nightly': + # SVN_VER_PATCH might change for security releases, e.g., when + # releasing 1.9.7 from the magic revision of 1.9.6. + # + # ### Would SVN_VER_MAJOR / SVN_VER_MINOR ever change? + # ### Note that SVN_VER_MINOR is duplicated in some places, see + # ### <https://subversion.apache.org/docs/community-guide/releasing.html#release-branches> + replacements += [('#define SVN_VER_MAJOR', + '[0-9][0-9]*', str(args.version.major)), + ('#define SVN_VER_MINOR', + '[0-9][0-9]*', str(args.version.minor)), + ('#define SVN_VER_PATCH', + '[0-9][0-9]*', str(args.version.patch))] + replace_lines(os.path.join(get_workdir(args.base_dir), + 'subversion', 'include', 'svn_version.h'), + replacements) + + # Basename for export and tarballs, e.g. subversion-1.9.5 or + # subversion-nightly-r1800000 + exportdir = get_exportdir(args.base_dir, args.version, args.revnum) + basename = os.path.basename(exportdir) + + def export(windows): + shutil.rmtree(exportdir, True) + if windows: + eol_style = "--native-eol CRLF" else: - extra_args = '-%s %d' % (args.version.pre, args.version.pre_num) - # Build Unix last to leave Unix-style svn_version.h for tagging + eol_style = "--native-eol LF" + run_script(args.verbose, "svn export %s %s %s" + % (eol_style, get_workdir(args.base_dir), exportdir)) + + def transform_sql(): + for root, dirs, files in os.walk(exportdir): + for fname in files: + if fname.endswith('.sql'): + run_script(args.verbose, + 'python build/transform_sql.py %s/%s %s/%s' + % (root, fname, root, fname[:-4] + '.h')) + + def clean_autom4te(): + for root, dirs, files in os.walk(get_workdir(args.base_dir)): + for dname in dirs: + if dname.startswith('autom4te') and dname.endswith('.cache'): + shutil.rmtree(os.path.join(root, dname)) + logging.info('Building Windows tarballs') - run_script(args.verbose, '%s/dist.sh -v %s -pr %s -r %d -zip %s' - % (sys.path[0], args.version.base, branch, args.revnum, - extra_args) ) - logging.info('Building UNIX tarballs') - run_script(args.verbose, '%s/dist.sh -v %s -pr %s -r %d %s' - % (sys.path[0], args.version.base, branch, args.revnum, - extra_args) ) + export(windows=True) + os.chdir(exportdir) + transform_sql() + # Can't use the po-update.sh in the Windows export since it has CRLF + # line endings and won't run, so use the one in the working copy. + run_script(args.verbose, + '%s/tools/po/po-update.sh pot' % get_workdir(args.base_dir)) + os.chdir(cwd) + clean_autom4te() # dist.sh does it but pointless on Windows? + os.chdir(get_tempdir(args.base_dir)) + run_script(args.verbose, + 'zip -q -r %s %s' % (basename + '.zip', basename)) + os.chdir(cwd) + + logging.info('Building Unix tarballs') + export(windows=False) + os.chdir(exportdir) + transform_sql() + run_script(args.verbose, + '''tools/po/po-update.sh pot + ./autogen.sh --release''', + hide_stderr=True) # SWIG is noisy + os.chdir(cwd) + clean_autom4te() # dist.sh does it but probably pointless + + # Do not use tar, it's probably GNU tar which produces tar files + # that are not compliant with POSIX.1 when including filenames + # longer than 100 chars. Platforms without a tar that understands + # the GNU tar extension will not be able to extract the resulting + # tar file. Use pax to produce POSIX.1 tar files. + # + # Use the gzip -n flag - this prevents it from storing the + # original name of the .tar file, and far more importantly, the + # mtime of the .tar file, in the produced .tar.gz file. This is + # important, because it makes the gzip encoding reproducable by + # anyone else who has an similar version of gzip, and also uses + # "gzip -9n". This means that committers who want to GPG-sign both + # the .tar.gz and the .tar.bz2 can download the .tar.bz2 (which is + # smaller), and locally generate an exact duplicate of the + # official .tar.gz file. This metadata is data on the temporary + # uncompressed tarball itself, not any of its contents, so there + # will be no effect on end-users. + os.chdir(get_tempdir(args.base_dir)) + run_script(args.verbose, + '''pax -x ustar -w -f %s %s + bzip2 -9fk %s + gzip -9nf %s''' + % (basename + '.tar', basename, + basename + '.tar', + basename + '.tar')) + os.chdir(cwd) # Move the results to the deploy directory logging.info('Moving artifacts and calculating checksums') for e in extns: - if args.version.pre == 'nightly': - filename = 'subversion-nightly.%s' % e - else: - filename = 'subversion-%s.%s' % (args.version, e) - - shutil.move(filename, get_deploydir(args.base_dir)) - filename = os.path.join(get_deploydir(args.base_dir), filename) + filename = basename + '.' + e + filepath = os.path.join(get_tempdir(args.base_dir), filename) + shutil.move(filepath, get_deploydir(args.base_dir)) + filepath = os.path.join(get_deploydir(args.base_dir), filename) m = hashlib.sha1() - m.update(open(filename, 'r').read()) - open(filename + '.sha1', 'w').write(m.hexdigest()) + m.update(open(filepath, 'r').read()) + open(filepath + '.sha1', 'w').write(m.hexdigest()) m = hashlib.sha512() - m.update(open(filename, 'r').read()) - open(filename + '.sha512', 'w').write(m.hexdigest()) + m.update(open(filepath, 'r').read()) + open(filepath + '.sha512', 'w').write(m.hexdigest()) - shutil.move('svn_version.h.dist', - get_deploydir(args.base_dir) + '/' + 'svn_version.h.dist' - + '-' + str(args.version)) + # Nightlies do not get tagged so do not need the header + if args.version.pre != 'nightly': + shutil.copy(os.path.join(get_workdir(args.base_dir), + 'subversion', 'include', 'svn_version.h'), + os.path.join(get_deploydir(args.base_dir), + 'svn_version.h.dist-%s' % str(args.version))) # And we're done! @@ -710,7 +874,9 @@ def clean_dist(args): versions = set(map(Version, filenames)) minor_lines = set(map(minor, versions)) to_keep = set() - for recent_line in sorted(minor_lines, reverse=True)[:2]: + # Keep 3 minor lines: 1.10.0-alpha3, 1.9.7, 1.8.19. + # TODO: When we release 1.A.0 GA we'll have to manually remove 1.(A-2).* artifacts. + for recent_line in sorted(minor_lines, reverse=True)[:3]: to_keep.add(max( x for x in versions if minor(x) == recent_line @@ -784,7 +950,7 @@ def write_news(args): template.generate(sys.stdout, data) -def get_sha1info(args, replace=False): +def get_sha1info(args): 'Return a list of sha1 info for the release' target = get_target(args) @@ -798,12 +964,7 @@ def get_sha1info(args, replace=False): for s in sha1s: i = info() # strip ".sha1" - fname = os.path.basename(s)[:-5] - if replace: - # replace the version number with the [version] reference - i.filename = Version.regex.sub('[version]', fname) - else: - i.filename = fname + i.filename = os.path.basename(s)[:-5] i.sha1 = open(s, 'r').read() sha1info.append(i) @@ -846,7 +1007,7 @@ def write_announcement(args): def write_downloads(args): 'Output the download section of the website.' - sha1info = get_sha1info(args, replace=True) + sha1info = get_sha1info(args) data = { 'version' : str(args.version), 'fileinfo' : sha1info, @@ -861,6 +1022,7 @@ def write_downloads(args): # Validate the signatures for a release key_start = '-----BEGIN PGP SIGNATURE-----' +key_end = '-----END PGP SIGNATURE-----' PUBLIC_KEY_ALGORITHMS = { # These values are taken from the RFC's registry at: @@ -895,9 +1057,27 @@ def get_siginfo(args, quiet=False): text = open(filename).read() keys = text.split(key_start) + # Check the keys file syntax. We've been bitten in the past + # with syntax errors in the key delimiters that GPG didn't + # catch for us, but the ASF key checker tool did. + if keys[0]: + sys.stderr.write("SYNTAX ERROR: %s does not start with '%s'\n" + % (filename, key_start)) + sys.exit(1) + keys = keys[1:] + if not quiet: - logging.info("Checking %d sig(s) in %s" % (len(keys[1:]), filename)) - for key in keys[1:]: + logging.info("Checking %d sig(s) in %s" % (len(keys), filename)) + + n = 0 + for key in keys: + n += 1 + if not key.rstrip().endswith(key_end): + sys.stderr.write("SYNTAX ERROR: Key %d in %s" + " does not end with '%s'\n" + % (n, filename, key_end)) + sys.exit(1) + fd, fn = tempfile.mkstemp() os.write(fd, key_start + key) os.close(fd) @@ -907,7 +1087,8 @@ def get_siginfo(args, quiet=False): if verified.valid: good_sigs[verified.fingerprint] = True else: - sys.stderr.write("BAD SIGNATURE for %s\n" % filename) + sys.stderr.write("BAD SIGNATURE: Key %d in %s\n" + % (n, filename)) if verified.key_id: sys.stderr.write(" key id: %s\n" % verified.key_id) sys.exit(1) @@ -1038,6 +1219,8 @@ def main(): subparser.add_argument('--branch', help='''The branch to base the release on, relative to ^/subversion/.''') + subparser.add_argument('--patches', + help='''The path to the directory containing patches.''') # Setup the parser for the sign-candidates subcommand subparser = subparsers.add_parser('sign-candidates', @@ -1173,6 +1356,9 @@ def main(): os.environ['PATH'] = os.path.join(get_prefix(args.base_dir), 'bin') + ':' \ + os.environ['PATH'] + # Make timestamps in tarballs independent of local timezone + os.environ['TZ'] = 'UTC' + # finally, run the subcommand, and give it the parsed arguments args.func(args) Modified: subversion/branches/addremove/tools/dist/templates/rc-release-ann.ezt URL: http://svn.apache.org/viewvc/subversion/branches/addremove/tools/dist/templates/rc-release-ann.ezt?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/tools/dist/templates/rc-release-ann.ezt (original) +++ subversion/branches/addremove/tools/dist/templates/rc-release-ann.ezt Tue Aug 22 14:19:36 2017 @@ -31,7 +31,7 @@ Apache Subversion open source version co issues, a complete list of [major-minor-patch]-blocking issues can be found here: - http://subversion.tigris.org/issues/buglist.cgi?component=subversion&issue_status=NEW&issue_status=STARTED&issue_status=REOPENED&target_milestone=[major-minor-patch] + https://issues.apache.org/jira/issues/?jql=project%20%3D%20SVN%20AND%20resolution%20%3D%20Unresolved%20AND%20fixVersion%20%3D%20[major-minor-patch]%20ORDER%20BY%20priority%20DESC%2C%20updated%20DESC A pre-release means the Subversion developers feel that this release is ready for widespread testing by the community. There are known issues Modified: subversion/branches/addremove/tools/dist/templates/stable-news.ezt URL: http://svn.apache.org/viewvc/subversion/branches/addremove/tools/dist/templates/stable-news.ezt?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/tools/dist/templates/stable-news.ezt (original) +++ subversion/branches/addremove/tools/dist/templates/stable-news.ezt Tue Aug 22 14:19:36 2017 @@ -5,14 +5,11 @@ </h3> <p>We are pleased to announce the release of Apache Subversion [version]. -[if-any is_recommended] - This is the most complete Subversion release to date, and we encourage +[if-any is_recommended] This is the most complete Subversion release to date, and we encourage users of Subversion to upgrade as soon as reasonable. -[else] - This is the most complete release of the [major-minor].x line to date, +[else] This is the most complete release of the [major-minor].x line to date, and we encourage all users to upgrade as soon as reasonable. -[end] - Please see the +[end] Please see the <a href="" >release announcement</a> and the <a href="http://svn.apache.org/repos/asf/subversion/tags/[version]/CHANGES" Modified: subversion/branches/addremove/tools/dist/templates/stable-release-ann.ezt URL: http://svn.apache.org/viewvc/subversion/branches/addremove/tools/dist/templates/stable-release-ann.ezt?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/tools/dist/templates/stable-release-ann.ezt (original) +++ subversion/branches/addremove/tools/dist/templates/stable-release-ann.ezt Tue Aug 22 14:19:36 2017 @@ -1,6 +1,6 @@ From: [email protected] To: [email protected], [email protected], [email protected], [email protected] -[if-any security]Cc: [email protected] +[if-any security]Cc: [email protected], [email protected], [email protected] [end][if-any security]Subject: [[]SECURITY][[]ANNOUNCE] Apache Subversion [version] released [else]Subject: [[]ANNOUNCE] Apache Subversion [version] released [end] Modified: subversion/branches/addremove/win-tests.py URL: http://svn.apache.org/viewvc/subversion/branches/addremove/win-tests.py?rev=1805769&r1=1805768&r2=1805769&view=diff ============================================================================== --- subversion/branches/addremove/win-tests.py (original) +++ subversion/branches/addremove/win-tests.py Tue Aug 22 14:19:36 2017 @@ -113,7 +113,7 @@ def _usage_exit(): print(" --config-file : Configuration file for tests") print(" --fsfs-sharding : Specify shard size (for fsfs)") print(" --fsfs-packing : Run 'svnadmin pack' automatically") - print(" --fsfs-compression=VAL : Set compression level to VAL (for fsfs)") + print(" --fsfs-compression=VAL : Set compression type to VAL (for fsfs)") print(" -q, --quiet : Deprecated; this is the default.") print(" Use --set-log-level instead.") @@ -191,7 +191,7 @@ memcached_server = None memcached_dir = None skip_c_tests = None dump_load_cross_check = None -fsfs_compression_level = None +fsfs_compression = None for opt, val in opts: if opt in ('-h', '--help'): @@ -287,7 +287,7 @@ for opt, val in opts: memcached_dir = val run_memcached = 1 elif opt == '--fsfs-compression': - fsfs_compression_level = int(val) + fsfs_compression = val # Calculate the source and test directory names abs_srcdir = os.path.abspath("") @@ -1017,6 +1017,7 @@ create_target_dir(CMDLINE_TEST_SCRIPT_NA # Ensure the tests directory is correctly cased abs_builddir = fix_case(abs_builddir) +failed = None daemon = None memcached = None # Run the tests @@ -1112,7 +1113,7 @@ if not test_javahl and not test_swig: opts.memcached_server = memcached_server opts.skip_c_tests = skip_c_tests opts.dump_load_cross_check = dump_load_cross_check - opts.fsfs_compression_level = fsfs_compression_level + opts.fsfs_compression = fsfs_compression th = run_tests.TestHarness(abs_srcdir, abs_builddir, log_file, fail_log_file, opts) old_cwd = os.getcwd() @@ -1330,6 +1331,10 @@ elif test_swig == 'ruby': print('[Test runner reported failure]') failed = True +elif test_swig: + print('Unknown Swig binding type: ' + str(test_swig)) + failed = True + # Stop service daemon, if any if daemon: del daemon
