From a5aaa549061435412a049993383d5164ed28cb22 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 23 Oct 2024 12:09:38 +0200 Subject: [PATCH 1/2] No errors if no Git or Gitea * chore(extension.ts): add interface for Gitea error response * feat(extension.ts): add global variables for status bar icons * feat(extension.ts): add helper function to check if a folder is a Git repository * feat(extension.ts): add helper function to check if the remote repository is a Gitea instance * feat(extension.ts): create Gitea pull request function * feat(extension.ts): add function to clone Gitea repository * feat(extension.ts): add function to add status bar icon * feat(extension.ts): add function to configure Gitea * feat(extension.ts): add function to get open pull requests * feat(extension.ts): add function to show open pull requests * feat(extension.ts): add function to update PR status bar item * feat(extension.ts): activate the plugin and register commands * feat(extension.ts): create status bar icon and start updater --- gitea-git-clone/src/extension.ts | 171 +++++++++++++++++++++++++++---- 1 file changed, 152 insertions(+), 19 deletions(-) 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); } From aea0ffbac6198436658ea70f7351c606a592b576 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 23 Oct 2024 12:19:17 +0200 Subject: [PATCH 2/2] Truncate commit title longer than 255 characters * chore(gitea-git-clone): update changelog and package version * fix(gitea-git-clone): truncate commit titles and bodies longer than 255 and 65535 characters respectively * feat(gitea-git-clone): show warning messages when commit titles and bodies are truncated --- gitea-git-clone/CHANGELOG.md | 9 ++++++++ gitea-git-clone/i18n/package.nls.de.json | 4 +++- gitea-git-clone/i18n/package.nls.json | 4 +++- gitea-git-clone/package.json | 2 +- gitea-git-clone/src/extension.ts | 27 +++++++++++++++++++----- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/gitea-git-clone/CHANGELOG.md b/gitea-git-clone/CHANGELOG.md index e976ac1..5d725a1 100644 --- a/gitea-git-clone/CHANGELOG.md +++ b/gitea-git-clone/CHANGELOG.md @@ -10,6 +10,15 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how - if working in PR show different Icon with hint - fix progress bar in notification +## 1.2.2 + +### Fixed + +- no errors if not a Git-Repository +- no errors if not a Gitea-Repository with configured upstream +- no Statusbar icons if not Git/Gitea-Repository +- truncate Commit Titles longer than 255 characters + ## 1.2.1 ### Fixed diff --git a/gitea-git-clone/i18n/package.nls.de.json b/gitea-git-clone/i18n/package.nls.de.json index f061e30..b11df4b 100644 --- a/gitea-git-clone/i18n/package.nls.de.json +++ b/gitea-git-clone/i18n/package.nls.de.json @@ -34,6 +34,8 @@ "giteaClone.defaultBranchError": "Fehler beim Abrufen des Basis-Branches: {0}", "giteaClone.repoError": "Fehler beim Abrufen der Repositories: {0}", "giteaClone.authFailed": "Authentifizierung fehlgeschlagen: {0}", - "giteaClone.pullRequestsError": "Fehler beim Abrufen der Pull Requests: {0}" + "giteaClone.pullRequestsError": "Fehler beim Abrufen der Pull Requests: {0}", + "giteaClone.titleTruncated": "Die Commit-Nachricht war zu lang und wurde für den Pull-Request-Titel gekürzt.", + "giteaClone.bodyTruncated": "Der Commit-Nachrichtentext war zu lang und wurde für die Pull-Request-Beschreibung gekürzt." } \ No newline at end of file diff --git a/gitea-git-clone/i18n/package.nls.json b/gitea-git-clone/i18n/package.nls.json index cb9c384..1a203c9 100644 --- a/gitea-git-clone/i18n/package.nls.json +++ b/gitea-git-clone/i18n/package.nls.json @@ -34,6 +34,8 @@ "giteaClone.defaultBranchError": "Error retrieving the base branch: {0}", "giteaClone.repoError": "Error retrieving repositories: {0}", "giteaClone.authFailed": "Authentication failed: {0}", - "giteaClone.pullRequestsError": "Error retrieving pull requests: {0}" + "giteaClone.pullRequestsError": "Error retrieving pull requests: {0}", + "giteaClone.titleTruncated": "The commit message was too long and has been truncated for the pull request title.", + "giteaClone.bodyTruncated": "The commit message body was too long and has been truncated for the pull request description." } \ No newline at end of file diff --git a/gitea-git-clone/package.json b/gitea-git-clone/package.json index 6316483..02c575a 100644 --- a/gitea-git-clone/package.json +++ b/gitea-git-clone/package.json @@ -2,7 +2,7 @@ "name": "gitea-workflow", "displayName": "Gitea Workflow", "description": "Clone from Gitea instances; Create PRs", - "version": "1.2.1", + "version": "1.2.2", "publisher": "computerliebe", "engines": { "vscode": "^1.94.0" diff --git a/gitea-git-clone/src/extension.ts b/gitea-git-clone/src/extension.ts index d6cd311..bba5cd8 100644 --- a/gitea-git-clone/src/extension.ts +++ b/gitea-git-clone/src/extension.ts @@ -122,19 +122,36 @@ 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: title, // Der letzte Commit als Titel - body: body || '', // Commit-Kommentare als Body + title: truncatedTitle, // Der getrunkierte Titel + body: truncatedBody || '', // Der getrunkierte Body head: branch, // Der aktuelle Branch als "head" base: baseBranch // Der ermittelte base-Branch };