mirror of
https://gitea.computerliebe.org/ComputerLiebe_ORG_private/Gitea-VSCode-Clone-Plugin.git
synced 2025-07-05 20:23:41 +00:00
Support of multiple Gitea instances
* chore(gitea-git-clone): update CHANGELOG.md and README.md * feat(gitea-git-clone): add support for multiple Gitea instances * feat(gitea-git-clone): enhance status bar integration with branch and build status * fix(gitea-git-clone): fix issues with status bar items not updating correctly * fix(gitea-git-clone): fix issues with long commit messages causing errors when creating pull requests
This commit is contained in:
@ -19,33 +19,46 @@ interface GiteaErrorResponse {
|
||||
}>;
|
||||
}
|
||||
|
||||
// Interface für Gitea-Instanzen
|
||||
interface GiteaInstance {
|
||||
name: string;
|
||||
url: string;
|
||||
token: string;
|
||||
}
|
||||
|
||||
// Initialisiere die Lokalisierung
|
||||
const localize = nls.config({ messageFormat: nls.MessageFormat.file })();
|
||||
|
||||
// Globale Variablen für Statusleisten-Icons
|
||||
let statusBarItem: vscode.StatusBarItem | null = null;
|
||||
let prStatusBarItem: vscode.StatusBarItem | null = null;
|
||||
let branchStatusBarItem: vscode.StatusBarItem | null = null;
|
||||
let buildStatusBarItem: vscode.StatusBarItem | null = null;
|
||||
|
||||
// Hilfsfunktion, um zu prüfen, ob ein Ordner ein Git-Repository ist
|
||||
async function isGitRepository(folderPath: string): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
exec(`git rev-parse --is-inside-work-tree`, { cwd: folderPath }, (error) => {
|
||||
resolve(!error);
|
||||
});
|
||||
});
|
||||
// Hilfsfunktion, um die Gitea-Instanzen zu laden
|
||||
function getGiteaInstances(): GiteaInstance[] {
|
||||
const instances = vscode.workspace.getConfiguration().get<any[]>('gitea.instances');
|
||||
if (!instances) {
|
||||
return [];
|
||||
}
|
||||
return instances.map((instance) => ({
|
||||
name: instance.name,
|
||||
url: instance.url,
|
||||
token: instance.token,
|
||||
}));
|
||||
}
|
||||
|
||||
// Hilfsfunktion, um zu prüfen, ob das Remote-Repository eine Gitea-Instanz ist
|
||||
async function isGiteaRepository(folderPath: string): Promise<boolean> {
|
||||
const instanceUrl = vscode.workspace.getConfiguration().get<string>('gitea.instanceUrl');
|
||||
if (!instanceUrl) {
|
||||
return false;
|
||||
// Hilfsfunktion, um die passende Gitea-Instanz basierend auf der Remote-URL zu ermitteln
|
||||
async function getMatchingGiteaInstance(folderPath: string): Promise<GiteaInstance | null> {
|
||||
const instances = getGiteaInstances();
|
||||
if (instances.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
exec(`git config --get remote.origin.url`, { cwd: folderPath }, (error, stdout) => {
|
||||
if (error || !stdout) {
|
||||
resolve(false);
|
||||
resolve(null);
|
||||
} else {
|
||||
let repoUrl = stdout.trim();
|
||||
|
||||
@ -59,22 +72,24 @@ async function isGiteaRepository(folderPath: string): Promise<boolean> {
|
||||
repoUrl = repoUrl.replace('.git', '');
|
||||
}
|
||||
|
||||
resolve(repoUrl.startsWith(instanceUrl));
|
||||
const matchingInstance = instances.find((instance) => repoUrl.startsWith(instance.url));
|
||||
resolve(matchingInstance || null);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Hilfsfunktion, um zu prüfen, ob ein Ordner ein Git-Repository ist
|
||||
async function isGitRepository(folderPath: string): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
exec(`git rev-parse --is-inside-work-tree`, { cwd: folderPath }, (error) => {
|
||||
resolve(!error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Funktion zum Erstellen eines Pull Requests
|
||||
async function createGiteaPullRequest() {
|
||||
const instanceUrl = vscode.workspace.getConfiguration().get<string>('gitea.instanceUrl');
|
||||
const token = vscode.workspace.getConfiguration().get<string>('gitea.personalAccessToken');
|
||||
|
||||
if (!instanceUrl || !token) {
|
||||
vscode.window.showErrorMessage(localize('giteaClone.configMissing', 'Gitea URL or Token is not configured.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Aktuellen Workspace-Ordner abrufen
|
||||
const currentWorkspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath;
|
||||
if (!currentWorkspaceFolder) {
|
||||
@ -89,13 +104,16 @@ async function createGiteaPullRequest() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prüfen, ob Remote-Repository eine Gitea-Instanz ist
|
||||
const isGiteaRepo = await isGiteaRepository(currentWorkspaceFolder);
|
||||
if (!isGiteaRepo) {
|
||||
// Kein Gitea-Repository, keine Aktion erforderlich
|
||||
// Passende Gitea-Instanz ermitteln
|
||||
const giteaInstance = await getMatchingGiteaInstance(currentWorkspaceFolder);
|
||||
if (!giteaInstance) {
|
||||
// Keine passende Gitea-Instanz gefunden
|
||||
return;
|
||||
}
|
||||
|
||||
const instanceUrl = giteaInstance.url;
|
||||
const token = giteaInstance.token;
|
||||
|
||||
// Git-Repository-Informationen abrufen
|
||||
exec(`git config --get remote.origin.url`, { cwd: currentWorkspaceFolder }, async (error, stdout, stderr) => {
|
||||
if (error || !stdout) {
|
||||
@ -122,32 +140,32 @@ async function createGiteaPullRequest() {
|
||||
// Den letzten Commit und den Branch abrufen
|
||||
const { title, body } = await getLastCommit(currentWorkspaceFolder);
|
||||
const branch = await getCurrentBranch(currentWorkspaceFolder);
|
||||
|
||||
|
||||
if (!branch) {
|
||||
vscode.window.showErrorMessage(localize('giteaClone.noBranch', 'Could not determine the branch.'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Base-Branch über die Gitea API ermitteln
|
||||
const baseBranch = await getDefaultBranch(instanceUrl, owner, repo, token);
|
||||
|
||||
|
||||
// Titel und Body auf maximale Länge beschränken
|
||||
const maxTitleLength = 255;
|
||||
const maxBodyLength = 65535; // Beispielwert, kann je nach Gitea-Konfiguration variieren
|
||||
|
||||
|
||||
let truncatedTitle = title;
|
||||
let truncatedBody = body;
|
||||
|
||||
|
||||
if (title.length > maxTitleLength) {
|
||||
truncatedTitle = title.substring(0, maxTitleLength);
|
||||
vscode.window.showWarningMessage(localize('giteaClone.titleTruncated', 'The commit message was too long and has been truncated for the pull request title.'));
|
||||
}
|
||||
|
||||
|
||||
if (body.length > maxBodyLength) {
|
||||
truncatedBody = body.substring(0, maxBodyLength);
|
||||
vscode.window.showWarningMessage(localize('giteaClone.bodyTruncated', 'The commit message body was too long and has been truncated for the pull request description.'));
|
||||
}
|
||||
|
||||
|
||||
// API-Request-Daten vorbereiten
|
||||
const prData = {
|
||||
title: truncatedTitle, // Der getrunkierte Titel
|
||||
@ -277,14 +295,34 @@ async function getDefaultBranch(instanceUrl: string, owner: string, repo: string
|
||||
|
||||
// Funktion zum Abrufen der Repositories des Benutzers von Gitea
|
||||
async function getGiteaRepositories(): Promise<any[]> {
|
||||
const instanceUrl = vscode.workspace.getConfiguration().get<string>('gitea.instanceUrl');
|
||||
const token = vscode.workspace.getConfiguration().get<string>('gitea.personalAccessToken');
|
||||
const instances = getGiteaInstances();
|
||||
|
||||
if (!instanceUrl || !token) {
|
||||
vscode.window.showErrorMessage(localize('giteaClone.configMissing', 'Gitea URL or Token is not configured.'));
|
||||
if (instances.length === 0) {
|
||||
vscode.window.showErrorMessage(localize('giteaClone.configMissing', 'No Gitea instances are configured.'));
|
||||
return [];
|
||||
}
|
||||
|
||||
// Benutzer wählt eine Gitea-Instanz aus
|
||||
const instanceNames = instances.map(instance => instance.name);
|
||||
const selectedInstanceName = await vscode.window.showQuickPick(instanceNames, {
|
||||
placeHolder: localize('giteaClone.selectInstance', 'Select a Gitea instance')
|
||||
});
|
||||
|
||||
if (!selectedInstanceName) {
|
||||
vscode.window.showInformationMessage(localize('giteaClone.noInstanceSelected', 'No Gitea instance selected.'));
|
||||
return [];
|
||||
}
|
||||
|
||||
const selectedInstance = instances.find(instance => instance.name === selectedInstanceName);
|
||||
|
||||
if (!selectedInstance) {
|
||||
vscode.window.showErrorMessage(localize('giteaClone.invalidInstance', 'Invalid Gitea instance selected.'));
|
||||
return [];
|
||||
}
|
||||
|
||||
const instanceUrl = selectedInstance.url;
|
||||
const token = selectedInstance.token;
|
||||
|
||||
try {
|
||||
const response = await axios.get(`${instanceUrl}/api/v1/user/repos`, {
|
||||
headers: {
|
||||
@ -414,9 +452,10 @@ async function addStatusBarIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isGiteaRepo = await isGiteaRepository(currentWorkspaceFolder);
|
||||
if (!isGiteaRepo) {
|
||||
// Kein Gitea-Repository
|
||||
// Passende Gitea-Instanz ermitteln
|
||||
const giteaInstance = await getMatchingGiteaInstance(currentWorkspaceFolder);
|
||||
if (!giteaInstance) {
|
||||
// Keine passende Gitea-Instanz gefunden
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -430,14 +469,34 @@ async function addStatusBarIcon() {
|
||||
|
||||
// Funktion zur Authentifizierung bei Gitea mit dem Personal Access Token (PAT)
|
||||
async function authenticateGitea() {
|
||||
const instanceUrl = vscode.workspace.getConfiguration().get<string>('gitea.instanceUrl');
|
||||
const token = vscode.workspace.getConfiguration().get<string>('gitea.personalAccessToken');
|
||||
const instances = getGiteaInstances();
|
||||
|
||||
if (!instanceUrl || !token) {
|
||||
vscode.window.showErrorMessage(localize('giteaClone.configMissing', 'Gitea URL or Token is not configured.'));
|
||||
if (instances.length === 0) {
|
||||
vscode.window.showErrorMessage(localize('giteaClone.configMissing', 'No Gitea instances are configured.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Benutzer wählt eine Gitea-Instanz aus
|
||||
const instanceNames = instances.map(instance => instance.name);
|
||||
const selectedInstanceName = await vscode.window.showQuickPick(instanceNames, {
|
||||
placeHolder: localize('giteaClone.selectInstance', 'Select a Gitea instance to authenticate')
|
||||
});
|
||||
|
||||
if (!selectedInstanceName) {
|
||||
vscode.window.showInformationMessage(localize('giteaClone.noInstanceSelected', 'No Gitea instance selected.'));
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedInstance = instances.find(instance => instance.name === selectedInstanceName);
|
||||
|
||||
if (!selectedInstance) {
|
||||
vscode.window.showErrorMessage(localize('giteaClone.invalidInstance', 'Invalid Gitea instance selected.'));
|
||||
return;
|
||||
}
|
||||
|
||||
const instanceUrl = selectedInstance.url;
|
||||
const token = selectedInstance.token;
|
||||
|
||||
try {
|
||||
const response = await axios.get(`${instanceUrl}/api/v1/user`, {
|
||||
headers: {
|
||||
@ -471,36 +530,82 @@ async function authenticateGitea() {
|
||||
}
|
||||
}
|
||||
|
||||
// Funktion zur Konfiguration der Gitea-Instanz und des Tokens über die Command Palette
|
||||
// Funktion zur Konfiguration der Gitea-Instanzen und Tokens über die Command Palette
|
||||
async function configureGitea() {
|
||||
const instanceUrl = await vscode.window.showInputBox({
|
||||
prompt: localize('giteaClone.enterInstanceUrl', 'Enter Gitea instance URL'),
|
||||
placeHolder: 'https://your-gitea-instance.com'
|
||||
const instances = getGiteaInstances();
|
||||
|
||||
// Benutzer fragt, ob er eine neue Instanz hinzufügen oder eine bestehende bearbeiten möchte
|
||||
const action = await vscode.window.showQuickPick(['Add New Instance', 'Edit Existing Instance'], {
|
||||
placeHolder: 'What would you like to do?'
|
||||
});
|
||||
|
||||
const token = await vscode.window.showInputBox({
|
||||
prompt: localize('giteaClone.enterToken', 'Enter Gitea Personal Access Token'),
|
||||
placeHolder: 'token',
|
||||
password: true
|
||||
});
|
||||
if (action === 'Add New Instance') {
|
||||
// Neue Instanz hinzufügen
|
||||
const name = await vscode.window.showInputBox({
|
||||
prompt: 'Enter a name for the Gitea instance',
|
||||
placeHolder: 'e.g., Company Gitea'
|
||||
});
|
||||
|
||||
if (instanceUrl && token) {
|
||||
await vscode.workspace.getConfiguration().update('gitea.instanceUrl', instanceUrl, vscode.ConfigurationTarget.Global);
|
||||
await vscode.workspace.getConfiguration().update('gitea.personalAccessToken', token, vscode.ConfigurationTarget.Global);
|
||||
vscode.window.showInformationMessage(localize('giteaClone.configUpdated', 'Gitea configuration updated.'));
|
||||
const instanceUrl = await vscode.window.showInputBox({
|
||||
prompt: localize('giteaClone.enterInstanceUrl', 'Enter Gitea instance URL'),
|
||||
placeHolder: 'https://your-gitea-instance.com'
|
||||
});
|
||||
|
||||
const token = await vscode.window.showInputBox({
|
||||
prompt: localize('giteaClone.enterToken', 'Enter Gitea Personal Access Token'),
|
||||
placeHolder: 'token',
|
||||
password: true
|
||||
});
|
||||
|
||||
if (name && instanceUrl && token) {
|
||||
instances.push({ name, url: instanceUrl, token });
|
||||
await vscode.workspace.getConfiguration().update('gitea.instances', instances, vscode.ConfigurationTarget.Global);
|
||||
vscode.window.showInformationMessage(localize('giteaClone.configUpdated', 'Gitea configuration updated.'));
|
||||
}
|
||||
} else if (action === 'Edit Existing Instance') {
|
||||
// Existierende Instanz bearbeiten
|
||||
const instanceNames = instances.map(instance => instance.name);
|
||||
const selectedInstanceName = await vscode.window.showQuickPick(instanceNames, {
|
||||
placeHolder: 'Select a Gitea instance to edit'
|
||||
});
|
||||
|
||||
if (!selectedInstanceName) {
|
||||
vscode.window.showInformationMessage(localize('giteaClone.noInstanceSelected', 'No Gitea instance selected.'));
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedInstanceIndex = instances.findIndex(instance => instance.name === selectedInstanceName);
|
||||
const selectedInstance = instances[selectedInstanceIndex];
|
||||
|
||||
const name = await vscode.window.showInputBox({
|
||||
prompt: 'Enter a name for the Gitea instance',
|
||||
placeHolder: 'e.g., Company Gitea',
|
||||
value: selectedInstance.name
|
||||
});
|
||||
|
||||
const instanceUrl = await vscode.window.showInputBox({
|
||||
prompt: localize('giteaClone.enterInstanceUrl', 'Enter Gitea instance URL'),
|
||||
placeHolder: 'https://your-gitea-instance.com',
|
||||
value: selectedInstance.url
|
||||
});
|
||||
|
||||
const token = await vscode.window.showInputBox({
|
||||
prompt: localize('giteaClone.enterToken', 'Enter Gitea Personal Access Token'),
|
||||
placeHolder: 'token',
|
||||
password: true,
|
||||
value: selectedInstance.token
|
||||
});
|
||||
|
||||
if (name && instanceUrl && token) {
|
||||
instances[selectedInstanceIndex] = { name, url: instanceUrl, token };
|
||||
await vscode.workspace.getConfiguration().update('gitea.instances', instances, vscode.ConfigurationTarget.Global);
|
||||
vscode.window.showInformationMessage(localize('giteaClone.configUpdated', 'Gitea configuration updated.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Funktion zum Abrufen offener Pull Requests
|
||||
async function getOpenPullRequests(): Promise<any[]> {
|
||||
const instanceUrl = vscode.workspace.getConfiguration().get<string>('gitea.instanceUrl');
|
||||
const token = vscode.workspace.getConfiguration().get<string>('gitea.personalAccessToken');
|
||||
|
||||
if (!instanceUrl || !token) {
|
||||
vscode.window.showErrorMessage(localize('giteaClone.configMissing', 'Gitea URL oder Token ist nicht konfiguriert.'));
|
||||
return [];
|
||||
}
|
||||
|
||||
// Aktuellen Workspace-Ordner abrufen
|
||||
const currentWorkspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath;
|
||||
if (!currentWorkspaceFolder) {
|
||||
@ -514,16 +619,20 @@ async function getOpenPullRequests(): Promise<any[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
const isGiteaRepo = await isGiteaRepository(currentWorkspaceFolder);
|
||||
if (!isGiteaRepo) {
|
||||
// Kein Gitea-Repository
|
||||
// Passende Gitea-Instanz ermitteln
|
||||
const giteaInstance = await getMatchingGiteaInstance(currentWorkspaceFolder);
|
||||
if (!giteaInstance) {
|
||||
// Keine passende Gitea-Instanz gefunden
|
||||
return [];
|
||||
}
|
||||
|
||||
const instanceUrl = giteaInstance.url;
|
||||
const token = giteaInstance.token;
|
||||
|
||||
// Git-Repository-Informationen abrufen
|
||||
const { owner, repo } = await getRepoInfo(currentWorkspaceFolder);
|
||||
if (!owner || !repo) {
|
||||
vscode.window.showErrorMessage(localize('giteaClone.repoInfoError', 'Konnte Repository-Informationen nicht abrufen.'));
|
||||
vscode.window.showErrorMessage(localize('giteaClone.repoInfoError', 'Could not retrieve repository information.'));
|
||||
return [];
|
||||
}
|
||||
|
||||
@ -540,7 +649,7 @@ async function getOpenPullRequests(): Promise<any[]> {
|
||||
if (response.status === 200) {
|
||||
return response.data;
|
||||
} else {
|
||||
vscode.window.showErrorMessage(localize('giteaClone.pullRequestsError', 'Fehler beim Abrufen der Pull Requests.'));
|
||||
vscode.window.showErrorMessage(localize('giteaClone.pullRequestsError', 'Error retrieving pull requests.'));
|
||||
return [];
|
||||
}
|
||||
} catch (err: any) {
|
||||
@ -572,7 +681,7 @@ async function getRepoInfo(folderPath: string): Promise<{ owner: string, repo: s
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(`git config --get remote.origin.url`, { cwd: folderPath }, (error, stdout) => {
|
||||
if (error || !stdout) {
|
||||
reject(localize('giteaClone.noRemoteUrl', 'Konnte Git-Remote-URL nicht abrufen.'));
|
||||
reject(localize('giteaClone.noRemoteUrl', 'Could not retrieve Git remote URL.'));
|
||||
} else {
|
||||
let repoUrl = stdout.trim();
|
||||
|
||||
@ -598,18 +707,18 @@ async function showOpenPullRequests() {
|
||||
const pullRequests = await getOpenPullRequests();
|
||||
|
||||
if (pullRequests.length === 0) {
|
||||
vscode.window.showInformationMessage(localize('giteaClone.noOpenPRs', 'Keine offenen Pull Requests vorhanden.'));
|
||||
vscode.window.showInformationMessage(localize('giteaClone.noOpenPRs', 'No open pull requests available.'));
|
||||
return;
|
||||
}
|
||||
|
||||
const prItems = pullRequests.map(pr => ({
|
||||
label: `#${pr.number}: ${pr.title}`,
|
||||
description: `von ${pr.user.username}`,
|
||||
description: `by ${pr.user.username}`,
|
||||
pr
|
||||
}));
|
||||
|
||||
const selectedPr = await vscode.window.showQuickPick(prItems, {
|
||||
placeHolder: localize('giteaClone.selectPullRequest', 'Wähle einen Pull Request zum Anzeigen aus')
|
||||
placeHolder: localize('giteaClone.selectPullRequest', 'Select a pull request to view')
|
||||
});
|
||||
|
||||
if (selectedPr) {
|
||||
@ -633,8 +742,9 @@ async function updatePRStatusBarItem(context: vscode.ExtensionContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isGiteaRepo = await isGiteaRepository(currentWorkspaceFolder);
|
||||
if (!isGiteaRepo) {
|
||||
// Passende Gitea-Instanz ermitteln
|
||||
const giteaInstance = await getMatchingGiteaInstance(currentWorkspaceFolder);
|
||||
if (!giteaInstance) {
|
||||
if (prStatusBarItem) prStatusBarItem.hide();
|
||||
return;
|
||||
}
|
||||
@ -644,7 +754,7 @@ async function updatePRStatusBarItem(context: vscode.ExtensionContext) {
|
||||
if (!prStatusBarItem) {
|
||||
prStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||
prStatusBarItem.command = 'gitea.showOpenPullRequests';
|
||||
prStatusBarItem.tooltip = localize('giteaClone.showOpenPullRequestsTooltip', 'Offene Pull Requests anzeigen');
|
||||
prStatusBarItem.tooltip = localize('giteaClone.showOpenPullRequestsTooltip', 'Show open pull requests');
|
||||
context.subscriptions.push(prStatusBarItem);
|
||||
}
|
||||
|
||||
@ -652,26 +762,179 @@ async function updatePRStatusBarItem(context: vscode.ExtensionContext) {
|
||||
prStatusBarItem.text = `$(git-pull-request) Gitea Open PRs: ${prCount}`;
|
||||
prStatusBarItem.show();
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Aktualisieren des PR-Statusleisten-Icons:', error);
|
||||
console.error('Error updating PR status bar item:', error);
|
||||
if (prStatusBarItem) {
|
||||
prStatusBarItem.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Funktion zum Starten des PR-Statusleisten-Updaters
|
||||
function startPRStatusBarItemUpdater(context: vscode.ExtensionContext) {
|
||||
updatePRStatusBarItem(context); // Initiales Update
|
||||
// Funktion zum Aktualisieren des Branch-Statusleisten-Icons
|
||||
async function updateBranchStatusBarItem() {
|
||||
try {
|
||||
const currentWorkspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath;
|
||||
if (!currentWorkspaceFolder) {
|
||||
if (branchStatusBarItem) branchStatusBarItem.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
const isGitRepo = await isGitRepository(currentWorkspaceFolder);
|
||||
if (!isGitRepo) {
|
||||
if (branchStatusBarItem) branchStatusBarItem.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
const branch = await getCurrentBranch(currentWorkspaceFolder);
|
||||
|
||||
if (!branchStatusBarItem) {
|
||||
branchStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||
branchStatusBarItem.tooltip = localize('giteaClone.branchStatusTooltip', 'Current branch status');
|
||||
branchStatusBarItem.command = 'git.checkout';
|
||||
}
|
||||
|
||||
// Überprüfen, ob der Branch up-to-date ist
|
||||
const branchStatus = await getBranchStatus(currentWorkspaceFolder, branch);
|
||||
|
||||
branchStatusBarItem.text = `$(git-branch) ${branch} ${branchStatus}`;
|
||||
branchStatusBarItem.show();
|
||||
} catch (error) {
|
||||
console.error('Error updating branch status bar item:', error);
|
||||
if (branchStatusBarItem) {
|
||||
branchStatusBarItem.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsfunktion, um den Branch-Status zu ermitteln
|
||||
async function getBranchStatus(folderPath: string, branch: string): Promise<string> {
|
||||
return new Promise((resolve) => {
|
||||
exec(`git status -sb`, { cwd: folderPath }, (error, stdout) => {
|
||||
if (error || !stdout) {
|
||||
resolve('');
|
||||
} else {
|
||||
const statusLine = stdout.split('\n')[0];
|
||||
const aheadMatch = /\[ahead (\d+)\]/.exec(statusLine);
|
||||
const behindMatch = /\[behind (\d+)\]/.exec(statusLine);
|
||||
|
||||
let status = '';
|
||||
if (aheadMatch) {
|
||||
status += `↑${aheadMatch[1]}`;
|
||||
}
|
||||
if (behindMatch) {
|
||||
status += `↓${behindMatch[1]}`;
|
||||
}
|
||||
|
||||
resolve(status);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Funktion zum Aktualisieren des Build-Statusleisten-Icons
|
||||
async function updateBuildStatusBarItem() {
|
||||
try {
|
||||
const currentWorkspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath;
|
||||
if (!currentWorkspaceFolder) {
|
||||
if (buildStatusBarItem) buildStatusBarItem.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
const isGitRepo = await isGitRepository(currentWorkspaceFolder);
|
||||
if (!isGitRepo) {
|
||||
if (buildStatusBarItem) buildStatusBarItem.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
// Passende Gitea-Instanz ermitteln
|
||||
const giteaInstance = await getMatchingGiteaInstance(currentWorkspaceFolder);
|
||||
if (!giteaInstance) {
|
||||
if (buildStatusBarItem) buildStatusBarItem.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
const instanceUrl = giteaInstance.url;
|
||||
const token = giteaInstance.token;
|
||||
|
||||
// Git-Repository-Informationen abrufen
|
||||
const { owner, repo } = await getRepoInfo(currentWorkspaceFolder);
|
||||
if (!owner || !repo) {
|
||||
if (buildStatusBarItem) buildStatusBarItem.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
// Aktuellen Commit-Hash abrufen
|
||||
const commitHash = await getCurrentCommitHash(currentWorkspaceFolder);
|
||||
|
||||
// Build-Status von Gitea abrufen
|
||||
const buildStatus = await getBuildStatus(instanceUrl, owner, repo, commitHash, token);
|
||||
|
||||
if (!buildStatusBarItem) {
|
||||
buildStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||
buildStatusBarItem.tooltip = localize('giteaClone.buildStatusTooltip', 'Build status of the current commit');
|
||||
}
|
||||
|
||||
buildStatusBarItem.text = `$(gear) Build: ${buildStatus}`;
|
||||
buildStatusBarItem.show();
|
||||
} catch (error) {
|
||||
console.error('Error updating build status bar item:', error);
|
||||
if (buildStatusBarItem) {
|
||||
buildStatusBarItem.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsfunktion, um den aktuellen Commit-Hash zu ermitteln
|
||||
async function getCurrentCommitHash(folderPath: string): Promise<string> {
|
||||
return new Promise((resolve) => {
|
||||
exec(`git rev-parse HEAD`, { cwd: folderPath }, (error, stdout) => {
|
||||
if (error || !stdout) {
|
||||
resolve('');
|
||||
} else {
|
||||
resolve(stdout.trim());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Hilfsfunktion, um den Build-Status von Gitea abzurufen
|
||||
async function getBuildStatus(instanceUrl: string, owner: string, repo: string, commitHash: string, token: string): Promise<string> {
|
||||
try {
|
||||
const response = await axios.get(`${instanceUrl}/api/v1/repos/${owner}/${repo}/statuses/${commitHash}`, {
|
||||
headers: {
|
||||
'Authorization': `token ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
if (response.status === 200 && response.data.length > 0) {
|
||||
const latestStatus = response.data[0];
|
||||
return latestStatus.state;
|
||||
} else {
|
||||
return 'unknown';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching build status:', error);
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
// Funktion zum Starten des Build- und Branch-Status-Updaters
|
||||
function startStatusBarItemUpdater(context: vscode.ExtensionContext) {
|
||||
updateBranchStatusBarItem();
|
||||
updateBuildStatusBarItem();
|
||||
|
||||
// Aktualisiere bei Fokuswechsel
|
||||
vscode.window.onDidChangeWindowState((windowState) => {
|
||||
if (windowState.focused) {
|
||||
updatePRStatusBarItem(context);
|
||||
updateBranchStatusBarItem();
|
||||
updateBuildStatusBarItem();
|
||||
}
|
||||
}, null, context.subscriptions);
|
||||
|
||||
// Aktualisiere alle 5 Minuten
|
||||
setInterval(() => updatePRStatusBarItem(context), 300000); // 5 Minuten
|
||||
// Aktualisiere alle 2 Minuten
|
||||
setInterval(() => {
|
||||
updateBranchStatusBarItem();
|
||||
updateBuildStatusBarItem();
|
||||
}, 120000); // 2 Minuten
|
||||
}
|
||||
|
||||
// Aktivierungsfunktion des Plugins
|
||||
@ -706,35 +969,38 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
vscode.workspace.onDidChangeWorkspaceFolders(async () => {
|
||||
if (statusBarItem) {
|
||||
const currentWorkspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath;
|
||||
if (currentWorkspaceFolder && await isGitRepository(currentWorkspaceFolder) && await isGiteaRepository(currentWorkspaceFolder)) {
|
||||
if (statusBarItem) {
|
||||
statusBarItem.show();
|
||||
}
|
||||
if (currentWorkspaceFolder && await isGitRepository(currentWorkspaceFolder) && await getMatchingGiteaInstance(currentWorkspaceFolder)) {
|
||||
statusBarItem.show();
|
||||
} else {
|
||||
statusBarItem.hide();
|
||||
}
|
||||
}
|
||||
|
||||
await updatePRStatusBarItem(context);
|
||||
updateBranchStatusBarItem();
|
||||
updateBuildStatusBarItem();
|
||||
});
|
||||
|
||||
vscode.window.onDidChangeActiveTextEditor(async () => {
|
||||
if (statusBarItem) {
|
||||
const currentWorkspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath;
|
||||
if (currentWorkspaceFolder && await isGitRepository(currentWorkspaceFolder) && await isGiteaRepository(currentWorkspaceFolder)) {
|
||||
if (statusBarItem) {
|
||||
statusBarItem.show();
|
||||
}
|
||||
if (currentWorkspaceFolder && await isGitRepository(currentWorkspaceFolder) && await getMatchingGiteaInstance(currentWorkspaceFolder)) {
|
||||
statusBarItem.show();
|
||||
} else {
|
||||
statusBarItem.hide();
|
||||
}
|
||||
}
|
||||
|
||||
await updatePRStatusBarItem(context);
|
||||
updateBranchStatusBarItem();
|
||||
updateBuildStatusBarItem();
|
||||
});
|
||||
|
||||
// Starten Sie den PR-Statusleisten-Updater
|
||||
startPRStatusBarItemUpdater(context);
|
||||
startStatusBarItemUpdater(context);
|
||||
|
||||
// Starten Sie den Branch- und Build-Statusleisten-Updater
|
||||
startStatusBarItemUpdater(context);
|
||||
}
|
||||
|
||||
// Deaktivierungsfunktion des Plugins
|
||||
|
Reference in New Issue
Block a user