Skip to content

Commit f6200ec

Browse files
committed
Validate git tags availability before setuptools-scm runs
Add pre-build validation that checks git tag availability directly to ensure builds fail early with clear error messages before setuptools-scm silently falls back to version '0.1.x'. Changes: - cuda_bindings/setup.py: Validate tags at import time (before setuptools-scm) - cuda_core/build_hooks.py: Validate tags in _build_cuda_core() before building - cuda_pathfinder/build_hooks.py: New custom build backend that validates tags before delegating to setuptools.build_meta - cuda_pathfinder/pyproject.toml: Configure custom build backend Benefits: - Fails immediately when pip install -e . is run, not during build - More direct: tests what setuptools-scm actually needs (git describe) - Cleaner: no dependency on generated files - Better UX: clear error messages with actionable fixes Error messages include: - Clear explanation of the problem - The actual git error output - Common causes (tags not fetched, wrong directory, etc.) - Package-specific debugging commands - Actionable fix: git fetch --tags
1 parent f8dddb3 commit f6200ec

4 files changed

Lines changed: 178 additions & 1 deletion

File tree

cuda_bindings/setup.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,69 @@
2323
from setuptools.command.editable_wheel import _TopLevelFinder, editable_wheel
2424
from setuptools.extension import Extension
2525

26+
27+
# ----------------------------------------------------------------------
28+
# Validate git tags are available (fail early before setuptools-scm runs)
29+
def _validate_git_tags_available():
30+
"""Verify that git tags are available for setuptools-scm version detection."""
31+
import subprocess
32+
33+
# Check if git is available
34+
try:
35+
subprocess.run(["git", "--version"], capture_output=True, check=True, timeout=5) # noqa: S607
36+
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
37+
raise RuntimeError(
38+
"Git is not available in PATH. setuptools-scm requires git to determine version from tags.\n"
39+
"Please ensure git is installed and available in your PATH."
40+
) from None
41+
42+
# Check if we're in a git repository
43+
try:
44+
subprocess.run(
45+
["git", "rev-parse", "--git-dir"], # noqa: S607
46+
capture_output=True,
47+
check=True,
48+
timeout=5,
49+
)
50+
except subprocess.CalledProcessError:
51+
raise RuntimeError(
52+
"Not in a git repository. setuptools-scm requires git tags to determine version.\n"
53+
"Please run this from within the cuda-python git repository."
54+
) from None
55+
56+
# Check if git describe works (this is what setuptools-scm uses)
57+
try:
58+
result = subprocess.run(
59+
["git", "describe", "--tags", "--long", "--match", "v*[0-9]*"], # noqa: S607
60+
capture_output=True,
61+
text=True,
62+
timeout=5,
63+
)
64+
if result.returncode != 0:
65+
raise RuntimeError(
66+
f"git describe failed! This means setuptools-scm will fall back to version '0.1.x'.\n"
67+
f"\n"
68+
f"Error: {result.stderr.strip()}\n"
69+
f"\n"
70+
f"This usually means:\n"
71+
f" 1. Git tags are not fetched (run: git fetch --tags)\n"
72+
f" 2. Running from wrong directory (setuptools_scm root='..')\n"
73+
f" 3. No matching tags found\n"
74+
f"\n"
75+
f"To fix:\n"
76+
f" git fetch --tags\n"
77+
f"\n"
78+
f"To debug, run: git describe --tags --long --match 'v*[0-9]*'"
79+
) from None
80+
except subprocess.TimeoutExpired:
81+
raise RuntimeError(
82+
"git describe command timed out. This may indicate git repository issues.\n"
83+
"Please check your git repository state."
84+
) from None
85+
86+
87+
_validate_git_tags_available()
88+
2689
# ----------------------------------------------------------------------
2790
# Fetch configuration options
2891

cuda_core/build_hooks.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,52 @@ def _determine_cuda_major_version() -> str:
8686

8787

8888
def _build_cuda_core():
89+
# Validate git tags are available (fail early before setuptools-scm runs)
90+
import subprocess
91+
92+
# Check if git is available
93+
try:
94+
subprocess.run(["git", "--version"], capture_output=True, check=True, timeout=5) # noqa: S607
95+
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
96+
raise RuntimeError(
97+
"Git is not available in PATH. setuptools-scm requires git to determine version from tags.\n"
98+
"Please ensure git is installed and available in your PATH."
99+
) from None
100+
101+
# Find git repository root (setuptools_scm root='..')
102+
repo_root = os.path.dirname(os.path.dirname(__file__))
103+
104+
# Check if git describe works (this is what setuptools-scm uses)
105+
try:
106+
result = subprocess.run(
107+
["git", "describe", "--tags", "--long", "--match", "cuda-core-v*[0-9]*"], # noqa: S607
108+
cwd=repo_root,
109+
capture_output=True,
110+
text=True,
111+
timeout=5,
112+
)
113+
if result.returncode != 0:
114+
raise RuntimeError(
115+
f"git describe failed! This means setuptools-scm will fall back to version '0.1.x'.\n"
116+
f"\n"
117+
f"Error: {result.stderr.strip()}\n"
118+
f"\n"
119+
f"This usually means:\n"
120+
f" 1. Git tags are not fetched (run: git fetch --tags)\n"
121+
f" 2. Running from wrong directory (setuptools_scm root='..')\n"
122+
f" 3. No matching tags found\n"
123+
f"\n"
124+
f"To fix:\n"
125+
f" git fetch --tags\n"
126+
f"\n"
127+
f"To debug, run: git describe --tags --long --match 'cuda-core-v*[0-9]*'"
128+
) from None
129+
except subprocess.TimeoutExpired:
130+
raise RuntimeError(
131+
"git describe command timed out. This may indicate git repository issues.\n"
132+
"Please check your git repository state."
133+
) from None
134+
89135
# Customizing the build hooks is needed because we must defer cythonization until cuda-bindings,
90136
# now a required build-time dependency that's dynamically installed via the other hook below,
91137
# is installed. Otherwise, cimport any cuda.bindings modules would fail!

cuda_pathfinder/build_hooks.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
"""
5+
Custom build hooks for cuda-pathfinder.
6+
7+
This module validates git tags are available before setuptools-scm runs,
8+
ensuring proper version detection during pip install. All PEP 517 build
9+
hooks are delegated to setuptools.build_meta.
10+
"""
11+
12+
import os
13+
import subprocess
14+
15+
16+
# Validate tags before importing setuptools.build_meta (which will use setuptools-scm)
17+
def _validate_git_tags_available():
18+
"""Verify that git tags are available for setuptools-scm version detection."""
19+
# Check if git is available
20+
try:
21+
subprocess.run(["git", "--version"], capture_output=True, check=True, timeout=5) # noqa: S607
22+
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
23+
raise RuntimeError(
24+
"Git is not available in PATH. setuptools-scm requires git to determine version from tags.\n"
25+
"Please ensure git is installed and available in your PATH."
26+
) from None
27+
28+
# Find git repository root (setuptools_scm root='..')
29+
repo_root = os.path.dirname(os.path.dirname(__file__))
30+
31+
# Check if git describe works (this is what setuptools-scm uses)
32+
try:
33+
result = subprocess.run(
34+
["git", "describe", "--tags", "--long", "--match", "cuda-pathfinder-v*[0-9]*"], # noqa: S607
35+
cwd=repo_root,
36+
capture_output=True,
37+
text=True,
38+
timeout=5,
39+
)
40+
if result.returncode != 0:
41+
raise RuntimeError(
42+
f"git describe failed! This means setuptools-scm will fall back to version '0.1.x'.\n"
43+
f"\n"
44+
f"Error: {result.stderr.strip()}\n"
45+
f"\n"
46+
f"This usually means:\n"
47+
f" 1. Git tags are not fetched (run: git fetch --tags)\n"
48+
f" 2. Running from wrong directory (setuptools_scm root='..')\n"
49+
f" 3. No matching tags found\n"
50+
f"\n"
51+
f"To fix:\n"
52+
f" git fetch --tags\n"
53+
f"\n"
54+
f"To debug, run: git describe --tags --long --match 'cuda-pathfinder-v*[0-9]*'"
55+
) from None
56+
except subprocess.TimeoutExpired:
57+
raise RuntimeError(
58+
"git describe command timed out. This may indicate git repository issues.\n"
59+
"Please check your git repository state."
60+
) from None
61+
62+
63+
# Validate tags before any build operations
64+
_validate_git_tags_available()
65+
66+
# Import and re-export all PEP 517 hooks from setuptools.build_meta
67+
from setuptools.build_meta import * # noqa: F403, E402

cuda_pathfinder/pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ requires = [
7070
"setuptools_scm[simple]>=8",
7171
"wheel"
7272
]
73-
build-backend = "setuptools.build_meta"
73+
build-backend = "build_hooks"
74+
backend-path = ["."]
7475

7576
[tool.setuptools_scm]
7677
root = ".."

0 commit comments

Comments
 (0)