You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2018/11/28 21:25:35 UTC
svn commit: r1847678 [25/25] - in /subversion/branches/swig-py3: ./ build/
build/ac-macros/ build/generator/ build/generator/templates/ build/win32/
contrib/client-side/ contrib/client-side/svn_load_dirs/
contrib/client-side/svnmerge/ contrib/hook-scri...
Modified: subversion/branches/swig-py3/tools/dist/backport/status.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/dist/backport/status.py?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/dist/backport/status.py (original)
+++ subversion/branches/swig-py3/tools/dist/backport/status.py Wed Nov 28 21:25:32 2018
@@ -194,10 +194,10 @@ class StatusFile:
try:
entry = StatusEntry(para_text, status_file=self)
kind = Kind.nomination
- except ParseException:
+ except ParseException as e:
kind = Kind.unknown
- logger.warning("Failed to parse entry {!r} in {!r}".format(
- para_text, status_fp))
+ logger.warning("Failed to parse entry {!r} in {!r}: {}".format(
+ para_text, status_fp, e))
else:
kind = Kind.preamble
@@ -379,9 +379,11 @@ class StatusEntry:
raise ParseException("Entry found with neither branch nor revisions")
# Parse the logsummary.
- while lines and not self._is_subheader(lines[0]):
+ while True:
self.logsummary.append(lines[0])
lines = lines[1:]
+ if (not lines) or self._is_subheader(lines[0]):
+ break
# Parse votes.
if "Votes:" in lines:
Modified: subversion/branches/swig-py3/tools/dist/backport_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/dist/backport_tests.py?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/dist/backport_tests.py (original)
+++ subversion/branches/swig-py3/tools/dist/backport_tests.py Wed Nov 28 21:25:32 2018
@@ -53,6 +53,12 @@ import sys
@contextlib.contextmanager
def chdir(dir):
+ """This is a context manager that saves the current working directory's
+ pathname. Upon entry it chdir's to the argument DIR; upon exit it chdir's
+ back to the saved pathname.
+
+ The current working directory is restored using os.chdir(), not os.fchdir().
+ """
try:
saved_dir = os.getcwd()
os.chdir(dir)
@@ -660,6 +666,21 @@ def backport_unicode_entry(sbox):
# Run it.
run_backport(sbox)
+#----------------------------------------------------------------------
+@BackportTest('76cee987-25c9-4d6c-ad40-000000000013')
+def backport_logsummary_colon(sbox):
+ "a logsummary that looks like a header"
+
+ # r6: nominate r4
+ approved_entries = [
+ make_entry([4], logsummary="HTTPv2: Add comments."),
+ ]
+ sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
+ sbox.simple_commit(message='Nominate r4')
+
+ # Run it.
+ run_backport(sbox)
+
#----------------------------------------------------------------------
@@ -680,6 +701,7 @@ test_list = [ None,
backport_otherproject_change,
backport_STATUS_mods,
backport_unicode_entry,
+ backport_logsummary_colon,
# When adding a new test, include the test number in the last
# 6 bytes of the UUID, in decimal.
]
Modified: subversion/branches/swig-py3/tools/dist/create-minor-release-branch.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/dist/create-minor-release-branch.py?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/dist/create-minor-release-branch.py (original)
+++ subversion/branches/swig-py3/tools/dist/create-minor-release-branch.py Wed Nov 28 21:25:32 2018
@@ -39,6 +39,9 @@ repos = 'https://svn.apache.org/repos/as
secure_repos = 'https://svn.apache.org/repos/asf/subversion'
buildbot_repos = 'https://svn.apache.org/repos/infra/infrastructure/buildbot/aegis/buildmaster'
+# Parameters
+dry_run = False
+
# Local working copies
base_dir = None # set by main()
@@ -72,15 +75,21 @@ def run(cmd, dry_run=False):
if not dry_run:
stdout = subprocess.check_output(cmd)
print(stdout)
+ else:
+ print(' ## dry-run; not executed')
def run_svn(cmd, dry_run=False):
run(['svn'] + cmd, dry_run)
def svn_commit(cmd):
- run_svn(['commit'] + cmd, dry_run=True)
+ run_svn(['commit'] + cmd, dry_run=dry_run)
+
+def svn_copy_branch(src, dst, message):
+ args = ['copy', src, dst, '-m', message]
+ run_svn(args, dry_run=dry_run)
-def svn_checkout(*args):
- args = ['checkout'] + list(args) + ['--revision={2017-12-01}']
+def svn_checkout(url, wc, *args):
+ args = ['checkout', url, wc] + list(args)
run_svn(args)
#----------------------------------------------------------------------
@@ -100,18 +109,19 @@ def prepend_file(path, text):
open(path, 'w').write(text + original)
#----------------------------------------------------------------------
-def make_release_branch(ver):
- run_svn(['copy', get_trunk_url(), get_branch_url(ver),
- '-m', 'Create the ' + ver.branch + '.x release branch.'],
- dry_run=True)
+def make_release_branch(ver, revnum):
+ svn_copy_branch(get_trunk_url() + '@' + (str(revnum) if revnum else ''),
+ get_branch_url(ver),
+ 'Create the ' + ver.branch + '.x release branch.')
#----------------------------------------------------------------------
-def update_minor_ver_in_trunk(ver):
+def update_minor_ver_in_trunk(ver, revnum):
"""Change the minor version in trunk to the next (future) minor version.
"""
trunk_wc = get_trunk_wc_path()
trunk_url = get_trunk_url()
- svn_checkout(trunk_url, trunk_wc)
+ svn_checkout(trunk_url + '@' + (str(revnum) if revnum else ''),
+ trunk_wc)
prev_ver = Version('1.%d.0' % (ver.minor - 1,))
next_ver = Version('1.%d.0' % (ver.minor + 1,))
@@ -242,14 +252,12 @@ Subversion: start monitoring the %s bran
svn_commit(commit_paths + ['-m', log_msg])
#----------------------------------------------------------------------
-def steps(args):
- ver = Version('1.10.0')
-
- make_release_branch(ver)
- update_minor_ver_in_trunk(ver)
- create_status_file_on_branch(ver)
- update_backport_bot(ver)
- update_buildbot_config(ver)
+def create_release_branch(args):
+ make_release_branch(args.version, args.revnum)
+ update_minor_ver_in_trunk(args.version, args.revnum)
+ create_status_file_on_branch(args.version)
+ update_backport_bot(args.version)
+ update_buildbot_config(args.version)
#----------------------------------------------------------------------
@@ -261,24 +269,37 @@ def main():
# Setup our main parser
parser = argparse.ArgumentParser(
description='Create an Apache Subversion release branch.')
- parser.add_argument('--verbose', action='store_true', default=False,
+ subparsers = parser.add_subparsers(title='subcommands')
+
+ # Setup the parser for the create-release-branch subcommand
+ subparser = subparsers.add_parser('create-release-branch',
+ help='''Create a minor release branch: branch from trunk,
+ update version numbers on trunk, create status
+ file on branch, update backport bot,
+ update buildbot config.''')
+ subparser.set_defaults(func=create_release_branch)
+ subparser.add_argument('version', type=Version,
+ help='''A version number to indicate the branch, such as
+ '1.7.0' (the '.0' is required).''')
+ subparser.add_argument('revnum', type=lambda arg: int(arg.lstrip('r')),
+ nargs='?', default=None,
+ help='''The trunk revision number to base the branch on.
+ Default is HEAD.''')
+ subparser.add_argument('--dry-run', action='store_true', default=False,
+ help='Avoid committing any changes to repositories.')
+ subparser.add_argument('--verbose', action='store_true', default=False,
help='Increase output verbosity')
- parser.add_argument('--base-dir', default=os.getcwd(),
+ subparser.add_argument('--base-dir', default=os.getcwd(),
help='''The directory in which to create needed files and
folders. The default is the current working
directory.''')
- subparsers = parser.add_subparsers(title='subcommands')
-
- # Setup the parser for the build-env subcommand
- subparser = subparsers.add_parser('steps',
- help='''Run the release-branch-creation steps.''')
- subparser.set_defaults(func=steps)
# Parse the arguments
args = parser.parse_args()
- global base_dir
+ global base_dir, dry_run
base_dir = args.base_dir
+ dry_run = args.dry_run
# Set up logging
logger = logging.getLogger()
Modified: subversion/branches/swig-py3/tools/dist/release.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/dist/release.py?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/dist/release.py (original)
+++ subversion/branches/swig-py3/tools/dist/release.py Wed Nov 28 21:25:32 2018
@@ -51,6 +51,9 @@ import operator
import itertools
import subprocess
import argparse # standard in Python 2.7
+import io
+
+import backport.status
# Find ezt, using Subversion's copy, if there isn't one on the system.
try:
@@ -71,16 +74,24 @@ tool_versions = {
'954bd69b391edc12d6a4a51a2dd1476543da5c6bbf05a95b59dc0dd6fd4c2969'],
'libtool' : ['2.4.6',
'e3bd4d5d3d025a36c21dd6af7ea818a2afcd4dfc1ea5a17b39d7854bcd0c06e3'],
- 'swig' : ['3.0.10',
- '2939aae39dec06095462f1b95ce1c958ac80d07b926e48871046d17c0094f44c'],
+ 'swig' : ['3.0.12',
+ '7cf9f447ae7ed1c51722efc45e7f14418d15d7a1e143ac9f09a668999f4fc94d'],
+ },
+ '1.11' : {
+ 'autoconf' : ['2.69',
+ '954bd69b391edc12d6a4a51a2dd1476543da5c6bbf05a95b59dc0dd6fd4c2969'],
+ 'libtool' : ['2.4.6',
+ 'e3bd4d5d3d025a36c21dd6af7ea818a2afcd4dfc1ea5a17b39d7854bcd0c06e3'],
+ 'swig' : ['3.0.12',
+ '7cf9f447ae7ed1c51722efc45e7f14418d15d7a1e143ac9f09a668999f4fc94d'],
},
'1.10' : {
'autoconf' : ['2.69',
'954bd69b391edc12d6a4a51a2dd1476543da5c6bbf05a95b59dc0dd6fd4c2969'],
'libtool' : ['2.4.6',
'e3bd4d5d3d025a36c21dd6af7ea818a2afcd4dfc1ea5a17b39d7854bcd0c06e3'],
- 'swig' : ['3.0.10',
- '2939aae39dec06095462f1b95ce1c958ac80d07b926e48871046d17c0094f44c'],
+ 'swig' : ['3.0.12',
+ '7cf9f447ae7ed1c51722efc45e7f14418d15d7a1e143ac9f09a668999f4fc94d'],
},
'1.9' : {
'autoconf' : ['2.69',
@@ -102,7 +113,9 @@ tool_versions = {
# The version that is our current recommended release
# ### TODO: derive this from svn_version.h; see ../../build/getversion.py
-recommended_release = '1.9'
+recommended_release = '1.11'
+# For clean-dist, a whitelist of artifacts to keep, by version.
+supported_release_lines = frozenset({"1.9", "1.10", "1.11", "1.12"})
# Some constants
repos = 'https://svn.apache.org/repos/asf/subversion'
@@ -712,9 +725,13 @@ def roll_tarballs(args):
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(filepath, 'r').read())
- open(filepath + '.sha1', 'w').write(m.hexdigest())
+ if args.version < Version("1.11.0-alpha1"):
+ # 1.10 and earlier generate *.sha1 files for compatibility reasons.
+ # They are deprecated, however, so we don't publicly link them in
+ # the announcements any more.
+ m = hashlib.sha1()
+ m.update(open(filepath, 'r').read())
+ open(filepath + '.sha1', 'w').write(m.hexdigest())
m = hashlib.sha512()
m.update(open(filepath, 'r').read())
open(filepath + '.sha512', 'w').write(m.hexdigest())
@@ -737,8 +754,12 @@ def sign_candidates(args):
def sign_file(filename):
asc_file = open(filename + '.asc', 'a')
logging.info("Signing %s" % filename)
- proc = subprocess.check_call(['gpg', '-ba', '-o', '-', filename],
- stdout=asc_file)
+ if args.userid:
+ proc = subprocess.check_call(['gpg', '-ba', '-u', args.userid,
+ '-o', '-', filename], stdout=asc_file)
+ else:
+ proc = subprocess.check_call(['gpg', '-ba', '-o', '-', filename],
+ stdout=asc_file)
asc_file.close()
target = get_target(args)
@@ -773,8 +794,9 @@ def post_candidates(args):
#----------------------------------------------------------------------
# Create tag
+# Bump versions on branch
-def create_tag(args):
+def create_tag_only(args):
'Create tag in the repository'
target = get_target(args)
@@ -805,62 +827,87 @@ def create_tag(args):
logging.error("Do you need to pass --branch=trunk?")
raise
- if not args.version.is_prerelease():
- logging.info('Bumping revisions on the branch')
- def replace_in_place(fd, startofline, flat, spare):
- """In file object FD, replace FLAT with SPARE in the first line
- starting with STARTOFLINE."""
-
- fd.seek(0, os.SEEK_SET)
- lines = fd.readlines()
- for i, line in enumerate(lines):
- if line.startswith(startofline):
- lines[i] = line.replace(flat, spare)
- break
- else:
- raise RuntimeError('Definition of %r not found' % startofline)
+def bump_versions_on_branch(args):
+ 'Bump version numbers on branch'
- fd.seek(0, os.SEEK_SET)
- fd.writelines(lines)
- fd.truncate() # for current callers, new value is never shorter.
-
- new_version = Version('%d.%d.%d' %
- (args.version.major, args.version.minor,
- args.version.patch + 1))
-
- def file_object_for(relpath):
- fd = tempfile.NamedTemporaryFile()
- url = branch + '/' + relpath
- fd.url = url
- subprocess.check_call(['svn', 'cat', '%s@%d' % (url, args.revnum)],
- stdout=fd)
- return fd
-
- svn_version_h = file_object_for('subversion/include/svn_version.h')
- replace_in_place(svn_version_h, '#define SVN_VER_PATCH ',
- str(args.version.patch), str(new_version.patch))
-
- STATUS = file_object_for('STATUS')
- replace_in_place(STATUS, 'Status of ',
- str(args.version), str(new_version))
-
- svn_version_h.seek(0, os.SEEK_SET)
- STATUS.seek(0, os.SEEK_SET)
- subprocess.check_call(['svnmucc', '-r', str(args.revnum),
- '-m', 'Post-release housekeeping: '
- 'bump the %s branch to %s.'
- % (branch.split('/')[-1], str(new_version)),
- 'put', svn_version_h.name, svn_version_h.url,
- 'put', STATUS.name, STATUS.url,
- ])
- del svn_version_h
- del STATUS
+ logging.info('Bumping version numbers on the branch')
+
+ if not args.branch:
+ args.branch = 'branches/%d.%d.x' % (args.version.major, args.version.minor)
+
+ branch = secure_repos + '/' + args.branch.rstrip('/')
+
+ def replace_in_place(fd, startofline, flat, spare):
+ """In file object FD, replace FLAT with SPARE in the first line
+ starting with regex STARTOFLINE."""
+
+ pattern = r'^(%s)%s' % (startofline, re.escape(flat))
+ repl = r'\g<1>%s' % (spare,)
+ fd.seek(0, os.SEEK_SET)
+ lines = fd.readlines()
+ for i, line in enumerate(lines):
+ replacement = re.sub(pattern, repl, line)
+ if replacement != line:
+ lines[i] = replacement
+ break
+ else:
+ raise RuntimeError("Could not replace r'%s' with r'%s' in '%s'"
+ % (pattern, repl, fd.url))
+
+ fd.seek(0, os.SEEK_SET)
+ fd.writelines(lines)
+ fd.truncate() # for current callers, new value is never shorter.
+
+ new_version = Version('%d.%d.%d' %
+ (args.version.major, args.version.minor,
+ args.version.patch + 1))
+
+ HEAD = subprocess.check_output(['svn', 'info', '--show-item=revision',
+ '--', branch]).strip()
+ HEAD = int(HEAD)
+ def file_object_for(relpath):
+ fd = tempfile.NamedTemporaryFile()
+ url = branch + '/' + relpath
+ fd.url = url
+ subprocess.check_call(['svn', 'cat', '%s@%d' % (url, HEAD)],
+ stdout=fd)
+ return fd
+
+ svn_version_h = file_object_for('subversion/include/svn_version.h')
+ replace_in_place(svn_version_h, '#define SVN_VER_PATCH *',
+ str(args.version.patch), str(new_version.patch))
+
+ STATUS = file_object_for('STATUS')
+ replace_in_place(STATUS, 'Status of ',
+ str(args.version), str(new_version))
+
+ svn_version_h.seek(0, os.SEEK_SET)
+ STATUS.seek(0, os.SEEK_SET)
+ subprocess.check_call(['svnmucc', '-r', str(HEAD),
+ '-m', 'Post-release housekeeping: '
+ 'bump the %s branch to %s.'
+ % (branch.split('/')[-1], str(new_version)),
+ 'put', svn_version_h.name, svn_version_h.url,
+ 'put', STATUS.name, STATUS.url,
+ ])
+ del svn_version_h
+ del STATUS
+
+def create_tag_and_bump_versions(args):
+ '''Create tag in the repository and, if not a prerelease version,
+ bump version numbers on the branch'''
+
+ create_tag_only(args)
+
+ if not args.version.is_prerelease():
+ bump_versions_on_branch(args)
#----------------------------------------------------------------------
# Clean dist
def clean_dist(args):
- 'Clean the distribution directory of all but the most recent artifacts.'
+ '''Clean the distribution directory of release artifacts of
+ no-longer-supported minor lines.'''
stdout = subprocess.check_output(['svn', 'list', dist_release_url])
@@ -872,15 +919,15 @@ def clean_dist(args):
filenames = stdout.split('\n')
filenames = filter(lambda x: x.startswith('subversion-'), filenames)
versions = set(map(Version, filenames))
- minor_lines = set(map(minor, versions))
to_keep = set()
- # 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(
+ for line_to_keep in [minor(Version(x + ".0")) for x in supported_release_lines]:
+ candidates = list(
x for x in versions
- if minor(x) == recent_line
- ))
+ if minor(x) == line_to_keep
+ )
+ if candidates:
+ to_keep.add(max(candidates))
for i in sorted(to_keep):
logging.info("Saving release '%s'", i)
@@ -938,6 +985,7 @@ def write_news(args):
'version_base' : args.version.base,
'anchor': args.version.get_download_anchor(),
'is_recommended': ezt_bool(args.version.is_recommended()),
+ 'announcement_url': args.announcement_url,
}
if args.version.is_prerelease():
@@ -947,38 +995,53 @@ def write_news(args):
template = ezt.Template()
template.parse(get_tmplfile(template_filename).read())
- template.generate(sys.stdout, data)
+
+ # Insert the output into an existing file if requested, else print it
+ if args.edit_html_file:
+ tmp_name = args.edit_html_file + '.tmp'
+ with open(args.edit_html_file, 'r') as f, open(tmp_name, 'w') as g:
+ inserted = False
+ for line in f:
+ if not inserted and line.startswith('<div class="h3" id="news-'):
+ template.generate(g, data)
+ g.write('\n')
+ inserted = True
+ g.write(line)
+ os.remove(args.edit_html_file)
+ os.rename(tmp_name, args.edit_html_file)
+ else:
+ template.generate(sys.stdout, data)
-def get_sha1info(args):
- 'Return a list of sha1 info for the release'
+def get_fileinfo(args):
+ 'Return a list of file info (filenames) for the release tarballs'
target = get_target(args)
- sha1s = glob.glob(os.path.join(target, 'subversion*-%s*.sha1' % args.version))
+ files = glob.glob(os.path.join(target, 'subversion*-%s*.asc' % args.version))
+ files.sort()
class info(object):
pass
- sha1info = []
- for s in sha1s:
+ fileinfo = []
+ for f in files:
i = info()
- # strip ".sha1"
- i.filename = os.path.basename(s)[:-5]
- i.sha1 = open(s, 'r').read()
- sha1info.append(i)
+ # strip ".asc"
+ i.filename = os.path.basename(f)[:-4]
+ fileinfo.append(i)
- return sha1info
+ return fileinfo
def write_announcement(args):
'Write the release announcement.'
- sha1info = get_sha1info(args)
- siginfo = "\n".join(get_siginfo(args, True)) + "\n"
+ siginfo = get_siginfo(args, True)
+ if not siginfo:
+ raise RuntimeError("No signatures found for %s at %s" % (args.version, args.target))
data = { 'version' : str(args.version),
- 'sha1info' : sha1info,
- 'siginfo' : siginfo,
+ 'siginfo' : "\n".join(siginfo) + "\n",
'major-minor' : args.version.branch,
'major-minor-patch' : args.version.base,
'anchor' : args.version.get_download_anchor(),
@@ -1007,10 +1070,10 @@ def write_announcement(args):
def write_downloads(args):
'Output the download section of the website.'
- sha1info = get_sha1info(args)
+ fileinfo = get_fileinfo(args)
data = { 'version' : str(args.version),
- 'fileinfo' : sha1info,
+ 'fileinfo' : fileinfo,
}
template = ezt.Template(compress_whitespace = False)
@@ -1247,15 +1310,29 @@ def write_changelog(args):
branch = secure_repos + '/' + args.branch
previous = secure_repos + '/' + args.previous
include_unlabeled = args.include_unlabeled
+ separator_line = ('-' * 72) + '\n'
mergeinfo = subprocess.check_output(['svn', 'mergeinfo', '--show-revs',
- 'eligible', '--log', branch, previous]).splitlines()
+ 'eligible', '--log', branch, previous])
+ log_messages_dict = {
+ # This is a dictionary mapping revision numbers to their respective
+ # log messages. The expression in the "key:" part of the dict
+ # comprehension extracts the revision number, as integer, from the
+ # 'svn log' output.
+ int(log_message.splitlines()[0].split()[0][1:]): log_message
+ # The [1:-1] ignores the empty first and last element of the split().
+ for log_message in mergeinfo.split(separator_line)[1:-1]
+ }
+ mergeinfo = mergeinfo.splitlines()
separator_pattern = re.compile('^-{72}$')
revline_pattern = re.compile('^r(\d+) \| [^\|]+ \| [^\|]+ \| \d+ lines?$')
- changes_prefix_pattern = re.compile('^\[(U|D)?:?([^\]]+)?\](.+)$')
- changes_suffix_pattern = re.compile('^(.+)\[(U|D)?:?([^\]]+)?\]$')
-
+ changes_prefix_pattern = re.compile(r'^\[(U|D)?:?([^\]]+)?\](.+)$')
+ changes_suffix_pattern = re.compile(r'^(.+)\[(U|D)?:?([^\]]+)?\]$')
+ # TODO: push this into backport.status as a library function
+ auto_merge_pattern = \
+ re.compile(r'^Merge (r\d+,? |the r\d+ group |the \S+ branch:)')
+
changes_dict = dict() # audience -> (section -> (change -> set(revision)))
revision = -1
got_firstline = False
@@ -1271,8 +1348,27 @@ def write_changelog(args):
# If there's an unlabeled summary from a previous section, and
# include_unlabeled is True, put it into uncategorized_changes.
if include_unlabeled and unlabeled_summary and not changes_ignore:
- add_to_changes_dict(changes_dict, None, None,
- unlabeled_summary, revision)
+ if auto_merge_pattern.match(unlabeled_summary):
+ # 1. Parse revision numbers from the first line
+ merged_revisions = [
+ int(x) for x in
+ re.compile(r'(?<=\br)\d+\b').findall(unlabeled_summary)
+ ]
+ # TODO pass each revnum in MERGED_REVISIONS through this
+ # logic, in order to extract CHANGES_PREFIX_PATTERN
+ # and CHANGES_SUFFIX_PATTERN lines from the trunk log
+ # message.
+
+ # 2. Parse the STATUS entry
+ this_log_message = log_messages_dict[revision]
+ status_paragraph = this_log_message.split('\n\n')[2]
+ logsummary = \
+ backport.status.StatusEntry(status_paragraph).logsummary
+ add_to_changes_dict(changes_dict, None, None,
+ ' '.join(logsummary), revision)
+ else:
+ add_to_changes_dict(changes_dict, None, None,
+ unlabeled_summary, revision)
revision = -1
got_firstline = False
unlabeled_summary = None
@@ -1295,13 +1391,13 @@ def write_changelog(args):
if not got_firstline:
got_firstline = True
- if (not re.search('status|changes|post-release housekeeping|follow-up|^\*',
+ if (not re.search(r'status|changes|post-release housekeeping|follow-up|^\*',
line, re.IGNORECASE)
and not changes_prefix_pattern.match(line)
and not changes_suffix_pattern.match(line)):
unlabeled_summary = line
- if re.search('\[(c:)?(skip|ignore)\]', line, re.IGNORECASE):
+ if re.search(r'\[(c:)?(skip|ignore)\]', line, re.IGNORECASE):
changes_ignore = True
prefix_match = changes_prefix_pattern.match(line)
@@ -1398,6 +1494,10 @@ def main():
subparser.add_argument('--target',
help='''The full path to the directory containing
release artifacts.''')
+ subparser.add_argument('--userid',
+ help='''The (optional) USER-ID specifying the key to be
+ used for signing, such as '110B1C95' (Key-ID). If
+ omitted, uses the default key.''')
# Setup the parser for the post-candidates subcommand
subparser = subparsers.add_parser('post-candidates',
@@ -1414,8 +1514,26 @@ def main():
# 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)
+ help='''Create the release tag and, if not a prerelease
+ version, bump version numbers on the branch.''')
+ subparser.set_defaults(func=create_tag_and_bump_versions)
+ subparser.add_argument('version', type=Version,
+ help='''The release label, such as '1.7.0-alpha1'.''')
+ subparser.add_argument('revnum', type=lambda arg: int(arg.lstrip('r')),
+ help='''The revision number to base the release on.''')
+ subparser.add_argument('--branch',
+ help='''The branch to base the release on,
+ relative to ^/subversion/.''')
+ subparser.add_argument('--username',
+ help='''Username for ''' + secure_repos + '''.''')
+ subparser.add_argument('--target',
+ help='''The full path to the directory containing
+ release artifacts.''')
+
+ # Setup the parser for the bump-versions-on-branch subcommand
+ subparser = subparsers.add_parser('bump-versions-on-branch',
+ help='''Bump version numbers on branch.''')
+ subparser.set_defaults(func=bump_versions_on_branch)
subparser.add_argument('version', type=Version,
help='''The release label, such as '1.7.0-alpha1'.''')
subparser.add_argument('revnum', type=lambda arg: int(arg.lstrip('r')),
@@ -1431,8 +1549,7 @@ def main():
# 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.''')
+ help=clean_dist.__doc__.split('\n\n')[0])
subparser.set_defaults(func=clean_dist)
subparser.add_argument('--dist-dir',
help='''The directory to clean.''')
@@ -1455,6 +1572,11 @@ def main():
help='''Output to stdout template text for use in the news
section of the Subversion website.''')
subparser.set_defaults(func=write_news)
+ subparser.add_argument('--announcement-url',
+ help='''The URL to the archived announcement email.''')
+ subparser.add_argument('--edit-html-file',
+ help='''Insert the text into this file
+ news.html, index.html).''')
subparser.add_argument('version', type=Version,
help='''The release label, such as '1.7.0-alpha1'.''')
Modified: subversion/branches/swig-py3/tools/dist/security/parser.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/dist/security/parser.py?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/dist/security/parser.py (original)
+++ subversion/branches/swig-py3/tools/dist/security/parser.py Wed Nov 28 21:25:32 2018
@@ -50,9 +50,16 @@ class Notification(object):
CULPRIT_SERVER = 'server'
CULPRIT_CLIENT = 'client'
- __CULPRITS = ((CULPRIT_SERVER, CULPRIT_CLIENT,
- (CULPRIT_SERVER, CULPRIT_CLIENT),
- (CULPRIT_CLIENT, CULPRIT_SERVER)))
+ # For compatibility, 'client' and 'server' may be specified either with
+ # or without a tuple.
+ __CULPRITS = (
+ CULPRIT_SERVER,
+ CULPRIT_CLIENT,
+ (CULPRIT_SERVER,)
+ (CULPRIT_CLIENT,)
+ (CULPRIT_SERVER, CULPRIT_CLIENT),
+ (CULPRIT_CLIENT, CULPRIT_SERVER),
+ )
def __init__(self, basedir, tracking_id,
title, culprit, advisory, patches):
Modified: subversion/branches/swig-py3/tools/dist/templates/download.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/dist/templates/download.ezt?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/dist/templates/download.ezt (original)
+++ subversion/branches/swig-py3/tools/dist/templates/download.ezt Wed Nov 28 21:25:32 2018
@@ -2,16 +2,14 @@
<table class="centered">
<tr>
<th>File</th>
- <th>Checksum (SHA1)</th>
<th>Checksum (SHA512)</th>
<th>Signatures</th>
</tr>
[for fileinfo]<tr>
<td><a href="[[]preferred]subversion/[fileinfo.filename]">[fileinfo.filename]</a></td>
- <td class="checksum">[fileinfo.sha1]</td>
<!-- The sha512 line does not have a class="checksum" since the link needn't
be rendered in monospace. -->
- <td>[<a href="http://www.apache.org/dist/subversion/[fileinfo.filename].sha512">SHA-512</a>]</td>
- <td>[<a href="http://www.apache.org/dist/subversion/[fileinfo.filename].asc">PGP</a>]</td>
+ <td>[<a href="https://www.apache.org/dist/subversion/[fileinfo.filename].sha512">SHA-512</a>]</td>
+ <td>[<a href="https://www.apache.org/dist/subversion/[fileinfo.filename].asc">PGP</a>]</td>
</tr>[end]
</table>
Modified: subversion/branches/swig-py3/tools/dist/templates/rc-news.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/dist/templates/rc-news.ezt?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/dist/templates/rc-news.ezt (original)
+++ subversion/branches/swig-py3/tools/dist/templates/rc-news.ezt Wed Nov 28 21:25:32 2018
@@ -8,10 +8,10 @@
release is not intended for production use, but is provided as a milestone
to encourage wider testing and feedback from intrepid users and maintainers.
Please see the
- <a href="">release
+ <a href="[announcement_url]">release
announcement</a> for more information about this release, and the
<a href="/docs/release-notes/[major-minor].html">release notes</a> and
- <a href="http://svn.apache.org/repos/asf/subversion/tags/[version]/CHANGES">
+ <a href="https://svn.apache.org/repos/asf/subversion/tags/[version]/CHANGES">
change log</a> for information about what will eventually be
in the [version_base] release.</p>
Modified: subversion/branches/swig-py3/tools/dist/templates/rc-release-ann.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/dist/templates/rc-release-ann.ezt?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/dist/templates/rc-release-ann.ezt (original)
+++ subversion/branches/swig-py3/tools/dist/templates/rc-release-ann.ezt Wed Nov 28 21:25:32 2018
@@ -5,12 +5,8 @@ Subject: [[]ANNOUNCE] Apache Subversion
I'm happy to announce the release of Apache Subversion [version].
Please choose the mirror closest to you by visiting:
- http://subversion.apache.org/download.cgi#[anchor]
+ https://subversion.apache.org/download.cgi#[anchor]
-The SHA1 checksums are:
-
-[for sha1info] [sha1info.sha1] [sha1info.filename]
-[end]
SHA-512 checksums are available at:
https://www.apache.org/dist/subversion/subversion-[version].tar.bz2.sha512
@@ -19,9 +15,9 @@ SHA-512 checksums are available at:
PGP Signatures are available at:
- http://www.apache.org/dist/subversion/subversion-[version].tar.bz2.asc
- http://www.apache.org/dist/subversion/subversion-[version].tar.gz.asc
- http://www.apache.org/dist/subversion/subversion-[version].zip.asc
+ https://www.apache.org/dist/subversion/subversion-[version].tar.bz2.asc
+ https://www.apache.org/dist/subversion/subversion-[version].tar.gz.asc
+ https://www.apache.org/dist/subversion/subversion-[version].zip.asc
For this release, the following people have provided PGP signatures:
@@ -57,13 +53,18 @@ end users please.
Release notes for the [major-minor].x release series may be found at:
- http://subversion.apache.org/docs/release-notes/[major-minor].html
+ https://subversion.apache.org/docs/release-notes/[major-minor].html
You can find the list of changes between [version] and earlier versions at:
- http://svn.apache.org/repos/asf/subversion/tags/[version]/CHANGES
+ https://svn.apache.org/repos/asf/subversion/tags/[version]/CHANGES
Questions, comments, and bug reports to users@subversion.apache.org.
Thanks,
- The Subversion Team
+
+--
+To unsubscribe, please see:
+
+ https://subversion.apache.org/mailing-lists.html#unsubscribing
Modified: subversion/branches/swig-py3/tools/dist/templates/stable-news.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/dist/templates/stable-news.ezt?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/dist/templates/stable-news.ezt (original)
+++ subversion/branches/swig-py3/tools/dist/templates/stable-news.ezt Wed Nov 28 21:25:32 2018
@@ -10,10 +10,10 @@
[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
- <a href=""
+ <a href="[announcement_url]"
>release announcement</a> and the
- <a href="http://svn.apache.org/repos/asf/subversion/tags/[version]/CHANGES"
- >change log</a> for more information about this release.</p>
+ <a href="/docs/release-notes/[major-minor]"
+ >release notes</a> for more information about this release.</p>
<p>To get this release from the nearest mirror, please visit our
<a href="/download.cgi#[anchor]">download page</a>.</p>
Modified: subversion/branches/swig-py3/tools/dist/templates/stable-release-ann.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/dist/templates/stable-release-ann.ezt?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/dist/templates/stable-release-ann.ezt (original)
+++ subversion/branches/swig-py3/tools/dist/templates/stable-release-ann.ezt Wed Nov 28 21:25:32 2018
@@ -7,7 +7,7 @@ To: announce@subversion.apache.org, user
I'm happy to announce the release of Apache Subversion [version].
Please choose the mirror closest to you by visiting:
- http://subversion.apache.org/download.cgi#[anchor]
+ https://subversion.apache.org/download.cgi#[anchor]
[if-any dot-zero]
This is a stable feature release of the Apache Subversion open source
version control system.
@@ -18,10 +18,6 @@ open source version control system.
This is a stable bugfix release of the Apache Subversion open source
version control system.
[end][end]
-The SHA1 checksums are:
-
-[for sha1info] [sha1info.sha1] [sha1info.filename]
-[end]
SHA-512 checksums are available at:
https://www.apache.org/dist/subversion/subversion-[version].tar.bz2.sha512
@@ -30,22 +26,27 @@ SHA-512 checksums are available at:
PGP Signatures are available at:
- http://www.apache.org/dist/subversion/subversion-[version].tar.bz2.asc
- http://www.apache.org/dist/subversion/subversion-[version].tar.gz.asc
- http://www.apache.org/dist/subversion/subversion-[version].zip.asc
+ https://www.apache.org/dist/subversion/subversion-[version].tar.bz2.asc
+ https://www.apache.org/dist/subversion/subversion-[version].tar.gz.asc
+ https://www.apache.org/dist/subversion/subversion-[version].zip.asc
For this release, the following people have provided PGP signatures:
[siginfo]
Release notes for the [major-minor].x release series may be found at:
- http://subversion.apache.org/docs/release-notes/[major-minor].html
+ https://subversion.apache.org/docs/release-notes/[major-minor].html
You can find the list of changes between [version] and earlier versions at:
- http://svn.apache.org/repos/asf/subversion/tags/[version]/CHANGES
+ https://svn.apache.org/repos/asf/subversion/tags/[version]/CHANGES
Questions, comments, and bug reports to users@subversion.apache.org.
Thanks,
- The Subversion Team
+
+--
+To unsubscribe, please see:
+
+ https://subversion.apache.org/mailing-lists.html#unsubscribing
Modified: subversion/branches/swig-py3/tools/hook-scripts/mailer/mailer.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/hook-scripts/mailer/mailer.py?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/hook-scripts/mailer/mailer.py (original)
+++ subversion/branches/swig-py3/tools/hook-scripts/mailer/mailer.py Wed Nov 28 21:25:32 2018
@@ -71,16 +71,10 @@ _MIN_SVN_VERSION = [1, 5, 0]
# Import the Subversion Python bindings, making sure they meet our
# minimum version requirements.
-try:
- import svn.fs
- import svn.delta
- import svn.repos
- import svn.core
-except ImportError:
- sys.stderr.write(
- "You need version %s or better of the Subversion Python bindings.\n" \
- % ".".join([str(x) for x in _MIN_SVN_VERSION]))
- sys.exit(1)
+import svn.fs
+import svn.delta
+import svn.repos
+import svn.core
if _MIN_SVN_VERSION > [svn.core.SVN_VER_MAJOR,
svn.core.SVN_VER_MINOR,
svn.core.SVN_VER_PATCH]:
Modified: subversion/branches/swig-py3/tools/server-side/svnauthz.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/server-side/svnauthz.c?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/server-side/svnauthz.c (original)
+++ subversion/branches/swig-py3/tools/server-side/svnauthz.c Wed Nov 28 21:25:32 2018
@@ -110,29 +110,34 @@ static svn_opt_subcommand_t
/* Array of available subcommands.
* The entire list must be terminated with an entry of nulls.
*/
-static const svn_opt_subcommand_desc2_t cmd_table[] =
+static const svn_opt_subcommand_desc3_t cmd_table[] =
{
- {"help", subcommand_help, {"?", "h"},
- ("usage: svnauthz help [SUBCOMMAND...]\n\n"
- "Describe the usage of this program or its subcommands.\n"),
+ {"help", subcommand_help, {"?", "h"}, {(
+ "usage: svnauthz help [SUBCOMMAND...]\n"
+ "\n"
+ "Describe the usage of this program or its subcommands.\n"
+ )},
{0} },
- {"validate", subcommand_validate, {0} /* no aliases */,
- ("Checks the syntax of an authz file.\n"
+ {"validate", subcommand_validate, {0} /* no aliases */, {(
+ "Checks the syntax of an authz file.\n"
"usage: 1. svnauthz validate TARGET\n"
- " 2. svnauthz validate --transaction TXN REPOS_PATH FILE_PATH\n\n"
+ " 2. svnauthz validate --transaction TXN REPOS_PATH FILE_PATH\n"
+ "\n"
" 1. Loads and validates the syntax of the authz file at TARGET.\n"
" TARGET can be a path to a file or an absolute file:// URL to an authz\n"
- " file in a repository, but cannot be a repository relative URL (^/).\n\n"
+ " file in a repository, but cannot be a repository relative URL (^/).\n"
+ "\n"
" 2. Loads and validates the syntax of the authz file at FILE_PATH in the\n"
- " transaction TXN in the repository at REPOS_PATH.\n\n"
+ " transaction TXN in the repository at REPOS_PATH.\n"
+ "\n"
"Returns:\n"
" 0 when syntax is OK.\n"
" 1 when syntax is invalid.\n"
" 2 operational error\n"
- ),
+ )},
{'t'} },
- {"accessof", subcommand_accessof, {0} /* no aliases */,
- ("Print or test the permissions set by an authz file.\n"
+ {"accessof", subcommand_accessof, {0} /* no aliases */, {(
+ "Print or test the permissions set by an authz file.\n"
"usage: 1. svnauthz accessof TARGET\n"
" 2. svnauthz accessof -t TXN REPOS_PATH FILE_PATH\n"
"\n"
@@ -159,10 +164,10 @@ static const svn_opt_subcommand_desc2_t
" 1 when syntax is invalid.\n"
" 2 operational error\n"
" 3 when '--is' argument doesn't match\n"
- ),
+ )},
{'t', svnauthz__username, svnauthz__path, svnauthz__repos, svnauthz__is,
svnauthz__groups_file, 'R'} },
- { NULL, NULL, {0}, NULL, {0} }
+ { NULL, NULL, {0}, {NULL}, {0} }
};
static svn_error_t *
@@ -171,11 +176,14 @@ subcommand_help(apr_getopt_t *os, void *
struct svnauthz_opt_state *opt_state = baton;
const char *header =
("general usage: svnauthz SUBCOMMAND TARGET [ARGS & OPTIONS ...]\n"
- " " SVNAUTHZ_COMPAT_NAME " TARGET\n\n"
+ " " SVNAUTHZ_COMPAT_NAME " TARGET\n"
+ "\n"
"If the command name starts with '" SVNAUTHZ_COMPAT_NAME "', runs in\n"
- "pre-1.8 compatibility mode: run the 'validate' subcommand on TARGET.\n\n"
+ "pre-1.8 compatibility mode: run the 'validate' subcommand on TARGET.\n"
+ "\n"
"Type 'svnauthz help <subcommand>' for help on a specific subcommand.\n"
- "Type 'svnauthz --version' to see the program version.\n\n"
+ "Type 'svnauthz --version' to see the program version.\n"
+ "\n"
"Available subcommands:\n");
const char *fs_desc_start
@@ -186,7 +194,7 @@ subcommand_help(apr_getopt_t *os, void *
version_footer = svn_stringbuf_create(fs_desc_start, pool);
SVN_ERR(svn_fs_print_modules(version_footer, pool));
- SVN_ERR(svn_opt_print_help4(os, "svnauthz",
+ SVN_ERR(svn_opt_print_help5(os, "svnauthz",
opt_state ? opt_state->version : FALSE,
FALSE, /* quiet */
FALSE, /* verbose */
@@ -459,7 +467,7 @@ sub_main(int *exit_code, int argc, const
{
svn_error_t *err;
- const svn_opt_subcommand_desc2_t *subcommand = NULL;
+ const svn_opt_subcommand_desc3_t *subcommand = NULL;
struct svnauthz_opt_state opt_state = { 0 };
apr_getopt_t *os;
apr_array_header_t *received_opts;
@@ -545,9 +553,9 @@ sub_main(int *exit_code, int argc, const
{
/* Pre 1.8 compatibility mode. */
if (argc == 1) /* No path argument */
- subcommand = svn_opt_get_canonical_subcommand2(cmd_table, "help");
+ subcommand = svn_opt_get_canonical_subcommand3(cmd_table, "help");
else
- subcommand = svn_opt_get_canonical_subcommand2(cmd_table, "validate");
+ subcommand = svn_opt_get_canonical_subcommand3(cmd_table, "validate");
}
/* If the user asked for help, then the rest of the arguments are
@@ -555,7 +563,7 @@ sub_main(int *exit_code, int argc, const
just typos/mistakes. Whatever the case, the subcommand to
actually run is subcommand_help(). */
if (opt_state.help)
- subcommand = svn_opt_get_canonical_subcommand2(cmd_table, "help");
+ subcommand = svn_opt_get_canonical_subcommand3(cmd_table, "help");
if (subcommand == NULL)
{
@@ -564,8 +572,8 @@ sub_main(int *exit_code, int argc, const
if (opt_state.version)
{
/* Use the "help" subcommand to handle the "--version" option. */
- static const svn_opt_subcommand_desc2_t pseudo_cmd =
- { "--version", subcommand_help, {0}, "",
+ static const svn_opt_subcommand_desc3_t pseudo_cmd =
+ { "--version", subcommand_help, {0}, {""},
{svnauthz__version /* must accept its own option */ } };
subcommand = &pseudo_cmd;
@@ -585,7 +593,7 @@ sub_main(int *exit_code, int argc, const
SVN_ERR(svn_utf_cstring_to_utf8(&first_arg, os->argv[os->ind++],
pool));
- subcommand = svn_opt_get_canonical_subcommand2(cmd_table, first_arg);
+ subcommand = svn_opt_get_canonical_subcommand3(cmd_table, first_arg);
if (subcommand == NULL)
{
os->ind++;
@@ -658,11 +666,11 @@ sub_main(int *exit_code, int argc, const
if (opt_id == 'h' || opt_id == '?')
continue;
- if (! svn_opt_subcommand_takes_option3(subcommand, opt_id, NULL))
+ if (! svn_opt_subcommand_takes_option4(subcommand, opt_id, NULL))
{
const char *optstr;
const apr_getopt_option_t *badopt =
- svn_opt_get_option_from_code2(opt_id, options_table, subcommand,
+ svn_opt_get_option_from_code3(opt_id, options_table, subcommand,
pool);
svn_opt_format_option(&optstr, badopt, FALSE, pool);
if (subcommand->name[0] == '-')
Modified: subversion/branches/swig-py3/tools/server-side/svnpubsub/svnwcsub.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/tools/server-side/svnpubsub/svnwcsub.py?rev=1847678&r1=1847677&r2=1847678&view=diff
==============================================================================
--- subversion/branches/swig-py3/tools/server-side/svnpubsub/svnwcsub.py (original)
+++ subversion/branches/swig-py3/tools/server-side/svnpubsub/svnwcsub.py Wed Nov 28 21:25:32 2018
@@ -32,7 +32,7 @@
# TODO:
# - bulk update at startup time to avoid backlog warnings
-# - fold BDEC into Daemon
+# - fold BigDoEverythingClasss ("BDEC") into Daemon
# - fold WorkingCopy._get_match() into __init__
# - remove wc_ready(). assume all WorkingCopy instances are usable.
# place the instances into .watch at creation. the .update_applies()