Skip to content

Commit db4125c

Browse files
committed
Refactor git describe command: use shim/runner pattern
Replace _validate_git_tags_available() functions with DRY shim/runner pattern: - Create scripts/git_describe_command_runner.py: shared implementation - Create git_describe_command_shim.py in each package: thin wrappers that check for scripts/ directory and delegate to the runner - Update pyproject.toml files to use git_describe_command_shim.py - Remove all three copies of _validate_git_tags_available() from build_hooks.py and setup.py Benefits: - DRY: single implementation in scripts/ - Portable: Python is always available (no git in PATH requirement) - Clear error messages: shims check for scripts/ and provide context - No import-time validation: only runs when setuptools-scm calls it - Cleaner code: cuda_pathfinder/build_hooks.py is now just 13 lines All three shim files are identical copies and must be kept in sync.
1 parent 0dadc89 commit db4125c

12 files changed

Lines changed: 288 additions & 177 deletions

.pre-commit-config.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ repos:
3131
- https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl
3232
exclude: '.*pixi\.lock'
3333

34+
- id: check-git-describe-command-shim-code
35+
name: Check git_describe_command_shim.py files are identical
36+
entry: python ./toolshed/check_git_describe_command_shim_code.py
37+
language: python
38+
files: '^(cuda_bindings|cuda_core|cuda_pathfinder)/git_describe_command_shim\.py$'
39+
3440
- id: no-markdown-in-docs-source
3541
name: Prevent markdown files in docs/source directories
3642
entry: bash -c
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env python3
2+
3+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4+
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
5+
6+
"""Shim that calls scripts/git_describe_command_runner.py if we're in a git repo.
7+
8+
This shim checks if we're in a git repository (by looking for scripts/ directory)
9+
and delegates to the shared git_describe_command_runner.py script.
10+
11+
NOTE:
12+
- cuda_bindings/git_describe_command_shim.py
13+
- cuda_core/git_describe_command_shim.py
14+
- cuda_pathfinder/git_describe_command_shim.py
15+
are EXACT COPIES, PLEASE KEEP ALL FILES IN SYNC.
16+
"""
17+
18+
import subprocess
19+
import sys
20+
from pathlib import Path
21+
22+
if len(sys.argv) < 2:
23+
print("Usage: python git_describe_command_shim.py <tag_pattern>", file=sys.stderr) # noqa: T201
24+
sys.exit(1)
25+
26+
tag_pattern = sys.argv[1]
27+
28+
# Find repo root (go up from package directory)
29+
package_dir = Path(__file__).parent
30+
repo_root = package_dir.parent
31+
scripts_dir = repo_root / "scripts"
32+
git_describe_script = scripts_dir / "git_describe_command_runner.py"
33+
34+
# Check if we're in a git repo (scripts/ should exist)
35+
if not scripts_dir.exists():
36+
print("ERROR: scripts/ directory not found.", file=sys.stderr) # noqa: T201
37+
print("This indicates we're not in a git repository.", file=sys.stderr) # noqa: T201
38+
print("git_describe_command_shim should not be called in this context.", file=sys.stderr) # noqa: T201
39+
sys.exit(1)
40+
41+
# Check if the shared script exists
42+
if not git_describe_script.exists():
43+
print(f"ERROR: {git_describe_script} not found.", file=sys.stderr) # noqa: T201
44+
print("The git_describe_command_runner script is missing.", file=sys.stderr) # noqa: T201
45+
sys.exit(1)
46+
47+
# Call the shared script (from repo root so it can find .git)
48+
result = subprocess.run( # noqa: S603
49+
[sys.executable, str(git_describe_script), tag_pattern],
50+
cwd=repo_root,
51+
timeout=10,
52+
)
53+
54+
sys.exit(result.returncode)

cuda_bindings/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,4 @@ root = ".."
8282
version_file = "cuda/bindings/_version.py"
8383
# We deliberately do not want to include the version suffixes (a/b/rc) in cuda-bindings versioning
8484
tag_regex = "^(?P<version>v\\d+\\.\\d+\\.\\d+)"
85-
git_describe_command = ["git", "describe", "--dirty", "--tags", "--long", "--match", "v*[0-9]*"]
85+
git_describe_command = ["python", "cuda_bindings/git_describe_command_shim.py", "v*[0-9]*"]

cuda_bindings/setup.py

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

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

cuda_core/build_hooks.py

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -86,63 +86,7 @@ def _determine_cuda_major_version() -> str:
8686
_extensions = None
8787

8888

89-
# Please keep the implementations in cuda-pathfinder, cuda-bindings, cuda-core in sync.
90-
def _validate_git_tags_available(tag_pattern: str) -> None:
91-
"""Verify that git tags are available for setuptools-scm version detection.
92-
93-
Args:
94-
tag_pattern: Git tag pattern to match (e.g., "v*[0-9]*")
95-
"""
96-
import subprocess
97-
98-
# Check if git is available
99-
try:
100-
subprocess.run(["git", "--version"], capture_output=True, check=True, timeout=5) # noqa: S607
101-
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
102-
raise RuntimeError(
103-
"Git is not available in PATH. setuptools-scm requires git to determine version from tags.\n"
104-
"Please ensure git is installed and available in your PATH."
105-
) from None
106-
107-
# Find git repository root (setuptools_scm root='..')
108-
repo_root = os.path.dirname(os.path.dirname(__file__))
109-
110-
# Check if git describe works (this is what setuptools-scm uses)
111-
try:
112-
result = subprocess.run( # noqa: S603
113-
["git", "describe", "--tags", "--long", "--match", tag_pattern], # noqa: S607
114-
cwd=repo_root,
115-
capture_output=True,
116-
text=True,
117-
timeout=5,
118-
)
119-
if result.returncode != 0:
120-
raise RuntimeError(
121-
f"git describe failed! This means setuptools-scm will fall back to version '0.1.x'.\n"
122-
f"\n"
123-
f"Error: {result.stderr.strip()}\n"
124-
f"\n"
125-
f"This usually means:\n"
126-
f" 1. Git tags are not fetched (run: git fetch --tags)\n"
127-
f" 2. Running from wrong directory (setuptools_scm root='..')\n"
128-
f" 3. No matching tags found\n"
129-
f"\n"
130-
f"To fix:\n"
131-
f" git fetch --tags\n"
132-
f"\n"
133-
f"To debug, run: git describe --tags --long --match '{tag_pattern}'"
134-
) from None
135-
except subprocess.TimeoutExpired:
136-
raise RuntimeError(
137-
"git describe command timed out. This may indicate git repository issues.\n"
138-
"Please check your git repository state."
139-
) from None
140-
141-
14289
def _build_cuda_core():
143-
# Validate git tags are available (fail early before setuptools-scm runs)
144-
_validate_git_tags_available("cuda-core-v*[0-9]*")
145-
14690
# Customizing the build hooks is needed because we must defer cythonization until cuda-bindings,
14791
# now a required build-time dependency that's dynamically installed via the other hook below,
14892
# is installed. Otherwise, cimport any cuda.bindings modules would fail!
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env python3
2+
3+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4+
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
5+
6+
"""Shim that calls scripts/git_describe_command_runner.py if we're in a git repo.
7+
8+
This shim checks if we're in a git repository (by looking for scripts/ directory)
9+
and delegates to the shared git_describe_command_runner.py script.
10+
11+
NOTE:
12+
- cuda_bindings/git_describe_command_shim.py
13+
- cuda_core/git_describe_command_shim.py
14+
- cuda_pathfinder/git_describe_command_shim.py
15+
are EXACT COPIES, PLEASE KEEP ALL FILES IN SYNC.
16+
"""
17+
18+
import subprocess
19+
import sys
20+
from pathlib import Path
21+
22+
if len(sys.argv) < 2:
23+
print("Usage: python git_describe_command_shim.py <tag_pattern>", file=sys.stderr) # noqa: T201
24+
sys.exit(1)
25+
26+
tag_pattern = sys.argv[1]
27+
28+
# Find repo root (go up from package directory)
29+
package_dir = Path(__file__).parent
30+
repo_root = package_dir.parent
31+
scripts_dir = repo_root / "scripts"
32+
git_describe_script = scripts_dir / "git_describe_command_runner.py"
33+
34+
# Check if we're in a git repo (scripts/ should exist)
35+
if not scripts_dir.exists():
36+
print("ERROR: scripts/ directory not found.", file=sys.stderr) # noqa: T201
37+
print("This indicates we're not in a git repository.", file=sys.stderr) # noqa: T201
38+
print("git_describe_command_shim should not be called in this context.", file=sys.stderr) # noqa: T201
39+
sys.exit(1)
40+
41+
# Check if the shared script exists
42+
if not git_describe_script.exists():
43+
print(f"ERROR: {git_describe_script} not found.", file=sys.stderr) # noqa: T201
44+
print("The git_describe_command_runner script is missing.", file=sys.stderr) # noqa: T201
45+
sys.exit(1)
46+
47+
# Call the shared script (from repo root so it can find .git)
48+
result = subprocess.run( # noqa: S603
49+
[sys.executable, str(git_describe_script), tag_pattern],
50+
cwd=repo_root,
51+
timeout=10,
52+
)
53+
54+
sys.exit(result.returncode)

cuda_core/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ root = ".."
8383
version_file = "cuda/core/_version.py"
8484
# We deliberately do not want to include the version suffixes (a/b/rc) in cuda-core versioning
8585
tag_regex = "^cuda-core-(?P<version>v\\d+\\.\\d+\\.\\d+)"
86-
git_describe_command = ["git", "describe", "--dirty", "--tags", "--long", "--match", "cuda-core-v*[0-9]*"]
86+
git_describe_command = ["python", "cuda_core/git_describe_command_shim.py", "cuda-core-v*[0-9]*"]
8787

8888
[tool.cibuildwheel]
8989
skip = "*-musllinux_*"

cuda_pathfinder/build_hooks.py

Lines changed: 1 addition & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -9,64 +9,5 @@
99
hooks are delegated to setuptools.build_meta.
1010
"""
1111

12-
import os
13-
14-
15-
# Please keep the implementations in cuda-pathfinder, cuda-bindings, cuda-core in sync.
16-
def _validate_git_tags_available(tag_pattern: str) -> None:
17-
"""Verify that git tags are available for setuptools-scm version detection.
18-
19-
Args:
20-
tag_pattern: Git tag pattern to match (e.g., "v*[0-9]*")
21-
"""
22-
import subprocess
23-
24-
# Check if git is available
25-
try:
26-
subprocess.run(["git", "--version"], capture_output=True, check=True, timeout=5) # noqa: S607
27-
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
28-
raise RuntimeError(
29-
"Git is not available in PATH. setuptools-scm requires git to determine version from tags.\n"
30-
"Please ensure git is installed and available in your PATH."
31-
) from None
32-
33-
# Find git repository root (setuptools_scm root='..')
34-
repo_root = os.path.dirname(os.path.dirname(__file__))
35-
36-
# Check if git describe works (this is what setuptools-scm uses)
37-
try:
38-
result = subprocess.run( # noqa: S603
39-
["git", "describe", "--tags", "--long", "--match", tag_pattern], # noqa: S607
40-
cwd=repo_root,
41-
capture_output=True,
42-
text=True,
43-
timeout=5,
44-
)
45-
if result.returncode != 0:
46-
raise RuntimeError(
47-
f"git describe failed! This means setuptools-scm will fall back to version '0.1.x'.\n"
48-
f"\n"
49-
f"Error: {result.stderr.strip()}\n"
50-
f"\n"
51-
f"This usually means:\n"
52-
f" 1. Git tags are not fetched (run: git fetch --tags)\n"
53-
f" 2. Running from wrong directory (setuptools_scm root='..')\n"
54-
f" 3. No matching tags found\n"
55-
f"\n"
56-
f"To fix:\n"
57-
f" git fetch --tags\n"
58-
f"\n"
59-
f"To debug, run: git describe --tags --long --match '{tag_pattern}'"
60-
) from None
61-
except subprocess.TimeoutExpired:
62-
raise RuntimeError(
63-
"git describe command timed out. This may indicate git repository issues.\n"
64-
"Please check your git repository state."
65-
) from None
66-
67-
68-
# Validate tags before any build operations
69-
_validate_git_tags_available("cuda-pathfinder-v*[0-9]*")
70-
7112
# Import and re-export all PEP 517 hooks from setuptools.build_meta
72-
from setuptools.build_meta import * # noqa: F403, E402
13+
from setuptools.build_meta import * # noqa: F403
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env python3
2+
3+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4+
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
5+
6+
"""Shim that calls scripts/git_describe_command_runner.py if we're in a git repo.
7+
8+
This shim checks if we're in a git repository (by looking for scripts/ directory)
9+
and delegates to the shared git_describe_command_runner.py script.
10+
11+
NOTE:
12+
- cuda_bindings/git_describe_command_shim.py
13+
- cuda_core/git_describe_command_shim.py
14+
- cuda_pathfinder/git_describe_command_shim.py
15+
are EXACT COPIES, PLEASE KEEP ALL FILES IN SYNC.
16+
"""
17+
18+
import subprocess
19+
import sys
20+
from pathlib import Path
21+
22+
if len(sys.argv) < 2:
23+
print("Usage: python git_describe_command_shim.py <tag_pattern>", file=sys.stderr) # noqa: T201
24+
sys.exit(1)
25+
26+
tag_pattern = sys.argv[1]
27+
28+
# Find repo root (go up from package directory)
29+
package_dir = Path(__file__).parent
30+
repo_root = package_dir.parent
31+
scripts_dir = repo_root / "scripts"
32+
git_describe_script = scripts_dir / "git_describe_command_runner.py"
33+
34+
# Check if we're in a git repo (scripts/ should exist)
35+
if not scripts_dir.exists():
36+
print("ERROR: scripts/ directory not found.", file=sys.stderr) # noqa: T201
37+
print("This indicates we're not in a git repository.", file=sys.stderr) # noqa: T201
38+
print("git_describe_command_shim should not be called in this context.", file=sys.stderr) # noqa: T201
39+
sys.exit(1)
40+
41+
# Check if the shared script exists
42+
if not git_describe_script.exists():
43+
print(f"ERROR: {git_describe_script} not found.", file=sys.stderr) # noqa: T201
44+
print("The git_describe_command_runner script is missing.", file=sys.stderr) # noqa: T201
45+
sys.exit(1)
46+
47+
# Call the shared script (from repo root so it can find .git)
48+
result = subprocess.run( # noqa: S603
49+
[sys.executable, str(git_describe_script), tag_pattern],
50+
cwd=repo_root,
51+
timeout=10,
52+
)
53+
54+
sys.exit(result.returncode)

cuda_pathfinder/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ root = ".."
7878
version_file = "cuda/pathfinder/_version.py"
7979
# We deliberately do not want to include the version suffixes (a/b/rc) in cuda-pathfinder versioning
8080
tag_regex = "^cuda-pathfinder-(?P<version>v\\d+\\.\\d+\\.\\d+)"
81-
git_describe_command = [ "git", "describe", "--dirty", "--tags", "--long", "--match", "cuda-pathfinder-v*[0-9]*" ]
81+
git_describe_command = ["python", "cuda_pathfinder/git_describe_command_shim.py", "cuda-pathfinder-v*[0-9]*"]
8282

8383
[tool.pytest.ini_options]
8484
addopts = "--showlocals"

0 commit comments

Comments
 (0)