tanmi-dock 0.7.2 → 0.7.3-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.
@@ -0,0 +1,266 @@
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
+ export 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
+ staleReferences: [],
37
+ };
38
+ const storePath = await store.getStorePath();
39
+ // 1. 检查项目引用一致性
40
+ info('检查项目引用...');
41
+ const projects = registry.listProjects();
42
+ for (const project of projects) {
43
+ // 检查项目路径是否存在
44
+ try {
45
+ await fs.access(project.path);
46
+ }
47
+ catch {
48
+ result.invalidProjects.push(project.path);
49
+ continue;
50
+ }
51
+ // 检查依赖的符号链接
52
+ for (const dep of project.dependencies) {
53
+ const linkPath = path.join(project.path, dep.linkedPath);
54
+ // 使用依赖记录的平台,或项目的第一个平台
55
+ const verifyPlatform = dep.platform ?? project.platforms?.[0] ?? 'macOS';
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
+ // 3. 检查失效引用(Registry 中 referencedBy 指向的项目没有实际符号链接)
112
+ info('检查引用一致性...');
113
+ const libraries = registry.listLibraries();
114
+ for (const lib of libraries) {
115
+ const libKey = registry.getLibraryKey(lib.libName, lib.commit);
116
+ for (const projectHash of lib.referencedBy) {
117
+ const project = registry.getProject(projectHash);
118
+ if (!project) {
119
+ // 项目不存在于 registry
120
+ result.staleReferences.push({
121
+ libKey,
122
+ projectHash,
123
+ projectPath: '(项目已删除)',
124
+ });
125
+ continue;
126
+ }
127
+ // 检查项目中是否有符号链接指向此库版本
128
+ let hasValidLink = false;
129
+ const libStorePath = path.join(storePath, lib.libName, lib.commit);
130
+ for (const dep of project.dependencies) {
131
+ if (dep.libName === lib.libName && dep.commit === lib.commit) {
132
+ const linkPath = path.join(project.path, dep.linkedPath);
133
+ try {
134
+ const stat = await fs.lstat(linkPath);
135
+ if (stat.isSymbolicLink()) {
136
+ const target = await fs.readlink(linkPath);
137
+ const resolvedTarget = path.resolve(path.dirname(linkPath), target);
138
+ // 检查链接是否指向此库版本
139
+ if (resolvedTarget.startsWith(libStorePath)) {
140
+ hasValidLink = true;
141
+ break;
142
+ }
143
+ }
144
+ else if (stat.isDirectory()) {
145
+ // 多平台模式:检查内部是否有符号链接指向此库
146
+ const entries = await fs.readdir(linkPath, { withFileTypes: true });
147
+ for (const entry of entries) {
148
+ if (entry.isSymbolicLink()) {
149
+ const subLinkPath = path.join(linkPath, entry.name);
150
+ const subTarget = await fs.readlink(subLinkPath);
151
+ const resolvedSubTarget = path.resolve(linkPath, subTarget);
152
+ if (resolvedSubTarget.startsWith(libStorePath)) {
153
+ hasValidLink = true;
154
+ break;
155
+ }
156
+ }
157
+ }
158
+ if (hasValidLink)
159
+ break;
160
+ }
161
+ }
162
+ catch {
163
+ // 链接不存在或无法读取
164
+ }
165
+ }
166
+ }
167
+ if (!hasValidLink) {
168
+ result.staleReferences.push({
169
+ libKey,
170
+ projectHash,
171
+ projectPath: project.path,
172
+ });
173
+ }
174
+ }
175
+ }
176
+ // 输出结果
177
+ blank();
178
+ separator();
179
+ // Registry 引用一致性
180
+ if (result.invalidProjects.length === 0 && result.missingLibraries.length === 0) {
181
+ success('[ok] Registry 引用一致');
182
+ }
183
+ else {
184
+ if (result.invalidProjects.length > 0) {
185
+ warn(`[warn] 发现 ${result.invalidProjects.length} 个无效项目`);
186
+ for (const p of result.invalidProjects) {
187
+ info(` - ${p} -> 路径不存在`);
188
+ }
189
+ }
190
+ if (result.missingLibraries.length > 0) {
191
+ error(`[err] 发现 ${result.missingLibraries.length} 个缺失库`);
192
+ for (const lib of result.missingLibraries) {
193
+ info(` - ${lib.libName}/${lib.commit.slice(0, 7)} (引用自 ${lib.project})`);
194
+ }
195
+ }
196
+ }
197
+ // 悬挂链接
198
+ if (result.danglingLinks.length === 0) {
199
+ success('[ok] 符号链接完整');
200
+ }
201
+ else {
202
+ warn(`[warn] 发现 ${result.danglingLinks.length} 个悬挂链接`);
203
+ for (const link of result.danglingLinks) {
204
+ info(` - ${link.path} -> 目标不存在`);
205
+ }
206
+ }
207
+ // 孤立库
208
+ if (result.orphanLibraries.length === 0) {
209
+ success('[ok] 无孤立库');
210
+ }
211
+ else {
212
+ const totalSize = result.orphanLibraries.reduce((sum, lib) => sum + lib.size, 0);
213
+ warn(`[warn] 发现 ${result.orphanLibraries.length} 个孤立库 (${formatSize(totalSize)})`);
214
+ for (const lib of result.orphanLibraries) {
215
+ info(` - ${lib.libName}/${lib.commit.slice(0, 7)} (${formatSize(lib.size)})`);
216
+ }
217
+ }
218
+ // 失效引用
219
+ if (result.staleReferences.length === 0) {
220
+ success('[ok] 引用关系一致');
221
+ }
222
+ else {
223
+ warn(`[warn] 发现 ${result.staleReferences.length} 个失效引用`);
224
+ for (const ref of result.staleReferences) {
225
+ info(` - ${ref.libKey} <- ${ref.projectPath}`);
226
+ }
227
+ }
228
+ // 总结和建议
229
+ blank();
230
+ const hasIssues = result.danglingLinks.length > 0 ||
231
+ result.orphanLibraries.length > 0 ||
232
+ result.missingLibraries.length > 0 ||
233
+ result.invalidProjects.length > 0 ||
234
+ result.staleReferences.length > 0;
235
+ if (hasIssues) {
236
+ hint('建议: 运行 tanmi-dock repair 修复问题');
237
+ }
238
+ else {
239
+ success('Store 完整性验证通过');
240
+ }
241
+ }
242
+ /**
243
+ * 递归计算目录大小
244
+ */
245
+ async function getDirSizeRecursive(dirPath) {
246
+ let size = 0;
247
+ try {
248
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
249
+ for (const entry of entries) {
250
+ const fullPath = path.join(dirPath, entry.name);
251
+ if (entry.isDirectory()) {
252
+ size += await getDirSizeRecursive(fullPath);
253
+ }
254
+ else {
255
+ const stat = await fs.stat(fullPath);
256
+ size += stat.size;
257
+ }
258
+ }
259
+ }
260
+ catch {
261
+ // 忽略错误
262
+ }
263
+ return size;
264
+ }
265
+ export default createVerifyCommand;
266
+ //# 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,7 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ *No recent activity*
7
+ </claude-mem-context>
@@ -0,0 +1,26 @@
1
+ /**
2
+ * iOS 路径映射生成器
3
+ * 为 CocoaPods podspec 生成路径映射文件
4
+ */
5
+ export interface IOSPathMapping {
6
+ libName: string;
7
+ storePath: string;
8
+ iosPath: string;
9
+ }
10
+ /**
11
+ * 生成 iOS 路径映射文件
12
+ * @param mappings 库路径映射列表
13
+ * @returns 生成的文件路径
14
+ */
15
+ export declare function generateIOSPathsFile(mappings: IOSPathMapping[]): Promise<string>;
16
+ /**
17
+ * 从注册表收集 iOS 路径映射
18
+ * @param projectPath 项目路径
19
+ * @param registry 注册表数据
20
+ * @returns 路径映射列表
21
+ */
22
+ export declare function collectIOSMappings(projectPath: string, linkedLibs: Map<string, {
23
+ storePath: string;
24
+ platforms: string[];
25
+ }>): IOSPathMapping[];
26
+ //# sourceMappingURL=ios-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ios-paths.d.ts","sourceRoot":"","sources":["../../src/utils/ios-paths.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAsCtF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,GAClE,cAAc,EAAE,CAmBlB"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * iOS 路径映射生成器
3
+ * 为 CocoaPods podspec 生成路径映射文件
4
+ */
5
+ import * as fs from 'fs/promises';
6
+ import * as path from 'path';
7
+ import { getConfig } from '../core/config.js';
8
+ import { logger } from './logger.js';
9
+ /**
10
+ * 生成 iOS 路径映射文件
11
+ * @param mappings 库路径映射列表
12
+ * @returns 生成的文件路径
13
+ */
14
+ export async function generateIOSPathsFile(mappings) {
15
+ const config = await getConfig();
16
+ const outputDir = path.dirname(config.registryPath);
17
+ const outputPath = path.join(outputDir, 'ios_paths.rb');
18
+ // 生成 Ruby 代码
19
+ const lines = [
20
+ '# Auto-generated by tanmi-dock',
21
+ '# Do not edit manually',
22
+ '#',
23
+ '# Usage in podspec:',
24
+ '# require_relative File.expand_path("~/.tanmi-dock/ios_paths.rb")',
25
+ '# spec.vendored_libraries = [',
26
+ '# "#{TANMI_DOCK_LIBS[\'libName\']}/lib/*.a",',
27
+ '# ]',
28
+ '',
29
+ 'TANMI_DOCK_LIBS = {',
30
+ ];
31
+ for (const mapping of mappings) {
32
+ lines.push(` '${mapping.libName}' => '${mapping.iosPath}',`);
33
+ }
34
+ lines.push('}.freeze');
35
+ lines.push('');
36
+ // 添加辅助方法
37
+ lines.push('# Helper method to get library path');
38
+ lines.push('def tanmi_dock_path(lib_name)');
39
+ lines.push(' TANMI_DOCK_LIBS[lib_name] || raise("tanmi-dock: Library \'#{lib_name}\' not found")');
40
+ lines.push('end');
41
+ lines.push('');
42
+ const content = lines.join('\n');
43
+ await fs.writeFile(outputPath, content, 'utf-8');
44
+ logger.debug(`Generated iOS paths file: ${outputPath}`);
45
+ return outputPath;
46
+ }
47
+ /**
48
+ * 从注册表收集 iOS 路径映射
49
+ * @param projectPath 项目路径
50
+ * @param registry 注册表数据
51
+ * @returns 路径映射列表
52
+ */
53
+ export function collectIOSMappings(projectPath, linkedLibs) {
54
+ const mappings = [];
55
+ for (const [libName, info] of linkedLibs) {
56
+ // 检查是否有 iOS 平台
57
+ const hasIOS = info.platforms.some((p) => p.toLowerCase() === 'ios');
58
+ if (!hasIOS)
59
+ continue;
60
+ // 构建 iOS 路径
61
+ const iosPath = path.join(info.storePath, 'iOS');
62
+ mappings.push({
63
+ libName,
64
+ storePath: info.storePath,
65
+ iosPath,
66
+ });
67
+ }
68
+ return mappings;
69
+ }
70
+ //# sourceMappingURL=ios-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ios-paths.js","sourceRoot":"","sources":["../../src/utils/ios-paths.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAA0B;IACnE,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAExD,aAAa;IACb,MAAM,KAAK,GAAa;QACtB,gCAAgC;QAChC,wBAAwB;QACxB,GAAG;QACH,qBAAqB;QACrB,qEAAqE;QACrE,iCAAiC;QACjC,kDAAkD;QAClD,OAAO;QACP,EAAE;QACF,qBAAqB;KACtB,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,OAAO,SAAS,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,SAAS;IACT,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAC;IACpG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEjD,MAAM,CAAC,KAAK,CAAC,6BAA6B,UAAU,EAAE,CAAC,CAAC;IACxD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,WAAmB,EACnB,UAAmE;IAEnE,MAAM,QAAQ,GAAqB,EAAE,CAAC;IAEtC,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,UAAU,EAAE,CAAC;QACzC,eAAe;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;QACrE,IAAI,CAAC,MAAM;YAAE,SAAS;QAEtB,YAAY;QACZ,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAEjD,QAAQ,CAAC,IAAI,CAAC;YACZ,OAAO;YACP,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { PodConfig, PodfileModifyResult } from '../types/index.js';
2
+ /**
3
+ * 查找项目中的 Podfile
4
+ * @param projectPath 项目路径
5
+ * @param maxDepth 最大搜索深度
6
+ * @returns Podfile 路径列表,按深度排序(浅层在前)
7
+ */
8
+ export declare function findPodfiles(projectPath: string, maxDepth?: number): Promise<string[]>;
9
+ /**
10
+ * 解析 Podfile 中已存在的 tanmi-dock pods
11
+ * @param content Podfile 内容
12
+ * @returns 已存在的 pod 名称到路径的映射
13
+ */
14
+ export declare function parseTanmiDockPods(content: string): Map<string, string>;
15
+ /**
16
+ * 修改 Podfile 添加/更新 pods
17
+ * @param podfilePath Podfile 路径
18
+ * @param pods 要添加的 Pod 配置列表
19
+ * @returns 修改结果
20
+ */
21
+ export declare function modifyPodfile(podfilePath: string, pods: PodConfig[]): Promise<PodfileModifyResult>;
22
+ /**
23
+ * 从 Podfile 中移除 tanmi-dock 块
24
+ * @param podfilePath Podfile 路径
25
+ * @returns 是否成功移除
26
+ */
27
+ export declare function removeTanmiDockBlock(podfilePath: string): Promise<boolean>;
28
+ /**
29
+ * 恢复 Podfile 备份
30
+ * @param podfilePath Podfile 路径
31
+ * @returns 是否成功恢复
32
+ */
33
+ export declare function restoreBackup(podfilePath: string): Promise<boolean>;
34
+ declare const _default: {
35
+ findPodfiles: typeof findPodfiles;
36
+ parseTanmiDockPods: typeof parseTanmiDockPods;
37
+ modifyPodfile: typeof modifyPodfile;
38
+ removeTanmiDockBlock: typeof removeTanmiDockBlock;
39
+ restoreBackup: typeof restoreBackup;
40
+ };
41
+ export default _default;
42
+ //# sourceMappingURL=podfile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"podfile.d.ts","sourceRoot":"","sources":["../../src/utils/podfile.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAOxE;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAyCvF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBvE;AA8CD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuFxG;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAuChF;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYzE;;;;;;;;AAED,wBAME"}