diff --git a/release.py b/release.py index 35b14093..3dcc48af 100755 --- a/release.py +++ b/release.py @@ -291,6 +291,20 @@ def run_cmd( error(f"{cmd} failed") +def ask_question(question: str) -> bool: + answer = "" + print(question) + while answer not in ("yes", "no"): + answer = input("Enter yes or no: ") + if answer == "yes": + return True + elif answer == "no": + return False + else: + print("Please enter yes or no.") + return True + + readme_re = re.compile(r"This is Python version 3\.\d").match @@ -763,7 +777,7 @@ def make_tag(tag: Tag, *, sign_gpg: bool = True) -> bool: print("There are still reST files in NEWS.d/next/...") if not good_files: print(f"There is no Misc/NEWS.d/{tag}.rst file.") - if input("Are you sure you want to tag? (y/n) > ") not in ("y", "yes"): + if not ask_question("Are you sure you want to tag?"): print("Aborting.") return False @@ -774,10 +788,7 @@ def make_tag(tag: Tag, *, sign_gpg: bool = True) -> bool: != f"branch-{tag}" ): print("It doesn't look like you're on the correct branch.") - if input("Are you sure you want to tag? (y/n) > ").lower() not in ( - "y", - "yes", - ): + if not ask_question("Are you sure you want to tag?"): print("Aborting.") return False diff --git a/run_release.py b/run_release.py index b346af37..b69b2d2e 100755 --- a/run_release.py +++ b/run_release.py @@ -36,7 +36,7 @@ import sbom import update_version_next from buildbotapi import BuildBotAPI, Builder -from release import ReleaseShelf, Tag, Task +from release import ReleaseShelf, Tag, Task, ask_question API_KEY_REGEXP = re.compile(r"(?P\w+):(?P\w+)") RELEASE_REGEXP = re.compile( @@ -287,20 +287,6 @@ def run(self) -> None: print(f"Congratulations, Python {self.db['release']} is released 🎉🎉🎉") -def ask_question(question: str) -> bool: - answer = "" - print(question) - while answer not in ("yes", "no"): - answer = input("Enter yes or no: ") - if answer == "yes": - return True - elif answer == "no": - return False - else: - print("Please enter yes or no.") - return True - - @contextlib.contextmanager def cd(path: Path) -> Iterator[None]: current_path = os.getcwd() diff --git a/tests/test_release.py b/tests/test_release.py index c72289ae..96d7bc68 100644 --- a/tests/test_release.py +++ b/tests/test_release.py @@ -46,6 +46,38 @@ def test_task(mocker: MockerFixture) -> None: my_task.assert_called_once_with(cast(release.ReleaseShelf, db)) +@pytest.mark.parametrize( + ["test_inputs", "expected"], + [ + (["yes"], True), + (["no"], False), + (["maybe", "yes"], True), + (["maybe", "no"], False), + (["", "nope", "y", "yes"], True), + (["", "nope", "n", "no"], False), + ], +) +def test_ask_question( + mocker: MockerFixture, + capsys: pytest.CaptureFixture[str], + test_inputs: list[str], + expected: bool, +) -> None: + # Arrange + mocker.patch("release.input", side_effect=test_inputs) + + # Act + result = release.ask_question("Do you want to proceed?") + + # Assert + assert result is expected + captured = capsys.readouterr() + assert "Do you want to proceed?" in captured.out + # All inputs except the last are invalid + invalid_count = len(test_inputs) - 1 + assert captured.out.count("Please enter yes or no.") == invalid_count + + def test_tweak_patchlevel(tmp_path: Path) -> None: # Arrange tag = release.Tag("3.14.0b2")