@huaiyou/hooks-git
Advanced tools
| #!/usr/bin/env node | ||
| 'use strict'; | ||
| const cac = require('cac'); | ||
| const execa = require('execa'); | ||
| function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } | ||
| const cac__default = /*#__PURE__*/_interopDefaultCompat(cac); | ||
| const errorMessages$1 = { | ||
| // 类型相关 | ||
| "type must be one of": "\u63D0\u4EA4\u7C7B\u578B\u5FC5\u987B\u662F\u4EE5\u4E0B\u4E4B\u4E00", | ||
| "type must not be empty": "\u63D0\u4EA4\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A", | ||
| "type must be lower case": "\u63D0\u4EA4\u7C7B\u578B\u5FC5\u987B\u662F\u5C0F\u5199", | ||
| // 主题相关 | ||
| "subject must not be empty": "\u63D0\u4EA4\u4E3B\u9898\u4E0D\u80FD\u4E3A\u7A7A", | ||
| "subject must not end with full stop": "\u63D0\u4EA4\u4E3B\u9898\u4E0D\u80FD\u4EE5\u53E5\u53F7\u7ED3\u5C3E", | ||
| "subject must be lower case": "\u63D0\u4EA4\u4E3B\u9898\u5FC5\u987B\u662F\u5C0F\u5199", | ||
| // 长度相关 | ||
| "header must not be longer than": "\u63D0\u4EA4\u5934\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7", | ||
| "body lines must not be longer than": "\u63D0\u4EA4\u6B63\u6587\u6BCF\u884C\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7", | ||
| "footer lines must not be longer than": "\u63D0\u4EA4\u811A\u6CE8\u6BCF\u884C\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7", | ||
| // 通用 | ||
| "must match the format": "\u5FC5\u987B\u5339\u914D\u683C\u5F0F", | ||
| "must be": "\u5FC5\u987B\u662F" | ||
| }; | ||
| function translateError$1(message) { | ||
| for (const [en, zh] of Object.entries(errorMessages$1)) { | ||
| if (message.includes(en)) { | ||
| return message.replace(en, zh); | ||
| } | ||
| } | ||
| return message; | ||
| } | ||
| async function runCommitlint(args) { | ||
| try { | ||
| await execa.execa("commitlint", args, { | ||
| stdio: "inherit", | ||
| reject: false | ||
| }); | ||
| } catch (error) { | ||
| if (error.stdout) { | ||
| const translated = translateError$1(error.stdout); | ||
| console.error(translated); | ||
| } | ||
| if (error.stderr) { | ||
| const translated = translateError$1(error.stderr); | ||
| console.error(translated); | ||
| } | ||
| if (error.message) { | ||
| const translated = translateError$1(error.message); | ||
| console.error(translated); | ||
| } | ||
| process.exit(1); | ||
| } | ||
| } | ||
| const errorMessages = { | ||
| // ���置相关 | ||
| "Failed to read config from file": "\u65E0\u6CD5\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6", | ||
| "could not find any valid configuration": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E", | ||
| "No valid configurations found": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E", | ||
| // 文件相关 | ||
| "Running tasks on": "\u6B63\u5728\u68C0\u67E5\u6587\u4EF6", | ||
| "Applying modifications from tasks": "\u5E94\u7528\u4EFB\u52A1\u4FEE\u6539", | ||
| "Restoring unstaged changes": "\u6062\u590D\u672A\u6682\u5B58\u7684\u66F4\u6539", | ||
| // 任务相关 | ||
| "Running tasks for staged files": "\u5BF9\u6682\u5B58\u6587\u4EF6\u8FD0\u884C\u4EFB\u52A1", | ||
| "No staged files found": "\u6CA1\u6709\u627E\u5230\u6682\u5B58\u7684\u6587\u4EF6", | ||
| "All files match patterns": "\u6240\u6709\u6587\u4EF6\u90FD\u5339\u914D\u5230\u6A21\u5F0F", | ||
| // 错误相关 | ||
| "Something went wrong": "\u51FA\u9519\u4E86", | ||
| "Command failed": "\u547D\u4EE4\u6267\u884C\u5931\u8D25", | ||
| "Task": "\u4EFB\u52A1", | ||
| "failed": "\u5931\u8D25", | ||
| "passed": "\u901A\u8FC7", | ||
| "skipped": "\u8DF3\u8FC7" | ||
| }; | ||
| function translateError(message) { | ||
| let translated = message; | ||
| for (const [en, zh] of Object.entries(errorMessages)) { | ||
| translated = translated.replace(new RegExp(en, "g"), zh); | ||
| } | ||
| return translated; | ||
| } | ||
| function translateLine(line) { | ||
| if (!line.trim() || /^[\s\─│┌┐└┘]+$/g.test(line)) { | ||
| return line; | ||
| } | ||
| return translateError(line); | ||
| } | ||
| async function runLintStaged() { | ||
| try { | ||
| const { stdout, stderr } = await execa.execa("lint-staged", [], { | ||
| stdio: "pipe" | ||
| }); | ||
| if (stdout) { | ||
| const lines = stdout.split("\n"); | ||
| lines.forEach((line) => { | ||
| console.log(translateLine(line)); | ||
| }); | ||
| } | ||
| if (stderr) { | ||
| const lines = stderr.split("\n"); | ||
| lines.forEach((line) => { | ||
| console.error(translateLine(line)); | ||
| }); | ||
| } | ||
| } catch (error) { | ||
| if (error.stdout) { | ||
| const lines = error.stdout.split("\n"); | ||
| lines.forEach((line) => { | ||
| console.log(translateLine(line)); | ||
| }); | ||
| } | ||
| if (error.stderr) { | ||
| const lines = error.stderr.split("\n"); | ||
| lines.forEach((line) => { | ||
| console.error(translateLine(line)); | ||
| }); | ||
| } | ||
| process.exit(1); | ||
| } | ||
| } | ||
| const cli = cac__default("hy-hooks-git-wrapper"); | ||
| cli.command("commitlint [...args]", "Run commitlint with Chinese error messages").action(async (args) => { | ||
| await runCommitlint(args); | ||
| }); | ||
| cli.command("lint-staged", "Run lint-staged with Chinese error messages").action(async () => { | ||
| await runLintStaged(); | ||
| }); | ||
| cli.help(); | ||
| cli.parse(); |
| #!/usr/bin/env node | ||
| import cac from 'cac'; | ||
| import { execa } from 'execa'; | ||
| const errorMessages$1 = { | ||
| // 类型相关 | ||
| "type must be one of": "\u63D0\u4EA4\u7C7B\u578B\u5FC5\u987B\u662F\u4EE5\u4E0B\u4E4B\u4E00", | ||
| "type must not be empty": "\u63D0\u4EA4\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A", | ||
| "type must be lower case": "\u63D0\u4EA4\u7C7B\u578B\u5FC5\u987B\u662F\u5C0F\u5199", | ||
| // 主题相关 | ||
| "subject must not be empty": "\u63D0\u4EA4\u4E3B\u9898\u4E0D\u80FD\u4E3A\u7A7A", | ||
| "subject must not end with full stop": "\u63D0\u4EA4\u4E3B\u9898\u4E0D\u80FD\u4EE5\u53E5\u53F7\u7ED3\u5C3E", | ||
| "subject must be lower case": "\u63D0\u4EA4\u4E3B\u9898\u5FC5\u987B\u662F\u5C0F\u5199", | ||
| // 长度相关 | ||
| "header must not be longer than": "\u63D0\u4EA4\u5934\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7", | ||
| "body lines must not be longer than": "\u63D0\u4EA4\u6B63\u6587\u6BCF\u884C\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7", | ||
| "footer lines must not be longer than": "\u63D0\u4EA4\u811A\u6CE8\u6BCF\u884C\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7", | ||
| // 通用 | ||
| "must match the format": "\u5FC5\u987B\u5339\u914D\u683C\u5F0F", | ||
| "must be": "\u5FC5\u987B\u662F" | ||
| }; | ||
| function translateError$1(message) { | ||
| for (const [en, zh] of Object.entries(errorMessages$1)) { | ||
| if (message.includes(en)) { | ||
| return message.replace(en, zh); | ||
| } | ||
| } | ||
| return message; | ||
| } | ||
| async function runCommitlint(args) { | ||
| try { | ||
| await execa("commitlint", args, { | ||
| stdio: "inherit", | ||
| reject: false | ||
| }); | ||
| } catch (error) { | ||
| if (error.stdout) { | ||
| const translated = translateError$1(error.stdout); | ||
| console.error(translated); | ||
| } | ||
| if (error.stderr) { | ||
| const translated = translateError$1(error.stderr); | ||
| console.error(translated); | ||
| } | ||
| if (error.message) { | ||
| const translated = translateError$1(error.message); | ||
| console.error(translated); | ||
| } | ||
| process.exit(1); | ||
| } | ||
| } | ||
| const errorMessages = { | ||
| // ���置相关 | ||
| "Failed to read config from file": "\u65E0\u6CD5\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6", | ||
| "could not find any valid configuration": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E", | ||
| "No valid configurations found": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E", | ||
| // 文件相关 | ||
| "Running tasks on": "\u6B63\u5728\u68C0\u67E5\u6587\u4EF6", | ||
| "Applying modifications from tasks": "\u5E94\u7528\u4EFB\u52A1\u4FEE\u6539", | ||
| "Restoring unstaged changes": "\u6062\u590D\u672A\u6682\u5B58\u7684\u66F4\u6539", | ||
| // 任务相关 | ||
| "Running tasks for staged files": "\u5BF9\u6682\u5B58\u6587\u4EF6\u8FD0\u884C\u4EFB\u52A1", | ||
| "No staged files found": "\u6CA1\u6709\u627E\u5230\u6682\u5B58\u7684\u6587\u4EF6", | ||
| "All files match patterns": "\u6240\u6709\u6587\u4EF6\u90FD\u5339\u914D\u5230\u6A21\u5F0F", | ||
| // 错误相关 | ||
| "Something went wrong": "\u51FA\u9519\u4E86", | ||
| "Command failed": "\u547D\u4EE4\u6267\u884C\u5931\u8D25", | ||
| "Task": "\u4EFB\u52A1", | ||
| "failed": "\u5931\u8D25", | ||
| "passed": "\u901A\u8FC7", | ||
| "skipped": "\u8DF3\u8FC7" | ||
| }; | ||
| function translateError(message) { | ||
| let translated = message; | ||
| for (const [en, zh] of Object.entries(errorMessages)) { | ||
| translated = translated.replace(new RegExp(en, "g"), zh); | ||
| } | ||
| return translated; | ||
| } | ||
| function translateLine(line) { | ||
| if (!line.trim() || /^[\s\─│┌┐└┘]+$/g.test(line)) { | ||
| return line; | ||
| } | ||
| return translateError(line); | ||
| } | ||
| async function runLintStaged() { | ||
| try { | ||
| const { stdout, stderr } = await execa("lint-staged", [], { | ||
| stdio: "pipe" | ||
| }); | ||
| if (stdout) { | ||
| const lines = stdout.split("\n"); | ||
| lines.forEach((line) => { | ||
| console.log(translateLine(line)); | ||
| }); | ||
| } | ||
| if (stderr) { | ||
| const lines = stderr.split("\n"); | ||
| lines.forEach((line) => { | ||
| console.error(translateLine(line)); | ||
| }); | ||
| } | ||
| } catch (error) { | ||
| if (error.stdout) { | ||
| const lines = error.stdout.split("\n"); | ||
| lines.forEach((line) => { | ||
| console.log(translateLine(line)); | ||
| }); | ||
| } | ||
| if (error.stderr) { | ||
| const lines = error.stderr.split("\n"); | ||
| lines.forEach((line) => { | ||
| console.error(translateLine(line)); | ||
| }); | ||
| } | ||
| process.exit(1); | ||
| } | ||
| } | ||
| const cli = cac("hy-hooks-git-wrapper"); | ||
| cli.command("commitlint [...args]", "Run commitlint with Chinese error messages").action(async (args) => { | ||
| await runCommitlint(args); | ||
| }); | ||
| cli.command("lint-staged", "Run lint-staged with Chinese error messages").action(async () => { | ||
| await runLintStaged(); | ||
| }); | ||
| cli.help(); | ||
| cli.parse(); |
+8
-0
| # @huaiyou/hooks-git | ||
| ## 2.2.0 | ||
| ### Minor Changes | ||
| - Add Chinese error message wrappers for commitlint and lint-staged | ||
| - Detect complex tsconfig and use .cjs config files (no ts-node needed) | ||
| - Add wrapper CLI to translate error messages to Chinese | ||
| ## 2.1.2 | ||
@@ -4,0 +12,0 @@ |
+28
-14
@@ -17,3 +17,3 @@ #!/usr/bin/env node | ||
| const version = "2.1.2"; | ||
| const version = "2.2.0"; | ||
@@ -115,7 +115,7 @@ const logger = { | ||
| const commitMsgPath = node_path.resolve(huskyDir, "commit-msg"); | ||
| const commitMsgContent = `npx --no -- commitlint --edit \${1} | ||
| const commitMsgContent = `npx --no -- @huaiyou/hooks-git/wrappers commitlint --edit \${1} | ||
| `; | ||
| await fs__default.outputFile(commitMsgPath, commitMsgContent, { mode: 493 }); | ||
| const preCommitPath = node_path.resolve(huskyDir, "pre-commit"); | ||
| const preCommitContent = `npx lint-staged | ||
| const preCommitContent = `npx --no -- @huaiyou/hooks-git/wrappers lint-staged | ||
| `; | ||
@@ -126,9 +126,27 @@ await fs__default.outputFile(preCommitPath, preCommitContent, { mode: 493 }); | ||
| const isTsProject = fs__default.existsSync(node_path.resolve(process.cwd(), "tsconfig.json")); | ||
| const commitlintFile = isTsProject ? "commitlint.config.ts" : isModule ? "commitlint.config.cjs" : "commitlint.config.js"; | ||
| const isComplexTsConfig2 = isTsProject && isComplexTsConfig2(); | ||
| let commitlintFile; | ||
| let lintStagedFile; | ||
| if (isComplexTsConfig2) { | ||
| commitlintFile = "commitlint.config.cjs"; | ||
| lintStagedFile = "lint-staged.config.cjs"; | ||
| } else if (isTsProject) { | ||
| commitlintFile = "commitlint.config.ts"; | ||
| lintStagedFile = "lint-staged.config.ts"; | ||
| } else if (isModule) { | ||
| commitlintFile = "commitlint.config.cjs"; | ||
| lintStagedFile = "lint-staged.config.cjs"; | ||
| } else { | ||
| commitlintFile = "commitlint.config.js"; | ||
| lintStagedFile = "lint-staged.config.js"; | ||
| } | ||
| if (!fs__default.existsSync(node_path.resolve(process.cwd(), commitlintFile))) { | ||
| let content = ""; | ||
| if (isTsProject) { | ||
| if (commitlintFile.endsWith(".ts")) { | ||
| content = `import { commitlintConfig } from '@huaiyou/hooks-git'; | ||
| export default commitlintConfig; | ||
| `; | ||
| } else if (commitlintFile.endsWith(".cjs")) { | ||
| content = `module.exports = require('@huaiyou/hooks-git/commitlint'); | ||
| `; | ||
| } else { | ||
@@ -143,9 +161,12 @@ content = `module.exports = require('@huaiyou/hooks-git/commitlint'); | ||
| } | ||
| const lintStagedFile = isTsProject ? "lint-staged.config.ts" : isModule ? "lint-staged.config.cjs" : "lint-staged.config.js"; | ||
| if (!fs__default.existsSync(node_path.resolve(process.cwd(), lintStagedFile))) { | ||
| let content = ""; | ||
| if (isTsProject) { | ||
| if (lintStagedFile.endsWith(".ts")) { | ||
| content = `import { createLintStagedConfig } from '@huaiyou/hooks-git'; | ||
| export default createLintStagedConfig(); | ||
| `; | ||
| } else if (lintStagedFile.endsWith(".cjs")) { | ||
| content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged'); | ||
| module.exports = createLintStagedConfig(); | ||
| `; | ||
| } else { | ||
@@ -161,9 +182,2 @@ content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged'); | ||
| } | ||
| if (isTsProject) { | ||
| const hasTsNode = pkg.devDependencies && pkg.devDependencies["ts-node"] || pkg.dependencies && pkg.dependencies["ts-node"]; | ||
| if (!hasTsNode) { | ||
| logger.info("Detected TypeScript project. Installing ts-node..."); | ||
| await runCommand("pnpm", ["add", "-D", "ts-node"]); | ||
| } | ||
| } | ||
| logger.info("Updating package.json scripts..."); | ||
@@ -170,0 +184,0 @@ await updatePackageJson((pkg2) => { |
+28
-14
@@ -9,3 +9,3 @@ #!/usr/bin/env node | ||
| const version = "2.1.2"; | ||
| const version = "2.2.0"; | ||
@@ -107,7 +107,7 @@ const logger = { | ||
| const commitMsgPath = resolve(huskyDir, "commit-msg"); | ||
| const commitMsgContent = `npx --no -- commitlint --edit \${1} | ||
| const commitMsgContent = `npx --no -- @huaiyou/hooks-git/wrappers commitlint --edit \${1} | ||
| `; | ||
| await fs.outputFile(commitMsgPath, commitMsgContent, { mode: 493 }); | ||
| const preCommitPath = resolve(huskyDir, "pre-commit"); | ||
| const preCommitContent = `npx lint-staged | ||
| const preCommitContent = `npx --no -- @huaiyou/hooks-git/wrappers lint-staged | ||
| `; | ||
@@ -118,9 +118,27 @@ await fs.outputFile(preCommitPath, preCommitContent, { mode: 493 }); | ||
| const isTsProject = fs.existsSync(resolve(process.cwd(), "tsconfig.json")); | ||
| const commitlintFile = isTsProject ? "commitlint.config.ts" : isModule ? "commitlint.config.cjs" : "commitlint.config.js"; | ||
| const isComplexTsConfig2 = isTsProject && isComplexTsConfig2(); | ||
| let commitlintFile; | ||
| let lintStagedFile; | ||
| if (isComplexTsConfig2) { | ||
| commitlintFile = "commitlint.config.cjs"; | ||
| lintStagedFile = "lint-staged.config.cjs"; | ||
| } else if (isTsProject) { | ||
| commitlintFile = "commitlint.config.ts"; | ||
| lintStagedFile = "lint-staged.config.ts"; | ||
| } else if (isModule) { | ||
| commitlintFile = "commitlint.config.cjs"; | ||
| lintStagedFile = "lint-staged.config.cjs"; | ||
| } else { | ||
| commitlintFile = "commitlint.config.js"; | ||
| lintStagedFile = "lint-staged.config.js"; | ||
| } | ||
| if (!fs.existsSync(resolve(process.cwd(), commitlintFile))) { | ||
| let content = ""; | ||
| if (isTsProject) { | ||
| if (commitlintFile.endsWith(".ts")) { | ||
| content = `import { commitlintConfig } from '@huaiyou/hooks-git'; | ||
| export default commitlintConfig; | ||
| `; | ||
| } else if (commitlintFile.endsWith(".cjs")) { | ||
| content = `module.exports = require('@huaiyou/hooks-git/commitlint'); | ||
| `; | ||
| } else { | ||
@@ -135,9 +153,12 @@ content = `module.exports = require('@huaiyou/hooks-git/commitlint'); | ||
| } | ||
| const lintStagedFile = isTsProject ? "lint-staged.config.ts" : isModule ? "lint-staged.config.cjs" : "lint-staged.config.js"; | ||
| if (!fs.existsSync(resolve(process.cwd(), lintStagedFile))) { | ||
| let content = ""; | ||
| if (isTsProject) { | ||
| if (lintStagedFile.endsWith(".ts")) { | ||
| content = `import { createLintStagedConfig } from '@huaiyou/hooks-git'; | ||
| export default createLintStagedConfig(); | ||
| `; | ||
| } else if (lintStagedFile.endsWith(".cjs")) { | ||
| content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged'); | ||
| module.exports = createLintStagedConfig(); | ||
| `; | ||
| } else { | ||
@@ -153,9 +174,2 @@ content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged'); | ||
| } | ||
| if (isTsProject) { | ||
| const hasTsNode = pkg.devDependencies && pkg.devDependencies["ts-node"] || pkg.dependencies && pkg.dependencies["ts-node"]; | ||
| if (!hasTsNode) { | ||
| logger.info("Detected TypeScript project. Installing ts-node..."); | ||
| await runCommand("pnpm", ["add", "-D", "ts-node"]); | ||
| } | ||
| } | ||
| logger.info("Updating package.json scripts..."); | ||
@@ -162,0 +176,0 @@ await updatePackageJson((pkg2) => { |
+8
-2
| { | ||
| "name": "@huaiyou/hooks-git", | ||
| "version": "2.1.2", | ||
| "version": "2.2.0", | ||
| "description": "Git hooks configuration with Husky, Commitlint and Lint-staged", | ||
| "bin": { | ||
| "hy-hooks-git": "./dist/cli.mjs" | ||
| "hy-hooks-git": "./dist/cli.mjs", | ||
| "hy-hooks-commitlint": "./dist/wrappers/cli.mjs", | ||
| "hy-hooks-lint-staged": "./dist/wrappers/cli.mjs" | ||
| }, | ||
@@ -32,2 +34,6 @@ "files": [ | ||
| "types": "./dist/lint-staged.d.ts" | ||
| }, | ||
| "./wrappers": { | ||
| "require": "./dist/wrappers/cli.cjs", | ||
| "import": "./dist/wrappers/cli.mjs" | ||
| } | ||
@@ -34,0 +40,0 @@ }, |
51791
25.36%28
21.74%1233
29.79%