zixulu 1.79.0 → 1.79.2

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/dist/index.js CHANGED
@@ -1727,8 +1727,90 @@ main()
1727
1727
  });
1728
1728
  return getCommitMessage("feature", "添加同步包脚本");
1729
1729
  }
1730
+ const regexPlaceholders = [
1731
+ {
1732
+ token: "__SPACE__",
1733
+ value: " "
1734
+ },
1735
+ {
1736
+ token: "__CARET__",
1737
+ value: "^"
1738
+ },
1739
+ {
1740
+ token: "__DOLLAR__",
1741
+ value: "$"
1742
+ },
1743
+ {
1744
+ token: "__PIPE__",
1745
+ value: "|"
1746
+ },
1747
+ {
1748
+ token: "__AMPERSAND__",
1749
+ value: "&"
1750
+ },
1751
+ {
1752
+ token: "__SEMICOLON__",
1753
+ value: ";"
1754
+ },
1755
+ {
1756
+ token: "__LPAREN__",
1757
+ value: "("
1758
+ },
1759
+ {
1760
+ token: "__RPAREN__",
1761
+ value: ")"
1762
+ },
1763
+ {
1764
+ token: "__LBRACE__",
1765
+ value: "{"
1766
+ },
1767
+ {
1768
+ token: "__RBRACE__",
1769
+ value: "}"
1770
+ },
1771
+ {
1772
+ token: "__LBRACKET__",
1773
+ value: "["
1774
+ },
1775
+ {
1776
+ token: "__RBRACKET__",
1777
+ value: "]"
1778
+ },
1779
+ {
1780
+ token: "__SQUOTE__",
1781
+ value: "'"
1782
+ },
1783
+ {
1784
+ token: "__DQUOTE__",
1785
+ value: '"'
1786
+ },
1787
+ {
1788
+ token: "__BACKTICK__",
1789
+ value: "`"
1790
+ },
1791
+ {
1792
+ token: "__AT__",
1793
+ value: "@"
1794
+ },
1795
+ {
1796
+ token: "__LT__",
1797
+ value: "<"
1798
+ },
1799
+ {
1800
+ token: "__GT__",
1801
+ value: ">"
1802
+ },
1803
+ {
1804
+ token: "__BACKSLASH__",
1805
+ value: "\\"
1806
+ }
1807
+ ];
1808
+ const regexPlaceholderHint = "特殊字符请使用 __XXX__ 占位符,例如 __CARET__、__DOLLAR__、__PIPE__、__LPAREN__、__RPAREN__、__AMPERSAND__、__SPACE__";
1809
+ function preprocessPlaceholderText(text) {
1810
+ return regexPlaceholders.reduce((result, placeholder)=>result.split(placeholder.token).join(placeholder.value), text);
1811
+ }
1730
1812
  function preprocessRegex(reg) {
1731
- return reg.replace(/\{\{CARET\}\}/g, "^");
1813
+ return preprocessPlaceholderText(reg);
1732
1814
  }
1733
1815
  async function addTag({ reg, flags, replacement, push, remote = "origin", force }) {
1734
1816
  const git = simpleGit();
@@ -1737,8 +1819,9 @@ async function addTag({ reg, flags, replacement, push, remote = "origin", force
1737
1819
  const status = await git.status();
1738
1820
  if (status.files.length > 0) return void external_consola_consola.error("当前 Git 仓库存在未提交的文件,请先提交或暂存这些文件");
1739
1821
  const processedReg = preprocessRegex(reg);
1822
+ const processedReplacement = preprocessPlaceholderText(replacement);
1740
1823
  external_consola_consola.info(`正则表达式: /${processedReg}/${flags ?? ""}`);
1741
- external_consola_consola.info(`替换字符串: ${replacement}`);
1824
+ external_consola_consola.info(`替换字符串: ${processedReplacement}`);
1742
1825
  const cont = await shouldContinue("是否继续?");
1743
1826
  if (!cont) return void external_consola_consola.info("操作已取消");
1744
1827
  const log = await git.log();
@@ -1751,7 +1834,7 @@ async function addTag({ reg, flags, replacement, push, remote = "origin", force
1751
1834
  for (const commit of commits){
1752
1835
  const regexp = new RegExp(processedReg, flags);
1753
1836
  if (regexp.test(commit.message)) {
1754
- const tagName = commit.message.replace(new RegExp(processedReg, flags), replacement);
1837
+ const tagName = commit.message.replace(new RegExp(processedReg, flags), processedReplacement);
1755
1838
  if (tagName && tagName.trim()) tagsToAdd.push({
1756
1839
  hash: commit.hash,
1757
1840
  message: commit.message,
@@ -3623,10 +3706,11 @@ async function replaceCommitMessage({ reg, replace, flags, push, remote = "origi
3623
3706
  "HEAD"
3624
3707
  ]);
3625
3708
  const processedReg = preprocessRegex(reg);
3709
+ const processedReplace = preprocessPlaceholderText(replace);
3626
3710
  external_consola_consola.warn("⚠️ 警告:此操作将重写 Git 历史,建议先备份");
3627
3711
  external_consola_consola.info(`目标分支: ${currentBranch}`);
3628
3712
  external_consola_consola.info(`正则表达式: /${processedReg}/${flags ?? ""}`);
3629
- external_consola_consola.info(`替换字符串: ${replace}`);
3713
+ external_consola_consola.info(`替换字符串: ${processedReplace}`);
3630
3714
  const cont = await shouldContinue("⚠️ 是否继续?此操作将重写 Git 历史");
3631
3715
  if (!cont) return void external_consola_consola.info("操作已取消");
3632
3716
  const logResult = await git.log([
@@ -3637,7 +3721,7 @@ async function replaceCommitMessage({ reg, replace, flags, push, remote = "origi
3637
3721
  const tempScriptPath = join(tmpdir(), `git-msg-filter-${Date.now()}.js`);
3638
3722
  const scriptContent = `
3639
3723
  const reg = ${JSON.stringify(processedReg)}
3640
- const replace = ${JSON.stringify(replace)}
3724
+ const replace = ${JSON.stringify(processedReplace)}
3641
3725
  const flags = ${JSON.stringify(flags ?? "")}
3642
3726
 
3643
3727
  let input = ""
@@ -3698,8 +3782,9 @@ async function replaceTag({ reg, replace, flags, push, remote = "origin" }) {
3698
3782
  const status = await git.status();
3699
3783
  if (status.files.length > 0) return void external_consola_consola.error("当前 Git 仓库存在未提交的文件,请先提交或暂存这些文件");
3700
3784
  const processedReg = preprocessRegex(reg);
3785
+ const processedReplace = preprocessPlaceholderText(replace);
3701
3786
  external_consola_consola.info(`正则表达式: /${processedReg}/${flags ?? ""}`);
3702
- external_consola_consola.info(`替换字符串: ${replace}`);
3787
+ external_consola_consola.info(`替换字符串: ${processedReplace}`);
3703
3788
  const cont = await shouldContinue("是否继续?");
3704
3789
  if (!cont) return void external_consola_consola.info("操作已取消");
3705
3790
  const tags = await git.tags();
@@ -3709,7 +3794,7 @@ async function replaceTag({ reg, replace, flags, push, remote = "origin" }) {
3709
3794
  const operations = [];
3710
3795
  for (const tag of allTags){
3711
3796
  const regexp = new RegExp(processedReg, flags);
3712
- const newTag = tag.replace(regexp, replace);
3797
+ const newTag = tag.replace(regexp, processedReplace);
3713
3798
  if (newTag !== tag) operations.push({
3714
3799
  oldTag: tag,
3715
3800
  newTag
@@ -5656,14 +5741,23 @@ async function syncTemplateProjects({ templateProjects }) {
5656
5741
  consola.info("没有可同步的模板项目");
5657
5742
  return templateProjects;
5658
5743
  }
5744
+ const selectedTemplateProjects = await selectSyncTemplateProjects({
5745
+ templateProjects
5746
+ });
5747
+ if (0 === selectedTemplateProjects.length) {
5748
+ consola.info("未选择任何项目");
5749
+ return templateProjects;
5750
+ }
5659
5751
  const templateProjectSet = new Set(templateProjects);
5660
- for (const [index, projectPath] of templateProjects.entries()){
5752
+ const failedProjectPathSet = new Set();
5753
+ for (const [index, projectPath] of selectedTemplateProjects.entries()){
5661
5754
  const { isAvailable, reason } = await checkSyncProjectAvailable({
5662
5755
  projectPath
5663
5756
  });
5664
5757
  if (!isAvailable) {
5665
5758
  const invalidReason = reason ?? "目录不可用";
5666
- consola.warn(`[${index + 1}/${templateProjects.length}] 跳过 ${projectPath},原因:${invalidReason}`);
5759
+ failedProjectPathSet.add(projectPath);
5760
+ consola.warn(`[${index + 1}/${selectedTemplateProjects.length}] 跳过 ${projectPath},原因:${invalidReason}`);
5667
5761
  const shouldDelete = await confirmDeleteInvalidTemplateProject({
5668
5762
  projectPath,
5669
5763
  reason: invalidReason
@@ -5674,15 +5768,32 @@ async function syncTemplateProjects({ templateProjects }) {
5674
5768
  }
5675
5769
  continue;
5676
5770
  }
5677
- await syncTemplateProject({
5771
+ const isSuccess = await syncTemplateProject({
5678
5772
  projectPath,
5679
5773
  index: index + 1,
5680
- total: templateProjects.length
5774
+ total: selectedTemplateProjects.length
5681
5775
  });
5776
+ if (!isSuccess) failedProjectPathSet.add(projectPath);
5682
5777
  }
5683
5778
  consola.success("模板项目同步完成");
5779
+ printFailedSyncTemplateProjects({
5780
+ failedProjectPaths: Array.from(failedProjectPathSet)
5781
+ });
5684
5782
  return Array.from(templateProjectSet);
5685
5783
  }
5784
+ async function selectSyncTemplateProjects({ templateProjects }) {
5785
+ const { projectPaths } = await inquirer_0.prompt({
5786
+ type: "checkbox",
5787
+ name: "projectPaths",
5788
+ message: "请选择要同步的项目",
5789
+ choices: templateProjects.map((projectPath)=>({
5790
+ name: projectPath,
5791
+ value: projectPath
5792
+ })),
5793
+ default: templateProjects
5794
+ });
5795
+ return projectPaths;
5796
+ }
5686
5797
  async function checkSyncProjectAvailable({ projectPath }) {
5687
5798
  if (!await isDirectory(projectPath)) return {
5688
5799
  isAvailable: false,
@@ -5733,6 +5844,13 @@ async function hasTemplateRemote({ cwd }) {
5733
5844
  return false;
5734
5845
  }
5735
5846
  }
5847
+ function printFailedSyncTemplateProjects({ failedProjectPaths }) {
5848
+ if (0 === failedProjectPaths.length) return;
5849
+ consola.warn("以下目录同步失败");
5850
+ failedProjectPaths.forEach((projectPath, index)=>{
5851
+ consola.log(`${index + 1}. ${projectPath}`);
5852
+ });
5853
+ }
5736
5854
  async function syncTemplateProject({ projectPath, index, total }) {
5737
5855
  consola.start(`[${index}/${total}] 开始同步 ${projectPath}`);
5738
5856
  try {
@@ -5770,12 +5888,14 @@ async function syncTemplateProject({ projectPath, index, total }) {
5770
5888
  command: "git push"
5771
5889
  });
5772
5890
  consola.success(`[${index}/${total}] 同步成功 ${projectPath}`);
5891
+ return true;
5773
5892
  } catch (error) {
5774
5893
  const errorMessage = getGitCommandErrorMessage({
5775
5894
  error
5776
5895
  });
5777
5896
  consola.error(`[${index}/${total}] 同步失败 ${projectPath}`);
5778
5897
  consola.error(errorMessage);
5898
+ return false;
5779
5899
  }
5780
5900
  }
5781
5901
  async function ensureGitRepository(cwd) {
@@ -6053,7 +6173,7 @@ program.command("sync-cursor-ext-to-code").alias("sce2c").description("同步 cu
6053
6173
  program.command("create-prisma-debugger").alias("cpd").description("创建 prisma 调试器").action(createPrismaDebugger);
6054
6174
  program.command("verdaccio").description("同步 verdaccio 配置").action(verdaccio);
6055
6175
  program.command("sync-agent-rules").alias("sar").description("同步 Agent 规则").action(actionWithBackup(asyncAgentRules));
6056
- program.command("replace-tag").alias("rt").description("替换所有 git tag (正则中可用 {{CARET}} 代替 ^)").argument("regexp", "正则表达式字符串").argument("[replace]", "替换字符串,默认为空字符串").option("-f, --flags <flags>", "正则表达式标志,如 i、g、m 等").option("-p, --push", "是否推送到远程仓库").option("-r, --remote <remote>", "远程仓库名称,默认为 origin").action(async (regexp, replace, options)=>{
6176
+ program.command("replace-tag").alias("rt").description(`替换所有 git tag (${regexPlaceholderHint})`).argument("regexp", "正则表达式字符串").argument("[replace]", "替换字符串,默认为空字符串").option("-f, --flags <flags>", "正则表达式标志,如 i、g、m 等").option("-p, --push", "是否推送到远程仓库").option("-r, --remote <remote>", "远程仓库名称,默认为 origin").action(async (regexp, replace, options)=>{
6057
6177
  await replaceTag({
6058
6178
  reg: regexp,
6059
6179
  replace: replace ?? "",
@@ -6062,7 +6182,7 @@ program.command("replace-tag").alias("rt").description("替换所有 git tag (
6062
6182
  remote: options.remote
6063
6183
  });
6064
6184
  });
6065
- program.command("remove-tag").alias("rmt").description("删除匹配的 git tag (正则中可用 {{CARET}} 代替 ^)").argument("regexp", "正则表达式字符串").option("-f, --flags <flags>", "正则表达式标志,如 i、g、m 等").option("-p, --push", "是否同时删除远程仓库的 tag").option("-r, --remote <remote>", "远程仓库名称,默认为 origin").action(async (regexp, options)=>{
6185
+ program.command("remove-tag").alias("rmt").description(`删除匹配的 git tag (${regexPlaceholderHint})`).argument("regexp", "正则表达式字符串").option("-f, --flags <flags>", "正则表达式标志,如 i、g、m 等").option("-p, --push", "是否同时删除远程仓库的 tag").option("-r, --remote <remote>", "远程仓库名称,默认为 origin").action(async (regexp, options)=>{
6066
6186
  await removeTag({
6067
6187
  reg: regexp,
6068
6188
  flags: options.flags,
@@ -6070,7 +6190,7 @@ program.command("remove-tag").alias("rmt").description("删除匹配的 git tag
6070
6190
  remote: options.remote
6071
6191
  });
6072
6192
  });
6073
- program.command("add-tag").alias("adt").description("为匹配的 commit 添加 git tag (正则中可用 {{CARET}} 代替 ^)").argument("regexp", "用于匹配 commit message 的正则表达式字符串").argument("replacement", "用于生成 tag 名称的替换字符串").option("-f, --flags <flags>", "正则表达式标志,如 i、g、m 等").option("-p, --push", "是否推送到远程仓库").option("-r, --remote <remote>", "远程仓库名称,默认为 origin").option("--force", "是否覆盖已存在的 tag").action(async (regexp, replacement, options)=>{
6193
+ program.command("add-tag").alias("adt").description(`为匹配的 commit 添加 git tag (${regexPlaceholderHint})`).argument("regexp", "用于匹配 commit message 的正则表达式字符串").argument("replacement", "用于生成 tag 名称的替换字符串").option("-f, --flags <flags>", "正则表达式标志,如 i、g、m 等").option("-p, --push", "是否推送到远程仓库").option("-r, --remote <remote>", "远程仓库名称,默认为 origin").option("--force", "是否覆盖已存在的 tag").action(async (regexp, replacement, options)=>{
6074
6194
  await addTag({
6075
6195
  reg: regexp,
6076
6196
  replacement,
@@ -6080,7 +6200,7 @@ program.command("add-tag").alias("adt").description("为匹配的 commit 添加
6080
6200
  force: options.force
6081
6201
  });
6082
6202
  });
6083
- program.command("replace-commit-message").alias("rcm").description("替换所有提交消息(⚠️ 会重写 Git 历史,正则中可用 {{CARET}} 代替 ^)").argument("regexp", "正则表达式字符串").argument("[replace]", "替换字符串,默认为空字符串").option("-f, --flags <flags>", "正则表达式标志,如 g、i 等(注意:sed 语法)").option("-p, --push", "是否强制推送到远程仓库").option("-r, --remote <remote>", "远程仓库名称,默认为 origin").option("-b, --branch <branch>", "分支名称,默认为当前分支").action(async (regexp, replace, options)=>{
6203
+ program.command("replace-commit-message").alias("rcm").description(`替换所有提交消息(⚠️ 会重写 Git 历史,${regexPlaceholderHint})`).argument("regexp", "正则表达式字符串").argument("[replace]", "替换字符串,默认为空字符串").option("-f, --flags <flags>", "正则表达式标志,如 g、i 等(注意:sed 语法)").option("-p, --push", "是否强制推送到远程仓库").option("-r, --remote <remote>", "远程仓库名称,默认为 origin").option("-b, --branch <branch>", "分支名称,默认为当前分支").action(async (regexp, replace, options)=>{
6084
6204
  await replaceCommitMessage({
6085
6205
  reg: regexp,
6086
6206
  replace: replace ?? "",