diff --git a/gitea-git-clone/src/extension.ts b/gitea-git-clone/src/extension.ts index 858e250..d6cd311 100644 --- a/gitea-git-clone/src/extension.ts +++ b/gitea-git-clone/src/extension.ts @@ -6,7 +6,7 @@ import * as nls from 'vscode-nls'; import * as path from 'path'; import * as fs from 'fs'; -//Interface +// Interface für die Gitea-Fehlerantwort interface GiteaErrorResponse { message?: string; url?: string; @@ -19,10 +19,52 @@ interface GiteaErrorResponse { }>; } - // 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; + +// Hilfsfunktion, um zu prüfen, ob ein Ordner ein Git-Repository ist +async function isGitRepository(folderPath: string): Promise { + return new Promise((resolve) => { + exec(`git rev-parse --is-inside-work-tree`, { cwd: folderPath }, (error) => { + resolve(!error); + }); + }); +} + +// Hilfsfunktion, um zu prüfen, ob das Remote-Repository eine Gitea-Instanz ist +async function isGiteaRepository(folderPath: string): Promise { + const instanceUrl = vscode.workspace.getConfiguration().get('gitea.instanceUrl'); + if (!instanceUrl) { + return false; + } + + return new Promise((resolve) => { + exec(`git config --get remote.origin.url`, { cwd: folderPath }, (error, stdout) => { + if (error || !stdout) { + resolve(false); + } else { + let repoUrl = stdout.trim(); + + // URL normalisieren + if (repoUrl.startsWith('git@')) { + const parts = repoUrl.split(':'); + const domain = parts[0].replace('git@', ''); + const path = parts[1].replace('.git', ''); + repoUrl = `https://${domain}/${path}`; + } else { + repoUrl = repoUrl.replace('.git', ''); + } + + resolve(repoUrl.startsWith(instanceUrl)); + } + }); + }); +} + // Funktion zum Erstellen eines Pull Requests async function createGiteaPullRequest() { const instanceUrl = vscode.workspace.getConfiguration().get('gitea.instanceUrl'); @@ -33,10 +75,24 @@ async function createGiteaPullRequest() { return; } - // Aktuellen Git-Ordner abrufen + // Aktuellen Workspace-Ordner abrufen const currentWorkspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath; if (!currentWorkspaceFolder) { - vscode.window.showErrorMessage(localize('giteaClone.noValidRepo', 'No valid Git repository found in the current workspace.')); + // Kein Arbeitsverzeichnis geöffnet + return; + } + + // Prüfen, ob aktueller Ordner ein Git-Repository ist + const isGitRepo = await isGitRepository(currentWorkspaceFolder); + if (!isGitRepo) { + // Kein Git-Repository, keine Aktion erforderlich + return; + } + + // Prüfen, ob Remote-Repository eine Gitea-Instanz ist + const isGiteaRepo = await isGiteaRepository(currentWorkspaceFolder); + if (!isGiteaRepo) { + // Kein Gitea-Repository, keine Aktion erforderlich return; } @@ -59,7 +115,7 @@ async function createGiteaPullRequest() { repoUrl = repoUrl.replace('.git', ''); } - // Extract repository owner and name from the URL + // Repository-Besitzer und -Name aus der URL extrahieren const [owner, repo] = repoUrl.split('/').slice(-2); try { @@ -327,8 +383,26 @@ async function cloneGiteaRepository() { } } -// Funktion zum Hinzufügen des Statusbar-Icons -function addStatusBarIcon() { +// Funktion zum Hinzufügen des Statusleisten-Icons +async function addStatusBarIcon() { + const currentWorkspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath; + if (!currentWorkspaceFolder) { + // Kein Arbeitsverzeichnis geöffnet + return null; + } + + const isGitRepo = await isGitRepository(currentWorkspaceFolder); + if (!isGitRepo) { + // Kein Git-Repository + return null; + } + + const isGiteaRepo = await isGiteaRepository(currentWorkspaceFolder); + if (!isGiteaRepo) { + // Kein Gitea-Repository + return null; + } + const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); statusBar.text = `$(git-pull-request) ${localize('giteaClone.createPullRequest', 'Create Gitea PR')}`; statusBar.tooltip = localize('giteaClone.createPullRequestTooltip', 'Create a Pull Request in Gitea'); @@ -400,8 +474,6 @@ async function configureGitea() { } } -// Features - // Funktion zum Abrufen offener Pull Requests async function getOpenPullRequests(): Promise { const instanceUrl = vscode.workspace.getConfiguration().get('gitea.instanceUrl'); @@ -412,10 +484,22 @@ async function getOpenPullRequests(): Promise { return []; } - // Aktuellen Git-Ordner abrufen + // Aktuellen Workspace-Ordner abrufen const currentWorkspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath; if (!currentWorkspaceFolder) { - vscode.window.showErrorMessage(localize('giteaClone.noValidRepo', 'Kein gültiges Git-Repository im aktuellen Arbeitsbereich gefunden.')); + // Kein Arbeitsverzeichnis geöffnet + return []; + } + + const isGitRepo = await isGitRepository(currentWorkspaceFolder); + if (!isGitRepo) { + // Kein Git-Repository + return []; + } + + const isGiteaRepo = await isGiteaRepository(currentWorkspaceFolder); + if (!isGiteaRepo) { + // Kein Gitea-Repository return []; } @@ -517,11 +601,27 @@ async function showOpenPullRequests() { } } -let prStatusBarItem: vscode.StatusBarItem; - // Funktion zum Aktualisieren des PR-Statusleisten-Icons async function updatePRStatusBarItem(context: vscode.ExtensionContext) { try { + const currentWorkspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath; + if (!currentWorkspaceFolder) { + if (prStatusBarItem) prStatusBarItem.hide(); + return; + } + + const isGitRepo = await isGitRepository(currentWorkspaceFolder); + if (!isGitRepo) { + if (prStatusBarItem) prStatusBarItem.hide(); + return; + } + + const isGiteaRepo = await isGiteaRepository(currentWorkspaceFolder); + if (!isGiteaRepo) { + if (prStatusBarItem) prStatusBarItem.hide(); + return; + } + const pullRequests = await getOpenPullRequests(); if (!prStatusBarItem) { @@ -558,7 +658,7 @@ function startPRStatusBarItemUpdater(context: vscode.ExtensionContext) { } // Aktivierungsfunktion des Plugins -export function activate(context: vscode.ExtensionContext) { +export async function activate(context: vscode.ExtensionContext) { // Registriert den Befehl zur Authentifizierung let authCommand = vscode.commands.registerCommand('gitea.authenticate', authenticateGitea); context.subscriptions.push(authCommand); @@ -571,10 +671,6 @@ export function activate(context: vscode.ExtensionContext) { let pullRequestCommand = vscode.commands.registerCommand('gitea.createPullRequest', createGiteaPullRequest); context.subscriptions.push(pullRequestCommand); - // Statusbar-Icon sofort anzeigen - const statusBar = addStatusBarIcon(); // Icon wird sofort beim Aktivieren angezeigt - context.subscriptions.push(statusBar); - // Befehl zum Klonen eines Repositories let cloneCommand = vscode.commands.registerCommand('gitea.cloneRepository', cloneGiteaRepository); context.subscriptions.push(cloneCommand); @@ -583,7 +679,44 @@ export function activate(context: vscode.ExtensionContext) { let showPRCommand = vscode.commands.registerCommand('gitea.showOpenPullRequests', showOpenPullRequests); context.subscriptions.push(showPRCommand); - // Statusleisten-Icon erstellen und Updater starten + // Statusleisten-Icon erstellen + statusBarItem = await addStatusBarIcon(); + if (statusBarItem) { + context.subscriptions.push(statusBarItem); + } + + // Statusleisten-Icons aktualisieren bei Änderungen im Arbeitsbereich + 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(); +} + } else { + statusBarItem.hide(); + } + } + + await updatePRStatusBarItem(context); + }); + + 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(); +} + } else { + statusBarItem.hide(); + } + } + + await updatePRStatusBarItem(context); + }); + + // Starten Sie den PR-Statusleisten-Updater startPRStatusBarItemUpdater(context); }