# -*- coding: utf-8 -*- r"""安装根推算(公共层内部助手,2026-09-22 P1 迁移时新增)。 为什么需要它: 平台件原先各自写 `pathlib.Path(__file__).resolve().parents[1]` 推安装根 —— 那是按"文件在 `src/` 下一层"这个**位置假设**写的;P1 把它们迁到 `app_common/common/app_common_guanlan/`(深三层)后,同一个式子会算成 `app_common/common`。 所以改成**按标记找根**:从文件所在目录向上找同时含 `configs/` 与 `guanlan.py`(或 `install-info.json`) 的那一层;找不到才回退到原先的三层上跳(迁移前的布局)。 保持不变: `WINDSCADA_ROOT` 环境变量覆盖仍然优先(见 paths.py)。 """ from __future__ import annotations import pathlib def install_root(start=None, fallback_up: int = 3) -> pathlib.Path: p = pathlib.Path(start).resolve() if start else pathlib.Path(__file__).resolve() base = p if p.is_dir() else p.parent for cand in [base, *base.parents]: if (cand / 'configs').is_dir() and ((cand / 'guanlan.py').is_file() or (cand / 'install-info.json').is_file()): return cand return base.parents[fallback_up - 1]