oct
Loading...
Searching...
No Matches
project_root Namespace Reference

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

Detailed Description

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)

Function Documentation

◆ _at_or_above_temp_boundary()

bool project_root._at_or_above_temp_boundary ( Path candidate,
Path | None temp_boundary )
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.

Here is the caller graph for this function:

◆ find_project_root()

Path project_root.find_project_root ( Path start)

Definition at line 85 of file project_root.py.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_project_root()

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.

Here is the call graph for this function:

◆ is_within_project_root()

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.

Here is the caller graph for this function:

◆ validate_path_containment()

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.

Here is the call graph for this function:

Variable Documentation

◆ MAX_OCTRC_SIZE

int project_root.MAX_OCTRC_SIZE = 64 * 1024

Definition at line 49 of file project_root.py.