Skip to content

Commit 5e5d791

Browse files
♻️ refactor(scm): 优化源代码管理部分
- 【Git】重构 GitProvider,添加类型定义并简化文件状态检测 - 【SVN】优化 SvnProvider 的错误处理和日志输出 - 【SCM】改进 SCMFactory 的可靠性和错误处理 - 【架构】统一错误处理和日志记录格式
1 parent 73dfaf4 commit 5e5d791

File tree

3 files changed

+60
-50
lines changed

3 files changed

+60
-50
lines changed

src/scm/GitProvider.ts

+21-26
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,25 @@ import { LocalizationManager } from "../utils/LocalizationManager";
77

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

10+
interface GitAPI {
11+
repositories: GitRepository[];
12+
getAPI(version: number): GitAPI;
13+
}
14+
15+
interface GitRepository {
16+
inputBox: {
17+
value: string;
18+
};
19+
commit(message: string, options: { all: boolean; files?: string[] }): Promise<void>;
20+
}
21+
1022
export class GitProvider implements ISCMProvider {
1123
type = "git" as const;
1224
private workspaceRoot: string;
25+
private readonly api: GitAPI;
1326

1427
constructor(private readonly gitExtension: any) {
28+
this.api = gitExtension.getAPI(1);
1529
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
1630
if (!workspaceRoot) {
1731
throw new Error(
@@ -27,39 +41,20 @@ export class GitProvider implements ISCMProvider {
2741
return repositories.length > 0;
2842
}
2943

44+
// 优化 getFileStatus 方法
3045
private async getFileStatus(file: string): Promise<string> {
3146
try {
32-
// 检查文件是否是新文件
33-
const { stdout: lsFiles } = await exec(`git ls-files "${file}"`, {
47+
const { stdout: status } = await exec(`git status --porcelain "${file}"`, {
3448
cwd: this.workspaceRoot,
3549
});
3650

37-
if (!lsFiles) {
38-
const { stdout: status } = await exec(
39-
`git status --porcelain "${file}"`,
40-
{
41-
cwd: this.workspaceRoot,
42-
}
43-
);
44-
if (status.startsWith("??")) {
45-
return "New File";
46-
}
47-
}
48-
49-
// 检查文件是否被删除
50-
const { stdout: status } = await exec(
51-
`git status --porcelain "${file}"`,
52-
{
53-
cwd: this.workspaceRoot,
54-
}
55-
);
56-
if (status.startsWith(" D") || status.startsWith("D ")) {
57-
return "Deleted File";
58-
}
59-
51+
if (!status) return "Unknown";
52+
53+
if (status.startsWith("??")) return "New File";
54+
if (status.startsWith(" D") || status.startsWith("D ")) return "Deleted File";
6055
return "Modified File";
6156
} catch (error) {
62-
console.error(`Error getting file status: ${error}`);
57+
console.error("Failed to get file status:", error instanceof Error ? error.message : error);
6358
return "Unknown";
6459
}
6560
}

src/scm/SCMProvider.ts

+31-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from "vscode";
22
import { GitProvider } from "./GitProvider";
33
import { SvnProvider } from "./SvnProvider";
4+
import { LocalizationManager } from "../utils/LocalizationManager";
45

56
export interface ISCMProvider {
67
type: "git" | "svn";
@@ -14,32 +15,46 @@ export class SCMFactory {
1415
private static currentProvider: ISCMProvider | undefined;
1516

1617
static async detectSCM(): Promise<ISCMProvider | undefined> {
17-
if (this.currentProvider) {
18-
return this.currentProvider;
19-
}
18+
try {
19+
if (this.currentProvider) {
20+
return this.currentProvider;
21+
}
2022

21-
const gitExtension = vscode.extensions.getExtension("vscode.git")?.exports;
22-
const svnExtension = vscode.extensions.getExtension(
23-
"johnstoncode.svn-scm"
24-
)?.exports;
23+
const gitExtension = vscode.extensions.getExtension("vscode.git");
24+
const svnExtension = vscode.extensions.getExtension(
25+
"johnstoncode.svn-scm"
26+
);
27+
28+
if (!gitExtension && !svnExtension) {
29+
throw new Error(
30+
LocalizationManager.getInstance().getMessage("scm.no.provider")
31+
);
32+
}
2533

26-
if (gitExtension) {
27-
const git = new GitProvider(gitExtension);
28-
if (await git.isAvailable()) {
34+
const git = gitExtension?.exports
35+
? new GitProvider(gitExtension.exports)
36+
: undefined;
37+
if (git && (await git.isAvailable())) {
2938
this.currentProvider = git;
3039
return git;
3140
}
32-
}
3341

34-
if (svnExtension) {
35-
const svn = new SvnProvider(svnExtension);
36-
if (await svn.isAvailable()) {
42+
const svn = svnExtension?.exports
43+
? new SvnProvider(svnExtension.exports)
44+
: undefined;
45+
if (svn && (await svn.isAvailable())) {
3746
this.currentProvider = svn;
3847
return svn;
3948
}
40-
}
4149

42-
return undefined;
50+
return undefined;
51+
} catch (error) {
52+
console.error(
53+
"SCM detection failed:",
54+
error instanceof Error ? error.message : error
55+
);
56+
return undefined;
57+
}
4358
}
4459

4560
static getCurrentSCMType(): "git" | "svn" | undefined {

src/scm/SvnProvider.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,7 @@ export class SvnProvider implements ISCMProvider {
2626

2727
async isAvailable(): Promise<boolean> {
2828
try {
29-
console.log("typeof", this.svnExtension, this.svnExtension.name);
30-
if (
31-
!this.svnExtension ||
32-
typeof this.svnExtension.getAPI !== "function"
33-
) {
29+
if (!this.svnExtension?.getAPI) {
3430
return false;
3531
}
3632

@@ -43,7 +39,7 @@ export class SvnProvider implements ISCMProvider {
4339
}
4440
return false;
4541
} catch (error) {
46-
console.error("Failed to check SVN availability:", error);
42+
console.error("SVN availability check failed:", error instanceof Error ? error.message : error);
4743
return false;
4844
}
4945
}
@@ -97,6 +93,7 @@ export class SvnProvider implements ISCMProvider {
9793
// 如果未启用简化,直接返回原始diff
9894
return stdout;
9995
} catch (error) {
96+
console.error("SVN diff failed:", error instanceof Error ? error.message : error);
10097
if (error instanceof Error) {
10198
vscode.window.showErrorMessage(
10299
LocalizationManager.getInstance().format(
@@ -118,9 +115,12 @@ export class SvnProvider implements ISCMProvider {
118115
}
119116

120117
try {
121-
await repository.commitFiles(files || [], message);
118+
if (!files?.length) {
119+
throw new Error(LocalizationManager.getInstance().getMessage("svn.no.files.selected"));
120+
}
121+
await repository.commitFiles(files, message);
122122
} catch (error) {
123-
console.error("Failed to commit to SVN:", error);
123+
console.error("SVN commit failed:", error instanceof Error ? error.message : error);
124124
throw new Error(
125125
LocalizationManager.getInstance().format("svn.commit.failed", error)
126126
);

0 commit comments

Comments
 (0)