mirror of
https://github.com/safishamsi/graphify.git
synced 2026-10-16 17:09:17 +00:00
feat(extract): include Verilog header files
Register .vh with the existing Verilog detection and extraction paths, including incremental and watch coverage. Refs #3749 AI-Assisted-By: OpenAI Codex
This commit is contained in:
1 parent
ef4450d9c2
commit
3b74b8ad3d
6 files changed
+64
-2
No files matched your search
@@ -344,7 +344,7 @@ To remove graphify from all platforms at once: `graphify uninstall` (add `--purg
|
||||
|
||||
| Type | Extensions |
|
||||
|------|-----------|
|
||||
| Code (37 tree-sitter grammars) | `.py .ts .mts .cts .js .jsx .tsx .mjs .go .rs .java .c .cpp .cc .cxx .h .hpp .cu .cuh .metal .rb .cs .kt .kts .scala .php .swift .lua .luau .toc .zig .ps1 .psm1 .psd1 .ex .exs .m .mm .ml .mli .jl .vue .svelte .astro .groovy .gradle .dart .v .sv .svh .sql .f .f90 .f95 .f03 .f08 .pas .pp .dpr .dpk .lpr .inc .dfm .lfm .lpk .sh .bash .json .dm .dme .dmi .dmm .dmf .sln .slnx .csproj .fsproj .vbproj .xaml .razor .cshtml` (`.dm`/`.dme` requires `uv tool install graphifyy[dm]`, `.ml`/`.mli` requires `uv tool install graphifyy[ocaml]`; `.mts`/`.cts` reuse the TypeScript grammar, `.cc`/`.cxx` and CUDA `.cu`/`.cuh` and Metal `.metal` reuse the C++ grammar) |
|
||||
| Code (37 tree-sitter grammars) | `.py .ts .mts .cts .js .jsx .tsx .mjs .go .rs .java .c .cpp .cc .cxx .h .hpp .cu .cuh .metal .rb .cs .kt .kts .scala .php .swift .lua .luau .toc .zig .ps1 .psm1 .psd1 .ex .exs .m .mm .ml .mli .jl .vue .svelte .astro .groovy .gradle .dart .v .sv .svh .vh .sql .f .f90 .f95 .f03 .f08 .pas .pp .dpr .dpk .lpr .inc .dfm .lfm .lpk .sh .bash .json .dm .dme .dmi .dmm .dmf .sln .slnx .csproj .fsproj .vbproj .xaml .razor .cshtml` (`.dm`/`.dme` requires `uv tool install graphifyy[dm]`, `.ml`/`.mli` requires `uv tool install graphifyy[ocaml]`; `.mts`/`.cts` reuse the TypeScript grammar, `.cc`/`.cxx` and CUDA `.cu`/`.cuh` and Metal `.metal` reuse the C++ grammar) |
|
||||
| Salesforce Apex | `.cls .trigger` (regex-based; classes, interfaces, enums, methods, triggers, SOQL/DML edges) |
|
||||
| Terraform / HCL | `.tf .tfvars .hcl` (requires `uv tool install graphifyy[terraform]`) |
|
||||
| OCaml | `.ml .mli` (requires `uv tool install graphifyy[ocaml]`) |
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ _MANIFEST_PATH = str(out_path("manifest.json"))
|
||||
_MTIME_COARSE_S = 2.0
|
||||
_MTIME_SUBSECOND_S = 0.05
|
||||
|
||||
CODE_EXTENSIONS = {'.py', '.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs', '.ejs', '.ets', '.go', '.rs', '.vb', '.cbl', '.cob', '.cobol', '.cpy', '.java', '.groovy', '.gradle', '.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.cu', '.cuh', '.metal', '.rb', '.rake', '.swift', '.kt', '.kts', '.cs', '.scala', '.php', '.lua', '.luau', '.toc', '.zig', '.ps1', '.psm1', '.psd1', '.ex', '.exs', '.m', '.mm', '.ml', '.mli', '.jl', '.vue', '.svelte', '.astro', '.dart', '.v', '.sv', '.svh', '.sql', '.r', '.f', '.F', '.f90', '.F90', '.f95', '.F95', '.f03', '.F03', '.f08', '.F08', '.pas', '.pp', '.dpr', '.dpk', '.lpr', '.inc', '.dfm', '.lfm', '.lpk', '.sh', '.bash', '.json', '.tf', '.tfvars', '.hcl', '.dm', '.dme', '.dmi', '.dmm', '.dmf', '.sln', '.slnx', '.csproj', '.fsproj', '.vbproj', '.xaml', '.razor', '.cshtml', '.cls', '.trigger', '.lisp', '.cl', '.lsp', '.asd', '.robot', '.resource', '.sol', '.erl', '.hrl', '.escript'}
|
||||
CODE_EXTENSIONS = {'.py', '.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs', '.ejs', '.ets', '.go', '.rs', '.vb', '.cbl', '.cob', '.cobol', '.cpy', '.java', '.groovy', '.gradle', '.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.cu', '.cuh', '.metal', '.rb', '.rake', '.swift', '.kt', '.kts', '.cs', '.scala', '.php', '.lua', '.luau', '.toc', '.zig', '.ps1', '.psm1', '.psd1', '.ex', '.exs', '.m', '.mm', '.ml', '.mli', '.jl', '.vue', '.svelte', '.astro', '.dart', '.v', '.sv', '.svh', '.vh', '.sql', '.r', '.f', '.F', '.f90', '.F90', '.f95', '.F95', '.f03', '.F03', '.f08', '.F08', '.pas', '.pp', '.dpr', '.dpk', '.lpr', '.inc', '.dfm', '.lfm', '.lpk', '.sh', '.bash', '.json', '.tf', '.tfvars', '.hcl', '.dm', '.dme', '.dmi', '.dmm', '.dmf', '.sln', '.slnx', '.csproj', '.fsproj', '.vbproj', '.xaml', '.razor', '.cshtml', '.cls', '.trigger', '.lisp', '.cl', '.lsp', '.asd', '.robot', '.resource', '.sol', '.erl', '.hrl', '.escript'}
|
||||
DOC_EXTENSIONS = {'.md', '.mdx', '.qmd', '.skill', '.txt', '.rst', '.html', '.yaml', '.yml'}
|
||||
PAPER_EXTENSIONS = {'.pdf'}
|
||||
IMAGE_EXTENSIONS = {'.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'}
|
||||
|
||||
@@ -6767,6 +6767,7 @@ _DISPATCH: dict[str, Any] = {
|
||||
".v": extract_verilog,
|
||||
".sv": extract_verilog,
|
||||
".svh": extract_verilog,
|
||||
".vh": extract_verilog,
|
||||
".sql": extract_sql,
|
||||
".md": extract_markdown,
|
||||
".mdx": extract_markdown,
|
||||
|
||||
@@ -34,6 +34,32 @@ def test_classify_python():
|
||||
def test_classify_typescript():
|
||||
assert classify_file(Path("bar.ts")) == FileType.CODE
|
||||
|
||||
@pytest.mark.parametrize("suffix", [".vh", ".VH"])
|
||||
def test_detect_verilog_headers(tmp_path, suffix):
|
||||
header = tmp_path / f"defs{suffix}"
|
||||
header.write_text("`define WIDTH 8\n", encoding="utf-8")
|
||||
|
||||
assert classify_file(header) == FileType.CODE
|
||||
result = detect(tmp_path)
|
||||
assert header.resolve() in {Path(path).resolve() for path in result["files"]["code"]}
|
||||
|
||||
def test_detect_incremental_requeues_changed_verilog_header(tmp_path):
|
||||
header = tmp_path / "defs.vh"
|
||||
header.write_text("`define WIDTH 8\n", encoding="utf-8")
|
||||
manifest_path = tmp_path / "graphify-out" / "manifest.json"
|
||||
|
||||
full = detect(tmp_path)
|
||||
save_manifest(full["files"], manifest_path, root=tmp_path, kind="ast")
|
||||
|
||||
warm = detect_incremental(tmp_path, manifest_path, kind="ast")
|
||||
assert warm["new_total"] == 0
|
||||
|
||||
header.write_text("`define WIDTH 16\n", encoding="utf-8")
|
||||
changed = detect_incremental(tmp_path, manifest_path, kind="ast")
|
||||
assert header.resolve() in {
|
||||
Path(path).resolve() for path in changed["new_files"]["code"]
|
||||
}
|
||||
|
||||
def test_classify_powershell_module():
|
||||
# #1315: .psm1 modules were never indexed (CODE_EXTENSIONS gap).
|
||||
assert classify_file(Path("Utils.psm1")) == FileType.CODE
|
||||
|
||||
@@ -3875,6 +3875,33 @@ def test_apex_no_dangling_edges():
|
||||
|
||||
# -- SystemVerilog -------------------------------------------------------------
|
||||
|
||||
@pytest.mark.parametrize("suffix", [".v", ".sv", ".svh", ".vh"])
|
||||
def test_verilog_family_dispatch(suffix):
|
||||
from graphify.extract import _get_extractor
|
||||
|
||||
assert _get_extractor(Path(f"defs{suffix}")) is extract_verilog
|
||||
|
||||
|
||||
@pytest.mark.parametrize("with_module", [False, True])
|
||||
def test_verilog_header_collection_and_extraction(tmp_path, with_module):
|
||||
from graphify.extract import collect_files, extract
|
||||
|
||||
header = tmp_path / "defs.vh"
|
||||
source = "`define WIDTH 8\n"
|
||||
if with_module:
|
||||
source += "module helper(input wire a, output wire b);\nassign b = a;\nendmodule\n"
|
||||
header.write_text(source, encoding="utf-8")
|
||||
|
||||
paths = collect_files(tmp_path)
|
||||
assert header in paths
|
||||
result = extract(paths, root=tmp_path, cache_root=tmp_path, parallel=False)
|
||||
assert header.name in {node["label"] for node in result["nodes"]}
|
||||
if with_module:
|
||||
assert (header.name, "helper") in _edge_labels(result, "defines")
|
||||
else:
|
||||
assert {node["label"] for node in result["nodes"]} == {header.name}
|
||||
|
||||
|
||||
def test_systemverilog_no_error():
|
||||
r = extract_verilog(FIXTURES / "sample.sv")
|
||||
assert "error" not in r
|
||||
|
||||
@@ -47,6 +47,14 @@ def test_watched_extensions_includes_code():
|
||||
assert ".go" in _WATCHED_EXTENSIONS
|
||||
assert ".rs" in _WATCHED_EXTENSIONS
|
||||
|
||||
def test_verilog_header_triggers_code_rebuild_without_llm(tmp_path):
|
||||
header = tmp_path / "defs.vh"
|
||||
header.write_text("`define WIDTH 8\n", encoding="utf-8")
|
||||
|
||||
assert ".vh" in _WATCHED_EXTENSIONS
|
||||
assert _batch_triggers_rebuild([header]) is True
|
||||
assert _batch_needs_llm_flag([header]) is False
|
||||
|
||||
def test_watched_extensions_includes_docs():
|
||||
assert ".md" in _WATCHED_EXTENSIONS
|
||||
assert ".txt" in _WATCHED_EXTENSIONS
|
||||
|
||||
Reference in new issue
Block a user