Repository navigation
[Feature] 运行环境页解析纳入项目 wrapper(mvnw、gradlew 等 projectFile 候选) #1640
Copy link
Copy link
Open
Labels
P2后续考虑:目前不着急,可安排到后续版本后续考虑:目前不着急,可安排到后续版本area:extensionsExtensions / 扩展Extensions / 扩展enhancementNew feature or requestNew feature or requestplatform:macosMacOS的需求MacOS的需求review: highghfind author score; see https://ghfind.comghfind author score; see https://ghfind.com
Description
Problem to solve / 要解决的问题
工具定义可以声明 projectFile 候选,也就是项目里自带的启动脚本,例如 mvnw、gradlew。Core 在项目层处理这类候选时:
- 从当前目录逐级向上,检查
<祖先目录>/<path>及其requires标记文件是否存在; - 运行项目里的脚本属于执行项目代码,所以还要求输入里有
projectCodeAllowed。
macOS 运行环境设置页(PR #1581)目前满足不了这两个条件:
- 宿主拿不到路径。
toolchains.discoveryPlan只输出扫描规则、home 布局、可执行布局、版本探测和登录 Shell 变量,没有projectFile候选的path和requires。宿主不知道该给 Core 收集哪些文件事实。 - 没有项目代码授权的来源。 设置页不传
projectCodeAllowed。
结果:Core 解析时找不到这些文件的事实,于是静默跳过项目 wrapper,wrapper 永远不会被选中。带 mvnw 的 Maven 项目在页面上会显示全局默认或自动检测到的 Maven,而将来实际构建用的是 wrapper,两者对不上。用户看不出项目里有 wrapper,也看不出它为什么没被用上。
Proposed solution / 建议方案
discoveryPlan输出 projectFile 候选。 把每个工具在当前平台适用的projectFile候选(path、requires)放进toolchains.discoveryPlan的输出。宿主照着清单,为每个查询目录及其祖先收集这些文件的事实(设置数量上限),不认识任何工具名。这是插件契约变更:修改shared/contracts/plugins/v1/后,合并时要同步到 lithe-plugin-docs。- 设计项目代码授权的来源。 例如沿用工作区信任,或逐项目确认。
- 未授权时,页面在项目步骤显示 Core 的
projectCodeRequiresAction,并提供授权入口; - 不默认授权,也不在打开页面时执行项目脚本;
- 运行 wrapper 来探测版本同样属于执行项目代码,受同一个授权约束。
- 未授权时,页面在项目步骤显示 Core 的
- 页面展示 wrapper。 项目步骤显示找到的 wrapper、它所在的目录,以及 Core 给出的状态(已选中、需要授权、不可执行等)。
验收方式:用临时工作区覆盖以下情况:
- 有或没有 wrapper;
- 缺少
requires标记; - 未授权和已授权;
- wrapper 在祖先目录;
- 超出数量上限时有诊断。
测试不执行真实的项目脚本。
Target platform / 目标平台
macOS
Area / 模块
Extensions / 扩展
Priority / 优先级
P2 / 后续考虑:目前不着急,可安排到后续版本
Alternatives considered / 已考虑的替代方案
- 宿主按工具名写死
mvnw、gradlew。 不采用。违反“宿主不认识工具名,工具内容全部由插件注入”的规则,每新增一种 wrapper 都要改宿主。 - 设置页默认传
projectCodeAllowed: true。 不采用。等于默认允许执行项目里的脚本,打开一个不可信的项目就可能运行其中的代码。 - 保持现状,在文档里说明。 页面会长期显示与实际构建不一致的结果,用户无法从界面发现原因。
Additional context / 补充信息
- 相关:PR feat(plugins): 插件注入的工具链框架与 macOS 只读环境设置页 #1581(Core 解析接入设置页)。
- 代码位置:
rust/lithe-core/src/toolchain/resolution.rs:discovery_plan的输出字段;项目层projectFile的祖先目录查找;projectCodeAllowed检查与projectCodeRequiresAction;macos/Sources/Lithe/Platform/MacOS/Runtime/MacToolchainDiscovery.swift:宿主按discoveryPlan收集事实,并调用toolchains.resolve。
- 决策记录:
.agents/notes/proposed/architecture/2026-10-31-plugin-injected-toolchains.md中“macOS 设置页的解析取舍”一节,已把这一点记为已知限制。 - 依据:源码阅读,不是发布包复现。Core 和契约是双端共享的,但 Windows 运行环境页尚未接入,本 Issue 按 macOS 设置页提出。
Checklist / 提交前检查
- I searched existing issues for duplicates. / 我已搜索现有 Issue,确认没有重复建议。
Metadata
Metadata
Assignees
Labels
P2后续考虑:目前不着急,可安排到后续版本后续考虑:目前不着急,可安排到后续版本area:extensionsExtensions / 扩展Extensions / 扩展enhancementNew feature or requestNew feature or requestplatform:macosMacOS的需求MacOS的需求review: highghfind author score; see https://ghfind.comghfind author score; see https://ghfind.com
Activity
feat(plugins): 运行环境页每行生效来源改由 Core toolchains.resolve 决定 (1lck#1581)
xiaoyumuxi commentedon Nov 1, 2026
补充:现状核对与分期方案
契约里已有的部分(不需要另做一套 wrapper 优先级)
wrappers、projectFile、projectKind(shared/contracts/plugins/v1/plugin-manifest.schema.json),Core 会校验每个 wrapper 都有对应的projectFile候选。插件作者现在就能声明mvnw、gradlew,后续补的都是宿主侧接线,插件契约不变。shared/contracts/plugins/v1/toolchains.md)。null,这时不导出 home 变量、不加 PATH;projectKind: "environment"带home时按定义的pathPrepend、exports注入。解析结果带有projectCode: true。unmet每项的原因码已包含projectCodeRequiresAction,也有source字段(shared/contracts/plugins/v1/proposals/toolchains/resolution.schema.json),把“需要授权”记进去不用改 schema。另做一套 wrapper 优先级会和 Core 的四层规则打架。#1581 刚修掉的就是这个问题:Swift 自己排的顺序和 Core 对不上。
新发现:wrapper 因未授权被跳过时,结果里看不出来
项目层只留一条 trace。wrapper 因
projectCodeRequiresAction失败后,Core 会接着试同目录的版本文件声明;一旦声明成功,结果里就只剩“已解析”,看不出这里其实有./mvnw、只是需要授权。目前unmet只记录requestedNotInstalled(rust/lithe-core/src/toolchain/resolution.rs项目层循环与project_selection)。不补这一点,页面会显示全局或版本文件指定的 Maven,而用户授权后实际构建会用 wrapper,两边对不上。
第一期:只展示,不执行任何项目代码
前置条件:#1581 合并。Core 的工具链模块是随它一起进入 preview 的。
toolchains.discoveryPlan输出项目文件候选。 每个工具在当前平台适用的projectFile候选(path、requires、home、projectKind)。只更新toolchains.md里宿主接口的说明,manifest schema 不变;合并后在 lithe-plugin-docs 同步契约目录。projectCodeRequiresAction被跳过时,把{code, tool, source: wrapper 路径}记入unmet,现有 schema 已允许。discoveryPlan为每个查询目录及其上级目录收集path和requires的文件事实,设数量上限,超限给诊断;宿主不认识任何工具名。有 wrapper 的目录也算“有自己的项目来源”,作为查询目录。projectCodeAllowed: false。项目步骤显示 wrapper 路径和“运行前需要确认”,摘要说明授权后优先用 wrapper、不授权时退到哪一层。新文案走shared/i18n/。discoveryPlan输出、unmet记录、wrapper 在上级目录、缺少requires标记。第二期:随 Build/Run 接入
toolchains.resolve一起做projectCodeAllowed: true解析;拒绝则退到下一层。目前没有持久的工作区信任状态,不能把“打开过项目”当成授权。maven-wrapper.properties、gradle-wrapper.properties后上报,这类工具专属解析放在插件里,宿主不碰。null不导出 home 变量和 PATH,避免把仓库根当成工具安装目录。为什么不放进 #1581
#1581 已有 82 个文件、新增约 1.8 万行,正在等评审,且已是 ready 状态,每次推送都会重跑完整 CI。第二期依赖的 Build/Run 调用方在 #1581 里还不存在。上面的改动全部是新增,不需要推翻 #1581 的结构。
feat(plugins): 插件注入的工具链框架与 macOS 只读环境设置页 (#1581)
feat(workspace): 支持目录索引排除并统一 Git 设置入口 (#1597)