@infly/libs 2.0.53 → 2.1.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.
@@ -1,254 +1,254 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
- const { checkAndUpdatePackages } = require("../../script/git-automation");
4
- const { gitOutput, findGitRepo, getGitCommonDir } = require("../../script/git-automation/git-utils");
5
- const { run } = require("./command");
6
-
7
- function getTargetBranch(rootPackageJson, mode) {
8
- const branchMap = rootPackageJson.projectConfig?.buildBranchMap || {};
9
- return branchMap[mode] || (mode === "prod" ? "master" : "develop");
10
- }
11
-
12
- function hasPackageGitRepos(rootDir) {
13
- const packagesDir = path.join(rootDir, "packages");
14
-
15
- if (!fs.existsSync(packagesDir)) {
16
- return false;
17
- }
18
-
19
- return ["infly-libs", "infly-ui"].some((name) => fs.existsSync(path.join(packagesDir, name, ".git")));
20
- }
21
-
22
- async function updatePackageSources(rootDir) {
23
- console.log("\x1b[32m%s\x1b[0m", "更新 admin-monorepo / packages 源码");
24
-
25
- if (hasPackageGitRepos(rootDir)) {
26
- console.log(" 使用 packages/* 独立 git 仓库模式,拉取 master");
27
- } else {
28
- console.log(" 使用 admin-monorepo 根仓库模式,拉取 master");
29
- }
30
-
31
- global.logColor = global.logColor || {
32
- success: "\n\x1b[32m%s\x1b[0m",
33
- error: "\n\x1b[31m%s\x1b[0m",
34
- warning: "\n\x1b[33m%s\x1b[0m",
35
- link: "\x1b[34m%s\x1b[0m",
36
- info: "\n\x1b[36m%s\x1b[0m"
37
- };
38
-
39
- const packagesDir = path.join(rootDir, "packages");
40
- await checkAndUpdatePackages(fs.existsSync(packagesDir) ? packagesDir : undefined, "master");
41
- }
42
-
43
- function getPackageSourcesKey(rootDir) {
44
- if (!hasPackageGitRepos(rootDir)) {
45
- return getGitCommonDir(rootDir);
46
- }
47
-
48
- return path.join(rootDir, "packages");
49
- }
50
-
51
- function findExistingAncestor(targetDir) {
52
- let current = targetDir;
53
-
54
- while (!fs.existsSync(current)) {
55
- const parent = path.dirname(current);
56
-
57
- if (parent === current) {
58
- return "";
59
- }
60
-
61
- current = parent;
62
- }
63
-
64
- return current;
65
- }
66
-
67
- function getDistRepoInfo(rootDir, pkg, targetBranch, options = {}) {
68
- const packageRoot = path.join(rootDir, pkg.dir);
69
- const vueConfigPath = path.join(packageRoot, "vue.config.js");
70
- const nextConfigJs = path.join(packageRoot, "next.config.js");
71
- const nextConfigMjs = path.join(packageRoot, "next.config.mjs");
72
- const nextConfigTs = path.join(packageRoot, "next.config.ts");
73
- const hasVueConfig = fs.existsSync(vueConfigPath);
74
- const hasNextConfig = !hasVueConfig && (
75
- fs.existsSync(nextConfigJs) ||
76
- fs.existsSync(nextConfigMjs) ||
77
- fs.existsSync(nextConfigTs)
78
- );
79
-
80
- let outputDir = pkg.viteOutputDir;
81
-
82
- if (outputDir) {
83
- // Vite 注册表已经提供经过校验的 dist 根,禁止再执行历史 vue.config.js。
84
- } else if (hasVueConfig) {
85
- outputDir = require(vueConfigPath).outputDir;
86
- } else if (hasNextConfig) {
87
- outputDir = pkg.packageJson.infly?.buildConfigs?.outputPath;
88
- } else {
89
- return null;
90
- }
91
-
92
- if (outputDir && !path.isAbsolute(outputDir)) {
93
- outputDir = path.resolve(packageRoot, outputDir);
94
- }
95
-
96
- if (!outputDir) {
97
- return null;
98
- }
99
-
100
- const existingOutputDir = fs.existsSync(outputDir) ? outputDir : findExistingAncestor(outputDir);
101
-
102
- if (!existingOutputDir) {
103
- return null;
104
- }
105
-
106
- const branchMap = pkg.packageJson.infly?.buildConfigs?.gitAutoPushReposBranchMap || {};
107
- const distBranch = branchMap[targetBranch] || targetBranch;
108
- let repoRoot = existingOutputDir;
109
- let repoKey = existingOutputDir;
110
- const repo = findGitRepo(existingOutputDir);
111
-
112
- if (repo) {
113
- repoRoot = repo.root;
114
- repoKey = repo.commonDir;
115
- } else {
116
- try {
117
- repoRoot = gitOutput(["-C", existingOutputDir, "rev-parse", "--show-toplevel"], rootDir);
118
- repoKey = getGitCommonDir(existingOutputDir);
119
- } catch (error) {
120
- if (!options.allowPathFallback) {
121
- throw error;
122
- }
123
- }
124
- }
125
-
126
- return {
127
- cwd: repoRoot,
128
- branch: distBranch,
129
- key: repoKey,
130
- label: `dist(${path.relative(rootDir, repoRoot)})`
131
- };
132
- }
133
-
134
- function getDistRepoTasks(rootDir, packages, targetBranch, options = {}) {
135
- const repos = new Map();
136
-
137
- packages.forEach((pkg) => {
138
- const repo = getDistRepoInfo(rootDir, pkg, targetBranch, options);
139
-
140
- if (repo && !repos.has(repo.key)) {
141
- repos.set(repo.key, {
142
- cwd: repo.cwd,
143
- branch: repo.branch,
144
- key: repo.key,
145
- label: repo.label
146
- });
147
- }
148
- });
149
-
150
- return Array.from(repos.values());
151
- }
152
-
153
- async function pullGitRepo(task) {
154
- console.log("\x1b[32m%s\x1b[0m", `更新 ${task.label} -> ${task.branch}`);
155
- const status = gitOutput(["status", "--porcelain"], task.cwd);
156
-
157
- if (status) {
158
- throw new Error(`${task.label} 存在未提交的更改,无法自动切换并拉取 ${task.branch}\n${status}`);
159
- }
160
-
161
- await run("git", ["checkout", task.branch], { cwd: task.cwd });
162
- await run("git", ["pull", "origin", task.branch], { cwd: task.cwd });
163
- }
164
-
165
- function getAppAndDistSourceTasks(rootDir, packages, targetBranch) {
166
- const appTasks = packages.map((pkg) => {
167
- const cwd = path.join(rootDir, pkg.dir);
168
-
169
- return {
170
- cwd,
171
- branch: targetBranch,
172
- label: pkg.name,
173
- key: getGitCommonDir(cwd),
174
- run: pullGitRepo
175
- };
176
- });
177
- const distTasks = getDistRepoTasks(rootDir, packages, targetBranch).map((task) => ({
178
- ...task,
179
- run: pullGitRepo
180
- }));
181
-
182
- return [...appTasks, ...distTasks];
183
- }
184
-
185
- async function runSourceTasksWithOverlapCheck(tasks) {
186
- const groups = new Map();
187
-
188
- tasks.forEach((task) => {
189
- const key = task.key || task.cwd || task.label;
190
-
191
- if (!groups.has(key)) {
192
- groups.set(key, []);
193
- }
194
-
195
- groups.get(key).push(task);
196
- });
197
-
198
- await Promise.all(
199
- Array.from(groups.values()).map(async (group) => {
200
- for (const task of group) {
201
- await task.run(task);
202
- }
203
- })
204
- );
205
- }
206
-
207
- async function updateAppAndDistSources(rootDir, packages, targetBranch) {
208
- const tasks = getAppAndDistSourceTasks(rootDir, packages, targetBranch);
209
-
210
- console.log("\x1b[32m%s\x1b[0m", "并行更新 app / dist 源码");
211
-
212
- await runSourceTasksWithOverlapCheck(tasks);
213
- }
214
-
215
- async function updateAllSources(rootDir, packages, targetBranch) {
216
- const tasks = [
217
- {
218
- label: "admin-monorepo/packages",
219
- key: getPackageSourcesKey(rootDir),
220
- run: () => updatePackageSources(rootDir)
221
- },
222
- ...getAppAndDistSourceTasks(rootDir, packages, targetBranch)
223
- ];
224
-
225
- await runSourceTasksWithOverlapCheck(tasks);
226
- }
227
-
228
- function printDryRunSourceUpdatePlan(rootDir, packages, targetBranch) {
229
- console.log("并行拉取:");
230
- console.log(" 1. admin-monorepo/packages -> master");
231
- packages.forEach((pkg, index) => {
232
- console.log(` ${index + 2}. ${pkg.name} -> ${targetBranch} (${pkg.dir})`);
233
- });
234
-
235
- const distTasks = getDistRepoTasks(rootDir, packages, targetBranch, { allowPathFallback: true });
236
-
237
- if (distTasks.length === 0) {
238
- console.log(` ${packages.length + 2}. dist 仓库 -> 未解析到可拉取仓库`);
239
- return;
240
- }
241
-
242
- distTasks.forEach((task, index) => {
243
- console.log(` ${packages.length + 2 + index}. ${task.label} -> ${task.branch} (${path.relative(rootDir, task.cwd)})`);
244
- });
245
- }
246
-
247
- module.exports = {
248
- getTargetBranch,
249
- updatePackageSources,
250
- updateAppAndDistSources,
251
- updateAllSources,
252
- getDistRepoTasks,
253
- printDryRunSourceUpdatePlan
254
- };
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const { checkAndUpdatePackages } = require("../../script/git-automation");
4
+ const { gitOutput, findGitRepo, getGitCommonDir } = require("../../script/git-automation/git-utils");
5
+ const { run } = require("./command");
6
+
7
+ function getTargetBranch(rootPackageJson, mode) {
8
+ const branchMap = rootPackageJson.projectConfig?.buildBranchMap || {};
9
+ return branchMap[mode] || (mode === "prod" ? "master" : "develop");
10
+ }
11
+
12
+ function hasPackageGitRepos(rootDir) {
13
+ const packagesDir = path.join(rootDir, "packages");
14
+
15
+ if (!fs.existsSync(packagesDir)) {
16
+ return false;
17
+ }
18
+
19
+ return ["infly-libs", "infly-ui"].some((name) => fs.existsSync(path.join(packagesDir, name, ".git")));
20
+ }
21
+
22
+ async function updatePackageSources(rootDir) {
23
+ console.log("\x1b[32m%s\x1b[0m", "更新 admin-monorepo / packages 源码");
24
+
25
+ if (hasPackageGitRepos(rootDir)) {
26
+ console.log(" 使用 packages/* 独立 git 仓库模式,拉取 master");
27
+ } else {
28
+ console.log(" 使用 admin-monorepo 根仓库模式,拉取 master");
29
+ }
30
+
31
+ global.logColor = global.logColor || {
32
+ success: "\n\x1b[32m%s\x1b[0m",
33
+ error: "\n\x1b[31m%s\x1b[0m",
34
+ warning: "\n\x1b[33m%s\x1b[0m",
35
+ link: "\x1b[34m%s\x1b[0m",
36
+ info: "\n\x1b[36m%s\x1b[0m"
37
+ };
38
+
39
+ const packagesDir = path.join(rootDir, "packages");
40
+ await checkAndUpdatePackages(fs.existsSync(packagesDir) ? packagesDir : undefined, "master");
41
+ }
42
+
43
+ function getPackageSourcesKey(rootDir) {
44
+ if (!hasPackageGitRepos(rootDir)) {
45
+ return getGitCommonDir(rootDir);
46
+ }
47
+
48
+ return path.join(rootDir, "packages");
49
+ }
50
+
51
+ function findExistingAncestor(targetDir) {
52
+ let current = targetDir;
53
+
54
+ while (!fs.existsSync(current)) {
55
+ const parent = path.dirname(current);
56
+
57
+ if (parent === current) {
58
+ return "";
59
+ }
60
+
61
+ current = parent;
62
+ }
63
+
64
+ return current;
65
+ }
66
+
67
+ function getDistRepoInfo(rootDir, pkg, targetBranch, options = {}) {
68
+ const packageRoot = path.join(rootDir, pkg.dir);
69
+ const vueConfigPath = path.join(packageRoot, "vue.config.js");
70
+ const nextConfigJs = path.join(packageRoot, "next.config.js");
71
+ const nextConfigMjs = path.join(packageRoot, "next.config.mjs");
72
+ const nextConfigTs = path.join(packageRoot, "next.config.ts");
73
+ const hasVueConfig = fs.existsSync(vueConfigPath);
74
+ const hasNextConfig = !hasVueConfig && (
75
+ fs.existsSync(nextConfigJs) ||
76
+ fs.existsSync(nextConfigMjs) ||
77
+ fs.existsSync(nextConfigTs)
78
+ );
79
+
80
+ let outputDir = pkg.viteOutputDir;
81
+
82
+ if (outputDir) {
83
+ // Vite 注册表已经提供经过校验的 dist 根,禁止再执行历史 vue.config.js。
84
+ } else if (hasVueConfig) {
85
+ outputDir = require(vueConfigPath).outputDir;
86
+ } else if (hasNextConfig) {
87
+ outputDir = pkg.packageJson.infly?.buildConfigs?.outputPath;
88
+ } else {
89
+ return null;
90
+ }
91
+
92
+ if (outputDir && !path.isAbsolute(outputDir)) {
93
+ outputDir = path.resolve(packageRoot, outputDir);
94
+ }
95
+
96
+ if (!outputDir) {
97
+ return null;
98
+ }
99
+
100
+ const existingOutputDir = fs.existsSync(outputDir) ? outputDir : findExistingAncestor(outputDir);
101
+
102
+ if (!existingOutputDir) {
103
+ return null;
104
+ }
105
+
106
+ const branchMap = pkg.packageJson.infly?.buildConfigs?.gitAutoPushReposBranchMap || {};
107
+ const distBranch = branchMap[targetBranch] || targetBranch;
108
+ let repoRoot = existingOutputDir;
109
+ let repoKey = existingOutputDir;
110
+ const repo = findGitRepo(existingOutputDir);
111
+
112
+ if (repo) {
113
+ repoRoot = repo.root;
114
+ repoKey = repo.commonDir;
115
+ } else {
116
+ try {
117
+ repoRoot = gitOutput(["-C", existingOutputDir, "rev-parse", "--show-toplevel"], rootDir);
118
+ repoKey = getGitCommonDir(existingOutputDir);
119
+ } catch (error) {
120
+ if (!options.allowPathFallback) {
121
+ throw error;
122
+ }
123
+ }
124
+ }
125
+
126
+ return {
127
+ cwd: repoRoot,
128
+ branch: distBranch,
129
+ key: repoKey,
130
+ label: `dist(${path.relative(rootDir, repoRoot)})`
131
+ };
132
+ }
133
+
134
+ function getDistRepoTasks(rootDir, packages, targetBranch, options = {}) {
135
+ const repos = new Map();
136
+
137
+ packages.forEach((pkg) => {
138
+ const repo = getDistRepoInfo(rootDir, pkg, targetBranch, options);
139
+
140
+ if (repo && !repos.has(repo.key)) {
141
+ repos.set(repo.key, {
142
+ cwd: repo.cwd,
143
+ branch: repo.branch,
144
+ key: repo.key,
145
+ label: repo.label
146
+ });
147
+ }
148
+ });
149
+
150
+ return Array.from(repos.values());
151
+ }
152
+
153
+ async function pullGitRepo(task) {
154
+ console.log("\x1b[32m%s\x1b[0m", `更新 ${task.label} -> ${task.branch}`);
155
+ const status = gitOutput(["status", "--porcelain"], task.cwd);
156
+
157
+ if (status) {
158
+ throw new Error(`${task.label} 存在未提交的更改,无法自动切换并拉取 ${task.branch}\n${status}`);
159
+ }
160
+
161
+ await run("git", ["checkout", task.branch], { cwd: task.cwd });
162
+ await run("git", ["pull", "origin", task.branch], { cwd: task.cwd });
163
+ }
164
+
165
+ function getAppAndDistSourceTasks(rootDir, packages, targetBranch) {
166
+ const appTasks = packages.map((pkg) => {
167
+ const cwd = path.join(rootDir, pkg.dir);
168
+
169
+ return {
170
+ cwd,
171
+ branch: targetBranch,
172
+ label: pkg.name,
173
+ key: getGitCommonDir(cwd),
174
+ run: pullGitRepo
175
+ };
176
+ });
177
+ const distTasks = getDistRepoTasks(rootDir, packages, targetBranch).map((task) => ({
178
+ ...task,
179
+ run: pullGitRepo
180
+ }));
181
+
182
+ return [...appTasks, ...distTasks];
183
+ }
184
+
185
+ async function runSourceTasksWithOverlapCheck(tasks) {
186
+ const groups = new Map();
187
+
188
+ tasks.forEach((task) => {
189
+ const key = task.key || task.cwd || task.label;
190
+
191
+ if (!groups.has(key)) {
192
+ groups.set(key, []);
193
+ }
194
+
195
+ groups.get(key).push(task);
196
+ });
197
+
198
+ await Promise.all(
199
+ Array.from(groups.values()).map(async (group) => {
200
+ for (const task of group) {
201
+ await task.run(task);
202
+ }
203
+ })
204
+ );
205
+ }
206
+
207
+ async function updateAppAndDistSources(rootDir, packages, targetBranch) {
208
+ const tasks = getAppAndDistSourceTasks(rootDir, packages, targetBranch);
209
+
210
+ console.log("\x1b[32m%s\x1b[0m", "并行更新 app / dist 源码");
211
+
212
+ await runSourceTasksWithOverlapCheck(tasks);
213
+ }
214
+
215
+ async function updateAllSources(rootDir, packages, targetBranch) {
216
+ const tasks = [
217
+ {
218
+ label: "admin-monorepo/packages",
219
+ key: getPackageSourcesKey(rootDir),
220
+ run: () => updatePackageSources(rootDir)
221
+ },
222
+ ...getAppAndDistSourceTasks(rootDir, packages, targetBranch)
223
+ ];
224
+
225
+ await runSourceTasksWithOverlapCheck(tasks);
226
+ }
227
+
228
+ function printDryRunSourceUpdatePlan(rootDir, packages, targetBranch) {
229
+ console.log("并行拉取:");
230
+ console.log(" 1. admin-monorepo/packages -> master");
231
+ packages.forEach((pkg, index) => {
232
+ console.log(` ${index + 2}. ${pkg.name} -> ${targetBranch} (${pkg.dir})`);
233
+ });
234
+
235
+ const distTasks = getDistRepoTasks(rootDir, packages, targetBranch, { allowPathFallback: true });
236
+
237
+ if (distTasks.length === 0) {
238
+ console.log(` ${packages.length + 2}. dist 仓库 -> 未解析到可拉取仓库`);
239
+ return;
240
+ }
241
+
242
+ distTasks.forEach((task, index) => {
243
+ console.log(` ${packages.length + 2 + index}. ${task.label} -> ${task.branch} (${path.relative(rootDir, task.cwd)})`);
244
+ });
245
+ }
246
+
247
+ module.exports = {
248
+ getTargetBranch,
249
+ updatePackageSources,
250
+ updateAppAndDistSources,
251
+ updateAllSources,
252
+ getDistRepoTasks,
253
+ printDryRunSourceUpdatePlan
254
+ };
@@ -1,78 +1,78 @@
1
- const path = require("path");
2
- const { spawn } = require("child_process");
3
- const { spawnBackground } = require("./command");
4
- const { createBuildContext } = require("./env");
5
-
6
- function killPreviewChild(child) {
7
- if (!child || child.killed) {
8
- return;
9
- }
10
-
11
- if (process.platform === "win32") {
12
- spawn("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
13
- stdio: "ignore",
14
- windowsHide: true
15
- });
16
- return;
17
- }
18
-
19
- child.kill();
20
- }
21
-
22
- function startBatchPreviews(rootDir, packages) {
23
- const previewPackages = packages.filter((pkg) => {
24
- return pkg.packageJson.infly?.buildConfigs?.enablePreview !== false;
25
- });
26
-
27
- if (previewPackages.length === 0) {
28
- return;
29
- }
30
-
31
- console.log("\n\x1b[32m%s\x1b[0m", "\x1b[42m\x1b[30m DONE \x1b[0m\x1b[32m 项目构建预览,CTRL + C 结束:");
32
-
33
- const children = previewPackages.map((pkg) => {
34
- const child = spawnBackground("infly-libs", ["preview", "--no-build"], {
35
- cwd: path.join(rootDir, pkg.dir),
36
- env: createBuildContext({
37
- batchPreview: true,
38
- outputDir: pkg.targetOutputDir || undefined,
39
- target: pkg.targetKey || undefined,
40
- targetLabel: pkg.targetLabel || undefined,
41
- })
42
- });
43
-
44
- // console.log(`preview ${pkg.name}: pid ${child.pid}`);
45
-
46
- child.on("close", (code, signal) => {
47
- if (code === 0 || signal) {
48
- return;
49
- }
50
-
51
- console.log(`preview ${pkg.name} 已退出,code=${code}`);
52
- });
53
-
54
- child.on("error", (error) => {
55
- console.error(`preview ${pkg.name} 启动失败:${error.message}`);
56
- });
57
-
58
- return child;
59
- });
60
-
61
- const stop = () => {
62
- children.forEach(killPreviewChild);
63
- };
64
-
65
- process.on("SIGINT", () => {
66
- stop();
67
- process.exit(0);
68
- });
69
-
70
- process.on("SIGTERM", () => {
71
- stop();
72
- process.exit(0);
73
- });
74
- }
75
-
76
- module.exports = {
77
- startBatchPreviews
78
- };
1
+ const path = require("path");
2
+ const { spawn } = require("child_process");
3
+ const { spawnBackground } = require("./command");
4
+ const { createBuildContext } = require("./env");
5
+
6
+ function killPreviewChild(child) {
7
+ if (!child || child.killed) {
8
+ return;
9
+ }
10
+
11
+ if (process.platform === "win32") {
12
+ spawn("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
13
+ stdio: "ignore",
14
+ windowsHide: true
15
+ });
16
+ return;
17
+ }
18
+
19
+ child.kill();
20
+ }
21
+
22
+ function startBatchPreviews(rootDir, packages) {
23
+ const previewPackages = packages.filter((pkg) => {
24
+ return pkg.packageJson.infly?.buildConfigs?.enablePreview !== false;
25
+ });
26
+
27
+ if (previewPackages.length === 0) {
28
+ return;
29
+ }
30
+
31
+ console.log("\n\x1b[32m%s\x1b[0m", "\x1b[42m\x1b[30m DONE \x1b[0m\x1b[32m 项目构建预览,CTRL + C 结束:");
32
+
33
+ const children = previewPackages.map((pkg) => {
34
+ const child = spawnBackground("infly-libs", ["preview", "--no-build"], {
35
+ cwd: path.join(rootDir, pkg.dir),
36
+ env: createBuildContext({
37
+ batchPreview: true,
38
+ outputDir: pkg.targetOutputDir || undefined,
39
+ target: pkg.targetKey || undefined,
40
+ targetLabel: pkg.targetLabel || undefined,
41
+ })
42
+ });
43
+
44
+ // console.log(`preview ${pkg.name}: pid ${child.pid}`);
45
+
46
+ child.on("close", (code, signal) => {
47
+ if (code === 0 || signal) {
48
+ return;
49
+ }
50
+
51
+ console.log(`preview ${pkg.name} 已退出,code=${code}`);
52
+ });
53
+
54
+ child.on("error", (error) => {
55
+ console.error(`preview ${pkg.name} 启动失败:${error.message}`);
56
+ });
57
+
58
+ return child;
59
+ });
60
+
61
+ const stop = () => {
62
+ children.forEach(killPreviewChild);
63
+ };
64
+
65
+ process.on("SIGINT", () => {
66
+ stop();
67
+ process.exit(0);
68
+ });
69
+
70
+ process.on("SIGTERM", () => {
71
+ stop();
72
+ process.exit(0);
73
+ });
74
+ }
75
+
76
+ module.exports = {
77
+ startBatchPreviews
78
+ };