Skip to content

Commit

Permalink
Merge pull request #1284 from effigies/doc/release-notes
Browse files Browse the repository at this point in the history
MNT: Add tool for generating GitHub-friendly release notes from RST changelog
  • Loading branch information
effigies authored Dec 12, 2023
2 parents 70795b0 + 33363bf commit 26a9886
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 5 deletions.
6 changes: 3 additions & 3 deletions Changelog
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ tested up to Python 3.12 and NumPy 1.26.
New features
------------
* Add generic :class:`~nibabel.pointset.Pointset` and regularly spaced
:class:`~nibabel.pointset.NDGrid` data structures in preparation for coordinate
:class:`~nibabel.pointset.Grid` data structures in preparation for coordinate
transformation and resampling (pr/1251) (CM, reviewed by Oscar Esteban)

Enhancements
------------
* Add :meth:`~nibabel.arrayproxy.ArrayProxy.copy` method to
:class:`~nibabel.arrayproxy.ArrayProxy` (pr/1255) (CM, reviewed by Paul McCarthy)
* Permit :meth:`~nibabel.xmlutils.XmlSerializable.to_xml` to pass keyword
arguments to :meth:`~xml.etree.ElementTree.ElementTree.tostring` (pr/1258)
arguments to :meth:`~xml.etree.ElementTree.tostring` (pr/1258)
(CM)
* Allow user expansion (e.g., ``~/...``) in strings passed to functions that
accept paths (pr/1260) (Reinder Vos de Wael, reviewed by CM)
Expand All @@ -54,7 +54,7 @@ Enhancements
``affine=None`` argument (pr/1253) (Blake Dewey, reviewed by CM)
* Warn on invalid MINC2 spacing declarations, treat as missing (pr/1237)
(Peter Suter, reviewed by CM)
* Refactor :func:`~nibabel.nicom.utils.find_private_element` for improved
* Refactor :func:`~nibabel.nicom.utils.find_private_section` for improved
readability and maintainability (pr/1228) (MB, reviewed by CM)

Bug fixes
Expand Down
94 changes: 94 additions & 0 deletions tools/markdown_release_notes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env python
import re
import sys
from pathlib import Path

CHANGELOG = Path(__file__).parent.parent / 'Changelog'

# Match release lines like "5.2.0 (Monday 11 December 2023)"
RELEASE_REGEX = re.compile(r"""((?:\d+)\.(?:\d+)\.(?:\d+)) \(\w+ \d{1,2} \w+ \d{4}\)$""")


def main():
version = sys.argv[1]
output = sys.argv[2]
if output == '-':
output = sys.stdout
else:
output = open(output, 'w')

release_notes = []
in_release_notes = False

with open(CHANGELOG) as f:
for line in f:
match = RELEASE_REGEX.match(line)
if match:
if in_release_notes:
break
in_release_notes = match.group(1) == version
next(f) # Skip the underline
continue

if in_release_notes:
release_notes.append(line)

# Drop empty lines at start and end
while release_notes and not release_notes[0].strip():
release_notes.pop(0)
while release_notes and not release_notes[-1].strip():
release_notes.pop()

# Join lines
release_notes = ''.join(release_notes)

# Remove line breaks when they are followed by a space
release_notes = re.sub(r'\n +', ' ', release_notes)

# Replace pr/<number> with #<number> for GitHub
release_notes = re.sub(r'\(pr/(\d+)\)', r'(#\1)', release_notes)

# Replace :mod:`package.X` with [package.X](...)
release_notes = re.sub(
r':mod:`nibabel\.(.*)`',
r'[nibabel.\1](https://nipy.org/nibabel/reference/nibabel.\1.html)',
release_notes,
)
# Replace :class/func/attr:`package.module.X` with [package.module.X](...)
release_notes = re.sub(
r':(?:class|func|attr):`(nibabel\.\w*)(\.[\w.]*)?\.(\w+)`',
r'[\1\2.\3](https://nipy.org/nibabel/reference/\1.html#\1\2.\3)',
release_notes,
)
release_notes = re.sub(
r':(?:class|func|attr):`~(nibabel\.\w*)(\.[\w.]*)?\.(\w+)`',
r'[\3](https://nipy.org/nibabel/reference/\1.html#\1\2.\3)',
release_notes,
)
# Replace :meth:`package.module.class.X` with [package.module.class.X](...)
release_notes = re.sub(
r':meth:`(nibabel\.[\w.]*)\.(\w+)\.(\w+)`',
r'[\1.\2.\3](https://nipy.org/nibabel/reference/\1.html#\1.\2.\3)',
release_notes,
)
release_notes = re.sub(
r':meth:`~(nibabel\.[\w.]*)\.(\w+)\.(\w+)`',
r'[\3](https://nipy.org/nibabel/reference/\1.html#\1.\2.\3)',
release_notes,
)

def python_doc(match):
module = match.group(1)
name = match.group(2)
return f'[{name}](https://docs.python.org/3/library/{module.lower()}.html#{module}.{name})'

release_notes = re.sub(r':meth:`~([\w.]+)\.(\w+)`', python_doc, release_notes)

output.write('## Release notes\n\n')
output.write(release_notes)

output.close()


if __name__ == '__main__':
main()
5 changes: 3 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ labels = check
deps =
flake8
blue
isort[colors]
# Broken extras, remove when fix is released
isort[colors]!=5.13.1
skip_install = true
commands =
blue --check --diff --color nibabel
Expand All @@ -153,7 +154,7 @@ description = Auto-apply style guide to the extent possible
labels = pre-release
deps =
blue
isort[colors]
isort
skip_install = true
commands =
blue nibabel
Expand Down

0 comments on commit 26a9886

Please sign in to comment.