tanmi-dock 0.4.0-beta.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/LICENSE +21 -0
- package/README.md +302 -0
- package/dist/commands/clean.d.ts +10 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +215 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/config.d.ts +10 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +105 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/doctor.d.ts +7 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +127 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +153 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/link.d.ts +7 -0
- package/dist/commands/link.d.ts.map +1 -0
- package/dist/commands/link.js +522 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/migrate.d.ts +7 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +137 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/projects.d.ts +7 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +126 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/repair.d.ts +7 -0
- package/dist/commands/repair.d.ts.map +1 -0
- package/dist/commands/repair.js +256 -0
- package/dist/commands/repair.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +172 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/unlink.d.ts +7 -0
- package/dist/commands/unlink.d.ts.map +1 -0
- package/dist/commands/unlink.js +104 -0
- package/dist/commands/unlink.js.map +1 -0
- package/dist/commands/verify.d.ts +7 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +190 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/core/codepac.d.ts +79 -0
- package/dist/core/codepac.d.ts.map +1 -0
- package/dist/core/codepac.js +188 -0
- package/dist/core/codepac.js.map +1 -0
- package/dist/core/config.d.ts +70 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +210 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/guard.d.ts +18 -0
- package/dist/core/guard.d.ts.map +1 -0
- package/dist/core/guard.js +82 -0
- package/dist/core/guard.js.map +1 -0
- package/dist/core/linker.d.ts +76 -0
- package/dist/core/linker.d.ts.map +1 -0
- package/dist/core/linker.js +263 -0
- package/dist/core/linker.js.map +1 -0
- package/dist/core/parser.d.ts +43 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +133 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/platform.d.ts +100 -0
- package/dist/core/platform.d.ts.map +1 -0
- package/dist/core/platform.js +193 -0
- package/dist/core/platform.js.map +1 -0
- package/dist/core/registry.d.ts +181 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +443 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/store.d.ts +77 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/store.js +226 -0
- package/dist/core/store.js.map +1 -0
- package/dist/core/transaction.d.ts +106 -0
- package/dist/core/transaction.d.ts.map +1 -0
- package/dist/core/transaction.js +295 -0
- package/dist/core/transaction.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +174 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +47 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/disk.d.ts +57 -0
- package/dist/utils/disk.d.ts.map +1 -0
- package/dist/utils/disk.js +313 -0
- package/dist/utils/disk.js.map +1 -0
- package/dist/utils/exit-codes.d.ts +42 -0
- package/dist/utils/exit-codes.d.ts.map +1 -0
- package/dist/utils/exit-codes.js +91 -0
- package/dist/utils/exit-codes.js.map +1 -0
- package/dist/utils/fs-utils.d.ts +44 -0
- package/dist/utils/fs-utils.d.ts.map +1 -0
- package/dist/utils/fs-utils.js +107 -0
- package/dist/utils/fs-utils.js.map +1 -0
- package/dist/utils/global-lock.d.ts +28 -0
- package/dist/utils/global-lock.d.ts.map +1 -0
- package/dist/utils/global-lock.js +89 -0
- package/dist/utils/global-lock.js.map +1 -0
- package/dist/utils/lock.d.ts +26 -0
- package/dist/utils/lock.d.ts.map +1 -0
- package/dist/utils/lock.js +68 -0
- package/dist/utils/lock.js.map +1 -0
- package/dist/utils/logger.d.ts +98 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +190 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/prompt.d.ts +32 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +131 -0
- package/dist/utils/prompt.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* status 命令 - 查看当前项目状态
|
|
3
|
+
*/
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import fs from 'fs/promises';
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { ensureInitialized } from '../core/guard.js';
|
|
8
|
+
import { parseProjectDependencies } from '../core/parser.js';
|
|
9
|
+
import { getRegistry } from '../core/registry.js';
|
|
10
|
+
import * as store from '../core/store.js';
|
|
11
|
+
import * as linker from '../core/linker.js';
|
|
12
|
+
import { resolvePath, shrinkHome } from '../core/platform.js';
|
|
13
|
+
import { info, warn, success, hint, blank, separator, title } from '../utils/logger.js';
|
|
14
|
+
/**
|
|
15
|
+
* 创建 status 命令
|
|
16
|
+
*/
|
|
17
|
+
export function createStatusCommand() {
|
|
18
|
+
return new Command('status')
|
|
19
|
+
.description('查看当前项目的链接状态')
|
|
20
|
+
.argument('[path]', '项目路径', '.')
|
|
21
|
+
.option('--json', '输出 JSON 格式')
|
|
22
|
+
.action(async (projectPath, options) => {
|
|
23
|
+
await ensureInitialized();
|
|
24
|
+
await showStatus(projectPath, options);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 显示项目状态
|
|
29
|
+
*/
|
|
30
|
+
async function showStatus(projectPath, options) {
|
|
31
|
+
const absolutePath = resolvePath(projectPath);
|
|
32
|
+
// 检查项目路径
|
|
33
|
+
try {
|
|
34
|
+
const stat = await fs.stat(absolutePath);
|
|
35
|
+
if (!stat.isDirectory()) {
|
|
36
|
+
warn(`路径不是目录: ${absolutePath}`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
warn(`路径不存在: ${absolutePath}`);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
// 加载注册表
|
|
45
|
+
const registry = getRegistry();
|
|
46
|
+
await registry.load();
|
|
47
|
+
const projectHash = registry.hashPath(absolutePath);
|
|
48
|
+
const projectInfo = registry.getProject(projectHash);
|
|
49
|
+
// 解析依赖
|
|
50
|
+
let dependencies;
|
|
51
|
+
let configPath;
|
|
52
|
+
try {
|
|
53
|
+
const result = await parseProjectDependencies(absolutePath);
|
|
54
|
+
dependencies = result.dependencies;
|
|
55
|
+
configPath = result.configPath;
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
warn(err.message);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
// 显示项目信息
|
|
62
|
+
title(`项目: ${shrinkHome(absolutePath)}`);
|
|
63
|
+
if (projectInfo) {
|
|
64
|
+
info(`最后链接: ${formatDate(projectInfo.lastLinked)}`);
|
|
65
|
+
info(`平台: ${projectInfo.platforms.join(', ') || '未指定'}`);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
warn('此项目尚未链接');
|
|
69
|
+
}
|
|
70
|
+
blank();
|
|
71
|
+
// 分析依赖状态
|
|
72
|
+
const thirdPartyDir = path.dirname(configPath);
|
|
73
|
+
const storePath = await store.getStorePath();
|
|
74
|
+
let linked = 0;
|
|
75
|
+
let broken = 0;
|
|
76
|
+
let unlinked = 0;
|
|
77
|
+
const brokenList = [];
|
|
78
|
+
const unlinkedList = [];
|
|
79
|
+
for (const dep of dependencies) {
|
|
80
|
+
const localPath = path.join(thirdPartyDir, dep.libName);
|
|
81
|
+
// 使用项目注册的第一个平台,或读取链接目标来判断
|
|
82
|
+
const statusPlatform = projectInfo?.platforms?.[0] ?? 'macOS';
|
|
83
|
+
const storeLibPath = store.getLibraryPath(storePath, dep.libName, dep.commit, statusPlatform);
|
|
84
|
+
const isLink = await linker.isSymlink(localPath);
|
|
85
|
+
if (isLink) {
|
|
86
|
+
const isValid = await linker.isValidLink(localPath);
|
|
87
|
+
// 对于多平台链接,只检查链接是否有效,不严格检查目标路径
|
|
88
|
+
const isCorrect = isValid ? await linker.isValidLink(localPath) : false;
|
|
89
|
+
if (isValid && isCorrect) {
|
|
90
|
+
linked++;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
broken++;
|
|
94
|
+
brokenList.push(`${dep.libName} (${dep.commit.slice(0, 7)})`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// 检查是否存在
|
|
99
|
+
try {
|
|
100
|
+
await fs.access(localPath);
|
|
101
|
+
unlinked++;
|
|
102
|
+
unlinkedList.push(`${dep.libName} (${dep.commit.slice(0, 7)}) - 普通目录`);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
unlinked++;
|
|
106
|
+
unlinkedList.push(`${dep.libName} (${dep.commit.slice(0, 7)}) - 不存在`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// JSON 输出
|
|
111
|
+
if (options.json) {
|
|
112
|
+
const output = {
|
|
113
|
+
project: absolutePath,
|
|
114
|
+
lastLinked: projectInfo?.lastLinked ?? null,
|
|
115
|
+
platforms: projectInfo?.platforms ?? [],
|
|
116
|
+
dependencies: {
|
|
117
|
+
total: dependencies.length,
|
|
118
|
+
linked,
|
|
119
|
+
broken,
|
|
120
|
+
unlinked,
|
|
121
|
+
},
|
|
122
|
+
brokenList,
|
|
123
|
+
unlinkedList,
|
|
124
|
+
};
|
|
125
|
+
console.log(JSON.stringify(output, null, 2));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
// 显示统计
|
|
129
|
+
info(`依赖状态 (${dependencies.length} 个):`);
|
|
130
|
+
success(` 已链接: ${linked}`);
|
|
131
|
+
if (broken > 0) {
|
|
132
|
+
warn(` 链接失效: ${broken}`);
|
|
133
|
+
}
|
|
134
|
+
if (unlinked > 0) {
|
|
135
|
+
warn(` 未链接: ${unlinked}`);
|
|
136
|
+
}
|
|
137
|
+
// 显示详情
|
|
138
|
+
if (brokenList.length > 0) {
|
|
139
|
+
blank();
|
|
140
|
+
warn('链接失效的库:');
|
|
141
|
+
for (const item of brokenList) {
|
|
142
|
+
info(` - ${item}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (unlinkedList.length > 0) {
|
|
146
|
+
blank();
|
|
147
|
+
warn('未链接的库:');
|
|
148
|
+
for (const item of unlinkedList) {
|
|
149
|
+
info(` - ${item}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// 建议
|
|
153
|
+
if (broken > 0 || unlinked > 0) {
|
|
154
|
+
blank();
|
|
155
|
+
separator();
|
|
156
|
+
hint('运行 tanmi-dock link . 更新链接');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 格式化日期
|
|
161
|
+
*/
|
|
162
|
+
function formatDate(isoString) {
|
|
163
|
+
const date = new Date(isoString);
|
|
164
|
+
const year = date.getFullYear();
|
|
165
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
166
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
167
|
+
const hour = String(date.getHours()).padStart(2, '0');
|
|
168
|
+
const minute = String(date.getMinutes()).padStart(2, '0');
|
|
169
|
+
return `${year}-${month}-${day} ${hour}:${minute}`;
|
|
170
|
+
}
|
|
171
|
+
export default createStatusCommand;
|
|
172
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlink.d.ts","sourceRoot":"","sources":["../../src/commands/unlink.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAS7C;AA+FD,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* unlink 命令 - 取消链接
|
|
3
|
+
*/
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import fs from 'fs/promises';
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { ensureInitialized } from '../core/guard.js';
|
|
8
|
+
import { getRegistry } from '../core/registry.js';
|
|
9
|
+
import * as linker from '../core/linker.js';
|
|
10
|
+
import { resolvePath, shrinkHome } from '../core/platform.js';
|
|
11
|
+
import { info, warn, success, error, hint, blank, separator } from '../utils/logger.js';
|
|
12
|
+
/**
|
|
13
|
+
* 创建 unlink 命令
|
|
14
|
+
*/
|
|
15
|
+
export function createUnlinkCommand() {
|
|
16
|
+
return new Command('unlink')
|
|
17
|
+
.description('取消项目的链接')
|
|
18
|
+
.argument('[path]', '项目路径', '.')
|
|
19
|
+
.option('--remove', '同时从 Store 删除无其他引用的库')
|
|
20
|
+
.action(async (projectPath, options) => {
|
|
21
|
+
await ensureInitialized();
|
|
22
|
+
await unlinkProject(projectPath, options);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 取消链接
|
|
27
|
+
*/
|
|
28
|
+
async function unlinkProject(projectPath, options) {
|
|
29
|
+
const absolutePath = resolvePath(projectPath);
|
|
30
|
+
// 检查项目路径
|
|
31
|
+
try {
|
|
32
|
+
const stat = await fs.stat(absolutePath);
|
|
33
|
+
if (!stat.isDirectory()) {
|
|
34
|
+
error(`路径不是目录: ${absolutePath}`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
error(`路径不存在: ${absolutePath}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
// 加载注册表
|
|
43
|
+
const registry = getRegistry();
|
|
44
|
+
await registry.load();
|
|
45
|
+
const projectHash = registry.hashPath(absolutePath);
|
|
46
|
+
const projectInfo = registry.getProject(projectHash);
|
|
47
|
+
if (!projectInfo) {
|
|
48
|
+
warn('此项目未被跟踪');
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
info(`取消链接: ${shrinkHome(absolutePath)}`);
|
|
52
|
+
blank();
|
|
53
|
+
let restored = 0;
|
|
54
|
+
let removed = 0;
|
|
55
|
+
// 遍历项目的依赖
|
|
56
|
+
for (const dep of projectInfo.dependencies) {
|
|
57
|
+
const localPath = path.join(absolutePath, dep.linkedPath);
|
|
58
|
+
const libKey = registry.getLibraryKey(dep.libName, dep.commit);
|
|
59
|
+
// 检查是否为符号链接
|
|
60
|
+
if (await linker.isSymlink(localPath)) {
|
|
61
|
+
try {
|
|
62
|
+
// 还原为普通目录(从 Store 复制内容)
|
|
63
|
+
await linker.restoreFromLink(localPath);
|
|
64
|
+
success(`${dep.libName} (${dep.commit.slice(0, 7)}) - 已还原`);
|
|
65
|
+
restored++;
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
warn(`${dep.libName} 还原失败: ${err.message}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// 移除引用关系
|
|
72
|
+
registry.removeReference(libKey, projectHash);
|
|
73
|
+
// 如果需要删除无引用的库
|
|
74
|
+
if (options.remove) {
|
|
75
|
+
const lib = registry.getLibrary(libKey);
|
|
76
|
+
if (lib && lib.referencedBy.length === 0) {
|
|
77
|
+
try {
|
|
78
|
+
const store = await import('../core/store.js');
|
|
79
|
+
// TODO: 1-1 需要遍历所有平台删除,暂时使用 platforms 字段
|
|
80
|
+
for (const platform of lib.platforms) {
|
|
81
|
+
await store.remove(dep.libName, dep.commit, platform);
|
|
82
|
+
}
|
|
83
|
+
registry.removeLibrary(libKey);
|
|
84
|
+
removed++;
|
|
85
|
+
hint(`${dep.libName} (${dep.commit.slice(0, 7)}) - 已从 Store 删除`);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
warn(`删除 ${dep.libName} 失败: ${err.message}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// 移除项目记录
|
|
94
|
+
registry.removeProject(projectHash);
|
|
95
|
+
await registry.save();
|
|
96
|
+
blank();
|
|
97
|
+
separator();
|
|
98
|
+
success(`完成: 还原 ${restored} 个链接`);
|
|
99
|
+
if (options.remove && removed > 0) {
|
|
100
|
+
info(`从 Store 删除 ${removed} 个库`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export default createUnlinkCommand;
|
|
104
|
+
//# sourceMappingURL=unlink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlink.js","sourceRoot":"","sources":["../../src/commands/unlink.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAO7C;AAoLD,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* verify 命令 - 验证 Store 和 Registry 完整性
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'fs/promises';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { ensureInitialized } from '../core/guard.js';
|
|
8
|
+
import { getRegistry } from '../core/registry.js';
|
|
9
|
+
import * as store from '../core/store.js';
|
|
10
|
+
import { formatSize } from '../utils/disk.js';
|
|
11
|
+
import { info, warn, success, error, hint, blank, title, separator } from '../utils/logger.js';
|
|
12
|
+
/**
|
|
13
|
+
* 创建 verify 命令
|
|
14
|
+
*/
|
|
15
|
+
export function createVerifyCommand() {
|
|
16
|
+
return new Command('verify')
|
|
17
|
+
.description('验证 Store 和 Registry 完整性')
|
|
18
|
+
.action(async () => {
|
|
19
|
+
await ensureInitialized();
|
|
20
|
+
await verifyIntegrity();
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 验证完整性
|
|
25
|
+
*/
|
|
26
|
+
async function verifyIntegrity() {
|
|
27
|
+
title('验证 Store 完整性');
|
|
28
|
+
blank();
|
|
29
|
+
const registry = getRegistry();
|
|
30
|
+
await registry.load();
|
|
31
|
+
const result = {
|
|
32
|
+
danglingLinks: [],
|
|
33
|
+
orphanLibraries: [],
|
|
34
|
+
missingLibraries: [],
|
|
35
|
+
invalidProjects: [],
|
|
36
|
+
};
|
|
37
|
+
const storePath = await store.getStorePath();
|
|
38
|
+
// 1. 检查项目引用一致性
|
|
39
|
+
info('检查项目引用...');
|
|
40
|
+
const projects = registry.listProjects();
|
|
41
|
+
for (const project of projects) {
|
|
42
|
+
// 检查项目路径是否存在
|
|
43
|
+
try {
|
|
44
|
+
await fs.access(project.path);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
result.invalidProjects.push(project.path);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// 检查依赖的符号链接
|
|
51
|
+
for (const dep of project.dependencies) {
|
|
52
|
+
const linkPath = path.join(project.path, dep.linkedPath);
|
|
53
|
+
// 使用依赖记录的平台,或项目的第一个平台
|
|
54
|
+
const verifyPlatform = dep.platform ?? project.platforms?.[0] ?? 'macOS';
|
|
55
|
+
const expectedTarget = store.getLibraryPath(storePath, dep.libName, dep.commit, verifyPlatform);
|
|
56
|
+
try {
|
|
57
|
+
const stat = await fs.lstat(linkPath);
|
|
58
|
+
if (stat.isSymbolicLink()) {
|
|
59
|
+
const actualTarget = await fs.readlink(linkPath);
|
|
60
|
+
const resolvedTarget = path.resolve(path.dirname(linkPath), actualTarget);
|
|
61
|
+
// 检查链接目标是否存在
|
|
62
|
+
try {
|
|
63
|
+
await fs.access(resolvedTarget);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
result.danglingLinks.push({ path: linkPath, target: resolvedTarget });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// 符号链接不存在,检查库是否在 Store
|
|
72
|
+
const exists = await store.exists(dep.libName, dep.commit, verifyPlatform);
|
|
73
|
+
if (!exists) {
|
|
74
|
+
result.missingLibraries.push({
|
|
75
|
+
libName: dep.libName,
|
|
76
|
+
commit: dep.commit,
|
|
77
|
+
project: project.path,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// 2. 检查孤立库(Store 中有但 Registry 没有)
|
|
84
|
+
info('检查孤立库...');
|
|
85
|
+
try {
|
|
86
|
+
const storeEntries = await fs.readdir(storePath);
|
|
87
|
+
for (const libName of storeEntries) {
|
|
88
|
+
const libPath = path.join(storePath, libName);
|
|
89
|
+
const stat = await fs.stat(libPath);
|
|
90
|
+
if (!stat.isDirectory())
|
|
91
|
+
continue;
|
|
92
|
+
const commits = await fs.readdir(libPath);
|
|
93
|
+
for (const commit of commits) {
|
|
94
|
+
const commitPath = path.join(libPath, commit);
|
|
95
|
+
const commitStat = await fs.stat(commitPath);
|
|
96
|
+
if (!commitStat.isDirectory())
|
|
97
|
+
continue;
|
|
98
|
+
const libKey = registry.getLibraryKey(libName, commit);
|
|
99
|
+
const libInfo = registry.getLibrary(libKey);
|
|
100
|
+
if (!libInfo) {
|
|
101
|
+
// 计算大小
|
|
102
|
+
const size = await getDirSizeRecursive(commitPath);
|
|
103
|
+
result.orphanLibraries.push({ libName, commit, size });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Store 目录不存在或无法读取
|
|
110
|
+
}
|
|
111
|
+
// 输出结果
|
|
112
|
+
blank();
|
|
113
|
+
separator();
|
|
114
|
+
// Registry 引用一致性
|
|
115
|
+
if (result.invalidProjects.length === 0 && result.missingLibraries.length === 0) {
|
|
116
|
+
success('[ok] Registry 引用一致');
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
if (result.invalidProjects.length > 0) {
|
|
120
|
+
warn(`[warn] 发现 ${result.invalidProjects.length} 个无效项目`);
|
|
121
|
+
for (const p of result.invalidProjects) {
|
|
122
|
+
info(` - ${p} -> 路径不存在`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (result.missingLibraries.length > 0) {
|
|
126
|
+
error(`[err] 发现 ${result.missingLibraries.length} 个缺失库`);
|
|
127
|
+
for (const lib of result.missingLibraries) {
|
|
128
|
+
info(` - ${lib.libName}/${lib.commit.slice(0, 7)} (引用自 ${lib.project})`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// 悬挂链接
|
|
133
|
+
if (result.danglingLinks.length === 0) {
|
|
134
|
+
success('[ok] 符号链接完整');
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
warn(`[warn] 发现 ${result.danglingLinks.length} 个悬挂链接`);
|
|
138
|
+
for (const link of result.danglingLinks) {
|
|
139
|
+
info(` - ${link.path} -> 目标不存在`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// 孤立库
|
|
143
|
+
if (result.orphanLibraries.length === 0) {
|
|
144
|
+
success('[ok] 无孤立库');
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const totalSize = result.orphanLibraries.reduce((sum, lib) => sum + lib.size, 0);
|
|
148
|
+
warn(`[warn] 发现 ${result.orphanLibraries.length} 个孤立库 (${formatSize(totalSize)})`);
|
|
149
|
+
for (const lib of result.orphanLibraries) {
|
|
150
|
+
info(` - ${lib.libName}/${lib.commit.slice(0, 7)} (${formatSize(lib.size)})`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// 总结和建议
|
|
154
|
+
blank();
|
|
155
|
+
const hasIssues = result.danglingLinks.length > 0 ||
|
|
156
|
+
result.orphanLibraries.length > 0 ||
|
|
157
|
+
result.missingLibraries.length > 0 ||
|
|
158
|
+
result.invalidProjects.length > 0;
|
|
159
|
+
if (hasIssues) {
|
|
160
|
+
hint('建议: 运行 tanmi-dock repair 修复问题');
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
success('Store 完整性验证通过');
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 递归计算目录大小
|
|
168
|
+
*/
|
|
169
|
+
async function getDirSizeRecursive(dirPath) {
|
|
170
|
+
let size = 0;
|
|
171
|
+
try {
|
|
172
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
173
|
+
for (const entry of entries) {
|
|
174
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
175
|
+
if (entry.isDirectory()) {
|
|
176
|
+
size += await getDirSizeRecursive(fullPath);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
const stat = await fs.stat(fullPath);
|
|
180
|
+
size += stat.size;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
// 忽略错误
|
|
186
|
+
}
|
|
187
|
+
return size;
|
|
188
|
+
}
|
|
189
|
+
export default createVerifyCommand;
|
|
190
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 检查 codepac 是否已安装
|
|
3
|
+
*/
|
|
4
|
+
export declare function isCodepacInstalled(): Promise<boolean>;
|
|
5
|
+
/**
|
|
6
|
+
* 获取 codepac 版本
|
|
7
|
+
*/
|
|
8
|
+
export declare function getVersion(): Promise<string | null>;
|
|
9
|
+
/**
|
|
10
|
+
* 安装依赖选项
|
|
11
|
+
*/
|
|
12
|
+
export interface InstallOptions {
|
|
13
|
+
/** codepac-dep.json 配置文件路径 */
|
|
14
|
+
configPath: string;
|
|
15
|
+
/** 目标目录(3rdparty 目录) */
|
|
16
|
+
targetDir: string;
|
|
17
|
+
/** 平台目录名 (macOS, iOS, android...) - 传给 codepac -p */
|
|
18
|
+
platform?: string;
|
|
19
|
+
/** 进度回调 */
|
|
20
|
+
onProgress?: (message: string) => void;
|
|
21
|
+
/** 是否静默模式 */
|
|
22
|
+
silent?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 使用 codepac 安装依赖
|
|
26
|
+
*/
|
|
27
|
+
export declare function install(options: InstallOptions): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* 安装单个库选项
|
|
30
|
+
*/
|
|
31
|
+
export interface InstallSingleOptions {
|
|
32
|
+
/** 库的 Git URL */
|
|
33
|
+
url: string;
|
|
34
|
+
/** commit hash */
|
|
35
|
+
commit: string;
|
|
36
|
+
/** 分支名 */
|
|
37
|
+
branch: string;
|
|
38
|
+
/** 目标目录 */
|
|
39
|
+
targetDir: string;
|
|
40
|
+
/** 平台目录名 (macOS, iOS, android...) - 传给 codepac -p */
|
|
41
|
+
platform?: string;
|
|
42
|
+
/** sparse checkout 配置 */
|
|
43
|
+
sparse?: object | string;
|
|
44
|
+
/** 进度回调 */
|
|
45
|
+
onProgress?: (message: string) => void;
|
|
46
|
+
/** 是否静默模式 */
|
|
47
|
+
silent?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 使用 codepac 安装单个库
|
|
51
|
+
* 注意:这需要 codepac 支持单库安装,如果不支持则需要创建临时配置文件
|
|
52
|
+
*/
|
|
53
|
+
export declare function installSingle(options: InstallSingleOptions): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* 更新库到最新 commit
|
|
56
|
+
*/
|
|
57
|
+
export interface UpdateOptions {
|
|
58
|
+
/** codepac-dep.json 配置文件路径 */
|
|
59
|
+
configPath: string;
|
|
60
|
+
/** 目标目录 */
|
|
61
|
+
targetDir: string;
|
|
62
|
+
/** 要更新的库名(不指定则更新所有) */
|
|
63
|
+
libName?: string;
|
|
64
|
+
/** 进度回调 */
|
|
65
|
+
onProgress?: (message: string) => void;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 更新依赖
|
|
69
|
+
*/
|
|
70
|
+
export declare function update(options: UpdateOptions): Promise<void>;
|
|
71
|
+
declare const _default: {
|
|
72
|
+
isCodepacInstalled: typeof isCodepacInstalled;
|
|
73
|
+
getVersion: typeof getVersion;
|
|
74
|
+
install: typeof install;
|
|
75
|
+
installSingle: typeof installSingle;
|
|
76
|
+
update: typeof update;
|
|
77
|
+
};
|
|
78
|
+
export default _default;
|
|
79
|
+
//# sourceMappingURL=codepac.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codepac.d.ts","sourceRoot":"","sources":["../../src/core/codepac.ts"],"names":[],"mappings":"AAeA;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO3D;AAED;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOzD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW;IACX,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDpE;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,iBAAiB;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU;IACV,MAAM,EAAE,MAAM,CAAC;IACf,WAAW;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,WAAW;IACX,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDhF;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW;IACX,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAkDlE;;;;;;;;AAED,wBAME"}
|