@openyida/yidacli 0.1.4 → 0.1.6
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/bin/yidacli.js +8 -0
- package/dist/copy.js +6 -0
- package/package.json +1 -3
- package/scripts/build.js +0 -93
- package/scripts/postinstall.js +0 -126
- package/scripts/prepublish.js +0 -162
package/bin/yidacli.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* 命令列表:
|
|
6
6
|
* yidacli env 检测当前 AI 工具环境和登录态
|
|
7
|
+
* yidacli copy [--force] 复制 openyida 工作目录到当前 AI 工具环境
|
|
7
8
|
* yidacli login 登录态管理
|
|
8
9
|
* yidacli logout 退出登录
|
|
9
10
|
* yidacli create-app "<名称>" [desc] [icon] [color] 创建应用
|
|
@@ -38,6 +39,7 @@ yidacli - 宜搭命令行工具
|
|
|
38
39
|
|
|
39
40
|
命令:
|
|
40
41
|
env 检测当前 AI 工具环境和登录态
|
|
42
|
+
copy [--force] 复制 openyida 工作目录到当前 AI 工具环境
|
|
41
43
|
login 登录态管理(优先缓存,否则扫码)
|
|
42
44
|
logout 退出登录 / 切换账号
|
|
43
45
|
create-app "<名称>" [描述] [图标] [颜色] 创建应用,输出 appType
|
|
@@ -85,6 +87,12 @@ async function main() {
|
|
|
85
87
|
break;
|
|
86
88
|
}
|
|
87
89
|
|
|
90
|
+
case 'copy': {
|
|
91
|
+
const { run } = require('../dist/copy');
|
|
92
|
+
run();
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
|
|
88
96
|
case 'login': {
|
|
89
97
|
const { ensureLogin, checkLoginOnly } = require('../dist/login');
|
|
90
98
|
if (args[0] === '--check-only') {
|
package/dist/copy.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
let fs=require("fs"),path=require("path"),os=require("os"),detectEnvironment=require("./env").detectEnvironment;function findPackageOpenyidaDir(){try{var o=require.resolve("@openyida/yidacli/package.json"),e=path.dirname(o),r=path.join(e,"openyida");return fs.existsSync(r)?r:null}catch{return null}}function mergeCopyDir(o,e){if(!fs.existsSync(o))return 0;var r;fs.mkdirSync(e,{recursive:!0});let n=0;for(r of fs.readdirSync(o,{withFileTypes:!0})){var i=path.join(o,r.name),l=path.join(e,r.name);r.isDirectory()?n+=mergeCopyDir(i,l):(fs.copyFileSync(i,l),console.log(" 覆盖: "+l),n++)}return n}function run(){var l="=".repeat(55);console.log(l),console.log(" yidacli copy - 初始化 openyida 工作目录"),console.log(l);var c=process.argv.slice(3).includes("--force"),s=findPackageOpenyidaDir();if(s||(console.error("\n❌ 未找到 npm 包内的 openyida/ 目录"),console.error(" 请确认 @openyida/yidacli 已正确全局安装:"),console.error(" npm install -g @openyida/yidacli"),process.exit(1)),console.log(`
|
|
2
|
+
📦 源目录: `+s),c){let o=path.join(process.cwd(),"openyida"),e=(console.log("⚠️ --force 模式:强制复制到当前目录"),console.log(`📁 目标目录: ${o}
|
|
3
|
+
`),mergeCopyDir(s,o));console.log(`
|
|
4
|
+
`+l),console.log(`✅ 完成!共复制/更新 ${e} 个文件`),console.log(" 目标目录: "+o),void console.log(l)}else{let{activeToolName:e,activeProjectRoot:o,results:r}=detectEnvironment();c=r.find(o=>o.displayName===e);let n,i=(c&&".real"===c.dirName?n=o||path.join(os.homedir(),".real","workspace","openyida"):e?n=path.join(process.cwd(),"openyida"):(console.error("\n❌ 未检测到活跃的 AI 工具环境"),console.error(" 支持的工具:悟空、OpenCode、Claude Code、Aone Copilot、Cursor、Qoder、iFlow"),console.error("\n 当前检测结果:"),r.forEach(o=>{console.error(` ${o.isActive?"✅":"⬜"} `+o.displayName)}),console.error("\n 如需强制复制到当前目录,请运行:"),console.error(" yidacli copy --force"),process.exit(1)),console.log("🤖 当前 AI 工具: "+e),console.log(`📁 目标目录: ${n}
|
|
5
|
+
`),mergeCopyDir(s,n));console.log(`
|
|
6
|
+
`+l),console.log(`✅ 完成!共复制/更新 ${i} 个文件`),console.log(" 目标目录: "+n),console.log(l)}}module.exports={run:run};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openyida/yidacli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "宜搭 CLI 工具 - 宜搭平台应用、页面、表单的命令行管理工具",
|
|
5
5
|
"main": "bin/yidacli.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,14 +9,12 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"bin",
|
|
11
11
|
"dist",
|
|
12
|
-
"scripts",
|
|
13
12
|
"openyida"
|
|
14
13
|
],
|
|
15
14
|
"scripts": {
|
|
16
15
|
"build": "node scripts/build.js",
|
|
17
16
|
"prepublishOnly": "node scripts/build.js && node scripts/prepublish.js",
|
|
18
17
|
"postpublish": "node scripts/prepublish.js --cleanup",
|
|
19
|
-
"postinstall": "playwright install chromium && node scripts/postinstall.js",
|
|
20
18
|
"release": "npm version patch && npm publish",
|
|
21
19
|
"test": "jest --config tests/jest.config.js",
|
|
22
20
|
"test:unit": "jest --config tests/jest.config.js tests/unit",
|
package/scripts/build.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* build.js - 构建脚本
|
|
4
|
-
*
|
|
5
|
-
* 将 src/ 目录下所有 JS 文件用 UglifyJS 压缩后输出到 dist/,
|
|
6
|
-
* 保持原有目录结构。
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
"use strict";
|
|
10
|
-
|
|
11
|
-
const fs = require("fs");
|
|
12
|
-
const path = require("path");
|
|
13
|
-
const UglifyJS = require("uglify-js");
|
|
14
|
-
|
|
15
|
-
const YIDA_CLI_DIR = path.resolve(__dirname, "..");
|
|
16
|
-
const SRC_DIR = path.resolve(YIDA_CLI_DIR, "src");
|
|
17
|
-
const DIST_DIR = path.resolve(YIDA_CLI_DIR, "dist");
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* 递归收集目录下所有 .js 文件
|
|
21
|
-
*/
|
|
22
|
-
function collectJsFiles(dir, baseDir) {
|
|
23
|
-
const results = [];
|
|
24
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
25
|
-
const fullPath = path.join(dir, entry.name);
|
|
26
|
-
if (entry.isDirectory()) {
|
|
27
|
-
results.push(...collectJsFiles(fullPath, baseDir));
|
|
28
|
-
} else if (entry.name.endsWith(".js")) {
|
|
29
|
-
results.push(fullPath);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return results;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function main() {
|
|
36
|
-
console.log("=".repeat(50));
|
|
37
|
-
console.log(" build - 构建 yida-cli(uglify src/ → dist/)");
|
|
38
|
-
console.log("=".repeat(50));
|
|
39
|
-
|
|
40
|
-
// 清空并重建 dist 目录
|
|
41
|
-
if (fs.existsSync(DIST_DIR)) {
|
|
42
|
-
fs.rmSync(DIST_DIR, { recursive: true, force: true });
|
|
43
|
-
console.log("\n 🗑️ 已清空旧的 dist/ 目录");
|
|
44
|
-
}
|
|
45
|
-
fs.mkdirSync(DIST_DIR, { recursive: true });
|
|
46
|
-
|
|
47
|
-
const jsFiles = collectJsFiles(SRC_DIR, SRC_DIR);
|
|
48
|
-
console.log(`\n 📦 共发现 ${jsFiles.length} 个源文件,开始压缩...\n`);
|
|
49
|
-
|
|
50
|
-
let successCount = 0;
|
|
51
|
-
let errorCount = 0;
|
|
52
|
-
|
|
53
|
-
for (const srcFile of jsFiles) {
|
|
54
|
-
const relativePath = path.relative(SRC_DIR, srcFile);
|
|
55
|
-
const distFile = path.join(DIST_DIR, relativePath);
|
|
56
|
-
|
|
57
|
-
// 确保目标目录存在
|
|
58
|
-
fs.mkdirSync(path.dirname(distFile), { recursive: true });
|
|
59
|
-
|
|
60
|
-
const sourceCode = fs.readFileSync(srcFile, "utf-8");
|
|
61
|
-
const result = UglifyJS.minify(sourceCode, {
|
|
62
|
-
// 保留 require 调用,不做模块打包
|
|
63
|
-
compress: { passes: 1 },
|
|
64
|
-
mangle: true,
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
if (result.error) {
|
|
68
|
-
console.error(` ❌ 压缩失败: ${relativePath}`);
|
|
69
|
-
console.error(` ${result.error.message}`);
|
|
70
|
-
errorCount++;
|
|
71
|
-
// 压缩失败时原样复制,保证可用性
|
|
72
|
-
fs.copyFileSync(srcFile, distFile);
|
|
73
|
-
} else {
|
|
74
|
-
fs.writeFileSync(distFile, result.code, "utf-8");
|
|
75
|
-
console.log(` ✅ ${relativePath}`);
|
|
76
|
-
successCount++;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
console.log("\n" + "=".repeat(50));
|
|
81
|
-
if (errorCount === 0) {
|
|
82
|
-
console.log(`✅ 构建完成,共压缩 ${successCount} 个文件`);
|
|
83
|
-
} else {
|
|
84
|
-
console.log(`⚠️ 构建完成,${successCount} 个成功,${errorCount} 个失败(已原样复制)`);
|
|
85
|
-
}
|
|
86
|
-
console.log("=".repeat(50));
|
|
87
|
-
|
|
88
|
-
if (errorCount > 0) {
|
|
89
|
-
process.exit(1);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
main();
|
package/scripts/postinstall.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* postinstall.js - npm 安装后钩子
|
|
4
|
-
*
|
|
5
|
-
* 检测当前运行的 AI 工具环境,将 npm 包内的 openyida/ 目录
|
|
6
|
-
* 合并复制到对应目标目录下。
|
|
7
|
-
*
|
|
8
|
-
* 复制目标策略:
|
|
9
|
-
* - 悟空(Wukong):复制到 ~/.real/workspace/openyida(专属 workspace)
|
|
10
|
-
* - 其他 AI 工具:复制到当前工程目录(process.cwd())下的 openyida/
|
|
11
|
-
*
|
|
12
|
-
* 文件覆盖策略:
|
|
13
|
-
* - 已存在的文件:强制覆盖(更新到最新版本)
|
|
14
|
-
* - 目标目录中已有但源目录没有的文件:保留(不删除用户数据)
|
|
15
|
-
*
|
|
16
|
-
* AI 工具检测逻辑复用 dist/env.js 的 detectEnvironment,
|
|
17
|
-
* 避免与 src/env.js 中的 TOOL_DETECTORS 产生重复维护的风险。
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
"use strict";
|
|
21
|
-
|
|
22
|
-
const fs = require("fs");
|
|
23
|
-
const path = require("path");
|
|
24
|
-
const os = require("os");
|
|
25
|
-
|
|
26
|
-
// npm 包内的 openyida 目录(由 prepublish 脚本拷贝进来)
|
|
27
|
-
const PACKAGE_OPENYIDA_DIR = path.resolve(__dirname, "..", "openyida");
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* 检测所有活跃的 AI 工具,返回其目标 openyida 目录列表。
|
|
31
|
-
*
|
|
32
|
-
* 复制策略:
|
|
33
|
-
* - 悟空(Wukong):复制到 ~/.real/workspace/openyida(专属 workspace)
|
|
34
|
-
* - 其他 AI 工具:复制到当前工程目录(process.cwd())下的 openyida/
|
|
35
|
-
*
|
|
36
|
-
* 复用 dist/env.js 的 detectEnvironment,避免重复维护 TOOL_DETECTORS。
|
|
37
|
-
*/
|
|
38
|
-
function detectActiveWorkspaces() {
|
|
39
|
-
// dist/env.js 由 prepublishOnly 构建产生,随 npm 包一起发布
|
|
40
|
-
const { detectEnvironment } = require("../dist/env");
|
|
41
|
-
const { results } = detectEnvironment();
|
|
42
|
-
|
|
43
|
-
const cwd = process.cwd();
|
|
44
|
-
|
|
45
|
-
return results
|
|
46
|
-
.filter((entry) => entry.isActive)
|
|
47
|
-
.map(({ displayName, dirName, workspaceRoot }) => {
|
|
48
|
-
const isWukong = dirName === ".real";
|
|
49
|
-
if (isWukong) {
|
|
50
|
-
// 悟空:使用专属 workspace 路径(workspaceRoot 已是 ~/.real/workspace/openyida)
|
|
51
|
-
return { displayName, destOpenyidaDir: workspaceRoot };
|
|
52
|
-
} else {
|
|
53
|
-
// 其他 AI 工具:复制到当前工程目录下的 openyida/
|
|
54
|
-
return { displayName, destOpenyidaDir: path.join(cwd, "openyida") };
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* 合并复制目录:
|
|
61
|
-
* - 源目录中的文件 → 强制覆盖到目标目录
|
|
62
|
-
* - 目标目录中已有但源目录没有的文件 → 保留不动
|
|
63
|
-
*/
|
|
64
|
-
function mergeCopyDir(sourceDir, destDir) {
|
|
65
|
-
if (!fs.existsSync(sourceDir)) return 0;
|
|
66
|
-
|
|
67
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
68
|
-
|
|
69
|
-
const entries = fs.readdirSync(sourceDir, { withFileTypes: true });
|
|
70
|
-
let copiedCount = 0;
|
|
71
|
-
|
|
72
|
-
for (const entry of entries) {
|
|
73
|
-
const sourcePath = path.join(sourceDir, entry.name);
|
|
74
|
-
const destPath = path.join(destDir, entry.name);
|
|
75
|
-
|
|
76
|
-
if (entry.isDirectory()) {
|
|
77
|
-
copiedCount += mergeCopyDir(sourcePath, destPath);
|
|
78
|
-
} else {
|
|
79
|
-
fs.copyFileSync(sourcePath, destPath);
|
|
80
|
-
console.log(` 覆盖: ${path.relative(os.homedir(), destPath)}`);
|
|
81
|
-
copiedCount++;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return copiedCount;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function main() {
|
|
89
|
-
console.log("=".repeat(55));
|
|
90
|
-
console.log(" yidacli postinstall - 初始化 openyida 工作目录");
|
|
91
|
-
console.log("=".repeat(55));
|
|
92
|
-
|
|
93
|
-
// 检查 npm 包内是否有 openyida 目录
|
|
94
|
-
if (!fs.existsSync(PACKAGE_OPENYIDA_DIR)) {
|
|
95
|
-
console.log("\n⚠️ npm 包内未找到 openyida/ 目录,跳过初始化");
|
|
96
|
-
console.log(" (这是正常情况,如需初始化请手动运行 yidacli env)");
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// 检测活跃的 AI 工具
|
|
101
|
-
const activeWorkspaces = detectActiveWorkspaces();
|
|
102
|
-
|
|
103
|
-
if (activeWorkspaces.length === 0) {
|
|
104
|
-
console.log("\n⚠️ 未检测到活跃的 AI 工具环境,跳过初始化");
|
|
105
|
-
console.log(" 支持的工具:悟空、OpenCode、Claude Code、Aone Copilot、Cursor、Qoder、iFlow");
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
console.log(`\n🤖 检测到 ${activeWorkspaces.length} 个活跃 AI 工具环境\n`);
|
|
110
|
-
|
|
111
|
-
let totalCopied = 0;
|
|
112
|
-
|
|
113
|
-
for (const { displayName, destOpenyidaDir } of activeWorkspaces) {
|
|
114
|
-
console.log(` 📁 ${displayName}`);
|
|
115
|
-
console.log(` 目标: ${destOpenyidaDir}`);
|
|
116
|
-
|
|
117
|
-
const copiedCount = mergeCopyDir(PACKAGE_OPENYIDA_DIR, destOpenyidaDir);
|
|
118
|
-
console.log(` ✅ 完成,共复制/更新 ${copiedCount} 个文件\n`);
|
|
119
|
-
totalCopied += copiedCount;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
console.log(`✅ 初始化完成,共处理 ${totalCopied} 个文件`);
|
|
123
|
-
console.log("=".repeat(55));
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
main();
|
package/scripts/prepublish.js
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* prepublish.js - npm 发布前钩子
|
|
4
|
-
*
|
|
5
|
-
* 将项目根目录的 openyida/ 目录完整拷贝到 yida-cli/openyida/,
|
|
6
|
-
* 使其随 npm 包一起发布,供 postinstall 脚本使用。
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
"use strict";
|
|
10
|
-
|
|
11
|
-
const fs = require("fs");
|
|
12
|
-
const path = require("path");
|
|
13
|
-
|
|
14
|
-
const YIDA_CLI_DIR = path.resolve(__dirname, "..");
|
|
15
|
-
const SOURCE_DIR = path.resolve(YIDA_CLI_DIR, "..", "openyida");
|
|
16
|
-
const DEST_DIR = path.resolve(YIDA_CLI_DIR, "openyida");
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* 递归复制目录(强制覆盖已有文件)
|
|
20
|
-
*/
|
|
21
|
-
function copyDirRecursive(sourceDir, destDir) {
|
|
22
|
-
if (!fs.existsSync(sourceDir)) {
|
|
23
|
-
throw new Error(`源目录不存在: ${sourceDir}`);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
27
|
-
|
|
28
|
-
const entries = fs.readdirSync(sourceDir, { withFileTypes: true });
|
|
29
|
-
let copiedCount = 0;
|
|
30
|
-
|
|
31
|
-
for (const entry of entries) {
|
|
32
|
-
const sourcePath = path.join(sourceDir, entry.name);
|
|
33
|
-
const destPath = path.join(destDir, entry.name);
|
|
34
|
-
|
|
35
|
-
if (entry.isDirectory()) {
|
|
36
|
-
copiedCount += copyDirRecursive(sourcePath, destPath);
|
|
37
|
-
} else {
|
|
38
|
-
fs.copyFileSync(sourcePath, destPath);
|
|
39
|
-
console.log(` 复制: ${path.relative(YIDA_CLI_DIR, destPath)}`);
|
|
40
|
-
copiedCount++;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return copiedCount;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* 递归收集目录下所有文件的相对路径(相对于 baseDir)。
|
|
49
|
-
* @returns {string[]} 排序后的相对路径列表
|
|
50
|
-
*/
|
|
51
|
-
function collectAllRelativePaths(baseDir, currentDir) {
|
|
52
|
-
const dir = currentDir || baseDir;
|
|
53
|
-
const results = [];
|
|
54
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
55
|
-
|
|
56
|
-
for (const entry of entries) {
|
|
57
|
-
const fullPath = path.join(dir, entry.name);
|
|
58
|
-
if (entry.isDirectory()) {
|
|
59
|
-
results.push(...collectAllRelativePaths(baseDir, fullPath));
|
|
60
|
-
} else {
|
|
61
|
-
results.push(path.relative(baseDir, fullPath));
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return results.sort();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* 校验拷贝结果:逐文件对比源目录和目标目录的内容是否完全一致。
|
|
70
|
-
* 有差异则打印详情并抛出错误。
|
|
71
|
-
*/
|
|
72
|
-
function verifyDiff(sourceDir, destDir) {
|
|
73
|
-
const sourcePaths = collectAllRelativePaths(sourceDir);
|
|
74
|
-
const destPaths = collectAllRelativePaths(destDir);
|
|
75
|
-
|
|
76
|
-
const missingInDest = sourcePaths.filter((p) => !destPaths.includes(p));
|
|
77
|
-
const extraInDest = destPaths.filter((p) => !sourcePaths.includes(p));
|
|
78
|
-
const contentMismatches = [];
|
|
79
|
-
|
|
80
|
-
for (const relativePath of sourcePaths) {
|
|
81
|
-
if (missingInDest.includes(relativePath)) continue;
|
|
82
|
-
const sourceContent = fs.readFileSync(path.join(sourceDir, relativePath));
|
|
83
|
-
const destContent = fs.readFileSync(path.join(destDir, relativePath));
|
|
84
|
-
if (!sourceContent.equals(destContent)) {
|
|
85
|
-
contentMismatches.push(relativePath);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const hasErrors = missingInDest.length > 0 || extraInDest.length > 0 || contentMismatches.length > 0;
|
|
90
|
-
|
|
91
|
-
if (!hasErrors) {
|
|
92
|
-
console.log(`\n✅ diff 校验通过,共 ${sourcePaths.length} 个文件内容完全一致`);
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
console.error("\n❌ diff 校验失败,拷贝结果与源目录不一致:");
|
|
97
|
-
|
|
98
|
-
if (missingInDest.length > 0) {
|
|
99
|
-
console.error(`\n 缺失文件(源有,目标无):`);
|
|
100
|
-
missingInDest.forEach((p) => console.error(` - ${p}`));
|
|
101
|
-
}
|
|
102
|
-
if (extraInDest.length > 0) {
|
|
103
|
-
console.error(`\n 多余文件(目标有,源无):`);
|
|
104
|
-
extraInDest.forEach((p) => console.error(` + ${p}`));
|
|
105
|
-
}
|
|
106
|
-
if (contentMismatches.length > 0) {
|
|
107
|
-
console.error(`\n 内容不一致的文件:`);
|
|
108
|
-
contentMismatches.forEach((p) => console.error(` ≠ ${p}`));
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
throw new Error("openyida 拷贝校验失败,请检查上方 diff 详情");
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function cleanup() {
|
|
115
|
-
console.log("=".repeat(50));
|
|
116
|
-
console.log(" postpublish - 清理临时 openyida 目录");
|
|
117
|
-
console.log("=".repeat(50));
|
|
118
|
-
console.log(`\n 目标目录: ${DEST_DIR}\n`);
|
|
119
|
-
|
|
120
|
-
if (fs.existsSync(DEST_DIR)) {
|
|
121
|
-
fs.rmSync(DEST_DIR, { recursive: true, force: true });
|
|
122
|
-
console.log("✅ 已删除临时 openyida/ 目录");
|
|
123
|
-
} else {
|
|
124
|
-
console.log("⚠️ 目录不存在,无需清理");
|
|
125
|
-
}
|
|
126
|
-
console.log("=".repeat(50));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function main() {
|
|
130
|
-
const isCleanup = process.argv.includes("--cleanup");
|
|
131
|
-
|
|
132
|
-
if (isCleanup) {
|
|
133
|
-
cleanup();
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
console.log("=".repeat(50));
|
|
138
|
-
console.log(" prepublish - 拷贝 openyida 到 yida-cli");
|
|
139
|
-
console.log("=".repeat(50));
|
|
140
|
-
console.log(`\n 源目录: ${SOURCE_DIR}`);
|
|
141
|
-
console.log(` 目标目录: ${DEST_DIR}\n`);
|
|
142
|
-
|
|
143
|
-
if (!fs.existsSync(SOURCE_DIR)) {
|
|
144
|
-
console.error(`❌ 源目录不存在: ${SOURCE_DIR}`);
|
|
145
|
-
console.error(" 请确保在项目根目录下存在 openyida/ 目录");
|
|
146
|
-
process.exit(1);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// 清空目标目录(确保不残留旧文件)
|
|
150
|
-
if (fs.existsSync(DEST_DIR)) {
|
|
151
|
-
fs.rmSync(DEST_DIR, { recursive: true, force: true });
|
|
152
|
-
console.log(" 🗑️ 已清空旧的 openyida/ 目录");
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const copiedCount = copyDirRecursive(SOURCE_DIR, DEST_DIR);
|
|
156
|
-
|
|
157
|
-
console.log(`\n 共复制 ${copiedCount} 个文件,开始 diff 校验...`);
|
|
158
|
-
verifyDiff(SOURCE_DIR, DEST_DIR);
|
|
159
|
-
console.log("=".repeat(50));
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
main();
|