Skip to content

Commit

Permalink
Add git to command palette (#1243)
Browse files Browse the repository at this point in the history
* Add git to command palette

* Add git to command palette

* Add git to command palette

* Add git to command palette

* Finish up the PR

* Deduplicate yjs

* Give another shot at fixing yjs

* Fix tests

* Lint the code

* Use debug mode

* Turn off debug

* Set up git identity for integration tests

---------

Co-authored-by: Frédéric Collonval <fcollonval@gmail.com>
  • Loading branch information
tsabbir96 and fcollonval authored Aug 8, 2023
1 parent 37d922b commit c639273
Show file tree
Hide file tree
Showing 21 changed files with 1,283 additions and 3,584 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ jobs:
run: jlpm playwright install chromium
working-directory: ui-tests

- name: Set up git
run: |
git config --global user.name 'Test Bot'
git config --global user.email 'test-bot@example.com'
- name: Execute integration tests
working-directory: ui-tests
run: |
Expand Down
2 changes: 1 addition & 1 deletion jupyterlab_git/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


def _jupyter_labextension_paths():
return [{"src": "labextension", "dest": "@jupyerlab/git"}]
return [{"src": "labextension", "dest": "@jupyterlab/git"}]


class JupyterLabGit(Configurable):
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@
"stylelint-config-recommended": "^13.0.0",
"stylelint-config-standard": "~34.0.0",
"ts-jest": "^26.0.0",
"typescript": "~4.3.5"
"typescript": "~4.3.5",
"yarn-dedupe": "^0.2.3",
"yjs": "^13.5.40"
},
"peerDependencies": {
"codemirror": "^5.0.0"
Expand Down
2 changes: 2 additions & 0 deletions src/__tests__/commands.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ describe('git-commands', () => {
iconLabel: '',
label: ''
},
isChecked: null,
value: undefined
});
const spyReset = jest.spyOn(model, 'reset');
Expand Down Expand Up @@ -146,6 +147,7 @@ describe('git-commands', () => {
iconLabel: '',
label: ''
},
isChecked: null,
value: {
checked
} as Git.ICheckboxFormValue
Expand Down
16 changes: 12 additions & 4 deletions src/__tests__/plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { ISettingRegistry, SettingRegistry } from '@jupyterlab/settingregistry';
import { JupyterLab } from '@jupyterlab/application';
import { showErrorMessage } from '@jupyterlab/apputils';
import { URLExt } from '@jupyterlab/coreutils';
import { Signal } from '@lumino/signaling';
import {
defaultMockedResponses,
IMockedResponses,
mockedRequestAPI
} from './utils';
import { IFileBrowserFactory } from '@jupyterlab/filebrowser';

jest.mock('../git');
jest.mock('@jupyterlab/application');
Expand All @@ -22,11 +24,17 @@ const plugin = plugins[0];
describe('plugin', () => {
const mockGit = git as jest.Mocked<typeof git>;
let app: jest.Mocked<JupyterLab>;
let browserFactory: jest.Mocked<IFileBrowserFactory>;
let mockResponses: IMockedResponses = {};
let settingRegistry: jest.Mocked<ISettingRegistry>;

beforeAll(() => {
app = new JupyterLab() as jest.Mocked<JupyterLab>;
browserFactory = {
defaultBrowser: {
model: { pathChanged: new Signal(null), restored: Promise.resolve() }
}
} as unknown as jest.Mocked<IFileBrowserFactory>;
settingRegistry = new SettingRegistry({
connector: null
}) as jest.Mocked<SettingRegistry>;
Expand Down Expand Up @@ -59,7 +67,7 @@ describe('plugin', () => {
const extension = await plugin.activate(
app,
null,
null,
browserFactory,
{ tracker: { currentWidget: null } },
null,
settingRegistry
Expand Down Expand Up @@ -94,7 +102,7 @@ describe('plugin', () => {
const extension = await plugin.activate(
app,
null,
null,
browserFactory,
{ tracker: { currentWidget: null } },
null,
settingRegistry
Expand Down Expand Up @@ -128,7 +136,7 @@ describe('plugin', () => {
const extension = await plugin.activate(
app,
null,
null,
browserFactory,
{ tracker: { currentWidget: null } },
null,
settingRegistry
Expand Down Expand Up @@ -159,7 +167,7 @@ describe('plugin', () => {
const extension = await plugin.activate(
app,
null,
null,
browserFactory,
{ tracker: { currentWidget: null } },
null,
settingRegistry
Expand Down
1 change: 1 addition & 0 deletions src/__tests__/test-components/BranchMenu.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ describe('BranchMenu', () => {
iconLabel: '',
label: ''
},
isChecked: null,
value: undefined
});
});
Expand Down
2 changes: 2 additions & 0 deletions src/__tests__/test-components/GitPanel.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ describe('GitPanel', () => {
iconLabel: '',
label: ''
},
isChecked: null,
value: {
name: commitUser['user.name'],
email: commitUser['user.email']
Expand Down Expand Up @@ -207,6 +208,7 @@ describe('GitPanel', () => {
...dialogValue.button,
accept: false
},
isChecked: null,
value: null
});

Expand Down
18 changes: 13 additions & 5 deletions src/cloneCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
import { CommandIDs, IGitExtension, Level } from './tokens';
import { IFileBrowserFactory } from '@jupyterlab/filebrowser';
import { Dialog, showDialog } from '@jupyterlab/apputils';
import { Dialog, ICommandPalette, showDialog } from '@jupyterlab/apputils';
import { GitCloneForm } from './widgets/GitCloneForm';
import { logger } from './logger';
import {
Expand All @@ -19,14 +19,16 @@ import { addCloneButton } from './widgets/gitClone';

export const gitCloneCommandPlugin: JupyterFrontEndPlugin<void> = {
id: '@jupyterlab/git:clone',
requires: [ITranslator, IGitExtension, IFileBrowserFactory],
requires: [IGitExtension, IFileBrowserFactory],
optional: [ICommandPalette, ITranslator],
activate: (
app: JupyterFrontEnd,
translator: ITranslator,
gitModel: IGitExtension,
fileBrowserFactory: IFileBrowserFactory
fileBrowserFactory: IFileBrowserFactory,
palette: ICommandPalette | null,
translator: ITranslator | null
) => {
translator = translator || nullTranslator;
translator = translator ?? nullTranslator;
const trans = translator.load('jupyterlab_git');
const fileBrowser = fileBrowserFactory.defaultBrowser;
const fileBrowserModel = fileBrowser.model;
Expand Down Expand Up @@ -89,6 +91,12 @@ export const gitCloneCommandPlugin: JupyterFrontEndPlugin<void> = {

// Add the context menu items for the default file browser
addFileBrowserContextMenu(gitModel, fileBrowser, app.contextMenu, trans);

if (palette) {
// Add the commands to the command palette
const category = 'Git Operations';
palette.addItem({ command: CommandIDs.gitClone, category });
}
},
autoStart: true
};
54 changes: 39 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import {
JupyterFrontEnd,
JupyterFrontEndPlugin
} from '@jupyterlab/application';
import { Dialog, showErrorMessage, Toolbar } from '@jupyterlab/apputils';
import {
Dialog,
ICommandPalette,
showErrorMessage,
Toolbar
} from '@jupyterlab/apputils';
import { IChangedArgs } from '@jupyterlab/coreutils';
import { IDocumentManager } from '@jupyterlab/docmanager';
import { FileBrowserModel, IFileBrowserFactory } from '@jupyterlab/filebrowser';
Expand All @@ -12,43 +17,41 @@ import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
import { IStatusBar } from '@jupyterlab/statusbar';
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
import { gitCloneCommandPlugin } from './cloneCommand';
import {
addCommands,
addFileBrowserContextMenu,
createGitMenu
} from './commandsAndMenu';
import { createImageDiff } from './components/diff/ImageDiff';
import { createNotebookDiff } from './components/diff/NotebookDiff';
import { addStatusBarWidget } from './components/StatusWidget';
import { GitExtension } from './model';
import { getServerSettings } from './server';
import { gitIcon } from './style/icons';
import { Git, IGitExtension } from './tokens';
import { CommandIDs, Git, IGitExtension } from './tokens';
import { addCloneButton } from './widgets/gitClone';
import { GitWidget } from './widgets/GitWidget';
import { gitCloneCommandPlugin } from './cloneCommand';
import { createImageDiff } from './components/diff/ImageDiff';

export { DiffModel } from './components/diff/model';
export { NotebookDiff } from './components/diff/NotebookDiff';
export { PlainTextDiff } from './components/diff/PlainTextDiff';
export { Git, IGitExtension } from './tokens';
export { logger, LoggerContext } from './logger';
export { Git, IGitExtension } from './tokens';

/**
* The default running sessions extension.
*/
const plugin: JupyterFrontEndPlugin<IGitExtension> = {
id: '@jupyterlab/git:plugin',
requires: [
IMainMenu,
ILayoutRestorer,
IFileBrowserFactory,
IRenderMimeRegistry,
ISettingRegistry,
IDocumentManager,
IStatusBar,
ITranslator
IDocumentManager
],
optional: [IMainMenu, IStatusBar, ICommandPalette, ITranslator],
provides: IGitExtension,
activate,
autoStart: true
Expand All @@ -64,14 +67,15 @@ export default [plugin, gitCloneCommandPlugin];
*/
async function activate(
app: JupyterFrontEnd,
mainMenu: IMainMenu,
restorer: ILayoutRestorer,
factory: IFileBrowserFactory,
renderMime: IRenderMimeRegistry,
settingRegistry: ISettingRegistry,
docmanager: IDocumentManager,
statusBar: IStatusBar,
translator?: ITranslator
mainMenu: IMainMenu | null,
statusBar: IStatusBar | null,
palette: ICommandPalette | null,
translator: ITranslator | null
): Promise<IGitExtension> {
let gitExtension: GitExtension | null = null;
let settings: ISettingRegistry.ISettings;
Expand All @@ -82,7 +86,7 @@ async function activate(
// And it is unlikely that another browser than the default will be used.
// Ref: https://github.com/jupyterlab/jupyterlab-git/issues/1014
const fileBrowser = factory.defaultBrowser;
translator = translator || nullTranslator;
translator = translator ?? nullTranslator;
const trans = translator.load('jupyterlab_git');

// Attempt to load application settings
Expand Down Expand Up @@ -186,6 +190,24 @@ async function activate(
gitPlugin.title.icon = gitIcon;
gitPlugin.title.caption = 'Git';

if (palette) {
// Add the commands to the command palette
const category = 'Git Operations';
[
CommandIDs.gitToggleSimpleStaging,
CommandIDs.gitToggleDoubleClickDiff,
CommandIDs.gitOpenGitignore,
CommandIDs.gitShowDiff,
CommandIDs.gitInit,
CommandIDs.gitMerge,
CommandIDs.gitPush,
CommandIDs.gitPull,
CommandIDs.gitResetToRemote,
CommandIDs.gitManageRemote,
CommandIDs.gitTerminalCommand
].forEach(command => palette.addItem({ command, category }));
}

// Let the application restorer track the running panel for restoration of
// application state (e.g. setting the running panel as the current side bar
// widget).
Expand All @@ -196,7 +218,7 @@ async function activate(
app.shell.add(gitPlugin, 'left', { rank: 200 });

// Add a menu for the plugin
if (app.version.split('.').slice(0, 2).join('.') < '3.1') {
if (mainMenu && app.version.split('.').slice(0, 2).join('.') < '3.1') {
// Support JLab 3.0
mainMenu.addMenu(createGitMenu(app.commands, trans), { rank: 60 });
}
Expand All @@ -205,7 +227,9 @@ async function activate(
addCloneButton(gitExtension, fileBrowser, app.commands, trans);

// Add the status bar widget
addStatusBarWidget(statusBar, gitExtension, settings, trans);
if (statusBar) {
addStatusBarWidget(statusBar, gitExtension, settings, trans);
}

// Add the context menu items for the default file browser
addFileBrowserContextMenu(
Expand Down
7 changes: 7 additions & 0 deletions ui-tests/jupyter_server_test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
opens the server to the world and provide access to JupyterLab
JavaScript objects through the global window variable.
"""
import sys
from tempfile import mkdtemp

try:
import jupyter_archive
except ImportError:
print("You must install `jupyter-archive` for the integration tests.")
sys.exit(1)

c.ServerApp.port = 8888
c.ServerApp.port_retries = 0
c.ServerApp.open_browser = False
Expand Down
6 changes: 2 additions & 4 deletions ui-tests/tests/commit-diff.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { test } from '@jupyterlab/galata';
import { expect } from '@playwright/test';
import { expect, test } from '@jupyterlab/galata';
import path from 'path';
import { extractFile } from './utils';

Expand All @@ -15,7 +14,7 @@ test.describe('Commits diff', () => {
);

// URL for merge conflict example repository
await page.goto(`tree/${tmpPath}/repository`);
await page.goto(`tree/${tmpPath}/test-repository`);
});

test('should display commits diff from history', async ({ page }) => {
Expand All @@ -40,7 +39,6 @@ test.describe('Commits diff', () => {

test('should display diff from single file history', async ({ page }) => {
await page.sidebar.openTab('filebrowser');
await page.pause();
await page.click('#filebrowser >> text=example.ipynb', {
button: 'right'
});
Expand Down
Binary file modified ui-tests/tests/data/test-repository-dirty.tar.gz
Binary file not shown.
Binary file modified ui-tests/tests/data/test-repository-stash.tar.gz
Binary file not shown.
Binary file modified ui-tests/tests/data/test-repository.tar.gz
Binary file not shown.
5 changes: 3 additions & 2 deletions ui-tests/tests/file-selection.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { test } from '@jupyterlab/galata';
import { expect } from '@playwright/test';
import { expect, test } from '@jupyterlab/galata';
import path from 'path';
import { extractFile } from './utils';

Expand Down Expand Up @@ -89,6 +88,8 @@ test.describe('File selection for simple staging', () => {
await page.sidebar.openTab('jp-git-sessions');
await page.click('button:has-text("Changes")');

await page.getByText('(4)').waitFor();

let markedFiles = page.locator('[data-test-checked=true]');
expect(await markedFiles.count()).toBeGreaterThanOrEqual(4);

Expand Down
3 changes: 1 addition & 2 deletions ui-tests/tests/git-stash.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { expect } from '@playwright/test';
import { test } from '@jupyterlab/galata';
import { expect, test } from '@jupyterlab/galata';
import path from 'path';
import { extractFile } from './utils';

Expand Down
5 changes: 2 additions & 3 deletions ui-tests/tests/image-diff.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { test } from '@jupyterlab/galata';
import { expect } from '@playwright/test';
import { expect, test } from '@jupyterlab/galata';
import path from 'path';
import { extractFile } from './utils';

Expand All @@ -15,7 +14,7 @@ test.describe('Image diff', () => {
);

// URL for merge conflict example repository
await page.goto(`tree/${tmpPath}/repository`);
await page.goto(`tree/${tmpPath}/test-repository`);
});

test('should display image diff from history', async ({ page }) => {
Expand Down
Loading

0 comments on commit c639273

Please sign in to comment.