Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
11 changes: 11 additions & 0 deletions tests/tools/test_generate_cmake_presets_no_prompt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import pytest

import tools.generate_cmake_presets as presets


def test_no_prompt_fails_when_cuda_compiler_is_missing(monkeypatch):
monkeypatch.setattr(presets, "CUDA_HOME", None)
monkeypatch.setattr(presets, "which", lambda name: None)

with pytest.raises(RuntimeError, match="--no-prompt"):
presets.generate_presets(no_prompt=True)
18 changes: 16 additions & 2 deletions tools/generate_cmake_presets.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ def get_cpu_cores():
return multiprocessing.cpu_count()


def generate_presets(output_path="CMakeUserPresets.json", force_overwrite=False):
def generate_presets(
output_path="CMakeUserPresets.json",
force_overwrite=False,
no_prompt=False,
):
Comment on lines +30 to +34

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

When --no-prompt is enabled, the script should run completely non-interactively. However, if the output file (e.g., CMakeUserPresets.json) already exists and --force-overwrite is not specified, the script will still block on the interactive input() prompt on line 160. In non-interactive environments like CI/CD pipelines, this will cause the script to hang or crash with an EOFError.

To prevent this, we should check if the file exists and raise a RuntimeError early when no_prompt is True and force_overwrite is False.

Suggested change
def generate_presets(
output_path="CMakeUserPresets.json",
force_overwrite=False,
no_prompt=False,
):
def generate_presets(
output_path="CMakeUserPresets.json",
force_overwrite=False,
no_prompt=False,
):
if no_prompt and not force_overwrite:
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
if os.path.exists(os.path.join(project_root, output_path)):
raise RuntimeError(
f"File '{output_path}' already exists. Use --force-overwrite "
"or run without --no-prompt to overwrite it."
)

"""Generates the CMakeUserPresets.json file."""

print("Attempting to detect your system configuration...")
Expand All @@ -46,6 +50,11 @@ def generate_presets(output_path="CMakeUserPresets.json", force_overwrite=False)
print(f"Found nvcc in PATH: {nvcc_path}")

if not nvcc_path:
if no_prompt:
raise RuntimeError(
"Could not automatically find 'nvcc'. Set CUDA_HOME, add nvcc "
"to PATH, or run without --no-prompt to enter it interactively."
)
nvcc_path_input = input(
"Could not automatically find 'nvcc'. Please provide the full "
"path to nvcc (e.g., /usr/local/cuda/bin/nvcc): "
Expand Down Expand Up @@ -176,6 +185,11 @@ def generate_presets(output_path="CMakeUserPresets.json", force_overwrite=False)
action="store_true",
help="Force overwrite existing CMakeUserPresets.json without prompting",
)
parser.add_argument(
"--no-prompt",
action="store_true",
help="Fail instead of prompting when required tools cannot be detected",
)

args = parser.parse_args()
generate_presets(force_overwrite=args.force_overwrite)
generate_presets(force_overwrite=args.force_overwrite, no_prompt=args.no_prompt)