sourcecode 2.5.12__tar.gz → 2.5.13__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-2.5.12 → sourcecode-2.5.13}/CHANGELOG.md +32 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/PKG-INFO +1 -1
- {sourcecode-2.5.12 → sourcecode-2.5.13}/pyproject.toml +1 -1
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/__init__.py +1 -1
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/path_filters.py +48 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/repository_ir.py +32 -1
- {sourcecode-2.5.12 → sourcecode-2.5.13}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/.gitignore +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/.ruff.toml +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/CONTRIBUTING.md +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/LICENSE +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/README.md +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/SECURITY.md +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/raw +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/archetype.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/cache.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/classifier.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/cli.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/context_cache.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/context_graph.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/dynamic_argument_surface.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/explain.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/format_contract.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/license.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/migrate_check.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/progress.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/reconciliation.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/redactor.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/__init__.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/context.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/errors.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/executor.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/planner.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/query.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/request.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/resolution.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/result.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/retriever.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/runtime.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/steps.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/steps_graph.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/steps_impact.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/steps_intf.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/steps_struct.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/retrieval/steps_txsec.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/ris.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/scanner.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/schema.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/security_config.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/serializer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/spring_impact.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/validation_inference.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/validation_surface.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/version_check.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/src/sourcecode/workspace.py +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/supabase/functions/README.md +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-2.5.12 → sourcecode-2.5.13}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.5.13] — 2026-07-18
|
|
4
|
+
|
|
5
|
+
**Test-fixture endpoints no longer pollute the production API surface.** Post-F1 field
|
|
6
|
+
validation (neo4j, keycloak) found that a JAX-RS / Spring resource shipping under
|
|
7
|
+
`src/main` of a test-utility module — a dummy web service, an Arquillian test-harness
|
|
8
|
+
resource — was reported flat as production API surface with no scope qualifier. This
|
|
9
|
+
inflated endpoint counts and injected phantom attack surface into security exploration,
|
|
10
|
+
the exact task the endpoint command is meant to serve, with no warning. This is the one
|
|
11
|
+
defect the post-F1 review classified as blocking.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **Endpoints from test-fixture / test-utility modules are excluded from the production
|
|
16
|
+
surface** (`repository_ir.py`, `path_filters.py`): a new structural, name-agnostic
|
|
17
|
+
helper `is_test_fixture_module_path` flags a module directory segment that carries a
|
|
18
|
+
delimited `test` token *together* with an infrastructure word (`util(s)`, `fixture(s)`,
|
|
19
|
+
`support`, `framework`, `kit`, `harness`, `tools`, `helper(s)`, `mock(s)`, `stub(s)`,
|
|
20
|
+
`dummy`) — e.g. `server-test-utils`, `foo-testkit`, `bar-test-support` — or a known
|
|
21
|
+
test-module segment (`testsuite`, `integration-arquillian`, `test-framework`). Requiring
|
|
22
|
+
both tokens in the *same* segment keeps legitimate `utils` / `support` / `tools` packages
|
|
23
|
+
from ever matching. `extract_java_endpoints` traces each endpoint back to its declaring
|
|
24
|
+
module and, when it is a test fixture, drops it from `endpoints` / `total` /
|
|
25
|
+
`no_security_signal` and the security-model heuristics. The exclusion is **transparent,
|
|
26
|
+
not silent**: excluded entries are preserved in a `test_util_endpoints` bucket with a
|
|
27
|
+
`scope: "test_util"` tag, a `test_util_excluded` count, and an explanatory `notes` entry.
|
|
28
|
+
Measured: neo4j 18 → 14 production (4 dummy `DummyThirdPartyWebService` endpoints moved to
|
|
29
|
+
the bucket); keycloak 775 → 673 production (102 Arquillian/test-framework harness
|
|
30
|
+
endpoints excluded). Control repos unchanged (spaghetti-api 7, petclinic 17, eureka 18,
|
|
31
|
+
Broadleaf 225). `is_test_or_fixture_path` and the migrate-check blocking count it feeds are
|
|
32
|
+
deliberately untouched — the new helper is narrower and wired only into endpoint
|
|
33
|
+
extraction.
|
|
34
|
+
|
|
3
35
|
## [2.5.12] — 2026-07-18
|
|
4
36
|
|
|
5
37
|
**F-1 (the Evidence Reconciliation Layer) is closed and its rule core frozen.** This release
|
|
@@ -120,6 +120,54 @@ def is_test_or_fixture_path(path: str) -> bool:
|
|
|
120
120
|
return False
|
|
121
121
|
|
|
122
122
|
|
|
123
|
+
# Infrastructure words that, combined with a delimited "test" token in the same
|
|
124
|
+
# directory segment, identify a module whose code is test scaffolding even though
|
|
125
|
+
# it lives under src/main (e.g. "server-test-utils", "foo-testkit"). Kept narrow
|
|
126
|
+
# on purpose: the "test" token must be present in the SAME segment, so packages
|
|
127
|
+
# named "utils"/"support"/"tools" alone never match.
|
|
128
|
+
_TEST_INFRA_TOKENS = frozenset({
|
|
129
|
+
"util", "utils", "fixture", "fixtures", "support",
|
|
130
|
+
"framework", "kit", "harness", "tools", "tool",
|
|
131
|
+
"helper", "helpers", "mock", "mocks", "stub", "stubs", "dummy",
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
# Glued (non-hyphenated) test-fixture module suffixes.
|
|
135
|
+
_TEST_INFRA_SUFFIXES = (
|
|
136
|
+
"testutils", "testutil", "testkit", "testfixtures", "testfixture",
|
|
137
|
+
"testsupport", "testframework", "testharness", "testtools",
|
|
138
|
+
"testhelpers", "testmocks", "teststubs",
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def is_test_fixture_module_path(path: str) -> bool:
|
|
143
|
+
"""Return True when *path* belongs to a test-fixture / test-utility MODULE.
|
|
144
|
+
|
|
145
|
+
Structural, name-agnostic: a directory segment must contain a hyphen/underscore
|
|
146
|
+
-delimited ``test`` token together with an infrastructure word (util(s),
|
|
147
|
+
fixture(s), support, framework, kit, harness, tools, helper(s), mock(s),
|
|
148
|
+
stub(s), dummy) — e.g. ``server-test-utils``, ``foo-testkit``,
|
|
149
|
+
``bar-test-support`` — or match a known test-module segment outright.
|
|
150
|
+
|
|
151
|
+
This is deliberately NARROWER than :func:`is_test_or_fixture_path`: it targets
|
|
152
|
+
modules that ship HTTP resources, JAX-RS ``@Path`` fixtures, or dummy
|
|
153
|
+
controllers under ``src/main`` so they are not misreported as production API
|
|
154
|
+
surface. Requiring both tokens in one segment keeps legitimate ``utils`` /
|
|
155
|
+
``support`` / ``tools`` packages from ever matching.
|
|
156
|
+
"""
|
|
157
|
+
norm = path.replace("\\", "/").lower()
|
|
158
|
+
parts = norm.split("/")
|
|
159
|
+
for part in parts[:-1]: # skip the filename
|
|
160
|
+
bare = part.rstrip("/")
|
|
161
|
+
if bare in _TEST_MODULE_SEGMENTS:
|
|
162
|
+
return True
|
|
163
|
+
if bare.endswith(_TEST_INFRA_SUFFIXES):
|
|
164
|
+
return True
|
|
165
|
+
toks = bare.replace("_", "-").split("-")
|
|
166
|
+
if "test" in toks and any(t in _TEST_INFRA_TOKENS for t in toks):
|
|
167
|
+
return True
|
|
168
|
+
return False
|
|
169
|
+
|
|
170
|
+
|
|
123
171
|
def is_vendor_path(path: str) -> bool:
|
|
124
172
|
"""Return True when *path* is inside a vendored / third-party directory.
|
|
125
173
|
|
|
@@ -5584,7 +5584,7 @@ def extract_java_endpoints(root: Path) -> "dict[str, Any]":
|
|
|
5584
5584
|
"""
|
|
5585
5585
|
import re as _re
|
|
5586
5586
|
from typing import Any as _Any
|
|
5587
|
-
from sourcecode.path_filters import is_test_path
|
|
5587
|
+
from sourcecode.path_filters import is_test_path, is_test_fixture_module_path
|
|
5588
5588
|
|
|
5589
5589
|
_EXTENDS_FROM_SIG = _re.compile(r'\bextends\s+(\w+)')
|
|
5590
5590
|
|
|
@@ -5753,6 +5753,16 @@ def extract_java_endpoints(root: Path) -> "dict[str, Any]":
|
|
|
5753
5753
|
endpoint_warnings = _recovery["warnings"]
|
|
5754
5754
|
_openapi_spec_path = _recovery["spec_path"]
|
|
5755
5755
|
|
|
5756
|
+
# Map each declared class/interface FQN to its source file so an endpoint can be
|
|
5757
|
+
# traced back to the MODULE that ships it. Used to flag endpoints that originate
|
|
5758
|
+
# in a test-fixture / test-utility module (dummy web services, JAX-RS @Path
|
|
5759
|
+
# fixtures) living under src/main — these are not production API surface.
|
|
5760
|
+
_fqn_to_file: dict[str, str] = {
|
|
5761
|
+
s.symbol: (s.source_file or s.declaring_file)
|
|
5762
|
+
for s in all_symbols
|
|
5763
|
+
if s.type in ("class", "interface")
|
|
5764
|
+
}
|
|
5765
|
+
|
|
5756
5766
|
endpoints: list[dict] = []
|
|
5757
5767
|
for route in routes:
|
|
5758
5768
|
handler = (
|
|
@@ -5769,6 +5779,9 @@ def extract_java_endpoints(root: Path) -> "dict[str, Any]":
|
|
|
5769
5779
|
"handler": handler,
|
|
5770
5780
|
"return_type": route.get("return_type", "void"),
|
|
5771
5781
|
}
|
|
5782
|
+
_src = _fqn_to_file.get(route.get("effective_class", ""), "")
|
|
5783
|
+
if _src and is_test_fixture_module_path(_src):
|
|
5784
|
+
entry["scope"] = "test_util"
|
|
5772
5785
|
# Use security_annotations already extracted by _build_route_surface
|
|
5773
5786
|
# via the canonical _route_security_from_sym extractor.
|
|
5774
5787
|
security_info = route.get("security_annotations")
|
|
@@ -5791,6 +5804,14 @@ def extract_java_endpoints(root: Path) -> "dict[str, Any]":
|
|
|
5791
5804
|
)
|
|
5792
5805
|
endpoints = [e for e in endpoints if not _FQN_PATH_RE.search(e.get("path", ""))]
|
|
5793
5806
|
|
|
5807
|
+
# Partition test-fixture/test-utility endpoints out of the production surface.
|
|
5808
|
+
# They ship under src/main of a *-test-utils / *-testkit / test-framework module
|
|
5809
|
+
# (dummy web services, JAX-RS @Path fixtures) and must not be reported as, or
|
|
5810
|
+
# counted with, the real API surface — but they are preserved in their own bucket
|
|
5811
|
+
# so nothing is silently dropped and the exclusion is auditable.
|
|
5812
|
+
_test_util_endpoints = [e for e in endpoints if e.get("scope") == "test_util"]
|
|
5813
|
+
endpoints = [e for e in endpoints if e.get("scope") != "test_util"]
|
|
5814
|
+
|
|
5794
5815
|
# "no_security_signal" = no recognized security annotation at method OR class level.
|
|
5795
5816
|
# Note: repos may use framework-level security (e.g. Keycloak itself) with no
|
|
5796
5817
|
# per-endpoint annotations — this count reflects annotation-based coverage only.
|
|
@@ -5919,6 +5940,16 @@ def extract_java_endpoints(root: Path) -> "dict[str, Any]":
|
|
|
5919
5940
|
# Keep legacy field name for backward compat, now means same as no_security_signal
|
|
5920
5941
|
"undocumented": no_security_signal,
|
|
5921
5942
|
}
|
|
5943
|
+
# Surface test-fixture endpoints excluded from the production surface above.
|
|
5944
|
+
# Reported separately (not hidden) so the exclusion is transparent and auditable.
|
|
5945
|
+
if _test_util_endpoints:
|
|
5946
|
+
result["test_util_endpoints"] = _test_util_endpoints
|
|
5947
|
+
result["test_util_excluded"] = len(_test_util_endpoints)
|
|
5948
|
+
result.setdefault("notes", []).append(
|
|
5949
|
+
f"{len(_test_util_endpoints)} endpoint(s) from test-fixture/test-utility "
|
|
5950
|
+
f"module(s) under src/main were excluded from the production surface "
|
|
5951
|
+
f"(see test_util_endpoints)."
|
|
5952
|
+
)
|
|
5922
5953
|
# Surface incomplete-endpoint warnings (interface-defined controllers) only when
|
|
5923
5954
|
# present, to keep output backward-compatible for the common case.
|
|
5924
5955
|
if endpoint_warnings:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|