You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/05/16 22:32:54 UTC

svn commit: r1339349 [37/37] - in /subversion/branches/fix-rdump-editor: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/client-side/vim/ contrib/server-side/ notes/ notes/api-errat...

Modified: subversion/branches/fix-rdump-editor/tools/dist/release.py
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/tools/dist/release.py?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/tools/dist/release.py (original)
+++ subversion/branches/fix-rdump-editor/tools/dist/release.py Wed May 16 20:32:43 2012
@@ -21,10 +21,10 @@
 
 
 # About this script:
-#   This script is intended to simplify creating Subversion releases, by
-#   automating as much as is possible.  It works well with our Apache
-#   infrastructure, and should make rolling, posting, and announcing
-#   releases dirt simple.
+#   This script is intended to simplify creating Subversion releases for
+#   any of the supported release lines of Subversion.
+#   It works well with our Apache infrastructure, and should make rolling,
+#   posting, and announcing releases dirt simple.
 #
 #   This script may be run on a number of platforms, but it is intended to
 #   be run on people.apache.org.  As such, it may have dependencies (such
@@ -39,6 +39,7 @@ import os
 import re
 import sys
 import glob
+import fnmatch
 import shutil
 import urllib2
 import hashlib
@@ -62,15 +63,32 @@ except ImportError:
     import ezt
 
 
-# Our required / recommended versions
-autoconf_ver = '2.68'
-libtool_ver = '2.4'
-swig_ver = '2.0.4'
+# Our required / recommended release tool versions by release branch
+tool_versions = {
+  'trunk' : {
+            'autoconf' : '2.68',
+            'libtool'  : '2.4',
+            'swig'     : '2.0.4',
+  },
+  '1.7' : {
+            'autoconf' : '2.68',
+            'libtool'  : '2.4',
+            'swig'     : '2.0.4',
+  },
+  '1.6' : {
+            'autoconf' : '2.64',
+            'libtool'  : '1.5.26',
+            'swig'     : '1.3.36',
+  },
+}
 
 # Some constants
 repos = 'http://svn.apache.org/repos/asf/subversion'
-people_host = 'minotaur.apache.org'
-people_dist_dir = '/www/www.apache.org/dist/subversion'
+secure_repos = 'https://svn.apache.org/repos/asf/subversion'
+dist_repos = 'https://dist.apache.org/repos/dist'
+dist_dev_url = dist_repos + '/dev/subversion'
+dist_release_url = dist_repos + '/release/subversion'
+extns = ['zip', 'tar.gz', 'tar.bz2']
 
 
 #----------------------------------------------------------------------
@@ -88,6 +106,7 @@ class Version(object):
             self.pre = 'nightly'
             self.pre_num = None
             self.base = 'nightly'
+            self.branch = 'trunk'
             return
 
         match = self.regex.search(ver_str)
@@ -107,6 +126,7 @@ class Version(object):
             self.pre_num = None
 
         self.base = '%d.%d.%d' % (self.major, self.minor, self.patch)
+        self.branch = '%d.%d' % (self.major, self.minor)
 
     def is_prerelease(self):
         return self.pre != None
@@ -189,10 +209,6 @@ def download_file(url, target):
     target_file = open(target, 'w')
     target_file.write(response.read())
 
-def assert_people():
-    if os.uname()[1] != people_host:
-        raise RuntimeError('Not running on expected host "%s"' % people_host)
-
 #----------------------------------------------------------------------
 # Cleaning up the environment
 
@@ -255,10 +271,11 @@ class RollDep(object):
 
 
 class AutoconfDep(RollDep):
-    def __init__(self, base_dir, use_existing, verbose):
+    def __init__(self, base_dir, use_existing, verbose, autoconf_ver):
         RollDep.__init__(self, base_dir, use_existing, verbose)
         self.label = 'autoconf'
         self._filebase = 'autoconf-' + autoconf_ver
+        self._autoconf_ver =  autoconf_ver
         self._url = 'http://ftp.gnu.org/gnu/autoconf/%s.tar.gz' % self._filebase
 
     def have_usable(self):
@@ -266,7 +283,7 @@ class AutoconfDep(RollDep):
         if not output: return False
 
         version = output[0].split()[-1:][0]
-        return version == autoconf_ver
+        return version == self._autoconf_ver
 
     def use_system(self):
         if not self._use_existing: return False
@@ -274,18 +291,18 @@ class AutoconfDep(RollDep):
 
 
 class LibtoolDep(RollDep):
-    def __init__(self, base_dir, use_existing, verbose):
+    def __init__(self, base_dir, use_existing, verbose, libtool_ver):
         RollDep.__init__(self, base_dir, use_existing, verbose)
         self.label = 'libtool'
         self._filebase = 'libtool-' + libtool_ver
+        self._libtool_ver = libtool_ver
         self._url = 'http://ftp.gnu.org/gnu/libtool/%s.tar.gz' % self._filebase
 
     def have_usable(self):
         output = self._test_version(['libtool', '--version'])
         if not output: return False
 
-        version = output[0].split()[-1:][0]
-        return version == libtool_ver
+        return self._libtool_ver in output[0]
 
     def use_system(self):
         # We unconditionally return False here, to avoid using a borked
@@ -294,10 +311,11 @@ class LibtoolDep(RollDep):
 
 
 class SwigDep(RollDep):
-    def __init__(self, base_dir, use_existing, verbose, sf_mirror):
+    def __init__(self, base_dir, use_existing, verbose, swig_ver, sf_mirror):
         RollDep.__init__(self, base_dir, use_existing, verbose)
         self.label = 'swig'
         self._filebase = 'swig-' + swig_ver
+        self._swig_ver = swig_ver
         self._url = 'http://sourceforge.net/projects/swig/files/swig/%(swig)s/%(swig)s.tar.gz/download?use_mirror=%(sf_mirror)s' % \
             { 'swig' : self._filebase,
               'sf_mirror' : sf_mirror }
@@ -308,7 +326,7 @@ class SwigDep(RollDep):
         if not output: return False
 
         version = output[1].split()[-1:][0]
-        return version == swig_ver
+        return version == self._swig_ver
 
     def use_system(self):
         if not self._use_existing: return False
@@ -326,9 +344,12 @@ def build_env(args):
         if not args.use_existing:
             raise
 
-    autoconf = AutoconfDep(args.base_dir, args.use_existing, args.verbose)
-    libtool = LibtoolDep(args.base_dir, args.use_existing, args.verbose)
+    autoconf = AutoconfDep(args.base_dir, args.use_existing, args.verbose,
+                           tool_versions[args.version.branch]['autoconf'])
+    libtool = LibtoolDep(args.base_dir, args.use_existing, args.verbose,
+                         tool_versions[args.version.branch]['libtool'])
     swig = SwigDep(args.base_dir, args.use_existing, args.verbose,
+                   tool_versions[args.version.branch]['swig'],
                    args.sf_mirror)
 
     # iterate over our rolling deps, and build them if needed
@@ -342,54 +363,37 @@ def build_env(args):
 #----------------------------------------------------------------------
 # Create release artifacts
 
-def fetch_changes(repos, branch, revision):
-    changes_peg_url = '%s/%s/CHANGES@%d' % (repos, branch, revision)
-    proc = subprocess.Popen(['svn', 'cat', changes_peg_url],
-                            stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-    (stdout, stderr) = proc.communicate()
-    proc.wait()
-    return stdout.split('\n')
-
-
 def compare_changes(repos, branch, revision):
-    # Compare trunk's version of CHANGES with that of the branch,
-    # ignoring any lines in trunk's version precede what *should*
-    # match the contents of the branch's version.  (This allows us to
-    # continue adding new stuff at the top of trunk's CHANGES that
-    # might relate to the *next* major release line.)
-    branch_CHANGES = fetch_changes(repos, branch, revision)
-    trunk_CHANGES = fetch_changes(repos, 'trunk', revision)
-    try:
-        first_matching_line = trunk_CHANGES.index(branch_CHANGES[0])
-    except ValueError:
-        raise RuntimeError('CHANGES not synced between trunk and branch')
-
-    trunk_CHANGES = trunk_CHANGES[first_matching_line:]
-    saw_diff = False
-    import difflib
-    for diff_line in difflib.unified_diff(trunk_CHANGES, branch_CHANGES):
-        saw_diff = True
-        logging.debug('%s', diff_line)
-    if saw_diff:
-        raise RuntimeError('CHANGES not synced between trunk and branch')
-
+    mergeinfo_cmd = ['svn', 'mergeinfo', '--show-revs=eligible',
+                     repos + '/trunk/CHANGES',
+                     repos + '/' + branch + '/' + 'CHANGES']
+    proc = subprocess.Popen(mergeinfo_cmd, stdout=subprocess.PIPE,
+                            stderr=subprocess.PIPE)
+    (stdout, stderr) = proc.communicate()
+    rc = proc.wait()
+    if stderr:
+      raise RuntimeError('svn mergeinfo failed: %s' % stderr)
+    if stdout:
+      raise RuntimeError('CHANGES has unmerged revisions: %s' % stdout)
 
 def roll_tarballs(args):
     'Create the release artifacts.'
-    extns = ['zip', 'tar.gz', 'tar.bz2']
 
     if args.branch:
         branch = args.branch
     else:
-        branch = 'branches/' + args.version.base[:-1] + 'x'
+        branch = 'branches/%d.%d.x' % (args.version.major, args.version.minor)
 
     logging.info('Rolling release %s from branch %s@%d' % (args.version,
                                                            branch, args.revnum))
 
     # Ensure we've got the appropriate rolling dependencies available
-    autoconf = AutoconfDep(args.base_dir, False, args.verbose)
-    libtool = LibtoolDep(args.base_dir, False, args.verbose)
-    swig = SwigDep(args.base_dir, False, args.verbose, None)
+    autoconf = AutoconfDep(args.base_dir, False, args.verbose,
+                         tool_versions[args.version.branch]['autoconf'])
+    libtool = LibtoolDep(args.base_dir, False, args.verbose,
+                         tool_versions[args.version.branch]['libtool'])
+    swig = SwigDep(args.base_dir, False, args.verbose,
+                   tool_versions[args.version.branch]['swig'], None)
 
     for dep in [autoconf, libtool, swig]:
         if not dep.have_usable():
@@ -413,14 +417,15 @@ def roll_tarballs(args):
             extra_args = '-nightly'
         else:
             extra_args = '-%s %d' % (args.version.pre, args.version.pre_num)
-    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) )
+    # Build Unix last to leave Unix-style svn_version.h for tagging
     logging.info('Buildling 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) )
 
     # Move the results to the deploy directory
     logging.info('Moving artifacts and calculating checksums')
@@ -440,44 +445,80 @@ def roll_tarballs(args):
 
     # And we're done!
 
-
 #----------------------------------------------------------------------
-# Post the candidate release artifacts
+# Sign the candidate release artifacts
+
+def sign_candidates(args):
+    'Sign candidate artifacts in the dist development directory.'
+
+    def sign_file(filename):
+        asc_file = open(filename + '.asc', 'a')
+        logging.info("Signing %s" % filename)
+        proc = subprocess.Popen(['gpg', '-ba', '-o', '-', filename],
+                              stdout=asc_file)
+        proc.wait()
+        asc_file.close()
 
-def post_candidates(args):
-    'Post the generated tarballs to web-accessible directory.'
     if args.target:
         target = args.target
     else:
-        target = os.path.join(os.getenv('HOME'), 'public_html', 'svn',
-                              str(args.version))
+        target = get_deploydir(args.base_dir)
 
-    logging.info('Moving tarballs to %s' % target)
-    if os.path.exists(target):
-        shutil.rmtree(target)
-    shutil.copytree(get_deploydir(args.base_dir), target)
+    for e in extns:
+        filename = os.path.join(target, 'subversion-%s.%s' % (args.version, e))
+        sign_file(filename)
+        if args.version.major >= 1 and args.version.minor <= 6:
+            filename = os.path.join(target,
+                                   'subversion-deps-%s.%s' % (args.version, e))
+            sign_file(filename)
 
-    data = { 'version'      : str(args.version),
-             'revnum'       : args.revnum,
-           }
 
-    # Choose the right template text
-    if args.version.is_prerelease():
-        if args.version.pre == 'nightly':
-            template_filename = 'nightly-candidates.ezt'
-        else:
-            template_filename = 'rc-candidates.ezt'
+#----------------------------------------------------------------------
+# Post the candidate release artifacts
+
+def post_candidates(args):
+    'Post candidate artifacts to the dist development directory.'
+
+    logging.info('Importing tarballs to %s' % dist_dev_url)
+    svn_cmd = ['svn', 'import', '-m',
+               'Add %s candidate release artifacts' % args.version.base,
+               '--auto-props', '--config-option',
+               'config:auto-props:*.asc=svn:eol-style=native;svn:mime-type=text/plain',
+               get_deploydir(args.base_dir), dist_dev_url]
+    if (args.username):
+        svn_cmd += ['--username', args.username]
+    proc = subprocess.Popen(svn_cmd)
+    (stdout, stderr) = proc.communicate()
+    proc.wait()
+
+#----------------------------------------------------------------------
+# Create tag
+
+def create_tag(args):
+    'Create tag in the repository'
+
+    logging.info('Creating tag for %s' % str(args.version))
+
+    if args.branch:
+        branch = secure_repos + '/' + args.branch
     else:
-        template_filename = 'stable-candidates.ezt'
+        branch = secure_repos + '/branches/%d.%d.x' % (args.version.major,
+                                                       args.version.minor)
 
-    template = ezt.Template()
-    template.parse(get_tmplfile(template_filename).read())
-    template.generate(open(os.path.join(target, 'HEADER.html'), 'w'), data)
+    tag = secure_repos + '/tags/' + str(args.version)
 
-    template = ezt.Template()
-    template.parse(get_tmplfile('htaccess.ezt').read())
-    template.generate(open(os.path.join(target, '.htaccess'), 'w'), data)
+    svnmucc_cmd = ['svnmucc', '-m',
+                   'Tagging release ' + str(args.version)]
+    if (args.username):
+        svnmucc_cmd += ['--username', args.username]
+    svnmucc_cmd += ['cp', str(args.revnum), branch, tag]
+    svnmucc_cmd += ['put', os.path.join(get_deploydir(args.base_dir),
+                                        'svn_version.h.dist'),
+                    tag + '/subversion/include/svn_version.h']
 
+    # don't redirect stdout/stderr since svnmucc might ask for a password
+    proc = subprocess.Popen(svnmucc_cmd)
+    proc.wait()
 
 #----------------------------------------------------------------------
 # Clean dist
@@ -485,28 +526,43 @@ def post_candidates(args):
 def clean_dist(args):
     'Clean the distribution directory of all but the most recent artifacts.'
 
-    if not args.dist_dir:
-        assert_people()
-        args.dist_dir = people_dist_dir
+    proc = subprocess.Popen(['svn', 'list', dist_release_url],
+                            stdout=subprocess.PIPE,
+                            stderr=subprocess.PIPE)
+    (stdout, stderr) = proc.communicate()
+    proc.wait()
+    if stderr:
+      raise RuntimeError(stderr)
 
-    logging.info('Cleaning dist dir \'%s\'' % args.dist_dir)
+    filenames = stdout.split('\n')
+    tar_gz_archives = []
+    for entry in filenames:
+      if fnmatch.fnmatch(entry, 'subversion-*.tar.gz'):
+        tar_gz_archives.append(entry)
 
-    filenames = glob.glob(os.path.join(args.dist_dir, 'subversion-*.tar.gz'))
     versions = []
-    for filename in filenames:
-        versions.append(Version(filename))
+    for archive in tar_gz_archives:
+        versions.append(Version(archive))
 
+    svnmucc_cmd = ['svnmucc', '-m', 'Remove old Subversion releases.\n' +
+                   'They are still available at ' +
+                   'http://archive.apache.org/dist/subversion/']
+    if (args.username):
+        svnmucc_cmd += ['--username', args.username]
     for k, g in itertools.groupby(sorted(versions),
                                   lambda x: (x.major, x.minor)):
         releases = list(g)
         logging.info("Saving release '%s'", releases[-1])
 
         for r in releases[:-1]:
-            for filename in glob.glob(os.path.join(args.dist_dir,
-                                                   'subversion-%s.*' % r)):
+            for filename in filenames:
+              if fnmatch.fnmatch(filename, 'subversion-%s.*' % r):
                 logging.info("Removing '%s'" % filename)
-                os.remove(filename)
+                svnmucc_cmd += ['rm', dist_release_url + '/' + filename]
 
+    # don't redirect stdout/stderr since svnmucc might ask for a password
+    proc = subprocess.Popen(svnmucc_cmd)
+    proc.wait()
 
 #----------------------------------------------------------------------
 # Move to dist
@@ -514,23 +570,31 @@ def clean_dist(args):
 def move_to_dist(args):
     'Move candidate artifacts to the distribution directory.'
 
-    if not args.dist_dir:
-        assert_people()
-        args.dist_dir = people_dist_dir
-
-    if args.target:
-        target = args.target
-    else:
-        target = os.path.join(os.getenv('HOME'), 'public_html', 'svn',
-                              str(args.version))
+    proc = subprocess.Popen(['svn', 'list', dist_dev_url],
+                            stdout=subprocess.PIPE,
+                            stderr=subprocess.PIPE)
+    (stdout, stderr) = proc.communicate()
+    proc.wait()
+    if stderr:
+      raise RuntimeError(stderr)
 
-    logging.info('Moving %s to dist dir \'%s\'' % (str(args.version),
-                                                   args.dist_dir) )
-    filenames = glob.glob(os.path.join(target,
-                                       'subversion-%s.*' % str(args.version)))
+    filenames = []
+    for entry in stdout.split('\n'):
+      if fnmatch.fnmatch(entry, 'subversion-%s.*' % str(args.version)):
+        filenames.append(entry)
+    svnmucc_cmd = ['svnmucc', '-m',
+                   'Publish Subversion-%s.' % str(args.version)]
+    if (args.username):
+        svnmucc_cmd += ['--username', args.username]
+    svnmucc_cmd += ['rm', dist_dev_url + '/' + 'svn_version.h.dist']
     for filename in filenames:
-        shutil.copy(filename, args.dist_dir)
+        svnmucc_cmd += ['mv', dist_dev_url + '/' + filename,
+                        dist_release_url + '/' + filename]
 
+    # don't redirect stdout/stderr since svnmucc might ask for a password
+    logging.info('Moving release artifacts to %s' % dist_release_url)
+    proc = subprocess.Popen(svnmucc_cmd)
+    proc.wait()
 
 #----------------------------------------------------------------------
 # Write announcements
@@ -539,7 +603,7 @@ def write_news(args):
     'Write text for the Subversion website.'
     data = { 'date' : datetime.date.today().strftime('%Y%m%d'),
              'date_pres' : datetime.date.today().strftime('%Y-%m-%d'),
-             'major-minor' : args.version.base[:3],
+             'major-minor' : '%d.%d' % (args.version.major, args.version.minor),
              'version' : str(args.version),
              'version_base' : args.version.base,
            }
@@ -584,7 +648,8 @@ def write_announcement(args):
     data = { 'version'              : str(args.version),
              'sha1info'             : sha1info,
              'siginfo'              : open('getsigs-output', 'r').read(),
-             'major-minor'          : args.version.base[:3],
+             'major-minor'          : '%d.%d' % (args.version.major,
+                                                 args.version.minor),
              'major-minor-patch'    : args.version.base,
            }
 
@@ -629,16 +694,16 @@ def check_sigs(args):
     if args.target:
         target = args.target
     else:
-        target = os.path.join(os.getenv('HOME'), 'public_html', 'svn',
-                              str(args.version))
+        target = get_deploydir(args.base_dir)
 
     good_sigs = {}
 
-    glob_pattern = os.path.join(target, 'subversion-%s*.asc' % args.version)
+    glob_pattern = os.path.join(target, 'subversion*-%s*.asc' % args.version)
     for filename in glob.glob(glob_pattern):
         text = open(filename).read()
         keys = text.split(key_start)
 
+        logging.info("Checking %d sig(s) in %s" % (len(keys[1:]), filename))
         for key in keys[1:]:
             fd, fn = tempfile.mkstemp()
             os.write(fd, key_start + key)
@@ -650,6 +715,8 @@ def check_sigs(args):
                 good_sigs[verified.key_id[-8:]] = True
             else:
                 sys.stderr.write("BAD SIGNATURE for %s\n" % filename)
+                if verified.key_id:
+                    sys.stderr.write("  key id: %s\n" % verified.key_id)
                 sys.exit(1)
 
     for id in good_sigs.keys():
@@ -694,6 +761,8 @@ def main():
                     help='''Download release prerequisistes, including autoconf,
                             libtool, and swig.''')
     subparser.set_defaults(func=build_env)
+    subparser.add_argument('version', type=Version,
+                    help='''The release label, such as '1.7.0-alpha1'.''')
     subparser.add_argument('--sf-mirror', default='softlayer',
                     help='''The mirror to use for downloading files from
                             SourceForge.  If in the EU, you may want to use
@@ -713,43 +782,59 @@ def main():
     subparser.add_argument('--branch',
                     help='''The branch to base the release on.''')
 
+    # Setup the parser for the sign-candidates subcommand
+    subparser = subparsers.add_parser('sign-candidates',
+                    help='''Sign the release artifacts.''')
+    subparser.set_defaults(func=sign_candidates)
+    subparser.add_argument('version', type=Version,
+                    help='''The release label, such as '1.7.0-alpha1'.''')
+    subparser.add_argument('--target',
+                    help='''The full path to the directory containing
+                            release artifacts.''')
+
     # Setup the parser for the post-candidates subcommand
     subparser = subparsers.add_parser('post-candidates',
-                    help='''Build the website to host the candidate tarballs.
-                            The default location is somewhere in ~/public_html.
-                            ''')
+                    help='''Commit candidates to the release development area
+                            of the dist.apache.org repository.''')
     subparser.set_defaults(func=post_candidates)
     subparser.add_argument('version', type=Version,
                     help='''The release label, such as '1.7.0-alpha1'.''')
+    subparser.add_argument('--username',
+                    help='''Username for ''' + dist_repos + '''.''')
+
+    # Setup the parser for the create-tag subcommand
+    subparser = subparsers.add_parser('create-tag',
+                    help='''Create the release tag.''')
+    subparser.set_defaults(func=create_tag)
+    subparser.add_argument('version', type=Version,
+                    help='''The release label, such as '1.7.0-alpha1'.''')
     subparser.add_argument('revnum', type=int,
                     help='''The revision number to base the release on.''')
-    subparser.add_argument('--target',
-                    help='''The full path to the destination.''')
+    subparser.add_argument('--branch',
+                    help='''The branch to base the release on.''')
+    subparser.add_argument('--username',
+                    help='''Username for ''' + secure_repos + '''.''')
 
     # The clean-dist subcommand
     subparser = subparsers.add_parser('clean-dist',
                     help='''Clean the distribution directory (and mirrors) of
-                            all but the most recent MAJOR.MINOR release.  If no
-                            dist-dir is given, this command will assume it is
-                            running on people.apache.org.''')
+                            all but the most recent MAJOR.MINOR release.''')
     subparser.set_defaults(func=clean_dist)
     subparser.add_argument('--dist-dir',
                     help='''The directory to clean.''')
+    subparser.add_argument('--username',
+                    help='''Username for ''' + dist_repos + '''.''')
 
     # The move-to-dist subcommand
     subparser = subparsers.add_parser('move-to-dist',
                     help='''Move candiates and signatures from the temporary
-                            post location to the permanent distribution
-                            directory.  If no dist-dir is given, this command
-                            will assume it is running on people.apache.org.''')
+                            release dev location to the permanent distribution
+                            directory.''')
     subparser.set_defaults(func=move_to_dist)
     subparser.add_argument('version', type=Version,
                     help='''The release label, such as '1.7.0-alpha1'.''')
-    subparser.add_argument('--dist-dir',
-                    help='''The directory to clean.''')
-    subparser.add_argument('--target',
-                    help='''The full path to the destination used in
-                            'post-candiates'..''')
+    subparser.add_argument('--username',
+                    help='''Username for ''' + dist_repos + '''.''')
 
     # The write-news subcommand
     subparser = subparsers.add_parser('write-news',
@@ -781,8 +866,8 @@ def main():
     subparser.add_argument('version', type=Version,
                     help='''The release label, such as '1.7.0-alpha1'.''')
     subparser.add_argument('--target',
-                    help='''The full path to the destination used in
-                            'post-candiates'..''')
+                    help='''The full path to the directory containing
+                            release artifacts.''')
 
     # A meta-target
     subparser = subparsers.add_parser('clean',

Modified: subversion/branches/fix-rdump-editor/tools/server-side/mod_dontdothat/mod_dontdothat.c
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/tools/server-side/mod_dontdothat/mod_dontdothat.c?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/tools/server-side/mod_dontdothat/mod_dontdothat.c (original)
+++ subversion/branches/fix-rdump-editor/tools/server-side/mod_dontdothat/mod_dontdothat.c Wed May 16 20:32:43 2012
@@ -271,7 +271,7 @@ dontdothat_filter(ap_filter_t *f,
             return rv;
         }
 
-      if (! XML_Parse(ctx->xmlp, str, len, last))
+      if (! XML_Parse(ctx->xmlp, str, (int)len, last))
         {
           /* let_it_go so we clean up our parser, no_soup_for_you so that we
            * bail out before bothering to parse this stuff a second time. */

Modified: subversion/branches/fix-rdump-editor/tools/server-side/svn-rep-sharing-stats.c
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/tools/server-side/svn-rep-sharing-stats.c?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/tools/server-side/svn-rep-sharing-stats.c (original)
+++ subversion/branches/fix-rdump-editor/tools/server-side/svn-rep-sharing-stats.c Wed May 16 20:32:43 2012
@@ -421,7 +421,6 @@ int
 main(int argc, const char *argv[])
 {
   const char *repos_path;
-  apr_allocator_t *allocator;
   apr_pool_t *pool;
   svn_boolean_t prop = FALSE, data = FALSE;
   svn_boolean_t quiet = FALSE;
@@ -446,13 +445,7 @@ main(int argc, const char *argv[])
   /* Create our top-level pool.  Use a separate mutexless allocator,
    * given this application is single threaded.
    */
-  if (apr_allocator_create(&allocator))
-    return EXIT_FAILURE;
-
-  apr_allocator_max_free_set(allocator, SVN_ALLOCATOR_RECOMMENDED_MAX_FREE);
-
-  pool = svn_pool_create_ex(NULL, allocator);
-  apr_allocator_owner_set(allocator, pool);
+  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
 
   /* Check library versions */
   err = check_lib_versions();

Modified: subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/example.conf
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/example.conf?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/example.conf (original)
+++ subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/example.conf Wed May 16 20:32:43 2012
@@ -2,115 +2,16 @@
 
 [DEFAULT]
 svnbin: /usr/local/bin/svn
-streams: http://svn-master.apache.org:2069/commits/xml
-         http://dist.apache.org:2069/commits/xml
+streams: http://svn.example.org:2069/commits/xml
 
-ASF: http://svn-master.apache.org/repos/asf
-INFRA: https://svn-master.apache.org/repos/infra
-CMS: %(INFRA)s/websites/production
-DIST: https://dist.apache.org/repos/dist
+## The values below are used by ConfigParser's interpolation syntax.
+## See http://docs.python.org/library/configparser
+SOME_REPOS: svn://svn.example.org/repos/chaos
 
 [env]
-HOME: /home/svnwc
+HOME: /home/svn
 LANG: en_US.UTF-8
 
 [track]
-/x1/www/apr.apache.org: %(ASF)s/apr/site/trunk/docs
-/x1/www/apr.apache.org/dev/dist: %(DIST)s/dev/apr
-/x1/www/www.apache.org/dist/apr: %(DIST)s/release/apr
-/x1/www/www.apache.org/dist/poi: %(DIST)s/release/poi
-/x1/www/www.apache.org/dist/pivot: %(DIST)s/release/pivot
-/x1/www/www.apache.org/dist/httpd: %(DIST)s/release/httpd
-/x1/www/www.apache.org/dist/incubator/airavata: %(DIST)s/release/incubator/airavata
-/x1/www/www.apache.org/: %(CMS)s/www
-/x1/www/httpd.apache.org/: %(ASF)s/httpd/site/trunk/docs
-/x1/www/httpd.apache.org/docs/2.0: %(ASF)s/httpd/httpd/branches/2.0.x/docs/manual
-/x1/www/httpd.apache.org/docs/2.2: %(ASF)s/httpd/httpd/branches/2.2.x/docs/manual
-/x1/www/httpd.apache.org/docs/1.3: %(ASF)s/httpd/httpd/branches/1.3.x/htdocs/manual
-/x1/www/httpd.apache.org/docs/2.4: %(ASF)s/httpd/httpd/branches/2.4.x/docs/manual
-/x1/www/httpd.apache.org/docs/trunk: %(ASF)s/httpd/httpd/trunk/docs/manual
-/x1/www/httpd.apache.org/mod_fcgid/mod: %(ASF)s/httpd/mod_fcgid/trunk/docs/manual/mod
-/x1/www/httpd.apache.org/mod_fcgid/style: %(ASF)s/httpd/httpd/trunk/docs/manual/style
-/x1/www/httpd.apache.org/mod_fcgid/images: %(ASF)s/httpd/httpd/trunk/docs/manual/images
-/x1/www/httpd.apache.org/dev/dist: %(DIST)s/dev/httpd
-/x1/www/httpd.apache.org/mod_ftp/mod: %(ASF)s/httpd/mod_ftp/trunk/docs/manual/mod
-/x1/www/httpd.apache.org/mod_ftp/style: %(ASF)s/httpd/httpd/trunk/docs/manual/style
-/x1/www/httpd.apache.org/mod_ftp/images: %(ASF)s/httpd/httpd/trunk/docs/manual/images
-/x1/www/httpd.apache.org/mod_ftp/ftp: %(ASF)s/httpd/mod_ftp/trunk/docs/manual/ftp
-/x1/www/libcloud.apache.org: %(CMS)s/libcloud
-/x1/www/river.apache.org: %(CMS)s/river/content
-/x1/www/incubator.apache.org/stanbol: %(CMS)s/stanbol/content/stanbol
-/x1/www/incubator.apache.org/kitty: %(CMS)s/kitty/content/kitty
-/x1/www/www.apache.org/dist/trafficserver: %(DIST)s/release/trafficserver
-/x1/staging/harmony.apache.org/eclipse/update: %(ASF)s/harmony/enhanced/tools/trunk/eclipse/org.apache.harmony.eclipse.site
-/x1/staging/harmony.apache.org/externals/security: %(ASF)s/harmony/enhanced/java/trunk/classlib/doc/security
-/x1/staging/harmony.apache.org/externals/regex: %(ASF)s/harmony/enhanced/java/trunk/classlib/doc/regex
-/x1/staging/harmony.apache.org: %(ASF)s/harmony/standard/site/trunk/docs
-/x1/www/harmony.apache.org/eclipse/update: %(ASF)s/harmony/enhanced/tools/trunk/eclipse/org.apache.harmony.eclipse.site
-/x1/www/harmony.apache.org/externals/security: %(ASF)s/harmony/enhanced/java/trunk/classlib/doc/security
-/x1/www/harmony.apache.org/externals/regex: %(ASF)s/harmony/enhanced/java/trunk/classlib/doc/regex
-/x1/www/harmony.apache.org: %(ASF)s/harmony/standard/site/branches/live/docs
-/x1/www/subversion.apache.org/: %(ASF)s/subversion/site
-/x1/www/trafficserver.apache.org/: %(CMS)s/trafficserver
-/x1/www/qpid.apache.org: %(ASF)s/qpid/site/docs
-/x1/www/pdfbox.apache.org: %(ASF)s/pdfbox/site/publish
-/x1/www/cassandra.apache.org: %(ASF)s/cassandra/site/publish
-/x1/www/community.apache.org: %(CMS)s/community
-/x1/www/nutch.apache.org: %(ASF)s/nutch/site/publish
-/x1/www/wicket.apache.org: %(ASF)s/wicket/common/site/trunk/_site
-/x1/www/wicket.apache.org/apidocs: %(ASF)s/wicket/common/site/apidocs
-/x1/www/incubator.apache.org/callback: %(CMS)s/callback/content/callback
-/x1/www/incubator.apache.org/zetacomponents: %(ASF)s/incubator/zetacomponents/website/htdocs
-/x1/www/incubator.apache.org/flex: %(CMS)s/flex/content/flex
-/x1/www/incubator.apache.org/jena: %(CMS)s/jena/content/jena
-/x1/www/incubator.apache.org/celix: %(CMS)s/celix/content/celix
-/x1/www/incubator.apache.org/lucene.net: %(CMS)s/lucene.net/content/lucene.net
-/x1/www/incubator.apache.org/easyant: %(ASF)s/incubator/easyant/site/production
-/x1/www/incubator.apache.org/etch: %(CMS)s/etch/content/etch
-/x1/www/incubator.apache.org/rave: %(CMS)s/rave/content/rave
-/x1/www/incubator.apache.org/wave: %(CMS)s/wave/content/wave
-/x1/www/incubator.apache.org/lucy: %(CMS)s/lucy/content/lucy
-/x1/www/incubator.apache.org/openmeetings: %(ASF)s/incubator/openmeetings/trunk/singlewebapp/docs
-/x1/www/incubator.apache.org/openofficeorg: %(CMS)s/openofficeorg/content/openofficeorg
-/x1/www/incubator.apache.org/odftoolkit: %(CMS)s/odftoolkit/content/odftoolkit
-/x1/www/incubator.apache.org/airavata: %(CMS)s/airavata/content/airavata
-/x1/www/incubator.apache.org/wookie: %(CMS)s/wookie/content/wookie
-/x1/www/incubator.apache.org/accumulo: %(CMS)s/accumulo/content/accumulo
-/x1/www/gora.apache.org: %(ASF)s/gora/site/publish
-/x1/www/incubator.apache.org/devicemap: %(CMS)s/devicemap/content/devicemap
-/x1/www/aries.apache.org: %(CMS)s/aries/content
-/x1/www/tika.apache.org: %(ASF)s/tika/site/publish
-/x1/www/uima.apache.org/pubsub: %(ASF)s/uima/site/trunk/uima-website/docs
-/x1/www/zookeeper.apache.org: %(CMS)s/zookeeper
-/x1/www/chemistry.apache.org: %(CMS)s/chemistry
-/x1/www/ant.apache.org: %(ASF)s/ant/site/ant/production
-/x1/www/ant.apache.org/ivy: %(ASF)s/ant/site/ivy/production
-/x1/www/ant.apache.org/ivy/ivyde: %(ASF)s/ant/site/ivyde/production
-/x1/www/www.apache.org/dist/esme: %(DIST)s/release/esme
-/x1/www/www.apache.org/dist/libcloud: %(DIST)s/release/libcloud
-/x1/www/archive.apachecon.com: %(INFRA)s/apachecon/archive.apachecon.com
-/x1/www/oodt.apache.org: %(ASF)s/oodt/site
-/x1/www/esme.apache.org: %(CMS)s/esme/content
-/x1/www/ooo-site.apache.org: %(CMS)s/ooo-site
-/x1/www/openejb.apache.org: %(CMS)s/openejb
-/x1/www/deltacloud.apache.org: %(ASF)s/deltacloud/trunk/site/output
-/x1/www/ace.apache.org: %(CMS)s/ace
-/x1/www/stdcxx.apache.org/doc: %(ASF)s/stdcxx/trunk/doc
-/x1/www/stdcxx.apache.org: %(ASF)s/stdcxx/site
-/x1/www/www.apache.org/dist/tomcat: %(DIST)s/release/tomcat
-/x1/www/incubator.apache.org/any23: %(ASF)s/incubator/any23/site
-/x1/www/incubator.apache.org/bloodhound: %(ASF)s/incubator/bloodhound/site
-/x1/www/labs.apache.org/: %(CMS)s/labs
-/x1/www/lucene.apache.org: %(CMS)s/lucene
-/x1/www/lucene.apache.org/content/core/old_versioned_docs: %(ASF)s/lucene/old_versioned_docs
-/x1/www/pivot.apache.org: %(ASF)s/pivot/site/trunk/deploy
-/x1/www/www.apache.org/dist/empire-db: %(DIST)s/release/empire-db
-/x1/www/empire-db.apache.org: %(ASF)s/empire-db/site
-/x1/www/www.apache.org/dist/subversion: %(DIST)s/release/subversion
-/x1/www/avro.apache.org: %(ASF)s/avro/site/publish
-/x1/www/incubator.apache.org/cordova: %(ASF)s/incubator/cordova/site/public
-/x1/www/mahout.apache.org: %(ASF)s/mahout/site/new_website
-/x1/www/opennlp.apache.org: %(CMS)s/opennlp
-/x1/www/gump.apache.org: %(ASF)s/gump/site
-/x1/www/incubator.apache.org/syncope: %(ASF)s/incubator/syncope/site
-/x1/staging/www.apache.org: %(ASF)s/infrastructure/site/branches/flamebait/docs
+/usr/local/foo/prod: %(SOME_REPOS)/foo/production
+/usr/local/foo/dev:  %(SOME_REPOS)/foo/trunk

Modified: subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/svntweet.py
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/svntweet.py?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/svntweet.py (original)
+++ subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/svntweet.py Wed May 16 20:32:43 2012
@@ -23,7 +23,7 @@
 #  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",
+#    {"stream": "http://svn.apache.org:2069/commits/xml",
 #     "username": "asfcommits",
 #     "password": "MyLuggageComboIs1234"}
 #

Modified: subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/svnwcsub.py
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/svnwcsub.py?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/svnwcsub.py (original)
+++ subversion/branches/fix-rdump-editor/tools/server-side/svnpubsub/svnwcsub.py Wed May 16 20:32:43 2012
@@ -110,6 +110,8 @@ class WorkingCopy(object):
             logging.info("autopopulate %s from %s" % (self.path, self.url))
             subprocess.check_call([svnbin, 'co', '-q',
                                    '--non-interactive',
+                                   '--config-option',
+                                   'config:miscellany:use-commit-times=on',
                                    '--', self.url, self.path],
                                   env=env)
 
@@ -242,6 +244,8 @@ class BackgroundWorker(threading.Thread)
                 '--non-interactive',
                 '--trust-server-cert',
                 '--ignore-externals',
+                '--config-option',
+                'config:miscellany:use-commit-times=on',
                 wc.path]
         subprocess.check_call(args, env=self.env)
 
@@ -257,6 +261,8 @@ class BackgroundWorker(threading.Thread)
         args = [self.svnbin, 'cleanup',
                 '--non-interactive',
                 '--trust-server-cert',
+                '--config-option',
+                'config:miscellany:use-commit-times=on',
                 wc.path]
         subprocess.check_call(args, env=self.env)
 

Modified: subversion/branches/fix-rdump-editor/win-tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fix-rdump-editor/win-tests.py?rev=1339349&r1=1339348&r2=1339349&view=diff
==============================================================================
--- subversion/branches/fix-rdump-editor/win-tests.py (original)
+++ subversion/branches/fix-rdump-editor/win-tests.py Wed May 16 20:32:43 2012
@@ -65,6 +65,8 @@ def _usage_exit():
   print("  -t, --test=TEST        : Run the TEST test (all is default); use")
   print("                           TEST#n to run a particular test number,")
   print("                           multiples also accepted e.g. '2,4-7'")
+  print("  --log-level=LEVEL      : Set log level to LEVEL (E.g. DEBUG)")
+  print("  --log-to-stdout        : Write log results to stdout")
 
   print("  --svnserve-args=list   : comma-separated list of arguments for")
   print("                           svnserve")
@@ -93,10 +95,9 @@ def _usage_exit():
   print("  -p, --parallel         : run multiple tests in parallel")
   print("  --server-minor-version : the minor version of the server being")
   print("                           tested")
-  print(" --config-file           : Configuration file for tests")
-  print(" --fsfs-sharding         : Specify shard size (for fsfs)")
-  print(" --fsfs-packing          : Run 'svnadmin pack' automatically")
-  print(" --log-to-stdout         : Write log results to stdout")
+  print("  --config-file          : Configuration file for tests")
+  print("  --fsfs-sharding        : Specify shard size (for fsfs)")
+  print("  --fsfs-packing         : Run 'svnadmin pack' automatically")
 
   sys.exit(0)
 
@@ -130,7 +131,7 @@ opts, args = my_getopt(sys.argv[1:], 'hr
                         'disable-http-v2', 'disable-bulk-updates', 'help',
                         'fsfs-packing', 'fsfs-sharding=', 'javahl',
                         'list', 'enable-sasl', 'bin=', 'parallel',
-                        'config-file=', 'server-minor-version=',
+                        'config-file=', 'server-minor-version=', 'log-level=',
                         'log-to-stdout', 'mode-filter=', 'milestone-filter='])
 if len(args) > 1:
   print('Warning: non-option arguments after the first one will be ignored')
@@ -163,6 +164,7 @@ config_file = None
 log_to_stdout = None
 mode_filter=None
 tests_to_run = []
+log_level = None
 
 for opt, val in opts:
   if opt in ('-h', '--help'):
@@ -230,6 +232,8 @@ for opt, val in opts:
     config_file = val
   elif opt == '--log-to-stdout':
     log_to_stdout = 1
+  elif opt == '--log-level':
+    log_level = val
 
 # Calculate the source and test directory names
 abs_srcdir = os.path.abspath("")
@@ -656,8 +660,6 @@ if create_dirs:
     baton = copied_execs
     for dirpath, dirs, files in os.walk('subversion'):
       copy_execs(baton, dirpath, dirs + files)
-    for dirpath, dirs, files in os.walk('tools/client-side/svnmucc'):
-      copy_execs(baton, dirpath, dirs + files)
   except:
     os.chdir(old_cwd)
     raise
@@ -736,7 +738,8 @@ if not test_javahl:
                              cleanup, enable_sasl, parallel, config_file,
                              fsfs_sharding, fsfs_packing,
                              list_tests, svn_bin, mode_filter,
-                             milestone_filter)
+                             milestone_filter,
+                             set_log_level=log_level)
   old_cwd = os.getcwd()
   try:
     os.chdir(abs_builddir)