@mznjs/mbump 2.0.3 → 2.2.0

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.
@@ -1,3 +1,5 @@
1
+ import { createRequire } from "module";
2
+
1
3
  //#region rolldown:runtime
2
4
  var __defProp = Object.defineProperty;
3
5
  var __export = (target, all) => {
@@ -6,6 +8,7 @@ var __export = (target, all) => {
6
8
  enumerable: true
7
9
  });
8
10
  };
11
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
9
12
 
10
13
  //#endregion
11
- export { __export };
14
+ export { __export, __require };
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","names":[],"sources":["../src/cli/index.ts"],"sourcesContent":null,"mappings":";;iBA2KgB,QAAA,CAAA;;;AAAhB"}
1
+ {"version":3,"file":"cli.d.ts","names":[],"sources":["../src/cli/index.ts"],"sourcesContent":null,"mappings":";;iBA6RgB,QAAA,CAAA;;;AAAhB"}
package/dist/cli.js CHANGED
@@ -1,15 +1,29 @@
1
1
  #!/usr/bin/env node
2
- import { VersionManager, loadConfigAsync, logger_default } from "./VersionManager-CwsuNWyP.js";
2
+ import { __require } from "./chunk-DAa1jVm7.js";
3
+ import { RustManager, VersionManager, clearConfigCache, isPathLike, loadConfigAsync, logger_default } from "./path-Dxq6zEl-.js";
3
4
  import { existsSync, readFileSync } from "node:fs";
4
- import { dirname, join } from "node:path";
5
+ import { dirname, join, resolve } from "node:path";
5
6
  import { execSync } from "node:child_process";
6
- import process from "node:process";
7
7
  import semver from "semver";
8
+ import process from "node:process";
8
9
  import { fileURLToPath } from "node:url";
9
10
  import inquirer from "inquirer";
10
11
 
11
12
  //#region src/cli/interactive.ts
12
- async function selectVersionInteractive(config, packageName, currentVersion) {
13
+ async function selectVersionInteractive(config, packageName, currentVersion, rootDir) {
14
+ let displayName = packageName;
15
+ if (rootDir && packageName !== "default") {
16
+ const pkgPath = config.packagePaths[packageName];
17
+ if (pkgPath) {
18
+ const { readFileSync: readFileSync$1 } = __require("node:fs");
19
+ const { join: join$1, resolve: resolve$1 } = __require("node:path");
20
+ try {
21
+ const fullPath = resolve$1(rootDir, pkgPath);
22
+ const pkgContent = JSON.parse(readFileSync$1(fullPath, "utf8"));
23
+ if (pkgContent.name) displayName = pkgContent.name;
24
+ } catch {}
25
+ }
26
+ }
13
27
  const choices = [
14
28
  {
15
29
  name: `major ${semver.inc(currentVersion, "major")}`,
@@ -55,7 +69,7 @@ async function selectVersionInteractive(config, packageName, currentVersion) {
55
69
  const answers = await inquirer.prompt([{
56
70
  type: "list",
57
71
  name: "versionType",
58
- message: `[${packageName}] Current version ${currentVersion} »`,
72
+ message: `[${displayName}] Current version ${currentVersion} »`,
59
73
  choices,
60
74
  default: config.defaults?.releaseType || "patch"
61
75
  }]);
@@ -85,7 +99,7 @@ async function selectAllVersionsInteractive(config, rootDir) {
85
99
  for (const packageName of allPackageNames) {
86
100
  const currentVersion = versionManager.getPackageVersion(packageName);
87
101
  if (currentVersion) {
88
- const selection = await selectVersionInteractive(config, packageName, currentVersion);
102
+ const selection = await selectVersionInteractive(config, packageName, currentVersion, rootDir);
89
103
  selections[packageName] = selection;
90
104
  }
91
105
  }
@@ -97,15 +111,21 @@ async function selectAllVersionsInteractive(config, rootDir) {
97
111
  function parseArgs(args, defaults = {}) {
98
112
  const parsed = {
99
113
  package: null,
100
- type: defaults.releaseType || defaults.type || "patch",
114
+ projectPath: null,
115
+ type: void 0,
101
116
  dryRun: defaults.dryRun || false,
102
117
  help: false,
118
+ version: false,
103
119
  verbose: defaults.verbose || false,
104
120
  autoCommit: defaults.git?.autoCommit !== false,
105
121
  push: defaults.git?.push !== false,
106
122
  allowUncommitted: defaults.allowUncommitted || false,
107
123
  npm: defaults.npm || false,
108
- showConfig: false
124
+ showConfig: false,
125
+ rust: false,
126
+ tag: defaults.git?.tag !== false,
127
+ tagPrefix: defaults.git?.tagPrefix || "v",
128
+ changelog: defaults.git?.changelog !== false
109
129
  };
110
130
  const allowedTypes = [
111
131
  "major",
@@ -136,12 +156,18 @@ function parseArgs(args, defaults = {}) {
136
156
  } else if (arg === "--allow-uncommitted" || arg === "-u") {
137
157
  parsed.allowUncommitted = true;
138
158
  i++;
139
- } else if (arg === "--npm" || arg === "-npm") {
159
+ } else if (arg === "--npm" || arg === "-N") {
140
160
  parsed.npm = true;
141
161
  i++;
142
- } else if (arg === "--show-config") {
162
+ } else if (arg === "--show-config" || arg === "-c") {
143
163
  parsed.showConfig = true;
144
164
  i++;
165
+ } else if (arg === "--rust" || arg === "-r") {
166
+ parsed.rust = true;
167
+ i++;
168
+ } else if (arg === "--version" || arg === "-V") {
169
+ parsed.version = true;
170
+ i++;
145
171
  } else if (arg === "--type" || arg === "-t") if (i + 1 < args.length) {
146
172
  const typeValue = args[i + 1];
147
173
  if (allowedTypes.includes(typeValue)) {
@@ -155,8 +181,10 @@ function parseArgs(args, defaults = {}) {
155
181
  else throw new Error(`不支持的版本类型: ${typeValue},支持的类型: ${allowedTypes.join(", ")}`);
156
182
  i++;
157
183
  } else if (!arg.startsWith("-")) {
158
- if (!parsed.package) parsed.package = arg;
184
+ if (!parsed.projectPath && !parsed.package) if (isPathLike(arg)) parsed.projectPath = arg;
185
+ else parsed.package = arg;
159
186
  else if (allowedTypes.includes(arg)) parsed.type = arg;
187
+ else if (!parsed.package && !isPathLike(arg)) parsed.package = arg;
160
188
  i++;
161
189
  } else i++;
162
190
  }
@@ -167,6 +195,21 @@ function parseArgs(args, defaults = {}) {
167
195
  //#region src/cli/index.ts
168
196
  const __filename = fileURLToPath(import.meta.url);
169
197
  const __dirname = dirname(__filename);
198
+ function renderPreview(preview) {
199
+ logger_default.info("🔍 Dry-run 模式 - 以下操作将被执行:\n");
200
+ for (const pkg of preview.packages) {
201
+ logger_default.info(` 📦 ${pkg.name}`);
202
+ logger_default.info(` 当前版本: ${pkg.oldVersion}`);
203
+ logger_default.info(` 新版本: ${pkg.newVersion}`);
204
+ logger_default.info(` Tag: ${pkg.tagName}`);
205
+ logger_default.info(` CHANGELOG: ${pkg.changelogEnabled ? "是" : pkg.isDefaultPackage ? "否(配置禁用)" : "跳过(子包)"}`);
206
+ logger_default.info("");
207
+ }
208
+ logger_default.info(` Git Commit: ${preview.autoCommit ? "是" : "否"}`);
209
+ logger_default.info(` Git Push: ${preview.push ? "是" : "否"}`);
210
+ logger_default.info(` NPM Publish: ${preview.npm ? "是" : "否"}`);
211
+ logger_default.info("\n✅ 以上为预览,未执行任何实际操作");
212
+ }
170
213
  let packageVersion = "1.0.0";
171
214
  const possiblePaths = [
172
215
  join(__dirname, "..", "..", "package.json"),
@@ -206,6 +249,54 @@ function getFriendlyErrorMessage(error) {
206
249
  message: "❌ 无效的包名",
207
250
  solution: "💡 请检查配置文件中的 packagePaths 是否正确设置"
208
251
  };
252
+ if (errorMessage.includes("不支持的版本类型")) return {
253
+ message: "❌ 不支持的版本类型",
254
+ solution: "💡 支持的版本类型: major, minor, patch, pre-patch, pre-minor, pre-major, next, as-is, conventional"
255
+ };
256
+ if (errorMessage.includes("无效的自定义版本号")) return {
257
+ message: "❌ 无效的自定义版本号",
258
+ solution: "💡 请使用符合 semver 规范的版本号,如 1.0.0, 1.0.1-beta.1"
259
+ };
260
+ if (errorMessage.includes("版本计算失败")) return {
261
+ message: "❌ 版本计算失败",
262
+ solution: "💡 请检查当前版本号是否符合 semver 规范,或使用 --verbose 模式查看详细错误"
263
+ };
264
+ if (errorMessage.includes("无法计算新版本号")) return {
265
+ message: "❌ 无法计算新版本号",
266
+ solution: "💡 请检查当前版本号是否符合 semver 规范,或尝试使用不同的版本类型"
267
+ };
268
+ if (errorMessage.includes("读取文件失败")) return {
269
+ message: "📁 文件读取失败",
270
+ solution: "💡 请检查文件路径是否正确,文件是否存在且有读取权限"
271
+ };
272
+ if (errorMessage.includes("写入文件失败")) return {
273
+ message: "📁 文件写入失败",
274
+ solution: "💡 请检查文件路径是否正确,是否有写入权限,磁盘空间是否充足"
275
+ };
276
+ if (errorMessage.includes("Git") && errorMessage.includes("失败")) return {
277
+ message: "🔧 Git 操作失败",
278
+ solution: "💡 请检查 Git 仓库状态,确保有提交权限,或使用 --verbose 模式查看详细错误"
279
+ };
280
+ if (errorMessage.includes("发布失败")) return {
281
+ message: "🚀 NPM 发布失败",
282
+ solution: "💡 请检查 NPM 配置、认证状态和网络连接,或使用 --verbose 模式查看详细错误"
283
+ };
284
+ if (errorMessage.includes("Cargo.toml")) return {
285
+ message: "🦀 Cargo.toml 操作失败",
286
+ solution: "💡 请检查 Cargo.toml 文件是否存在,格式是否正确,或使用 --verbose 模式查看详细错误"
287
+ };
288
+ if (errorMessage.includes("不存在 package.json")) return {
289
+ message: "📦 package.json 不存在",
290
+ solution: "💡 请确保指定的路径是一个有效的 Node.js 项目目录"
291
+ };
292
+ if (errorMessage.includes("路径") && errorMessage.includes("不存在") && !errorMessage.includes("package.json")) return {
293
+ message: "📂 路径不存在",
294
+ solution: "💡 请检查路径是否正确,确保目录存在"
295
+ };
296
+ if (errorMessage.includes("配置错误")) return {
297
+ message: "⚙️ 配置错误",
298
+ solution: "💡 请检查配置文件是否正确,或使用 --show-config 查看当前配置"
299
+ };
209
300
  return {
210
301
  message: `❌ ${errorMessage}`,
211
302
  solution: "💡 请检查错误信息,或使用 --verbose 模式查看更多详情"
@@ -259,10 +350,11 @@ function showHelp() {
259
350
  ========================
260
351
  企业级版本管理工具,支持单包和monorepo场景
261
352
 
262
- 用法: mbump [package] [type] [options]
353
+ 用法: mbump [package|path] [type] [options]
263
354
 
264
355
  参数:
265
356
  [package] 要更新的包名称或 "all" 更新所有包
357
+ [path] 项目目录路径(支持 ./path, ../path, /path, C:\\path),自动查找该目录下的 package.json
266
358
  [type] 版本升级类型: major, minor, patch, pre-patch, pre-minor, pre-major
267
359
 
268
360
  选项:
@@ -271,8 +363,10 @@ function showHelp() {
271
363
  --no-commit, -n 禁用自动git提交
272
364
  --no-push, -p 禁用自动推送到远程仓库
273
365
  --allow-uncommitted, -u 允许在有未提交更改的情况下继续操作
274
- --npm, -npm 启用npm包发布功能(默认不发布)
275
- --show-config 显示当前加载的完整配置信息
366
+ --npm, -N 启用npm包发布功能(默认不发布)
367
+ --show-config, -c 显示当前加载的完整配置信息
368
+ --rust, -r 启用 Rust 项目模式,更新 Cargo.toml 中的版本号
369
+ --version, -V 显示版本信息
276
370
  --help, -h 显示此帮助信息
277
371
 
278
372
  示例:
@@ -281,6 +375,18 @@ function showHelp() {
281
375
  mbump plugins major --dry-run # 试运行升级plugins包主版本
282
376
  mbump core patch --no-push # 更新版本并提交到本地,但不推送到远程
283
377
  mbump components patch --npm # 更新版本并发布到npm
378
+
379
+ # 路径模式(直接指定项目目录)
380
+ mbump ./packages/my-pkg # 更新 ./packages/my-pkg 目录下的 package.json
381
+ mbump ./packages/my-pkg patch # 指定版本类型
382
+ mbump ../other-project minor # 更新上级目录的项目
383
+
384
+ # Rust 项目模式(更新 Cargo.toml)
385
+ mbump --rust patch # 更新当前目录 Rust 项目的补丁版本
386
+ mbump -r minor # 更新当前目录 Rust 项目的小版本
387
+ mbump -r major --dry-run # 试运行升级当前目录 Rust 项目的主版本
388
+ mbump ./backend -r patch # 更新指定目录下的 Rust 项目
389
+ mbump ./backend -r -d # 试运行模式更新指定目录下的 Rust 项目
284
390
  `;
285
391
  logger_default.info(helpText);
286
392
  }
@@ -302,13 +408,164 @@ async function main() {
302
408
  showHelp();
303
409
  process.exit(0);
304
410
  }
411
+ if (args.includes("--version") || args.includes("-V")) {
412
+ logger_default.info(`mbump v${packageVersion}`);
413
+ process.exit(0);
414
+ }
415
+ const parsedArgs = parseArgs(args);
416
+ if (parsedArgs.rust) {
417
+ const rootDir$1 = parsedArgs.projectPath ? resolve(process.cwd(), parsedArgs.projectPath) : process.cwd();
418
+ if (parsedArgs.projectPath && !existsSync(rootDir$1)) {
419
+ displayError(new Error(`路径 "${parsedArgs.projectPath}" 不存在`), { operation: "路径验证" });
420
+ process.exit(1);
421
+ }
422
+ const rustManager = new RustManager(rootDir$1);
423
+ if (parsedArgs.projectPath) logger_default.info(`切换到项目路径: ${rootDir$1}`);
424
+ if (hasUncommittedChanges()) if (!parsedArgs.allowUncommitted) {
425
+ logger_default.warn("警告: 检测到未提交的Git更改");
426
+ const inquirer$1 = await import("inquirer");
427
+ const answers = await inquirer$1.default.prompt([{
428
+ type: "confirm",
429
+ name: "continue",
430
+ message: parsedArgs.dryRun ? "是否继续(dry-run模式不会实际提交更改)?" : "是否提交这些更改并继续?",
431
+ default: true
432
+ }]);
433
+ if (!answers.continue) {
434
+ logger_default.info("操作已取消");
435
+ process.exit(0);
436
+ }
437
+ if (!parsedArgs.dryRun) {
438
+ const commitMessage = "chore: update mbump config and settings";
439
+ execSync(`git add . && git commit -m "${commitMessage}"`, {
440
+ encoding: "utf8",
441
+ stdio: "pipe"
442
+ });
443
+ logger_default.success(`已提交更改: ${commitMessage}`);
444
+ } else logger_default.info("dry-run模式: 跳过实际提交操作");
445
+ } else logger_default.warn("警告: 存在未提交的Git更改,您选择了忽略此检查。请注意这可能导致不一致的版本状态。");
446
+ if (!rustManager.exists()) {
447
+ displayError(new Error(`Cargo.toml 文件不存在于路径 "${rootDir$1}"`), { operation: "Rust 项目检测" });
448
+ logger_default.info(`💡 请确保指定的路径是 Rust 项目根目录`);
449
+ process.exit(1);
450
+ }
451
+ const currentVersion = rustManager.getCurrentVersion();
452
+ if (!currentVersion) {
453
+ displayError(new Error(`Cargo.toml 文件中未找到 [package] 部分的 version 字段`), { operation: "版本读取" });
454
+ process.exit(1);
455
+ }
456
+ let selectedType$1 = parsedArgs.type;
457
+ let customVersion$1 = null;
458
+ if (!parsedArgs.type) {
459
+ const config$1 = {
460
+ defaults: { releaseType: "patch" },
461
+ packagePaths: {}
462
+ };
463
+ const selection = await selectVersionInteractive(config$1, "rust", currentVersion);
464
+ selectedType$1 = selection.type;
465
+ customVersion$1 = selection.customVersion;
466
+ }
467
+ try {
468
+ rustManager.updateVersion(selectedType$1, {
469
+ dryRun: parsedArgs.dryRun,
470
+ verbose: parsedArgs.verbose,
471
+ autoCommit: parsedArgs.autoCommit,
472
+ push: parsedArgs.push,
473
+ customVersion: customVersion$1,
474
+ tag: parsedArgs.tag,
475
+ tagPrefix: parsedArgs.tagPrefix,
476
+ changelog: parsedArgs.changelog,
477
+ allowUncommitted: parsedArgs.allowUncommitted
478
+ });
479
+ process.exit(0);
480
+ } catch (error) {
481
+ displayError(error, { operation: "Rust 版本更新" });
482
+ process.exit(1);
483
+ }
484
+ }
485
+ if (parsedArgs.projectPath) {
486
+ const resolvedProjectPath = resolve(process.cwd(), parsedArgs.projectPath);
487
+ if (!existsSync(resolvedProjectPath)) {
488
+ displayError(new Error(`路径 "${parsedArgs.projectPath}" 不存在`), { operation: "路径验证" });
489
+ process.exit(1);
490
+ }
491
+ const pkgJsonPath = join(resolvedProjectPath, "package.json");
492
+ if (!existsSync(pkgJsonPath)) {
493
+ displayError(new Error(`路径 "${parsedArgs.projectPath}" 中不存在 package.json`), { operation: "package.json 检测" });
494
+ logger_default.info(`💡 请确保指定的路径是一个有效的 Node.js 项目目录`);
495
+ process.exit(1);
496
+ }
497
+ logger_default.info(`切换到项目路径: ${resolvedProjectPath}`);
498
+ const pkgJsonContent = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
499
+ const packageName = pkgJsonContent.name || "default";
500
+ parsedArgs.package = packageName;
501
+ clearConfigCache(resolvedProjectPath);
502
+ const projectConfig = await loadConfigAsync(resolvedProjectPath);
503
+ projectConfig.packagePaths = { [packageName]: pkgJsonPath };
504
+ const projectVersionManager = new VersionManager({
505
+ config: projectConfig,
506
+ rootDir: resolvedProjectPath
507
+ });
508
+ logger_default.setLevel(parsedArgs.verbose ? "debug" : "info");
509
+ if (hasUncommittedChanges()) if (!parsedArgs.allowUncommitted) {
510
+ logger_default.warn("警告: 检测到未提交的Git更改");
511
+ const inquirer$1 = await import("inquirer");
512
+ const answers = await inquirer$1.default.prompt([{
513
+ type: "confirm",
514
+ name: "continue",
515
+ message: parsedArgs.dryRun ? "是否继续(dry-run模式不会实际提交更改)?" : "是否提交这些更改并继续?",
516
+ default: true
517
+ }]);
518
+ if (!answers.continue) {
519
+ logger_default.info("操作已取消");
520
+ process.exit(0);
521
+ }
522
+ if (!parsedArgs.dryRun) {
523
+ const commitMessage = "chore: update mbump config and settings";
524
+ execSync(`git add . && git commit -m "${commitMessage}"`, {
525
+ encoding: "utf8",
526
+ stdio: "pipe"
527
+ });
528
+ logger_default.success(`已提交更改: ${commitMessage}`);
529
+ } else logger_default.info("dry-run模式: 跳过实际提交操作");
530
+ } else logger_default.warn("警告: 存在未提交的Git更改,您选择了忽略此检查。请注意这可能导致不一致的版本状态。");
531
+ let selectedType$1 = parsedArgs.type;
532
+ let customVersion$1 = null;
533
+ if (!parsedArgs.type) {
534
+ const currentVersion = projectVersionManager.getPackageVersion(packageName);
535
+ if (currentVersion) {
536
+ const selection = await selectVersionInteractive(projectConfig, packageName, currentVersion, resolvedProjectPath);
537
+ selectedType$1 = selection.type;
538
+ customVersion$1 = selection.customVersion;
539
+ }
540
+ }
541
+ if (parsedArgs.dryRun) {
542
+ const preview = await projectVersionManager.previewUpdate(parsedArgs.package, selectedType$1, {
543
+ customVersion: customVersion$1,
544
+ autoCommit: parsedArgs.autoCommit,
545
+ push: parsedArgs.push,
546
+ npm: parsedArgs.npm
547
+ });
548
+ renderPreview(preview);
549
+ process.exit(0);
550
+ }
551
+ await projectVersionManager.updateVersion(parsedArgs.package, selectedType$1, {
552
+ dryRun: parsedArgs.dryRun,
553
+ verbose: parsedArgs.verbose,
554
+ autoCommit: parsedArgs.autoCommit,
555
+ push: parsedArgs.push,
556
+ npm: parsedArgs.npm,
557
+ customVersion: customVersion$1
558
+ });
559
+ logger_default.success(`版本更新完成`);
560
+ process.exit(0);
561
+ }
305
562
  const rootDir = process.cwd();
306
563
  const config = await logger_default.withSpinner("正在加载配置...", () => loadConfigAsync(rootDir), {
307
564
  succeedText: "配置加载完成",
308
565
  failText: "配置加载失败"
309
566
  });
310
- const parsedArgs = parseArgs(args, config.defaults);
311
- if (parsedArgs.showConfig) {
567
+ const parsedArgsWithDefaults = parseArgs(args, config.defaults);
568
+ if (parsedArgsWithDefaults.showConfig) {
312
569
  logger_default.info("📋 当前加载的配置:");
313
570
  logger_default.info("");
314
571
  if (config.usedConfigPath) {
@@ -339,30 +596,90 @@ async function main() {
339
596
  process.exit(0);
340
597
  }
341
598
  const packageNames = Object.keys(config.packagePaths);
342
- if (!parsedArgs.package) if (packageNames.includes("default")) parsedArgs.package = "default";
343
- else if (packageNames.length === 1) parsedArgs.package = packageNames[0];
344
- else throw new Error(`未指定包名
345
- 请指定要更新的包名,可选包: ${packageNames.join(", ")} 或使用 "all" 更新所有包`);
346
- else if (parsedArgs.package !== "all" && !packageNames.includes(parsedArgs.package)) throw new Error(`包名 "${parsedArgs.package}" 未在配置中找到\n可用的包名: ${packageNames.join(", ")} 或使用 "all" 更新所有包`);
599
+ if (!parsedArgsWithDefaults.package) if (packageNames.includes("default")) parsedArgsWithDefaults.package = "default";
600
+ else if (packageNames.length === 1) parsedArgsWithDefaults.package = packageNames[0];
601
+ else {
602
+ displayError(new Error(`未指定包名\n可用的包名: ${packageNames.join(", ")} 或使用 "all" 更新所有包`));
603
+ process.exit(1);
604
+ }
605
+ else if (parsedArgsWithDefaults.package !== "all" && !packageNames.includes(parsedArgsWithDefaults.package)) {
606
+ const maybePath = parsedArgsWithDefaults.package;
607
+ if (maybePath) {
608
+ const resolvedPath = resolve(process.cwd(), maybePath);
609
+ const pkgJsonPath = join(resolvedPath, "package.json");
610
+ if (existsSync(resolvedPath) && existsSync(pkgJsonPath)) {
611
+ logger_default.info(`切换到项目路径: ${resolvedPath}`);
612
+ const pkgJsonContent = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
613
+ const packageName = pkgJsonContent.name || "default";
614
+ clearConfigCache(resolvedPath);
615
+ const projectConfig = await loadConfigAsync(resolvedPath);
616
+ projectConfig.packagePaths = { [packageName]: pkgJsonPath };
617
+ const projectVersionManager = new VersionManager({
618
+ config: projectConfig,
619
+ rootDir: resolvedPath
620
+ });
621
+ logger_default.setLevel(parsedArgsWithDefaults.verbose ? "debug" : "info");
622
+ let selectedType$1 = parsedArgsWithDefaults.type;
623
+ let customVersion$1 = null;
624
+ if (!parsedArgsWithDefaults.type) {
625
+ const currentVersion = projectVersionManager.getPackageVersion(packageName);
626
+ if (currentVersion) {
627
+ const selection = await selectVersionInteractive(projectConfig, packageName, currentVersion, resolvedPath);
628
+ selectedType$1 = selection.type;
629
+ customVersion$1 = selection.customVersion;
630
+ }
631
+ }
632
+ if (parsedArgsWithDefaults.dryRun) {
633
+ const preview = await projectVersionManager.previewUpdate(packageName, selectedType$1, {
634
+ customVersion: customVersion$1,
635
+ autoCommit: parsedArgsWithDefaults.autoCommit,
636
+ push: parsedArgsWithDefaults.push,
637
+ npm: parsedArgsWithDefaults.npm
638
+ });
639
+ renderPreview(preview);
640
+ process.exit(0);
641
+ }
642
+ await projectVersionManager.updateVersion(packageName, selectedType$1, {
643
+ dryRun: parsedArgsWithDefaults.dryRun,
644
+ verbose: parsedArgsWithDefaults.verbose,
645
+ autoCommit: parsedArgsWithDefaults.autoCommit,
646
+ push: parsedArgsWithDefaults.push,
647
+ npm: parsedArgsWithDefaults.npm,
648
+ customVersion: customVersion$1
649
+ });
650
+ logger_default.success(`版本更新完成`);
651
+ process.exit(0);
652
+ } else {
653
+ displayError(new Error(`包名 "${parsedArgsWithDefaults.package}" 未在配置中找到,且路径 "${resolvedPath}" 不是有效的项目目录`), { operation: "包名/路径解析" });
654
+ logger_default.info(`💡 可用的包名: ${packageNames.join(", ")} 或使用 "all" 更新所有包`);
655
+ logger_default.info(`💡 也可以使用路径模式: mbump ./packages/my-pkg`);
656
+ process.exit(1);
657
+ }
658
+ }
659
+ displayError(new Error(`包名 "${parsedArgsWithDefaults.package}" 未在配置中找到`), { operation: "包名解析" });
660
+ logger_default.info(`💡 可用的包名: ${packageNames.join(", ")} 或使用 "all" 更新所有包`);
661
+ logger_default.info(`💡 也可以使用路径模式: mbump ./packages/my-pkg`);
662
+ process.exit(1);
663
+ }
347
664
  const versionManager = new VersionManager({
348
665
  config,
349
666
  rootDir
350
667
  });
351
- logger_default.setLevel(parsedArgs.verbose ? "debug" : "info");
352
- if (hasUncommittedChanges()) if (!parsedArgs.allowUncommitted) {
668
+ logger_default.setLevel(parsedArgsWithDefaults.verbose ? "debug" : "info");
669
+ if (hasUncommittedChanges()) if (!parsedArgsWithDefaults.allowUncommitted) {
353
670
  logger_default.warn("警告: 检测到未提交的Git更改");
354
671
  const inquirer$1 = await import("inquirer");
355
672
  const answers = await inquirer$1.default.prompt([{
356
673
  type: "confirm",
357
674
  name: "continue",
358
- message: parsedArgs.dryRun ? "是否继续(dry-run模式不会实际提交更改)?" : "是否提交这些更改并继续?",
675
+ message: parsedArgsWithDefaults.dryRun ? "是否继续(dry-run模式不会实际提交更改)?" : "是否提交这些更改并继续?",
359
676
  default: true
360
677
  }]);
361
678
  if (!answers.continue) {
362
679
  logger_default.info("操作已取消");
363
680
  process.exit(0);
364
681
  }
365
- if (!parsedArgs.dryRun) {
682
+ if (!parsedArgsWithDefaults.dryRun) {
366
683
  const commitMessage = "chore: update mbump config and settings";
367
684
  execSync(`git add . && git commit -m "${commitMessage}"`, {
368
685
  encoding: "utf8",
@@ -371,21 +688,21 @@ async function main() {
371
688
  logger_default.success(`已提交更改: ${commitMessage}`);
372
689
  } else logger_default.info("dry-run模式: 跳过实际提交操作");
373
690
  } else logger_default.warn("警告: 存在未提交的Git更改,您选择了忽略此检查。请注意这可能导致不一致的版本状态。");
374
- if (parsedArgs.verbose) {
691
+ if (parsedArgsWithDefaults.verbose) {
375
692
  if (config.usedConfigPath) {
376
693
  const fileName = config.usedConfigPath.split("\\").pop() || config.usedConfigPath;
377
694
  logger_default.info(`使用配置文件: ${fileName}`);
378
695
  }
379
- logger_default.info(`更新信息: 包=${parsedArgs.package}, 类型=${parsedArgs.type}${parsedArgs.dryRun ? " (试运行)" : ""}`);
696
+ logger_default.info(`更新信息: 包=${parsedArgsWithDefaults.package}, 类型=${parsedArgsWithDefaults.type}${parsedArgsWithDefaults.dryRun ? " (试运行)" : ""}`);
380
697
  }
381
- let selectedType = parsedArgs.type;
698
+ let selectedType = parsedArgsWithDefaults.type;
382
699
  let customVersion = null;
383
700
  const packageVersionSelections = {};
384
- if (!args.some((arg) => arg === "--type" || arg.startsWith("--type=") || arg === "-t" || arg.startsWith("-t="))) if (parsedArgs.package === "all") {
701
+ if (!parsedArgsWithDefaults.type) if (parsedArgsWithDefaults.package === "all") {
385
702
  const selections = await selectAllVersionsInteractive(config, rootDir);
386
703
  Object.assign(packageVersionSelections, selections);
387
704
  } else {
388
- const packageName = parsedArgs.package;
705
+ const packageName = parsedArgsWithDefaults.package;
389
706
  const currentVersion = versionManager.getPackageVersion(packageName);
390
707
  if (currentVersion) {
391
708
  const selection = await selectVersionInteractive(config, packageName, currentVersion);
@@ -393,24 +710,15 @@ async function main() {
393
710
  customVersion = selection.customVersion;
394
711
  }
395
712
  }
396
- if (parsedArgs.package === "all" && Object.keys(packageVersionSelections).length > 0) {
397
- if (parsedArgs.dryRun) {
398
- logger_default.info("🔍 Dry-run 模式 - 以下操作将被执行:\n");
399
- for (const [packageName, selection] of Object.entries(packageVersionSelections)) {
400
- const pkgPath = config.packagePaths[packageName];
401
- const pkg = versionManager.getPackageInfo(pkgPath);
402
- const newVersion = selection.customVersion || semver.inc(pkg.version, selection.type);
403
- const isDefaultPackage = packageName === "default" || pkgPath === "package.json";
404
- const tagPrefix = config.git?.tagPrefix || "v";
405
- const tagName = isDefaultPackage ? `${tagPrefix}${newVersion}` : `${pkg.name}@${newVersion}`;
406
- logger_default.info(` 📦 ${packageName}`);
407
- logger_default.info(` 当前版本: ${pkg.version}`);
408
- logger_default.info(` 新版本: ${newVersion}`);
409
- logger_default.info(` Tag: ${tagName}`);
410
- logger_default.info(` CHANGELOG: ${isDefaultPackage && config.git?.changelog !== false ? "是" : "跳过(子包或配置禁用)"}`);
411
- logger_default.info("");
412
- }
413
- logger_default.info("✅ 以上为预览,未执行任何实际操作");
713
+ if (parsedArgsWithDefaults.package === "all" && Object.keys(packageVersionSelections).length > 0) {
714
+ if (parsedArgsWithDefaults.dryRun) {
715
+ const preview = await versionManager.previewUpdate("all", "patch", {
716
+ packageVersionSelections,
717
+ autoCommit: parsedArgsWithDefaults.autoCommit,
718
+ push: parsedArgsWithDefaults.push,
719
+ npm: parsedArgsWithDefaults.npm
720
+ });
721
+ renderPreview(preview);
414
722
  process.exit(0);
415
723
  }
416
724
  const updatedPackagesInfo = [];
@@ -424,8 +732,8 @@ async function main() {
424
732
  updateProgress(current, total, packageName, "processing");
425
733
  try {
426
734
  const result = await versionManager.updateVersion(packageName, selection.type, {
427
- dryRun: parsedArgs.dryRun,
428
- verbose: parsedArgs.verbose,
735
+ dryRun: parsedArgsWithDefaults.dryRun,
736
+ verbose: parsedArgsWithDefaults.verbose,
429
737
  customVersion: selection.customVersion,
430
738
  autoCommit: false,
431
739
  push: false,
@@ -458,8 +766,8 @@ async function main() {
458
766
  });
459
767
  logger_default.info("\n💡 提示: 可以单独重试失败的包,或检查错误信息后重新运行");
460
768
  }
461
- if (!parsedArgs.dryRun && parsedArgs.autoCommit && updatedPackagesInfo.length > 0) await versionManager.gitCommitAndPush(parsedArgs.push, updatedPackagesInfo, config.git?.tag !== false, config.git?.tagPrefix || "v");
462
- if (parsedArgs.npm && !parsedArgs.dryRun) {
769
+ if (!parsedArgsWithDefaults.dryRun && parsedArgsWithDefaults.autoCommit && updatedPackagesInfo.length > 0) await versionManager.gitCommitAndPush(parsedArgsWithDefaults.push, updatedPackagesInfo, config.git?.tag !== false, config.git?.tagPrefix || "v");
770
+ if (parsedArgsWithDefaults.npm && !parsedArgsWithDefaults.dryRun) {
463
771
  const npmErrors = [];
464
772
  const npmPackages = Object.entries(packageVersionSelections);
465
773
  const npmTotal = npmPackages.length;
@@ -471,7 +779,7 @@ async function main() {
471
779
  try {
472
780
  await versionManager.updateVersion(packageName, selection.type, {
473
781
  dryRun: false,
474
- verbose: parsedArgs.verbose,
782
+ verbose: parsedArgsWithDefaults.verbose,
475
783
  customVersion: selection.customVersion,
476
784
  autoCommit: false,
477
785
  push: false,
@@ -499,35 +807,26 @@ async function main() {
499
807
  }
500
808
  }
501
809
  } else {
502
- if (parsedArgs.dryRun && parsedArgs.package) {
503
- const pkgPath = config.packagePaths[parsedArgs.package];
504
- const pkg = versionManager.getPackageInfo(pkgPath);
505
- const newVersion = customVersion || semver.inc(pkg.version, selectedType);
506
- const isDefaultPackage = parsedArgs.package === "default" || pkgPath === "package.json";
507
- const tagPrefix = config.git?.tagPrefix || "v";
508
- const tagName = isDefaultPackage ? `${tagPrefix}${newVersion}` : `${pkg.name}@${newVersion}`;
509
- logger_default.info("🔍 Dry-run 模式 - 以下操作将被执行:\n");
510
- logger_default.info(` 📦 ${parsedArgs.package}`);
511
- logger_default.info(` 当前版本: ${pkg.version}`);
512
- logger_default.info(` 新版本: ${newVersion}`);
513
- logger_default.info(` Tag: ${tagName}`);
514
- logger_default.info(` CHANGELOG: ${config.git?.changelog !== false ? "是" : "否(配置禁用)"}`);
515
- logger_default.info(` Git Commit: ${parsedArgs.autoCommit ? "是" : "否"}`);
516
- logger_default.info(` Git Push: ${parsedArgs.push ? "是" : "否"}`);
517
- logger_default.info(` NPM Publish: ${parsedArgs.npm ? "是" : "否"}`);
518
- logger_default.info("\n✅ 以上为预览,未执行任何实际操作");
810
+ if (parsedArgsWithDefaults.dryRun && parsedArgsWithDefaults.package) {
811
+ const preview = await versionManager.previewUpdate(parsedArgsWithDefaults.package, selectedType, {
812
+ customVersion,
813
+ autoCommit: parsedArgsWithDefaults.autoCommit,
814
+ push: parsedArgsWithDefaults.push,
815
+ npm: parsedArgsWithDefaults.npm
816
+ });
817
+ renderPreview(preview);
519
818
  process.exit(0);
520
819
  }
521
- await versionManager.updateVersion(parsedArgs.package, selectedType, {
522
- dryRun: parsedArgs.dryRun,
523
- verbose: parsedArgs.verbose,
820
+ await versionManager.updateVersion(parsedArgsWithDefaults.package, selectedType, {
821
+ dryRun: parsedArgsWithDefaults.dryRun,
822
+ verbose: parsedArgsWithDefaults.verbose,
524
823
  customVersion,
525
- autoCommit: parsedArgs.autoCommit,
526
- push: parsedArgs.push,
527
- npm: parsedArgs.npm
824
+ autoCommit: parsedArgsWithDefaults.autoCommit,
825
+ push: parsedArgsWithDefaults.push,
826
+ npm: parsedArgsWithDefaults.npm
528
827
  });
529
828
  }
530
- logger_default.success(`版本更新完成${parsedArgs.dryRun ? " (试运行模式)" : ""}`);
829
+ logger_default.success(`版本更新完成${parsedArgsWithDefaults.dryRun ? " (试运行模式)" : ""}`);
531
830
  process.exit(0);
532
831
  } catch (error) {
533
832
  displayError(error);