Skip to content

Commit

Permalink
♻️ refactor(scm): 优化源代码管理部分
Browse files Browse the repository at this point in the history
- 【Git】重构 GitProvider,添加类型定义并简化文件状态检测
- 【SVN】优化 SvnProvider 的错误处理和日志输出
- 【SCM】改进 SCMFactory 的可靠性和错误处理
- 【架构】统一错误处理和日志记录格式
  • Loading branch information
littleCareless committed Dec 10, 2024
1 parent 73dfaf4 commit 5e5d791
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 50 deletions.
47 changes: 21 additions & 26 deletions src/scm/GitProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,25 @@ import { LocalizationManager } from "../utils/LocalizationManager";

const exec = promisify(childProcess.exec);

interface GitAPI {
repositories: GitRepository[];
getAPI(version: number): GitAPI;
}

interface GitRepository {
inputBox: {
value: string;
};
commit(message: string, options: { all: boolean; files?: string[] }): Promise<void>;
}

export class GitProvider implements ISCMProvider {
type = "git" as const;
private workspaceRoot: string;
private readonly api: GitAPI;

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

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

if (!lsFiles) {
const { stdout: status } = await exec(
`git status --porcelain "${file}"`,
{
cwd: this.workspaceRoot,
}
);
if (status.startsWith("??")) {
return "New File";
}
}

// 检查文件是否被删除
const { stdout: status } = await exec(
`git status --porcelain "${file}"`,
{
cwd: this.workspaceRoot,
}
);
if (status.startsWith(" D") || status.startsWith("D ")) {
return "Deleted File";
}

if (!status) return "Unknown";

if (status.startsWith("??")) return "New File";
if (status.startsWith(" D") || status.startsWith("D ")) return "Deleted File";
return "Modified File";
} catch (error) {
console.error(`Error getting file status: ${error}`);
console.error("Failed to get file status:", error instanceof Error ? error.message : error);
return "Unknown";
}
}
Expand Down
47 changes: 31 additions & 16 deletions src/scm/SCMProvider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as vscode from "vscode";
import { GitProvider } from "./GitProvider";
import { SvnProvider } from "./SvnProvider";
import { LocalizationManager } from "../utils/LocalizationManager";

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

static async detectSCM(): Promise<ISCMProvider | undefined> {
if (this.currentProvider) {
return this.currentProvider;
}
try {
if (this.currentProvider) {
return this.currentProvider;
}

const gitExtension = vscode.extensions.getExtension("vscode.git")?.exports;
const svnExtension = vscode.extensions.getExtension(
"johnstoncode.svn-scm"
)?.exports;
const gitExtension = vscode.extensions.getExtension("vscode.git");
const svnExtension = vscode.extensions.getExtension(
"johnstoncode.svn-scm"
);

if (!gitExtension && !svnExtension) {
throw new Error(
LocalizationManager.getInstance().getMessage("scm.no.provider")
);
}

if (gitExtension) {
const git = new GitProvider(gitExtension);
if (await git.isAvailable()) {
const git = gitExtension?.exports
? new GitProvider(gitExtension.exports)
: undefined;
if (git && (await git.isAvailable())) {
this.currentProvider = git;
return git;
}
}

if (svnExtension) {
const svn = new SvnProvider(svnExtension);
if (await svn.isAvailable()) {
const svn = svnExtension?.exports
? new SvnProvider(svnExtension.exports)
: undefined;
if (svn && (await svn.isAvailable())) {
this.currentProvider = svn;
return svn;
}
}

return undefined;
return undefined;
} catch (error) {
console.error(
"SCM detection failed:",
error instanceof Error ? error.message : error
);
return undefined;
}
}

static getCurrentSCMType(): "git" | "svn" | undefined {
Expand Down
16 changes: 8 additions & 8 deletions src/scm/SvnProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@ export class SvnProvider implements ISCMProvider {

async isAvailable(): Promise<boolean> {
try {
console.log("typeof", this.svnExtension, this.svnExtension.name);
if (
!this.svnExtension ||
typeof this.svnExtension.getAPI !== "function"
) {
if (!this.svnExtension?.getAPI) {
return false;
}

Expand All @@ -43,7 +39,7 @@ export class SvnProvider implements ISCMProvider {
}
return false;
} catch (error) {
console.error("Failed to check SVN availability:", error);
console.error("SVN availability check failed:", error instanceof Error ? error.message : error);
return false;
}
}
Expand Down Expand Up @@ -97,6 +93,7 @@ export class SvnProvider implements ISCMProvider {
// 如果未启用简化,直接返回原始diff
return stdout;
} catch (error) {
console.error("SVN diff failed:", error instanceof Error ? error.message : error);
if (error instanceof Error) {
vscode.window.showErrorMessage(
LocalizationManager.getInstance().format(
Expand All @@ -118,9 +115,12 @@ export class SvnProvider implements ISCMProvider {
}

try {
await repository.commitFiles(files || [], message);
if (!files?.length) {
throw new Error(LocalizationManager.getInstance().getMessage("svn.no.files.selected"));
}
await repository.commitFiles(files, message);
} catch (error) {
console.error("Failed to commit to SVN:", error);
console.error("SVN commit failed:", error instanceof Error ? error.message : error);
throw new Error(
LocalizationManager.getInstance().format("svn.commit.failed", error)
);
Expand Down

0 comments on commit 5e5d791

Please sign in to comment.