graph-dependency-analyzer 0.2.0__py3-none-any.whl
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.
- graph_dependency_analyzer-0.2.0.dist-info/METADATA +158 -0
- graph_dependency_analyzer-0.2.0.dist-info/RECORD +86 -0
- graph_dependency_analyzer-0.2.0.dist-info/WHEEL +5 -0
- graph_dependency_analyzer-0.2.0.dist-info/entry_points.txt +2 -0
- graph_dependency_analyzer-0.2.0.dist-info/top_level.txt +1 -0
- src/__init__.py +0 -0
- src/application/__init__.py +0 -0
- src/application/dtos/__init__.py +0 -0
- src/application/dtos/affected_component.py +59 -0
- src/application/dtos/batch_processing_result.py +17 -0
- src/application/dtos/impact_analysis_response.py +56 -0
- src/application/dtos/impact_query_request.py +38 -0
- src/application/dtos/index_batch_request.py +53 -0
- src/application/dtos/index_batch_response.py +72 -0
- src/application/dtos/index_result.py +20 -0
- src/application/dtos/repository_index_result.py +79 -0
- src/application/exceptions.py +41 -0
- src/application/services/__init__.py +0 -0
- src/application/services/file_scanner_service.py +258 -0
- src/application/services/progress_tracker.py +132 -0
- src/application/use_cases/__init__.py +0 -0
- src/application/use_cases/clear_all_data_use_case.py +180 -0
- src/application/use_cases/index_batch_use_case.py +153 -0
- src/application/use_cases/index_repository_use_case.py +683 -0
- src/application/use_cases/indexing_orchestrator.py +181 -0
- src/application/use_cases/list_repositories_use_case.py +84 -0
- src/cli.py +512 -0
- src/config/__init__.py +5 -0
- src/config/container.py +211 -0
- src/config/logging_config.py +123 -0
- src/config/settings.py +165 -0
- src/domain/__init__.py +0 -0
- src/domain/entities/__init__.py +20 -0
- src/domain/entities/ast_node.py +32 -0
- src/domain/entities/code_chunk.py +45 -0
- src/domain/entities/code_file.py +44 -0
- src/domain/entities/dependency_graph.py +110 -0
- src/domain/entities/repository.py +46 -0
- src/domain/exceptions.py +36 -0
- src/domain/repositories/__init__.py +22 -0
- src/domain/repositories/i_code_parser.py +50 -0
- src/domain/repositories/i_dependency_extractor.py +35 -0
- src/domain/repositories/i_embedding_provider.py +31 -0
- src/domain/repositories/i_graph_repository.py +78 -0
- src/domain/repositories/i_vector_repository.py +55 -0
- src/domain/services/__init__.py +8 -0
- src/domain/services/dependency_extractor.py +962 -0
- src/domain/services/semantic_chunk_builder.py +719 -0
- src/domain/value_objects/__init__.py +12 -0
- src/domain/value_objects/chunk_type.py +24 -0
- src/domain/value_objects/dependency_type.py +22 -0
- src/domain/value_objects/node_type.py +22 -0
- src/domain/value_objects/qualified_name.py +78 -0
- src/infrastructure/__init__.py +0 -0
- src/infrastructure/exceptions.py +41 -0
- src/infrastructure/external_apis/__init__.py +0 -0
- src/infrastructure/external_apis/ollama_embedding_provider.py +134 -0
- src/infrastructure/external_apis/openai_embedding_provider.py +231 -0
- src/infrastructure/parsing/__init__.py +20 -0
- src/infrastructure/parsing/config_file_parser.py +347 -0
- src/infrastructure/parsing/gradle_dependency_parser.py +159 -0
- src/infrastructure/parsing/groovy_parser.py +198 -0
- src/infrastructure/parsing/maven_dependency_parser.py +147 -0
- src/infrastructure/parsing/microfrontend_config_parser.py +242 -0
- src/infrastructure/parsing/npm_package_dependency_parser.py +255 -0
- src/infrastructure/parsing/python_parser.py +211 -0
- src/infrastructure/parsing/sql_schema_parser.py +658 -0
- src/infrastructure/parsing/tree_sitter_java_parser.py +434 -0
- src/infrastructure/parsing/tree_sitter_typescript_parser.py +600 -0
- src/infrastructure/persistence/__init__.py +0 -0
- src/infrastructure/persistence/graph_export_repository.py +443 -0
- src/infrastructure/persistence/neo4j_dependency_repository.py +657 -0
- src/infrastructure/persistence/qdrant_vector_repository.py +357 -0
- src/infrastructure/persistence/repository_relationship_repository.py +1312 -0
- src/presentation/__init__.py +0 -0
- src/presentation/api/__init__.py +0 -0
- src/presentation/api/rest/__init__.py +0 -0
- src/presentation/api/rest/exception_handlers.py +174 -0
- src/presentation/api/rest/main.py +80 -0
- src/presentation/api/rest/routers/__init__.py +5 -0
- src/presentation/api/rest/routers/admin.py +103 -0
- src/presentation/api/rest/routers/analysis.py +980 -0
- src/presentation/api/rest/routers/export.py +442 -0
- src/presentation/api/rest/routers/health.py +117 -0
- src/presentation/api/rest/routers/indexing.py +148 -0
- src/presentation/api/rest/routers/relationships.py +1089 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""
|
|
2
|
+
IndexBatchUseCase Implementation (Task 8.3)
|
|
3
|
+
|
|
4
|
+
Orchestrates batch indexing of multiple repositories.
|
|
5
|
+
Validates repositories and delegates to IndexingOrchestrator.
|
|
6
|
+
"""
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Callable
|
|
9
|
+
import structlog
|
|
10
|
+
|
|
11
|
+
from src.config.settings import Settings
|
|
12
|
+
from src.application.dtos.index_batch_request import IndexBatchRequest
|
|
13
|
+
from src.application.dtos.index_batch_response import IndexBatchResponse
|
|
14
|
+
from src.application.dtos.repository_index_result import RepositoryIndexResult
|
|
15
|
+
from src.application.use_cases.indexing_orchestrator import IndexingOrchestrator
|
|
16
|
+
from src.application.services.progress_tracker import ProgressUpdate
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
logger = structlog.get_logger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class IndexBatchUseCase:
|
|
23
|
+
"""
|
|
24
|
+
Use Case for batch indexing multiple repositories.
|
|
25
|
+
|
|
26
|
+
Responsibilities:
|
|
27
|
+
- Validate repository list (non-empty, paths exist)
|
|
28
|
+
- Resolve full paths from REPOSITORIES_PATH base
|
|
29
|
+
- Delegate parallel processing to IndexingOrchestrator
|
|
30
|
+
- Aggregate success/failure results
|
|
31
|
+
|
|
32
|
+
Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.9, 2.10, 2.11
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(self, orchestrator: IndexingOrchestrator, settings: Settings):
|
|
36
|
+
"""
|
|
37
|
+
Initialize use case.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
orchestrator: IndexingOrchestrator for parallel processing
|
|
41
|
+
settings: Settings with REPOSITORIES_PATH configured
|
|
42
|
+
"""
|
|
43
|
+
self.orchestrator = orchestrator
|
|
44
|
+
self.settings = settings
|
|
45
|
+
|
|
46
|
+
async def execute(
|
|
47
|
+
self,
|
|
48
|
+
request: IndexBatchRequest,
|
|
49
|
+
progress_callback: Callable[[str, ProgressUpdate], None] | None = None
|
|
50
|
+
) -> IndexBatchResponse:
|
|
51
|
+
"""
|
|
52
|
+
Process multiple repositories in parallel.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
request: Request with repository names and parallel limit
|
|
56
|
+
progress_callback: Optional callback (repo_name, progress_update)
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
IndexBatchResponse with success/failure counts and details
|
|
60
|
+
|
|
61
|
+
Raises:
|
|
62
|
+
ValueError: If repository list empty or no valid repos found
|
|
63
|
+
"""
|
|
64
|
+
# Precondition: repositories not empty
|
|
65
|
+
if not request.repositories:
|
|
66
|
+
raise ValueError("Lista de repositórios não pode estar vazia")
|
|
67
|
+
|
|
68
|
+
# Resolve base path
|
|
69
|
+
base_path = Path(self.settings.repository.repositories_path)
|
|
70
|
+
|
|
71
|
+
logger.info(
|
|
72
|
+
"batch_indexing_requested",
|
|
73
|
+
base_path=str(base_path),
|
|
74
|
+
repositories=request.repositories,
|
|
75
|
+
parallel=request.parallel
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
# Validate base path exists
|
|
79
|
+
if not base_path.exists():
|
|
80
|
+
error_msg = f"Repositories base path does not exist: {base_path}"
|
|
81
|
+
logger.error("base_path_not_found", path=str(base_path))
|
|
82
|
+
raise ValueError(error_msg)
|
|
83
|
+
|
|
84
|
+
# Resolve full paths and validate existence
|
|
85
|
+
valid_paths: list[Path] = []
|
|
86
|
+
|
|
87
|
+
for repo_name in request.repositories:
|
|
88
|
+
repo_path = base_path / repo_name
|
|
89
|
+
|
|
90
|
+
if not repo_path.exists():
|
|
91
|
+
logger.warning(
|
|
92
|
+
"repository_not_found",
|
|
93
|
+
repository=repo_name,
|
|
94
|
+
expected_path=str(repo_path)
|
|
95
|
+
)
|
|
96
|
+
continue
|
|
97
|
+
|
|
98
|
+
valid_paths.append(repo_path)
|
|
99
|
+
logger.debug(
|
|
100
|
+
"repository_validated",
|
|
101
|
+
repository=repo_name,
|
|
102
|
+
path=str(repo_path)
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
# If no valid repositories, error
|
|
106
|
+
if not valid_paths:
|
|
107
|
+
error_msg = (
|
|
108
|
+
f"Nenhum repositório válido encontrado em {base_path}. "
|
|
109
|
+
f"Requisitados: {request.repositories}"
|
|
110
|
+
)
|
|
111
|
+
logger.error("no_valid_repositories", requested=request.repositories)
|
|
112
|
+
raise ValueError(error_msg)
|
|
113
|
+
|
|
114
|
+
logger.info(
|
|
115
|
+
"batch_processing_starting",
|
|
116
|
+
valid_repositories=len(valid_paths),
|
|
117
|
+
parallel=request.parallel
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# Delegate to orchestrator
|
|
121
|
+
batch_result = await self.orchestrator.process_batch(
|
|
122
|
+
repositories=valid_paths,
|
|
123
|
+
parallel=request.parallel,
|
|
124
|
+
progress_callback=progress_callback
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# Convert BatchProcessingResult to IndexBatchResponse
|
|
128
|
+
response = IndexBatchResponse(
|
|
129
|
+
total_processed=batch_result.total_processed,
|
|
130
|
+
success_count=batch_result.success_count,
|
|
131
|
+
failed_count=batch_result.failed_count,
|
|
132
|
+
results=[
|
|
133
|
+
RepositoryIndexResult(
|
|
134
|
+
repository=result.repository_name,
|
|
135
|
+
status=result.status,
|
|
136
|
+
files_processed=result.files_processed if result.status == "success" else None,
|
|
137
|
+
chunks_created=result.chunks_created if result.status == "success" else None,
|
|
138
|
+
nodes_created=result.nodes_created if result.status == "success" else None,
|
|
139
|
+
relationships_created=result.relationships_created if result.status == "success" else None,
|
|
140
|
+
error_message=result.error_message
|
|
141
|
+
)
|
|
142
|
+
for result in batch_result.results
|
|
143
|
+
]
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
logger.info(
|
|
147
|
+
"batch_processing_completed",
|
|
148
|
+
total=response.total_processed,
|
|
149
|
+
success=response.success_count,
|
|
150
|
+
failed=response.failed_count
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
return response
|