diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | doc/conf.py | 12 | ||||
-rw-r--r-- | howto.txt | 16 | ||||
-rw-r--r-- | igor.py | 126 |
4 files changed, 100 insertions, 60 deletions
@@ -146,6 +146,9 @@ sample_html_beta: _sample_cog_html ## Generate sample HTML report for a beta rel REPO_OWNER = nedbat/coveragepy +edit_for_release: ## Edit sources to insert release facts. + python igor.py edit_for_release + kit: ## Make the source distribution. python -m build @@ -181,6 +184,9 @@ update_stable: ## Set the stable branch to the latest release. git branch -f stable $$(python setup.py --version) git push origin stable +bump_version: ## Edit sources to bump the version after a release. + python igor.py bump_version + ##@ Documentation diff --git a/doc/conf.py b/doc/conf.py index c9599e0e..38b8f0fe 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -57,18 +57,20 @@ master_doc = 'index' # General information about the project. project = 'Coverage.py' -copyright = '2009\N{EN DASH}2022, Ned Batchelder' # CHANGEME # pylint: disable=redefined-builtin # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. -# -# The short X.Y.Z version. # CHANGEME + +# @@@ editable +copyright = "2009–2022, Ned Batchelder" # pylint: disable=redefined-builtin +# The short X.Y.Z version. version = "6.5.0" -# The full version, including alpha/beta/rc tags. # CHANGEME +# The full version, including alpha/beta/rc tags. release = "6.5.0" -# The date of release, in "monthname day, year" format. # CHANGEME +# The date of release, in "monthname day, year" format. release_date = "September 29, 2022" +# @@@ end rst_epilog = """ .. |release_date| replace:: {release_date} @@ -7,10 +7,10 @@ version_info = (4, 0, 2, "candidate", 1) version_info = (4, 0, 2, "final", 0) - Supported Python version numbers. Search for "PYVERSIONS". -- Copyright date in NOTICE.txt +- Update source files with release facts: + $ make edit_for_release - run `python igor.py cheats` to get useful snippets for next steps. -- Update CHANGES.rst, including release date. - - don't forget the jump target +- Look over CHANGES.rst - Update README.rst - "New in x.y:" - Python versions supported @@ -18,8 +18,6 @@ - Python versions in doc/index.rst - IF PRE-RELEASE: - Version of latest stable release in doc/index.rst - - Version, release, release_date and copyright date in doc/conf.py - - Look for CHANGEME comments - Make sure the docs are cogged: $ make prebuild - Don't forget the man page: doc/python-coverage.1.txt @@ -61,14 +59,8 @@ $ make clean github_releases - Visit the fixed issues on GitHub and mention the version it was fixed in. $ make comment_on_fixes - - "This is now released as part of [coverage 5.2](https://pypi.org/project/coverage/5.2)." - Bump version: - - coverage/version.py - - increment version number - - IF NOT PRE-RELEASE: - - set to alpha-0 if just released. - - CHANGES.rst - - add an "Unreleased" section to the top. + $ make bump_version $ git push - Update readthedocs - @ https://readthedocs.org/projects/coverage/versions/ @@ -15,10 +15,12 @@ import glob import inspect import os import platform +import re import subprocess import sys import sysconfig import textwrap +import types import warnings import zipfile @@ -380,56 +382,94 @@ def do_quietly(command): return proc.returncode +def get_release_facts(): + """Return an object with facts about the current release.""" + import coverage + facts = types.SimpleNamespace() + facts.ver = coverage.__version__ + facts.vi = coverage.version_info + facts.shortver = f"{facts.vi[0]}.{facts.vi[1]}.{facts.vi[2]}" + facts.anchor = facts.shortver.replace(".", "-") + if facts.vi[3] != "final": + facts.anchor += f"{facts.vi[3][0]}{facts.vi[4]}" + facts.next_vi = (facts.vi[0], facts.vi[1], facts.vi[2]+1, "alpha", 0) + facts.now = datetime.datetime.now() + facts.branch = subprocess.getoutput("git rev-parse --abbrev-ref @") + return facts + + +def update_file(fname, pattern, replacement): + """Update the contents of a file, replacing pattern with replacement.""" + with open(fname) as fobj: + old_text = fobj.read() + + new_text = re.sub(pattern, replacement, old_text, count=1) + + if new_text != old_text: + print(f"Updating {fname}") + with open(fname, "w") as fobj: + fobj.write(new_text) + +UNRELEASED = "Unreleased\n----------" + +def do_edit_for_release(): + """Edit a few files in preparation for a release.""" + facts = get_release_facts() + + # NOTICE.txt + update_file("NOTICE.txt", r"Copyright 2004.*? Ned", f"Copyright 2004-{facts.now:%Y} Ned") + + # CHANGES.rst + title = f"Version {facts.ver} — {facts.now:%Y-%m-%d}" + rule = "-" * len(title) + new_head = f".. _changes_{facts.anchor}:\n\n{title}\n{rule}" + + update_file("CHANGES.rst", re.escape(UNRELEASED), new_head) + + # doc/conf.py + new_conf = textwrap.dedent(f"""\ + # @@@ editable + copyright = "2009\N{EN DASH}{facts.now:%Y}, Ned Batchelder" # pylint: disable=redefined-builtin + # The short X.Y.Z version. + version = "{facts.shortver}" + # The full version, including alpha/beta/rc tags. + release = "{facts.ver}" + # The date of release, in "monthname day, year" format. + release_date = "{facts.now:%B %-d, %Y}" + # @@@ end + """) + update_file("doc/conf.py", r"(?s)# @@@ editable\n.*# @@@ end\n", new_conf) + + +def do_bump_version(): + """Edit a few files right after a release to bump the version.""" + facts = get_release_facts() + + # CHANGES.rst + update_file( + "CHANGES.rst", + r"(?m)^\.\. _changes_", + f"{UNRELEASED}\n\nNothing yet.\n\n\n.. _changes_", + ) + + # coverage/version.py + next_version = f"version_info = {facts.next_vi}".replace("'", '"') + update_file("coverage/version.py", r"(?m)^version_info = .*$", next_version) + + def do_cheats(): """Show a cheatsheet of useful things during releasing.""" - import coverage - ver = coverage.__version__ - vi = coverage.version_info - shortver = f"{vi[0]}.{vi[1]}.{vi[2]}" - anchor = shortver.replace(".", "-") - if vi[3] != "final": - anchor += f"{vi[3][0]}{vi[4]}" - now = datetime.datetime.now() - branch = subprocess.getoutput("git rev-parse --abbrev-ref @") - print(f"Coverage version is {ver}") - - print(f"pip install git+https://github.com/nedbat/coveragepy@{branch}") - print(f"https://coverage.readthedocs.io/en/{ver}/changes.html#changes-{anchor}") - - print("\n## for CHANGES.rst before release:") - print(f".. _changes_{anchor}:") - print() - head = f"Version {ver} — {now:%Y-%m-%d}" - print(head) - print("-" * len(head)) - - print("\n## For doc/conf.py before release:") - print("\n".join([ - '# The short X.Y.Z version. # CHANGEME', - f'version = "{shortver}"', - '# The full version, including alpha/beta/rc tags. # CHANGEME', - f'release = "{ver}"', - '# The date of release, in "monthname day, year" format. # CHANGEME', - f'release_date = "{now:%B %-d, %Y}"', - ])) + facts = get_release_facts() + print(f"Coverage version is {facts.ver}") + + print(f"pip install git+https://github.com/nedbat/coveragepy@{facts.branch}") + print(f"https://coverage.readthedocs.io/en/{facts.ver}/changes.html#changes-{facts.anchor}") print( "\n## For GitHub commenting:\n" + "This is now released as part of " + - f"[coverage {ver}](https://pypi.org/project/coverage/{ver})." + f"[coverage {facts.ver}](https://pypi.org/project/coverage/{facts.ver})." ) - print("\n## For version.py next:") - next_vi = (vi[0], vi[1], vi[2]+1, "alpha", 0) - print(f"version_info = {next_vi}".replace("'", '"')) - print("\n## For CHANGES.rst after release:") - print(textwrap.dedent("""\ - Unreleased - ---------- - - Nothing yet. - - - """)) def do_help(): |