sourcecode 0.7.0__tar.gz → 0.9.0__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.
- {sourcecode-0.7.0 → sourcecode-0.9.0}/PKG-INFO +1 -1
- {sourcecode-0.7.0 → sourcecode-0.9.0}/docs/schema.md +2 -2
- {sourcecode-0.7.0 → sourcecode-0.9.0}/pyproject.toml +1 -1
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/cli.py +102 -1
- sourcecode-0.9.0/src/sourcecode/coverage_parser.py +539 -0
- sourcecode-0.9.0/src/sourcecode/metrics_analyzer.py +495 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/schema.py +124 -0
- sourcecode-0.9.0/src/sourcecode/semantic_analyzer.py +1887 -0
- sourcecode-0.9.0/tests/fixtures/coverage.xml +15 -0
- sourcecode-0.9.0/tests/fixtures/jacoco.xml +14 -0
- sourcecode-0.9.0/tests/fixtures/lcov.info +16 -0
- sourcecode-0.9.0/tests/test_coverage_parser.py +182 -0
- sourcecode-0.9.0/tests/test_integration_metrics.py +119 -0
- sourcecode-0.9.0/tests/test_integration_semantics.py +185 -0
- sourcecode-0.9.0/tests/test_metrics_analyzer.py +456 -0
- sourcecode-0.9.0/tests/test_semantic_analyzer_node.py +493 -0
- sourcecode-0.9.0/tests/test_semantic_analyzer_python.py +302 -0
- sourcecode-0.9.0/tests/test_semantic_import_resolution.py +355 -0
- sourcecode-0.9.0/tests/test_semantic_schema.py +129 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/.gitignore +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/.ruff.toml +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/README.md +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/serializer.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/__init__.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/conftest.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/fastapi_app/src/main.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/go_service/cmd/api/main.go +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/go_service/go.mod +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/nextjs_app/package.json +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_classifier.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_cli.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_dependency_analyzer_node_python.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_dependency_analyzer_polyglot.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_dependency_schema.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_detector_go_rust_java.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_detector_nodejs.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_detector_php_ruby_dart.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_detector_python.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_detector_universal_managed.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_detector_universal_systems.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_detectors_base.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_doc_analyzer_jsdom.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_doc_analyzer_python.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_graph_analyzer_polyglot.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_graph_analyzer_python_node.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_graph_schema.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_integration.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_integration_dependencies.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_integration_detection.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_integration_docs.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_integration_graph_modules.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_integration_lqn.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_integration_multistack.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_integration_universal.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_packaging.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_real_projects.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_redactor.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_scanner.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_schema.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_summarizer.py +0 -0
- {sourcecode-0.7.0 → sourcecode-0.9.0}/tests/test_workspace_analyzer.py +0 -0
|
@@ -61,7 +61,7 @@ Campos:
|
|
|
61
61
|
{
|
|
62
62
|
"schema_version": "1.0",
|
|
63
63
|
"generated_at": "2026-04-07T19:41:05.686277+00:00",
|
|
64
|
-
"sourcecode_version": "0.
|
|
64
|
+
"sourcecode_version": "0.9.0",
|
|
65
65
|
"analyzed_path": "/abs/path/to/project"
|
|
66
66
|
}
|
|
67
67
|
```
|
|
@@ -582,7 +582,7 @@ Ejemplo de salida para un monorepo con web Node.js y API Python con `--dependenc
|
|
|
582
582
|
"metadata": {
|
|
583
583
|
"schema_version": "1.0",
|
|
584
584
|
"generated_at": "2026-04-07T19:41:05.686277+00:00",
|
|
585
|
-
"sourcecode_version": "0.
|
|
585
|
+
"sourcecode_version": "0.9.0",
|
|
586
586
|
"analyzed_path": "/abs/path/to/project"
|
|
587
587
|
},
|
|
588
588
|
"file_tree": {
|
|
@@ -107,6 +107,16 @@ def main(
|
|
|
107
107
|
help="Profundidad de extraccion de docs: module|symbols|full",
|
|
108
108
|
show_default=True,
|
|
109
109
|
),
|
|
110
|
+
full_metrics: bool = typer.Option(
|
|
111
|
+
False,
|
|
112
|
+
"--full-metrics",
|
|
113
|
+
help="Incluir metricas de calidad: LOC, simbolos, complejidad, tests y cobertura por fichero",
|
|
114
|
+
),
|
|
115
|
+
semantics: bool = typer.Option(
|
|
116
|
+
False,
|
|
117
|
+
"--semantics",
|
|
118
|
+
help="Incluir call graph semantico, linking cross-file de simbolos y resolucion avanzada de imports",
|
|
119
|
+
),
|
|
110
120
|
) -> None:
|
|
111
121
|
"""Genera un mapa de contexto estructurado del proyecto en formato JSON o YAML."""
|
|
112
122
|
# Validar formato
|
|
@@ -145,9 +155,18 @@ def main(
|
|
|
145
155
|
from sourcecode.detectors import ProjectDetector, build_default_detectors
|
|
146
156
|
from sourcecode.doc_analyzer import DocAnalyzer
|
|
147
157
|
from sourcecode.graph_analyzer import GraphAnalyzer, GraphDetail
|
|
158
|
+
from sourcecode.metrics_analyzer import MetricsAnalyzer
|
|
148
159
|
from sourcecode.redactor import SecretRedactor, redact_dict
|
|
149
160
|
from sourcecode.scanner import FileScanner
|
|
150
|
-
from sourcecode.schema import
|
|
161
|
+
from sourcecode.schema import (
|
|
162
|
+
AnalysisMetadata,
|
|
163
|
+
DocRecord,
|
|
164
|
+
DocsDepth,
|
|
165
|
+
DocSummary,
|
|
166
|
+
EntryPoint,
|
|
167
|
+
SourceMap,
|
|
168
|
+
StackDetection,
|
|
169
|
+
)
|
|
151
170
|
from sourcecode.serializer import compact_view, write_output
|
|
152
171
|
from sourcecode.workspace import WorkspaceAnalyzer
|
|
153
172
|
|
|
@@ -212,6 +231,10 @@ def main(
|
|
|
212
231
|
graph_detail_typed = cast(GraphDetail, graph_detail)
|
|
213
232
|
docs_depth_typed = cast(DocsDepth, docs_depth)
|
|
214
233
|
doc_analyzer = DocAnalyzer() if docs else None
|
|
234
|
+
metrics_analyzer = MetricsAnalyzer() if full_metrics else None
|
|
235
|
+
|
|
236
|
+
from sourcecode.semantic_analyzer import SemanticAnalyzer
|
|
237
|
+
semantic_analyzer = SemanticAnalyzer() if semantics else None
|
|
215
238
|
|
|
216
239
|
root_manifests = [
|
|
217
240
|
manifest
|
|
@@ -269,6 +292,24 @@ def main(
|
|
|
269
292
|
doc_records.extend(root_doc_records)
|
|
270
293
|
doc_summaries.append(root_doc_summary)
|
|
271
294
|
|
|
295
|
+
file_metrics_records: list = []
|
|
296
|
+
metrics_summaries = []
|
|
297
|
+
if metrics_analyzer is not None:
|
|
298
|
+
root_metrics_tree = (
|
|
299
|
+
prune_workspace_paths(
|
|
300
|
+
file_tree,
|
|
301
|
+
[workspace.path for workspace in workspace_analysis.workspaces],
|
|
302
|
+
)
|
|
303
|
+
if workspace_analysis.workspaces
|
|
304
|
+
else file_tree
|
|
305
|
+
)
|
|
306
|
+
root_file_metrics, root_metrics_summary = metrics_analyzer.analyze(
|
|
307
|
+
target,
|
|
308
|
+
root_metrics_tree,
|
|
309
|
+
)
|
|
310
|
+
file_metrics_records.extend(root_file_metrics)
|
|
311
|
+
metrics_summaries.append(root_metrics_summary)
|
|
312
|
+
|
|
272
313
|
for workspace in workspace_analysis.workspaces:
|
|
273
314
|
workspace_root = target / workspace.path
|
|
274
315
|
if not workspace_root.exists() or not workspace_root.is_dir():
|
|
@@ -327,6 +368,18 @@ def main(
|
|
|
327
368
|
]
|
|
328
369
|
doc_records.extend(prefixed_doc_records)
|
|
329
370
|
doc_summaries.append(workspace_doc_summary)
|
|
371
|
+
if metrics_analyzer is not None:
|
|
372
|
+
ws_file_metrics, ws_metrics_summary = metrics_analyzer.analyze(
|
|
373
|
+
workspace_root,
|
|
374
|
+
workspace_tree,
|
|
375
|
+
workspace=workspace.path,
|
|
376
|
+
)
|
|
377
|
+
prefixed_file_metrics = [
|
|
378
|
+
replace(m, path=f"{workspace.path}/{m.path}")
|
|
379
|
+
for m in ws_file_metrics
|
|
380
|
+
]
|
|
381
|
+
file_metrics_records.extend(prefixed_file_metrics)
|
|
382
|
+
metrics_summaries.append(ws_metrics_summary)
|
|
330
383
|
|
|
331
384
|
stacks, project_type = detector.classify_results(
|
|
332
385
|
file_tree,
|
|
@@ -355,6 +408,11 @@ def main(
|
|
|
355
408
|
if doc_analyzer is not None
|
|
356
409
|
else None
|
|
357
410
|
)
|
|
411
|
+
metrics_summary = (
|
|
412
|
+
metrics_analyzer.merge_summaries(metrics_summaries)
|
|
413
|
+
if metrics_analyzer is not None
|
|
414
|
+
else None
|
|
415
|
+
)
|
|
358
416
|
|
|
359
417
|
# 3. Construir el schema
|
|
360
418
|
metadata = AnalysisMetadata(analyzed_path=str(target))
|
|
@@ -370,8 +428,51 @@ def main(
|
|
|
370
428
|
module_graph_summary=module_graph.summary if module_graph is not None else None,
|
|
371
429
|
docs=doc_records,
|
|
372
430
|
doc_summary=doc_summary,
|
|
431
|
+
file_metrics=file_metrics_records,
|
|
432
|
+
metrics_summary=metrics_summary,
|
|
373
433
|
)
|
|
374
434
|
|
|
435
|
+
# Semantic analysis (--semantics flag)
|
|
436
|
+
if semantic_analyzer is not None:
|
|
437
|
+
if workspace_analysis.workspaces:
|
|
438
|
+
all_sem_calls: list[Any] = []
|
|
439
|
+
all_sem_symbols: list[Any] = []
|
|
440
|
+
all_sem_links: list[Any] = []
|
|
441
|
+
all_sem_summaries: list[Any] = []
|
|
442
|
+
for ws in workspace_analysis.workspaces:
|
|
443
|
+
ws_calls, ws_syms, ws_links, ws_sum = semantic_analyzer.analyze(
|
|
444
|
+
target / ws.path,
|
|
445
|
+
(
|
|
446
|
+
filter_sensitive_files(
|
|
447
|
+
FileScanner(target / ws.path, max_depth=depth).scan_tree()
|
|
448
|
+
)
|
|
449
|
+
),
|
|
450
|
+
workspace=ws.path,
|
|
451
|
+
)
|
|
452
|
+
all_sem_calls.extend(ws_calls)
|
|
453
|
+
all_sem_symbols.extend(ws_syms)
|
|
454
|
+
all_sem_links.extend(ws_links)
|
|
455
|
+
all_sem_summaries.append(ws_sum)
|
|
456
|
+
merged_sem = semantic_analyzer.merge_summaries(all_sem_summaries)
|
|
457
|
+
sm = replace(
|
|
458
|
+
sm,
|
|
459
|
+
semantic_calls=all_sem_calls,
|
|
460
|
+
semantic_symbols=all_sem_symbols,
|
|
461
|
+
semantic_links=all_sem_links,
|
|
462
|
+
semantic_summary=merged_sem,
|
|
463
|
+
)
|
|
464
|
+
else:
|
|
465
|
+
sem_calls, sem_syms, sem_links, sem_sum = semantic_analyzer.analyze(
|
|
466
|
+
target, file_tree
|
|
467
|
+
)
|
|
468
|
+
sm = replace(
|
|
469
|
+
sm,
|
|
470
|
+
semantic_calls=sem_calls,
|
|
471
|
+
semantic_symbols=sem_syms,
|
|
472
|
+
semantic_links=sem_links,
|
|
473
|
+
semantic_summary=sem_sum,
|
|
474
|
+
)
|
|
475
|
+
|
|
375
476
|
# Phase 9: LLM Output Quality — poblar campos derivados
|
|
376
477
|
from sourcecode.summarizer import ProjectSummarizer
|
|
377
478
|
from sourcecode.tree_utils import flatten_file_tree
|