* feat(extension.ts): add support for localization in Gitea Git Clone extension

* feat(extension.ts): add command to clone a repository from Gitea
This commit is contained in:
2024-10-21 10:17:08 +02:00
parent 2f58d729ab
commit 7544998d93
5 changed files with 212 additions and 28 deletions

View File

@ -1,6 +1,10 @@
import * as vscode from 'vscode';
import axios from 'axios';
import { exec } from 'child_process';
import * as nls from 'vscode-nls';
// Initialisiere die Lokalisierung
const localize = nls.config({ messageFormat: nls.MessageFormat.file })();
// Funktion zum Erstellen eines Pull Requests
async function createGiteaPullRequest() {
@ -8,21 +12,21 @@ async function createGiteaPullRequest() {
const token = vscode.workspace.getConfiguration().get<string>('gitea.personalAccessToken');
if (!instanceUrl || !token) {
vscode.window.showErrorMessage('Gitea URL oder Token ist nicht konfiguriert.');
vscode.window.showErrorMessage(localize('giteaClone.configMissing', 'Gitea URL or Token is not configured.'));
return;
}
// Aktuellen Git-Ordner abrufen
const currentWorkspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath;
if (!currentWorkspaceFolder) {
vscode.window.showErrorMessage('Kein gültiges Git-Repository im aktuellen Workspace gefunden.');
vscode.window.showErrorMessage(localize('giteaClone.noValidRepo', 'No valid Git repository found in the current workspace.'));
return;
}
// Git-Repository-Informationen abrufen
exec(`git config --get remote.origin.url`, { cwd: currentWorkspaceFolder }, async (error, stdout, stderr) => {
if (error || !stdout) {
vscode.window.showErrorMessage('Konnte die Git-Remote-URL nicht abrufen.');
vscode.window.showErrorMessage(localize('giteaClone.noRemoteUrl', 'Could not retrieve Git remote URL.'));
return;
}
@ -47,7 +51,7 @@ async function createGiteaPullRequest() {
const branch = await getCurrentBranch(currentWorkspaceFolder);
if (!branch) {
vscode.window.showErrorMessage('Branch konnte nicht ermittelt werden.');
vscode.window.showErrorMessage(localize('giteaClone.noBranch', 'Could not determine the branch.'));
return;
}
@ -80,10 +84,10 @@ async function createGiteaPullRequest() {
// Öffne die URL des erstellten PRs im Browser
vscode.env.openExternal(vscode.Uri.parse(prUrl));
vscode.window.showInformationMessage('Pull-Request erfolgreich erstellt und im Browser geöffnet.');
vscode.window.showInformationMessage(localize('giteaClone.pullRequestCreated', 'Pull request created successfully and opened in the browser.'));
} catch (err: any) {
vscode.window.showErrorMessage(`Fehler beim Erstellen des Pull Requests: ${err.message}`);
console.error('Fehler beim Erstellen des PRs:', err);
vscode.window.showErrorMessage(localize('giteaClone.pullRequestError', `Error creating pull request: ${err.message}`));
console.error('Error creating PR:', err);
}
});
}
@ -93,7 +97,7 @@ async function getLastCommit(folderPath: string): Promise<{ title: string, body:
return new Promise((resolve, reject) => {
exec(`git log -1 --pretty=format:"%s%n%b"`, { cwd: folderPath }, (error, stdout) => {
if (error) {
reject('Fehler beim Abrufen des letzten Commits.');
reject(localize('giteaClone.commitError', 'Error retrieving the last commit.'));
} else {
const output = stdout.split('\n');
const title = output[0]; // Commit-Message als Titel
@ -109,7 +113,7 @@ async function getCurrentBranch(folderPath: string): Promise<string> {
return new Promise((resolve, reject) => {
exec(`git rev-parse --abbrev-ref HEAD`, { cwd: folderPath }, (error, stdout) => {
if (error) {
reject('Fehler beim Abrufen des Branches.');
reject(localize('giteaClone.branchError', 'Error retrieving the branch.'));
} else {
resolve(stdout.trim());
}
@ -129,20 +133,120 @@ async function getDefaultBranch(instanceUrl: string, owner: string, repo: string
if (response.status === 200 && response.data.default_branch) {
return response.data.default_branch;
} else {
vscode.window.showErrorMessage('Konnte den base-Branch nicht ermitteln. Standardmäßig "main" verwendet.');
vscode.window.showErrorMessage(localize('giteaClone.defaultBranchError', 'Could not determine the base branch. Defaulting to "main".'));
return 'main';
}
} catch (error) {
vscode.window.showErrorMessage('Fehler beim Abrufen des base-Branches. Standardmäßig "main" verwendet.');
vscode.window.showErrorMessage(localize('giteaClone.defaultBranchError', 'Error retrieving the base branch. Defaulting to "main".'));
return 'main';
}
}
// 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');
if (!instanceUrl || !token) {
vscode.window.showErrorMessage(localize('giteaClone.configMissing', 'Gitea URL or Token is not configured.'));
return [];
}
try {
const response = await axios.get(`${instanceUrl}/api/v1/user/repos`, {
headers: {
'Authorization': `token ${token}`
}
});
if (response.status === 200) {
return response.data;
} else {
vscode.window.showErrorMessage(localize('giteaClone.repoError', 'Error retrieving repositories.'));
return [];
}
} catch (error) {
vscode.window.showErrorMessage(localize('giteaClone.apiError', 'Error connecting to Gitea API.'));
console.error(error);
return [];
}
}
// Funktion zum Klonen eines Repositories via SSH
async function cloneGiteaRepository() {
const repos = await getGiteaRepositories();
if (repos.length === 0) {
vscode.window.showInformationMessage(localize('giteaClone.noRepos', 'No repositories found.'));
return;
}
const repoNames = repos.map(repo => repo.full_name);
const selectedRepo = await vscode.window.showQuickPick(repoNames, {
placeHolder: localize('giteaClone.selectRepo', 'Select a repository to clone')
});
if (!selectedRepo) {
vscode.window.showInformationMessage(localize('giteaClone.noRepoSelected', 'No repository selected.'));
return;
}
const repo = repos.find(r => r.full_name === selectedRepo);
if (repo && repo.ssh_url) {
const folderUri = await vscode.window.showOpenDialog({
canSelectFiles: false,
canSelectFolders: true,
canSelectMany: false,
openLabel: localize('giteaClone.selectFolder', 'Select folder to clone into')
});
if (folderUri && folderUri[0]) {
const folderPath = folderUri[0].fsPath;
vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: localize('giteaClone.cloningRepo', `Cloning ${selectedRepo}`),
cancellable: false
}, async (progress, token) => {
progress.report({ message: localize('giteaClone.cloningProgress', 'Cloning in progress...'), increment: 0 });
return new Promise<void>((resolve, reject) => {
exec(`git clone ${repo.ssh_url} ${folderPath}`, (error, stdout, stderr) => {
if (error) {
vscode.window.showErrorMessage(localize('giteaClone.cloneError', 'Error cloning the repository.'));
console.error(stderr);
reject(error);
} else {
progress.report({ message: localize('giteaClone.cloneComplete', 'Repository cloned successfully.'), increment: 100 });
vscode.window.showInformationMessage(localize('giteaClone.cloneSuccess', `Repository ${selectedRepo} cloned successfully.`));
// Öffne das geklonte Repository im VSCode
try {
vscode.commands.executeCommand('vscode.openFolder', vscode.Uri.file(folderPath), true)
.then(() => resolve());
} catch (err: unknown) {
vscode.window.showErrorMessage(localize('giteaClone.openRepoError', 'Error opening the cloned repository.'));
console.error(err);
reject(err);
}
}
});
});
});
} else {
vscode.window.showInformationMessage(localize('giteaClone.noFolderSelected', 'No target folder selected.'));
}
} else {
vscode.window.showErrorMessage(localize('giteaClone.noSshUrl', 'Could not find SSH clone URL.'));
}
}
// Funktion zum Hinzufügen des Statusbar-Icons
function addStatusBarIcon() {
const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
statusBar.text = `$(git-pull-request) Create Gitea PR`;
statusBar.tooltip = 'Create a Pull Request in Gitea';
statusBar.text = `$(git-pull-request) ${localize('giteaClone.createPullRequest', 'Create Gitea PR')}`;
statusBar.tooltip = localize('giteaClone.createPullRequestTooltip', 'Create a Pull Request in Gitea');
statusBar.command = 'gitea.createPullRequest';
statusBar.show(); // Sofortiges Anzeigen des Icons in der Statusleiste
return statusBar;
@ -154,7 +258,7 @@ async function authenticateGitea() {
const token = vscode.workspace.getConfiguration().get<string>('gitea.personalAccessToken');
if (!instanceUrl || !token) {
vscode.window.showErrorMessage('Gitea URL oder Token ist nicht konfiguriert.');
vscode.window.showErrorMessage(localize('giteaClone.configMissing', 'Gitea URL or Token is not configured.'));
return;
}
@ -166,10 +270,10 @@ async function authenticateGitea() {
});
if (response.status === 200) {
vscode.window.showInformationMessage(`Authentifizierung erfolgreich: ${response.data.username}`);
vscode.window.showInformationMessage(localize('giteaClone.authSuccess', `Authentication successful: ${response.data.username}`));
}
} catch (error) {
vscode.window.showErrorMessage('Authentifizierung fehlgeschlagen.');
vscode.window.showErrorMessage(localize('giteaClone.authFailed', 'Authentication failed.'));
console.error(error);
}
}
@ -177,20 +281,20 @@ async function authenticateGitea() {
// Funktion zur Konfiguration der Gitea-Instanz und des Tokens über die Command Palette
async function configureGitea() {
const instanceUrl = await vscode.window.showInputBox({
prompt: "Gitea Instanz-URL eingeben",
placeHolder: "https://your-gitea-instance.com"
prompt: localize('giteaClone.enterInstanceUrl', 'Enter Gitea instance URL'),
placeHolder: 'https://your-gitea-instance.com'
});
const token = await vscode.window.showInputBox({
prompt: "Gitea Personal Access Token eingeben",
placeHolder: "token",
prompt: localize('giteaClone.enterToken', 'Enter Gitea Personal Access Token'),
placeHolder: 'token',
password: true
});
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('Gitea Konfiguration aktualisiert.');
vscode.window.showInformationMessage(localize('giteaClone.configUpdated', 'Gitea configuration updated.'));
}
}
@ -211,6 +315,10 @@ export function activate(context: vscode.ExtensionContext) {
// 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);
}
// Deaktivierungsfunktion des Plugins