modwire 9.2.1__tar.gz → 9.2.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.
- {modwire-9.2.1 → modwire-9.2.3}/.dev/modwire.egg-info/SOURCES.txt +10 -3
- {modwire-9.2.1 → modwire-9.2.3}/Makefile +4 -1
- {modwire-9.2.1 → modwire-9.2.3}/PKG-INFO +6 -4
- {modwire-9.2.1 → modwire-9.2.3}/README.md +5 -3
- {modwire-9.2.1 → modwire-9.2.3}/docs/target-language-ownership.md +7 -6
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/application.py +20 -6
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/models/shape_rules.py +1 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/services/file_resolver.py +22 -7
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/application.py +70 -75
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/domain.py +14 -3
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/models/cache_outcome.py +6 -13
- modwire-9.2.3/src/modwire/cli/cache/models/cache_plan.py +22 -0
- modwire-9.2.3/src/modwire/cli/cache/models/cache_stage.py +9 -0
- modwire-9.2.3/src/modwire/cli/cache/models/cache_storage_state.py +11 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/models/cached_result.py +2 -1
- modwire-9.2.3/src/modwire/cli/cache/models/source_cache_entry.py +8 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/services/cache_identity.py +11 -8
- modwire-9.2.3/src/modwire/cli/cache/services/filesystem_cache_storage.py +284 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/facade.py +25 -13
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/domain.py +1 -1
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/batch_source_reader.py +2 -2
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/templates/ARCHITECTURE.md +4 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/templates/architecture.yaml +1 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/php/script.php +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/php/script.src.php +7 -2
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/typescript/script.js +16 -20
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/typescript/script.ts +18 -22
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/services/python_syntax_parser.py +38 -3
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/code_map.py +1 -1
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_value.py +2 -0
- modwire-9.2.3/src/modwire/shared/code/models/source_value_scope.py +7 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/application/test_07_cache.py +48 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/base_test.py +1 -1
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/insights/base_test.py +2 -2
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/insights/test_02_invariants.py +19 -10
- modwire-9.2.3/tests/architecture/report_benchmark/__init__.py +1 -0
- modwire-9.2.3/tests/architecture/report_benchmark/benchmark_process_timeout.py +6 -0
- modwire-9.2.3/tests/architecture/report_benchmark/run.py +424 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/shape/base_test.py +3 -1
- modwire-9.2.3/tests/architecture/shape/test_01_limits.py +241 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/shape/test_02_invariants.py +38 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/initialization/test_02_invariants.py +1 -0
- modwire-9.2.3/tests/extraction/cache_benchmark/run.py +318 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/extractors/test_03_native_symbols.py +21 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/syntax/php/example_shapes.php +3 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/syntax/python/example_shapes.py +3 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/syntax/typescript/example_shapes.ts +3 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/shared/code/test_02_invariants.py +13 -10
- {modwire-9.2.1 → modwire-9.2.3}/tests/support/code_map.py +30 -24
- modwire-9.2.1/src/modwire/cli/cache/models/extraction_snapshot.py +0 -8
- modwire-9.2.1/src/modwire/cli/cache/services/filesystem_cache_storage.py +0 -147
- modwire-9.2.1/tests/architecture/shape/test_01_limits.py +0 -126
- modwire-9.2.1/tests/extraction/cache_benchmark/run.py +0 -155
- {modwire-9.2.1 → modwire-9.2.3}/.github/workflows/ci.yml +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/.github/workflows/release.yml +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/.gitignore +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/AGENTS.md +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/LICENSE +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/MANIFEST.in +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/pyproject.toml +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/scripts/check_extractors.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/scripts/generate_docs.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/scripts/verify_consumer.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/setup.cfg +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/setup.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/__main__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/domain.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/models/edge_rule_violation.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/models/flow_report.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/models/flow_violation.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/models/types.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/services/backward_flow_analyzer.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/services/boundaries_flow_analyzer.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/services/module_boundary_analyzer.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/services/no_cycles_flow_analyzer.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/boundaries/services/no_reentry_flow_analyzer.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/models/architecture_config.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/models/boundaries_config.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/models/boundary_rule.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/models/configuration_value.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/models/flow_realm.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/models/flow_rules.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/models/shape_config.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/models/shape_realm.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/config/models/tag_rule.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/facade.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/domain.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/models/callable_report_entry.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/models/callables_report.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/models/clusters_report.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/models/clusters_report_item.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/models/coherence_report.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/models/exports_report.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/models/exports_report_item.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/models/hotspots_report.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/models/hotspots_report_item.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/models/insight_report.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/services/callables_reporter.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/services/clusters_reporter.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/services/coherence_reporter.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/services/exports_reporter.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/services/hotspots_reporter.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/insights/services/insight_report_field_map.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/map/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/map/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/map/domain.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/map/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/map/models/architecture_map.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/map/models/architecture_realm.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/map/models/tag_map.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/map/models/tag_match.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/map/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/map/services/architecture_map_loader.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/map/services/tag_matcher.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/domain.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/models/architecture_group.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/models/map_report.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/models/report_catalog.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/models/report_descriptor.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/models/report_item.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/models/report_metadata.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/models/report_node.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/models/report_section.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/report/services/map_report_collector.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/domain.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/models/shape_realm_architecture_map.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/models/shape_report.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/models/shape_violation.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/services/abstract_class_resolver.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/services/callable_resolver.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/services/class_resolver.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/services/import_resolver.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/services/property_resolver.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/services/signature_resolver.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/architecture/shape/services/symbol_resolver.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/autowiring.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/models/cache_entry.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/models/cache_key.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/models/cache_options.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/cache/services/cache_codec.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/documentation/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/documentation/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/documentation/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/documentation/services/documentation_generator.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/initialization/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/initialization/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/initialization/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/initialization/models/initialization_result.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/initialization/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/initialization/services/initialization_service.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/models/command_request.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/models/extractor_batch_input.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/models/extractor_command_input.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/models/extractor_source_input.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/models/report_pipeline_context.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/models/scan_policy.py +0 -0
- {modwire-9.2.1/src/modwire/cli/cache → modwire-9.2.3/src/modwire/cli/pipeline}/models/source_entry.py +0 -0
- {modwire-9.2.1/src/modwire/cli/cache → modwire-9.2.3/src/modwire/cli/pipeline}/models/source_inventory.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/callables_insight.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/clusters_insight.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/coherence_insight.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/command_line.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/configuration_loader.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/extractor_command.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/flow_violations.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/hotspots_insight.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/map_tree.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/output_console.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/shape_violations.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/success.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/unknown_files_warning.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/pipeline/services/unused_exports_insight.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/models/defaults.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/models/init_asset.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/templates/AGENTS.md +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/templates/INDEX.md +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/templates/MODWIRE.md +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/templates/RULES.md +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/templates/TESTING.md +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/cli/resources/templates/WORKFLOW.md +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/dependency/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/dependency/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/dependency/domain.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/dependency/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/dependency/services/graph_builder.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/dependency/services/import_resolver.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/dependency/services/suffix_index.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/domain.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/models/batch_config.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/models/extraction_request.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/models/extractor_resource.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/models/extractor_runtime.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/models/python_call_context.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/php/build.php +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/php/build.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/php/composer.json +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/php/composer.lock +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/python/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/python/script.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/typescript/build.mjs +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/typescript/build.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/typescript/package-lock.json +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/typescript/package.json +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/resources/typescript/tsconfig.json +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/services/php_extractor.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/services/python_call_reader.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/services/python_extractor.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/extractors/services/type_script_extractor.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/extraction/facade.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/py.typed +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/application.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/domain.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/code_package.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/dependency_edge_result.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/dependency_graph.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/dependency_node_result.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/duplicate_identity_error.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/edge.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/edge_resolution.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/identity.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/node.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/query_builder.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/query_types.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/queryable_code_map.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_abstract_class.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_call.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_callable.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_callable_symbol.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_class.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_class_method.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_class_property.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_export.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_extraction.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_file.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_file_result.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_function.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_import.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_imported_symbol.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_interface.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_item_result.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_parameter.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_signature.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_symbol.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/source_type.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/models/types.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/services/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/services/glob_path_matcher.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/code/services/identity_resolver.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/values/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/values/models/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/src/modwire/shared/values/models/value_model.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/application/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/application/base_test.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/application/test_01_attacks.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/application/test_06_happy_path.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/boundaries/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/boundaries/base_test.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/boundaries/test_01_attacks.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/boundaries/test_02_invariants.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/boundaries/test_03_public_api.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/boundaries/test_04_paths.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/config/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/config/test_01_attacks.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/config/test_02_invariants.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/insights/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/map/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/map/test_02_patterns.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/report/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/report/test_02_invariants.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/architecture/shape/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/base_test.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/documentation/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/documentation/test_02_invariants.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/initialization/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/initialization/test_01_attacks.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/initialization/test_03_interruption.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/initialization/test_04_cleanup.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/initialization/test_05_recovery.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/pipeline/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/pipeline/base_test.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/pipeline/test_01_attacks.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/pipeline/test_02_invariants.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/pipeline/test_03_interruption.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/pipeline/test_04_command_transport.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/pipeline/test_05_recovery.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/cli/pipeline/test_06_happy_path.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/conftest.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/base_test.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/big_projects/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/big_projects/project.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/big_projects/projects.json +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/big_projects/resolution_results.json +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/big_projects/results.json +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/big_projects/run.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/cache_benchmark/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/dependency/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/dependency/test_02_invariants.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/extractors/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/extractors/test_01_attacks.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/extractors/test_02_invariants.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/scan_benchmark/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/scan_benchmark/prepare.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/scan_benchmark/results.json +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/extraction/scan_benchmark/run.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/php/ignored/example_generated.php +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/php/src/example_application/example_actions/example_action.php +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/php/src/example_domain/example_model/example_record.php +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/php/src/example_domain/example_services/example_policy.php +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/php/src/example_interfaces/example_http/example_controller.php +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/python/ignored/example_generated.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/python/src/example_application/example_actions/example_action.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/python/src/example_domain/example_model/example_record.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/python/src/example_domain/example_services/example_policy.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/python/src/example_interfaces/example_http/example_controller.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/typescript/ignored/example_generated.ts +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/typescript/src/example_application/example_actions/example_action.ts +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/typescript/src/example_domain/example_model/example_record.ts +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/typescript/src/example_domain/example_model/example_view.tsx +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/typescript/src/example_domain/example_services/example_audit.js +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/typescript/src/example_domain/example_services/example_callables.ts +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/typescript/src/example_domain/example_services/example_policy.ts +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/typescript/src/example_interfaces/example_http/example_controller.ts +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/fixtures/languages/typescript/src/example_interfaces/example_http/example_view.jsx +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/shared/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/shared/code/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/support/__init__.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/support/base_test.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/tests/support/service_test.py +0 -0
- {modwire-9.2.1 → modwire-9.2.3}/uv.lock +0 -0
|
@@ -120,10 +120,11 @@ src/modwire/cli/cache/models/cache_entry.py
|
|
|
120
120
|
src/modwire/cli/cache/models/cache_key.py
|
|
121
121
|
src/modwire/cli/cache/models/cache_options.py
|
|
122
122
|
src/modwire/cli/cache/models/cache_outcome.py
|
|
123
|
+
src/modwire/cli/cache/models/cache_plan.py
|
|
124
|
+
src/modwire/cli/cache/models/cache_stage.py
|
|
125
|
+
src/modwire/cli/cache/models/cache_storage_state.py
|
|
123
126
|
src/modwire/cli/cache/models/cached_result.py
|
|
124
|
-
src/modwire/cli/cache/models/
|
|
125
|
-
src/modwire/cli/cache/models/source_entry.py
|
|
126
|
-
src/modwire/cli/cache/models/source_inventory.py
|
|
127
|
+
src/modwire/cli/cache/models/source_cache_entry.py
|
|
127
128
|
src/modwire/cli/cache/services/__init__.py
|
|
128
129
|
src/modwire/cli/cache/services/cache_codec.py
|
|
129
130
|
src/modwire/cli/cache/services/cache_identity.py
|
|
@@ -148,6 +149,8 @@ src/modwire/cli/pipeline/models/extractor_command_input.py
|
|
|
148
149
|
src/modwire/cli/pipeline/models/extractor_source_input.py
|
|
149
150
|
src/modwire/cli/pipeline/models/report_pipeline_context.py
|
|
150
151
|
src/modwire/cli/pipeline/models/scan_policy.py
|
|
152
|
+
src/modwire/cli/pipeline/models/source_entry.py
|
|
153
|
+
src/modwire/cli/pipeline/models/source_inventory.py
|
|
151
154
|
src/modwire/cli/pipeline/services/__init__.py
|
|
152
155
|
src/modwire/cli/pipeline/services/batch_source_reader.py
|
|
153
156
|
src/modwire/cli/pipeline/services/callables_insight.py
|
|
@@ -256,6 +259,7 @@ src/modwire/shared/code/models/source_signature.py
|
|
|
256
259
|
src/modwire/shared/code/models/source_symbol.py
|
|
257
260
|
src/modwire/shared/code/models/source_type.py
|
|
258
261
|
src/modwire/shared/code/models/source_value.py
|
|
262
|
+
src/modwire/shared/code/models/source_value_scope.py
|
|
259
263
|
src/modwire/shared/code/models/types.py
|
|
260
264
|
src/modwire/shared/code/services/__init__.py
|
|
261
265
|
src/modwire/shared/code/services/glob_path_matcher.py
|
|
@@ -288,6 +292,9 @@ tests/architecture/map/__init__.py
|
|
|
288
292
|
tests/architecture/map/test_02_patterns.py
|
|
289
293
|
tests/architecture/report/__init__.py
|
|
290
294
|
tests/architecture/report/test_02_invariants.py
|
|
295
|
+
tests/architecture/report_benchmark/__init__.py
|
|
296
|
+
tests/architecture/report_benchmark/benchmark_process_timeout.py
|
|
297
|
+
tests/architecture/report_benchmark/run.py
|
|
291
298
|
tests/architecture/shape/__init__.py
|
|
292
299
|
tests/architecture/shape/base_test.py
|
|
293
300
|
tests/architecture/shape/test_01_limits.py
|
|
@@ -7,7 +7,7 @@ PROJECT_ROOT := $(CURDIR)
|
|
|
7
7
|
export PYTHONPYCACHEPREFIX := $(PROJECT_ROOT)/$(DEV_DIR)/cache/python
|
|
8
8
|
export UV_CACHE_DIR := $(PROJECT_ROOT)/$(DEV_DIR)/cache/uv
|
|
9
9
|
|
|
10
|
-
.PHONY: big-projects build cache-benchmark ci docs docs-check extractor-check format format-check host-check lint package-check scan-benchmark scan-benchmark-fixture test type-check
|
|
10
|
+
.PHONY: big-projects build cache-benchmark ci docs docs-check extractor-check format format-check host-check lint package-check report-benchmark scan-benchmark scan-benchmark-fixture test type-check
|
|
11
11
|
|
|
12
12
|
format:
|
|
13
13
|
uv run ruff format src tests scripts
|
|
@@ -37,6 +37,9 @@ scan-benchmark:
|
|
|
37
37
|
cache-benchmark:
|
|
38
38
|
uv run python -m tests.extraction.cache_benchmark.run --root "$(CACHE_BENCHMARK_ROOT)" --language "$(CACHE_BENCHMARK_LANGUAGE)" --cache-directory .dev/benchmarks/cache --incremental-source "$(CACHE_BENCHMARK_SOURCE)" --replacement-source "$(CACHE_BENCHMARK_REPLACEMENT)"
|
|
39
39
|
|
|
40
|
+
report-benchmark:
|
|
41
|
+
uv run python -m tests.architecture.report_benchmark.run --root "$(REPORT_BENCHMARK_ROOT)" --language "$(REPORT_BENCHMARK_LANGUAGE)" --cache-directory "$(REPORT_BENCHMARK_CACHE)" --cache-namespace "$(REPORT_BENCHMARK_NAMESPACE)"
|
|
42
|
+
|
|
40
43
|
docs-check:
|
|
41
44
|
uv run python scripts/generate_docs.py --check
|
|
42
45
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modwire
|
|
3
|
-
Version: 9.2.
|
|
3
|
+
Version: 9.2.3
|
|
4
4
|
Summary: Code extraction, architecture analysis and the Modwire CLI.
|
|
5
5
|
Author: Tomasz Szpak
|
|
6
6
|
License-Expression: MIT
|
|
@@ -120,9 +120,11 @@ Public stages reported by cached Modwire operations.
|
|
|
120
120
|
|
|
121
121
|
Content-safe lifecycle counts for one stage of a cached operation.
|
|
122
122
|
|
|
123
|
-
Extraction counts describe current source records.
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
Extraction counts describe current source records. An exact code-map hit
|
|
124
|
+
reports its digest-backed manifest sources as extraction hits without loading
|
|
125
|
+
individual source payloads. Code-map and report counts describe one entry.
|
|
126
|
+
Invalidated entries are also misses. Diagnostics include the configured
|
|
127
|
+
namespace but never cache keys, source identities, or content.
|
|
126
128
|
|
|
127
129
|
## `CachedResult`
|
|
128
130
|
|
|
@@ -92,9 +92,11 @@ Public stages reported by cached Modwire operations.
|
|
|
92
92
|
|
|
93
93
|
Content-safe lifecycle counts for one stage of a cached operation.
|
|
94
94
|
|
|
95
|
-
Extraction counts describe current source records.
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
Extraction counts describe current source records. An exact code-map hit
|
|
96
|
+
reports its digest-backed manifest sources as extraction hits without loading
|
|
97
|
+
individual source payloads. Code-map and report counts describe one entry.
|
|
98
|
+
Invalidated entries are also misses. Diagnostics include the configured
|
|
99
|
+
namespace but never cache keys, source identities, or content.
|
|
98
100
|
|
|
99
101
|
## `CachedResult`
|
|
100
102
|
|
|
@@ -16,16 +16,17 @@ Shared code, dependency resolution, architecture analysis, traversal, consumer v
|
|
|
16
16
|
orchestration must not contain supported-language tables, runtime commands, extension tables, or language-selection
|
|
17
17
|
branches. Callers select a registered extractor explicitly.
|
|
18
18
|
|
|
19
|
-
## Shared contract version
|
|
19
|
+
## Shared contract version 3
|
|
20
20
|
|
|
21
|
-
The class-level `CodeMap.schema_version` is `
|
|
22
|
-
|
|
21
|
+
The class-level `CodeMap.schema_version` is `3`. Every runtime `SourceValue` declares a language-neutral `module`,
|
|
22
|
+
`local`, or `member` scope. Extractors distinguish variable assignments from constants and keep type aliases and export
|
|
23
|
+
metadata out of runtime values. Callable kinds are `function`, `instance_method`, `type_method`, `static_method`,
|
|
23
24
|
`constructor`, `callable_value`, and `anonymous`. Parameter kinds are `positional`, `variadic_positional`,
|
|
24
25
|
`named_only`, and `variadic_named`.
|
|
25
26
|
|
|
26
|
-
Version 1 serialized maps used extractor-specific callable and parameter vocabulary
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
Version 1 serialized maps used extractor-specific callable and parameter vocabulary, while version 2 values have no
|
|
28
|
+
explicit value scope. Neither is accepted as version 3. Regenerate them from source with the same registered extractor;
|
|
29
|
+
the cache identity includes the code-map schema and invalidates older maps instead of migrating them silently.
|
|
29
30
|
|
|
30
31
|
## Adding an extractor
|
|
31
32
|
|
|
@@ -11,7 +11,8 @@ from .architecture.facade import ArchitectureFacade
|
|
|
11
11
|
from .architecture.report.models.report_catalog import ReportCatalog
|
|
12
12
|
from .architecture.report.models.report_node import ReportNode
|
|
13
13
|
from .cli.cache.models.cache_options import CacheOptions
|
|
14
|
-
from .cli.cache.models.cache_outcome import CacheOutcome
|
|
14
|
+
from .cli.cache.models.cache_outcome import CacheOutcome
|
|
15
|
+
from .cli.cache.models.cache_stage import CacheStage
|
|
15
16
|
from .cli.cache.models.cached_result import CachedResult
|
|
16
17
|
from .cli.facade import CliFacade
|
|
17
18
|
from .cli.pipeline.models.scan_policy import ScanPolicy
|
|
@@ -82,9 +83,11 @@ class ModwireApplication:
|
|
|
82
83
|
|
|
83
84
|
cached = self.cli.cached_reports(code_map.code_map, config, options)
|
|
84
85
|
if cached.value is not None:
|
|
86
|
+
self.cli.maintain_cache(options)
|
|
85
87
|
return CachedResult(value=cached.value, outcomes=cached.outcomes)
|
|
86
88
|
reports = self.architecture.analyze(code_map, config)
|
|
87
89
|
self.cli.store_reports(code_map.code_map, config, reports, options)
|
|
90
|
+
self.cli.maintain_cache(options)
|
|
88
91
|
outcome = cached.outcome(CacheStage.REPORTS).model_copy(update={"computed": 1, "stored": 1})
|
|
89
92
|
return CachedResult(value=reports, outcomes=(outcome,))
|
|
90
93
|
|
|
@@ -124,16 +127,27 @@ class ModwireApplication:
|
|
|
124
127
|
"""Return a code map and public outcomes for extraction and complete-map reuse."""
|
|
125
128
|
|
|
126
129
|
request = self.extraction.request(language, str(root))
|
|
127
|
-
|
|
128
|
-
cached = self.cli.cached_code_map(
|
|
130
|
+
plan = self.cli.prepare_cache(request, policy)
|
|
131
|
+
cached = self.cli.cached_code_map(plan, options)
|
|
129
132
|
outcome = cached.outcome(CacheStage.CODE_MAP)
|
|
130
133
|
if cached.value is not None:
|
|
131
134
|
code_map = cached.value
|
|
135
|
+
extraction_outcomes = (
|
|
136
|
+
CacheOutcome(
|
|
137
|
+
stage=CacheStage.EXTRACTION,
|
|
138
|
+
namespace=options.namespace,
|
|
139
|
+
hits=len(plan.sources),
|
|
140
|
+
),
|
|
141
|
+
)
|
|
132
142
|
else:
|
|
133
|
-
|
|
134
|
-
self.cli.
|
|
143
|
+
sources = self.cli.cached_sources(request, plan, options)
|
|
144
|
+
self.cli.maintain_manifest(plan, options)
|
|
145
|
+
code_map = self.extraction.generate_map(language, sources.value)
|
|
146
|
+
self.cli.store_code_map(plan, code_map, options)
|
|
135
147
|
outcome = outcome.model_copy(update={"computed": 1, "stored": 1})
|
|
136
|
-
|
|
148
|
+
extraction_outcomes = sources.outcomes
|
|
149
|
+
self.cli.maintain_cache(options)
|
|
150
|
+
return CachedResult(value=code_map, outcomes=(*extraction_outcomes, outcome))
|
|
137
151
|
|
|
138
152
|
def generate_queryable_map_cached(
|
|
139
153
|
self, language: str, root: str, policy: ScanPolicy, options: CacheOptions
|
|
@@ -9,6 +9,7 @@ class ShapeRules(ConfigurationValue):
|
|
|
9
9
|
max_types_per_file: int = Field(default=-1, ge=-1)
|
|
10
10
|
max_abstract_classes_per_file: int = Field(default=-1, ge=-1)
|
|
11
11
|
max_functions_per_file: int = Field(default=0, ge=-1)
|
|
12
|
+
max_variables_per_file: int = Field(default=0, ge=-1)
|
|
12
13
|
max_methods_per_class: int = Field(default=-1, ge=-1)
|
|
13
14
|
max_declared_args: int = Field(default=-1, ge=-1)
|
|
14
15
|
max_function_lines: int = Field(default=-1, ge=-1)
|
|
@@ -2,6 +2,8 @@ from dataclasses import dataclass
|
|
|
2
2
|
|
|
3
3
|
from wireup import injectable
|
|
4
4
|
|
|
5
|
+
from ....shared.code.models.identity import FileId
|
|
6
|
+
from ....shared.code.models.source_value_scope import SourceValueScope
|
|
5
7
|
from ...config.models.shape_rules import ShapeRules
|
|
6
8
|
from ..domain import BaseShapeResolver, ShapeResolverInterface
|
|
7
9
|
from ..models.shape_realm_architecture_map import ShapeRealmArchitectureMap
|
|
@@ -23,12 +25,16 @@ class FileResolver(ShapeResolverInterface, BaseShapeResolver):
|
|
|
23
25
|
violations: list[ShapeViolation | None] = []
|
|
24
26
|
code_map = architecture_map.code_map
|
|
25
27
|
for source_id in self.realm_source_ids(architecture_map):
|
|
28
|
+
source_result = code_map.source_file(FileId(source_id))
|
|
29
|
+
if source_result is None:
|
|
30
|
+
raise RuntimeError(f"Shape realm references missing source: {source_id}")
|
|
31
|
+
source_file = source_result.file
|
|
26
32
|
violations.extend(
|
|
27
33
|
[
|
|
28
34
|
self.limit_violation(
|
|
29
35
|
source_id=source_id,
|
|
30
36
|
rule_name="max_classes_per_file",
|
|
31
|
-
actual=
|
|
37
|
+
actual=len(source_file.classes),
|
|
32
38
|
limit=config.max_classes_per_file,
|
|
33
39
|
symbol_kind="file",
|
|
34
40
|
symbol_name="",
|
|
@@ -36,7 +42,7 @@ class FileResolver(ShapeResolverInterface, BaseShapeResolver):
|
|
|
36
42
|
self.limit_violation(
|
|
37
43
|
source_id=source_id,
|
|
38
44
|
rule_name="max_interfaces_per_file",
|
|
39
|
-
actual=
|
|
45
|
+
actual=len(source_file.interfaces),
|
|
40
46
|
limit=config.max_interfaces_per_file,
|
|
41
47
|
symbol_kind="file",
|
|
42
48
|
symbol_name="",
|
|
@@ -44,7 +50,7 @@ class FileResolver(ShapeResolverInterface, BaseShapeResolver):
|
|
|
44
50
|
self.limit_violation(
|
|
45
51
|
source_id=source_id,
|
|
46
52
|
rule_name="max_types_per_file",
|
|
47
|
-
actual=
|
|
53
|
+
actual=len(source_file.types),
|
|
48
54
|
limit=config.max_types_per_file,
|
|
49
55
|
symbol_kind="file",
|
|
50
56
|
symbol_name="",
|
|
@@ -52,9 +58,7 @@ class FileResolver(ShapeResolverInterface, BaseShapeResolver):
|
|
|
52
58
|
self.limit_violation(
|
|
53
59
|
source_id=source_id,
|
|
54
60
|
rule_name="max_abstract_classes_per_file",
|
|
55
|
-
actual=
|
|
56
|
-
.where_equal(lambda result: result.source_id, source_id)
|
|
57
|
-
.count(),
|
|
61
|
+
actual=len(source_file.abstract_classes),
|
|
58
62
|
limit=config.max_abstract_classes_per_file,
|
|
59
63
|
symbol_kind="file",
|
|
60
64
|
symbol_name="",
|
|
@@ -62,11 +66,22 @@ class FileResolver(ShapeResolverInterface, BaseShapeResolver):
|
|
|
62
66
|
self.limit_violation(
|
|
63
67
|
source_id=source_id,
|
|
64
68
|
rule_name="max_functions_per_file",
|
|
65
|
-
actual=
|
|
69
|
+
actual=len(source_file.functions),
|
|
66
70
|
limit=config.max_functions_per_file,
|
|
67
71
|
symbol_kind="file",
|
|
68
72
|
symbol_name="",
|
|
69
73
|
),
|
|
74
|
+
self.limit_violation(
|
|
75
|
+
source_id=source_id,
|
|
76
|
+
rule_name="max_variables_per_file",
|
|
77
|
+
actual=sum(
|
|
78
|
+
value.scope == SourceValueScope.MODULE and value.declaration_kind == "assignment"
|
|
79
|
+
for value in source_file.values
|
|
80
|
+
),
|
|
81
|
+
limit=config.max_variables_per_file,
|
|
82
|
+
symbol_kind="file",
|
|
83
|
+
symbol_name="",
|
|
84
|
+
),
|
|
70
85
|
]
|
|
71
86
|
)
|
|
72
87
|
return tuple(violation for violation in violations if violation is not None)
|
|
@@ -18,19 +18,15 @@ from ..pipeline.models.scan_policy import ScanPolicy
|
|
|
18
18
|
from .domain import CacheStorage
|
|
19
19
|
from .models.cache_key import CacheKey
|
|
20
20
|
from .models.cache_options import CacheOptions
|
|
21
|
-
from .models.cache_outcome import CacheOutcome
|
|
21
|
+
from .models.cache_outcome import CacheOutcome
|
|
22
|
+
from .models.cache_plan import CachePlan
|
|
23
|
+
from .models.cache_stage import CacheStage
|
|
22
24
|
from .models.cached_result import CachedResult
|
|
23
|
-
from .models.
|
|
25
|
+
from .models.source_cache_entry import SourceCacheEntry
|
|
24
26
|
from .services.cache_codec import CacheCodec
|
|
25
27
|
from .services.cache_identity import CacheIdentity
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
@dataclass(frozen=True)
|
|
29
|
-
class _CacheRead:
|
|
30
|
-
value: object | None
|
|
31
|
-
invalidated: bool
|
|
32
|
-
|
|
33
|
-
|
|
34
30
|
@injectable
|
|
35
31
|
@dataclass(frozen=True)
|
|
36
32
|
class CacheApplication:
|
|
@@ -46,41 +42,58 @@ class CacheApplication:
|
|
|
46
42
|
self.reader.ensure_available(request.runtime)
|
|
47
43
|
return self.reader.extract_source(request, policy)
|
|
48
44
|
|
|
49
|
-
def
|
|
50
|
-
self, request: ExtractionRequest, policy: ScanPolicy, options: CacheOptions
|
|
51
|
-
) -> CachedResult[ExtractionSnapshot]:
|
|
45
|
+
def prepare(self, request: ExtractionRequest, policy: ScanPolicy) -> CachePlan:
|
|
52
46
|
inventory = self.reader.inventory(request, policy)
|
|
53
|
-
|
|
47
|
+
sources = tuple(
|
|
48
|
+
SourceCacheEntry(entry=entry, key=self.identity.source(request, policy, entry))
|
|
49
|
+
for entry in inventory.entries
|
|
50
|
+
)
|
|
51
|
+
return CachePlan(
|
|
52
|
+
inventory=inventory,
|
|
53
|
+
sources=sources,
|
|
54
|
+
manifest=self.identity.manifest(request, policy, sources),
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
def sources(
|
|
58
|
+
self, request: ExtractionRequest, plan: CachePlan, options: CacheOptions
|
|
59
|
+
) -> CachedResult[SourceExtraction]:
|
|
60
|
+
payloads = self.storage.read_many(options, tuple(source.key for source in plan.sources))
|
|
54
61
|
files: dict[FileId, SourceFile] = {}
|
|
55
62
|
misses: list[FileId] = []
|
|
63
|
+
invalid_keys: list[CacheKey] = []
|
|
56
64
|
hits = 0
|
|
57
65
|
invalidated = 0
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
sources_by_id = {source.entry.source_id: source for source in plan.sources}
|
|
67
|
+
for source, payload in zip(plan.sources, payloads, strict=True):
|
|
68
|
+
cached_value = self.codec.decode(source.key, payload) if payload is not None else None
|
|
69
|
+
cached_invalidated = payload is not None and cached_value is None
|
|
61
70
|
try:
|
|
62
|
-
source_file = SourceFile.model_validate(
|
|
63
|
-
if source_file.file_id != entry.source_id:
|
|
71
|
+
source_file = SourceFile.model_validate(cached_value)
|
|
72
|
+
if source_file.file_id != source.entry.source_id:
|
|
64
73
|
raise ValueError("Cached source identity does not match its key.")
|
|
65
|
-
files[entry.source_id] = source_file
|
|
74
|
+
files[source.entry.source_id] = source_file
|
|
66
75
|
hits += 1
|
|
67
76
|
except (TypeError, ValueError, ValidationError):
|
|
68
|
-
if
|
|
69
|
-
|
|
70
|
-
invalidated += int(
|
|
71
|
-
misses.append(entry.source_id)
|
|
77
|
+
if payload is not None:
|
|
78
|
+
invalid_keys.append(source.key)
|
|
79
|
+
invalidated += int(cached_invalidated or cached_value is not None)
|
|
80
|
+
misses.append(source.entry.source_id)
|
|
81
|
+
self.storage.delete_many(options, tuple(invalid_keys))
|
|
72
82
|
|
|
73
|
-
if misses or not inventory.entries:
|
|
83
|
+
if misses or not plan.inventory.entries:
|
|
74
84
|
self.reader.ensure_available(request.runtime)
|
|
75
|
-
extracted = self.reader.extract_entries(request, inventory, tuple(misses))
|
|
85
|
+
extracted = self.reader.extract_entries(request, plan.inventory, tuple(misses))
|
|
86
|
+
writes: list[tuple[CacheKey, bytes]] = []
|
|
76
87
|
for source_id in misses:
|
|
77
88
|
source_file = extracted.get(source_id)
|
|
78
89
|
if source_file is None:
|
|
79
90
|
raise RuntimeError(f"Extractor omitted a requested source file: {source_id}")
|
|
80
91
|
files[source_id] = source_file
|
|
81
|
-
|
|
92
|
+
source = sources_by_id[source_id]
|
|
93
|
+
writes.append((source.key, self.codec.encode(source.key, source_file.model_dump(mode="json"))))
|
|
94
|
+
self.storage.write_many(options, tuple(writes))
|
|
82
95
|
|
|
83
|
-
ordered_files = {entry.source_id: files[entry.source_id] for
|
|
96
|
+
ordered_files = {source.entry.source_id: files[source.entry.source_id] for source in plan.sources}
|
|
84
97
|
modules: dict[ModuleId, FileId] = {}
|
|
85
98
|
for file_id, source_file in ordered_files.items():
|
|
86
99
|
existing = modules.get(source_file.module_id)
|
|
@@ -91,28 +104,12 @@ class CacheApplication:
|
|
|
91
104
|
extraction = SourceExtraction(
|
|
92
105
|
files=ordered_files,
|
|
93
106
|
modules=modules,
|
|
94
|
-
files_found=inventory.files_found,
|
|
95
|
-
files_excluded=inventory.files_excluded,
|
|
96
|
-
directories_pruned=inventory.directories_pruned,
|
|
107
|
+
files_found=plan.inventory.files_found,
|
|
108
|
+
files_excluded=plan.inventory.files_excluded,
|
|
109
|
+
directories_pruned=plan.inventory.directories_pruned,
|
|
97
110
|
)
|
|
98
|
-
manifest = self.identity.manifest(request, policy, inventory.entries)
|
|
99
|
-
self._write(
|
|
100
|
-
options,
|
|
101
|
-
manifest,
|
|
102
|
-
{
|
|
103
|
-
"sources": [
|
|
104
|
-
{
|
|
105
|
-
"relative_path": entry.relative_path,
|
|
106
|
-
"content_digest": entry.content_digest,
|
|
107
|
-
"source_key": keys[entry.source_id].digest,
|
|
108
|
-
}
|
|
109
|
-
for entry in inventory.entries
|
|
110
|
-
]
|
|
111
|
-
},
|
|
112
|
-
)
|
|
113
|
-
self.prune(options)
|
|
114
111
|
return CachedResult(
|
|
115
|
-
value=
|
|
112
|
+
value=extraction,
|
|
116
113
|
outcomes=(
|
|
117
114
|
CacheOutcome(
|
|
118
115
|
stage=CacheStage.EXTRACTION,
|
|
@@ -126,35 +123,40 @@ class CacheApplication:
|
|
|
126
123
|
),
|
|
127
124
|
)
|
|
128
125
|
|
|
129
|
-
def
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
def maintain_manifest(self, plan: CachePlan, options: CacheOptions) -> bool:
|
|
127
|
+
expected = plan.manifest_value()
|
|
128
|
+
payload = self.storage.read(options, plan.manifest)
|
|
129
|
+
if payload is not None and self.codec.decode(plan.manifest, payload) == expected:
|
|
130
|
+
return False
|
|
131
|
+
return self._write(options, plan.manifest, expected)
|
|
132
|
+
|
|
133
|
+
def code_map(self, plan: CachePlan, options: CacheOptions) -> CachedResult[CodeMap | None]:
|
|
134
|
+
key = self.identity.code_map("", plan.manifest)
|
|
135
|
+
cached_value, cached_invalidated = self._read(options, key)
|
|
132
136
|
try:
|
|
133
|
-
value = CodeMap.model_validate(
|
|
137
|
+
value = CodeMap.model_validate(cached_value)
|
|
134
138
|
outcome = CacheOutcome(stage=CacheStage.CODE_MAP, namespace=options.namespace, hits=1)
|
|
135
139
|
except (TypeError, ValueError, ValidationError):
|
|
136
|
-
if
|
|
140
|
+
if cached_value is not None and not cached_invalidated:
|
|
137
141
|
self.storage.delete(options, key)
|
|
138
142
|
value = None
|
|
139
143
|
outcome = CacheOutcome(
|
|
140
144
|
stage=CacheStage.CODE_MAP,
|
|
141
145
|
namespace=options.namespace,
|
|
142
146
|
misses=1,
|
|
143
|
-
invalidated=int(
|
|
147
|
+
invalidated=int(cached_invalidated or cached_value is not None),
|
|
144
148
|
)
|
|
145
149
|
return CachedResult[CodeMap | None](value=value, outcomes=(outcome,))
|
|
146
150
|
|
|
147
|
-
def store_code_map(self,
|
|
148
|
-
self._write(options, self.identity.code_map("",
|
|
149
|
-
self.prune(options)
|
|
151
|
+
def store_code_map(self, plan: CachePlan, code_map: CodeMap, options: CacheOptions) -> None:
|
|
152
|
+
self._write(options, self.identity.code_map("", plan.manifest), code_map.model_dump(mode="json"))
|
|
150
153
|
|
|
151
154
|
def reports(
|
|
152
155
|
self, code_map: CodeMap, config: ArchitectureConfig, options: CacheOptions
|
|
153
156
|
) -> CachedResult[tuple[ReportNode, ...] | None]:
|
|
154
157
|
key = self.identity.reports(code_map, config)
|
|
155
|
-
|
|
156
|
-
cached_value
|
|
157
|
-
invalidated = cached.invalidated or cached_value is not None
|
|
158
|
+
cached_value, cached_invalidated = self._read(options, key)
|
|
159
|
+
invalidated = cached_invalidated or cached_value is not None
|
|
158
160
|
try:
|
|
159
161
|
if not isinstance(cached_value, list):
|
|
160
162
|
raise ValueError("Cached reports must be a list.")
|
|
@@ -162,7 +164,7 @@ class CacheApplication:
|
|
|
162
164
|
value = tuple(sorted(reports, key=lambda item: (item.metadata.order, item.metadata.id)))
|
|
163
165
|
outcome = CacheOutcome(stage=CacheStage.REPORTS, namespace=options.namespace, hits=1)
|
|
164
166
|
except (AttributeError, ImportError, KeyError, TypeError, ValueError, ValidationError):
|
|
165
|
-
if cached_value is not None and not
|
|
167
|
+
if cached_value is not None and not cached_invalidated:
|
|
166
168
|
self.storage.delete(options, key)
|
|
167
169
|
value = None
|
|
168
170
|
outcome = CacheOutcome(
|
|
@@ -188,32 +190,25 @@ class CacheApplication:
|
|
|
188
190
|
for report in reports
|
|
189
191
|
]
|
|
190
192
|
self._write(options, self.identity.reports(code_map, config), value)
|
|
191
|
-
|
|
193
|
+
|
|
194
|
+
def maintain(self, options: CacheOptions) -> bool:
|
|
195
|
+
return self.storage.enforce_capacity(options)
|
|
192
196
|
|
|
193
197
|
def clear(self, options: CacheOptions) -> None:
|
|
194
198
|
self.storage.clear(options)
|
|
195
199
|
|
|
196
|
-
def
|
|
197
|
-
entries = self.storage.entries(options)
|
|
198
|
-
total = sum(entry.size for entry in entries)
|
|
199
|
-
for entry in sorted(entries, key=lambda item: (item.last_access_ns, item.key.kind, item.key.digest)):
|
|
200
|
-
if total <= options.max_bytes:
|
|
201
|
-
break
|
|
202
|
-
self.storage.delete(options, entry.key)
|
|
203
|
-
total -= entry.size
|
|
204
|
-
|
|
205
|
-
def _read(self, options: CacheOptions, key: CacheKey) -> _CacheRead:
|
|
200
|
+
def _read(self, options: CacheOptions, key: CacheKey) -> tuple[object | None, bool]:
|
|
206
201
|
payload = self.storage.read(options, key)
|
|
207
202
|
if payload is None:
|
|
208
|
-
return
|
|
203
|
+
return None, False
|
|
209
204
|
value = self.codec.decode(key, payload)
|
|
210
205
|
if value is None:
|
|
211
206
|
self.storage.delete(options, key)
|
|
212
|
-
return
|
|
213
|
-
return
|
|
207
|
+
return None, True
|
|
208
|
+
return value, False
|
|
214
209
|
|
|
215
|
-
def _write(self, options: CacheOptions, key: CacheKey, value: object) ->
|
|
216
|
-
self.storage.write(options, key, self.codec.encode(key, value))
|
|
210
|
+
def _write(self, options: CacheOptions, key: CacheKey, value: object) -> bool:
|
|
211
|
+
return self.storage.write(options, key, self.codec.encode(key, value))
|
|
217
212
|
|
|
218
213
|
def _report(self, value: object) -> ReportNode:
|
|
219
214
|
if not isinstance(value, dict):
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
2
|
|
|
3
|
-
from .models.cache_entry import CacheEntry
|
|
4
3
|
from .models.cache_key import CacheKey
|
|
5
4
|
from .models.cache_options import CacheOptions
|
|
6
5
|
|
|
@@ -11,17 +10,29 @@ class CacheStorage(ABC):
|
|
|
11
10
|
raise NotImplementedError
|
|
12
11
|
|
|
13
12
|
@abstractmethod
|
|
14
|
-
def
|
|
13
|
+
def read_many(self, options: CacheOptions, keys: tuple[CacheKey, ...]) -> tuple[bytes | None, ...]:
|
|
15
14
|
raise NotImplementedError
|
|
16
15
|
|
|
17
16
|
@abstractmethod
|
|
18
|
-
def
|
|
17
|
+
def write(self, options: CacheOptions, key: CacheKey, payload: bytes) -> bool:
|
|
18
|
+
raise NotImplementedError
|
|
19
|
+
|
|
20
|
+
@abstractmethod
|
|
21
|
+
def write_many(self, options: CacheOptions, payloads: tuple[tuple[CacheKey, bytes], ...]) -> tuple[CacheKey, ...]:
|
|
19
22
|
raise NotImplementedError
|
|
20
23
|
|
|
21
24
|
@abstractmethod
|
|
22
25
|
def delete(self, options: CacheOptions, key: CacheKey) -> None:
|
|
23
26
|
raise NotImplementedError
|
|
24
27
|
|
|
28
|
+
@abstractmethod
|
|
29
|
+
def delete_many(self, options: CacheOptions, keys: tuple[CacheKey, ...]) -> None:
|
|
30
|
+
raise NotImplementedError
|
|
31
|
+
|
|
32
|
+
@abstractmethod
|
|
33
|
+
def enforce_capacity(self, options: CacheOptions) -> bool:
|
|
34
|
+
raise NotImplementedError
|
|
35
|
+
|
|
25
36
|
@abstractmethod
|
|
26
37
|
def clear(self, options: CacheOptions) -> None:
|
|
27
38
|
raise NotImplementedError
|
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
from enum import StrEnum
|
|
2
|
-
|
|
3
1
|
from pydantic import field_validator
|
|
4
2
|
|
|
5
3
|
from ....shared.values.models.value_model import ValueModel
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class CacheStage(StrEnum):
|
|
9
|
-
"""Public stages reported by cached Modwire operations."""
|
|
10
|
-
|
|
11
|
-
EXTRACTION = "extraction"
|
|
12
|
-
CODE_MAP = "code-map"
|
|
13
|
-
REPORTS = "reports"
|
|
4
|
+
from .cache_stage import CacheStage
|
|
14
5
|
|
|
15
6
|
|
|
16
7
|
class CacheOutcome(ValueModel):
|
|
17
8
|
"""Content-safe lifecycle counts for one stage of a cached operation.
|
|
18
9
|
|
|
19
|
-
Extraction counts describe current source records.
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
Extraction counts describe current source records. An exact code-map hit
|
|
11
|
+
reports its digest-backed manifest sources as extraction hits without loading
|
|
12
|
+
individual source payloads. Code-map and report counts describe one entry.
|
|
13
|
+
Invalidated entries are also misses. Diagnostics include the configured
|
|
14
|
+
namespace but never cache keys, source identities, or content.
|
|
22
15
|
"""
|
|
23
16
|
|
|
24
17
|
stage: CacheStage
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from ....shared.values.models.value_model import ValueModel
|
|
2
|
+
from ...pipeline.models.source_inventory import SourceInventory
|
|
3
|
+
from .cache_key import CacheKey
|
|
4
|
+
from .source_cache_entry import SourceCacheEntry
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CachePlan(ValueModel):
|
|
8
|
+
inventory: SourceInventory
|
|
9
|
+
sources: tuple[SourceCacheEntry, ...]
|
|
10
|
+
manifest: CacheKey
|
|
11
|
+
|
|
12
|
+
def manifest_value(self) -> dict[str, object]:
|
|
13
|
+
return {
|
|
14
|
+
"sources": [
|
|
15
|
+
{
|
|
16
|
+
"relative_path": source.entry.relative_path,
|
|
17
|
+
"content_digest": source.entry.content_digest,
|
|
18
|
+
"source_key": source.key.digest,
|
|
19
|
+
}
|
|
20
|
+
for source in sorted(self.sources, key=lambda item: item.entry.relative_path)
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from ....shared.values.models.value_model import ValueModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CacheStorageState(ValueModel):
|
|
9
|
+
schema_version: Literal[1] = 1
|
|
10
|
+
total_bytes: int = Field(ge=0)
|
|
11
|
+
entry_count: int = Field(ge=0)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from pydantic import field_validator
|
|
2
2
|
|
|
3
3
|
from ....shared.values.models.value_model import ValueModel
|
|
4
|
-
from .cache_outcome import CacheOutcome
|
|
4
|
+
from .cache_outcome import CacheOutcome
|
|
5
|
+
from .cache_stage import CacheStage
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class CachedResult[Result](ValueModel):
|