Sfoglia il codice sorgente

fix(v7): detectHosts 扩展名匹配大小写不敏感(修 ubuntu CI)

CI ubuntu 挂在 opencode 双 shim 探测测试,两层根因:
1. 测试只注入 env 未注入 platform:'win32'——Linux 按 posix 只查无扩展名,
   .cmd 分支测不到(测试缺陷,已补注入)。
2. 注入后仍挂:PATHEXT 惯例大写(.CMD)而 shim 文件小写(.cmd),真实
   Windows 靠文件系统大小写不敏感命中;大小写敏感文件系统上模拟 win32
   即 miss。按 Windows 语义修在实现层:exts 补小写变体去重——匹配不再
   依赖文件系统特性(大小写敏感卷/跨平台模拟同样成立)。

验证:Windows 全量 716 绿 + drift 绿;WSL units 6/6 绿。
lingfengQAQ 2 mesi fa
parent
commit
887dc1ae6f
2 ha cambiato i file con 8 aggiunte e 3 eliminazioni
  1. 5 1
      v7/src/installer/detect.js
  2. 3 2
      v7/test/installer/units.test.js

+ 5 - 1
v7/src/installer/detect.js

@@ -8,10 +8,14 @@ import path from 'node:path'
 export async function detectHosts(registry, { env = process.env, platform = process.platform } = {}) {
   const pathVar = env.PATH || env.Path || ''
   const dirs = pathVar.split(path.delimiter).filter(Boolean)
-  const exts =
+  // win32 语义:PATHEXT 惯例大写(.CMD)而 shim 文件常为小写(.cmd),真实 Windows 靠
+  // 文件系统大小写不敏感命中——这里补小写变体,使匹配不依赖文件系统特性
+  // (大小写敏感卷/跨平台模拟 win32 同样成立)。
+  const rawExts =
     platform === 'win32'
       ? ['', ...(env.PATHEXT || '.COM;.EXE;.BAT;.CMD').split(';').filter(Boolean)]
       : ['']
+  const exts = [...new Set(rawExts.flatMap((e) => [e, e.toLowerCase()]))]
   const hits = []
   for (const [host, cfg] of Object.entries(registry.hosts)) {
     if (host === '_default' || !cfg.detect_bin) continue

+ 3 - 2
v7/test/installer/units.test.js

@@ -47,15 +47,16 @@ test('detectHosts:opencode 探测命中(win32 .cmd/no-ext 双 shim 形态)
   try {
     // A1 实测 Windows 三 shim 形态:opencode / opencode.cmd / opencode.ps1 并存——
     // '' ext 分支命中无扩展名 shim;.CMD ext 分支命中 .cmd。两形态分别断言。
+    // platform 显式注入 win32:不注入时 Linux CI 按 posix 只查无扩展名,.cmd 分支测不到。
     await fs.writeFile(path.join(root, 'opencode'), '#!/bin/sh\n', 'utf8')
     await fs.writeFile(path.join(root, 'opencode.cmd'), '@echo off\n', 'utf8')
     const env = { PATH: root, PATHEXT: '.COM;.EXE;.BAT;.CMD' }
-    const hits = await detectHosts(REGISTRY, { env })
+    const hits = await detectHosts(REGISTRY, { env, platform: 'win32' })
     assert.ok(hits.includes('opencode'), `opencode 应命中:${JSON.stringify(hits)}`)
 
     // 只有 .cmd 时(win32 常见)也命中
     await fs.rm(path.join(root, 'opencode'), { force: true })
-    const hits2 = await detectHosts(REGISTRY, { env })
+    const hits2 = await detectHosts(REGISTRY, { env, platform: 'win32' })
     assert.ok(hits2.includes('opencode'), `.cmd shim 应命中:${JSON.stringify(hits2)}`)
   } finally {
     await cleanup()