Files
dss/dss/analyze/project_analyzer.py
2025-12-11 07:13:06 -03:00

114 lines
3.6 KiB
Python

"""This module provides tools for analyzing a project."""
import json
import logging
import subprocess
from pathlib import Path
from typing import Dict
from dss.analyze.base import ProjectAnalysis
log = logging.getLogger(__name__)
# Path to the node.js parser script.
# This assumes the script is located in the same directory as this file.
parser_script_path = Path(__file__).parent / "parser.js"
def analyze_project(
path: str,
output_graph: bool = False,
prune: bool = False,
visualize: bool = False,
) -> ProjectAnalysis:
"""
Analyzes a project, including all its components and their dependencies.
Args:
path: The path to the project to analyze.
output_graph: Whether to output the dependency graph.
prune: Whether to prune the dependency graph.
visualize: Whether to visualize the dependency graph.
Returns:
A ProjectAnalysis object containing the analysis results.
"""
project_path = Path(path).resolve()
log.info(f"Analyzing project at {project_path}...")
# Get all component files in the project.
component_files = list(project_path.glob("**/*.js")) + list(project_path.glob("**/*.jsx"))
# For each component file, get its AST.
for file_path in component_files:
if file_path.is_file():
# Call the external node.js parser
result = subprocess.run(
["node", str(parser_script_path), file_path],
capture_output=True,
text=True,
check=True,
)
# The AST is now in result.stdout as a JSON string.
ast = json.loads(result.stdout)
# TODO: Do something with the AST.
# TODO: Populate the ProjectAnalysis object with the analysis results.
analysis = ProjectAnalysis(
project_name=project_path.name,
project_path=str(project_path),
total_files=len(component_files),
components={},
)
log.info(f"Analysis complete for {project_path.name}.")
return analysis
def export_project_context(analysis: ProjectAnalysis, output_path: str):
"""
Exports the project context to a JSON file.
"""
log.info(f"Exporting project context to {output_path}...")
with open(output_path, "w") as f:
json.dump(analysis.dict(), f, indent=2)
log.info("Export complete.")
def get_ast(file_path: str) -> Dict:
"""
Gets the AST of a file using a node.js parser.
"""
log.info(f"Getting AST for {file_path}...")
result = subprocess.run(
["node", str(parser_script_path), file_path],
capture_output=True,
text=True,
check=True,
)
log.info("AST retrieved.")
return json.loads(result.stdout)
def main():
"""
Main function for the project analyzer.
"""
import argparse
parser = argparse.ArgumentParser(description="Analyze a project.")
parser.add_argument("path", help="The path to the project to analyze.")
parser.add_argument("--output-graph", action="store_true", help="Output the dependency graph.")
parser.add_argument("--prune", action="store_true", help="Prune the dependency graph.")
parser.add_argument("--visualize", action="store_true", help="Visualize the dependency graph.")
parser.add_argument("--export-context", help="Export the project context to a JSON file.")
args = parser.parse_args()
analysis = analyze_project(args.path, args.output_graph, args.prune, args.visualize)
if args.export_context:
export_project_context(analysis, args.export_context)
if __name__ == "__main__":
main()