MooTool Next Compose 环境变量工具与 Electron 对齐:EnvEngine、会话恢复与 Vitest 对照实战

发布时间:2026/10/16 2:29:47
MooTool Next Compose 环境变量工具与 Electron 对齐:EnvEngine、会话恢复与 Vitest 对照实战
桌面应用开发工具【免费下载链接】MooToolHandy tool set for developers项目地址https://gitcode.com/gh_mirrors/mo/MooTool点击查看免费下载环境变量工具F08是 MooTool 三款桌面产品线共有的核心系统工具本文以next-compose/docs/fixtures/electron-next-envTools-vitest.md这份对照登记表为主干系统梳理MooTool Next Compose如何把 Electron 版的「导出分区、previewDiff、环境文件更新、权限拒绝保持原文件、会话恢复」逐项搬进 Compose 桌面产品并以单测EnvEngineTest/EnvSessionMetadataTest/VariablesSessionRestoreTest锁定行为。读完本文你可以完整掌握 Compose 版环境变量引擎的存储路径、shell 钩子、原子写入、提权策略、导出格式与会话 wire 的来龙去脉也能直接看懂这份对照表的每一行对应仓库中的哪段实现与测试。一、这份对照表在讲什么electron-next-envTools-vitest.md是next-compose/docs/fixtures/目录下的一张「Electron ↔ Compose 验证对照登记表」。它的作用不是复述 Electron 代码而是给出一个可审计的契约每一类行为在 Electron 源文件里是什么、在 Compose 里由哪个测试证明等价。表内四条已落地登记 一条会话登记如下caseIdsourceProductsourceFileCompose 验证export-sectionsMooTool Next Electronnext/src/features/variables/VariablesTool.tsxformatEnvironmentEnvEngineTest.formatExportUsesElectronSectionHeadersEnvExportSections运行时区为 Compose 产品名preview-diff同上编辑对话框variables.diff 保存前摘要EnvEngineTest.previewDiffDescribesScopeFileAndDeleteenv-file-update同上next/src/shared/systemService.test.tsEnvEngineTest.updatesEnvironmentFileLikeElectronSystemServiceFixture见 electron-next-systemService-vitest.mdpermission-denyCompose 行为—EnvEngineTest.systemWriteWithoutElevationKeepsOriginalFilesession-restoreCompose 会话tab/scope/query wireEnvSessionMetadataTest/VariablesSessionRestoreTestDIFF-535末尾还登记了两个 diff 切片DIFF-534导出分区 previewDiff 回归与 DIFF-535会话 metadata 恢复。也就是说这张表就是 F08 在「Electron 参照 → Compose 实现 → 单测锁定」这条链路中的索引页。二、先看 Electron 参照端导出格式与系统服务对照表前三行的 sourceFile 都指向 Electron 侧理解它们才能看懂 Compose 对齐了什么。2.1formatEnvironment的四段导出分区Electron 的变量工具页在 VariablesTool.tsx 中定义formatEnvironment(snapshot)把快照按「持久用户 → 持久系统 → 当前进程 → Electron runtime」四个分区拼成一个文本每个分区用一行------------标题分隔条目格式为keyvaluefunction formatEnvironment(snapshot: EnvironmentSnapshot): string { return [ ------------Persistent user environment---------------, ...snapshot.user.map((entry) ${entry.key}${entry.value}), , ------------Persistent system environment---------------, ...snapshot.system.map((entry) ${entry.key}${entry.value}), , ------------Current process environment---------------, ...snapshot.environment.map((entry) ${entry.key}${entry.value}), , ------------Electron runtime---------------, ...snapshot.runtime.map((entry) ${entry.key}${entry.value}) ].join(\n) }exportValues()在 VariablesTool.tsx 通过window.mootool.saveTextFile把这段内容落盘默认文件名为mootool-environment.txt。这就是 Compose 端EnvExportSections要对齐的「分区标题」。2.2systemService.test.ts的环境文件更新链对照表的env-file-update行指向 systemService.test.ts。该用例给定一段含注释、export JAVA_HOME/old jdk、OTHERvalue的文本验证三件事updateEnvironmentContent(source, JAVA_HOME, /opt/jdks, true)把单引号值安全转义为/opt/jdk\s注释与其他行原样保留parseEnvironmentContent能解析回JAVA_HOME/opt/jdks与OTHERvalue传入value undefined时删除该键得到# keep this comment\nOTHERvalue\n。这些纯函数位于 systemService.ts配套的 IPC 边界校验normalizeEnvironmentVariableInput/normalizeDeleteEnvironmentVariableInput同样在该测试文件中负责在进入主进程前拒绝非法键名如BAD-NAME与含换行的非法值——两个产品线在这一层保持了同一套安全约束。三、Compose 侧核心实现EnvEngine 与 EnvExportSectionsCompose 版把这些行为收敛进一个可单测的纯 Kotlin 引擎 EnvEngine.kt配套类型EnvTab/EnvDisplayScope/EnvPersistScope/EnvErrorCode、快照与写入结果均在同一文件。3.1 产品独立的路径与 shell 钩子EnvStoreConfig.production(directories)EnvEngine.kt决定各平台路径平台用户文件系统文件shell profilemacOS数据目录data/environment/etc/zshenv~/.zshenvLinux数据目录data/environment/etc/environment~/.profileWindows数据目录data/environment空走注册表~/.unused-compose-env-profile数据目录来自AppDirectoriesmacOS 为~/Library/Application Support/com.rememberber.mootool.next.compose/dataLinux 走 XDG 数据目录Windows 为%APPDATA%/MooToolNextCompose/data见 AppPaths.kt。这一点与 Electron 有本质区别Electron 写~/.MooTool/environment并在 profile 里插入# MooTool environment 钩子Compose 明确不读写~/.MooTool其 shell 钩子常量是隔离标记const val SHELL_HOOK_BEGIN # MooTool Next Compose environment const val SHELL_HOOK_END # MooTool Next Compose environment ensureShellHookEnvEngine.kt在 profile 里追加# MooTool Next Compose environment [ -f userFile ] . userFile # MooTool Next Compose environment 正因为标记不同两个产品线可以同时安装、互不覆盖。这一设计决策的完整理由见 DIFF-016产品线独立要求自有路径与标记规格禁止用进程 Map 冒充系统设置。3.2 解析、序列化与安全校验EnvEngine.parseContent用正则^\s*(?:export\s)?([A-Za-z_][A-Za-z0-9_]*)\s*\s*(.*)$匹配赋值行unquote还原单双引号\转义、\与\\反转义未知行一律跳过但不删除。updateContent逐行扫描把目标键的所有赋值替换为一条新的序列化行其他行含注释、非赋值文本原样保留若键不存在则追加最后统一以\n结尾EnvEngine.kt。序列化分两种模式EnvEngine.kt// shellExport true用户作用域或 macOS 的系统作用域 export $key${value.replace(, \\)} // 否则 $key\${value.replace(\\, \\\\).replace(\, \\\)}\校验规则与 Electron 完全一致键名必须匹配^[A-Za-z_][A-Za-z0-9_]*$值长度上限 65535且不得包含\0、\r、\nvalidateName/validateValueEnvEngine.kt。非法输入抛EnvException并携带EnvErrorCodeINVALID_NAME/INVALID_VALUE等。3.3 导出分区与运行时信息EnvExportSectionsEnvEngine.kt把四个分区标题抽成常量其中前三个标题与 ElectronformatEnvironment逐字相同第四个刻意不同object EnvExportSections { const val USER ------------Persistent user environment--------------- const val SYSTEM ------------Persistent system environment--------------- const val PROCESS ------------Current process environment--------------- const val RUNTIME_COMPOSE ------------Compose runtime--------------- }formatExportEnvEngine.kt按 user → system → process → runtime 顺序输出。runtime 分区由runtimeEntriesEnvEngine.kt生成先是mootool.productProductIdentity.DISPLAY_NAME MooTool Next Compose见 ProductIdentity.kt、mootool.version、mootool.id再是 JVM 与 OS 属性java.version、os.name、user.home、file.encoding等。Electron 的 runtime 区则显示process.versions.electron/chrome/node与process.cwd见 systemService.ts。Compose 没有 Electron 运行时字段所以用产品名/JVM/OS 代替——这正是 DIFF-016 强调的「Electron 运行时字段在 JVM 桌面产品中没有对应物」。3.4 写入流程diff → 备份 → 原子写入 → 提权EnvEngine.set/delete收敛到私有writeEnvEngine.kt完整链路是校验键名与值snapshot(config)取写入前快照previewDiff生成「scope 目标文件 旧值 → 新值/删除」摘要备份若目标文件已存在先复制到data/backups/environment/environment-scope-UTC 时间戳.bakbackupIfPresent更新内容后以tmp-pid临时文件 ATOMIC_MOVE原子落盘用户文件写完后把权限收窄为仅 owner 可读写atomicWrite用户作用域追加/校验 shell 钩子macOS 额外尝试launchctl setenv/unsetenv失败静默忽略系统作用域直接写若抛权限类 IOException 且允许提权则走writeElevated——macOS 用osascript do shell script ... with administrator privilegesLinux 用pkexec复制并chmod 644EnvEngine.kt若allowElevation false则抛出EnvErrorCode.PERMISSION返回写入后快照 备份路径 diff。注意第 4 步的关键差异Compose 绝不改写当前 JVM 的System.getenv()。Electron 在写完后会通过syncCurrentProcessEnvironment把process.env[key]原地更新systemService.tsCompose 则明确拒绝这种行为理由见 DIFF-016「规格禁止用进程 Map 冒充系统设置」。用户保存的用户/系统变量只在重新登录、新终端或已加载 Compose shell 钩子的会话中生效。Windows 分支单独走 PowerShell用户作用域[Environment]::SetEnvironmentVariable(...,[EnvironmentVariableTarget]::User)系统作用域通过Start-Process -Verb RunAs提权读取则用GetEnvironmentVariables Sort UTF-8 输出解析readWindows/writeWindowsEnvEngine.kt。该分支在本机Intel macOS未实测属于已知限制。四、四条对照登记逐一拆解下面把对照表每一行映射到 Compose 单测 EnvEngineTest.kt 的具体断言证明「登记 ≠ 口头承诺测试确实锁住了行为」。4.1 export-sectionsformatExportUsesElectronSectionHeadersEnvEngineTest.kt 构造一个含 user/system/process/runtime 四项的快照断言EnvEngine.formatExport输出依次包含EnvExportSections.USER、SYSTEM、PROCESS、RUNTIME_COMPOSE条目呈现为U1、PATH/bin并且不包含Electron runtime。这条测试锁死两件事分区标题与 Electron 对齐前三段逐字一致以及运行时区必须使用 Compose 产品名而非 Electron 字样。4.2 preview-diffpreviewDiffDescribesScopeFileAndDeleteEnvEngineTest.kt 验证EnvEngine.previewDiff的输出结构更新时包含作用域名user、目标文件/data/environment、旧值FOO: bar与箭头→ baz删除一个不存在的键时输出MISSING: (absent)与→ (delete)。该摘要正是VariablesScreen编辑对话框里variables.diff区域展示的保存前预览见 VariablesScreen.kt对应 Electron 编辑对话框中同样的variables.diff 保存前摘要。4.3 env-file-updateupdatesEnvironmentFileLikeElectronSystemServiceFixtureEnvEngineTest.kt 使用与 ElectronsystemService.test.ts完全相同的输入文本# keep this commentexport JAVA_HOME/old jdkOTHERvalue验证更新含单引号的值时输出export JAVA_HOME/opt/jdk\s注释与其他行原样保留EnvEngine.parseContent可解析回两个条目以value null调用时删除该键保留注释。updatesEnvironmentFileLikeElectronSystemServiceFixture这个名字直接表明它是「对齐 Electron fixture」的回归测试对照表的env-file-update行同时挂到 electron-next-systemService-vitest.md后者把env-update一行也登记为同一个测试。配套用例parsesAndUpdatesWhileKeepingUnknownLinesEnvEngineTest.kt还覆盖了重复赋值取最后一个、非赋值文本保留、单引号值往返、非法键名1ABC抛INVALID_NAME、含换行的值抛INVALID_VALUE等边界。userFileRoundTripCreatesBackupAndDoesNotMutateProcessMapEnvEngineTest.kt是这条链路的完整闭环真实写临时文件 → 断言备份文件存在 → 断言.zshenv里含SHELL_HOOK_BEGIN且不含 Electron 标记# MooTool environment → 断言System.getenv()前后逐项相等进程 Map 未被改写→ 断言 runtime 含java.version与mootool.product…Compose…→ 删除后导出文本含Compose runtime且不含Electron runtime。4.4 permission-denysystemWriteWithoutElevationKeepsOriginalFile这是表格中sourceProduct标为「Compose 行为」的一行代表 Compose 自己的新增约束没有 Electron 参照。测试 EnvEngineTest.kt 构造一个setWritable(false)的锁目录以allowElevation false写入系统作用域断言抛出EnvException且code EnvErrorCode.PERMISSION、目标文件不存在没有创建半成品、随后snapshot(config).system仍为空原文件保持原状。这印证了 DIFF-016 中「系统作用域在无权限时按需提权拒绝时保持原文件」的实现承诺。五、会话恢复session-restore 登记的 tab/scope/query wire对照表最后一行session-restore不指向 Electron而是 Compose 自己的会话子系统登记于 DIFF-535F08 缺与 F11/F15 同级的可单测 metadata/restore 模块本轮补上。5.1 EnvSessionMetadatawire 规范化EnvSessionMetadata.kt 定义了持久化到会话 JSON 的 wire 值常量environment/runtimetabuser/system/processscope。normalizeTab把任何未知输入回退为environmentnormalizeScope把未知输入回退为process。测试 EnvSessionMetadataTest.kt 覆盖大小写归一Runtime→runtime、User→user与空串回退→process。5.2 EnvSessionRestore VariablesSession重载即恢复VariablesSessionSessionManager.kt持有tab/scope/query及 transient 状态snapshot、loading、saving、error、notice、editor 字段、lastBackup、lastDiff。EnvSessionRestore.applyEnvSessionRestore.kt把 wire 字符串映射回枚举并重置全部 transient 状态snapshot null、loading false、saving false、error 、notice 、editorOpen false、deleteKey 、lastBackup 、lastDiff 。会话的读写由SessionManager.variablesSession()/persistVariables()承担加载时从 store 反序列化VariablesSessionSnapshottab/scope/query三个字段均带默认值保存时序列化当前状态SessionManager.kt。VariablesScreen在切 Tab、切 scope、输入搜索词、增删改时都会调用persist()确保 UI 状态持续落盘。测试 VariablesSessionRestoreTest.kt 把 session 置为 Runtime/System/PATH/已载入快照/loading/error然后restore(VariablesSessionSnapshot(environment, user, JAVA))断言恢复为EnvTab.Environment、EnvDisplayScope.User、query JAVA、snapshot null、loading false、error 。5.3 会话链路与安全边界DIFF-535明确说明 F08 是「无通用历史」工具不把变量值写入会话 JSON 或通用历史VariablesSessionSnapshot只含 tab/scope/query避免密钥类环境变量进入 SQLite 或历史库见 DIFF-016「受影响范围」与 feature-parity.md 中「variables 不声明通用历史」的注册说明。相比之下EnvSnapshot这类临时快照只在内存中刷新VariablesScreen.refresh走EnvWiringPresentation.runSnapshot见 EnvWiringPresentation.kt。六、从表格到运行如何查看、构建与验证本产品是独立的 Compose Multiplatform Desktop 工程见 README.md与 Electron 版互不依赖需 JDK 21。开发运行与测试cd next-compose export JAVA_HOME$(/usr/libexec/java_home -v 21) # macOSLinux 请指向已安装的 JDK 21 ./scripts/check-toolchain.sh ./scripts/check-core.sh MOOTOOL_COMPOSE_DATA_DIR$PWD/local.properties.d/dev-profile ./scripts/run.sh跑 F08 相关单测EnvEngineTest、EnvSessionMetadataTest、VariablesSessionRestoreTest./gradlew :composeApp:desktopTest --offline测试结果在composeApp/build/reports/tests/desktopTest/index.html可查看。三个 diff 文档各自记录过完整运行结论F08 验收当轮desktopTest100/100见 2026-09-09-f08/results.mdDIFF-534 记为841/841DIFF-535 记为851/851均为 JDK 21、offline 运行另有默认跳过的公网 GET/multipart smoke。这些是开发切片快照而非发布保证具体以你本地运行结果为准。界面侧运行后在工具列表⌘/CtrlK中进入「环境变量」顶部 Tab 为 Environment/RuntimeEnvironment 下有 user/system/process 作用域切换编辑对话框中展示variables.diff保存前摘要。Compose 导出默认文件名为mootool-next-compose-environment.txt见 VariablesScreen.kt区别于 Electron 的mootool-environment.txt。七、局限与后续切片从 DIFF-016「受影响范围」与 results.md「未测」可以明确列出本功能的已知边界新终端不会自动看到用户变量除非已加载 Compose shell 钩子macOS 会额外尝试launchctl setenv失败忽略系统文件在 macOS 为/etc/zshenv、Linux 为/etc/environment但并非所有发行版的唯一全局环境来源Windows 用户/系统走 PowerShell 注册表目标在 Intel macOS 本机未实测不把变量值写入会话 JSON 或通用历史防密钥进 SQLite未做项还包括窗口截图、系统提权对话框的界面验收以及新终端实际加载钩子的手工验证。这些边界在后续切片如 P7 三平台安装验收中才会逐步收敛阅读对照表与 DIFF 记录时应一并留意。八、小结一份可审计的 parity 登记electron-next-envTools-vitest.md这类 fixture 的价值在于它把「Electron 参照、Compose 实现、单测锁定」三件事压进同一张表。EnvEngineTest用与 Electron 相同的 fixture 文本验证解析/序列化兼容用formatExportUsesElectronSectionHeaders锁定分区标题逐字对齐用systemWriteWithoutElevationKeepsOriginalFile记录 Compose 自己的权限语义EnvSessionMetadataTest/VariablesSessionRestoreTest则覆盖会话 wire 与恢复。如果你要为本产品新增功能或回归检查 F08正确姿势是先读这张对照表定位 caseId再打开EnvEngineTest对应的测试方法最后回看 DIFF-534、DIFF-535 与 DIFF-016 的行为描述。这条从「文档登记 → 测试断言 → diff 决策」的证据链正是整个 next-compose 切片工程可复现、可审计的研发方式的缩影。赞分享桌面应用开发工具【免费下载链接】MooToolHandy tool set for developers项目地址https://gitcode.com/gh_mirrors/mo/MooTool点击查看免费下载相关推荐MooTool next-compose Cron 工具测试对齐从 Electron Vitest 到 Compose Kotlin 的 Quartz 语义迁移MooTool next compose Cron 工具测试对齐从 Electron Vitest 到 Compose Kotlin 的 Quartz 语义迁桌面应用开发工具MooTool Compose 版跨产品草稿迁移Java t_func_content 字段对齐与工具会话恢复实战MooTool Compose 版跨产品草稿迁移Java t_func_content 字段对齐与工具会话恢复实战 本篇基于 DIFF 153 对齐文档 ht桌面应用开发工具MooTool Vault Git 面板文案对齐实战Compose git.* 与 Electron json.git.* 全量对照解析MooTool Vault Git 面板文案对齐实战Compose git. 与 Electron json.git. 全量对照解析 导读 在 MooTool桌面应用开发工具上一篇开源制造执行系统openMES企业数字化转型的智能引擎下一篇数字记忆守护者5分钟拯救你的B站缓存视频创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考