ORIGINAL_PATH = os.environ['PATH']
def main():
+ if not os.path.isfile('packaging/release-rsync'):
+ die('You must run this script from the top of your rsync checkout.')
+
now = datetime.now()
cl_today = now.strftime('* %a %b %d %Y')
year = now.strftime('%Y')
signal.signal(signal.SIGINT, signal_handler)
- if cmd_txt_chk(['packaging/prep-auto-dir']) == '':
+ if cmd_txt_chk(['packaging/prep-auto-dir']).out == '':
die('You must setup an auto-build-save dir to use this script.');
auto_dir, gen_files = get_gen_files(True)
{dash_line}
""")
+ with open('build/rsync.1') as fh:
+ for line in fh:
+ if line.startswith(r'.\" prefix='):
+ doc_prefix = line.split('=')[1].strip()
+ if doc_prefix != '/usr':
+ warn(f"*** The documentation was built with prefix {doc_prefix} instead of /usr ***")
+ die("*** Read the md2man script for a way to override this. ***")
+ break
+ if line.startswith('.P'):
+ die("Failed to find the prefix comment at the start of the rsync.1 manpage.")
+
if not os.path.isdir(dest):
die(dest, "dest does not exist")
if not os.path.isdir('.git'):
curversion = get_rsync_version()
# All version values are strings!
- lastversion, last_protocol_version = get_NEWS_version_info()
+ lastversion, last_protocol_version, pdate = get_NEWS_version_info()
protocol_version, subprotocol_version = get_protocol_versions()
version = curversion
if os.path.lexists(rsync_ver):
die(f'"{rsync_ver}" must not exist in the current directory.')
- out = cmd_txt_chk(['git', 'tag', '-l', v_ver])
+ out = cmd_txt_chk(['git', 'tag', '-l', v_ver]).out
if out != '':
print(f"Tag {v_ver} already exists.")
ans = input("\nDelete tag or quit? [Q/del] ")
release += '.' + pre
finalversion = re.sub(r'pre\d+', '', version)
- if protocol_version == last_protocol_version:
- proto_changed = 'unchanged'
- proto_change_date = ' ' * 11
- else:
- proto_changed = 'changed'
+ proto_changed = protocol_version != last_protocol_version
+ if proto_changed:
if finalversion in pdate:
proto_change_date = pdate[finalversion]
else:
if re.match(r'^\d\d \w\w\w \d\d\d\d$', ans):
break
proto_change_date = ans
+ else:
+ proto_change_date = ' ' * 11
if 'pre' in lastversion:
if not pre:
with open(fn, 'r', encoding='utf-8') as fh:
old_txt = txt = fh.read()
if fn == 'version.h':
- txt = f'#define RSYNC_VERSION "{version}"\n'
+ x_re = re.compile(r'^(#define RSYNC_VERSION).*', re.M)
+ msg = f"Unable to update RSYNC_VERSION in {fn}"
+ txt = replace_or_die(x_re, r'\1 "%s"' % version, txt, msg)
elif '.spec' in fn:
for var, val in specvars.items():
x_re = re.compile(r'^%s .*' % re.escape(var), re.M)
txt = replace_or_die(x_re, r'%s \1' % cl_today, txt, f"Unable to update ChangeLog header in {fn}")
elif fn == 'rsync.h':
x_re = re.compile('(#define\s+SUBPROTOCOL_VERSION)\s+(\d+)')
- repl = lambda m: m[1] + ' ' + '0' if not pre or proto_changed != 'changed' else 1 if m[2] == '0' else m[2]
+ repl = lambda m: m[1] + ' ' + ('0' if not pre or not proto_changed else '1' if m[2] == '0' else m[2])
txt = replace_or_die(x_re, repl, txt, f"Unable to find SUBPROTOCOL_VERSION define in {fn}")
elif fn == 'NEWS.md':
efv = re.escape(finalversion)
- x_re = re.compile(r'^<.+>\s+# NEWS for rsync %s \(UNRELEASED\)\s+Protocol: .+\n' % efv)
+ x_re = re.compile(r'^# NEWS for rsync %s \(UNRELEASED\)\s+## Changes in this version:\n' % efv
+ + r'(\n### PROTOCOL NUMBER:\s+- The protocol number was changed to \d+\.\n)?')
rel_day = 'UNRELEASED' if pre else today
- repl = (f'<a name="{finalversion}"></a>\n\n# NEWS for rsync {finalversion} ({rel_day})\n\n'
- + f"Protocol: {protocol_version} ({proto_changed})\n")
+ repl = (f'# NEWS for rsync {finalversion} ({rel_day})\n\n'
+ + '## Changes in this version:\n')
+ if proto_changed:
+ repl += f'\n### PROTOCOL NUMBER:\n\n - The protocol number was changed to {protocol_version}.\n'
good_top = re.sub(r'\(.*?\)', '(UNRELEASED)', repl, 1)
msg = f"The top lines of {fn} are not in the right format. It should be:\n" + good_top
txt = replace_or_die(x_re, repl, txt, msg)
cmd_chk(['packaging/year-tweak'])
print(dash_line)
- cmd_run("git diff --color | less -p '^diff .*'")
+ cmd_run("git diff".split())
srctar_name = f"{rsync_ver}.tar.gz"
pattar_name = f"rsync-patches-{version}.tar.gz"
About to:
- git commit all changes
- - generate the manpages
+ - run a full build, ensuring that the manpages & configure.sh are up-to-date
- merge the {args.master_branch} branch into the patch/{args.master_branch}/* branches
- - update the files in the "patches" dir and OPTIONALLY
- (if you type 'y') to launch a shell for each patch
+ - update the files in the "patches" dir and OPTIONALLY (if you type 'y') to
+ run patch-update with the --make option (which opens a shell on error)
""")
ans = input("<Press Enter OR 'y' to continue> ")
if s.returncode:
die('Aborting')
- cmd_chk('make gen')
+ cmd_chk('touch configure.ac && packaging/smart-make && make gen')
- print(f'Creating any missing patch branches.')
+ print('Creating any missing patch branches.')
s = cmd_run(f'packaging/branch-from-patch --branch={args.master_branch} --add-missing')
if s.returncode:
die('Aborting')
die('Aborting')
if re.match(r'^y', ans, re.I):
- print(f'\nVisiting all "patch/{args.master_branch}/*" branches ...')
- cmd_run(f"packaging/patch-update --branch={args.master_branch} --skip-check --shell")
+ print(f'\nRunning smart-make on all "patch/{args.master_branch}/*" branches ...')
+ cmd_run(f"packaging/patch-update --branch={args.master_branch} --skip-check --make")
if os.path.isdir('patches/.git'):
s = cmd_run(f"cd patches && git commit -a -m 'The patches for {version}.'")
# TODO: is there a better way to ensure that our passphrase is in the agent?
cmd_run("touch TeMp; gpg --sign TeMp; rm TeMp*")
- out = cmd_txt(f"git tag -s -m 'Version {version}.' {v_ver}", capture='combined')
+ out = cmd_txt(f"git tag -s -m 'Version {version}.' {v_ver}", capture='combined').out
print(out, end='')
if 'bad passphrase' in out or 'failed' in out:
die('Aborting')
if os.path.isdir('patches/.git'):
- out = cmd_txt(f"cd patches && git tag -s -m 'Version {version}.' {v_ver}", capture='combined')
+ out = cmd_txt(f"cd patches && git tag -s -m 'Version {version}.' {v_ver}", capture='combined').out
print(out, end='')
if 'bad passphrase' in out or 'failed' in out:
die('Aborting')
shutil.rmtree(rsync_ver)
print(f"Updating the other files in {dest} ...")
- md_files = 'README.md NEWS.md'.split()
+ md_files = 'README.md NEWS.md INSTALL.md'.split()
html_files = [ fn for fn in gen_pathnames if fn.endswith('.html') ]
cmd_chk(['rsync', '-a', *md_files, *html_files, dest])
- cmd_chk(["packaging/md2html"] + [ dest +'/'+ fn for fn in md_files ])
+ cmd_chk(["./md-convert", "--dest", dest, *md_files])
cmd_chk(f"git log --name-status | gzip -9 >{dest}/ChangeLog.gz")