@huaiyou/hooks-git 2.1.2 → 2.2.1
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 +38 -15
- package/dist/cli.mjs +38 -15
- package/dist/wrappers/cli.cjs +137 -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 +131 -0
- package/package.json +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @huaiyou/hooks-git
|
|
2
2
|
|
|
3
|
+
## 2.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fix build issue with function naming conflicts
|
|
8
|
+
|
|
9
|
+
## 2.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Add Chinese error message wrappers for commitlint and lint-staged
|
|
14
|
+
- Detect complex tsconfig and use .cjs config files (no ts-node needed)
|
|
15
|
+
- Add wrapper CLI to translate error messages to Chinese
|
|
16
|
+
|
|
3
17
|
## 2.1.2
|
|
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.1
|
|
17
|
+
const version = "2.2.1";
|
|
18
18
|
|
|
19
19
|
const logger = {
|
|
20
20
|
/**
|
|
@@ -75,6 +75,15 @@ const updatePackageJson = async (callback) => {
|
|
|
75
75
|
await fs__default.writeJson(pkgPath, newPkg, { spaces: 2 });
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
+
function checkComplexTsConfig() {
|
|
79
|
+
try {
|
|
80
|
+
const tsconfigPath = node_path.resolve(process.cwd(), "tsconfig.json");
|
|
81
|
+
const tsconfig = fs__default.readJsonSync(tsconfigPath);
|
|
82
|
+
return tsconfig.files === "" || Array.isArray(tsconfig.files) && tsconfig.files.length === 0 && tsconfig.references;
|
|
83
|
+
} catch {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
78
87
|
const init = async () => {
|
|
79
88
|
logger.box("Initializing @huaiyou/hooks-git");
|
|
80
89
|
const gitDirPath = node_path.resolve(process.cwd(), ".git");
|
|
@@ -105,28 +114,46 @@ const init = async () => {
|
|
|
105
114
|
}
|
|
106
115
|
try {
|
|
107
116
|
await runCommand(pm === "yarn" ? "npx" : pm, ["husky", "install"]);
|
|
108
|
-
} catch
|
|
117
|
+
} catch {
|
|
109
118
|
logger.error("Failed to initialize husky.");
|
|
110
119
|
}
|
|
111
120
|
logger.info("Adding hooks...");
|
|
112
121
|
const huskyDir = node_path.resolve(process.cwd(), ".husky");
|
|
113
122
|
const commitMsgPath = node_path.resolve(huskyDir, "commit-msg");
|
|
114
|
-
const commitMsgContent = `npx --no -- commitlint --edit \${1}
|
|
123
|
+
const commitMsgContent = `npx --no -- @huaiyou/hooks-git/wrappers commitlint --edit \${1}
|
|
115
124
|
`;
|
|
116
125
|
await fs__default.outputFile(commitMsgPath, commitMsgContent, { mode: 493 });
|
|
117
126
|
const preCommitPath = node_path.resolve(huskyDir, "pre-commit");
|
|
118
|
-
const preCommitContent = `npx lint-staged
|
|
127
|
+
const preCommitContent = `npx --no -- @huaiyou/hooks-git/wrappers lint-staged
|
|
119
128
|
`;
|
|
120
129
|
await fs__default.outputFile(preCommitPath, preCommitContent, { mode: 493 });
|
|
121
130
|
logger.info("Creating configuration files...");
|
|
122
131
|
const isModule = pkg.type === "module";
|
|
123
132
|
const isTsProject = fs__default.existsSync(node_path.resolve(process.cwd(), "tsconfig.json"));
|
|
124
|
-
const
|
|
133
|
+
const hasComplexTsConfig = isTsProject && checkComplexTsConfig();
|
|
134
|
+
let commitlintFile;
|
|
135
|
+
let lintStagedFile;
|
|
136
|
+
if (hasComplexTsConfig) {
|
|
137
|
+
commitlintFile = "commitlint.config.cjs";
|
|
138
|
+
lintStagedFile = "lint-staged.config.cjs";
|
|
139
|
+
} else if (isTsProject) {
|
|
140
|
+
commitlintFile = "commitlint.config.ts";
|
|
141
|
+
lintStagedFile = "lint-staged.config.ts";
|
|
142
|
+
} else if (isModule) {
|
|
143
|
+
commitlintFile = "commitlint.config.cjs";
|
|
144
|
+
lintStagedFile = "lint-staged.config.cjs";
|
|
145
|
+
} else {
|
|
146
|
+
commitlintFile = "commitlint.config.js";
|
|
147
|
+
lintStagedFile = "lint-staged.config.js";
|
|
148
|
+
}
|
|
125
149
|
if (!fs__default.existsSync(node_path.resolve(process.cwd(), commitlintFile))) {
|
|
126
150
|
let content = "";
|
|
127
|
-
if (
|
|
151
|
+
if (commitlintFile.endsWith(".ts")) {
|
|
128
152
|
content = `import { commitlintConfig } from '@huaiyou/hooks-git';
|
|
129
153
|
export default commitlintConfig;
|
|
154
|
+
`;
|
|
155
|
+
} else if (commitlintFile.endsWith(".cjs")) {
|
|
156
|
+
content = `module.exports = require('@huaiyou/hooks-git/commitlint');
|
|
130
157
|
`;
|
|
131
158
|
} else {
|
|
132
159
|
content = `module.exports = require('@huaiyou/hooks-git/commitlint');
|
|
@@ -137,12 +164,15 @@ export default commitlintConfig;
|
|
|
137
164
|
} else {
|
|
138
165
|
logger.warn("commitlint config already exists. Skipping...");
|
|
139
166
|
}
|
|
140
|
-
const lintStagedFile = isTsProject ? "lint-staged.config.ts" : isModule ? "lint-staged.config.cjs" : "lint-staged.config.js";
|
|
141
167
|
if (!fs__default.existsSync(node_path.resolve(process.cwd(), lintStagedFile))) {
|
|
142
168
|
let content = "";
|
|
143
|
-
if (
|
|
169
|
+
if (lintStagedFile.endsWith(".ts")) {
|
|
144
170
|
content = `import { createLintStagedConfig } from '@huaiyou/hooks-git';
|
|
145
171
|
export default createLintStagedConfig();
|
|
172
|
+
`;
|
|
173
|
+
} else if (lintStagedFile.endsWith(".cjs")) {
|
|
174
|
+
content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
|
|
175
|
+
module.exports = createLintStagedConfig();
|
|
146
176
|
`;
|
|
147
177
|
} else {
|
|
148
178
|
content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
|
|
@@ -154,13 +184,6 @@ module.exports = createLintStagedConfig();
|
|
|
154
184
|
} else {
|
|
155
185
|
logger.warn("lint-staged config already exists. Skipping...");
|
|
156
186
|
}
|
|
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
187
|
logger.info("Updating package.json scripts...");
|
|
165
188
|
await updatePackageJson((pkg2) => {
|
|
166
189
|
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.1
|
|
9
|
+
const version = "2.2.1";
|
|
10
10
|
|
|
11
11
|
const logger = {
|
|
12
12
|
/**
|
|
@@ -67,6 +67,15 @@ const updatePackageJson = async (callback) => {
|
|
|
67
67
|
await fs.writeJson(pkgPath, newPkg, { spaces: 2 });
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
+
function checkComplexTsConfig() {
|
|
71
|
+
try {
|
|
72
|
+
const tsconfigPath = resolve(process.cwd(), "tsconfig.json");
|
|
73
|
+
const tsconfig = fs.readJsonSync(tsconfigPath);
|
|
74
|
+
return tsconfig.files === "" || Array.isArray(tsconfig.files) && tsconfig.files.length === 0 && tsconfig.references;
|
|
75
|
+
} catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
70
79
|
const init = async () => {
|
|
71
80
|
logger.box("Initializing @huaiyou/hooks-git");
|
|
72
81
|
const gitDirPath = resolve(process.cwd(), ".git");
|
|
@@ -97,28 +106,46 @@ const init = async () => {
|
|
|
97
106
|
}
|
|
98
107
|
try {
|
|
99
108
|
await runCommand(pm === "yarn" ? "npx" : pm, ["husky", "install"]);
|
|
100
|
-
} catch
|
|
109
|
+
} catch {
|
|
101
110
|
logger.error("Failed to initialize husky.");
|
|
102
111
|
}
|
|
103
112
|
logger.info("Adding hooks...");
|
|
104
113
|
const huskyDir = resolve(process.cwd(), ".husky");
|
|
105
114
|
const commitMsgPath = resolve(huskyDir, "commit-msg");
|
|
106
|
-
const commitMsgContent = `npx --no -- commitlint --edit \${1}
|
|
115
|
+
const commitMsgContent = `npx --no -- @huaiyou/hooks-git/wrappers commitlint --edit \${1}
|
|
107
116
|
`;
|
|
108
117
|
await fs.outputFile(commitMsgPath, commitMsgContent, { mode: 493 });
|
|
109
118
|
const preCommitPath = resolve(huskyDir, "pre-commit");
|
|
110
|
-
const preCommitContent = `npx lint-staged
|
|
119
|
+
const preCommitContent = `npx --no -- @huaiyou/hooks-git/wrappers lint-staged
|
|
111
120
|
`;
|
|
112
121
|
await fs.outputFile(preCommitPath, preCommitContent, { mode: 493 });
|
|
113
122
|
logger.info("Creating configuration files...");
|
|
114
123
|
const isModule = pkg.type === "module";
|
|
115
124
|
const isTsProject = fs.existsSync(resolve(process.cwd(), "tsconfig.json"));
|
|
116
|
-
const
|
|
125
|
+
const hasComplexTsConfig = isTsProject && checkComplexTsConfig();
|
|
126
|
+
let commitlintFile;
|
|
127
|
+
let lintStagedFile;
|
|
128
|
+
if (hasComplexTsConfig) {
|
|
129
|
+
commitlintFile = "commitlint.config.cjs";
|
|
130
|
+
lintStagedFile = "lint-staged.config.cjs";
|
|
131
|
+
} else if (isTsProject) {
|
|
132
|
+
commitlintFile = "commitlint.config.ts";
|
|
133
|
+
lintStagedFile = "lint-staged.config.ts";
|
|
134
|
+
} else if (isModule) {
|
|
135
|
+
commitlintFile = "commitlint.config.cjs";
|
|
136
|
+
lintStagedFile = "lint-staged.config.cjs";
|
|
137
|
+
} else {
|
|
138
|
+
commitlintFile = "commitlint.config.js";
|
|
139
|
+
lintStagedFile = "lint-staged.config.js";
|
|
140
|
+
}
|
|
117
141
|
if (!fs.existsSync(resolve(process.cwd(), commitlintFile))) {
|
|
118
142
|
let content = "";
|
|
119
|
-
if (
|
|
143
|
+
if (commitlintFile.endsWith(".ts")) {
|
|
120
144
|
content = `import { commitlintConfig } from '@huaiyou/hooks-git';
|
|
121
145
|
export default commitlintConfig;
|
|
146
|
+
`;
|
|
147
|
+
} else if (commitlintFile.endsWith(".cjs")) {
|
|
148
|
+
content = `module.exports = require('@huaiyou/hooks-git/commitlint');
|
|
122
149
|
`;
|
|
123
150
|
} else {
|
|
124
151
|
content = `module.exports = require('@huaiyou/hooks-git/commitlint');
|
|
@@ -129,12 +156,15 @@ export default commitlintConfig;
|
|
|
129
156
|
} else {
|
|
130
157
|
logger.warn("commitlint config already exists. Skipping...");
|
|
131
158
|
}
|
|
132
|
-
const lintStagedFile = isTsProject ? "lint-staged.config.ts" : isModule ? "lint-staged.config.cjs" : "lint-staged.config.js";
|
|
133
159
|
if (!fs.existsSync(resolve(process.cwd(), lintStagedFile))) {
|
|
134
160
|
let content = "";
|
|
135
|
-
if (
|
|
161
|
+
if (lintStagedFile.endsWith(".ts")) {
|
|
136
162
|
content = `import { createLintStagedConfig } from '@huaiyou/hooks-git';
|
|
137
163
|
export default createLintStagedConfig();
|
|
164
|
+
`;
|
|
165
|
+
} else if (lintStagedFile.endsWith(".cjs")) {
|
|
166
|
+
content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
|
|
167
|
+
module.exports = createLintStagedConfig();
|
|
138
168
|
`;
|
|
139
169
|
} else {
|
|
140
170
|
content = `const { createLintStagedConfig } = require('@huaiyou/hooks-git/lint-staged');
|
|
@@ -146,13 +176,6 @@ module.exports = createLintStagedConfig();
|
|
|
146
176
|
} else {
|
|
147
177
|
logger.warn("lint-staged config already exists. Skipping...");
|
|
148
178
|
}
|
|
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
179
|
logger.info("Updating package.json scripts...");
|
|
157
180
|
await updatePackageJson((pkg2) => {
|
|
158
181
|
pkg2.scripts = pkg2.scripts || {};
|
|
@@ -0,0 +1,137 @@
|
|
|
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
|
+
const err = error;
|
|
44
|
+
if (err.stdout) {
|
|
45
|
+
const translated = translateError$1(err.stdout);
|
|
46
|
+
process.stderr.write(translated + "\n");
|
|
47
|
+
}
|
|
48
|
+
if (err.stderr) {
|
|
49
|
+
const translated = translateError$1(err.stderr);
|
|
50
|
+
process.stderr.write(translated + "\n");
|
|
51
|
+
}
|
|
52
|
+
if (err.message) {
|
|
53
|
+
const translated = translateError$1(err.message);
|
|
54
|
+
process.stderr.write(translated + "\n");
|
|
55
|
+
}
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const errorMessages = {
|
|
61
|
+
// 配置相关
|
|
62
|
+
"Failed to read config from file": "\u65E0\u6CD5\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6",
|
|
63
|
+
"could not find any valid configuration": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E",
|
|
64
|
+
"No valid configurations found": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E",
|
|
65
|
+
// 文件相关
|
|
66
|
+
"Running tasks on": "\u6B63\u5728\u68C0\u67E5\u6587\u4EF6",
|
|
67
|
+
"Applying modifications from tasks": "\u5E94\u7528\u4EFB\u52A1\u4FEE\u6539",
|
|
68
|
+
"Restoring unstaged changes": "\u6062\u590D\u672A\u6682\u5B58\u7684\u66F4\u6539",
|
|
69
|
+
// 任务相关
|
|
70
|
+
"Running tasks for staged files": "\u5BF9\u6682\u5B58\u6587\u4EF6\u8FD0\u884C\u4EFB\u52A1",
|
|
71
|
+
"No staged files found": "\u6CA1\u6709\u627E\u5230\u6682\u5B58\u7684\u6587\u4EF6",
|
|
72
|
+
"All files match patterns": "\u6240\u6709\u6587\u4EF6\u90FD\u5339\u914D\u5230\u6A21\u5F0F",
|
|
73
|
+
// 错误相关
|
|
74
|
+
"Something went wrong": "\u51FA\u9519\u4E86",
|
|
75
|
+
"Command failed": "\u547D\u4EE4\u6267\u884C\u5931\u8D25",
|
|
76
|
+
Task: "\u4EFB\u52A1",
|
|
77
|
+
failed: "\u5931\u8D25",
|
|
78
|
+
passed: "\u901A\u8FC7",
|
|
79
|
+
skipped: "\u8DF3\u8FC7"
|
|
80
|
+
};
|
|
81
|
+
function translateError(message) {
|
|
82
|
+
let translated = message;
|
|
83
|
+
for (const [en, zh] of Object.entries(errorMessages)) {
|
|
84
|
+
translated = translated.replace(new RegExp(en, "g"), zh);
|
|
85
|
+
}
|
|
86
|
+
return translated;
|
|
87
|
+
}
|
|
88
|
+
function translateLine(line) {
|
|
89
|
+
if (!line.trim() || /^[\s─│┌┐└┘]+$/g.test(line)) {
|
|
90
|
+
return line;
|
|
91
|
+
}
|
|
92
|
+
return translateError(line);
|
|
93
|
+
}
|
|
94
|
+
async function runLintStaged() {
|
|
95
|
+
try {
|
|
96
|
+
const { stdout, stderr } = await execa.execa("lint-staged", [], {
|
|
97
|
+
stdio: "pipe"
|
|
98
|
+
});
|
|
99
|
+
if (stdout) {
|
|
100
|
+
const lines = stdout.split("\n");
|
|
101
|
+
lines.forEach((line) => {
|
|
102
|
+
process.stdout.write(translateLine(line) + "\n");
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
if (stderr) {
|
|
106
|
+
const lines = stderr.split("\n");
|
|
107
|
+
lines.forEach((line) => {
|
|
108
|
+
process.stderr.write(translateLine(line) + "\n");
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
} catch (error) {
|
|
112
|
+
const err = error;
|
|
113
|
+
if (err.stdout) {
|
|
114
|
+
const lines = err.stdout.split("\n");
|
|
115
|
+
lines.forEach((line) => {
|
|
116
|
+
process.stdout.write(translateLine(line) + "\n");
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (err.stderr) {
|
|
120
|
+
const lines = err.stderr.split("\n");
|
|
121
|
+
lines.forEach((line) => {
|
|
122
|
+
process.stderr.write(translateLine(line) + "\n");
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const cli = cac__default("hy-hooks-git-wrapper");
|
|
130
|
+
cli.command("commitlint [...args]", "Run commitlint with Chinese error messages").action(async (args) => {
|
|
131
|
+
await runCommitlint(args);
|
|
132
|
+
});
|
|
133
|
+
cli.command("lint-staged", "Run lint-staged with Chinese error messages").action(async () => {
|
|
134
|
+
await runLintStaged();
|
|
135
|
+
});
|
|
136
|
+
cli.help();
|
|
137
|
+
cli.parse();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,131 @@
|
|
|
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
|
+
const err = error;
|
|
38
|
+
if (err.stdout) {
|
|
39
|
+
const translated = translateError$1(err.stdout);
|
|
40
|
+
process.stderr.write(translated + "\n");
|
|
41
|
+
}
|
|
42
|
+
if (err.stderr) {
|
|
43
|
+
const translated = translateError$1(err.stderr);
|
|
44
|
+
process.stderr.write(translated + "\n");
|
|
45
|
+
}
|
|
46
|
+
if (err.message) {
|
|
47
|
+
const translated = translateError$1(err.message);
|
|
48
|
+
process.stderr.write(translated + "\n");
|
|
49
|
+
}
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const errorMessages = {
|
|
55
|
+
// 配置相关
|
|
56
|
+
"Failed to read config from file": "\u65E0\u6CD5\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6",
|
|
57
|
+
"could not find any valid configuration": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E",
|
|
58
|
+
"No valid configurations found": "\u627E\u4E0D\u5230\u6709\u6548\u7684\u914D\u7F6E",
|
|
59
|
+
// 文件相关
|
|
60
|
+
"Running tasks on": "\u6B63\u5728\u68C0\u67E5\u6587\u4EF6",
|
|
61
|
+
"Applying modifications from tasks": "\u5E94\u7528\u4EFB\u52A1\u4FEE\u6539",
|
|
62
|
+
"Restoring unstaged changes": "\u6062\u590D\u672A\u6682\u5B58\u7684\u66F4\u6539",
|
|
63
|
+
// 任务相关
|
|
64
|
+
"Running tasks for staged files": "\u5BF9\u6682\u5B58\u6587\u4EF6\u8FD0\u884C\u4EFB\u52A1",
|
|
65
|
+
"No staged files found": "\u6CA1\u6709\u627E\u5230\u6682\u5B58\u7684\u6587\u4EF6",
|
|
66
|
+
"All files match patterns": "\u6240\u6709\u6587\u4EF6\u90FD\u5339\u914D\u5230\u6A21\u5F0F",
|
|
67
|
+
// 错误相关
|
|
68
|
+
"Something went wrong": "\u51FA\u9519\u4E86",
|
|
69
|
+
"Command failed": "\u547D\u4EE4\u6267\u884C\u5931\u8D25",
|
|
70
|
+
Task: "\u4EFB\u52A1",
|
|
71
|
+
failed: "\u5931\u8D25",
|
|
72
|
+
passed: "\u901A\u8FC7",
|
|
73
|
+
skipped: "\u8DF3\u8FC7"
|
|
74
|
+
};
|
|
75
|
+
function translateError(message) {
|
|
76
|
+
let translated = message;
|
|
77
|
+
for (const [en, zh] of Object.entries(errorMessages)) {
|
|
78
|
+
translated = translated.replace(new RegExp(en, "g"), zh);
|
|
79
|
+
}
|
|
80
|
+
return translated;
|
|
81
|
+
}
|
|
82
|
+
function translateLine(line) {
|
|
83
|
+
if (!line.trim() || /^[\s─│┌┐└┘]+$/g.test(line)) {
|
|
84
|
+
return line;
|
|
85
|
+
}
|
|
86
|
+
return translateError(line);
|
|
87
|
+
}
|
|
88
|
+
async function runLintStaged() {
|
|
89
|
+
try {
|
|
90
|
+
const { stdout, stderr } = await execa("lint-staged", [], {
|
|
91
|
+
stdio: "pipe"
|
|
92
|
+
});
|
|
93
|
+
if (stdout) {
|
|
94
|
+
const lines = stdout.split("\n");
|
|
95
|
+
lines.forEach((line) => {
|
|
96
|
+
process.stdout.write(translateLine(line) + "\n");
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (stderr) {
|
|
100
|
+
const lines = stderr.split("\n");
|
|
101
|
+
lines.forEach((line) => {
|
|
102
|
+
process.stderr.write(translateLine(line) + "\n");
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
} catch (error) {
|
|
106
|
+
const err = error;
|
|
107
|
+
if (err.stdout) {
|
|
108
|
+
const lines = err.stdout.split("\n");
|
|
109
|
+
lines.forEach((line) => {
|
|
110
|
+
process.stdout.write(translateLine(line) + "\n");
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (err.stderr) {
|
|
114
|
+
const lines = err.stderr.split("\n");
|
|
115
|
+
lines.forEach((line) => {
|
|
116
|
+
process.stderr.write(translateLine(line) + "\n");
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const cli = cac("hy-hooks-git-wrapper");
|
|
124
|
+
cli.command("commitlint [...args]", "Run commitlint with Chinese error messages").action(async (args) => {
|
|
125
|
+
await runCommitlint(args);
|
|
126
|
+
});
|
|
127
|
+
cli.command("lint-staged", "Run lint-staged with Chinese error messages").action(async () => {
|
|
128
|
+
await runLintStaged();
|
|
129
|
+
});
|
|
130
|
+
cli.help();
|
|
131
|
+
cli.parse();
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huaiyou/hooks-git",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
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": {
|