g2log 1.5.1 → 1.6.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.
Files changed (2) hide show
  1. package/git-user-log.js +157 -1
  2. package/package.json +1 -1
package/git-user-log.js CHANGED
@@ -281,6 +281,154 @@ function listRepositories() {
281
281
  return config.repositories || {};
282
282
  }
283
283
 
284
+ // 递归搜索指定目录下的所有 Git 仓库
285
+ async function findGitRepositories(searchPath, maxDepth = 3, currentDepth = 0) {
286
+ const results = [];
287
+
288
+ // 如果达到最大深度,停止搜索
289
+ if (currentDepth >= maxDepth) {
290
+ return results;
291
+ }
292
+
293
+ try {
294
+ const entries = fs.readdirSync(searchPath, { withFileTypes: true });
295
+
296
+ for (const entry of entries) {
297
+ const fullPath = path.join(searchPath, entry.name);
298
+
299
+ // 跳过隐藏目录和特殊目录
300
+ if (entry.name.startsWith('.')) {
301
+ continue;
302
+ }
303
+
304
+ // 跳过 node_modules 等常见不需要搜索的目录
305
+ const skipDirs = ['node_modules', '.git', 'dist', 'build', 'target', 'vendor', '.vscode', '.idea'];
306
+ if (skipDirs.includes(entry.name)) {
307
+ continue;
308
+ }
309
+
310
+ if (entry.isDirectory()) {
311
+ // 检查是否是 Git 仓库
312
+ const gitDir = path.join(fullPath, '.git');
313
+ if (fs.existsSync(gitDir)) {
314
+ // 使用文件夹名作为别名
315
+ results.push({
316
+ alias: entry.name,
317
+ path: fullPath
318
+ });
319
+ } else {
320
+ // 递归搜索子目录
321
+ const subResults = await findGitRepositories(fullPath, maxDepth, currentDepth + 1);
322
+ results.push(...subResults);
323
+ }
324
+ }
325
+ }
326
+ } catch (error) {
327
+ // 忽略无权限访问的目录
328
+ }
329
+
330
+ return results;
331
+ }
332
+
333
+ // 从用户主目录搜索 Git 仓库并添加到配置
334
+ async function findAndAddRepositories() {
335
+ const spinner = createSpinner();
336
+ const searchPaths = [
337
+ path.join(os.homedir(), 'Projects'),
338
+ path.join(os.homedir(), 'projects'),
339
+ path.join(os.homedir(), 'Workspace'),
340
+ path.join(os.homedir(), 'workspace'),
341
+ path.join(os.homedir(), 'Development'),
342
+ path.join(os.homedir(), 'development'),
343
+ path.join(os.homedir(), 'code'),
344
+ path.join(os.homedir(), 'src'),
345
+ os.homedir()
346
+ ];
347
+
348
+ console.log(colorize('\n🔍 正在搜索 Git 仓库...', 'cyan'));
349
+ console.log(colorize('搜索路径:', 'dim'), searchPaths.join(', '));
350
+ console.log('');
351
+
352
+ const allRepos = [];
353
+ const seenPaths = new Set();
354
+
355
+ for (const searchPath of searchPaths) {
356
+ if (!fs.existsSync(searchPath)) {
357
+ continue;
358
+ }
359
+
360
+ spinner.start(`🔍 正在搜索: ${searchPath}`);
361
+ const repos = await findGitRepositories(searchPath, 3);
362
+
363
+ for (const repo of repos) {
364
+ if (!seenPaths.has(repo.path)) {
365
+ seenPaths.add(repo.path);
366
+ allRepos.push(repo);
367
+ }
368
+ }
369
+ }
370
+
371
+ spinner.stop(`✅ 搜索完成,找到 ${allRepos.length} 个 Git 仓库`);
372
+
373
+ if (allRepos.length === 0) {
374
+ console.log(colorize('⚠️ 未找到任何 Git 仓库', 'yellow'));
375
+ console.log(colorize('💡 提示: 请将项目放在常见的目录中(如 ~/Projects, ~/Workspace 等)', 'cyan'));
376
+ return 0;
377
+ }
378
+
379
+ // 显示找到的仓库
380
+ console.log(colorize('\n📦 找到的仓库:', 'bright'));
381
+ console.log(colorize('─'.repeat(50), 'dim'));
382
+ allRepos.forEach((repo, index) => {
383
+ console.log(` ${colorize(String(index + 1) + '.', 'green')} ${colorize(repo.alias, 'cyan')}: ${repo.path}`);
384
+ });
385
+ console.log(colorize('─'.repeat(50), 'dim'));
386
+
387
+ // 询问是否添加到配置
388
+ const rl = readline.createInterface({
389
+ input: process.stdin,
390
+ output: process.stdout
391
+ });
392
+
393
+ const question = (query) => new Promise((resolve) => rl.question(query, resolve));
394
+
395
+ try {
396
+ const answer = await question(colorize('\n❓ 是否将这些仓库添加到配置?(y/n): ', 'cyan'));
397
+ rl.close();
398
+
399
+ if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
400
+ const config = loadConfig();
401
+ if (!config.repositories) {
402
+ config.repositories = {};
403
+ }
404
+
405
+ let addedCount = 0;
406
+ for (const repo of allRepos) {
407
+ // 处理重名,添加后缀
408
+ let alias = repo.alias;
409
+ let counter = 1;
410
+ while (config.repositories[alias]) {
411
+ alias = `${repo.alias}-${counter}`;
412
+ counter++;
413
+ }
414
+
415
+ config.repositories[alias] = repo.path;
416
+ addedCount++;
417
+ }
418
+
419
+ saveConfig(config);
420
+ console.log(colorize(`\n✅ 已添加 ${addedCount} 个仓库到配置文件`, 'green'));
421
+ return addedCount;
422
+ } else {
423
+ console.log(colorize('ℹ️ 已取消', 'blue'));
424
+ return 0;
425
+ }
426
+ } catch (error) {
427
+ rl.close();
428
+ return 0;
429
+ }
430
+ }
431
+
284
432
  // 创建一个高级spinner
285
433
  function createSpinner() {
286
434
  // 如果ora模块未加载完成或不支持,提供一个简单的替代方案
@@ -450,6 +598,7 @@ function showHelp() {
450
598
  --version 显示当前版本号
451
599
 
452
600
  配置管理:
601
+ --find 自动搜索并添加 Git 仓库到配置
453
602
  --config 启动交互式配置向导
454
603
  --set-api-key 设置API密钥
455
604
  --set-api-provider 设置API提供商 (OpenAI/DeepSeek)
@@ -462,6 +611,7 @@ function showHelp() {
462
611
  --uninstall 删除g2log配置文件 (~/.git-user-log-config.json)
463
612
 
464
613
  示例:
614
+ g2log --find # 自动搜索并添加仓库
465
615
  g2log # 获取所有作者的提交
466
616
  g2log --author "张三" # 只获取张三的提交
467
617
  g2log --since "2024-01-01" --until "2024-01-31"
@@ -1779,7 +1929,13 @@ async function getGitLogs() {
1779
1929
  process.exit(1);
1780
1930
  }
1781
1931
  }
1782
-
1932
+
1933
+ // 搜索并添加仓库
1934
+ if (args.find) {
1935
+ const count = await findAndAddRepositories();
1936
+ process.exit(count > 0 ? 0 : 1);
1937
+ }
1938
+
1783
1939
  // 显示NPX运行信息
1784
1940
  showNpxInfo();
1785
1941
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "g2log",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "查询Git提交记录并通过AI进行总结,支持多作者、多仓库,可通过npx直接运行",
5
5
  "main": "git-user-log.js",
6
6
  "bin": {