1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-08 12:40:49 -08:00

Automate more of the release registration steps.

Copied from Perforce
 Change: 184892
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Gareth Rees 2014-03-19 23:01:23 +00:00
parent bddb20f682
commit 6726b6ddc7
3 changed files with 95 additions and 37 deletions

View file

@ -183,10 +183,6 @@ On a Unix (including OS X) machine:
p4 -c $CLIENT client -d $CLIENT
rm -rf /tmp/$CLIENT
7. Registering the release
--------------------------
#. Edit the index of releases (``release/index.html``) and add the
release to the table, in a manner consistent with previous releases.
@ -201,6 +197,10 @@ On a Unix (including OS X) machine:
p4 submit -d "MPS: registered release $RELEASE."
7. Registering the release
--------------------------
#. Visit the `project
updater <http://info.ravenbrook.com/infosys/cgi/data_update.cgi>`__,
select “mps” from the dropdown, and hit “Find releases”.

View file

@ -63,7 +63,7 @@ VERSION_BRANCH_ENTRY = '''
{description}
</td>
<td>
<a href="https://info.ravenbrook.com/infosys/cgi/perfbrowse.cgi?@describe+{base}">base</a><br>
<a href="https://info.ravenbrook.com/infosys/cgi/perfbrowse.cgi?@describe+{base}">base</a><br />
<a href="https://info.ravenbrook.com/infosys/cgi/perfbrowse.cgi?@changes+{depot}/project/{project}/{child}/...">changelists</a>
</td>
</tr>
@ -80,9 +80,8 @@ def main(argv):
help='Changelevel at which to make the branch.')
parser.add_argument('-d', '--description',
help='Description of the branch (for the branch spec).')
parser.add_argument('-y', '--commit', action='store_true',
help='Carry out the operation (by default, just '
'show a preview).')
parser.add_argument('-y', '--yes', action='store_true',
help='Yes, really make the branch.')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-c', '--child',
help='Name of the child branch.')
@ -92,6 +91,7 @@ def main(argv):
help='Name of the task branch.')
args = parser.parse_args(argv[1:])
args.depot = DEPOT
args.today = datetime.date.today().strftime('%Y-%m-%d')
fmt = lambda s: s.format_map(vars(args))
if not args.project:
@ -133,8 +133,7 @@ def main(argv):
if args.task:
if not re.match(TASK_RE, args.task):
raise Error(fmt("Invalid task: {task}"))
args.child = fmt(datetime.date.today()
.strftime('branch/%Y-%m-%d/{task}'))
args.child = fmt('branch/{today}/{task}')
print(fmt("child={child}"))
elif args.version:
# Deduce version number from code/version.c.
@ -172,12 +171,12 @@ def main(argv):
if any(p4.run('branches', '-E', args.branch)):
print(fmt("Branch spec {branch} already exists: skipping."))
have_branch = True
elif args.commit:
elif args.yes:
print(fmt("Creating branch spec {branch}."))
p4.run('branch', '-i').send(branch_spec).done()
have_branch = True
else:
print("-y/--commit not specified: skipping branch creation.")
print("--yes omitted: skipping branch creation.")
# Populate the branch
if any(p4.run('dirs', fmt('{depot}/project/{project}/{child}'))):
@ -188,15 +187,15 @@ def main(argv):
'-b', args.branch,
'-d', fmt("Branching {parent} to {child}."),
'-s', srcs]
if args.commit:
if args.yes:
print(fmt("Populating branch {branch}..."))
populate_args.remove('-n')
p4.do(*populate_args)
elif have_branch:
print("-y/--commit not specified: dry-run (-n) only.")
print("--yes omitted: populate -n ...")
p4.do(*populate_args)
else:
print("-y/--commit not specified: skipping populate.")
print("--yes omitted: skipping populate.")
# Determine the first change on the branch
cmd = p4.run('changes', fmt('{depot}/project/{project}/{child}/...'))
@ -204,7 +203,7 @@ def main(argv):
args.base = int(deque(cmd, maxlen=1).pop()['change'])
print(fmt("base={base}"))
except IndexError:
args.commit = False
args.yes = False
args.base = args.changelevel
print(fmt("Branch {child} not populated: using base={base}"))
@ -225,11 +224,10 @@ def main(argv):
for result in conn.run('diff'):
if 'data' in result:
print(result['data'])
if args.commit:
if args.yes:
conn.do('submit', '-d', fmt("Registering {child}."), filename)
else:
print(fmt("-y/--commit not specified: skipping submit of\n"
" {filespec}."))
print(fmt("--yes omitted: skipping submit of {filespec}"))
# Task branches
if not args.version:
@ -247,7 +245,7 @@ def main(argv):
if any(p4.run('clients', '-E', args.git_client)):
print(fmt("client {git_client} already exists: skipping."))
have_git_branch = True
elif args.commit:
elif args.yes:
client_spec = dict(
Client=args.git_client,
Description=fmt("Git-fusion client for syncing {project} "
@ -260,7 +258,7 @@ def main(argv):
p4.run('client', '-i').send(client_spec).done()
have_git_branch = True
else:
print("-y/--commit not specified: skipping git branch creation.")
print(fmt("--yes omitted: skipping {git_client}"))
# Update table of pushes
register('{depot}/infosys/robots/git-fusion/etc/pushes',

View file

@ -20,6 +20,7 @@
from __future__ import unicode_literals
import argparse
from contextlib import contextmanager
import datetime
import os
import re
import subprocess
@ -39,15 +40,34 @@ def pushdir(dir):
yield
os.chdir(cwd)
ROOT = '//info.ravenbrook.com/project'
DEPOT = '//info.ravenbrook.com'
PROJECT_RE = r'[a-z][a-z0-9.-]*'
PROJECT_FILESPEC_RE = r'{}/({})/'.format(re.escape(ROOT), PROJECT_RE)
PROJECT_FILESPEC_RE = r'{}/project/({})/'.format(re.escape(DEPOT), PROJECT_RE)
VERSION_RE = r'\d+\.\d+'
CUSTOMER_RE = r'[a-z][a-z0-9.-]*'
BRANCH_RE = (r'master|(?:custom/({})/)?(?:main|version/({}))'
.format(CUSTOMER_RE, VERSION_RE))
BRANCH_FILESPEC_RE = r'{}({})(?:/|$)'.format(PROJECT_FILESPEC_RE, BRANCH_RE)
RELEASE_ENTRY = '''
<tr valign="top">
<td><a href="{release}/">{release}</a></td>
<td>{today}<br />
<a href="https://info.ravenbrook.com/infosys/cgi/perfbrowse.cgi?@files+{origin}/...@{changelevel}">{branch}/...@{changelevel}</a></td>
<td>
{description}
</td>
<td>
<a href="/project/{project}/issue/?action=known&amp;sort=Priority%3AJob&amp;release={release}">Known</a> <br />
<a href="/project/{project}/issue/?action=fixed&amp;release={release}">Fixed</a>
</td>
</tr>
'''
VERSION_ENTRY = ''' <a href="/project/{project}/release/{release}/">{release}</a>
'''
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument('-P', '--project',
@ -56,11 +76,13 @@ def main(argv):
help='Name of the branch to make the release from.')
parser.add_argument('-C', '--changelevel', type=int,
help='Changelevel at which to make the release.')
parser.add_argument('-y', '--commit', action='store_true',
help='Carry out the operation (by default, just '
'show a preview).')
parser.add_argument('-d', '--description',
help='Description of the release.')
parser.add_argument('-y', '--yes', action='store_true',
help='Yes, really make the release.')
args = parser.parse_args(argv[1:])
args.root = ROOT
args.depot = DEPOT
args.today = datetime.date.today().strftime('%Y-%m-%d')
fmt = lambda s: s.format_map(vars(args))
if not args.project:
@ -72,7 +94,7 @@ def main(argv):
args.project = m.group(1)
print(fmt("project={project}"))
if not any(p4.run('dirs', fmt('{root}/{project}'))):
if not any(p4.run('dirs', fmt('{depot}/project/{project}'))):
raise Error(fmt("No such project: {project}"))
if not args.branch:
@ -97,16 +119,17 @@ def main(argv):
if args.version:
print(fmt("version={version}"))
if not any(p4.run('dirs', fmt('{root}/{project}/{branch}'))):
args.origin = fmt('{depot}/project/{project}/{branch}')
if not any(p4.run('dirs', args.origin)):
raise Error(fmt("No such branch: {branch}"))
if not args.changelevel:
cmd = p4.run('changes', '-m', '1', fmt('{root}/{project}/{branch}/...'))
cmd = p4.run('changes', '-m', '1', fmt('{origin}/...'))
args.changelevel = int(next(cmd)['change'])
print(fmt("changelevel={changelevel}"))
# Deduce release from code/version.c.
f = fmt('{root}/{project}/{branch}/code/version.c@{changelevel}')
f = fmt('{origin}/code/version.c@{changelevel}')
m = re.search(r'^#define MPS_RELEASE "release/((\d+\.\d+)\.\d+)"$',
p4.contents(f), re.M)
if not m:
@ -116,15 +139,19 @@ def main(argv):
if args.version and args.version != m.group(2):
raise Error(fmt("Version {version} does not match release {release}"))
if args.customer:
args.reldir = fmt('{root}/{project}/custom/{customer}/release/{release}')
args.reldir = fmt('{depot}/project/{project}/custom/{customer}/release/{release}')
else:
args.reldir = fmt('{root}/{project}/release/{release}')
args.reldir = fmt('{depot}/project/{project}/release/{release}')
if not args.description:
args.description = fmt("Release {release}.")
print(fmt("description={description}"))
args.kit = fmt('mps-kit-{release}')
client_spec = dict(
View0=fmt('{root}/{project}/{branch}/... //__CLIENT__/{kit}/...'),
View0=fmt('{origin}/... //__CLIENT__/{kit}/...'),
View1=fmt('{reldir}/... //__CLIENT__/release/{release}/...'))
srcs = fmt('{root}/{project}/{branch}/...@{changelevel}')
srcs = fmt('{origin}/...@{changelevel}')
for line_end, args.ext, cmd in (('local', 'tar.gz', ['tar', 'czf']),
('win', 'zip', ['zip', '-r'])):
client_spec['LineEnd'] = line_end
@ -139,8 +166,8 @@ def main(argv):
os.makedirs(fmt('release/{release}'))
subprocess.check_call(cmd + [archive, args.kit],
stdout=subprocess.DEVNULL)
if not args.commit:
print("-y/--commit not specified: skipping.")
if not args.yes:
print(fmt("--yes omitted: skipping submit of {kit}.{ext}"))
else:
conn.do('add', os.path.join(client_root, archive))
desc = fmt("Adding the MPS Kit {ext} archive for "
@ -149,6 +176,39 @@ def main(argv):
else:
print("{} already exists: skipping.".format(archive))
def register(filespec, search, replace):
args.filespec = fmt(filespec)
if p4.contents(args.filespec).find(args.release) != -1:
print(fmt("{filespec} already updated: skipping."))
return
client_spec = dict(View0=fmt('{filespec} //__CLIENT__/target'))
with p4.temp_client(client_spec) as (conn, client_root):
filename = os.path.join(client_root, 'target')
conn.do('sync', filename)
conn.do('edit', filename)
with open(filename, encoding='utf8') as f:
text = re.sub(search, fmt(replace), f.read(), 1)
with open(filename, 'w', encoding='utf8') as f:
f.write(text)
for result in conn.run('diff'):
if 'data' in result:
print(result['data'])
if args.yes:
conn.do('submit', '-d', fmt("Registering release {release}."),
filename)
else:
print(fmt("--yes omitted: skipping submit of {filespec}"))
if not args.customer:
register('{depot}/project/{project}/release/index.html',
'(?<=<tbody>\n)', RELEASE_ENTRY)
register('{depot}/project/{project}/version/index.html',
(r'(?<=<td><a href="{0}/">{0}</a></td>\n <td>\n)'
.format(re.escape(args.version), re.escape(args.project))),
VERSION_ENTRY)
register('{depot}/project/{project}/index.rst',
r'release/\d+\.\d+\.\d+', 'release/{release}')
if __name__ == '__main__':
main(sys.argv)