|
oct
|
Functions | |
| bool | _at_or_above_temp_boundary (Path candidate, Path|None temp_boundary) |
| Path | find_project_root (Path start) |
| Path | get_project_root (click.Context ctx) |
| bool | is_within_project_root (Path path, Path project_root) |
| Path | validate_path_containment (Path path, Path project_root, bool allow_outside=False) |
Variables | |
| int | MAX_OCTRC_SIZE = 64 * 1024 |
Purpose
-------
Provide shared logic for detecting the root of an Option C project.
Responsibilities
----------------
- Walk upward from the current directory.
- Identify the project root by required directories.
Diagnostics
-----------
Domain: OCT-CORE
Levels:
L2 - (none) a failed search raises through click rather than logging
L3 - root search entry, and each containment check with its verdict
L4 - (none)
Contracts
---------
- Root discovery never adopts a root at or above the OS temp boundary.
- ``.octrc.json`` files larger than :data:`MAX_OCTRC_SIZE` are skipped
rather than read, so an oversized parent config cannot exhaust memory.
- ``is_within_project_root`` is the containment predicate; every caller
that needs to refuse an escaping path goes through it or
``validate_path_containment``.
Dependencies
------------
- oct.core.diagnostics (_dbg structured logger)
- click (ClickException for a failed root search, a rejected --root-dir or an escaping path; echo for the diagnostics/ deprecation warning; the Context carrying --root-dir)
|
protected |
Return True if *candidate* is the OS temp dir or an ancestor of it. FS-560 / Plan 151 T6: root discovery must never adopt a project root at or above ``tempfile.gettempdir()``. A stray ``.option_c/`` (or other) root marker at the temp root would otherwise let the walk-up ESCAPE a per-test tmp sandbox and run git-mutating operations at the temp root - the reproducible environment-poisoning loop diagnosed in Plan 151 T3 (a marker at ``%TEMP%\\.option_c`` fabricated 14 oc_chat + 17 oct false failures by git-initialising ``%TEMP%``). Markers STRICTLY BELOW the temp boundary - legitimate pytest ``tmp_path`` projects, which always live under a ``pytest-*`` subdir of the temp root - are unaffected. Never raises: an unresolvable path is treated as "not above the boundary" so discovery degrades to its pre-fix behaviour rather than failing closed on an IO error.
Definition at line 52 of file project_root.py.
| Path project_root.find_project_root | ( | Path | start | ) |
Definition at line 85 of file project_root.py.
| Path project_root.get_project_root | ( | click.Context | ctx | ) |
Return project root from --root-dir override or auto-detection. When ``--root-dir`` is supplied, OI-405 requires the target directory to look like an Option C project (contain ``pyproject.toml`` or ``.octrc.json``). If the user intentionally wants to point at an unrelated directory, they must also pass ``--allow-outside-project``, which is recorded in ``ctx.obj``.
Definition at line 169 of file project_root.py.
| bool project_root.is_within_project_root | ( | Path | path, |
| Path | project_root ) |
Pure predicate: True if ``path`` resolves inside ``project_root``. Symlink-safe: both sides are resolved before comparison so symlink targets cannot escape the project root. Never raises - any ``OSError`` during resolution is treated as "not inside". Intended for library callers (e.g. ``oct.core.git``) that must not depend on Click.
Definition at line 201 of file project_root.py.
| Path project_root.validate_path_containment | ( | Path | path, |
| Path | project_root, | ||
| bool | allow_outside = False ) |
Resolve ``path`` and verify it is within ``project_root``. If ``allow_outside`` is True, the resolved path is returned without containment enforcement. Otherwise, a ``click.ClickException`` is raised when the path falls outside ``project_root``. Used by export and clean commands to prevent accidental operations on files outside the project via symlink tricks or bare ``..`` paths (OI-405).
Definition at line 221 of file project_root.py.
| int project_root.MAX_OCTRC_SIZE = 64 * 1024 |
Definition at line 49 of file project_root.py.