From c4811006c121c4946dca3bc7be143d59d2881809 Mon Sep 17 00:00:00 2001 From: Casey Brooks Date: Fri, 26 Dec 2025 19:04:58 +0000 Subject: [PATCH 1/2] fix(quickstart): abort on existing conf --- sphinx/cmd/quickstart.py | 17 +++++++--- tests/test_quickstart.py | 67 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/sphinx/cmd/quickstart.py b/sphinx/cmd/quickstart.py index a40a2107310..e9b7dbb230b 100644 --- a/sphinx/cmd/quickstart.py +++ b/sphinx/cmd/quickstart.py @@ -222,10 +222,19 @@ def ask_user(d: Dict) -> None: 'selected root path.'))) print(__('sphinx-quickstart will not overwrite existing Sphinx projects.')) print() - d['path'] = do_prompt(__('Please enter a new root path (or just Enter to exit)'), - '', is_path) - if not d['path']: - sys.exit(1) + while True: + new_root = do_prompt( + __('Please enter a new root path (or just Enter to exit)'), + '', allow_empty) + if not new_root: + print(bold(__('Found existing conf.py — aborting.'))) + sys.exit(1) + try: + d['path'] = is_path(new_root) + except ValidationError as err: + print(red('* ' + str(err))) + continue + break if 'sep' not in d: print() diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py index 94144ef2210..e5a7c4e8ba9 100644 --- a/tests/test_quickstart.py +++ b/tests/test_quickstart.py @@ -223,6 +223,73 @@ def test_quickstart_and_build(tempdir): assert not warnings +def test_existing_conf_enter_exits(tempdir, capsys): + tempdir.joinpath('conf.py').write_text('') + answers = { + 'Root path': tempdir, + } + qs.term_input = mock_input(answers) + d = {} + + with pytest.raises(SystemExit) as excinfo: + qs.ask_user(d) + + assert excinfo.value.code == 1 + captured = capsys.readouterr().out + assert 'Found existing conf.py — aborting.' in captured + + +def test_existing_source_conf_enter_exits(tempdir, capsys): + sourcedir = tempdir.joinpath('source') + sourcedir.makedirs(exist_ok=True) + sourcedir.joinpath('conf.py').write_text('') + answers = { + 'Root path': tempdir, + } + qs.term_input = mock_input(answers) + d = {} + + with pytest.raises(SystemExit) as excinfo: + qs.ask_user(d) + + assert excinfo.value.code == 1 + captured = capsys.readouterr().out + assert 'Found existing conf.py — aborting.' in captured + + +def test_existing_conf_accepts_new_path(tempdir): + tempdir.joinpath('conf.py').write_text('') + new_root = tempdir.joinpath('fresh') + new_root.makedirs(exist_ok=True) + answers = { + 'Root path': tempdir, + 'Please enter a new root path (or just Enter to exit)': str(new_root), + 'Project name': 'Relocated Project', + 'Author name': 'Author', + 'Project version': '1.0', + } + qs.term_input = mock_input(answers) + d = {} + qs.ask_user(d) + assert d['path'] == str(new_root) + + qs.generate(d) + + assert (new_root / 'conf.py').isfile() + assert (new_root / 'index.rst').isfile() + assert sorted(tempdir.listdir()) == ['conf.py', 'fresh'] + + +def test_quickstart_quiet_mode_existing_conf(tempdir, capsys): + tempdir.joinpath('conf.py').write_text('') + + result = qs.main(['-q', '-p', 'proj', '-a', 'auth', str(tempdir)]) + + assert result == 1 + captured = capsys.readouterr().out + assert 'Error: specified path is not a directory' in captured + + def test_default_filename(tempdir): answers = { 'Root path': tempdir, From 179369c36ccb5e2e9b75de90ffdf63dd1cfbbbaf Mon Sep 17 00:00:00 2001 From: Casey Brooks Date: Fri, 26 Dec 2025 19:15:13 +0000 Subject: [PATCH 2/2] test(quickstart): normalize directory listing --- tests/test_quickstart.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py index e5a7c4e8ba9..9ceb6c85433 100644 --- a/tests/test_quickstart.py +++ b/tests/test_quickstart.py @@ -8,6 +8,7 @@ :license: BSD, see LICENSE for details. """ +import os import time from io import StringIO @@ -277,7 +278,7 @@ def test_existing_conf_accepts_new_path(tempdir): assert (new_root / 'conf.py').isfile() assert (new_root / 'index.rst').isfile() - assert sorted(tempdir.listdir()) == ['conf.py', 'fresh'] + assert sorted(os.path.basename(entry) for entry in tempdir.listdir()) == ['conf.py', 'fresh'] def test_quickstart_quiet_mode_existing_conf(tempdir, capsys):