codegraphcontext 0.3.2__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codegraphcontext-0.3.3/MANIFEST.in +4 -0
- {codegraphcontext-0.3.2/src/codegraphcontext.egg-info → codegraphcontext-0.3.3}/PKG-INFO +2 -2
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/README.md +1 -1
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/pyproject.toml +1 -1
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/cli_helpers.py +15 -243
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/main.py +1 -1
- codegraphcontext-0.3.3/src/codegraphcontext/cli/visualizer.py +50 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/graph_builder.py +76 -60
- codegraphcontext-0.3.3/src/codegraphcontext/tools/handlers/query_handlers.py +87 -0
- codegraphcontext-0.3.3/src/codegraphcontext/utils/visualize_graph.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/viz/server.py +18 -17
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3/src/codegraphcontext.egg-info}/PKG-INFO +2 -2
- codegraphcontext-0.3.2/MANIFEST.in +0 -5
- codegraphcontext-0.3.2/src/codegraphcontext/cli/visualizer.py +0 -1391
- codegraphcontext-0.3.2/src/codegraphcontext/tools/handlers/query_handlers.py +0 -181
- codegraphcontext-0.3.2/src/codegraphcontext/utils/visualize_graph.py +0 -150
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/LICENSE +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/setup.cfg +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/__init__.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/__main__.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/__init__.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/config_manager.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/registry_commands.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/setup_macos.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/cli/setup_wizard.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/core/__init__.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/core/bundle_registry.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/core/cgc_bundle.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/core/database.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/core/database_falkordb.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/core/database_falkordb_remote.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/core/database_kuzu.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/core/falkor_worker.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/core/jobs.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/core/watcher.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/prompts.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/server.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tool_definitions.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/__init__.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/code_finder.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/handlers/indexing_handlers.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/handlers/management_handlers.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/handlers/watcher_handlers.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/c.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/cpp.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/csharp.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/dart.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/elixir.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/go.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/haskell.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/java.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/javascript.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/perl.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/php.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/python.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/ruby.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/rust.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/scala.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/swift.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/typescript.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/package_resolver.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/scip_indexer.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/scip_pb2.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/system.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/utils/debug_log.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext.egg-info/SOURCES.txt +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext.egg-info/requires.txt +0 -0
- {codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codegraphcontext
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: An MCP server that indexes local code into a graph database to provide context to AI assistants.
|
|
5
5
|
Author-email: Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -160,7 +160,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
160
160
|
---
|
|
161
161
|
|
|
162
162
|
## Project Details
|
|
163
|
-
- **Version:** 0.3.
|
|
163
|
+
- **Version:** 0.3.3
|
|
164
164
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
165
165
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
166
166
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -96,7 +96,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
96
96
|
---
|
|
97
97
|
|
|
98
98
|
## Project Details
|
|
99
|
-
- **Version:** 0.3.
|
|
99
|
+
- **Version:** 0.3.3
|
|
100
100
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
101
101
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
102
102
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codegraphcontext"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.3"
|
|
4
4
|
description = "An MCP server that indexes local code into a graph database to provide context to AI assistants."
|
|
5
5
|
authors = [{ name = "Shashank Shekhar Singh", email = "shashankshekharsingh1205@gmail.com" }]
|
|
6
6
|
readme = "README.md"
|
|
@@ -340,7 +340,9 @@ def cypher_helper_visual(query: str):
|
|
|
340
340
|
console.print(f"[bold red]An error occurred while executing query:[/bold red] {e}")
|
|
341
341
|
finally:
|
|
342
342
|
db_manager.close_driver()
|
|
343
|
-
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
import uvicorn
|
|
344
346
|
import urllib.parse
|
|
345
347
|
from ..viz.server import run_server, set_db_manager
|
|
346
348
|
|
|
@@ -356,12 +358,18 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000):
|
|
|
356
358
|
set_db_manager(db_manager)
|
|
357
359
|
|
|
358
360
|
# Determine the static directory (built React app)
|
|
361
|
+
# This points to src/codegraphcontext/viz/dist where we build the website
|
|
359
362
|
static_dir = Path(__file__).parent.parent / "viz" / "dist"
|
|
363
|
+
|
|
364
|
+
# Fallback for development if not yet built in viz/dist
|
|
360
365
|
if not static_dir.exists():
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
366
|
+
dev_static_dir = Path.cwd() / "website" / "dist"
|
|
367
|
+
if dev_static_dir.exists():
|
|
368
|
+
static_dir = dev_static_dir
|
|
369
|
+
else:
|
|
370
|
+
console.print("[yellow]Warning: Visualization assets not found. Please run 'cd website && npm run build' first.[/yellow]")
|
|
371
|
+
# We continue anyway to let the server start (helpful for dev)
|
|
372
|
+
|
|
365
373
|
# Construct the URL
|
|
366
374
|
backend_url = f"http://localhost:{port}"
|
|
367
375
|
params = {"backend": backend_url}
|
|
@@ -369,7 +377,7 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000):
|
|
|
369
377
|
params["repo_path"] = str(Path(repo_path).resolve())
|
|
370
378
|
|
|
371
379
|
query_string = urllib.parse.urlencode(params)
|
|
372
|
-
visualization_url = f"{backend_url}/
|
|
380
|
+
visualization_url = f"{backend_url}/explore?{query_string}"
|
|
373
381
|
|
|
374
382
|
console.print(f"[green]Starting visualizer server on {backend_url}...[/green]")
|
|
375
383
|
console.print(f"[cyan]Opening Playground UI:[/cyan] {visualization_url}")
|
|
@@ -377,6 +385,7 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000):
|
|
|
377
385
|
# Open browser in a separate thread/process if possible, or just before starting server
|
|
378
386
|
def open_browser():
|
|
379
387
|
import time
|
|
388
|
+
import webbrowser
|
|
380
389
|
time.sleep(1.5) # Give the server a moment to start
|
|
381
390
|
webbrowser.open(visualization_url)
|
|
382
391
|
|
|
@@ -390,243 +399,6 @@ def visualize_helper(repo_path: Optional[str] = None, port: int = 8000):
|
|
|
390
399
|
finally:
|
|
391
400
|
db_manager.close_driver()
|
|
392
401
|
|
|
393
|
-
def _visualize_falkordb(db_manager):
|
|
394
|
-
console.print("[dim]Generating FalkorDB visualization (showing up to 500 relationships)...[/dim]")
|
|
395
|
-
try:
|
|
396
|
-
data_nodes = []
|
|
397
|
-
data_edges = []
|
|
398
|
-
|
|
399
|
-
with db_manager.get_driver().session() as session:
|
|
400
|
-
# Fetch nodes and edges
|
|
401
|
-
q = "MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 500"
|
|
402
|
-
result = session.run(q)
|
|
403
|
-
|
|
404
|
-
seen_nodes = set()
|
|
405
|
-
|
|
406
|
-
for record in result:
|
|
407
|
-
# record values are Node/Relationship objects from falkordb client
|
|
408
|
-
n = record['n']
|
|
409
|
-
r = record['r']
|
|
410
|
-
m = record['m']
|
|
411
|
-
|
|
412
|
-
# Process Node helper
|
|
413
|
-
def process_node(node):
|
|
414
|
-
nid = getattr(node, 'id', -1)
|
|
415
|
-
labels = getattr(node, 'labels', [])
|
|
416
|
-
lbl = list(labels)[0] if labels else "Node"
|
|
417
|
-
props = getattr(node, 'properties', {})
|
|
418
|
-
name = props.get('name', str(nid))
|
|
419
|
-
|
|
420
|
-
if nid not in seen_nodes:
|
|
421
|
-
seen_nodes.add(nid)
|
|
422
|
-
color = "#97c2fc" # Default blue
|
|
423
|
-
if "Repository" in labels: color = "#ffb3ba" # Red
|
|
424
|
-
elif "File" in labels: color = "#baffc9" # Green
|
|
425
|
-
elif "Class" in labels: color = "#bae1ff" # Light Blue
|
|
426
|
-
elif "Function" in labels: color = "#ffffba" # Yellow
|
|
427
|
-
elif "Package" in labels: color = "#ffdfba" # Orange
|
|
428
|
-
|
|
429
|
-
data_nodes.append({
|
|
430
|
-
"id": nid,
|
|
431
|
-
"label": name,
|
|
432
|
-
"group": lbl,
|
|
433
|
-
"title": str(props),
|
|
434
|
-
"color": color
|
|
435
|
-
})
|
|
436
|
-
return nid
|
|
437
|
-
|
|
438
|
-
nid = process_node(n)
|
|
439
|
-
mid = process_node(m)
|
|
440
|
-
|
|
441
|
-
# Check Edge
|
|
442
|
-
e_type = getattr(r, 'relation', '') or getattr(r, 'type', 'REL')
|
|
443
|
-
data_edges.append({
|
|
444
|
-
"from": nid,
|
|
445
|
-
"to": mid,
|
|
446
|
-
"label": e_type,
|
|
447
|
-
"arrows": "to"
|
|
448
|
-
})
|
|
449
|
-
|
|
450
|
-
filename = "codegraph_viz.html"
|
|
451
|
-
html_content = f"""
|
|
452
|
-
<!DOCTYPE html>
|
|
453
|
-
<html>
|
|
454
|
-
<head>
|
|
455
|
-
<title>CodeGraphContext Visualization</title>
|
|
456
|
-
<script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
|
|
457
|
-
<style type="text/css">
|
|
458
|
-
#mynetwork {{
|
|
459
|
-
width: 100%;
|
|
460
|
-
height: 100vh;
|
|
461
|
-
border: 1px solid lightgray;
|
|
462
|
-
}}
|
|
463
|
-
</style>
|
|
464
|
-
</head>
|
|
465
|
-
<body>
|
|
466
|
-
<div id="mynetwork"></div>
|
|
467
|
-
<script type="text/javascript">
|
|
468
|
-
var nodes = new vis.DataSet({json.dumps(data_nodes)});
|
|
469
|
-
var edges = new vis.DataSet({json.dumps(data_edges)});
|
|
470
|
-
var container = document.getElementById('mynetwork');
|
|
471
|
-
var data = {{ nodes: nodes, edges: edges }};
|
|
472
|
-
var options = {{
|
|
473
|
-
nodes: {{ shape: 'dot', size: 16 }},
|
|
474
|
-
physics: {{ stabilization: false }},
|
|
475
|
-
layout: {{ improvedLayout: false }}
|
|
476
|
-
}};
|
|
477
|
-
var network = new vis.Network(container, data, options);
|
|
478
|
-
</script>
|
|
479
|
-
</body>
|
|
480
|
-
</html>
|
|
481
|
-
"""
|
|
482
|
-
|
|
483
|
-
out_path = Path(filename).resolve()
|
|
484
|
-
with open(out_path, "w") as f:
|
|
485
|
-
f.write(html_content)
|
|
486
|
-
|
|
487
|
-
console.print(f"[green]Visualization generated at:[/green] {out_path}")
|
|
488
|
-
console.print("Opening in default browser...")
|
|
489
|
-
webbrowser.open(f"file://{out_path}")
|
|
490
|
-
|
|
491
|
-
except Exception as e:
|
|
492
|
-
console.print(f"[bold red]Visualization failed:[/bold red] {e}")
|
|
493
|
-
import traceback
|
|
494
|
-
traceback.print_exc()
|
|
495
|
-
finally:
|
|
496
|
-
db_manager.close_driver()
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
def _visualize_kuzudb(db_manager):
|
|
500
|
-
console.print("[dim]Generating KùzuDB visualization (showing up to 500 relationships)...[/dim]")
|
|
501
|
-
try:
|
|
502
|
-
data_nodes = []
|
|
503
|
-
data_edges = []
|
|
504
|
-
|
|
505
|
-
with db_manager.get_driver().session() as session:
|
|
506
|
-
# Fetch nodes and edges
|
|
507
|
-
# KùzuDB returns dicts for n, r, m in the result
|
|
508
|
-
q = "MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 500"
|
|
509
|
-
result = session.run(q)
|
|
510
|
-
|
|
511
|
-
seen_nodes = set()
|
|
512
|
-
|
|
513
|
-
# Helper to extract Node ID and props
|
|
514
|
-
def process_node(node):
|
|
515
|
-
uid = None
|
|
516
|
-
lbl = 'Node'
|
|
517
|
-
props = {}
|
|
518
|
-
|
|
519
|
-
# Handle Kuzu Node Object (processed by wrapper)
|
|
520
|
-
if hasattr(node, 'properties'):
|
|
521
|
-
props = node.properties or {}
|
|
522
|
-
if hasattr(node, 'labels') and node.labels:
|
|
523
|
-
lbl = node.labels[0]
|
|
524
|
-
if hasattr(node, 'id'):
|
|
525
|
-
uid = str(node.id)
|
|
526
|
-
# Handle Dictionary (raw Kuzu result)
|
|
527
|
-
elif isinstance(node, dict):
|
|
528
|
-
if '_id' in node:
|
|
529
|
-
uid = f"{node['_id']['table']}_{node['_id']['offset']}"
|
|
530
|
-
lbl = node.get('_label', 'Node')
|
|
531
|
-
props = {k: v for k, v in node.items() if not k.startswith('_')}
|
|
532
|
-
|
|
533
|
-
if not uid:
|
|
534
|
-
uid = str(uuid.uuid4())
|
|
535
|
-
|
|
536
|
-
name = props.get('name', str(uid))
|
|
537
|
-
|
|
538
|
-
if uid not in seen_nodes:
|
|
539
|
-
seen_nodes.add(uid)
|
|
540
|
-
color = "#97c2fc" # Default blue
|
|
541
|
-
if "Repository" == lbl: color = "#ffb3ba"
|
|
542
|
-
elif "File" == lbl: color = "#baffc9"
|
|
543
|
-
elif "Class" == lbl: color = "#bae1ff"
|
|
544
|
-
elif "Function" == lbl: color = "#ffffba"
|
|
545
|
-
elif "Module" == lbl: color = "#ffdfba"
|
|
546
|
-
|
|
547
|
-
data_nodes.append({
|
|
548
|
-
"id": uid,
|
|
549
|
-
"label": name,
|
|
550
|
-
"group": lbl,
|
|
551
|
-
"title": str(props),
|
|
552
|
-
"color": color
|
|
553
|
-
})
|
|
554
|
-
return uid
|
|
555
|
-
|
|
556
|
-
# Iterate results
|
|
557
|
-
for record in result:
|
|
558
|
-
# record is dict-like access to row items
|
|
559
|
-
n = record['n']
|
|
560
|
-
r = record['r']
|
|
561
|
-
m = record['m']
|
|
562
|
-
|
|
563
|
-
nid = process_node(n)
|
|
564
|
-
mid = process_node(m)
|
|
565
|
-
|
|
566
|
-
# Process Edge
|
|
567
|
-
e_type = 'REL'
|
|
568
|
-
if hasattr(r, 'type'):
|
|
569
|
-
e_type = r.type
|
|
570
|
-
elif isinstance(r, dict):
|
|
571
|
-
e_type = r.get('_label', 'REL')
|
|
572
|
-
elif hasattr(r, 'label'): # Some versions
|
|
573
|
-
e_type = r.label
|
|
574
|
-
|
|
575
|
-
data_edges.append({
|
|
576
|
-
"from": nid,
|
|
577
|
-
"to": mid,
|
|
578
|
-
"label": e_type,
|
|
579
|
-
"arrows": "to"
|
|
580
|
-
})
|
|
581
|
-
|
|
582
|
-
filename = "codegraph_viz.html"
|
|
583
|
-
html_content = f"""
|
|
584
|
-
<!DOCTYPE html>
|
|
585
|
-
<html>
|
|
586
|
-
<head>
|
|
587
|
-
<title>CodeGraphContext KùzuDB Visualization</title>
|
|
588
|
-
<script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
|
|
589
|
-
<style type="text/css">
|
|
590
|
-
#mynetwork {{
|
|
591
|
-
width: 100%;
|
|
592
|
-
height: 100vh;
|
|
593
|
-
border: 1px solid lightgray;
|
|
594
|
-
}}
|
|
595
|
-
</style>
|
|
596
|
-
</head>
|
|
597
|
-
<body>
|
|
598
|
-
<div id="mynetwork"></div>
|
|
599
|
-
<script type="text/javascript">
|
|
600
|
-
var nodes = new vis.DataSet({json.dumps(data_nodes)});
|
|
601
|
-
var edges = new vis.DataSet({json.dumps(data_edges)});
|
|
602
|
-
var container = document.getElementById('mynetwork');
|
|
603
|
-
var data = {{ nodes: nodes, edges: edges }};
|
|
604
|
-
var options = {{
|
|
605
|
-
nodes: {{ shape: 'dot', size: 16 }},
|
|
606
|
-
physics: {{ stabilization: false }},
|
|
607
|
-
layout: {{ improvedLayout: false }}
|
|
608
|
-
}};
|
|
609
|
-
var network = new vis.Network(container, data, options);
|
|
610
|
-
</script>
|
|
611
|
-
</body>
|
|
612
|
-
</html>
|
|
613
|
-
"""
|
|
614
|
-
|
|
615
|
-
out_path = Path(filename).resolve()
|
|
616
|
-
with open(out_path, "w") as f:
|
|
617
|
-
f.write(html_content)
|
|
618
|
-
|
|
619
|
-
console.print(f"[green]Visualization generated at:[/green] {out_path}")
|
|
620
|
-
console.print("Opening in default browser...")
|
|
621
|
-
webbrowser.open(f"file://{out_path}")
|
|
622
|
-
|
|
623
|
-
except Exception as e:
|
|
624
|
-
console.print(f"[bold red]Visualization failed:[/bold red] {e}")
|
|
625
|
-
import traceback
|
|
626
|
-
traceback.print_exc()
|
|
627
|
-
finally:
|
|
628
|
-
db_manager.close_driver()
|
|
629
|
-
|
|
630
402
|
|
|
631
403
|
def reindex_helper(path: str):
|
|
632
404
|
"""Force re-index by deleting and rebuilding the repository."""
|
|
@@ -999,7 +999,7 @@ def visualize(
|
|
|
999
999
|
port: int = typer.Option(8000, "--port", "-p", help="Port to run the visualizer server on.")
|
|
1000
1000
|
):
|
|
1001
1001
|
"""
|
|
1002
|
-
Launches the interactive
|
|
1002
|
+
Launches the interactive UI to visualize the code graph.
|
|
1003
1003
|
"""
|
|
1004
1004
|
_load_credentials()
|
|
1005
1005
|
visualize_helper(repo, port)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import urllib.parse
|
|
2
|
+
from typing import Optional, List, Dict, Any, Set
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from .cli_helpers import visualize_helper
|
|
5
|
+
|
|
6
|
+
def check_visual_flag(ctx, visual: bool, cypher_query: str = None):
|
|
7
|
+
"""
|
|
8
|
+
Helper to check the --visual flag and launch the visualizer.
|
|
9
|
+
This is called from within analyze/find commands.
|
|
10
|
+
"""
|
|
11
|
+
if visual and cypher_query:
|
|
12
|
+
# We start the visualizer on port 8000
|
|
13
|
+
# Passing empty repo handles showing just the query results
|
|
14
|
+
port = 8000
|
|
15
|
+
encoded_query = urllib.parse.quote(cypher_query)
|
|
16
|
+
visualization_url = f"http://localhost:{port}/explore?cypher_query={encoded_query}"
|
|
17
|
+
|
|
18
|
+
from rich.console import Console
|
|
19
|
+
console = Console(stderr=True)
|
|
20
|
+
console.print(f"[green]Starting visualizer...[/green]")
|
|
21
|
+
console.print(f"[cyan]Visualizing results at:[/cyan] {visualization_url}")
|
|
22
|
+
|
|
23
|
+
# Start the backend server and open the browser
|
|
24
|
+
visualize_helper(repo_path=None, port=port)
|
|
25
|
+
return True
|
|
26
|
+
return False
|
|
27
|
+
|
|
28
|
+
def visualize_call_graph(cypher_query: str):
|
|
29
|
+
"""Visualize a call graph result."""
|
|
30
|
+
visualize_helper(repo_path=None, port=8000)
|
|
31
|
+
|
|
32
|
+
def visualize_call_chain(cypher_query: str):
|
|
33
|
+
"""Visualize a call chain result."""
|
|
34
|
+
visualize_helper(repo_path=None, port=8000)
|
|
35
|
+
|
|
36
|
+
def visualize_dependencies(cypher_query: str):
|
|
37
|
+
"""Visualize code dependencies."""
|
|
38
|
+
visualize_helper(repo_path=None, port=8000)
|
|
39
|
+
|
|
40
|
+
def visualize_inheritance_tree(cypher_query: str):
|
|
41
|
+
"""Visualize class inheritance tree."""
|
|
42
|
+
visualize_helper(repo_path=None, port=8000)
|
|
43
|
+
|
|
44
|
+
def visualize_overrides(cypher_query: str):
|
|
45
|
+
"""Visualize method overrides."""
|
|
46
|
+
visualize_helper(repo_path=None, port=8000)
|
|
47
|
+
|
|
48
|
+
def visualize_search_results(cypher_query: str):
|
|
49
|
+
"""Visualize search results."""
|
|
50
|
+
visualize_helper(repo_path=None, port=8000)
|
{codegraphcontext-0.3.2 → codegraphcontext-0.3.3}/src/codegraphcontext/tools/graph_builder.py
RENAMED
|
@@ -115,39 +115,54 @@ class GraphBuilder:
|
|
|
115
115
|
self.loop = loop
|
|
116
116
|
self.driver = self.db_manager.get_driver()
|
|
117
117
|
self.parsers = {
|
|
118
|
-
'.py':
|
|
119
|
-
'.ipynb':
|
|
120
|
-
'.js':
|
|
121
|
-
'.jsx':
|
|
122
|
-
'.mjs':
|
|
123
|
-
'.cjs':
|
|
124
|
-
'.go':
|
|
125
|
-
'.ts':
|
|
126
|
-
'.tsx':
|
|
127
|
-
'.cpp':
|
|
128
|
-
'.h':
|
|
129
|
-
'.hpp':
|
|
130
|
-
'.hh':
|
|
131
|
-
'.rs':
|
|
132
|
-
'.c':
|
|
133
|
-
# '.h':
|
|
134
|
-
'.java':
|
|
135
|
-
'.rb':
|
|
136
|
-
'.cs':
|
|
137
|
-
'.php':
|
|
138
|
-
'.kt':
|
|
139
|
-
'.scala':
|
|
140
|
-
'.sc':
|
|
141
|
-
'.swift':
|
|
142
|
-
'.hs':
|
|
143
|
-
'.dart':
|
|
144
|
-
'.pl':
|
|
145
|
-
'.pm':
|
|
146
|
-
'.ex':
|
|
147
|
-
'.exs':
|
|
118
|
+
'.py': 'python',
|
|
119
|
+
'.ipynb': 'python',
|
|
120
|
+
'.js': 'javascript',
|
|
121
|
+
'.jsx': 'javascript',
|
|
122
|
+
'.mjs': 'javascript',
|
|
123
|
+
'.cjs': 'javascript',
|
|
124
|
+
'.go': 'go',
|
|
125
|
+
'.ts': 'typescript',
|
|
126
|
+
'.tsx': 'typescript',
|
|
127
|
+
'.cpp': 'cpp',
|
|
128
|
+
'.h': 'cpp',
|
|
129
|
+
'.hpp': 'cpp',
|
|
130
|
+
'.hh': 'cpp',
|
|
131
|
+
'.rs': 'rust',
|
|
132
|
+
'.c': 'c',
|
|
133
|
+
# '.h': 'c', # Need to write an algo for distinguishing C vs C++ headers
|
|
134
|
+
'.java': 'java',
|
|
135
|
+
'.rb': 'ruby',
|
|
136
|
+
'.cs': 'c_sharp',
|
|
137
|
+
'.php': 'php',
|
|
138
|
+
'.kt': 'kotlin',
|
|
139
|
+
'.scala': 'scala',
|
|
140
|
+
'.sc': 'scala',
|
|
141
|
+
'.swift': 'swift',
|
|
142
|
+
'.hs': 'haskell',
|
|
143
|
+
'.dart': 'dart',
|
|
144
|
+
'.pl': 'perl',
|
|
145
|
+
'.pm': 'perl',
|
|
146
|
+
'.ex': 'elixir',
|
|
147
|
+
'.exs': 'elixir',
|
|
148
148
|
}
|
|
149
|
+
self._parsed_cache = {}
|
|
149
150
|
self.create_schema()
|
|
150
151
|
|
|
152
|
+
def get_parser(self, extension: str) -> Optional[TreeSitterParser]:
|
|
153
|
+
"""Gets or creates a TreeSitterParser for the given extension."""
|
|
154
|
+
lang_name = self.parsers.get(extension)
|
|
155
|
+
if not lang_name:
|
|
156
|
+
return None
|
|
157
|
+
|
|
158
|
+
if lang_name not in self._parsed_cache:
|
|
159
|
+
try:
|
|
160
|
+
self._parsed_cache[lang_name] = TreeSitterParser(lang_name)
|
|
161
|
+
except Exception as e:
|
|
162
|
+
warning_logger(f"Failed to initialize parser for {lang_name}: {e}")
|
|
163
|
+
return None
|
|
164
|
+
return self._parsed_cache[lang_name]
|
|
165
|
+
|
|
151
166
|
# A general schema creation based on common features across languages
|
|
152
167
|
def create_schema(self):
|
|
153
168
|
"""Create constraints and indexes in Neo4j."""
|
|
@@ -175,6 +190,7 @@ class GraphBuilder:
|
|
|
175
190
|
session.run("CREATE INDEX function_lang IF NOT EXISTS FOR (f:Function) ON (f.lang)")
|
|
176
191
|
session.run("CREATE INDEX class_lang IF NOT EXISTS FOR (c:Class) ON (c.lang)")
|
|
177
192
|
session.run("CREATE INDEX annotation_lang IF NOT EXISTS FOR (a:Annotation) ON (a.lang)")
|
|
193
|
+
|
|
178
194
|
is_falkordb = getattr(self.db_manager, 'get_backend_type', lambda: 'neo4j')() != 'neo4j'
|
|
179
195
|
if is_falkordb:
|
|
180
196
|
# FalkorDB uses db.idx.fulltext.createNodeIndex per label
|
|
@@ -242,85 +258,85 @@ class GraphBuilder:
|
|
|
242
258
|
|
|
243
259
|
if '.py' in files_by_lang:
|
|
244
260
|
from .languages import python as python_lang_module
|
|
245
|
-
imports_map.update(python_lang_module.pre_scan_python(files_by_lang['.py'], self.
|
|
261
|
+
imports_map.update(python_lang_module.pre_scan_python(files_by_lang['.py'], self.get_parser('.py')))
|
|
246
262
|
if '.ipynb' in files_by_lang:
|
|
247
263
|
from .languages import python as python_lang_module
|
|
248
|
-
imports_map.update(python_lang_module.pre_scan_python(files_by_lang['.ipynb'], self.
|
|
264
|
+
imports_map.update(python_lang_module.pre_scan_python(files_by_lang['.ipynb'], self.get_parser('.ipynb')))
|
|
249
265
|
if '.js' in files_by_lang:
|
|
250
266
|
from .languages import javascript as js_lang_module
|
|
251
|
-
imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.js'], self.
|
|
267
|
+
imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.js'], self.get_parser('.js')))
|
|
252
268
|
if '.jsx' in files_by_lang:
|
|
253
269
|
from .languages import javascript as js_lang_module
|
|
254
|
-
imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.jsx'], self.
|
|
270
|
+
imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.jsx'], self.get_parser('.jsx')))
|
|
255
271
|
if '.mjs' in files_by_lang:
|
|
256
272
|
from .languages import javascript as js_lang_module
|
|
257
|
-
imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.mjs'], self.
|
|
273
|
+
imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.mjs'], self.get_parser('.mjs')))
|
|
258
274
|
if '.cjs' in files_by_lang:
|
|
259
275
|
from .languages import javascript as js_lang_module
|
|
260
|
-
imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.cjs'], self.
|
|
276
|
+
imports_map.update(js_lang_module.pre_scan_javascript(files_by_lang['.cjs'], self.get_parser('.cjs')))
|
|
261
277
|
if '.go' in files_by_lang:
|
|
262
278
|
from .languages import go as go_lang_module
|
|
263
|
-
imports_map.update(go_lang_module.pre_scan_go(files_by_lang['.go'], self.
|
|
279
|
+
imports_map.update(go_lang_module.pre_scan_go(files_by_lang['.go'], self.get_parser('.go')))
|
|
264
280
|
if '.ts' in files_by_lang:
|
|
265
281
|
from .languages import typescript as ts_lang_module
|
|
266
|
-
imports_map.update(ts_lang_module.pre_scan_typescript(files_by_lang['.ts'], self.
|
|
282
|
+
imports_map.update(ts_lang_module.pre_scan_typescript(files_by_lang['.ts'], self.get_parser('.ts')))
|
|
267
283
|
if '.tsx' in files_by_lang:
|
|
268
284
|
from .languages import typescriptjsx as tsx_lang_module
|
|
269
|
-
imports_map.update(tsx_lang_module.pre_scan_typescript(files_by_lang['.tsx'], self.
|
|
285
|
+
imports_map.update(tsx_lang_module.pre_scan_typescript(files_by_lang['.tsx'], self.get_parser('.tsx')))
|
|
270
286
|
if '.cpp' in files_by_lang:
|
|
271
287
|
from .languages import cpp as cpp_lang_module
|
|
272
|
-
imports_map.update(cpp_lang_module.pre_scan_cpp(files_by_lang['.cpp'], self.
|
|
288
|
+
imports_map.update(cpp_lang_module.pre_scan_cpp(files_by_lang['.cpp'], self.get_parser('.cpp')))
|
|
273
289
|
if '.h' in files_by_lang:
|
|
274
290
|
from .languages import cpp as cpp_lang_module
|
|
275
|
-
imports_map.update(cpp_lang_module.pre_scan_cpp(files_by_lang['.h'], self.
|
|
291
|
+
imports_map.update(cpp_lang_module.pre_scan_cpp(files_by_lang['.h'], self.get_parser('.h')))
|
|
276
292
|
if '.hpp' in files_by_lang:
|
|
277
293
|
from .languages import cpp as cpp_lang_module
|
|
278
|
-
imports_map.update(cpp_lang_module.pre_scan_cpp(files_by_lang['.hpp'], self.
|
|
294
|
+
imports_map.update(cpp_lang_module.pre_scan_cpp(files_by_lang['.hpp'], self.get_parser('.hpp')))
|
|
279
295
|
if '.hh' in files_by_lang:
|
|
280
296
|
from .languages import cpp as cpp_lang_module
|
|
281
|
-
imports_map.update(cpp_lang_module.pre_scan_cpp(files_by_lang['.hh'], self.
|
|
297
|
+
imports_map.update(cpp_lang_module.pre_scan_cpp(files_by_lang['.hh'], self.get_parser('.hh')))
|
|
282
298
|
if '.rs' in files_by_lang:
|
|
283
299
|
from .languages import rust as rust_lang_module
|
|
284
|
-
imports_map.update(rust_lang_module.pre_scan_rust(files_by_lang['.rs'], self.
|
|
300
|
+
imports_map.update(rust_lang_module.pre_scan_rust(files_by_lang['.rs'], self.get_parser('.rs')))
|
|
285
301
|
if '.c' in files_by_lang:
|
|
286
302
|
from .languages import c as c_lang_module
|
|
287
|
-
imports_map.update(c_lang_module.pre_scan_c(files_by_lang['.c'], self.
|
|
303
|
+
imports_map.update(c_lang_module.pre_scan_c(files_by_lang['.c'], self.get_parser('.c')))
|
|
288
304
|
elif '.java' in files_by_lang:
|
|
289
305
|
from .languages import java as java_lang_module
|
|
290
|
-
imports_map.update(java_lang_module.pre_scan_java(files_by_lang['.java'], self.
|
|
306
|
+
imports_map.update(java_lang_module.pre_scan_java(files_by_lang['.java'], self.get_parser('.java')))
|
|
291
307
|
elif '.rb' in files_by_lang:
|
|
292
308
|
from .languages import ruby as ruby_lang_module
|
|
293
|
-
imports_map.update(ruby_lang_module.pre_scan_ruby(files_by_lang['.rb'], self.
|
|
309
|
+
imports_map.update(ruby_lang_module.pre_scan_ruby(files_by_lang['.rb'], self.get_parser('.rb')))
|
|
294
310
|
elif '.cs' in files_by_lang:
|
|
295
311
|
from .languages import csharp as csharp_lang_module
|
|
296
|
-
imports_map.update(csharp_lang_module.pre_scan_csharp(files_by_lang['.cs'], self.
|
|
312
|
+
imports_map.update(csharp_lang_module.pre_scan_csharp(files_by_lang['.cs'], self.get_parser('.cs')))
|
|
297
313
|
if '.kt' in files_by_lang:
|
|
298
314
|
from .languages import kotlin as kotlin_lang_module
|
|
299
|
-
imports_map.update(kotlin_lang_module.pre_scan_kotlin(files_by_lang['.kt'], self.
|
|
315
|
+
imports_map.update(kotlin_lang_module.pre_scan_kotlin(files_by_lang['.kt'], self.get_parser('.kt')))
|
|
300
316
|
if '.scala' in files_by_lang:
|
|
301
317
|
from .languages import scala as scala_lang_module
|
|
302
|
-
imports_map.update(scala_lang_module.pre_scan_scala(files_by_lang['.scala'], self.
|
|
318
|
+
imports_map.update(scala_lang_module.pre_scan_scala(files_by_lang['.scala'], self.get_parser('.scala')))
|
|
303
319
|
if '.sc' in files_by_lang:
|
|
304
320
|
from .languages import scala as scala_lang_module
|
|
305
|
-
imports_map.update(scala_lang_module.pre_scan_scala(files_by_lang['.sc'], self.
|
|
321
|
+
imports_map.update(scala_lang_module.pre_scan_scala(files_by_lang['.sc'], self.get_parser('.sc')))
|
|
306
322
|
if '.swift' in files_by_lang:
|
|
307
323
|
from .languages import swift as swift_lang_module
|
|
308
|
-
imports_map.update(swift_lang_module.pre_scan_swift(files_by_lang['.swift'], self.
|
|
324
|
+
imports_map.update(swift_lang_module.pre_scan_swift(files_by_lang['.swift'], self.get_parser('.swift')))
|
|
309
325
|
if '.dart' in files_by_lang:
|
|
310
326
|
from .languages import dart as dart_lang_module
|
|
311
|
-
imports_map.update(dart_lang_module.pre_scan_dart(files_by_lang['.dart'], self.
|
|
327
|
+
imports_map.update(dart_lang_module.pre_scan_dart(files_by_lang['.dart'], self.get_parser('.dart')))
|
|
312
328
|
if '.pl' in files_by_lang:
|
|
313
329
|
from .languages import perl as perl_lang_module
|
|
314
|
-
imports_map.update(perl_lang_module.pre_scan_perl(files_by_lang['.pl'], self.
|
|
330
|
+
imports_map.update(perl_lang_module.pre_scan_perl(files_by_lang['.pl'], self.get_parser('.pl')))
|
|
315
331
|
if '.pm' in files_by_lang:
|
|
316
332
|
from .languages import perl as perl_lang_module
|
|
317
|
-
imports_map.update(perl_lang_module.pre_scan_perl(files_by_lang['.pm'], self.
|
|
333
|
+
imports_map.update(perl_lang_module.pre_scan_perl(files_by_lang['.pm'], self.get_parser('.pm')))
|
|
318
334
|
if '.ex' in files_by_lang:
|
|
319
335
|
from .languages import elixir as elixir_lang_module
|
|
320
|
-
imports_map.update(elixir_lang_module.pre_scan_elixir(files_by_lang['.ex'], self.
|
|
336
|
+
imports_map.update(elixir_lang_module.pre_scan_elixir(files_by_lang['.ex'], self.get_parser('.ex')))
|
|
321
337
|
if '.exs' in files_by_lang:
|
|
322
338
|
from .languages import elixir as elixir_lang_module
|
|
323
|
-
imports_map.update(elixir_lang_module.pre_scan_elixir(files_by_lang['.exs'], self.
|
|
339
|
+
imports_map.update(elixir_lang_module.pre_scan_elixir(files_by_lang['.exs'], self.get_parser('.exs')))
|
|
324
340
|
|
|
325
341
|
return imports_map
|
|
326
342
|
|
|
@@ -996,7 +1012,7 @@ class GraphBuilder:
|
|
|
996
1012
|
|
|
997
1013
|
def parse_file(self, repo_path: Path, path: Path, is_dependency: bool = False) -> Dict:
|
|
998
1014
|
"""Parses a file with the appropriate language parser and extracts code elements."""
|
|
999
|
-
parser = self.
|
|
1015
|
+
parser = self.get_parser(path.suffix)
|
|
1000
1016
|
if not parser:
|
|
1001
1017
|
warning_logger(f"No parser found for file extension {path.suffix}. Skipping {path}")
|
|
1002
1018
|
return {"path": str(path), "error": f"No parser for {path.suffix}"}
|
|
@@ -1123,9 +1139,9 @@ class GraphBuilder:
|
|
|
1123
1139
|
|
|
1124
1140
|
# Step 5: Tree-sitter supplement — add source text, complexity, imports and bases
|
|
1125
1141
|
file_path = Path(abs_path_str)
|
|
1126
|
-
|
|
1142
|
+
ts_parser = self.get_parser(file_path.suffix)
|
|
1143
|
+
if file_path.exists() and ts_parser:
|
|
1127
1144
|
try:
|
|
1128
|
-
ts_parser = self.parsers[file_path.suffix]
|
|
1129
1145
|
ts_data = ts_parser.parse(file_path, is_dependency, index_source=True)
|
|
1130
1146
|
if "error" not in ts_data:
|
|
1131
1147
|
# 1. Functions: complexity, source, decorators
|