mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 19:59:26 +00:00
fix(contributor-scan): retain declared Gruntfile and report census gaps honestly
This commit is contained in:
@@ -267,7 +267,11 @@ class NullBackend:
|
||||
|
||||
|
||||
def engine_runtime_identity(
|
||||
*, include_tests: bool = True, language: str | None = None, execution_budget: ExecutionBudget | None = None
|
||||
*,
|
||||
include_tests: bool = True,
|
||||
include_build_configs: bool = True,
|
||||
language: str | None = None,
|
||||
execution_budget: ExecutionBudget | None = None,
|
||||
) -> str:
|
||||
"""Installed frontend/adaptation bytes, also used by comparison eligibility provenance."""
|
||||
from .artifact import digest_value, graph_bytes
|
||||
@@ -296,6 +300,7 @@ def engine_runtime_identity(
|
||||
"version": version,
|
||||
"files": installation,
|
||||
"include_tests": include_tests,
|
||||
"include_build_configs": include_build_configs,
|
||||
"java_options": os.environ.get("JAVA_TOOL_OPTIONS", ""),
|
||||
}
|
||||
)
|
||||
@@ -307,6 +312,7 @@ class JoernBackend:
|
||||
|
||||
runner: Runner | None = None
|
||||
include_tests: bool = True # Explicit input policy for the versioned frontend adaptation.
|
||||
include_build_configs: bool = True # Explicit retention of supported build configuration source.
|
||||
build_timeout: int = BUILD_TIMEOUT_SECONDS
|
||||
query_timeout: int = field(default_factory=lambda: _configured_timeout())
|
||||
heap_mb: int = 0 # 0 means read the environment, then fall back to CPG_HEAP_MB
|
||||
@@ -380,10 +386,14 @@ class JoernBackend:
|
||||
(("implementation", code),),
|
||||
(
|
||||
("include_tests", str(self.include_tests)),
|
||||
("include_build_configs", str(self.include_build_configs)),
|
||||
(
|
||||
"installation",
|
||||
engine_runtime_identity(
|
||||
include_tests=self.include_tests, language=language, execution_budget=execution_budget or self.execution_budget
|
||||
include_tests=self.include_tests,
|
||||
include_build_configs=self.include_build_configs,
|
||||
language=language,
|
||||
execution_budget=execution_budget or self.execution_budget,
|
||||
),
|
||||
),
|
||||
("java_options", os.environ.get("JAVA_TOOL_OPTIONS", "default") or "default"),
|
||||
@@ -1189,6 +1199,7 @@ class JoernBackend:
|
||||
"""
|
||||
env = dict(os.environ)
|
||||
env["OUSAST_INCLUDE_TESTS"] = "1" if self.include_tests else "0"
|
||||
env["OUSAST_INCLUDE_BUILD_CONFIGS"] = "1" if self.include_build_configs else "0"
|
||||
env["JAVA_TOOL_OPTIONS"] = f"{env.get('JAVA_TOOL_OPTIONS', '').strip()} -Xmx{self._heap_mb()}m".strip()
|
||||
return env
|
||||
|
||||
|
||||
@@ -106,6 +106,9 @@ class PartitionGraph:
|
||||
raw = batch(kind, selected) if callable(batch) else {rid: graph.run(kind, params) for rid, params in selected.items()}
|
||||
if not isinstance(raw, Mapping):
|
||||
continue
|
||||
raw = dict(raw)
|
||||
if not isinstance(raw.get("__census__"), list):
|
||||
raw["__census__"] = []
|
||||
for rid, rows in raw.items():
|
||||
if rid in selected and isinstance(rows, list):
|
||||
answers[rid] = self._normalize(rows)
|
||||
@@ -117,17 +120,18 @@ class PartitionGraph:
|
||||
observed = {p.removeprefix("./") for n in names if isinstance(n, list) for p in n if isinstance(p, str)}
|
||||
if not named or not expected <= observed:
|
||||
self.diagnostics.append("partition_file_census_incomplete" if named else "partition_file_census_unavailable")
|
||||
reason = "partition_file_census_incomplete" if named else "partition_file_census_unavailable"
|
||||
rows = [
|
||||
{
|
||||
"methods": 0,
|
||||
"files": 0,
|
||||
"shards": max((int(str(r.get("shards", 1))) for r in rows if isinstance(r, Mapping)), default=1),
|
||||
}
|
||||
]
|
||||
dict(r, census_failure=reason, missing_file_names=sorted(expected - observed) if named else [])
|
||||
for r in normalized
|
||||
if isinstance(r, Mapping)
|
||||
] or [{"census_failure": reason, "missing_file_names": []}]
|
||||
# Preserve any individual empty or sharded graph's degradation.
|
||||
previous = answers.get(rid, [])
|
||||
if not previous or any(
|
||||
isinstance(r, Mapping) and (int(str(r.get("methods", 0))) == 0 or int(str(r.get("shards", 1))) > 1) for r in rows
|
||||
isinstance(r, Mapping)
|
||||
and (r.get("census_failure") or int(str(r.get("methods", 0))) == 0 or int(str(r.get("shards", 1))) > 1)
|
||||
for r in rows
|
||||
):
|
||||
answers[rid] = rows
|
||||
return answers
|
||||
|
||||
@@ -355,6 +355,8 @@ def _scan_repository_impl(
|
||||
in {
|
||||
"files_unparsed",
|
||||
"cpg_empty",
|
||||
"partition_file_census_incomplete",
|
||||
"partition_file_census_unavailable",
|
||||
"cpg_sharded",
|
||||
"cross_partition_semantics_unresolved",
|
||||
"vendor_semantics_unresolved",
|
||||
@@ -410,8 +412,14 @@ def _scan_repository_impl(
|
||||
if census and not census_reported:
|
||||
entry = census[0] if isinstance(census[0], Mapping) else {}
|
||||
methods = int(str(entry.get("methods", "0")) or 0)
|
||||
if methods == 0:
|
||||
degradations.append({"stage": "model", "reason": "cpg_empty", "files": int(str(entry.get("files", "0")) or 0)})
|
||||
if methods == 0 or entry.get("census_failure"):
|
||||
degradations.append(
|
||||
{
|
||||
"stage": "model",
|
||||
"reason": "cpg_empty" if "methods" in entry and methods == 0 else entry.get("census_failure", "cpg_empty"),
|
||||
**{k: entry[k] for k in ("methods", "files", "missing_file_names") if k in entry},
|
||||
}
|
||||
)
|
||||
# More than one graph means some files could only be built apart from the rest, and a
|
||||
# flow whose source is in one shard and whose sink is in another does not exist for any
|
||||
# question we can ask. Reporting the split is the difference between a partial answer and
|
||||
@@ -508,6 +516,8 @@ def _scan_repository_impl(
|
||||
in {
|
||||
"files_unparsed",
|
||||
"cpg_empty",
|
||||
"partition_file_census_incomplete",
|
||||
"partition_file_census_unavailable",
|
||||
"cpg_sharded",
|
||||
"cross_partition_semantics_unresolved",
|
||||
"vendor_semantics_unresolved",
|
||||
@@ -741,8 +751,14 @@ def _evidence_pass(
|
||||
shards = int(str(entry.get("shards", "1")))
|
||||
except ValueError:
|
||||
methods, shards = 0, 1
|
||||
if methods <= 0:
|
||||
degradations.append({"stage": "model", "reason": "cpg_empty"})
|
||||
if methods <= 0 or entry.get("census_failure"):
|
||||
degradations.append(
|
||||
{
|
||||
"stage": "model",
|
||||
"reason": "cpg_empty" if "methods" in entry and methods <= 0 else entry.get("census_failure", "cpg_empty"),
|
||||
**{k: entry[k] for k in ("methods", "files", "missing_file_names") if k in entry},
|
||||
}
|
||||
)
|
||||
if shards > 1:
|
||||
degradations.append({"stage": "model", "reason": "cpg_sharded", "shards": shards})
|
||||
by_rid = {rid: (region, spec) for rid, region, spec in work}
|
||||
|
||||
Reference in New Issue
Block a user