|
| PreCommitResult | pre_commit_checks (Path project_root, str branch, str message, bool force_commit, str profile, dict octrc) |
| list[Path] | _resolve_scope (Path project_root, Literal["staged", "changed", "all"] scope) |
| list[Path] | _walk_secret_filenames (Path project_root, *, exclude_dirs, wildcard_exclude_dirs, patterns) |
| | _build_linter_context (Path project_root) |
| | _build_formatter_context (Path project_root, *, bool fix_mode=False) |
| list[tuple[str, int, str]] | _run_secrets_pass (list[Path] all_files, Path project_root, *, float code_entropy_threshold=4.5, float docstring_entropy_threshold=5.0, float comment_entropy_threshold=5.0, str secret_match_mode="substring", list[dict]|None entropy_exclusions=None, list[str]|None excluded_field_patterns=None) |
| tuple[int, list[dict]] | _run_lint_pass (list[Path] py_files, Path project_root, str profile, bool fix_mode=False) |
| int | _run_format_pass (list[Path] py_files, Path project_root, bool fix_mode=False) |
| int | _run_test_pass (Path project_root, bool sandbox=False) |
| QualityGateResult | run_quality_gate (Path project_root, Literal["staged", "changed", "all"] scope, Literal["proto", "compact", "strict"] profile, bool include_tests=False, bool fix=False, bool sandbox=False) |
| QualityGateResult | run_quality_gate_on_files (Path project_root, list[Path] files, Literal["proto", "compact", "strict"] profile, bool include_tests=False, bool fix=False, bool sandbox=False) |
Purpose
-------
Orchestrate the Phase 4B unified quality gate: lint + format dry-run +
secrets detection on a scoped set of files. Returns a structured
:class:`QualityGateResult` that downstream consumers (``oct git check``,
``oct git commit``, hooks, MCP) can inspect and render.
Responsibilities
----------------
- Resolve file scope (staged / changed / all) via :mod:`oct.core.git`.
- Run the linter on Python files via :func:`oct.linter.oct_lint._lint_single_file`.
- Run the formatter in dry-run mode via :func:`oct.formatter.oct_format.format_file`.
- Run secrets detection (content + filename pattern) via
:func:`oct.linter.oct_lint.check_no_hardcoded_secrets` and
:data:`oct.core.exclusions.NEVER_EXPORT_FILE_PATTERNS`.
- Optionally run pytest via subprocess (``--include-tests``).
- Support ``--fix`` two-pass mode: detect → fix → re-verify.
Diagnostics
-----------
Domain: GIT
Levels:
L2 — lifecycle: gate start/end, scope resolution
L3 — details: per-pass summary counts
L4 — deep trace: per-file check outcomes
Contracts
---------
- This module does not import ``click``. It is a pure orchestrator.
- It calls existing library functions (linter, formatter, exclusions)
directly; it never shells out to ``oct lint`` or ``oct format``.
- The only subprocess call is for pytest (``--include-tests``), which is
a distinct tool boundary.
- :func:`run_quality_gate` never raises on check failures; it returns
a :class:`QualityGateResult` with the findings. Only infrastructure
errors (missing git repo, broken imports) may propagate.
| int oct.git.quality_gate._run_test_pass |
( |
Path | project_root, |
|
|
bool | sandbox = False ) |
|
protected |
Run ``python -m pytest tests/`` and return the failure count.
Returns 0 if all tests pass (exit code 0), or 1 if any test fails
(non-zero exit code). This is a subprocess boundary — tests are a
distinct tool and their execution is not inline.
When ``sandbox=True`` (OI-517), the pytest subprocess runs under a
sanitised environment via :class:`oct.mcp.sandbox.SandboxExecutor`:
secret-named env vars are stripped, ``PYTHONPATH`` is dropped, and a
600s wall-clock ceiling is enforced. Output is capped at 1 MiB so a
runaway test cannot flood stderr.
Definition at line 498 of file quality_gate.py.
| QualityGateResult oct.git.quality_gate.run_quality_gate |
( |
Path | project_root, |
|
|
Literal["staged", "changed", "all"] | scope, |
|
|
Literal["proto", "compact", "strict"] | profile, |
|
|
bool | include_tests = False, |
|
|
bool | fix = False, |
|
|
bool | sandbox = False ) |
Orchestrate lint + format-dry-run + secrets on the scoped files.
When ``fix=True``, runs in two passes:
1. **Detect pass:** run the gate with ``fix=False`` to record the
initial state.
2. **Fix pass:** run lint and format with ``fix_mode=True`` to apply
auto-fixes.
3. **Re-verify pass:** run the gate again with ``fix=False``. The
returned result reflects the post-fix state.
Secrets are **never** auto-fixed (no safe auto-fix for a hardcoded
password). The ``--fix`` flag does not bypass the always-blocking
secrets rule.
Parameters
----------
project_root
Resolved project root containing ``.octrc.json``, ``tests/``, etc.
scope
``"staged"`` checks only the git index; ``"changed"`` checks
staged + unstaged + untracked; ``"all"`` checks every Python file.
profile
Lint profile: ``"proto"`` / ``"compact"`` / ``"strict"``.
include_tests
If True, also run ``pytest`` as a subprocess (exit code 4 on fail).
fix
If True, attempt auto-fix of lint/format violations, then re-check.
sandbox
OI-517: when True and ``include_tests`` is True, the pytest
subprocess runs under the MCP sandbox environment — sanitised
env, no network side-channels via PYTHONPATH, output capped.
Definition at line 545 of file quality_gate.py.
| QualityGateResult oct.git.quality_gate.run_quality_gate_on_files |
( |
Path | project_root, |
|
|
list[Path] | files, |
|
|
Literal["proto", "compact", "strict"] | profile, |
|
|
bool | include_tests = False, |
|
|
bool | fix = False, |
|
|
bool | sandbox = False ) |
Run the quality gate on an explicit file list.
Identical contract to :func:`run_quality_gate` but accepts a
pre-resolved list of files instead of computing one from a scope
string. This is the entry point used by F1.3 per-subproject
fan-out at workspace-level commit, where the workspace-wide
staged set is grouped into subproject buckets and each bucket
runs under its own profile.
Parameters
----------
project_root
Resolved project root for octrc / linter-context / secrets
config loading. For a per-subproject call, pass the
subproject's path; for a workspace-level call, pass the
workspace root.
files
Pre-filtered list of files to lint / format / scan. May
include non-Python files (passed through to the secrets
scanner; lint/format ignore them via the suffix filter).
profile
Lint profile: ``"proto"`` / ``"compact"`` / ``"strict"``.
include_tests, fix, sandbox
Same semantics as :func:`run_quality_gate`.
Definition at line 604 of file quality_gate.py.