-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit-utils.ts
More file actions
145 lines (121 loc) · 4.28 KB
/
git-utils.ts
File metadata and controls
145 lines (121 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path';
/**
* 从当前工作区的Git配置中自动提取GitLab项目信息
*/
export class GitConfigParser {
/**
* 尝试从当前工作区获取GitLab项目ID
* @returns GitLab项目ID(格式:group/project 或 数字ID),如果不是GitLab项目返回null
*/
public static async getGitlabProjectIdFromWorkspace(): Promise<string | null> {
const workspaceFolders = vscode.workspace.workspaceFolders;
if (!workspaceFolders || workspaceFolders.length === 0) {
return null;
}
// 尝试第一个工作区文件夹
const workspacePath = workspaceFolders[0].uri.fsPath;
const gitConfigPath = path.join(workspacePath, '.git', 'config');
// 检查.git/config是否存在
if (!fs.existsSync(gitConfigPath)) {
return null;
}
try {
const configContent = fs.readFileSync(gitConfigPath, 'utf-8');
return this.parseGitlabProjectId(configContent);
} catch (error) {
console.error('Failed to read git config:', error);
return null;
}
}
/**
* 检查当前工作区是否是GitLab项目
* @returns 如果是GitLab项目返回true,否则返回false
*/
public static async isGitlabProject(): Promise<boolean> {
const projectId = await this.getGitlabProjectIdFromWorkspace();
return projectId !== null;
}
/**
* 从Git配置内容中解析GitLab项目ID
* @param configContent .git/config文件内容
* @returns GitLab项目ID或null
*/
private static parseGitlabProjectId(configContent: string): string | null {
// 匹配 remote "origin" 部分的URL
// 示例格式:
// [remote "origin"]
// url = git@gitlab.com:username/project.git
// url = https://gitlab.com/username/project.git
// url = git@gitlab.your-company.com:group/subgroup/project.git
const urlMatch = configContent.match(/\[remote "origin"\]\s*\n\s*url\s*=\s*(.+)/);
if (!urlMatch || !urlMatch[1]) {
return null;
}
const remoteUrl = urlMatch[1].trim();
// 检查是否是GitLab URL(包含gitlab关键字)
if (!remoteUrl.toLowerCase().includes('gitlab')) {
return null;
}
// 解析不同格式的GitLab URL
let projectPath: string | null = null;
// SSH格式: git@gitlab.com:username/project.git
const sshMatch = remoteUrl.match(/git@[^:]+:(.+?)(?:\.git)?$/);
if (sshMatch) {
projectPath = sshMatch[1];
}
// HTTPS格式: https://gitlab.com/username/project.git
const httpsMatch = remoteUrl.match(/https?:\/\/[^\/]+\/(.+?)(?:\.git)?$/);
if (httpsMatch) {
projectPath = httpsMatch[1];
}
if (projectPath) {
// 直接返回项目路径,不进行URL编码
// gitbeaker库会自动处理URL编码
// 例如:argos/argos-server(不要编码为argos%2Fargos-server)
return projectPath;
}
return null;
}
/**
* 从Git配置中提取GitLab服务器地址
* @returns GitLab服务器地址或null
*/
public static async getGitlabServerUrl(): Promise<string | null> {
const workspaceFolders = vscode.workspace.workspaceFolders;
if (!workspaceFolders || workspaceFolders.length === 0) {
return null;
}
const workspacePath = workspaceFolders[0].uri.fsPath;
const gitConfigPath = path.join(workspacePath, '.git', 'config');
if (!fs.existsSync(gitConfigPath)) {
return null;
}
try {
const configContent = fs.readFileSync(gitConfigPath, 'utf-8');
const urlMatch = configContent.match(/\[remote "origin"\]\s*\n\s*url\s*=\s*(.+)/);
if (!urlMatch || !urlMatch[1]) {
return null;
}
const remoteUrl = urlMatch[1].trim();
if (!remoteUrl.toLowerCase().includes('gitlab')) {
return null;
}
// SSH格式: git@gitlab.com:... -> https://gitlab.com
const sshMatch = remoteUrl.match(/git@([^:]+):/);
if (sshMatch) {
return `https://${sshMatch[1]}`;
}
// HTTPS格式: https://gitlab.com/... -> https://gitlab.com
const httpsMatch = remoteUrl.match(/(https?:\/\/[^\/]+)/);
if (httpsMatch) {
return httpsMatch[1];
}
return null;
} catch (error) {
console.error('Failed to read git config:', error);
return null;
}
}
}