@huaiyou/hooks-git 2.1.1 → 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.
- package/CHANGELOG.md +14 -0
- package/dist/cli.cjs +30 -16
- package/dist/cli.mjs +30 -16
- package/dist/wrappers/cli.cjs +135 -0
- package/dist/wrappers/cli.d.cts +1 -0
- package/dist/wrappers/cli.d.mts +1 -0
- package/dist/wrappers/cli.d.ts +1 -0
- package/dist/wrappers/cli.mjs +129 -0
- package/package.json +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @huaiyou/hooks-git
|
|
2
2
|
|
|
3
|
+
## 2.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add Chinese error message wrappers for commitlint and lint-staged
|
|
8
|
+
- Detect complex tsconfig and use .cjs config files (no ts-node needed)
|
|
9
|
+
- Add wrapper CLI to translate error messages to Chinese
|
|
10
|
+
|
|
11
|
+
## 2.1.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Fix init command - move package.json reading before dependency check
|
|
16
|
+
|
|
3
17
|
## 2.1.1
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/cli.cjs
CHANGED
|
@@ -14,7 +14,7 @@ const cac__default = /*#__PURE__*/_interopDefaultCompat(cac);
|
|
|
14
14
|
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
15
15
|
const picocolors__default = /*#__PURE__*/_interopDefaultCompat(picocolors);
|
|
16
16
|
|
|
17
|
-
const version = "2.
|
|
17
|
+
const version = "2.2.0";
|
|
18
18
|
|
|
19
19
|
const logger = {
|
|
20
20
|
/**
|
|
@@ -84,6 +84,8 @@ const init = async () => {
|
|
|
84
84
|
}
|
|
85
85
|
logger.info("Installing dependencies...");
|
|
86
86
|
const pm = await getPackageManager();
|
|
87
|
+
const pkgPath = node_path.resolve(process.cwd(), "package.json");
|
|
88
|
+
const pkg = await fs__default.readJson(pkgPath);
|
|
87
89
|
const devDepsNeeded = [];
|
|
88
90
|
if (!pkg.devDependencies?.husky && !pkg.dependencies?.husky) {
|
|
89
91
|
devDepsNeeded.push("husky");
|
|
@@ -109,24 +111,40 @@ const init = async () => {
|
|
|
109
111
|
logger.info("Adding hooks...");
|
|
110
112
|
const huskyDir = node_path.resolve(process.cwd(), ".husky");
|
|
111
113
|
const commitMsgPath = node_path.resolve(huskyDir, "commit-msg");
|
|
112
|
-
const commitMsgContent = `npx --no -- commitlint --edit \${1}
|
|
114
|
+
const commitMsgContent = `npx --no -- @huaiyou/hooks-git/wrappers commitlint --edit \${1}
|
|
113
115
|
`;
|
|
114
116
|
await fs__default.outputFile(commitMsgPath, commitMsgContent, { mode: 493 });
|
|
115
117
|
const preCommitPath = node_path.resolve(huskyDir, "pre-commit");
|
|
116
|
-
const preCommitContent = `npx lint-staged
|
|
118
|
+
const preCommitContent = `npx --no -- @huaiyou/hooks-git/wrappers lint-staged
|
|
117
119
|
`;
|
|
118
120
|
await fs__default.outputFile(preCommitPath, preCommitContent, { mode: 493 });
|
|
119
121
|
logger.info("Creating configuration files...");
|
|
120
|
-
const pkgPath = node_path.resolve(process.cwd(), "package.json");
|
|
121
|
-
const pkg = await fs__default.readJson(pkgPath);
|
|
122
122
|
const isModule = pkg.type === "module";
|
|
123
123
|
const isTsProject = fs__default.existsSync(node_path.resolve(process.cwd(), "tsconfig.json"));
|
|
124
|
-
const
|
|
124
|
+
const isComplexTsConfig2 = isTsProject && isComplexTsConfig2();
|
|
125
|
+
let commitlintFile;
|
|
126
|
+
let lintStagedFile;
|
|
127
|
+
if (isComplexTsConfig2) {
|
|
128
|
+
commitlintFile = "commitlint.config.cjs";
|
|
129
|
+
lintStagedFile = "lint-staged.config.cjs";
|
|
130
|
+
} else if (isTsProject) {
|
|
131
|
+
commitlintFile = "commitlint.config.ts";
|
|
132
|
+
lintStagedFile = "lint-staged.config.ts";
|
|
133
|
+
} else if (isModule) {
|
|
134
|
+
commitlintFile = "commitlint.config.cjs";
|
|
135
|
+
lintStagedFile = "lint-staged.config.cjs";
|
|
136
|
+
} else {
|
|
137
|
+
commitlintFile = "commitlint.config.js";
|
|
138
|
+
lintStagedFile = "lint-staged.config.js";
|
|
139
|
+
}
|
|
125
140
|
if (!fs__default.existsSync(node_path.resolve(process.cwd(), commitlintFile))) {
|
|
126
141
|
let content = "";
|
|
127
|
-
if (
|
|
142
|
+
if (commitlintFile.endsWith(".ts")) {
|
|
128
143
|
content = `import { commitlintConfig } from '@huaiyou/hooks-git';
|
|
129
144
|
export default commitlintConfig;
|
|
145
|
+
`;
|
|
146
|
+
} else if (commitlintFile.endsWith(".cjs")) {
|
|
147
|
+
content = `module.exports = require('@huaiyou/hooks-git/commitlint');
|
|
130
148
|
`;
|
|
131
149
|
} else {
|
|
132
150
|
content = `module.exports = require('@huaiyou/hooks-git/commitlint');
|
|
@@ -137,12 +155,15 @@ export default commitlintConfig;
|
|
|
137
155
|
} else {
|
|
138
156
|
logger.warn("commitlint config already exists. Skipping...");
|
|
139
157
|
}
|
|
140
|
-
const lintStagedFile = isTsProject ? "lint-staged.config.ts" : isModule ? "lint-staged.config.cjs" : "lint-staged.config.js";
|
|
141
158
|
if (!fs__default.existsSync(node_path.resolve(process.cwd(), lintStagedFile))) {
|
|
142
159
|
let content = "";
|
|
143
|
-
if (
|
|
160
|
+
if (lintStagedFile.endsWith(".ts")) {
|
|
144
161
|
content = `import { createLintStagedConfig } from '@huaiyou/hooks-git';
|
|
145
162
|
export default createLintStagedConfig();
|
|
163
|
+
`;
|
|
164
|
+
} else if (lintStagedFile.endsWith(".cjs")) {
|
|
165
|
+
content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
|
|
166
|
+
module.exports = createLintStagedConfig();
|
|
146
167
|
`;
|
|
147
168
|
} else {
|
|
148
169
|
content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
|
|
@@ -154,13 +175,6 @@ module.exports = createLintStagedConfig();
|
|
|
154
175
|
} else {
|
|
155
176
|
logger.warn("lint-staged config already exists. Skipping...");
|
|
156
177
|
}
|
|
157
|
-
if (isTsProject) {
|
|
158
|
-
const hasTsNode = pkg.devDependencies && pkg.devDependencies["ts-node"] || pkg.dependencies && pkg.dependencies["ts-node"];
|
|
159
|
-
if (!hasTsNode) {
|
|
160
|
-
logger.info("Detected TypeScript project. Installing ts-node...");
|
|
161
|
-
await runCommand("pnpm", ["add", "-D", "ts-node"]);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
178
|
logger.info("Updating package.json scripts...");
|
|
165
179
|
await updatePackageJson((pkg2) => {
|
|
166
180
|
pkg2.scripts = pkg2.scripts || {};
|
package/dist/cli.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { consola } from 'consola';
|
|
|
6
6
|
import { execa } from 'execa';
|
|
7
7
|
import picocolors from 'picocolors';
|
|
8
8
|
|
|
9
|
-
const version = "2.
|
|
9
|
+
const version = "2.2.0";
|
|
10
10
|
|
|
11
11
|
const logger = {
|
|
12
12
|
/**
|
|
@@ -76,6 +76,8 @@ const init = async () => {
|
|
|
76
76
|
}
|
|
77
77
|
logger.info("Installing dependencies...");
|
|
78
78
|
const pm = await getPackageManager();
|
|
79
|
+
const pkgPath = resolve(process.cwd(), "package.json");
|
|
80
|
+
const pkg = await fs.readJson(pkgPath);
|
|
79
81
|
const devDepsNeeded = [];
|
|
80
82
|
if (!pkg.devDependencies?.husky && !pkg.dependencies?.husky) {
|
|
81
83
|
devDepsNeeded.push("husky");
|
|
@@ -101,24 +103,40 @@ const init = async () => {
|
|
|
101
103
|
logger.info("Adding hooks...");
|
|
102
104
|
const huskyDir = resolve(process.cwd(), ".husky");
|
|
103
105
|
const commitMsgPath = resolve(huskyDir, "commit-msg");
|
|
104
|
-
const commitMsgContent = `npx --no -- commitlint --edit \${1}
|
|
106
|
+
const commitMsgContent = `npx --no -- @huaiyou/hooks-git/wrappers commitlint --edit \${1}
|
|
105
107
|
`;
|
|
106
108
|
await fs.outputFile(commitMsgPath, commitMsgContent, { mode: 493 });
|
|
107
109
|
const preCommitPath = resolve(huskyDir, "pre-commit");
|
|
108
|
-
const preCommitContent = `npx lint-staged
|
|
110
|
+
const preCommitContent = `npx --no -- @huaiyou/hooks-git/wrappers lint-staged
|
|
109
111
|
`;
|
|
110
112
|
await fs.outputFile(preCommitPath, preCommitContent, { mode: 493 });
|
|
111
113
|
logger.info("Creating configuration files...");
|
|
112
|
-
const pkgPath = resolve(process.cwd(), "package.json");
|
|
113
|
-
const pkg = await fs.readJson(pkgPath);
|
|
114
114
|
const isModule = pkg.type === "module";
|
|
115
115
|
const isTsProject = fs.existsSync(resolve(process.cwd(), "tsconfig.json"));
|
|
116
|
-
const
|
|
116
|
+
const isComplexTsConfig2 = isTsProject && isComplexTsConfig2();
|
|
117
|
+
let commitlintFile;
|
|
118
|
+
let lintStagedFile;
|
|
119
|
+
if (isComplexTsConfig2) {
|
|
120
|
+
commitlintFile = "commitlint.config.cjs";
|
|
121
|
+
lintStagedFile = "lint-staged.config.cjs";
|
|
122
|
+
} else if (isTsProject) {
|
|
123
|
+
commitlintFile = "commitlint.config.ts";
|
|
124
|
+
lintStagedFile = "lint-staged.config.ts";
|
|
125
|
+
} else if (isModule) {
|
|
126
|
+
commitlintFile = "commitlint.config.cjs";
|
|
127
|
+
lintStagedFile = "lint-staged.config.cjs";
|
|
128
|
+
} else {
|
|
129
|
+
commitlintFile = "commitlint.config.js";
|
|
130
|
+
lintStagedFile = "lint-staged.config.js";
|
|
131
|
+
}
|
|
117
132
|
if (!fs.existsSync(resolve(process.cwd(), commitlintFile))) {
|
|
118
133
|
let content = "";
|
|
119
|
-
if (
|
|
134
|
+
if (commitlintFile.endsWith(".ts")) {
|
|
120
135
|
content = `import { commitlintConfig } from '@huaiyou/hooks-git';
|
|
121
136
|
export default commitlintConfig;
|
|
137
|
+
`;
|
|
138
|
+
} else if (commitlintFile.endsWith(".cjs")) {
|
|
139
|
+
content = `module.exports = require('@huaiyou/hooks-git/commitlint');
|
|
122
140
|
`;
|
|
123
141
|
} else {
|
|
124
142
|
content = `module.exports = require('@huaiyou/hooks-git/commitlint');
|
|
@@ -129,12 +147,15 @@ export default commitlintConfig;
|
|
|
129
147
|
} else {
|
|
130
148
|
logger.warn("commitlint config already exists. Skipping...");
|
|
131
149
|
}
|
|
132
|
-
const lintStagedFile = isTsProject ? "lint-staged.config.ts" : isModule ? "lint-staged.config.cjs" : "lint-staged.config.js";
|
|
133
150
|
if (!fs.existsSync(resolve(process.cwd(), lintStagedFile))) {
|
|
134
151
|
let content = "";
|
|
135
|
-
if (
|
|
152
|
+
if (lintStagedFile.endsWith(".ts")) {
|
|
136
153
|
content = `import { createLintStagedConfig } from '@huaiyou/hooks-git';
|
|
137
154
|
export default createLintStagedConfig();
|
|
155
|
+
`;
|
|
156
|
+
} else if (lintStagedFile.endsWith(".cjs")) {
|
|
157
|
+
content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
|
|
158
|
+
module.exports = createLintStagedConfig();
|
|
138
159
|
`;
|
|
139
160
|
} else {
|
|
140
161
|
content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
|
|
@@ -146,13 +167,6 @@ module.exports = createLintStagedConfig();
|
|
|
146
167
|
} else {
|
|
147
168
|
logger.warn("lint-staged config already exists. Skipping...");
|
|
148
169
|
}
|
|
149
|
-
if (isTsProject) {
|
|
150
|
-
const hasTsNode = pkg.devDependencies && pkg.devDependencies["ts-node"] || pkg.dependencies && pkg.dependencies["ts-node"];
|
|
151
|
-
if (!hasTsNode) {
|
|
152
|
-
logger.info("Detected TypeScript project. Installing ts-node...");
|
|
153
|
-
await runCommand("pnpm", ["add", "-D", "ts-node"]);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
170
|
logger.info("Updating package.json scripts...");
|
|
157
171
|
await updatePackageJson((pkg2) => {
|
|
158
172
|
pkg2.scripts = pkg2.scripts || {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const cac = require('cac');
|
|
5
|
+
const execa = require('execa');
|
|
6
|
+
|
|
7
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
8
|
+
|
|
9
|
+
const cac__default = /*#__PURE__*/_interopDefaultCompat(cac);
|
|
10
|
+
|
|
11
|
+
const errorMessages$1 = {
|
|
12
|
+
// 类型相关
|
|
13
|
+
"type must be one of": "\u63D0\u4EA4\u7C7B\u578B\u5FC5\u987B\u662F\u4EE5\u4E0B\u4E4B\u4E00",
|
|
14
|
+
"type must not be empty": "\u63D0\u4EA4\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A",
|
|
15
|
+
"type must be lower case": "\u63D0\u4EA4\u7C7B\u578B\u5FC5\u987B\u662F\u5C0F\u5199",
|
|
16
|
+
// 主题相关
|
|
17
|
+
"subject must not be empty": "\u63D0\u4EA4\u4E3B\u9898\u4E0D\u80FD\u4E3A\u7A7A",
|
|
18
|
+
"subject must not end with full stop": "\u63D0\u4EA4\u4E3B\u9898\u4E0D\u80FD\u4EE5\u53E5\u53F7\u7ED3\u5C3E",
|
|
19
|
+
"subject must be lower case": "\u63D0\u4EA4\u4E3B\u9898\u5FC5\u987B\u662F\u5C0F\u5199",
|
|
20
|
+
// 长度相关
|
|
21
|
+
"header must not be longer than": "\u63D0\u4EA4\u5934\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7",
|
|
22
|
+
"body lines must not be longer than": "\u63D0\u4EA4\u6B63\u6587\u6BCF\u884C\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7",
|
|
23
|
+
"footer lines must not be longer than": "\u63D0\u4EA4\u811A\u6CE8\u6BCF\u884C\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7",
|
|
24
|
+
// 通用
|
|
25
|
+
"must match the format": "\u5FC5\u987B\u5339\u914D\u683C\u5F0F",
|
|
26
|
+
"must be": "\u5FC5\u987B\u662F"
|
|
27
|
+
};
|
|
28
|
+
function translateError$1(message) {
|
|
29
|
+
for (const [en, zh] of Object.entries(errorMessages$1)) {
|
|
30
|
+
if (message.includes(en)) {
|
|
31
|
+
return message.replace(en, zh);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return message;
|
|
35
|
+
}
|
|
36
|
+
async function runCommitlint(args) {
|
|
37
|
+
try {
|
|
38
|
+
await execa.execa("commitlint", args, {
|
|
39
|
+
stdio: "inherit",
|
|
40
|
+
reject: false
|
|
41
|
+
});
|
|
42
|
+
} catch (error) {
|
|
43
|
+
if (error.stdout) {
|
|
44
|
+
const translated = translateError$1(error.stdout);
|
|
45
|
+
console.error(translated);
|
|
46
|
+
}
|
|
47
|
+
if (error.stderr) {
|
|
48
|
+
const translated = translateError$1(error.stderr);
|
|
49
|
+
console.error(translated);
|
|
50
|
+
}
|
|
51
|
+
if (error.message) {
|
|
52
|
+
const translated = translateError$1(error.message);
|
|
53
|
+
console.error(translated);
|
|
54
|
+
}
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const errorMessages = {
|
|
60
|
+
// ���置相关
|
|
61
|
+
"Failed to read config from file": "\u65E0\u6CD5\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6",
|
|
62
|
+
"could not find any valid configuration": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E",
|
|
63
|
+
"No valid configurations found": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E",
|
|
64
|
+
// 文件相关
|
|
65
|
+
"Running tasks on": "\u6B63\u5728\u68C0\u67E5\u6587\u4EF6",
|
|
66
|
+
"Applying modifications from tasks": "\u5E94\u7528\u4EFB\u52A1\u4FEE\u6539",
|
|
67
|
+
"Restoring unstaged changes": "\u6062\u590D\u672A\u6682\u5B58\u7684\u66F4\u6539",
|
|
68
|
+
// 任务相关
|
|
69
|
+
"Running tasks for staged files": "\u5BF9\u6682\u5B58\u6587\u4EF6\u8FD0\u884C\u4EFB\u52A1",
|
|
70
|
+
"No staged files found": "\u6CA1\u6709\u627E\u5230\u6682\u5B58\u7684\u6587\u4EF6",
|
|
71
|
+
"All files match patterns": "\u6240\u6709\u6587\u4EF6\u90FD\u5339\u914D\u5230\u6A21\u5F0F",
|
|
72
|
+
// 错误相关
|
|
73
|
+
"Something went wrong": "\u51FA\u9519\u4E86",
|
|
74
|
+
"Command failed": "\u547D\u4EE4\u6267\u884C\u5931\u8D25",
|
|
75
|
+
"Task": "\u4EFB\u52A1",
|
|
76
|
+
"failed": "\u5931\u8D25",
|
|
77
|
+
"passed": "\u901A\u8FC7",
|
|
78
|
+
"skipped": "\u8DF3\u8FC7"
|
|
79
|
+
};
|
|
80
|
+
function translateError(message) {
|
|
81
|
+
let translated = message;
|
|
82
|
+
for (const [en, zh] of Object.entries(errorMessages)) {
|
|
83
|
+
translated = translated.replace(new RegExp(en, "g"), zh);
|
|
84
|
+
}
|
|
85
|
+
return translated;
|
|
86
|
+
}
|
|
87
|
+
function translateLine(line) {
|
|
88
|
+
if (!line.trim() || /^[\s\─│┌┐└┘]+$/g.test(line)) {
|
|
89
|
+
return line;
|
|
90
|
+
}
|
|
91
|
+
return translateError(line);
|
|
92
|
+
}
|
|
93
|
+
async function runLintStaged() {
|
|
94
|
+
try {
|
|
95
|
+
const { stdout, stderr } = await execa.execa("lint-staged", [], {
|
|
96
|
+
stdio: "pipe"
|
|
97
|
+
});
|
|
98
|
+
if (stdout) {
|
|
99
|
+
const lines = stdout.split("\n");
|
|
100
|
+
lines.forEach((line) => {
|
|
101
|
+
console.log(translateLine(line));
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (stderr) {
|
|
105
|
+
const lines = stderr.split("\n");
|
|
106
|
+
lines.forEach((line) => {
|
|
107
|
+
console.error(translateLine(line));
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
} catch (error) {
|
|
111
|
+
if (error.stdout) {
|
|
112
|
+
const lines = error.stdout.split("\n");
|
|
113
|
+
lines.forEach((line) => {
|
|
114
|
+
console.log(translateLine(line));
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (error.stderr) {
|
|
118
|
+
const lines = error.stderr.split("\n");
|
|
119
|
+
lines.forEach((line) => {
|
|
120
|
+
console.error(translateLine(line));
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const cli = cac__default("hy-hooks-git-wrapper");
|
|
128
|
+
cli.command("commitlint [...args]", "Run commitlint with Chinese error messages").action(async (args) => {
|
|
129
|
+
await runCommitlint(args);
|
|
130
|
+
});
|
|
131
|
+
cli.command("lint-staged", "Run lint-staged with Chinese error messages").action(async () => {
|
|
132
|
+
await runLintStaged();
|
|
133
|
+
});
|
|
134
|
+
cli.help();
|
|
135
|
+
cli.parse();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import cac from 'cac';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
|
+
|
|
5
|
+
const errorMessages$1 = {
|
|
6
|
+
// 类型相关
|
|
7
|
+
"type must be one of": "\u63D0\u4EA4\u7C7B\u578B\u5FC5\u987B\u662F\u4EE5\u4E0B\u4E4B\u4E00",
|
|
8
|
+
"type must not be empty": "\u63D0\u4EA4\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A",
|
|
9
|
+
"type must be lower case": "\u63D0\u4EA4\u7C7B\u578B\u5FC5\u987B\u662F\u5C0F\u5199",
|
|
10
|
+
// 主题相关
|
|
11
|
+
"subject must not be empty": "\u63D0\u4EA4\u4E3B\u9898\u4E0D\u80FD\u4E3A\u7A7A",
|
|
12
|
+
"subject must not end with full stop": "\u63D0\u4EA4\u4E3B\u9898\u4E0D\u80FD\u4EE5\u53E5\u53F7\u7ED3\u5C3E",
|
|
13
|
+
"subject must be lower case": "\u63D0\u4EA4\u4E3B\u9898\u5FC5\u987B\u662F\u5C0F\u5199",
|
|
14
|
+
// 长度相关
|
|
15
|
+
"header must not be longer than": "\u63D0\u4EA4\u5934\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7",
|
|
16
|
+
"body lines must not be longer than": "\u63D0\u4EA4\u6B63\u6587\u6BCF\u884C\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7",
|
|
17
|
+
"footer lines must not be longer than": "\u63D0\u4EA4\u811A\u6CE8\u6BCF\u884C\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7",
|
|
18
|
+
// 通用
|
|
19
|
+
"must match the format": "\u5FC5\u987B\u5339\u914D\u683C\u5F0F",
|
|
20
|
+
"must be": "\u5FC5\u987B\u662F"
|
|
21
|
+
};
|
|
22
|
+
function translateError$1(message) {
|
|
23
|
+
for (const [en, zh] of Object.entries(errorMessages$1)) {
|
|
24
|
+
if (message.includes(en)) {
|
|
25
|
+
return message.replace(en, zh);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return message;
|
|
29
|
+
}
|
|
30
|
+
async function runCommitlint(args) {
|
|
31
|
+
try {
|
|
32
|
+
await execa("commitlint", args, {
|
|
33
|
+
stdio: "inherit",
|
|
34
|
+
reject: false
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (error.stdout) {
|
|
38
|
+
const translated = translateError$1(error.stdout);
|
|
39
|
+
console.error(translated);
|
|
40
|
+
}
|
|
41
|
+
if (error.stderr) {
|
|
42
|
+
const translated = translateError$1(error.stderr);
|
|
43
|
+
console.error(translated);
|
|
44
|
+
}
|
|
45
|
+
if (error.message) {
|
|
46
|
+
const translated = translateError$1(error.message);
|
|
47
|
+
console.error(translated);
|
|
48
|
+
}
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const errorMessages = {
|
|
54
|
+
// ���置相关
|
|
55
|
+
"Failed to read config from file": "\u65E0\u6CD5\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6",
|
|
56
|
+
"could not find any valid configuration": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E",
|
|
57
|
+
"No valid configurations found": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E",
|
|
58
|
+
// 文件相关
|
|
59
|
+
"Running tasks on": "\u6B63\u5728\u68C0\u67E5\u6587\u4EF6",
|
|
60
|
+
"Applying modifications from tasks": "\u5E94\u7528\u4EFB\u52A1\u4FEE\u6539",
|
|
61
|
+
"Restoring unstaged changes": "\u6062\u590D\u672A\u6682\u5B58\u7684\u66F4\u6539",
|
|
62
|
+
// 任务相关
|
|
63
|
+
"Running tasks for staged files": "\u5BF9\u6682\u5B58\u6587\u4EF6\u8FD0\u884C\u4EFB\u52A1",
|
|
64
|
+
"No staged files found": "\u6CA1\u6709\u627E\u5230\u6682\u5B58\u7684\u6587\u4EF6",
|
|
65
|
+
"All files match patterns": "\u6240\u6709\u6587\u4EF6\u90FD\u5339\u914D\u5230\u6A21\u5F0F",
|
|
66
|
+
// 错误相关
|
|
67
|
+
"Something went wrong": "\u51FA\u9519\u4E86",
|
|
68
|
+
"Command failed": "\u547D\u4EE4\u6267\u884C\u5931\u8D25",
|
|
69
|
+
"Task": "\u4EFB\u52A1",
|
|
70
|
+
"failed": "\u5931\u8D25",
|
|
71
|
+
"passed": "\u901A\u8FC7",
|
|
72
|
+
"skipped": "\u8DF3\u8FC7"
|
|
73
|
+
};
|
|
74
|
+
function translateError(message) {
|
|
75
|
+
let translated = message;
|
|
76
|
+
for (const [en, zh] of Object.entries(errorMessages)) {
|
|
77
|
+
translated = translated.replace(new RegExp(en, "g"), zh);
|
|
78
|
+
}
|
|
79
|
+
return translated;
|
|
80
|
+
}
|
|
81
|
+
function translateLine(line) {
|
|
82
|
+
if (!line.trim() || /^[\s\─│┌┐└┘]+$/g.test(line)) {
|
|
83
|
+
return line;
|
|
84
|
+
}
|
|
85
|
+
return translateError(line);
|
|
86
|
+
}
|
|
87
|
+
async function runLintStaged() {
|
|
88
|
+
try {
|
|
89
|
+
const { stdout, stderr } = await execa("lint-staged", [], {
|
|
90
|
+
stdio: "pipe"
|
|
91
|
+
});
|
|
92
|
+
if (stdout) {
|
|
93
|
+
const lines = stdout.split("\n");
|
|
94
|
+
lines.forEach((line) => {
|
|
95
|
+
console.log(translateLine(line));
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (stderr) {
|
|
99
|
+
const lines = stderr.split("\n");
|
|
100
|
+
lines.forEach((line) => {
|
|
101
|
+
console.error(translateLine(line));
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
} catch (error) {
|
|
105
|
+
if (error.stdout) {
|
|
106
|
+
const lines = error.stdout.split("\n");
|
|
107
|
+
lines.forEach((line) => {
|
|
108
|
+
console.log(translateLine(line));
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
if (error.stderr) {
|
|
112
|
+
const lines = error.stderr.split("\n");
|
|
113
|
+
lines.forEach((line) => {
|
|
114
|
+
console.error(translateLine(line));
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const cli = cac("hy-hooks-git-wrapper");
|
|
122
|
+
cli.command("commitlint [...args]", "Run commitlint with Chinese error messages").action(async (args) => {
|
|
123
|
+
await runCommitlint(args);
|
|
124
|
+
});
|
|
125
|
+
cli.command("lint-staged", "Run lint-staged with Chinese error messages").action(async () => {
|
|
126
|
+
await runLintStaged();
|
|
127
|
+
});
|
|
128
|
+
cli.help();
|
|
129
|
+
cli.parse();
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huaiyou/hooks-git",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Git hooks configuration with Husky, Commitlint and Lint-staged",
|
|
5
5
|
"bin": {
|
|
6
|
-
"hy-hooks-git": "./dist/cli.mjs"
|
|
6
|
+
"hy-hooks-git": "./dist/cli.mjs",
|
|
7
|
+
"hy-hooks-commitlint": "./dist/wrappers/cli.mjs",
|
|
8
|
+
"hy-hooks-lint-staged": "./dist/wrappers/cli.mjs"
|
|
7
9
|
},
|
|
8
10
|
"files": [
|
|
9
11
|
"dist",
|
|
@@ -29,6 +31,10 @@
|
|
|
29
31
|
"require": "./dist/lint-staged.cjs",
|
|
30
32
|
"import": "./dist/lint-staged.mjs",
|
|
31
33
|
"types": "./dist/lint-staged.d.ts"
|
|
34
|
+
},
|
|
35
|
+
"./wrappers": {
|
|
36
|
+
"require": "./dist/wrappers/cli.cjs",
|
|
37
|
+
"import": "./dist/wrappers/cli.mjs"
|
|
32
38
|
}
|
|
33
39
|
},
|
|
34
40
|
"scripts": {
|