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

Add --gh and --section flags to "blurb add" #15

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
# Temporarily remove 3.13 pending:
# https://github.com/pytest-dev/pyfakefs/issues/1017
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,13 @@ Here's how you interact with the file:

* Add the GitHub issue number for this commit to the
end of the `.. gh-issue:` line.
Can be passed on the CLI via the `--gh` flag.

* Uncomment the line with the relevant `Misc/NEWS` section for this entry.
For example, if this should go in the `Library` section, uncomment
the line reading `#.. section: Library`. To uncomment, just delete
the `#` at the front of the line.
Can be passed on the CLI via the `--section` flag.

* Finally, go to the end of the file, and enter your `NEWS` entry.
This should be a single paragraph of English text using
Expand Down Expand Up @@ -239,6 +241,12 @@ part of the cherry-picking process.

## Changelog

### 1.2.0

- Add the `--gh` and `--section` flags to the `add` command.
This lets you pre-fill-in the `gh-issue` and `section` fields
in the template.

### 1.1.0

- Support GitHub Issues in addition to b.p.o (bugs.python.org).
Expand Down
71 changes: 46 additions & 25 deletions src/blurb/blurb.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
#
# Please enter the relevant GitHub issue number here:
#
.. gh-issue:
.. gh-issue: {gh}

#
# Uncomment one of these "section:" lines to specify which section
Expand All @@ -90,6 +90,7 @@
#.. section: IDLE
#.. section: Tools/Demos
#.. section: C API
{section}

# Write your Misc/NEWS.d entry below. It should be a simple ReST paragraph.
# Don't start with "- Issue #<n>: " or "- gh-issue-<n>: " or that sort of stuff.
Expand Down Expand Up @@ -451,6 +452,8 @@
line_number = None

def throw(s):
nonlocal filename
nonlocal line_number
raise BlurbError(f"Error in {filename}:{line_number}:\n{s}")

def finish_entry():
Expand Down Expand Up @@ -870,7 +873,7 @@


@subcommand
def add():
def add(*, gh="", section=""):
"""
Add a blurb (a Misc/NEWS.d/next entry) to the current CPython repo.
"""
Expand All @@ -881,24 +884,23 @@
os.close(handle)
atexit.register(lambda : os.unlink(tmp_path))

def init_tmp_with_template():
with open(tmp_path, "wt", encoding="utf-8") as file:
# hack:
# my editor likes to strip trailing whitespace from lines.
# normally this is a good idea. but in the case of the template
# it's unhelpful.
# so, manually ensure there's a space at the end of the gh-issue line.
text = template

issue_line = ".. gh-issue:"
without_space = "\n" + issue_line + "\n"
with_space = "\n" + issue_line + " \n"
if without_space not in text:
sys.exit("Can't find gh-issue line to ensure there's a space on the end!")
text = text.replace(without_space, with_space)
file.write(text)
if gh:
try:
int(gh)
except ValueError:
error(f"blurb add --gh argument {gh} is not a valid integer!")

Check warning on line 891 in src/blurb/blurb.py

View check run for this annotation

Codecov / codecov/patch

src/blurb/blurb.py#L887-L891

Added lines #L887 - L891 were not covered by tests

if section:
if section not in sections:
error(

Check warning on line 895 in src/blurb/blurb.py

View check run for this annotation

Codecov / codecov/patch

src/blurb/blurb.py#L893-L895

Added lines #L893 - L895 were not covered by tests
f"blurb add --section argument {section!r} is not a valid section!"
" Use one of:\n" + "\n".join(sections)
)

init_tmp_with_template()
section = f".. section: {section}\n"

Check warning on line 900 in src/blurb/blurb.py

View check run for this annotation

Codecov / codecov/patch

src/blurb/blurb.py#L900

Added line #L900 was not covered by tests

with open(tmp_path, "wt", encoding="utf-8") as file:
file.write(template.format(gh=gh, section=section))

Check warning on line 903 in src/blurb/blurb.py

View check run for this annotation

Codecov / codecov/patch

src/blurb/blurb.py#L902-L903

Added lines #L902 - L903 were not covered by tests

# We need to be clever about EDITOR.
# On the one hand, it might be a legitimate path to an
Expand Down Expand Up @@ -1221,36 +1223,55 @@
kwargs = {}
for name, p in inspect.signature(fn).parameters.items():
if p.kind == inspect.Parameter.KEYWORD_ONLY:
assert isinstance(p.default, bool), "blurb command-line processing only handles boolean options"
assert isinstance(
p.default, (bool, str)
), "blurb command-line processing only handles boolean options"
kwargs[name] = p.default
short_options[name[0]] = name
long_options[name] = name

filtered_args = []
done_with_options = False
needs_oparg = None

def handle_option(s, dict):
def handle_option(s, dict, fn_name):
nonlocal needs_oparg
name = dict.get(s, None)
if not name:
sys.exit(f'blurb: Unknown option for {subcommand}: "{s}"')
kwargs[name] = not kwargs[name]
sys.exit(f'blurb: Unknown option for {fn_name}: "{s}"')

value = kwargs[name]
if isinstance(value, bool):
kwargs[name] = not value
else:
needs_oparg = name

# print(f"short_options {short_options} long_options {long_options}")
for a in args:
if needs_oparg:
kwargs[needs_oparg] = a
needs_oparg = None
continue

if done_with_options:
filtered_args.append(a)
continue

if a.startswith('-'):
if a == "--":
done_with_options = True
elif a.startswith("--"):
handle_option(a[2:], long_options)
handle_option(a[2:], long_options, fn.__name__)
else:
for s in a[1:]:
handle_option(s, short_options)
handle_option(s, short_options, fn.__name__)
continue
filtered_args.append(a)

if needs_oparg:
sys.exit(
f"Error: blurb: {fn_name} {needs_oparg} most be followed by an option argument"
)

sys.exit(fn(*filtered_args, **kwargs))
except TypeError as e:
Expand Down