UNPKG

@jupyterlab/git

Version:

A JupyterLab extension for version control using git

104 lines (103 loc) 5.76 kB
import { Dialog, ICommandPalette, IToolbarWidgetRegistry, Notification, ReactWidget, showDialog, ToolbarButtonComponent, UseSignal } from '@jupyterlab/apputils'; import { IDefaultFileBrowser } from '@jupyterlab/filebrowser'; import { ITranslator, nullTranslator } from '@jupyterlab/translation'; import * as React from 'react'; import { addFileBrowserContextMenu, Operation, showGitOperationDialog } from './commandsAndMenu'; import { cloneIcon } from './style/icons'; import { CommandIDs, IGitExtension } from './tokens'; import { GitCloneForm } from './widgets/GitCloneForm'; import { showDetails, showError } from './notifications'; export const gitCloneCommandPlugin = { id: '@jupyterlab/git:clone', description: 'Adds a Git clone command to the file browser toolbar.', requires: [IGitExtension, IDefaultFileBrowser, IToolbarWidgetRegistry], optional: [ICommandPalette, ITranslator], activate: (app, gitModel, fileBrowser, toolbarRegistry, palette, translator) => { translator = translator !== null && translator !== void 0 ? translator : nullTranslator; const trans = translator.load('jupyterlab_git'); const fileBrowserModel = fileBrowser.model; /** Add git clone command */ app.commands.addCommand(CommandIDs.gitClone, { label: trans.__('Clone a Repository'), caption: trans.__('Clone a repository from a URL'), isEnabled: () => gitModel.pathRepository === null, execute: async () => { var _a; const result = await showDialog({ title: trans.__('Clone a repo'), body: new GitCloneForm(trans), focusNodeSelector: 'input', buttons: [ Dialog.cancelButton({ label: trans.__('Cancel') }), Dialog.okButton({ label: trans.__('Clone') }) ] }); if (result.button.accept && ((_a = result.value) === null || _a === void 0 ? void 0 : _a.url)) { const id = Notification.emit(trans.__('Cloning…'), 'in-progress', { autoClose: false }); const url = decodeURIComponent(result.value.url); const hostnameMatch = url.match(/git@(.+):.+/); if (hostnameMatch && hostnameMatch.length > 1) { const hostname = hostnameMatch[1]; const isKnownHost = await gitModel.checkKnownHost(hostname); if (!isKnownHost) { const result = await showDialog({ title: trans.__('Unknown Host'), body: trans.__('The host %1 is not known. Would you like to add it to the known_hosts file?', hostname), buttons: [ Dialog.cancelButton({ label: trans.__('Cancel') }), Dialog.okButton({ label: trans.__('OK') }) ] }); if (result.button.accept) { await gitModel.addHostToKnownList(hostname); } } } try { const details = await showGitOperationDialog(gitModel, Operation.Clone, trans, { path: app.serviceManager.contents.localPath(fileBrowserModel.path), url: result.value.url, versioning: result.value.versioning, submodules: result.value.submodules }); Notification.update({ id, message: trans.__('Successfully cloned'), type: 'success', ...showDetails(details, trans) }); await fileBrowserModel.refresh(); } catch (error) { console.error('Encountered an error when cloning the repository. Error: ', error); Notification.update({ id, message: trans.__('Failed to clone'), type: 'error', ...showError(error, trans) }); throw error; } } } }); // Register a clone button to the file browser extension toolbar toolbarRegistry.addFactory('FileBrowser', 'gitClone', () => ReactWidget.create(React.createElement(UseSignal, { signal: gitModel.repositoryChanged, initialArgs: { name: 'pathRepository', oldValue: null, newValue: gitModel.pathRepository } }, (_, change) => (React.createElement(ToolbarButtonComponent, { enabled: (change === null || change === void 0 ? void 0 : change.newValue) === null, icon: cloneIcon, onClick: () => { app.commands.execute(CommandIDs.gitClone); }, tooltip: trans.__('Git Clone') }))))); // Add the context menu items for the default file browser addFileBrowserContextMenu(gitModel, fileBrowser, app.serviceManager.contents, app.contextMenu, trans); if (palette) { // Add the commands to the command palette const category = 'Git Operations'; palette.addItem({ command: CommandIDs.gitClone, category }); } }, autoStart: true };