git-yike-logger-hook
Version:
A TypeScript Git hook plugin for automatically generating commit logs with TODO/WIP comment scanning
569 lines (425 loc) • 11.8 kB
Markdown
# API 参考文档
## 概述
Git Logger Hook 提供了一套完整的 API 用于生成和管理 Git 提交日志。所有 API 都是异步的,返回 Promise 对象。
## 核心类
### GitLogger
主要的日志生成器类,负责协调各个模块完成日志生成。
#### 构造函数
```typescript
constructor(config?: Partial<LoggerConfig>)
```
**参数:**
- `config` (可选): 配置选项
**示例:**
```typescript
import { GitLogger } from 'git-logger-hook';
// 使用默认配置
const logger = new GitLogger();
// 自定义配置
const logger = new GitLogger({
logDir: './custom-logs',
includeUnstaged: true
});
```
#### 方法
##### generateLog()
生成并保存当前提交的日志。
```typescript
async generateLog(): Promise<void>
```
**返回值:** `Promise<void>`
**异常:**
- `Error`: 如果不在 Git 仓库中
- `Error`: 如果无法获取提交信息
- `Error`: 如果无法写入日志文件
**示例:**
```typescript
try {
await logger.generateLog();
console.log('日志生成成功');
} catch (error) {
console.error('日志生成失败:', error.message);
}
```
##### getAllLogs()
获取所有日志文件。
```typescript
async getAllLogs(): Promise<CommitLog[]>
```
**返回值:** `Promise<CommitLog[]>` - 按时间倒序排列的日志数组
**示例:**
```typescript
const logs = await logger.getAllLogs();
console.log(`找到 ${logs.length} 个日志文件`);
logs.forEach(log => {
console.log(`${log.timestamp}: ${log.message}`);
console.log(`TODO: ${log.comments.todos.length} 个`);
console.log(`WIP: ${log.comments.wips.length} 个`);
});
```
##### cleanupLogs()
清理旧日志文件。
```typescript
async cleanupLogs(keepCount: number): Promise<void>
```
**参数:**
- `keepCount`: 保留的日志文件数量
**返回值:** `Promise<void>`
**示例:**
```typescript
// 只保留最近 50 个日志文件
await logger.cleanupLogs(50);
```
### GitUtils
Git 操作工具类,封装了所有 Git 相关操作。
#### 构造函数
```typescript
constructor()
```
#### 方法
##### getCurrentCommitInfo()
获取当前提交信息。
```typescript
async getCurrentCommitInfo(): Promise<Partial<CommitLog>>
```
**返回值:** `Promise<Partial<CommitLog>>` - 包含以下字段的对象:
- `author`: 提交人信息
- `timestamp`: 提交时间
- `message`: 提交消息
- `commitHash`: 提交哈希
**示例:**
```typescript
const gitUtils = new GitUtils();
const commitInfo = await gitUtils.getCurrentCommitInfo();
if (commitInfo.commitHash) {
console.log(`提交哈希: ${commitInfo.commitHash}`);
console.log(`提交人: ${commitInfo.author?.name}`);
console.log(`提交时间: ${commitInfo.timestamp}`);
} else {
console.log('这是首次提交');
}
```
##### getCurrentBranch()
获取当前分支名称。
```typescript
async getCurrentBranch(): Promise<string>
```
**返回值:** `Promise<string>` - 分支名称,如果无法获取则返回 'unknown'
**示例:**
```typescript
const branch = await gitUtils.getCurrentBranch();
console.log(`当前分支: ${branch}`);
```
##### getRemoteInfo()
获取远程仓库信息。
```typescript
async getRemoteInfo(): Promise<{ name: string; url: string } | undefined>
```
**返回值:** `Promise<{ name: string; url: string } | undefined>` - 远程仓库信息,如果无法获取则返回 undefined
**示例:**
```typescript
const remote = await gitUtils.getRemoteInfo();
if (remote) {
console.log(`远程仓库: ${remote.name} - ${remote.url}`);
} else {
console.log('没有配置远程仓库');
}
```
##### getFileChanges()
获取文件变更信息。
```typescript
async getFileChanges(): Promise<{
added: string[];
modified: string[];
deleted: string[];
renamed: Array<{ from: string; to: string }>;
}>
```
**返回值:** 包含文件变更信息的对象
**示例:**
```typescript
const changes = await gitUtils.getFileChanges();
console.log(`新增文件: ${changes.added.length} 个`);
console.log(`修改文件: ${changes.modified.length} 个`);
console.log(`删除文件: ${changes.deleted.length} 个`);
console.log(`重命名文件: ${changes.renamed.length} 个`);
```
##### isGitRepository()
检查是否在 Git 仓库中。
```typescript
async isGitRepository(): Promise<boolean>
```
**返回值:** `Promise<boolean>` - 是否在 Git 仓库中
**示例:**
```typescript
const isRepo = await gitUtils.isGitRepository();
if (!isRepo) {
console.log('当前目录不是 Git 仓库');
process.exit(1);
}
```
### CommentScanner
代码注释扫描器,用于提取 JavaScript/TypeScript 文件中的注释。
#### 构造函数
```typescript
constructor()
```
#### 方法
##### scanDirectory()
扫描目录下所有 JavaScript/TypeScript 文件。
```typescript
async scanDirectory(dirPath: string): Promise<{
todos: CodeComment[];
wips: CodeComment[];
}>
```
**参数:**
- `dirPath`: 要扫描的目录路径
**返回值:** 包含 TODO 和 WIP 注释的对象
**示例:**
```typescript
const scanner = new CommentScanner();
const comments = await scanner.scanDirectory('./src');
console.log(`找到 ${comments.todos.length} 个 TODO 注释`);
console.log(`找到 ${comments.wips.length} 个 WIP 注释`);
comments.todos.forEach(todo => {
console.log(`${todo.filePath}:${todo.lineNumber} - ${todo.content}`);
});
```
##### scanFile()
扫描单个文件。
```typescript
async scanFile(filePath: string): Promise<{
todos: CodeComment[];
wips: CodeComment[];
}>
```
**参数:**
- `filePath`: 文件路径
**返回值:** 包含 TODO 和 WIP 注释的对象
**示例:**
```typescript
const scanner = new CommentScanner();
const comments = await scanner.scanFile('./src/example.js');
comments.todos.forEach(todo => {
console.log(`行 ${todo.lineNumber}: ${todo.content}`);
});
```
##### scanChangedFiles()
扫描变更的文件。
```typescript
async scanChangedFiles(changedFiles: {
added: string[];
modified: string[];
deleted: string[];
}): Promise<{
todos: CodeComment[];
wips: CodeComment[];
}>
```
**参数:**
- `changedFiles`: 变更文件列表
**返回值:** 包含 TODO 和 WIP 注释的对象
**示例:**
```typescript
const scanner = new CommentScanner();
const gitUtils = new GitUtils();
const fileChanges = await gitUtils.getFileChanges();
const comments = await scanner.scanChangedFiles(fileChanges);
console.log(`变更文件中的注释: ${comments.todos.length + comments.wips.length} 个`);
```
## 数据类型
### CommitLog
提交日志的数据结构。
```typescript
interface CommitLog {
author: {
name: string;
email: string;
};
timestamp: string;
message: string;
commitHash: string;
changedFiles: {
added: string[];
modified: string[];
deleted: string[];
renamed: Array<{
from: string;
to: string;
}>;
};
branch: string;
remote?: {
name: string;
url: string;
};
comments: {
todos: CodeComment[];
wips: CodeComment[];
};
}
```
### CodeComment
代码注释的数据结构。
```typescript
interface CodeComment {
type: 'TODO' | 'WIP';
content: string;
filePath: string;
lineNumber: number;
fullLine: string;
}
```
### LoggerConfig
日志生成器的配置选项。
```typescript
interface LoggerConfig {
logDir: string;
includeUnstaged: boolean;
includeUntracked: boolean;
filePatterns?: string[];
}
```
### GitStatus
Git 状态信息。
```typescript
interface GitStatus {
staged: string[];
unstaged: string[];
untracked: string[];
}
```
## 错误处理
### 常见错误类型
#### GitRepositoryError
当不在 Git 仓库中时抛出。
```typescript
try {
await logger.generateLog();
} catch (error) {
if (error.message.includes('不是 Git 仓库')) {
console.log('请在 Git 仓库中运行此命令');
}
}
```
#### CommitInfoError
当无法获取提交信息时抛出。
```typescript
try {
const commitInfo = await gitUtils.getCurrentCommitInfo();
} catch (error) {
if (error.message.includes('获取提交信息失败')) {
console.log('无法获取提交信息,可能是首次提交');
}
}
```
#### FileSystemError
当文件系统操作失败时抛出。
```typescript
try {
await logger.generateLog();
} catch (error) {
if (error.message.includes('无法写入')) {
console.log('请检查文件权限');
}
}
```
## 使用示例
### 基本使用
```typescript
import { GitLogger } from 'git-logger-hook';
async function main() {
const logger = new GitLogger();
try {
// 生成日志
await logger.generateLog();
console.log('日志生成成功');
// 获取所有日志
const logs = await logger.getAllLogs();
console.log(`共有 ${logs.length} 个日志文件`);
// 清理旧日志
await logger.cleanupLogs(100);
console.log('旧日志清理完成');
} catch (error) {
console.error('操作失败:', error.message);
}
}
main();
```
### 自定义配置
```typescript
import { GitLogger } from 'git-logger-hook';
const logger = new GitLogger({
logDir: './custom-logs',
includeUnstaged: true,
includeUntracked: false,
filePatterns: ['*.js', '*.ts', '*.jsx', '*.tsx']
});
await logger.generateLog();
```
### 单独使用注释扫描器
```typescript
import { CommentScanner } from 'git-logger-hook';
const scanner = new CommentScanner();
// 扫描单个文件
const fileComments = await scanner.scanFile('./src/example.js');
console.log('TODO:', fileComments.todos);
console.log('WIP:', fileComments.wips);
// 扫描整个目录
const dirComments = await scanner.scanDirectory('./src');
console.log(`目录中总共有 ${dirComments.todos.length + dirComments.wips.length} 个注释`);
```
### 单独使用 Git 工具
```typescript
import { GitUtils } from 'git-logger-hook';
const gitUtils = new GitUtils();
// 检查是否在 Git 仓库中
const isRepo = await gitUtils.isGitRepository();
if (!isRepo) {
console.log('请在 Git 仓库中运行');
process.exit(1);
}
// 获取当前分支
const branch = await gitUtils.getCurrentBranch();
console.log(`当前分支: ${branch}`);
// 获取文件变更
const changes = await gitUtils.getFileChanges();
console.log('文件变更:', changes);
```
## 最佳实践
### 1. 错误处理
```typescript
async function safeGenerateLog() {
try {
await logger.generateLog();
} catch (error) {
console.error('日志生成失败:', error.message);
// 不要因为日志生成失败而阻止提交
process.exit(0);
}
}
```
### 2. 性能优化
```typescript
// 只扫描变更的文件,不要扫描整个项目
const fileChanges = await gitUtils.getFileChanges();
const comments = await scanner.scanChangedFiles(fileChanges);
```
### 3. 配置管理
```typescript
// 使用环境变量或配置文件
const config = {
logDir: process.env.LOG_DIR || '.git-logs',
includeUnstaged: process.env.INCLUDE_UNSTAGED === 'true',
includeUntracked: process.env.INCLUDE_UNTRACKED === 'true'
};
const logger = new GitLogger(config);
```
### 4. 日志轮转
```typescript
// 定期清理旧日志
setInterval(async () => {
await logger.cleanupLogs(100);
}, 24 * 60 * 60 * 1000); // 每天清理一次
```