Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blurb: replace spaces with underscores in news directory #499

Merged
merged 17 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# .coveragerc to control coverage.py

[report]
# Regexes for lines to exclude from consideration
exclude_lines =
# Have to re-enable the standard pragma:
pragma: no cover

# Don't complain if non-runnable code isn't run:
if __name__ == .__main__.:
def main

[run]
omit =
**/blurb/__main__.py
21 changes: 19 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ name: Tests

on: [push, pull_request, workflow_dispatch]

env:
FORCE_COLOR: 1

jobs:
build_ubuntu:
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12-dev"]
name: ${{ matrix.python-version }}
Expand All @@ -20,11 +24,24 @@ jobs:
run: |
python --version
python -m pip install --upgrade pip
python -m pip install --upgrade flit
python -m pip install --upgrade build pytest pytest-cov pyfakefs
- name: install
run: |
cd blurb
flit install
python -m build
echo dist/*.whl | xargs -I % python -m pip install %
- name: test
run: |
blurb test
- name: pytest
# TODO Pending https://github.com/pytest-dev/pyfakefs/issues/770
if: matrix.python-version != '3.12-dev'
run: |
python -I -m pytest --cov blurb
- name: Upload coverage
# TODO Pending https://github.com/pytest-dev/pyfakefs/issues/770
if: matrix.python-version != '3.12-dev'
uses: codecov/codecov-action@v3
with:
flags: ${{ matrix.python-version }}
name: Python ${{ matrix.python-version }}
108 changes: 28 additions & 80 deletions blurb/blurb.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
"""Command-line tool to manage CPython Misc/NEWS.d entries."""
from __future__ import annotations
__version__ = "1.1.0"

##
Expand Down Expand Up @@ -51,7 +52,6 @@
import io
import inspect
import itertools
import math
import os
from pathlib import Path
import re
Expand Down Expand Up @@ -111,17 +111,28 @@
sections.append(section.strip())


def sanitize_section(section):
def sanitize_section(section: str) -> str:
"""
Cleans up a section string, making it viable as a directory name.
Cleans up a section string, making it viable as a directory name.
hugovk marked this conversation as resolved.
Show resolved Hide resolved
"""
return section.replace("/", "-").replace(" ", "-")


def sanitize_section_legacy(section: str) -> str:
"""
Cleans up a section string, making it viable as a directory name (allow spaces).
hugovk marked this conversation as resolved.
Show resolved Hide resolved
"""
return section.replace("/", "-")


_unsanitize_section = {
"C-API": "C API",
"Core-and-Builtins": "Core and Builtins",
"Tools-Demos": "Tools/Demos",
}

def unsanitize_section(section):

def unsanitize_section(section: str) -> str:
return _unsanitize_section.get(section, section)


Expand Down Expand Up @@ -249,40 +260,6 @@ def safe_mkdir(path):
os.makedirs(path)


def which(cmd, path="PATH"):
"""Find cmd on PATH."""
if os.path.exists(cmd):
return cmd
if cmd[0] == '/':
return None
for segment in os.getenv(path).split(":"):
program = os.path.normpath(os.path.join(segment, cmd))
if os.path.exists(program):
return program
return None


def strip_whitespace_lines(lines):
# strip from head
while lines:
if lines[0]:
break
lines.pop(0)

# strip from tail
while lines:
if lines[-1]:
return
lines.pop()


def longest_line(lines):
longest = 0
for line in lines:
longest = max(longest, len(line))
return longest


def version_key(element):
fields = list(element.split("."))
if len(fields) == 1:
Expand Down Expand Up @@ -328,15 +305,19 @@ def glob_versions():
return versions


def glob_blurbs(version):
def glob_blurbs(version: str) -> list[str]:
filenames = []
base = os.path.join("Misc", "NEWS.d", version)
if version != "next":
wildcard = base + ".rst"
filenames.extend(glob.glob(wildcard))
else:
for section in sections:
wildcard = os.path.join(base, sanitize_section(section), "*.rst")
sanitized_sections = (
{sanitize_section(section) for section in sections} |
{sanitize_section_legacy(section) for section in sections}
)
for section in sanitized_sections:
wildcard = os.path.join(base, section, "*.rst")
entries = glob.glob(wildcard)
entries.sort(reverse=True)
deletables = [x for x in entries if x.endswith("/README.rst")]
Expand Down Expand Up @@ -558,10 +539,10 @@ def save(self, path):
file.write(text)

@staticmethod
def _parse_next_filename(filename):
def _parse_next_filename(filename: str) -> dict[str, str]:
"""
Parses a "next" filename into its equivalent blurb metadata.
Returns a dict.
Parses a "next" filename into its equivalent blurb metadata.
Returns a dict.
"""
components = filename.split(os.sep)
section, filename = components[-2:]
Expand All @@ -575,7 +556,7 @@ def _parse_next_filename(filename):
metadata = {"date": fields[0], "nonce": fields[-2], "section": section}

for field in fields[1:-2]:
for name in ("gh-issue","bpo"):
for name in ("gh-issue", "bpo"):
_, got, value = field.partition(name + "-")
if got:
metadata[name] = value.strip()
Expand Down Expand Up @@ -604,15 +585,15 @@ def ensure_metadata(self):
if name not in metadata:
metadata[name] = default

def _extract_next_filename(self):
def _extract_next_filename(self) -> str:
"""
changes metadata!
"""
self.ensure_metadata()
metadata, body = self[-1]
metadata['section'] = sanitize_section(metadata['section'])
metadata['root'] = root
if int(metadata["gh-issue"]) > 0 :
if int(metadata["gh-issue"]) > 0:
path = "{root}/Misc/NEWS.d/next/{section}/{date}.gh-issue-{gh-issue}.{nonce}.rst".format_map(metadata)
elif int(metadata["bpo"]) > 0:
# assume it's a GH issue number
Expand All @@ -632,31 +613,6 @@ def save_next(self):
blurb.save(filename)
return filename

def save_split_next(self):
"""
Save out blurbs created from "blurb split".
They don't have dates, so we have to get creative.
"""
filenames = []
# the "date" MUST have a leading zero.
# this ensures these files sort after all
# newly created blurbs.
width = int(math.ceil(math.log(len(self), 10))) + 1
i = 1
blurb = Blurbs()
while self:
metadata, body = self.pop()
metadata['date'] = str(i).rjust(width, '0')
if 'release date' in metadata:
del metadata['release date']
blurb.append((metadata, body))
filename = blurb._extract_next_filename()
blurb.save(filename)
blurb.clear()
filenames.append(filename)
i += 1
return filenames


tests_run = 0

Expand Down Expand Up @@ -694,13 +650,6 @@ def filename_test(self, filename):
b.load(filename)



def run(s):
process = subprocess.run(s.split(), capture_output=True)
process.check_returncode()
return process.stdout.decode('ascii')


readme_re = re.compile(r"This is \w+ version \d+\.\d+").match

def chdir_to_repo_root():
Expand Down Expand Up @@ -993,7 +942,6 @@ def release(version):
metadata = {"no changes": "True", "gh-issue": "0", "section": "Library", "date": date, "nonce": nonceify(body)}
blurbs.append((metadata, body))
else:
no_changes = None
count = len(filenames)
print(f'Merging {count} blurbs to "{output}".')

Expand Down
Loading