@wwkit/opm 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/managers/npm.js +4 -3
- package/src/tools/webwork/index.js +137 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wwkit/opm",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"author": "bluesliu <langcai163@163.com>",
|
|
5
5
|
"description": "Unified CLI — package management (npm/pip/dnf/apt) + config view + opencode maintenance",
|
|
6
6
|
"type": "module",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"basic-ftp": "^6.2.1",
|
|
36
36
|
"extract-zip": "^2.0.1",
|
|
37
37
|
"systeminformation": "^5.23.0",
|
|
38
|
-
"@wwkit/
|
|
38
|
+
"@wwkit/harness": "1.0.17",
|
|
39
|
+
"@wwkit/shared": "1.0.11"
|
|
39
40
|
},
|
|
40
41
|
"publishConfig": {
|
|
41
42
|
"registry": "https://registry.npmjs.org/",
|
package/src/managers/npm.js
CHANGED
|
@@ -454,13 +454,14 @@ export class NpmManager extends PackageManager {
|
|
|
454
454
|
}
|
|
455
455
|
|
|
456
456
|
/**
|
|
457
|
-
* 构造 --allow-scripts 参数(仅 npm >= 11 支持)
|
|
458
|
-
*
|
|
457
|
+
* 构造 --dangerously-allow-all-scripts 参数(仅 npm >= 11 支持)
|
|
458
|
+
* npm < 11 默认放行所有脚本,无需此 flag;npm >= 11 默认阻止,需显式放行
|
|
459
|
+
* @param {string} name - 包名(保留签名兼容,未使用)
|
|
459
460
|
* @returns {string[]}
|
|
460
461
|
* @private
|
|
461
462
|
*/
|
|
462
463
|
_allowScriptsArgs(name) {
|
|
463
|
-
return this._npmMajor() >= 11 ? [
|
|
464
|
+
return this._npmMajor() >= 11 ? ['--dangerously-allow-all-scripts'] : []
|
|
464
465
|
}
|
|
465
466
|
|
|
466
467
|
async install(name, version, opts = {}) {
|
|
@@ -10,16 +10,20 @@
|
|
|
10
10
|
* 6. harness(npm 全局安装 @wwkit/harness,已安装则跳过)
|
|
11
11
|
* 7. sshproxy(npm 全局安装 @wwkit/sshproxy,已安装则跳过)
|
|
12
12
|
*
|
|
13
|
+
* npm 包安装使用 --dangerously-allow-all-scripts(npm >= 11)放行 postinstall 脚本。
|
|
14
|
+
*
|
|
13
15
|
* install 流程:镜像可达检查 → 安装组件 → 初始化 → 验证
|
|
14
|
-
* init 流程:ww config init → ww
|
|
15
|
-
* verify 流程:ww sqlite debug → ww run debug → ww web status → ww webdriver debug
|
|
16
|
+
* init 流程:ww config init → 写运行时路径(cft/harness) → ww sqlite init → ww web init → summary
|
|
17
|
+
* verify 流程:ww doctor → ww sqlite debug → ww run debug → ww web status → ww webdriver debug
|
|
16
18
|
*
|
|
17
19
|
* 命令: version / versions / installed / install / init / verify / uninstall / upgrade / help
|
|
18
20
|
*/
|
|
19
21
|
|
|
22
|
+
import fs from 'node:fs'
|
|
23
|
+
import path from 'node:path'
|
|
20
24
|
import { execSync } from 'node:child_process'
|
|
21
25
|
|
|
22
|
-
import { Shell } from '@wwkit/shared'
|
|
26
|
+
import { Shell, getXdgConfigDir } from '@wwkit/shared'
|
|
23
27
|
import { parseFlags } from '../../cli/helpers/args.js'
|
|
24
28
|
import { output } from '../../formatter.js'
|
|
25
29
|
import { getActiveProxy, getConfig, getActiveRegistry } from '../../config.js'
|
|
@@ -190,9 +194,7 @@ export class WebworkGroup {
|
|
|
190
194
|
|
|
191
195
|
output({ action: verb, results, summary: { ok, skipped, failed, total } })
|
|
192
196
|
|
|
193
|
-
|
|
194
|
-
process.exit(1)
|
|
195
|
-
}
|
|
197
|
+
return { results, ok, skipped, failed }
|
|
196
198
|
}
|
|
197
199
|
|
|
198
200
|
async _install(parsed) {
|
|
@@ -280,9 +282,8 @@ export class WebworkGroup {
|
|
|
280
282
|
async _init(parsed) {
|
|
281
283
|
const steps = [
|
|
282
284
|
{ name: 'config', cmd: 'ww config init', required: true },
|
|
283
|
-
{ name: 'webdriver', cmd: 'ww webdriver init', required: true, hint: 'Downloads Chrome for Testing (~200MB)' },
|
|
284
|
-
{ name: 'opencode', cmd: 'ww opencode init', required: true },
|
|
285
285
|
{ name: 'sqlite', cmd: 'ww sqlite init', required: true },
|
|
286
|
+
{ name: 'web', cmd: 'ww web init', required: true, hint: 'Start web service :7901' },
|
|
286
287
|
]
|
|
287
288
|
|
|
288
289
|
for (const step of steps) {
|
|
@@ -290,6 +291,9 @@ export class WebworkGroup {
|
|
|
290
291
|
try {
|
|
291
292
|
execSync(step.cmd, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] })
|
|
292
293
|
console.log(` [OK] ${step.name}`)
|
|
294
|
+
if (step.name === 'config') {
|
|
295
|
+
this._writeRuntimePaths()
|
|
296
|
+
}
|
|
293
297
|
} catch (err) {
|
|
294
298
|
if (step.required) {
|
|
295
299
|
throw new Error(`${step.name} init failed: ${err.message}`)
|
|
@@ -297,6 +301,120 @@ export class WebworkGroup {
|
|
|
297
301
|
console.error(` [WARN] ${step.name}: ${err.message}`)
|
|
298
302
|
}
|
|
299
303
|
}
|
|
304
|
+
|
|
305
|
+
await this._summary()
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* 将 cft/harness 的实际安装路径写入 webwork.json5(替代 post.py 的配置集成)
|
|
310
|
+
* 在 ww config init 之后执行,确保 webwork.json5 已存在
|
|
311
|
+
*/
|
|
312
|
+
_writeRuntimePaths() {
|
|
313
|
+
const configDir = getXdgConfigDir('webwork')
|
|
314
|
+
let configPath = null
|
|
315
|
+
for (const fname of ['webwork.json5', 'webwork.json']) {
|
|
316
|
+
const p = path.join(configDir, fname)
|
|
317
|
+
if (fs.existsSync(p)) { configPath = p; break }
|
|
318
|
+
}
|
|
319
|
+
if (!configPath) {
|
|
320
|
+
console.log(' [SKIP] webwork.json5 not found, skip runtime paths')
|
|
321
|
+
return
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
let cfg
|
|
325
|
+
try {
|
|
326
|
+
cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'))
|
|
327
|
+
} catch {
|
|
328
|
+
console.log(' [SKIP] webwork.json5 parse failed, skip runtime paths')
|
|
329
|
+
return
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
let changed = false
|
|
333
|
+
|
|
334
|
+
const cft = new CftGroup()
|
|
335
|
+
const cftActive = cft._readActive()
|
|
336
|
+
if (cftActive) {
|
|
337
|
+
const cftPath = cft._versionRoot(cftActive)
|
|
338
|
+
if (fs.existsSync(path.join(cftPath, 'installed.json'))) {
|
|
339
|
+
cfg.webdriver = cfg.webdriver || {}
|
|
340
|
+
cfg.webdriver.chromium = cfg.webdriver.chromium || {}
|
|
341
|
+
cfg.webdriver.chromium.cft = cfg.webdriver.chromium.cft || {}
|
|
342
|
+
cfg.webdriver.chromium.cft.location = cftPath
|
|
343
|
+
console.log(` [OK] webdriver.chromium.cft.location = ${cftPath}`)
|
|
344
|
+
changed = true
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
try {
|
|
349
|
+
const npmRoot = execSync('npm root -g', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim()
|
|
350
|
+
const harnessDir = path.join(npmRoot, '@wwkit', 'harness')
|
|
351
|
+
if (fs.existsSync(harnessDir)) {
|
|
352
|
+
cfg.plugin = cfg.plugin || {}
|
|
353
|
+
cfg.plugin.opencode = cfg.plugin.opencode || {}
|
|
354
|
+
cfg.plugin.opencode.config_dir = harnessDir
|
|
355
|
+
console.log(` [OK] plugin.opencode.config_dir = ${harnessDir}`)
|
|
356
|
+
changed = true
|
|
357
|
+
}
|
|
358
|
+
} catch {}
|
|
359
|
+
|
|
360
|
+
if (changed) {
|
|
361
|
+
fs.writeFileSync(configPath, JSON.stringify(cfg, null, 2), 'utf8')
|
|
362
|
+
console.log(' [OK] webwork.json5 updated with runtime paths')
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* 打印安装状态汇总(对齐 ww init 的 _step_summary)
|
|
368
|
+
*/
|
|
369
|
+
async _summary() {
|
|
370
|
+
console.log(' [SUMMARY]')
|
|
371
|
+
console.log(` OS: ${process.platform} ${process.arch}`)
|
|
372
|
+
console.log(` Node: ${process.version}`)
|
|
373
|
+
try {
|
|
374
|
+
const npmVer = execSync('npm --version', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim()
|
|
375
|
+
console.log(` npm: ${npmVer}`)
|
|
376
|
+
} catch {}
|
|
377
|
+
console.log(' [Components]')
|
|
378
|
+
for (const { key, label } of COMPONENTS) {
|
|
379
|
+
try {
|
|
380
|
+
const installed = await this._isComponentInstalled(key)
|
|
381
|
+
const version = await this._getComponentVersion(key)
|
|
382
|
+
console.log(` ${label.padEnd(14)} ${version || '-'} ${installed ? '✓' : '✗'}`)
|
|
383
|
+
} catch {
|
|
384
|
+
console.log(` ${label.padEnd(14)} - ?`)
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
console.log(' [Config]')
|
|
388
|
+
try {
|
|
389
|
+
const npmRegistry = getActiveRegistry('npm')
|
|
390
|
+
console.log(` npm mirror: ${npmRegistry || '(未配置)'}`)
|
|
391
|
+
} catch {}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
async _isComponentInstalled(key) {
|
|
395
|
+
switch (key) {
|
|
396
|
+
case 'python': return this._pythonInstalled()
|
|
397
|
+
case 'blues-lib': return await this._pipInstalled('blues-lib')
|
|
398
|
+
case 'cft': return this._cftInstalled()
|
|
399
|
+
case 'node': return this._nodeInstalled()
|
|
400
|
+
case 'opencode': return await this._npmInstalled(NPM_PACKAGES.opencode)
|
|
401
|
+
case 'harness': return await this._npmInstalled(NPM_PACKAGES.harness)
|
|
402
|
+
case 'sshproxy': return await this._npmInstalled(NPM_PACKAGES.sshproxy)
|
|
403
|
+
default: return false
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
async _getComponentVersion(key) {
|
|
408
|
+
switch (key) {
|
|
409
|
+
case 'python': return await this._pythonVersion()
|
|
410
|
+
case 'blues-lib': return await this._pipVersion('blues-lib')
|
|
411
|
+
case 'cft': return this._cftVersion()
|
|
412
|
+
case 'node': return this._nodeVersion()
|
|
413
|
+
case 'opencode': return await this._npmVersion(NPM_PACKAGES.opencode)
|
|
414
|
+
case 'harness': return await this._npmVersion(NPM_PACKAGES.harness)
|
|
415
|
+
case 'sshproxy': return await this._npmVersion(NPM_PACKAGES.sshproxy)
|
|
416
|
+
default: return '-'
|
|
417
|
+
}
|
|
300
418
|
}
|
|
301
419
|
|
|
302
420
|
/**
|
|
@@ -304,6 +422,15 @@ export class WebworkGroup {
|
|
|
304
422
|
* @param {object} parsed
|
|
305
423
|
*/
|
|
306
424
|
async _verify(parsed) {
|
|
425
|
+
console.log(' [VERIFY] doctor (ww doctor)...')
|
|
426
|
+
try {
|
|
427
|
+
execSync('ww doctor', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] })
|
|
428
|
+
console.log(' [OK] doctor')
|
|
429
|
+
} catch (err) {
|
|
430
|
+
const out = err.stdout ? err.stdout.toString().trim() : ''
|
|
431
|
+
console.error(` [WARN] doctor:\n${out || err.message}`)
|
|
432
|
+
}
|
|
433
|
+
|
|
307
434
|
const checks = [
|
|
308
435
|
{ name: 'sqlite', cmd: 'ww sqlite debug', pattern: /访问成功|ok|success/i },
|
|
309
436
|
{ name: 'run', cmd: 'ww run debug', pattern: /run debug/i },
|
|
@@ -672,12 +799,12 @@ export class WebworkGroup {
|
|
|
672
799
|
if (existing.installed) {
|
|
673
800
|
return { action: 'skipped', reason: `${name} ${existing.version} already installed`, version: existing.version }
|
|
674
801
|
}
|
|
675
|
-
return npm.install(name, null, { global: true, proxy, allowScripts:
|
|
802
|
+
return npm.install(name, null, { global: true, proxy, allowScripts: true })
|
|
676
803
|
}
|
|
677
804
|
|
|
678
805
|
async _upgradeNpmPackage(name, proxy) {
|
|
679
806
|
const npm = new NpmManager()
|
|
680
|
-
return npm.upgrade(name, { global: true, proxy, allowScripts:
|
|
807
|
+
return npm.upgrade(name, { global: true, proxy, allowScripts: true })
|
|
681
808
|
}
|
|
682
809
|
|
|
683
810
|
async _uninstallNpmPackage(name) {
|