Skip to content

Commit 79801c4

Browse files
📝 docs(scm): 添加源代码管理模块详细注释和类型定义
- 【代码完善】为所有SCM相关类添加完整的JSDoc文档注释 - 【类型增强】完善接口定义与类型声明 - 【结构优化】规范化错误处理和异常提示 - 【文档补充】补充各个类的职责说明和使用说明 - 【代码规范】统一异步方法的错误处理风格 - 【可维护性】增加关键流程的详细注释说明
1 parent 2e70f09 commit 79801c4

6 files changed

+276
-11
lines changed

src/scm/AuthorService.ts

+28-1
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,50 @@ import { LocalizationManager } from "../utils/LocalizationManager";
66

77
const execAsync = promisify(exec);
88

9+
/**
10+
* 作者服务类
11+
* 用于获取Git或SVN仓库的作者信息
12+
*/
913
export class AuthorService {
14+
/**
15+
* 构造函数
16+
* @param workspacePath 工作区路径
17+
*/
1018
constructor(private readonly workspacePath: string) {}
1119

20+
/**
21+
* 获取仓库作者信息
22+
* @param type 仓库类型:'git'或'svn'
23+
* @returns 作者名称
24+
*/
1225
async getAuthor(type: "git" | "svn"): Promise<string> {
1326
if (type === "git") {
1427
return this.getGitAuthor();
1528
}
1629
return this.getSvnAuthor();
1730
}
1831

32+
/**
33+
* 获取Git仓库的作者信息
34+
* @returns Git配置中的用户名
35+
*/
1936
private async getGitAuthor(): Promise<string> {
2037
const { stdout } = await execAsync("git config user.name");
2138
return stdout.trim();
2239
}
2340

41+
/**
42+
* 获取SVN仓库的作者信息
43+
* 优先从SVN身份验证信息获取,如果失败则提示用户手动输入
44+
* @returns SVN作者名称
45+
* @throws 如果无法获取作者信息则抛出错误
46+
*/
2447
private async getSvnAuthor(): Promise<string> {
25-
// await SvnUtils.getSvnAuthorFromInfo(this.workspacePath) ||
2648
console.log(
2749
"getSvnAuthorFromAuth",
2850
await SvnUtils.getSvnAuthorFromAuth(this.workspacePath)
2951
);
52+
// 尝试从SVN认证信息获取作者,如果失败则提示手动输入
3053
const author =
3154
(await SvnUtils.getSvnAuthorFromAuth(this.workspacePath)) ||
3255
(await this.promptForAuthor());
@@ -40,6 +63,10 @@ export class AuthorService {
4063
return author;
4164
}
4265

66+
/**
67+
* 提示用户手动输入作者信息
68+
* @returns 用户输入的作者名称,如果用户取消则返回undefined
69+
*/
4370
private async promptForAuthor(): Promise<string | undefined> {
4471
const locManager = LocalizationManager.getInstance();
4572
return vscode.window.showInputBox({

src/scm/CommitLogStrategy.ts

+45-2
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,52 @@ import { DateUtils } from "../utils/DateUtils";
44

55
const execAsync = promisify(exec);
66

7+
/**
8+
* 表示一个时间段的接口
9+
*/
710
interface Period {
11+
/** 开始日期 */
812
startDate: string;
13+
/** 结束日期 */
914
endDate: string;
1015
}
1116

17+
/**
18+
* 提交日志策略接口
19+
* 定义了获取代码提交记录的统一接口
20+
*/
1221
export interface CommitLogStrategy {
22+
/**
23+
* 获取指定时间段内指定作者的提交记录
24+
* @param workspacePath 工作区路径
25+
* @param period 时间段
26+
* @param author 作者名
27+
* @returns 提交记录数组
28+
*/
1329
getCommits(
1430
workspacePath: string,
1531
period: Period,
1632
author: string
1733
): Promise<string[]>;
1834
}
1935

36+
/**
37+
* Git提交记录策略实现类
38+
*/
2039
export class GitCommitStrategy implements CommitLogStrategy {
40+
/**
41+
* 获取Git仓库的提交记录
42+
* @param workspacePath Git仓库路径
43+
* @param period 查询的时间段
44+
* @param author 提交作者
45+
* @returns 格式化后的提交记录数组
46+
*/
2147
async getCommits(
2248
workspacePath: string,
2349
period: Period,
2450
author: string
2551
): Promise<string[]> {
52+
// 构建git log命令,格式化输出提交信息
2653
const command = `git log --since="${period.startDate}" --until="${period.endDate}" --pretty=format:"%h - %an, %ar : %s" --author="${author}"`;
2754

2855
console.log("command", command);
@@ -31,14 +58,23 @@ export class GitCommitStrategy implements CommitLogStrategy {
3158
}
3259
}
3360

61+
/**
62+
* SVN提交记录策略实现类
63+
*/
3464
export class SvnCommitStrategy implements CommitLogStrategy {
65+
/**
66+
* 获取SVN仓库的提交记录
67+
* @param workspacePath SVN仓库路径
68+
* @param period 查询的时间段
69+
* @param author 提交作者
70+
* @returns 解析后的提交记录数组
71+
*/
3572
async getCommits(
3673
workspacePath: string,
3774
period: Period,
3875
author: string
3976
): Promise<string[]> {
40-
// const { startDate, endDate } = DateUtils.getDateRangeFromPeriod(period);
41-
77+
// 构建svn log命令,使用XML格式输出
4278
const command = `svn log -r "{${period.startDate}}:{${period.endDate}}" --search="${author}" --xml`;
4379

4480
console.log("command", command);
@@ -47,12 +83,19 @@ export class SvnCommitStrategy implements CommitLogStrategy {
4783
return this.parseXmlLogs(stdout);
4884
}
4985

86+
/**
87+
* 解析SVN的XML格式日志输出
88+
* @param xmlOutput XML格式的SVN日志输出
89+
* @returns 提取的提交消息数组
90+
*/
5091
private parseXmlLogs(xmlOutput: string): string[] {
5192
const commits: string[] = [];
93+
// 匹配<logentry>标签内的<msg>内容
5294
const logEntriesRegex =
5395
/<logentry[^>]*>[\s\S]*?<msg>([\s\S]*?)<\/msg>[\s\S]*?<\/logentry>/g;
5496
let match;
5597

98+
// 循环提取所有匹配的提交消息
5699
while ((match = logEntriesRegex.exec(xmlOutput)) !== null) {
57100
if (match[1]?.trim()) {
58101
commits.push(match[1].trim());

src/scm/GitProvider.ts

+71-5
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,59 @@ import { LocalizationManager } from "../utils/LocalizationManager";
77

88
const exec = promisify(childProcess.exec);
99

10+
/**
11+
* Git API接口定义
12+
*/
1013
interface GitAPI {
14+
/** Git仓库集合 */
1115
repositories: GitRepository[];
16+
17+
/**
18+
* 获取指定版本的Git API
19+
* @param version - API版本号
20+
*/
1221
getAPI(version: number): GitAPI;
1322
}
1423

24+
/**
25+
* Git仓库接口定义
26+
*/
1527
interface GitRepository {
28+
/** 提交信息输入框 */
1629
inputBox: {
1730
value: string;
1831
};
32+
33+
/**
34+
* 执行提交操作
35+
* @param message - 提交信息
36+
* @param options - 提交选项
37+
*/
1938
commit(
2039
message: string,
2140
options: { all: boolean; files?: string[] }
2241
): Promise<void>;
2342
}
2443

44+
/**
45+
* Git源代码管理提供者实现
46+
* @implements {ISCMProvider}
47+
*/
2548
export class GitProvider implements ISCMProvider {
49+
/** SCM类型标识符 */
2650
type = "git" as const;
51+
52+
/** 工作区根目录路径 */
2753
private workspaceRoot: string;
54+
55+
/** Git API实例 */
2856
private readonly api: GitAPI;
2957

58+
/**
59+
* 创建Git提供者实例
60+
* @param gitExtension - VS Code Git扩展实例
61+
* @throws {Error} 当未找到工作区时抛出错误
62+
*/
3063
constructor(private readonly gitExtension: any) {
3164
this.api = gitExtension.getAPI(1);
3265
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
@@ -38,13 +71,22 @@ export class GitProvider implements ISCMProvider {
3871
this.workspaceRoot = workspaceRoot;
3972
}
4073

74+
/**
75+
* 检查Git是否可用
76+
* @returns {Promise<boolean>} 如果Git可用返回true,否则返回false
77+
*/
4178
async isAvailable(): Promise<boolean> {
4279
const api = this.gitExtension.getAPI(1);
4380
const repositories = api.repositories;
4481
return repositories.length > 0;
4582
}
4683

47-
// 优化 getFileStatus 方法
84+
/**
85+
* 获取文件状态
86+
* @param {string} file - 文件路径
87+
* @returns {Promise<string>} 返回文件状态描述
88+
* @private
89+
*/
4890
private async getFileStatus(file: string): Promise<string> {
4991
try {
5092
const { stdout: status } = await exec(
@@ -74,27 +116,35 @@ export class GitProvider implements ISCMProvider {
74116
}
75117
}
76118

119+
/**
120+
* 获取文件差异信息
121+
* @param {string[]} [files] - 可选的文件路径数组
122+
* @returns {Promise<string | undefined>} 返回差异文本
123+
* @throws {Error} 当执行diff命令失败时抛出错误
124+
*/
77125
async getDiff(files?: string[]): Promise<string | undefined> {
78126
try {
79127
let diffOutput = "";
80128

81129
if (files && files.length > 0) {
82-
// 处理多个文件的情况
130+
// 处理指定文件的差异
83131
for (const file of files) {
84132
const fileStatus = await this.getFileStatus(file);
85-
const escapedFile = file.replace(/"/g, '\\"');
133+
const escapedFile = file.replace(/"/g, '\\"'); // 转义文件路径中的双引号
86134

135+
// 执行单个文件的diff命令
87136
const { stdout } = await exec(`git diff HEAD -- "${escapedFile}"`, {
88137
cwd: this.workspaceRoot,
89-
maxBuffer: 1024 * 1024 * 10,
138+
maxBuffer: 1024 * 1024 * 10, // 设置更大的缓冲区以处理大型差异
90139
});
91140

141+
// 添加文件状态和差异信息
92142
if (stdout.trim()) {
93143
diffOutput += `\n=== ${fileStatus}: ${file} ===\n${stdout}`;
94144
}
95145
}
96146
} else {
97-
// 处理所有改动文件的情况
147+
// 获取所有更改的差异
98148
const { stdout } = await exec("git diff HEAD", {
99149
cwd: this.workspaceRoot,
100150
maxBuffer: 1024 * 1024 * 10,
@@ -148,6 +198,12 @@ export class GitProvider implements ISCMProvider {
148198
}
149199
}
150200

201+
/**
202+
* 提交更改
203+
* @param {string} message - 提交信息
204+
* @param {string[]} [files] - 要提交的文件路径数组
205+
* @throws {Error} 当提交失败或未找到仓库时抛出错误
206+
*/
151207
async commit(message: string, files?: string[]): Promise<void> {
152208
const api = this.gitExtension.getAPI(1);
153209
const repository = api.repositories[0];
@@ -161,6 +217,11 @@ export class GitProvider implements ISCMProvider {
161217
await repository.commit(message, { all: files ? false : true, files });
162218
}
163219

220+
/**
221+
* 设置提交输入框的内容
222+
* @param {string} message - 要设置的提交信息
223+
* @throws {Error} 当未找到仓库时抛出错误
224+
*/
164225
async setCommitInput(message: string): Promise<void> {
165226
const api = this.gitExtension.getAPI(1);
166227
const repository = api.repositories[0];
@@ -174,6 +235,11 @@ export class GitProvider implements ISCMProvider {
174235
repository.inputBox.value = message;
175236
}
176237

238+
/**
239+
* 获取提交输入框的当前内容
240+
* @returns {Promise<string>} 返回当前的提交信息
241+
* @throws {Error} 当未找到仓库时抛出错误
242+
*/
177243
async getCommitInput(): Promise<string> {
178244
const api = this.gitExtension.getAPI(1);
179245
const repository = api.repositories[0];

src/scm/SCMProvider.ts

+28
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,42 @@ import { GitProvider } from "./GitProvider";
33
import { SvnProvider } from "./SvnProvider";
44
import { LocalizationManager } from "../utils/LocalizationManager";
55

6+
/**
7+
* 源代码管理提供者接口
8+
* 定义了通用的SCM操作方法
9+
*/
610
export interface ISCMProvider {
11+
/** SCM类型:"git" 或 "svn" */
712
type: "git" | "svn";
13+
14+
/** 检查SCM系统是否可用 */
815
isAvailable(): Promise<boolean>;
16+
17+
/** 获取文件差异 */
918
getDiff(files?: string[]): Promise<string | undefined>;
19+
20+
/** 提交更改 */
1021
commit(message: string, files?: string[]): Promise<void>;
22+
23+
/** 设置提交信息 */
1124
setCommitInput(message: string): Promise<void>;
25+
26+
/** 获取当前提交信息 */
1227
getCommitInput(): Promise<string>;
1328
}
1429

30+
/**
31+
* SCM工厂类
32+
* 用于创建和管理源代码管理提供者实例
33+
*/
1534
export class SCMFactory {
35+
/** 当前激活的SCM提供者实例 */
1636
private static currentProvider: ISCMProvider | undefined;
1737

38+
/**
39+
* 检测并创建可用的SCM提供者
40+
* @returns {Promise<ISCMProvider | undefined>} 返回可用的SCM提供者实例,如果没有可用的提供者则返回undefined
41+
*/
1842
static async detectSCM(): Promise<ISCMProvider | undefined> {
1943
try {
2044
if (this.currentProvider) {
@@ -58,6 +82,10 @@ export class SCMFactory {
5882
}
5983
}
6084

85+
/**
86+
* 获取当前使用的SCM类型
87+
* @returns {"git" | "svn" | undefined} 返回当前SCM类型,如果未设置则返回undefined
88+
*/
6189
static getCurrentSCMType(): "git" | "svn" | undefined {
6290
return this.currentProvider?.type;
6391
}

0 commit comments

Comments
 (0)