autosnippet 1.1.19 → 1.1.20

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/asnip.js CHANGED
@@ -226,4 +226,31 @@ commander
226
226
  });
227
227
  });
228
228
 
229
+ commander
230
+ .command('root')
231
+ .description('mark current directory as project root by creating AutoSnippetRoot.boxspec.json')
232
+ .action(() => {
233
+ const fs = require('fs');
234
+ const path = require('path');
235
+ const rootMarkerPath = path.join(CMD_PATH, 'AutoSnippetRoot.boxspec.json');
236
+
237
+ try {
238
+ // 检查文件是否已存在
239
+ fs.accessSync(rootMarkerPath, fs.constants.F_OK);
240
+ console.log(`根目录标记文件已存在: ${rootMarkerPath}`);
241
+ } catch (err) {
242
+ // 文件不存在,创建它
243
+ try {
244
+ // 创建一个空的标记文件
245
+ fs.writeFileSync(rootMarkerPath, JSON.stringify({
246
+ root: true,
247
+ description: 'This file marks the project root directory for AutoSnippet'
248
+ }, null, 2), 'utf8');
249
+ console.log(`已创建根目录标记文件: ${rootMarkerPath}`);
250
+ } catch (writeErr) {
251
+ console.error(`创建根目录标记文件失败: ${writeErr.message}`);
252
+ }
253
+ }
254
+ });
255
+
229
256
  commander.parse(process.argv);
package/bin/create.js CHANGED
@@ -41,6 +41,51 @@ function determineModuleName(filePath, packageInfo) {
41
41
  return packageInfo.name;
42
42
  }
43
43
 
44
+ /**
45
+ * 从文件路径确定 target 的根目录(包含 Code 或 Sources 的目录)
46
+ * @param {string} filePath - 文件路径
47
+ * @returns {Promise<string|null>} target 根目录路径,如果找不到返回 null
48
+ */
49
+ async function findTargetRootDir(filePath) {
50
+ const fs = require('fs');
51
+ let currentPath = path.dirname(path.resolve(filePath));
52
+ const maxLevels = 10;
53
+ let levelsChecked = 0;
54
+
55
+ // ✅ 向上查找包含 Code 或 Sources 目录的目录(target 根目录)
56
+ // 例如:BDNetworkAPI/Code/xxx.m -> BDNetworkAPI/
57
+ while (currentPath && levelsChecked < maxLevels) {
58
+ try {
59
+ const entries = await fs.promises.readdir(currentPath, { withFileTypes: true });
60
+
61
+ // 检查当前目录是否包含 Code 或 Sources 目录
62
+ for (const entry of entries) {
63
+ if (entry.isDirectory() && (entry.name === 'Code' || entry.name === 'Sources')) {
64
+ // 找到包含 Code 或 Sources 的目录,这就是 target 根目录
65
+ console.log(`[findTargetRootDir] 找到 target 根目录: ${currentPath} (包含 ${entry.name})`);
66
+ return currentPath;
67
+ }
68
+ }
69
+
70
+ // 继续向上查找
71
+ const parentPath = path.dirname(currentPath);
72
+ if (parentPath === currentPath) {
73
+ break;
74
+ }
75
+ currentPath = parentPath;
76
+ levelsChecked++;
77
+ } catch (err) {
78
+ if (err.code === 'ENOENT' || err.code === 'EACCES') {
79
+ break;
80
+ }
81
+ throw err;
82
+ }
83
+ }
84
+
85
+ console.log(`[findTargetRootDir] 未找到 target 根目录(Code 或 Sources)`);
86
+ return null;
87
+ }
88
+
44
89
  function updateCodeSnippets(specFile, word, key, value) {
45
90
  if (key && key !== 'title' && key !== 'link' && key !== 'summary') {
46
91
  console.log('此项属性不存在或不可修改。');
@@ -224,7 +269,7 @@ function readStream(specFile, filePathArr, snippet, isHaveHeader) {
224
269
  }
225
270
  });
226
271
 
227
- rl.on('close', function () {
272
+ rl.on('close', async function () {
228
273
  if (codeList.length > 1) {
229
274
  codeList.pop();
230
275
 
@@ -243,9 +288,14 @@ function readStream(specFile, filePathArr, snippet, isHaveHeader) {
243
288
  if (!packagePath) {
244
289
  console.log('未找到 Package.swift 文件,请检查路径。');
245
290
  snippet['{content}'] = codeList;
246
- // ✅ SPM 模块:.boxspec 文件位置在模块根目录(与 Package.swift 同级)
247
- const moduleSpecFile = path.join(path.dirname(packagePath), 'AutoSnippet.boxspec.json');
248
- saveFromFile(moduleSpecFile, snippet);
291
+ // ✅ 查找 target 根目录(Code Sources 的父目录)
292
+ let targetRootDir = await findTargetRootDir(filePath);
293
+ if (!targetRootDir) {
294
+ // 如果找不到,使用文件所在目录的父目录作为后备
295
+ targetRootDir = path.dirname(path.dirname(filePath));
296
+ }
297
+ const moduleSpecFile = path.join(targetRootDir, 'AutoSnippet.boxspec.json');
298
+ await saveFromFile(moduleSpecFile, snippet);
249
299
  return;
250
300
  }
251
301
 
@@ -253,8 +303,14 @@ function readStream(specFile, filePathArr, snippet, isHaveHeader) {
253
303
  const packageInfo = await findPath.parsePackageSwift(packagePath);
254
304
  if (!packageInfo) {
255
305
  snippet['{content}'] = codeList;
256
- const moduleSpecFile = path.join(path.dirname(packagePath), 'AutoSnippet.boxspec.json');
257
- saveFromFile(moduleSpecFile, snippet);
306
+ // 查找 target 根目录(Code 或 Sources 的父目录)
307
+ let targetRootDir = await findTargetRootDir(filePath);
308
+ if (!targetRootDir) {
309
+ // 如果找不到,使用 Package.swift 所在目录作为后备
310
+ targetRootDir = path.dirname(packagePath);
311
+ }
312
+ const moduleSpecFile = path.join(targetRootDir, 'AutoSnippet.boxspec.json');
313
+ await saveFromFile(moduleSpecFile, snippet);
258
314
  return;
259
315
  }
260
316
 
@@ -262,50 +318,54 @@ function readStream(specFile, filePathArr, snippet, isHaveHeader) {
262
318
  const moduleName = determineModuleName(filePath, packageInfo);
263
319
  const headerNameWithoutExt = fileName.substring(0, fileName.length - 2); // 移除 .h
264
320
 
265
- // ✅ 模块根目录就是 Package.swift 所在目录(packageInfo.path)
266
- // .boxspec.json 文件将创建在这个目录下(与 Package.swift 同级)
267
- const moduleRoot = packageInfo.path;
321
+ // ✅ 查找 target 根目录(Code 或 Sources 的父目录)
322
+ let targetRootDir = await findTargetRootDir(filePath);
323
+ if (!targetRootDir) {
324
+ // 如果找不到 target 根目录,使用 Package.swift 所在目录作为后备
325
+ targetRootDir = packageInfo.path;
326
+ }
327
+ console.log(`[createCodeSnippets] target 根目录: ${targetRootDir}`);
328
+ const moduleRoot = targetRootDir;
268
329
 
269
330
  // ✅ 查找头文件(适配 SPM 的 include/ModuleName/ 结构)
270
- // 在 Package.swift 所在目录下查找(可能包含 Services/Services/... 这样的结构)
271
- const headerPath = await findPath.findSubHeaderPath(moduleRoot, headerNameWithoutExt, moduleName);
331
+ // 在 target 根目录下查找(可能包含 Code/ 或 Sources/ 这样的结构)
332
+ const headerPath = await findPath.findSubHeaderPath(targetRootDir, headerNameWithoutExt, moduleName);
272
333
 
273
334
  snippet['{content}'] = codeList;
274
335
  snippet['{specName}'] = moduleName; // ✅ specName 是 target 名称(如 BDNetworkAPI),不是包名(如 Business)
275
336
 
276
337
  if (headerPath) {
277
- // ✅ headName 存储相对于 Package.swift 所在目录的相对路径
278
- // 例如:如果 Package.swift 在 Business/,头文件在 Business/Business/BDNetworkAPI/Code/xxx.h
279
- // 则 headName = "Business/BDNetworkAPI/Code/xxx.h"
280
- const headerRelativePath = path.relative(moduleRoot, headerPath);
338
+ // ✅ headName 存储相对于 target 根目录的相对路径
339
+ // 例如:target 根目录在 BDNetworkAPI/,头文件在 BDNetworkAPI/Code/xxx.h
340
+ // 则 headName = "Code/xxx.h"
341
+ const headerRelativePath = path.relative(targetRootDir, headerPath);
281
342
  snippet['{headName}'] = headerRelativePath;
282
343
  } else {
283
344
  // 如果找不到头文件,使用文件名
284
345
  snippet['{headName}'] = fileName;
285
346
  }
286
347
 
287
- // 查找 README.md
348
+ // 查找 README.md(在 target 根目录)
288
349
  try {
289
- const readmePath = path.join(packageInfo.path, README_NAME);
350
+ const readmePath = path.join(targetRootDir, README_NAME);
290
351
  await fs.promises.access(readmePath);
291
- const moduleRoot = packageInfo.path;
292
- const readmeRelativePath = path.relative(moduleRoot, readmePath);
352
+ const readmeRelativePath = path.relative(targetRootDir, readmePath);
293
353
  snippet['{readme}'] = encodeURI(readmeRelativePath);
294
354
  } catch {
295
355
  // README.md 不存在,跳过
296
356
  }
297
357
 
298
- // ✅ SPM 模块:.boxspec 文件位置在模块根目录(与 Package.swift 同级)
299
- const moduleSpecFile = path.join(packageInfo.path, 'AutoSnippet.boxspec.json');
300
- saveFromFile(moduleSpecFile, snippet);
301
- }).catch(function (err) {
358
+ // ✅ SPM 模块:.boxspec 文件位置在 target 根目录(Code 或 Sources 的父目录)
359
+ const moduleSpecFile = path.join(targetRootDir, 'AutoSnippet.boxspec.json');
360
+ await saveFromFile(moduleSpecFile, snippet);
361
+ }).catch(async function (err) {
302
362
  console.error('Error finding Package.swift:', err);
303
363
  snippet['{content}'] = codeList;
304
- saveFromFile(specFile, snippet);
364
+ await saveFromFile(specFile, snippet);
305
365
  });
306
366
  } else {
307
367
  snippet['{content}'] = codeList;
308
- saveFromFile(specFile, snippet);
368
+ await saveFromFile(specFile, snippet);
309
369
  }
310
370
  // 移除ACode标识
311
371
  removeAcodeMark(filePath, positionList);
@@ -315,7 +375,8 @@ function readStream(specFile, filePathArr, snippet, isHaveHeader) {
315
375
  });
316
376
  }
317
377
 
318
- function saveFromFile(specFile, snippet) {
378
+ async function saveFromFile(specFile, snippet) {
379
+ const findPath = require('./findPath.js');
319
380
  let placeholder = null;
320
381
 
321
382
  try {
@@ -370,7 +431,58 @@ function saveFromFile(specFile, snippet) {
370
431
  console.log(err);
371
432
  }
372
433
  cache.updateCache(specFile, content);
373
- // ✅ 只写入刚创建的代码片段,而不是所有代码片段
434
+
435
+ // ✅ 同步到根目录的 AutoSnippetRoot.boxspec.json
436
+ try {
437
+ const rootSpecFile = await findPath.getRootSpecFilePath(specFile);
438
+ if (rootSpecFile) {
439
+ // 读取根配置文件
440
+ let rootPlaceholder = null;
441
+ try {
442
+ const rootData = fs.readFileSync(rootSpecFile, 'utf8');
443
+ if (rootData) {
444
+ rootPlaceholder = JSON.parse(rootData);
445
+ }
446
+ } catch (err) {
447
+ if (err.code === 'ENOENT') {
448
+ rootPlaceholder = { list: [] };
449
+ } else {
450
+ console.error(`[saveFromFile] 读取根配置文件失败: ${err.message}`);
451
+ }
452
+ }
453
+
454
+ if (rootPlaceholder != null) {
455
+ // 检查是否已存在相同的 identifier
456
+ let exists = false;
457
+ if (rootPlaceholder.list) {
458
+ for (let i = 0; i < rootPlaceholder.list.length; i++) {
459
+ if (rootPlaceholder.list[i]['{identifier}'] === snippet['{identifier}']) {
460
+ // 已存在,更新它
461
+ rootPlaceholder.list[i] = snippet;
462
+ exists = true;
463
+ break;
464
+ }
465
+ }
466
+ } else {
467
+ rootPlaceholder.list = [];
468
+ }
469
+
470
+ // 如果不存在,添加到列表
471
+ if (!exists) {
472
+ rootPlaceholder.list.push(snippet);
473
+ }
474
+
475
+ // 写入根配置文件
476
+ const rootContent = JSON.stringify(rootPlaceholder, null, 4);
477
+ fs.writeFileSync(rootSpecFile, rootContent, 'utf8');
478
+ console.log(`[saveFromFile] 已同步 snippet 到根目录配置文件: ${rootSpecFile}`);
479
+ }
480
+ }
481
+ } catch (err) {
482
+ console.error(`[saveFromFile] 同步到根配置文件失败: ${err.message}`);
483
+ }
484
+
485
+ // ✅ 只写入刚创建的单个代码片段
374
486
  install.addCodeSnippets(specFile, snippet);
375
487
  }
376
488
  }
package/bin/findPath.js CHANGED
@@ -4,6 +4,7 @@ const fs = require('fs');
4
4
  const path = require('path');
5
5
  // 全局常量
6
6
  const HOLDER_NAME = 'AutoSnippet.boxspec.json';
7
+ const ROOT_MARKER_NAME = 'AutoSnippetRoot.boxspec.json'; // 项目根目录标记文件
7
8
  const PACKAGE_SWIFT = 'Package.swift';
8
9
  const README_NAME = 'readme.md';
9
10
 
@@ -503,13 +504,13 @@ async function findSubASSpecPath(filePath) {
503
504
  }
504
505
 
505
506
  /**
506
- * 向上查找项目根目录(包含 .git、Package.swift 等的目录)
507
+ * 向上查找项目根目录(查找 AutoSnippetRoot.boxspec.json 文件)
507
508
  * @param {string} filePath - 起始文件路径或目录路径
508
- * @returns {Promise<string|null>} 项目根目录路径,如果找不到返回 null
509
+ * @returns {Promise<string|null>} 项目根目录路径(AutoSnippetRoot.boxspec.json 所在目录),如果找不到返回 null
509
510
  */
510
511
  async function findProjectRoot(filePath) {
511
512
  console.log(`[findProjectRoot] 开始查找,传入路径: ${filePath}`);
512
- // ✅ 确保从目录路径开始查找,如果是文件路径,先转换为目录路径
513
+ // ✅ 简化逻辑:向上查找 AutoSnippetRoot.boxspec.json 文件
513
514
  let currentPath = path.resolve(filePath);
514
515
 
515
516
  // 检查路径是文件还是目录
@@ -537,9 +538,16 @@ async function findProjectRoot(filePath) {
537
538
 
538
539
  while (currentPath && levelsChecked < maxLevels) {
539
540
  try {
540
- const entries = await getDirectoryEntries(currentPath);
541
- if (entries && isProjectRoot(currentPath, entries)) {
542
- return currentPath;
541
+ // 查找 AutoSnippetRoot.boxspec.json 文件
542
+ const rootMarkerPath = path.join(currentPath, ROOT_MARKER_NAME);
543
+ try {
544
+ const stats = await fs.promises.stat(rootMarkerPath);
545
+ if (stats.isFile()) {
546
+ console.log(`[findProjectRoot] 找到根目录标记文件: ${rootMarkerPath}`);
547
+ return currentPath;
548
+ }
549
+ } catch (err) {
550
+ // 文件不存在,继续向上查找
543
551
  }
544
552
 
545
553
  const parentPath = path.dirname(currentPath);
@@ -549,7 +557,7 @@ async function findProjectRoot(filePath) {
549
557
  currentPath = parentPath;
550
558
  levelsChecked++;
551
559
  } catch (err) {
552
- // ✅ 处理各种文件系统错误,包括 ENOTDIR
560
+ // ✅ 处理各种文件系统错误
553
561
  if (err.code === 'ENOENT' || err.code === 'EACCES' || err.code === 'ENOTDIR') {
554
562
  const parentPath = path.dirname(currentPath);
555
563
  if (parentPath === currentPath) {
@@ -563,6 +571,7 @@ async function findProjectRoot(filePath) {
563
571
  }
564
572
  }
565
573
 
574
+ console.log(`[findProjectRoot] 未找到根目录标记文件 ${ROOT_MARKER_NAME}`);
566
575
  return null;
567
576
  }
568
577
 
@@ -661,6 +670,35 @@ async function findModuleDirectory(dirPath, moduleName, headerFileName) {
661
670
  return null;
662
671
  }
663
672
 
673
+ /**
674
+ * 获取根目录的 AutoSnippetRoot.boxspec.json 文件路径
675
+ * @param {string} filePath - 起始文件路径或目录路径
676
+ * @returns {Promise<string|null>} 根目录的 AutoSnippetRoot.boxspec.json 文件路径,如果找不到返回 null
677
+ */
678
+ async function getRootSpecFilePath(filePath) {
679
+ const projectRoot = await findProjectRoot(filePath);
680
+ if (!projectRoot) {
681
+ return null;
682
+ }
683
+ const rootSpecFile = path.join(projectRoot, ROOT_MARKER_NAME);
684
+
685
+ // 检查文件是否存在,如果不存在则创建
686
+ try {
687
+ await fs.promises.access(rootSpecFile);
688
+ } catch (err) {
689
+ if (err.code === 'ENOENT') {
690
+ // 文件不存在,创建它
691
+ const specObj = {
692
+ list: []
693
+ };
694
+ const content = JSON.stringify(specObj, null, 4);
695
+ fs.writeFileSync(rootSpecFile, content, 'utf8');
696
+ }
697
+ }
698
+
699
+ return rootSpecFile;
700
+ }
701
+
664
702
  exports.findASSpecPath = findASSpecPath;
665
703
  exports.findASSpecPathAsync = findASSpecPathAsync;
666
704
  exports.findPackageSwiftPath = findPackageSwiftPath;
@@ -668,4 +706,6 @@ exports.parsePackageSwift = parsePackageSwift;
668
706
  exports.findSubHeaderPath = findSubHeaderPath;
669
707
  exports.findSubASSpecPath = findSubASSpecPath;
670
708
  exports.findProjectRoot = findProjectRoot;
671
- exports.findModuleHeaderFromRoot = findModuleHeaderFromRoot;
709
+ exports.findModuleHeaderFromRoot = findModuleHeaderFromRoot;
710
+ exports.getRootSpecFilePath = getRootSpecFilePath;
711
+ exports.ROOT_MARKER_NAME = ROOT_MARKER_NAME;
package/bin/init.js CHANGED
@@ -16,16 +16,22 @@ async function mergeSubSpecs(mainSpecFile) {
16
16
  list: []
17
17
  };
18
18
 
19
- // ✅ 从项目根目录开始查找,而不是从主配置文件所在目录
20
- // 找到项目根目录(包含 .git、Package.swift 等的目录)
19
+ // ✅ 找到项目根目录的 AutoSnippetRoot.boxspec.json 文件
21
20
  console.log(`[mergeSubSpecs] 主配置文件路径: ${mainSpecFile}`);
22
- const projectRoot = await findPath.findProjectRoot(mainSpecFile);
23
- const searchRoot = projectRoot || path.dirname(mainSpecFile);
24
- console.log(`[mergeSubSpecs] 项目根目录: ${projectRoot || 'null'}`);
21
+ const rootSpecFile = await findPath.getRootSpecFilePath(mainSpecFile);
22
+ if (!rootSpecFile) {
23
+ console.error(`[mergeSubSpecs] 未找到项目根目录,无法聚合配置`);
24
+ return;
25
+ }
26
+ console.log(`[mergeSubSpecs] 根目录配置文件: ${rootSpecFile}`);
27
+
28
+ const projectRoot = path.dirname(rootSpecFile);
29
+ const searchRoot = projectRoot;
30
+ console.log(`[mergeSubSpecs] 项目根目录: ${projectRoot}`);
25
31
  console.log(`[mergeSubSpecs] 搜索根目录: ${searchRoot}`);
26
32
 
27
- const specSlashIndex = mainSpecFile.lastIndexOf('/');
28
- const specFilePath = mainSpecFile.substring(0, specSlashIndex + 1);
33
+ const specSlashIndex = rootSpecFile.lastIndexOf('/');
34
+ const specFilePath = rootSpecFile.substring(0, specSlashIndex + 1);
29
35
 
30
36
  // ✅ 从项目根目录向下查找子模块的 AutoSnippet.boxspec.json
31
37
  console.log(`[mergeSubSpecs] 开始查找子模块配置,搜索根目录: ${searchRoot}`);
@@ -37,8 +43,9 @@ async function mergeSubSpecs(mainSpecFile) {
37
43
 
38
44
  const slashIndex = filename.lastIndexOf('/');
39
45
  let thePath = filename.substring(0, slashIndex + 1);
40
- if (filename === mainSpecFile) {
41
- thePath = '';
46
+ if (filename === rootSpecFile) {
47
+ // 跳过根目录的 AutoSnippetRoot.boxspec.json,避免循环引用
48
+ continue;
42
49
  } else {
43
50
  thePath = thePath.replace(specFilePath, '');
44
51
  }
@@ -69,33 +76,92 @@ async function mergeSubSpecs(mainSpecFile) {
69
76
  try {
70
77
  const content = JSON.stringify(specObj, null, 4);
71
78
  if (content) {
72
- fs.writeFileSync(mainSpecFile, content, 'utf8');
79
+ // 写入根目录的 AutoSnippetRoot.boxspec.json
80
+ fs.writeFileSync(rootSpecFile, content, 'utf8');
81
+ console.log(`[mergeSubSpecs] 已聚合 ${specObj.list.length} 个 snippet 到根目录配置文件`);
73
82
  }
74
83
  } catch (err) {
75
84
  console.error(err);
76
85
  }
77
86
  }
78
87
 
88
+ /**
89
+ * 从目录路径确定 target 的根目录(包含 Code 或 Sources 的目录)
90
+ * @param {string} dirPath - 目录路径
91
+ * @returns {Promise<string|null>} target 根目录路径,如果找不到返回 null
92
+ */
93
+ async function findTargetRootDirFromPath(dirPath) {
94
+ let currentPath = path.resolve(dirPath);
95
+ const maxLevels = 10;
96
+ let levelsChecked = 0;
97
+
98
+ // ✅ 向上查找包含 Code 或 Sources 目录的目录(target 根目录)
99
+ while (currentPath && levelsChecked < maxLevels) {
100
+ try {
101
+ const entries = await fs.promises.readdir(currentPath, { withFileTypes: true });
102
+
103
+ // 检查当前目录是否包含 Code 或 Sources 目录
104
+ for (const entry of entries) {
105
+ if (entry.isDirectory() && (entry.name === 'Code' || entry.name === 'Sources')) {
106
+ // 找到包含 Code 或 Sources 的目录,这就是 target 根目录
107
+ console.log(`[findTargetRootDirFromPath] 找到 target 根目录: ${currentPath} (包含 ${entry.name})`);
108
+ return currentPath;
109
+ }
110
+ }
111
+
112
+ // 继续向上查找
113
+ const parentPath = path.dirname(currentPath);
114
+ if (parentPath === currentPath) {
115
+ break;
116
+ }
117
+ currentPath = parentPath;
118
+ levelsChecked++;
119
+ } catch (err) {
120
+ if (err.code === 'ENOENT' || err.code === 'EACCES') {
121
+ break;
122
+ }
123
+ throw err;
124
+ }
125
+ }
126
+
127
+ console.log(`[findTargetRootDirFromPath] 未找到 target 根目录(Code 或 Sources)`);
128
+ return null;
129
+ }
130
+
79
131
  async function initSpec() {
80
- // ✅ 查找 Package.swift,在其同级目录创建 AutoSnippet.boxspec.json
81
- let packagePath = await findPath.findPackageSwiftPath(CMD_PATH);
132
+ // ✅ 查找 target 根目录(包含 Code 或 Sources 的目录),在该目录创建 AutoSnippet.boxspec.json
133
+ let targetRootDir = await findTargetRootDirFromPath(CMD_PATH);
134
+
135
+ // 如果找不到 target 根目录,尝试查找 Package.swift 作为后备
136
+ if (!targetRootDir) {
137
+ let packagePath = await findPath.findPackageSwiftPath(CMD_PATH);
138
+ if (packagePath) {
139
+ targetRootDir = path.dirname(packagePath);
140
+ console.log(`[initSpec] 使用 Package.swift 所在目录作为 target 根目录: ${targetRootDir}`);
141
+ } else {
142
+ // 如果都找不到,使用当前目录
143
+ targetRootDir = CMD_PATH;
144
+ console.log(`[initSpec] 使用当前目录作为 target 根目录: ${targetRootDir}`);
145
+ }
146
+ }
82
147
 
83
- // 如果找不到 Package.swift,使用当前目录
84
- const configDir = packagePath ? path.dirname(packagePath) : CMD_PATH;
85
- const filePath = path.join(configDir, 'AutoSnippet.boxspec.json');
148
+ const filePath = path.join(targetRootDir, 'AutoSnippet.boxspec.json');
149
+ console.log(`[initSpec] 将在 target 根目录创建配置文件: ${filePath}`);
86
150
 
87
151
  // 如果配置文件不存在,创建一个空的
88
152
  try {
89
153
  await fs.promises.access(filePath);
154
+ console.log(`[initSpec] 配置文件已存在: ${filePath}`);
90
155
  } catch (error) {
91
156
  const specObj = {
92
157
  list: []
93
158
  };
94
159
  const content = JSON.stringify(specObj, null, 4);
95
160
  fs.writeFileSync(filePath, content, 'utf8');
161
+ console.log(`[initSpec] 已创建配置文件: ${filePath}`);
96
162
  }
97
163
 
98
- // ✅ 聚合子模块配置到主配置文件
164
+ // ✅ 聚合子模块配置到根目录的 AutoSnippetRoot.boxspec.json
99
165
  await mergeSubSpecs(filePath);
100
166
  }
101
167
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autosnippet",
3
- "version": "1.1.19",
3
+ "version": "1.1.20",
4
4
  "description": "A iOS module management tool.",
5
5
  "main": "index.js",
6
6
  "scripts": {