@apdesign/code-style-react 1.1.3 → 1.1.5
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/package.json +3 -1
- package/scripts/buildEslint.sh +10 -2
- package/scripts/runEslint.js +111 -21
- package/scripts/runStylelint.js +137 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@apdesign/code-style-react",
|
3
|
-
"version": "1.1.
|
3
|
+
"version": "1.1.5",
|
4
4
|
"scripts": {},
|
5
5
|
"bin": {
|
6
6
|
"apdesign-code-style": "cli.js"
|
@@ -18,6 +18,7 @@
|
|
18
18
|
"license": "ISC",
|
19
19
|
"description": "",
|
20
20
|
"dependencies": {
|
21
|
+
"@types/glob": "^8.1.0",
|
21
22
|
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
22
23
|
"@typescript-eslint/parser": "^6.21.0",
|
23
24
|
"css-color-names": "^1.0.1",
|
@@ -30,6 +31,7 @@
|
|
30
31
|
"eslint-plugin-prettier": "^5.2.1",
|
31
32
|
"eslint-plugin-react": "^7.37.2",
|
32
33
|
"eslint-plugin-react-hooks": "^4.6.2",
|
34
|
+
"glob": "^11.0.3",
|
33
35
|
"husky": "^9.1.7",
|
34
36
|
"lint-staged": "^15.3.0",
|
35
37
|
"postcss-less": "^6.0.0",
|
package/scripts/buildEslint.sh
CHANGED
@@ -5,19 +5,27 @@ echo "🔍 Starting ESLint check (Git diff files only)..."
|
|
5
5
|
PROJECT_ROOT=$(git rev-parse --show-toplevel)
|
6
6
|
cd "$PROJECT_ROOT" || exit 1
|
7
7
|
|
8
|
+
# 参数:commitId(必填),路径(可选)
|
8
9
|
TARGET_COMMIT=$1
|
9
10
|
LATEST_COMMIT=$(git rev-parse HEAD)
|
10
11
|
|
11
12
|
if [ -z "$TARGET_COMMIT" ]; then
|
12
13
|
echo "❗ Error: Missing target commit ID."
|
13
|
-
echo "👉 Usage: $0 <target-commit-id>"
|
14
|
+
echo "👉 Usage: $0 <target-commit-id> [project-path]"
|
14
15
|
exit 1
|
15
16
|
fi
|
16
17
|
|
17
18
|
echo "获取到上一次运行commit ID: $TARGET_COMMIT"
|
18
19
|
echo "获取到当前最新的commit ID: $LATEST_COMMIT"
|
19
20
|
|
20
|
-
|
21
|
+
# 处理路径参数
|
22
|
+
if [ -n "$FULL_PATH" ]; then
|
23
|
+
PROJECT_NAME=$(basename "$FULL_PATH")
|
24
|
+
echo "📂 检测子项目: $PROJECT_NAME"
|
25
|
+
DIFF_FILES=$(git diff --name-only "$TARGET_COMMIT" "$LATEST_COMMIT" -- "*/$PROJECT_NAME/*.{ts,tsx,js,jsx}")
|
26
|
+
else
|
27
|
+
DIFF_FILES=$(git diff --name-only "$TARGET_COMMIT" "$LATEST_COMMIT" -- '*.ts' '*.tsx' '*.js' '*.jsx')
|
28
|
+
fi
|
21
29
|
|
22
30
|
if [ -z "$DIFF_FILES" ]; then
|
23
31
|
echo "✅ No matching file changes detected, skipping ESLint check"
|
package/scripts/runEslint.js
CHANGED
@@ -4,22 +4,66 @@ let spawnSync;
|
|
4
4
|
let spawn;
|
5
5
|
let path;
|
6
6
|
let fs;
|
7
|
+
let os;
|
8
|
+
let glob;
|
7
9
|
|
8
|
-
async function runEslint(
|
10
|
+
async function runEslint() {
|
9
11
|
try {
|
10
12
|
if (typeof require !== 'undefined') {
|
11
13
|
// CommonJS
|
12
14
|
({ spawnSync, spawn } = require('child_process'));
|
13
15
|
path = require('path');
|
14
16
|
fs = require('fs');
|
17
|
+
os = require('os');
|
18
|
+
glob = require('glob');
|
15
19
|
} else {
|
16
20
|
// ESM
|
17
21
|
({ spawnSync, spawn } = await import('node:child_process'));
|
18
22
|
path = await import('node:path');
|
19
23
|
fs = await import('node:fs');
|
24
|
+
os = await import('node:os');
|
25
|
+
glob = (await import('glob')).default;
|
20
26
|
}
|
21
27
|
|
22
|
-
|
28
|
+
// 参数解析
|
29
|
+
const args = process.argv.slice(2);
|
30
|
+
|
31
|
+
// 默认并发数为 CPU 核心数,但不超过 8
|
32
|
+
let maxWorkers = Math.min(os.cpus().length, 8);
|
33
|
+
|
34
|
+
let branchArg = null;
|
35
|
+
|
36
|
+
// 找到 --max-workers 参数
|
37
|
+
const maxWorkersArgIndex = args.indexOf('--max-workers');
|
38
|
+
if (maxWorkersArgIndex !== -1 && args[maxWorkersArgIndex + 1]) {
|
39
|
+
const val = parseInt(args[maxWorkersArgIndex + 1], 10);
|
40
|
+
if (!isNaN(val) && val > 0) {
|
41
|
+
maxWorkers = Math.min(val, 8); // 限制最大值为 8
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
// targetPath 是第一个不是 --max-workers 的参数
|
46
|
+
let targetPath = process.cwd();
|
47
|
+
for (let i = 0; i < args.length; i++) {
|
48
|
+
if (i === maxWorkersArgIndex || i === maxWorkersArgIndex + 1) continue;
|
49
|
+
if (!targetPath || targetPath === process.cwd()) {
|
50
|
+
targetPath = args[i];
|
51
|
+
continue;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
// 检查是否有分支参数 (--branch <branchName>)
|
56
|
+
const branchIndex = args.indexOf('--branch');
|
57
|
+
if (branchIndex !== -1 && args[branchIndex + 1]) {
|
58
|
+
branchArg = args[branchIndex + 1];
|
59
|
+
}
|
60
|
+
|
61
|
+
console.log(`\n[ESLint 启动配置]`);
|
62
|
+
console.log(`- 检查路径: ${targetPath}`);
|
63
|
+
console.log(`- 并发进程数: ${maxWorkers}`);
|
64
|
+
console.log('');
|
65
|
+
|
66
|
+
// 路径解析
|
23
67
|
let rootDir = path.resolve(targetPath);
|
24
68
|
|
25
69
|
// 如果传的是单个目录名且路径不存在,则在 packages/ 下查找
|
@@ -34,7 +78,7 @@ async function runEslint(targetPathArg) {
|
|
34
78
|
}
|
35
79
|
}
|
36
80
|
|
37
|
-
console.log('
|
81
|
+
console.log('目标路径解析为:', rootDir);
|
38
82
|
|
39
83
|
const gitRootResult = spawnSync('git', ['rev-parse', '--show-toplevel'], {
|
40
84
|
cwd: rootDir,
|
@@ -48,14 +92,12 @@ async function runEslint(targetPathArg) {
|
|
48
92
|
}
|
49
93
|
|
50
94
|
const gitRoot = gitRootResult.stdout.trim();
|
51
|
-
console.log('Git 根目录:', gitRoot);
|
52
95
|
|
53
96
|
let targetBranch = 'master';
|
54
97
|
if (targetPath !== process.cwd()) {
|
55
98
|
const lastDir = path.basename(rootDir);
|
56
99
|
targetBranch = `master-${lastDir.split('-').pop()}`;
|
57
100
|
}
|
58
|
-
console.log('目标分支:', targetBranch);
|
59
101
|
|
60
102
|
// 获取当前分支
|
61
103
|
const currentBranchResult = spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
@@ -70,11 +112,27 @@ async function runEslint(targetPathArg) {
|
|
70
112
|
}
|
71
113
|
|
72
114
|
const currentBranch = currentBranchResult.stdout.trim();
|
73
|
-
|
115
|
+
|
116
|
+
console.log(`[Git 信息]`);
|
117
|
+
console.log(`- 仓库根目录: ${gitRoot}`);
|
118
|
+
console.log(`- 当前分支: ${currentBranch}`);
|
119
|
+
console.log(`- 目标分支: ${branchArg || targetBranch}`);
|
120
|
+
console.log('');
|
121
|
+
|
122
|
+
const statusResult = spawnSync('git', ['status', '--porcelain'], {
|
123
|
+
cwd: gitRoot,
|
124
|
+
encoding: 'utf-8',
|
125
|
+
shell: true,
|
126
|
+
});
|
127
|
+
if (statusResult.status === 0 && statusResult.stdout.trim()) {
|
128
|
+
console.warn(
|
129
|
+
'⚠️ 检测到当前分支有未提交的更改,切换分支可能失败或导致代码丢失,请先提交或暂存更改!\n',
|
130
|
+
);
|
131
|
+
}
|
74
132
|
|
75
133
|
// 切换分支并拉取最新代码
|
76
|
-
if (currentBranch !== targetBranch) {
|
77
|
-
console.log(
|
134
|
+
if (!branchArg && currentBranch !== targetBranch) {
|
135
|
+
console.log(`➡️ 切换到分支 ${targetBranch} ...`);
|
78
136
|
const checkout = spawnSync('git', ['checkout', targetBranch], {
|
79
137
|
cwd: gitRoot,
|
80
138
|
stdio: 'inherit',
|
@@ -84,9 +142,11 @@ async function runEslint(targetPathArg) {
|
|
84
142
|
console.error(`切换分支失败`);
|
85
143
|
process.exit(1);
|
86
144
|
}
|
145
|
+
} else if (branchArg) {
|
146
|
+
console.log(`➡️ 使用指定分支 ${branchArg} `);
|
87
147
|
}
|
88
148
|
|
89
|
-
console.log('
|
149
|
+
console.log('⬇️ 正在拉取最新代码...');
|
90
150
|
const pull = spawnSync('git', ['pull'], {
|
91
151
|
cwd: gitRoot,
|
92
152
|
stdio: 'inherit',
|
@@ -105,19 +165,49 @@ async function runEslint(targetPathArg) {
|
|
105
165
|
console.log(`检查目录: ${eslintTarget}`);
|
106
166
|
}
|
107
167
|
|
108
|
-
|
109
|
-
|
110
|
-
'
|
111
|
-
|
112
|
-
|
113
|
-
cwd: rootDir,
|
114
|
-
stdio: 'inherit',
|
115
|
-
shell: true,
|
116
|
-
},
|
117
|
-
);
|
168
|
+
const allFiles = glob.sync('**/*.{js,jsx,ts,tsx}', { cwd: eslintTarget, absolute: true });
|
169
|
+
if (allFiles.length === 0) {
|
170
|
+
console.log('没有需要检查的文件');
|
171
|
+
return;
|
172
|
+
}
|
118
173
|
|
119
|
-
|
120
|
-
|
174
|
+
// 多进程拆分
|
175
|
+
const chunkSize = Math.max(1, Math.ceil(allFiles.length / maxWorkers)); // 最少一个文件
|
176
|
+
const chunks = [];
|
177
|
+
for (let i = 0; i < allFiles.length; i += chunkSize) {
|
178
|
+
chunks.push(allFiles.slice(i, i + chunkSize));
|
179
|
+
}
|
180
|
+
|
181
|
+
let finished = 0;
|
182
|
+
let hasError = false;
|
183
|
+
|
184
|
+
// 并行 ESLint
|
185
|
+
console.log(`[ESLint 执行]`);
|
186
|
+
console.log(`- 共计文件: ${allFiles.length}`);
|
187
|
+
console.log(`- 拆分任务: ${chunks.length} 个`);
|
188
|
+
console.log('');
|
189
|
+
console.log('🚀 开始并行执行 ESLint ...\n');
|
190
|
+
|
191
|
+
chunks.forEach((chunk) => {
|
192
|
+
const eslint = spawn(
|
193
|
+
'npx',
|
194
|
+
['eslint', ...chunk, '--ext', 'ts,tsx,js,jsx', '--report-unused-disable-directives'],
|
195
|
+
{
|
196
|
+
cwd: rootDir,
|
197
|
+
stdio: 'inherit',
|
198
|
+
shell: true,
|
199
|
+
},
|
200
|
+
);
|
201
|
+
|
202
|
+
eslint.on('close', (code) => {
|
203
|
+
if (code !== 0 && code !== null) {
|
204
|
+
hasError = true;
|
205
|
+
}
|
206
|
+
finished++;
|
207
|
+
if (finished === chunks.length) {
|
208
|
+
process.exit(hasError ? 1 : 0);
|
209
|
+
}
|
210
|
+
});
|
121
211
|
});
|
122
212
|
} catch (err) {
|
123
213
|
console.error('脚本执行出错:', err);
|
@@ -0,0 +1,137 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
let spawnSync;
|
4
|
+
let spawn;
|
5
|
+
let path;
|
6
|
+
let fs;
|
7
|
+
|
8
|
+
async function runStylelint(targetPathArg) {
|
9
|
+
try {
|
10
|
+
if (typeof require !== 'undefined') {
|
11
|
+
// CommonJS
|
12
|
+
({ spawnSync, spawn } = require('child_process'));
|
13
|
+
path = require('path');
|
14
|
+
fs = require('fs');
|
15
|
+
} else {
|
16
|
+
// ESM
|
17
|
+
({ spawnSync, spawn } = await import('node:child_process'));
|
18
|
+
path = await import('node:path');
|
19
|
+
fs = await import('node:fs');
|
20
|
+
}
|
21
|
+
|
22
|
+
const targetPath = targetPathArg || process.cwd();
|
23
|
+
let rootDir = path.resolve(targetPath);
|
24
|
+
|
25
|
+
// 如果传的是单个目录名且路径不存在,则在 packages/ 下查找
|
26
|
+
if (!fs.existsSync(rootDir) && targetPath !== process.cwd()) {
|
27
|
+
const baseDir = process.cwd(); // 当前项目根目录
|
28
|
+
const fullPath = path.join(baseDir, 'packages', targetPath);
|
29
|
+
if (fs.existsSync(fullPath)) {
|
30
|
+
rootDir = fullPath;
|
31
|
+
} else {
|
32
|
+
console.error(`找不到目录: packages/${targetPath}`);
|
33
|
+
process.exit(1);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
console.log('目标路径:', rootDir);
|
38
|
+
|
39
|
+
const gitRootResult = spawnSync('git', ['rev-parse', '--show-toplevel'], {
|
40
|
+
cwd: rootDir,
|
41
|
+
encoding: 'utf-8',
|
42
|
+
shell: true,
|
43
|
+
});
|
44
|
+
|
45
|
+
if (gitRootResult.status !== 0 || !gitRootResult.stdout) {
|
46
|
+
console.error('无法获取 Git 根目录,请确保路径在 Git 仓库内');
|
47
|
+
process.exit(1);
|
48
|
+
}
|
49
|
+
|
50
|
+
const gitRoot = gitRootResult.stdout.trim();
|
51
|
+
console.log('Git 根目录:', gitRoot);
|
52
|
+
|
53
|
+
let targetBranch = 'master';
|
54
|
+
if (targetPath !== process.cwd()) {
|
55
|
+
const lastDir = path.basename(rootDir);
|
56
|
+
targetBranch = `master-${lastDir.split('-').pop()}`;
|
57
|
+
}
|
58
|
+
console.log('目标分支:', targetBranch);
|
59
|
+
|
60
|
+
// 获取当前分支
|
61
|
+
const currentBranchResult = spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
62
|
+
cwd: gitRoot,
|
63
|
+
encoding: 'utf-8',
|
64
|
+
shell: true,
|
65
|
+
});
|
66
|
+
|
67
|
+
if (currentBranchResult.status !== 0 || !currentBranchResult.stdout) {
|
68
|
+
console.error('无法获取当前 Git 分支');
|
69
|
+
process.exit(1);
|
70
|
+
}
|
71
|
+
|
72
|
+
const currentBranch = currentBranchResult.stdout.trim();
|
73
|
+
console.log('当前分支:', currentBranch);
|
74
|
+
|
75
|
+
// 切换分支并拉取最新代码
|
76
|
+
if (currentBranch !== targetBranch) {
|
77
|
+
console.log(`切换到分支 ${targetBranch} ...`);
|
78
|
+
const checkout = spawnSync('git', ['checkout', targetBranch], {
|
79
|
+
cwd: gitRoot,
|
80
|
+
stdio: 'inherit',
|
81
|
+
shell: true,
|
82
|
+
});
|
83
|
+
if (checkout.status !== 0) {
|
84
|
+
console.error(`切换分支失败`);
|
85
|
+
process.exit(1);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
console.log('拉取最新代码...');
|
90
|
+
const pull = spawnSync('git', ['pull'], {
|
91
|
+
cwd: gitRoot,
|
92
|
+
stdio: 'inherit',
|
93
|
+
shell: true,
|
94
|
+
});
|
95
|
+
if (pull.status !== 0) {
|
96
|
+
console.error('git pull 失败');
|
97
|
+
process.exit(1);
|
98
|
+
}
|
99
|
+
|
100
|
+
const srcPath = path.join(rootDir, 'src');
|
101
|
+
const stylelintTarget = fs.existsSync(srcPath)
|
102
|
+
? `${srcPath}/**/*.{css,scss,less}`
|
103
|
+
: './**/*.{css,scss,less}';
|
104
|
+
|
105
|
+
if (!fs.existsSync(srcPath)) {
|
106
|
+
console.warn(`src 文件夹不存在,改为检查当前目录下样式文件: ${stylelintTarget}`);
|
107
|
+
} else {
|
108
|
+
console.log(`检查目录样式文件: ${stylelintTarget}`);
|
109
|
+
}
|
110
|
+
|
111
|
+
console.log('执行 Stylelint...');
|
112
|
+
const stylelint = spawn(
|
113
|
+
'npx',
|
114
|
+
[
|
115
|
+
'stylelint',
|
116
|
+
stylelintTarget,
|
117
|
+
'--allow-empty-input',
|
118
|
+
'--report-needless-disables',
|
119
|
+
'--report-invalid-scope-disables',
|
120
|
+
],
|
121
|
+
{
|
122
|
+
cwd: rootDir,
|
123
|
+
stdio: 'inherit',
|
124
|
+
shell: true,
|
125
|
+
},
|
126
|
+
);
|
127
|
+
|
128
|
+
stylelint.on('close', (code) => {
|
129
|
+
process.exit(code);
|
130
|
+
});
|
131
|
+
} catch (err) {
|
132
|
+
console.error('脚本执行出错:', err);
|
133
|
+
process.exit(1);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
module.exports = runStylelint;
|