@ranger1/dx 0.1.95 → 0.1.97
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/lib/cli/commands/core.js +88 -45
- package/lib/cli/commands/db.js +22 -32
- package/lib/cli/commands/export.js +7 -2
- package/lib/cli/commands/start.js +14 -33
- package/lib/cli/commands/worktree.js +0 -4
- package/lib/cli/dx-cli.js +46 -98
- package/lib/cli/flags.js +5 -7
- package/lib/cli/help-model.js +217 -0
- package/lib/cli/help-renderer.js +135 -0
- package/lib/cli/help-schema.js +549 -0
- package/lib/cli/help.js +114 -291
- package/lib/env.js +4 -5
- package/lib/worktree.js +37 -17
- package/package.json +1 -1
package/lib/cli/commands/core.js
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
-
import { join, relative } from 'node:path'
|
|
2
|
+
import { dirname, join, relative } from 'node:path'
|
|
3
3
|
import { logger } from '../../logger.js'
|
|
4
4
|
import { confirmManager } from '../../confirm.js'
|
|
5
5
|
import { execManager } from '../../exec.js'
|
|
6
6
|
import { showHelp, showCommandHelp } from '../help.js'
|
|
7
7
|
|
|
8
8
|
export function handleHelp(cli, args = []) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
else showHelp()
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function handleDev(cli, args = []) {
|
|
15
|
-
return cli.reportDevCommandRemoved(args)
|
|
9
|
+
if (args[0]) showCommandHelp(args[0], cli)
|
|
10
|
+
else showHelp(cli)
|
|
16
11
|
}
|
|
17
12
|
|
|
18
13
|
export async function handleBuild(cli, args) {
|
|
@@ -24,12 +19,6 @@ export async function handleBuild(cli, args) {
|
|
|
24
19
|
|
|
25
20
|
const buildConfig = cli.commands.build[target]
|
|
26
21
|
if (!buildConfig) {
|
|
27
|
-
// 兼容用户误输入或快捷命令,把 "all./scripts/dx" 这类粘连错误拆分
|
|
28
|
-
const fixed = String(target).split(/\s|\t|\r|\n|\u00A0|\.|\//)[0]
|
|
29
|
-
if (fixed && cli.commands.build[fixed]) {
|
|
30
|
-
logger.warn(`自动修正构建目标: ${target} -> ${fixed}`)
|
|
31
|
-
return await handleBuild(cli, [fixed])
|
|
32
|
-
}
|
|
33
22
|
logger.error(`未找到构建目标: ${target}`)
|
|
34
23
|
process.exitCode = 1
|
|
35
24
|
return
|
|
@@ -40,14 +29,12 @@ export async function handleBuild(cli, args) {
|
|
|
40
29
|
// 处理嵌套配置
|
|
41
30
|
let config = buildConfig
|
|
42
31
|
if (typeof config === 'object' && !config.command) {
|
|
43
|
-
const supportsCurrentEnv = Boolean(
|
|
44
|
-
config[envKey] || (envKey === 'staging' && config.prod),
|
|
45
|
-
)
|
|
32
|
+
const supportsCurrentEnv = Boolean(config[envKey])
|
|
46
33
|
if (explicitEnv && !supportsCurrentEnv) {
|
|
47
34
|
const envFlag = cli.getEnvironmentFlagExample(envKey) || `--${envKey}`
|
|
48
35
|
logger.error(`构建目标 ${target} 不支持 ${envFlag} 环境`)
|
|
49
36
|
logger.info('显式传入环境标志时,必须是该 target 实际支持的环境。')
|
|
50
|
-
const available = ['
|
|
37
|
+
const available = ['development', 'staging', 'production', 'test', 'e2e']
|
|
51
38
|
.filter(key => key in config)
|
|
52
39
|
.map(key => cli.getEnvironmentFlagExample(key) || `--${key}`)
|
|
53
40
|
if (available.length > 0) {
|
|
@@ -61,10 +48,15 @@ export async function handleBuild(cli, args) {
|
|
|
61
48
|
return
|
|
62
49
|
}
|
|
63
50
|
|
|
64
|
-
//
|
|
51
|
+
// 严格按显式环境选择配置,不做环境回退
|
|
65
52
|
if (config[envKey]) config = config[envKey]
|
|
66
|
-
else
|
|
67
|
-
|
|
53
|
+
else config = null
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!config) {
|
|
57
|
+
logger.error(`构建目标 ${target} 未提供 ${cli.getEnvironmentFlagExample(envKey) || envKey} 环境配置`)
|
|
58
|
+
process.exitCode = 1
|
|
59
|
+
return
|
|
68
60
|
}
|
|
69
61
|
|
|
70
62
|
if (config.concurrent) {
|
|
@@ -83,11 +75,7 @@ export async function handleTest(cli, args) {
|
|
|
83
75
|
|
|
84
76
|
// 解析 -t 参数用于指定特定测试用例(使用原始参数列表)
|
|
85
77
|
const allArgs = cli.args // 使用原始参数列表包含所有标志
|
|
86
|
-
const
|
|
87
|
-
let testNamePattern = null
|
|
88
|
-
if (testNamePatternIndex !== -1 && testNamePatternIndex + 1 < allArgs.length) {
|
|
89
|
-
testNamePattern = allArgs[testNamePatternIndex + 1]
|
|
90
|
-
}
|
|
78
|
+
const testNamePattern = resolveTestNamePattern(allArgs)
|
|
91
79
|
|
|
92
80
|
// 根据测试类型自动设置环境标志
|
|
93
81
|
if (type === 'e2e' && !cli.flags.e2e) {
|
|
@@ -120,7 +108,8 @@ export async function handleTest(cli, args) {
|
|
|
120
108
|
process.exit(1)
|
|
121
109
|
}
|
|
122
110
|
|
|
123
|
-
|
|
111
|
+
const normalizedTestPath = normalizeE2eTestPathForCommand(cli, fileCommand, testPath)
|
|
112
|
+
let command = fileCommand.replace('{TEST_PATH}', shellEscape(normalizedTestPath))
|
|
124
113
|
|
|
125
114
|
if (testNamePattern) {
|
|
126
115
|
command += ` -t ${shellEscape(testNamePattern)}`
|
|
@@ -179,6 +168,15 @@ function shellEscape(value) {
|
|
|
179
168
|
return `'${String(value).replace(/'/g, `'\\''`)}'`
|
|
180
169
|
}
|
|
181
170
|
|
|
171
|
+
function resolveTestNamePattern(args = []) {
|
|
172
|
+
const aliases = ['-t', '--name', '--test-name-pattern']
|
|
173
|
+
for (let i = 0; i < args.length; i++) {
|
|
174
|
+
if (!aliases.includes(args[i])) continue
|
|
175
|
+
if (i + 1 < args.length) return args[i + 1]
|
|
176
|
+
}
|
|
177
|
+
return null
|
|
178
|
+
}
|
|
179
|
+
|
|
182
180
|
function shouldUseDirectPathArg(command) {
|
|
183
181
|
const text = String(command || '')
|
|
184
182
|
return (
|
|
@@ -196,11 +194,11 @@ function normalizeUnitTestPathForCommand(cli, command, testPath) {
|
|
|
196
194
|
return rawPath
|
|
197
195
|
}
|
|
198
196
|
|
|
199
|
-
const
|
|
200
|
-
if (!
|
|
197
|
+
const projectCwd = resolveNxTargetProjectCwd(cli, command, ['test'])
|
|
198
|
+
if (!projectCwd) return rawPath
|
|
201
199
|
|
|
202
200
|
const projectRoot = cli?.projectRoot || process.cwd()
|
|
203
|
-
const absoluteProjectCwd = join(projectRoot,
|
|
201
|
+
const absoluteProjectCwd = join(projectRoot, projectCwd)
|
|
204
202
|
const absoluteTestPath = join(projectRoot, rawPath)
|
|
205
203
|
const relativePath = relative(absoluteProjectCwd, absoluteTestPath)
|
|
206
204
|
|
|
@@ -211,33 +209,78 @@ function normalizeUnitTestPathForCommand(cli, command, testPath) {
|
|
|
211
209
|
return relativePath
|
|
212
210
|
}
|
|
213
211
|
|
|
214
|
-
function
|
|
212
|
+
function normalizeE2eTestPathForCommand(cli, command, testPath) {
|
|
213
|
+
const rawPath = String(testPath || '')
|
|
214
|
+
if (!rawPath) return rawPath
|
|
215
|
+
|
|
216
|
+
const projectCwd = resolveNxTargetProjectCwd(cli, command, ['test:e2e'])
|
|
217
|
+
if (!projectCwd) return rawPath
|
|
218
|
+
|
|
215
219
|
const projectRoot = cli?.projectRoot || process.cwd()
|
|
216
|
-
const
|
|
217
|
-
|
|
220
|
+
const absoluteProjectCwd = join(projectRoot, projectCwd)
|
|
221
|
+
const absoluteTestPath = join(projectRoot, rawPath)
|
|
222
|
+
const relativePath = relative(absoluteProjectCwd, absoluteTestPath)
|
|
218
223
|
|
|
219
|
-
|
|
224
|
+
if (!relativePath || relativePath.startsWith('..')) {
|
|
225
|
+
return rawPath
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return relativePath
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function resolveNxTargetProjectCwd(cli, command, targetNames = []) {
|
|
232
|
+
const projectRoot = cli?.projectRoot || process.cwd()
|
|
233
|
+
const nxResolution = extractNxTarget(command, targetNames)
|
|
234
|
+
if (!nxResolution) return null
|
|
235
|
+
|
|
236
|
+
const projectDir = join(projectRoot, 'apps', nxResolution.project)
|
|
237
|
+
const projectConfigPath = join(projectDir, 'project.json')
|
|
220
238
|
if (!existsSync(projectConfigPath)) return null
|
|
221
239
|
|
|
222
240
|
try {
|
|
223
241
|
const projectConfig = JSON.parse(readFileSync(projectConfigPath, 'utf8'))
|
|
224
|
-
const
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
242
|
+
const resolvedTarget = projectConfig?.targets?.[nxResolution.target]
|
|
243
|
+
const cwd = resolvedTarget?.options?.cwd
|
|
244
|
+
if (typeof cwd === 'string' && cwd.trim().length > 0) {
|
|
245
|
+
return cwd
|
|
246
|
+
}
|
|
247
|
+
if (nxResolution.target === 'test:e2e') {
|
|
248
|
+
const e2eDir = join(projectDir, 'e2e')
|
|
249
|
+
if (existsSync(e2eDir)) {
|
|
250
|
+
return relative(projectRoot, e2eDir)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return relative(projectRoot, dirname(projectConfigPath))
|
|
230
254
|
} catch {
|
|
231
255
|
return null
|
|
232
256
|
}
|
|
233
257
|
}
|
|
234
258
|
|
|
235
|
-
function
|
|
259
|
+
function extractNxTarget(command, targetNames = []) {
|
|
236
260
|
const text = String(command || '').trim()
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
261
|
+
const names = Array.isArray(targetNames) && targetNames.length > 0 ? targetNames : ['test']
|
|
262
|
+
|
|
263
|
+
for (const targetName of names) {
|
|
264
|
+
if (targetName === 'test') {
|
|
265
|
+
const directMatch = text.match(/\bnx(?:\.js)?\s+test\s+([^\s]+)/)
|
|
266
|
+
if (directMatch?.[1]) {
|
|
267
|
+
return { project: directMatch[1], target: 'test' }
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const escapedTarget = targetName.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
|
|
272
|
+
const runMatch = text.match(new RegExp(`\\bnx(?:\\.js)?\\s+run\\s+([^:\\s]+):${escapedTarget}\\b`))
|
|
273
|
+
if (runMatch?.[1]) {
|
|
274
|
+
return { project: runMatch[1], target: targetName }
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const directColonMatch = text.match(new RegExp(`\\bnx(?:\\.js)?\\s+${escapedTarget}\\s+([^\\s]+)`))
|
|
278
|
+
if (directColonMatch?.[1]) {
|
|
279
|
+
return { project: directColonMatch[1], target: targetName }
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return null
|
|
241
284
|
}
|
|
242
285
|
|
|
243
286
|
export async function handleLint(cli, args) {
|
package/lib/cli/commands/db.js
CHANGED
|
@@ -22,7 +22,7 @@ export async function handleDatabase(cli, args) {
|
|
|
22
22
|
const envKey = cli.normalizeEnvKey(environment)
|
|
23
23
|
|
|
24
24
|
// 创建迁移只允许在开发环境进行,避免 AI/用户在非开发环境误执行
|
|
25
|
-
if (action === 'migrate' && envKey && envKey !== '
|
|
25
|
+
if (action === 'migrate' && envKey && envKey !== 'development') {
|
|
26
26
|
const envFlag = cli.getEnvironmentFlagExample(envKey) || `--${envKey}`
|
|
27
27
|
logger.error('dx db migrate 仅允许在 --dev 环境下创建迁移')
|
|
28
28
|
logger.info('请使用 `dx db migrate --dev --name <migration-name>` 创建新迁移。')
|
|
@@ -49,10 +49,15 @@ export async function handleDatabase(cli, args) {
|
|
|
49
49
|
// 处理嵌套配置
|
|
50
50
|
let config = dbConfig
|
|
51
51
|
if (typeof config === 'object' && !config.command) {
|
|
52
|
-
//
|
|
52
|
+
// 严格按显式环境选择配置,不做环境回退
|
|
53
53
|
if (config[envKey]) config = config[envKey]
|
|
54
|
-
else
|
|
55
|
-
|
|
54
|
+
else config = null
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!config) {
|
|
58
|
+
logger.error(`数据库操作 ${action} 未提供 ${cli.getEnvironmentFlagExample(envKey) || envKey} 环境配置`)
|
|
59
|
+
process.exitCode = 1
|
|
60
|
+
return
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
// 危险操作确认
|
|
@@ -71,7 +76,7 @@ export async function handleDatabase(cli, args) {
|
|
|
71
76
|
|
|
72
77
|
// 支持为 migrate 传入迁移名:--name/-n
|
|
73
78
|
let command = config.command
|
|
74
|
-
if (action === 'migrate' && envKey === '
|
|
79
|
+
if (action === 'migrate' && envKey === 'development') {
|
|
75
80
|
const allArgs = cli.args
|
|
76
81
|
let migrationName = null
|
|
77
82
|
// 优先解析显式标志 --name/-n
|
|
@@ -123,24 +128,14 @@ export async function handleDatabase(cli, args) {
|
|
|
123
128
|
.join('')
|
|
124
129
|
}
|
|
125
130
|
|
|
126
|
-
if (action === 'reset' && envKey !== '
|
|
131
|
+
if (action === 'reset' && envKey !== 'production') {
|
|
127
132
|
extraEnv.PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION = 'yes'
|
|
128
133
|
logger.info('非生产环境重置数据库,已自动确认危险操作: PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION=yes')
|
|
129
134
|
}
|
|
130
135
|
|
|
131
|
-
const execFlags = { ...cli.flags }
|
|
132
|
-
;['dev', 'development', 'prod', 'production', 'test', 'e2e', 'staging', 'stage'].forEach(
|
|
133
|
-
key => delete execFlags[key],
|
|
134
|
-
)
|
|
135
|
-
if (envKey === 'prod') execFlags.prod = true
|
|
136
|
-
else if (envKey === 'dev') execFlags.dev = true
|
|
137
|
-
else if (envKey === 'test') execFlags.test = true
|
|
138
|
-
else if (envKey === 'e2e') execFlags.e2e = true
|
|
139
|
-
else if (envKey === 'staging') execFlags.staging = true
|
|
140
|
-
|
|
141
136
|
await cli.executeCommand(
|
|
142
137
|
{ ...config, command, env: { ...(config.env || {}), ...extraEnv } },
|
|
143
|
-
|
|
138
|
+
cli.createExecutionFlags(environment),
|
|
144
139
|
)
|
|
145
140
|
}
|
|
146
141
|
|
|
@@ -177,7 +172,7 @@ export async function handleDatabaseScript(cli, scriptName, envKey, dbConfig) {
|
|
|
177
172
|
return
|
|
178
173
|
}
|
|
179
174
|
|
|
180
|
-
const environment = envKey
|
|
175
|
+
const environment = envKey
|
|
181
176
|
logger.step(`执行数据库脚本: ${cleanScriptName} (${environment})`)
|
|
182
177
|
logger.info(`脚本路径: ${scriptPath}`)
|
|
183
178
|
|
|
@@ -185,12 +180,17 @@ export async function handleDatabaseScript(cli, scriptName, envKey, dbConfig) {
|
|
|
185
180
|
let config = dbConfig
|
|
186
181
|
if (typeof config === 'object' && !config.command) {
|
|
187
182
|
if (config[envKey]) config = config[envKey]
|
|
188
|
-
else
|
|
189
|
-
|
|
183
|
+
else config = null
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (!config) {
|
|
187
|
+
logger.error(`数据库脚本 ${scriptName} 未提供 ${cli.getEnvironmentFlagExample(envKey) || envKey} 环境配置`)
|
|
188
|
+
process.exitCode = 1
|
|
189
|
+
return
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
// 危险操作确认
|
|
193
|
-
if (config.dangerous && envKey === '
|
|
193
|
+
if (config.dangerous && envKey === 'production') {
|
|
194
194
|
const confirmed = await confirmManager.confirmDatabaseOperation(
|
|
195
195
|
`script: ${cleanScriptName}`,
|
|
196
196
|
envManager.getEnvironmentDescription(environment),
|
|
@@ -224,18 +224,8 @@ export async function handleDatabaseScript(cli, scriptName, envKey, dbConfig) {
|
|
|
224
224
|
const extraEnv = { NX_CACHE: 'false' }
|
|
225
225
|
logger.info('为数据库脚本禁用 Nx 缓存: NX_CACHE=false')
|
|
226
226
|
|
|
227
|
-
const execFlags = { ...cli.flags }
|
|
228
|
-
;['dev', 'development', 'prod', 'production', 'test', 'e2e', 'staging', 'stage'].forEach(
|
|
229
|
-
key => delete execFlags[key],
|
|
230
|
-
)
|
|
231
|
-
if (envKey === 'prod') execFlags.prod = true
|
|
232
|
-
else if (envKey === 'dev') execFlags.dev = true
|
|
233
|
-
else if (envKey === 'test') execFlags.test = true
|
|
234
|
-
else if (envKey === 'e2e') execFlags.e2e = true
|
|
235
|
-
else if (envKey === 'staging') execFlags.staging = true
|
|
236
|
-
|
|
237
227
|
await cli.executeCommand(
|
|
238
228
|
{ ...config, command, env: { ...(config.env || {}), ...extraEnv } },
|
|
239
|
-
|
|
229
|
+
cli.createExecutionFlags(environment),
|
|
240
230
|
)
|
|
241
231
|
}
|
|
@@ -25,8 +25,13 @@ export async function handleExport(cli, args) {
|
|
|
25
25
|
let config = exportConfig
|
|
26
26
|
if (typeof config === 'object' && !config.command) {
|
|
27
27
|
if (config[envKey]) config = config[envKey]
|
|
28
|
-
else
|
|
29
|
-
|
|
28
|
+
else config = null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!config) {
|
|
32
|
+
logger.error(`导出目标 ${target} 未提供 ${cli.getEnvironmentFlagExample(envKey) || envKey} 环境配置`)
|
|
33
|
+
process.exitCode = 1
|
|
34
|
+
return
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
logger.step(`导出 ${target} (${environment})`)
|
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
import { logger } from '../../logger.js'
|
|
2
2
|
|
|
3
3
|
export async function handleStart(cli, args) {
|
|
4
|
-
const service = args[0] || '
|
|
4
|
+
const service = args[0] || 'development'
|
|
5
5
|
|
|
6
6
|
const environment = cli.determineEnvironment()
|
|
7
7
|
const envKey = cli.normalizeEnvKey(environment)
|
|
8
|
-
|
|
9
|
-
let rawConfig = cli.commands.start[service]
|
|
10
|
-
let configNamespace = 'start'
|
|
11
|
-
|
|
12
|
-
if (!rawConfig && cli.commands.dev?.[service]) {
|
|
13
|
-
if (envKey !== 'dev') {
|
|
14
|
-
logger.error(`目标 ${service} 仅支持开发环境启动,请使用 --dev 或省略环境标志。`)
|
|
15
|
-
process.exitCode = 1
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
rawConfig = cli.commands.dev[service]
|
|
19
|
-
configNamespace = 'dev'
|
|
20
|
-
logger.info(`检测到 legacy "dev" 配置,已自动回退至 ${service} 开发脚本。`)
|
|
21
|
-
}
|
|
8
|
+
const rawConfig = cli.commands.start[service]
|
|
22
9
|
|
|
23
10
|
if (!rawConfig) {
|
|
24
11
|
logger.error(`未找到启动配置: ${service}`)
|
|
@@ -27,13 +14,17 @@ export async function handleStart(cli, args) {
|
|
|
27
14
|
}
|
|
28
15
|
|
|
29
16
|
let startConfig = rawConfig
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
17
|
+
const isRunnableConfig =
|
|
18
|
+
rawConfig &&
|
|
19
|
+
typeof rawConfig === 'object' &&
|
|
20
|
+
(rawConfig.command || rawConfig.internal || rawConfig.concurrent || rawConfig.sequential)
|
|
21
|
+
|
|
22
|
+
if (!isRunnableConfig && rawConfig && typeof rawConfig === 'object') {
|
|
23
|
+
startConfig = rawConfig[envKey] || null
|
|
33
24
|
}
|
|
34
25
|
|
|
35
26
|
if (!startConfig) {
|
|
36
|
-
logger.error(`启动目标 ${service} 未提供 ${
|
|
27
|
+
logger.error(`启动目标 ${service} 未提供 ${cli.getEnvironmentFlagExample(envKey) || envKey} 环境配置。`)
|
|
37
28
|
process.exitCode = 1
|
|
38
29
|
return
|
|
39
30
|
}
|
|
@@ -41,7 +32,7 @@ export async function handleStart(cli, args) {
|
|
|
41
32
|
logger.step(`启动 ${service} 服务 (${environment})`)
|
|
42
33
|
|
|
43
34
|
if (startConfig.concurrent && Array.isArray(startConfig.commands)) {
|
|
44
|
-
await cli.handleConcurrentCommands(startConfig.commands,
|
|
35
|
+
await cli.handleConcurrentCommands(startConfig.commands, 'start', envKey)
|
|
45
36
|
return
|
|
46
37
|
}
|
|
47
38
|
|
|
@@ -52,26 +43,16 @@ export async function handleStart(cli, args) {
|
|
|
52
43
|
|
|
53
44
|
const ports = cli.collectStartPorts(service, startConfig, envKey)
|
|
54
45
|
|
|
55
|
-
if (envKey === '
|
|
46
|
+
if (envKey === 'development' && ports.length > 0) {
|
|
56
47
|
logger.info(`开发环境自动清理端口: ${ports.join(', ')}`)
|
|
57
48
|
}
|
|
58
49
|
|
|
59
50
|
const configToExecute = {
|
|
60
51
|
...startConfig,
|
|
61
52
|
...(ports.length > 0 ? { ports } : {}),
|
|
62
|
-
...(envKey === '
|
|
53
|
+
...(envKey === 'development' ? { forcePortCleanup: true } : {}),
|
|
63
54
|
}
|
|
64
55
|
|
|
65
56
|
// 为执行阶段构造环境标志,确保 dotenv 选择正确层
|
|
66
|
-
|
|
67
|
-
;['dev', 'development', 'prod', 'production', 'test', 'e2e', 'staging', 'stage'].forEach(
|
|
68
|
-
key => delete execFlags[key]
|
|
69
|
-
)
|
|
70
|
-
if (envKey === 'prod') execFlags.prod = true
|
|
71
|
-
else if (envKey === 'dev') execFlags.dev = true
|
|
72
|
-
else if (envKey === 'test') execFlags.test = true
|
|
73
|
-
else if (envKey === 'e2e') execFlags.e2e = true
|
|
74
|
-
else if (envKey === 'staging') execFlags.staging = true
|
|
75
|
-
|
|
76
|
-
await cli.executeCommand(configToExecute, execFlags)
|
|
57
|
+
await cli.executeCommand(configToExecute, cli.createExecutionFlags(environment))
|
|
77
58
|
}
|
|
@@ -64,8 +64,6 @@ export async function handleWorktree(cli, args) {
|
|
|
64
64
|
break
|
|
65
65
|
|
|
66
66
|
case 'del':
|
|
67
|
-
case 'delete':
|
|
68
|
-
case 'rm':
|
|
69
67
|
// 互斥校验:--all 不能与 issue 编号同时使用
|
|
70
68
|
// args[0] 是 action,args[1] 开始才是 issue 编号
|
|
71
69
|
if (cli.flags.all && args.length > 1) {
|
|
@@ -131,12 +129,10 @@ export async function handleWorktree(cli, args) {
|
|
|
131
129
|
break
|
|
132
130
|
|
|
133
131
|
case 'list':
|
|
134
|
-
case 'ls':
|
|
135
132
|
await worktreeManager.list()
|
|
136
133
|
break
|
|
137
134
|
|
|
138
135
|
case 'clean':
|
|
139
|
-
case 'prune':
|
|
140
136
|
await worktreeManager.clean()
|
|
141
137
|
break
|
|
142
138
|
|