Skip to content

Commit b47a607

Browse files
committed
Remove basedpyright and brew references for portability
1 parent 2f0bb2e commit b47a607

6 files changed

Lines changed: 46 additions & 97 deletions

File tree

.pre-commit-config.yaml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,3 @@ repos:
1616
pass_filenames: false
1717
always_run: true
1818

19-
- id: basedpyright
20-
name: basedpyright (Python)
21-
description: Type-check Python with basedpyright (fail on errors only, show warnings)
22-
entry: bash -c 'cd tools/block-schema-lint && out=$(uv run basedpyright scan_blocks.py 2>&1); echo "$out"; echo "$out" | tail -1 | grep -q "^0 errors" && exit 0 || exit 1'
23-
language: system
24-
files: ^tools/block-schema-lint/scan_blocks\.py$
25-
pass_filenames: false

tools/block-schema-lint/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ endif()
1010
# ── clang scanner + validation ────────────────────────────────────
1111
find_program(UV uv)
1212
if(NOT UV)
13-
message(STATUS "block-schema-lint: uv not found (install: brew install uv)")
13+
message(STATUS "block-schema-lint: uv not found (install: pip install uv or see https://docs.astral.sh/uv/)")
1414
return()
1515
endif()
1616
message(STATUS "block-schema-lint: ${UV}")
@@ -57,5 +57,5 @@ if(CUE)
5757
message(STATUS "block-schema-lint: cue schemas at ${CMAKE_CURRENT_SOURCE_DIR}/schemas")
5858
message(STATUS " Run \"cue vet -d BlockCatalog schemas/*.cue <input.json>\" to validate")
5959
else()
60-
message(STATUS "block-schema-lint: cue not found (install: brew install cue-lang/tap/cue)")
60+
message(STATUS "block-schema-lint: cue not found (see https://cuelang.org/docs/install/)")
6161
endif()

tools/block-schema-lint/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,12 @@ uv sync --dev
7878

7979
Installs dev tools into `.venv/`:
8080

81-
- `basedpyright` — type checker
81+
- `n` — type checker
8282

8383
### Type checking
8484

8585
```bash
86-
uv run basedpyright scan_blocks.py
86+
uv run n scan_blocks.py
8787
```
8888

8989
The project defines TypedDicts (`MemberDict`, `BlockDict`, `IssueDict`, etc.)
@@ -97,9 +97,9 @@ suppressed to "warning" level.
9797

9898
### macOS notes
9999

100-
The tool prefers brew's LLVM over Xcode's clang to avoid libclang/resource-dir
101-
version mismatch. It uses `-cxx-isystem /opt/homebrew/opt/llvm/include/c++/v1`
102-
to find libc++ headers.
100+
The tool dynamically discovers the LLVM installation from the detected libclang
101+
library path, avoiding libclang/resource-dir version mismatch. It uses
102+
`-cxx-isystem` with the discovered libc++ include path.
103103

104104
## Dependencies
105105

tools/block-schema-lint/pyproject.toml

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,6 @@ name = "block-schema-lint"
33
version = "0.1.0"
44
requires-python = ">=3.11"
55

6-
[dependency-groups]
7-
dev = ["basedpyright"]
8-
9-
[tool.basedpyright]
10-
# clang.cindex is a C extension with incomplete stubs — its enum values
11-
# (CursorKind.STRUCT_DECL, CursorKind.CLASS_DECL, etc.) are dynamically
12-
# generated and missing from the .pyi file. Suppress false positives.
13-
# clang.cindex stub limitations — cannot fix without upstream changes
14-
reportAttributeAccessIssue = "warning"
15-
reportUnknownMemberType = "warning"
16-
reportExplicitAny = "warning"
17-
reportUnknownVariableType = "warning"
18-
reportUnknownArgumentType = "warning"
19-
reportUnknownParameterType = "warning"
20-
21-
# Intentional Python patterns: implicit string concatenation for multi-line
22-
# strings, argparse.add_argument() return values, os.unlink() in finally blocks
23-
reportImplicitStringConcatenation = "none"
24-
reportUnusedCallResult = "none"
25-
reportUnusedFunction = "none"
26-
27-
# Genuine errors we want to catch
28-
reportMissingTypeArgument = "error"
29-
reportPossiblyUnboundVariable = "error"
30-
reportMissingImports = false # clang is a PEP 723 runtime dep, not installed in host Python
31-
reportMissingModuleSource = "none" # clang stubs via typings/, not installed in .venv
32-
336
[tool.ruff]
347
target-version = "py311"
358

tools/block-schema-lint/scan_blocks.py

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -134,23 +134,12 @@ def _find_resource_dir() -> str:
134134
"""Find clang resource directory.
135135
136136
1. LLVM_RESOURCE_DIR env var
137-
2. On macOS, prefer brew's clang over Xcode's (avoids libclang/resource-dir mismatch)
138-
3. `clang -print-resource-dir` fallback
137+
2. `clang -print-resource-dir` via PATH or common LLVM installation directories
139138
"""
140139
env = os.environ.get("LLVM_RESOURCE_DIR")
141140
if env:
142141
return env
143142

144-
# On macOS, prefer brew's clang to match brew's libclang
145-
brew_clang = "/opt/homebrew/opt/llvm/bin/clang"
146-
if IS_MACOS and os.path.isfile(brew_clang):
147-
try:
148-
result = subprocess.check_output([brew_clang, "-print-resource-dir"], text=True).strip()
149-
if result:
150-
return result
151-
except Exception:
152-
pass
153-
154143
clang_path = shutil.which("clang") or next(
155144
(shutil.which(f"clang-{v}") for v in range(99, 10, -1)),
156145
None,
@@ -198,8 +187,24 @@ def _find_libclang() -> str:
198187
candidates: list[str] = []
199188

200189
if IS_MACOS:
201-
candidates = [
202-
"/opt/homebrew/opt/llvm/lib/libclang.dylib",
190+
# Try llvm-config --libdir first (find any version with glob)
191+
llvm_config = shutil.which("llvm-config")
192+
if not llvm_config:
193+
for v in range(99, 10, -1):
194+
p = shutil.which(f"llvm-config-{v}")
195+
if p:
196+
llvm_config = p
197+
break
198+
if llvm_config:
199+
try:
200+
libdir = subprocess.check_output([llvm_config, "--libdir"], text=True).strip()
201+
libdir_p = Path(libdir)
202+
if libdir_p.is_dir():
203+
for f in sorted(libdir_p.glob("libclang*.dylib"), reverse=True):
204+
candidates.append(str(f))
205+
except Exception:
206+
pass
207+
candidates += [
203208
"/usr/local/opt/llvm/lib/libclang.dylib",
204209
"/Library/Developer/CommandLineTools/usr/lib/libclang.dylib",
205210
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libclang.dylib",
@@ -251,7 +256,7 @@ def _find_libclang() -> str:
251256

252257
import clang.cindex as ci # noqa: E402 # runtime dep from uv, not system
253258

254-
# Point clang at brew's libclang (or env-overridden path)
259+
# Point clang at libclang (env var CLANG_LIBRARY_PATH overrides auto-detection)
255260
ci.Config.set_library_file(LIBCLANG_PATH)
256261

257262
_INDEX = ci.Index.create()
@@ -339,6 +344,20 @@ def discover_project_includes(project_root: str) -> list[str]:
339344
# ── parsing ────────────────────────────────────────────────────────
340345

341346

347+
def _find_libcxx_include() -> str | None:
348+
"""Find libc++ include dir alongside the detected libclang path."""
349+
try:
350+
libclang = Path(LIBCLANG_PATH).resolve()
351+
except Exception:
352+
return None
353+
# Walk up from libclang path looking for include/c++/v1
354+
for parent in libclang.parents:
355+
candidate = parent / "include" / "c++" / "v1"
356+
if candidate.is_dir():
357+
return str(candidate)
358+
return None
359+
360+
342361
def _build_clang_args(
343362
extra_includes: list[str] | None = None,
344363
) -> list[str]:
@@ -354,12 +373,12 @@ def _build_clang_args(
354373
"-x",
355374
"c++",
356375
]
357-
# On macOS, ensure brew's libc++ headers are found (libclang may not
376+
# On macOS, ensure libc++ headers are found (libclang may not
358377
# auto-detect the SDK the same way the clang driver does).
359378
if IS_MACOS:
360-
_brew_cxx = "/opt/homebrew/opt/llvm/include/c++/v1"
361-
if os.path.isdir(_brew_cxx):
362-
args.extend(["-cxx-isystem", _brew_cxx])
379+
_llvm_cxx = _find_libcxx_include()
380+
if _llvm_cxx:
381+
args.extend(["-cxx-isystem", _llvm_cxx])
363382
for inc in itertools.chain(
364383
GR4_INCLUDE_PATHS, PROJECT_INCLUDE_PATHS, extra_includes or []
365384
):
@@ -1473,7 +1492,7 @@ def main() -> int:
14731492
print(f" {line}", file=sys.stderr)
14741493
except FileNotFoundError:
14751494
print(
1476-
"cue not found (install: brew install cue-lang/tap/cue)",
1495+
"cue not found (see https://cuelang.org/docs/install/)",
14771496
file=sys.stderr,
14781497
)
14791498
finally:

tools/block-schema-lint/uv.lock

Lines changed: 0 additions & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)