oct
Loading...
Searching...
No Matches
paths.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# oct/core/paths.py
4
5"""
6Purpose
7-------
8Provide a single canonical helper for rendering filesystem paths in
9user-facing output. OCT commands (``oct lint``, ``oct health``, ``oct
10git check``, ...) must present paths as project-relative POSIX strings
11so findings are portable across machines, cross-platform, and safe to
12paste into tickets, CI logs, and patch files.
13
14Responsibilities
15----------------
16- Convert an absolute :class:`pathlib.Path` into a project-relative
17 POSIX string when the path is inside *project_root*.
18- Fall back to an absolute POSIX string when *path* is outside the
19 project (e.g. a stdlib file surfaced by a traceback, a user-supplied
20 lint target under ``C:\\`` or ``/tmp``).
21
22Diagnostics
23-----------
24Domain: OCT-CORE
25Levels:
26 L2 - lifecycle
27 L3 - semantic details
28 L4 - each path relativisation, with its project root
29
30Contracts
31---------
32- Never raises on valid ``Path`` input.
33- Always returns forward slashes (POSIX), even on Windows.
34- ``project_root`` must be an absolute, resolved path for the relative
35 calculation to be correct; callers typically hand it straight from
36 :class:`LinterContext.project_root` (already resolved at context
37 construction).
38
39Dependencies
40------------
41- oct.core.diagnostics (_dbg structured logger)
42"""
43
44from __future__ import annotations
45
46from pathlib import Path
47from oct.core.diagnostics import _dbg
48
49
50def to_project_relative(path: Path, project_root: Path) -> str:
51 """Render *path* as a project-relative POSIX string.
52
53 OI-533: standardises path output across linter, health, and git
54 commands so findings never leak absolute machine paths into CI
55 artifacts or pasted error reports.
56
57 Parameters
58 ----------
59 path
60 The file or directory to render. May be absolute or relative.
61 project_root
62 The project root; typically ``ctx.project_root``. Should be
63 absolute and resolved so :meth:`~pathlib.Path.relative_to`
64 computes the expected relative.
65
66 Returns
67 -------
68 Project-relative POSIX string when *path* lives inside
69 *project_root*; otherwise the absolute POSIX form of *path* (so
70 out-of-tree paths remain unambiguous).
71 """
72 func = "to_project_relative"
73 _dbg("OCT-CORE", func, f"relativising {path} against {project_root}", 4)
74 try:
75 return path.relative_to(project_root).as_posix()
76 except ValueError:
77 return path.as_posix()
str to_project_relative(Path path, Path project_root)
Definition paths.py:50