diff --git a/gitea-git-clone/CHANGELOG.md b/gitea-git-clone/CHANGELOG.md index fe1ab24..ad9fa42 100644 --- a/gitea-git-clone/CHANGELOG.md +++ b/gitea-git-clone/CHANGELOG.md @@ -10,6 +10,12 @@ 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.0 + +### Added + +- Show open Pull Requests (Command and Status Bar Icon) + ## 1.1.0 ### Added diff --git a/gitea-git-clone/README.md b/gitea-git-clone/README.md index eb0ff95..e4d80ef 100644 --- a/gitea-git-clone/README.md +++ b/gitea-git-clone/README.md @@ -1,21 +1,22 @@ -A Visual Studio Code extension that allows you to clone repositories from your Gitea instance via SSH, manage Gitea authentication using a Personal Access Token (PAT), and create Pull Requests (PRs) directly from your workspace. -Features +# Gitea Workflow -### Gitea Authentication: -- Authenticate with your Gitea instance using a Personal Access Token. -### Clone via SSH: -- Clone repositories from Gitea using SSH URLs. -### Auto-Open Repository: -- After cloning, the repository will be automatically opened in the workspace. -### Create Pull Requests: -- Create Pull Requests directly from your workspace without leaving VSCode. Automatically set the title, body, and branch for the PR. +A Visual Studio Code extension that allows you to clone repositories from your Gitea instance via SSH, manage Gitea authentication using a Personal Access Token (PAT), and create Pull Requests (PRs) directly from your workspace. + +## Features + +- **Gitea Authentication**: Authenticate with your Gitea instance using a Personal Access Token. +- **Clone via SSH**: Clone repositories from Gitea using SSH URLs. +- **Auto-Open Repository**: After cloning, the repository will be automatically opened in the workspace. +- **See Open Pull Requests**: Use the icon in the status bar or the command to check how many open PRs exist and open them in a browser. +- **Create Pull Requests**: Create Pull Requests (PRs) directly from your workspace ## Commands -`Gitea: Authenticate` Authenticate with your Gitea instance using your Personal Access Token (PAT). -`Gitea: Configure` Set the URL of your Gitea instance and your PAT. -`Gitea: Clone Repository` Clone a repository from Gitea via SSH. -`Gitea: Create Pull Request` Create a Pull Request for the current repository. +- `Gitea: Authenticate`: Authenticate with your Gitea instance using your Personal Access Token (PAT). +- `Gitea: Configure`: Set the URL of your Gitea instance and your PAT. +- `Gitea: Clone Repository`: Clone a repository from Gitea via SSH. +- `Gitea: Create Pull Request`: Create a pull request for the current repository. +- `Gitea: Show Open Pull Request`: Shows open pull request for the current repository and link to them. ## Requirements @@ -23,37 +24,37 @@ Features A Personal Access Token (PAT) from your Gitea instance for authentication. ## Configuration +You can configure the Gitea instance URL, your Personal Access Token, and default clone settings in your VSCode settings: -You can configure the Gitea instance URL and your Personal Access Token in your VSCode settings: - -````json - +```json { "gitea.instanceUrl": "https://your-gitea-instance.com", - "gitea.personalAccessToken": "your-personal-access-token" + "gitea.personalAccessToken": "your-personal-access-token", } ```` ## Usage -Authentication - Run to authenticate with your Gitea instance. - You can set or update your Gitea instance URL and Personal Access Token by running +### Authentication -Cloning a Repository +Run `Gitea: Authenticate` to authenticate with your Gitea instance. +You can set or update your Gitea instance URL and Personal Access Token by running `Gitea: Configure` - Run to clone a repository from your Gitea account. - Choose the repository you want to clone and select the folder where you want to clone it. - The repository will be cloned via SSH and automatically opened in VSCode. +### Cloning a Repository -Creating a Pull Request +Run `Gitea: Clone Repository` to clone a repository from your Gitea account. +Choose the repository you want to clone and select the folder where you want to clone it. +The repository will be cloned via SSH and automatically opened in VSCode. - Ensure that you are on the branch for which you want to create a Pull Request. - Run from the command palette. - The PR title will be automatically set to the latest commit message, and the body will include the commit description (if any). - The current branch will be used as the source (head), and the base branch will be automatically fetched from the repository's default branch (e.g., main or master). - Once the Pull Request is created, the Gitea web interface will open in your browser for further review. +### Creating a Pull Request + +_Ensure that you are on the branch for which you want to create a Pull Request._ +Run `Gitea: Create Pull Request` from the command palette. +The PR title will be automatically set to the latest commit message, and the body will include the commit description (if any). +The current branch will be used as the source (head), and the base branch will be automatically fetched from the repository's default branch (e.g., main or master). +Once the Pull Request is created, the Gitea web interface will open in your browser for further review. ## Issues -If you encounter any issues or have feature requests, please feel free to submit them in the issues section. \ No newline at end of file +If you encounter any issues or have feature requests, please feel free to submit them in [the issues section](https://gitea.computerliebe.org/ComputerLiebe/Gitea-Workflow/issues). + diff --git a/gitea-git-clone/i18n/package.nls.de.json b/gitea-git-clone/i18n/package.nls.de.json index 1c68104..354b369 100644 --- a/gitea-git-clone/i18n/package.nls.de.json +++ b/gitea-git-clone/i18n/package.nls.de.json @@ -28,6 +28,11 @@ "giteaClone.cloneError": "Fehler beim Klonen des Repositories.", "giteaClone.noFolderSelected": "Kein Zielordner ausgewählt.", "giteaClone.noSshUrl": "Konnte die SSH-Klon-URL nicht finden.", - "giteaClone.openRepoError": "Fehler beim Öffnen des geklonten Repositories." + "giteaClone.openRepoError": "Fehler beim Öffnen des geklonten Repositories.", + "giteaClone.noOpenPRs": "Keine offenen Pull Requests vorhanden.", + "giteaClone.selectPullRequest": "Wähle einen Pull Request zum Anzeigen aus", + "giteaClone.repoInfoError": "Konnte Repository-Informationen nicht abrufen.", + "giteaClone.pullRequestsError": "Fehler beim Abrufen der Pull Requests.", + "giteaClone.showOpenPullRequestsTooltip": "Offene Pull Requests anzeigen" } \ 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 064d654..203762f 100644 --- a/gitea-git-clone/i18n/package.nls.json +++ b/gitea-git-clone/i18n/package.nls.json @@ -28,6 +28,11 @@ "giteaClone.cloneError": "Error cloning the repository.", "giteaClone.noFolderSelected": "No target folder selected.", "giteaClone.noSshUrl": "Could not find SSH clone URL.", - "giteaClone.openRepoError": "Error opening the cloned repository." + "giteaClone.openRepoError": "Error opening the cloned repository.", + "giteaClone.noOpenPRs": "There are no open pull requests.", + "giteaClone.selectPullRequest": "Select a pull request to view", + "giteaClone.repoInfoError": "Could not retrieve repository information.", + "giteaClone.pullRequestsError": "Error retrieving pull requests.", + "giteaClone.showOpenPullRequestsTooltip": "Show open pull requests" } \ No newline at end of file diff --git a/gitea-git-clone/package.json b/gitea-git-clone/package.json index 0e9c7eb..e5ea26a 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.1.0", + "version": "1.2.0", "publisher": "computerliebe", "engines": { "vscode": "^1.94.0" @@ -23,20 +23,27 @@ "commands": [ { "command": "gitea.createPullRequest", - "title": "Gitea: Create Pull Request", + "title": "Create Pull Request", "category": "Gitea" }, { "command": "gitea.authenticate", - "title": "Gitea: Authenticate" + "title": " Authenticate", + "category": "Gitea" }, { "command": "gitea.configure", - "title": "Gitea: Configure URL" + "title": " Configure URL" }, { "command": "gitea.cloneRepository", - "title": "Gitea: Clone Repository" + "title": " Clone Repository", + "category": "Gitea" + }, + { + "command": "gitea.showOpenPullRequests", + "title": " Show open Pull Requests", + "category": "Gitea" } ], "configuration": { diff --git a/gitea-git-clone/src/extension.ts b/gitea-git-clone/src/extension.ts index 0be0d20..7ee1fba 100644 --- a/gitea-git-clone/src/extension.ts +++ b/gitea-git-clone/src/extension.ts @@ -298,6 +298,150 @@ async function configureGitea() { } } +// Features + +// Funktion zum Abrufen offener Pull Requests +async function getOpenPullRequests(): Promise { + const instanceUrl = vscode.workspace.getConfiguration().get('gitea.instanceUrl'); + const token = vscode.workspace.getConfiguration().get('gitea.personalAccessToken'); + + if (!instanceUrl || !token) { + vscode.window.showErrorMessage(localize('giteaClone.configMissing', 'Gitea URL oder Token ist nicht konfiguriert.')); + return []; + } + + // Aktuellen Git-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.')); + return []; + } + + // Git-Repository-Informationen abrufen + const { owner, repo } = await getRepoInfo(currentWorkspaceFolder); + if (!owner || !repo) { + vscode.window.showErrorMessage(localize('giteaClone.repoInfoError', 'Konnte Repository-Informationen nicht abrufen.')); + return []; + } + + try { + const response = await axios.get(`${instanceUrl}/api/v1/repos/${owner}/${repo}/pulls`, { + headers: { + 'Authorization': `token ${token}` + }, + params: { + state: 'open' + } + }); + + if (response.status === 200) { + return response.data; + } else { + vscode.window.showErrorMessage(localize('giteaClone.pullRequestsError', 'Fehler beim Abrufen der Pull Requests.')); + return []; + } + } catch (error) { + vscode.window.showErrorMessage(localize('giteaClone.apiError', 'Fehler bei der Verbindung zur Gitea API.')); + console.error(error); + return []; + } +} + +// Hilfsfunktion zum Abrufen von Repository-Informationen +async function getRepoInfo(folderPath: string): Promise<{ owner: string, repo: string }> { + 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.')); + } else { + let repoUrl = stdout.trim(); + + // URL umwandeln, wenn sie im SSH-Format vorliegt + 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', ''); + } + + const [owner, repo] = repoUrl.split('/').slice(-2); + resolve({ owner, repo }); + } + }); + }); +} + +// Funktion zum Anzeigen offener Pull Requests +async function showOpenPullRequests() { + const pullRequests = await getOpenPullRequests(); + + if (pullRequests.length === 0) { + vscode.window.showInformationMessage(localize('giteaClone.noOpenPRs', 'Keine offenen Pull Requests vorhanden.')); + return; + } + + const prItems = pullRequests.map(pr => ({ + label: `#${pr.number}: ${pr.title}`, + description: `von ${pr.user.username}`, + pr + })); + + const selectedPr = await vscode.window.showQuickPick(prItems, { + placeHolder: localize('giteaClone.selectPullRequest', 'Wähle einen Pull Request zum Anzeigen aus') + }); + + if (selectedPr) { + // Öffne die URL des ausgewählten PRs im Browser + vscode.env.openExternal(vscode.Uri.parse(selectedPr.pr.html_url)); + } +} + + +let extensionContext: vscode.ExtensionContext; + +// Funktion zum Aktualisieren des PR-Statusleisten-Icons +let prStatusBarItem: vscode.StatusBarItem; + +async function updatePRStatusBarItem(context: vscode.ExtensionContext) { + try { + const pullRequests = await getOpenPullRequests(); + + if (!prStatusBarItem) { + prStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); + prStatusBarItem.command = 'gitea.showOpenPullRequests'; + prStatusBarItem.tooltip = localize('giteaClone.showOpenPullRequestsTooltip', 'Offene Pull Requests anzeigen'); + context.subscriptions.push(prStatusBarItem); + } + + const prCount = pullRequests.length; + prStatusBarItem.text = `$(git-pull-request) Gitea Open PRs: ${prCount}`; + prStatusBarItem.show(); + } catch (error) { + console.error('Fehler beim Aktualisieren des PR-Statusleisten-Icons:', error); + if (prStatusBarItem) { + prStatusBarItem.hide(); + } + } +} + +// Funktion zum Starten des PR-Statusleisten-Updaters +function startPRStatusBarItemUpdater(context: vscode.ExtensionContext) { + updatePRStatusBarItem(context); // Initiales Update + + // Aktualisiere bei Fokuswechsel + vscode.window.onDidChangeWindowState((windowState) => { + if (windowState.focused) { + updatePRStatusBarItem(context); + } + }, null, context.subscriptions); + + // Aktualisiere alle 5 Minuten + setInterval(() => updatePRStatusBarItem(context), 300000); // 5 Minuten +} + + // Aktivierungsfunktion des Plugins export function activate(context: vscode.ExtensionContext) { // Registriert den Befehl zur Authentifizierung @@ -319,6 +463,13 @@ export function activate(context: vscode.ExtensionContext) { // Befehl zum Klonen eines Repositories let cloneCommand = vscode.commands.registerCommand('gitea.cloneRepository', cloneGiteaRepository); context.subscriptions.push(cloneCommand); + + // Befehl zum Anzeigen offener Pull Requests + let showPRCommand = vscode.commands.registerCommand('gitea.showOpenPullRequests', showOpenPullRequests); + context.subscriptions.push(showPRCommand); + + // Statusleisten-Icon erstellen und Updater starten + startPRStatusBarItemUpdater(context); } // Deaktivierungsfunktion des Plugins