mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 11:49:28 +00:00
74 lines
3.2 KiB
Python
74 lines
3.2 KiB
Python
"""Where the `[[layout]]` facts meet a repository: which paths are vendored, which are tests.
|
|
|
|
One place, imported by the preprocessor (vendored trees leave the targets), the scan (test regions are
|
|
not product, and vendored directories leave the graph) and the position benchmark (so it measures the
|
|
order the scan spends). Facts are rows; this is only the matching.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import fnmatch
|
|
from collections.abc import Iterable, Sequence
|
|
from pathlib import Path
|
|
|
|
from ..semantic.facts import LayoutFact, load_facts
|
|
from .regions import ScanRegion
|
|
|
|
|
|
def layout_facts(language: str | None = None) -> tuple[LayoutFact, ...]:
|
|
"""The layout rows -- for one language, or for every language when the question is about a tree."""
|
|
facts = load_facts()
|
|
return tuple(facts.for_language(language).layouts if language else facts.layouts)
|
|
|
|
|
|
def _matches(relative: str, patterns: Iterable[str]) -> bool:
|
|
"""gitignore-style: `dir/` names a directory at any depth, anything else a path or basename glob."""
|
|
parts = relative.split("/")
|
|
for pattern in patterns:
|
|
if pattern.endswith("/"):
|
|
directory = pattern.rstrip("/")
|
|
if any(
|
|
fnmatch.fnmatch("/".join(parts[start:end]), directory)
|
|
for start in range(len(parts))
|
|
for end in range(start + 1, len(parts) + 1)
|
|
):
|
|
return True
|
|
elif fnmatch.fnmatch(relative, pattern) or fnmatch.fnmatch(parts[-1], pattern):
|
|
return True
|
|
return False
|
|
|
|
|
|
def is_vendored(relative: str, facts: Sequence[LayoutFact] | None = None) -> bool:
|
|
rows = facts if facts is not None else layout_facts()
|
|
return _matches(relative, (p for fact in rows for p in fact.vendored))
|
|
|
|
|
|
def is_test_path(relative: str, facts: Sequence[LayoutFact] | None = None) -> bool:
|
|
rows = facts if facts is not None else layout_facts()
|
|
return _matches(relative, (p for fact in rows for p in fact.tests))
|
|
|
|
|
|
def vendored_directories(root: Path, facts: Sequence[LayoutFact] | None = None) -> tuple[str, ...]:
|
|
"""The vendored directories actually present under ``root``, repository-relative, shallowest first --
|
|
what a frontend's ``--exclude`` takes."""
|
|
rows = facts if facts is not None else layout_facts()
|
|
names = {p.rstrip("/") for fact in rows for p in fact.vendored if p.endswith("/")}
|
|
found: list[str] = []
|
|
for path in sorted(root.rglob("*")):
|
|
if not path.is_dir() or path.name not in names:
|
|
continue
|
|
relative = path.relative_to(root).as_posix()
|
|
if any(relative.startswith(f"{seen}/") for seen in found):
|
|
continue # already covered by a shallower vendored directory
|
|
found.append(relative)
|
|
return tuple(found)
|
|
|
|
|
|
def with_layout(regions: Sequence[ScanRegion], facts: Sequence[LayoutFact] | None = None) -> tuple[ScanRegion, ...]:
|
|
"""Test-path regions marked not shipped -- ordered after the product's, never removed. A region a
|
|
build manifest already declared shipped stays so: the manifest is the project's own word."""
|
|
from dataclasses import replace
|
|
|
|
rows = facts if facts is not None else layout_facts()
|
|
return tuple(replace(r, shipped=False) if r.shipped and is_test_path(r.path, rows) else r for r in regions)
|