Skip to content

Commit

Permalink
Move Git history view to SCM package
Browse files Browse the repository at this point in the history
Signed-off-by: Nigel Westbury <nigelipse@miegel.org>
  • Loading branch information
westbury committed Nov 22, 2019
1 parent fc49b2c commit c008384
Show file tree
Hide file tree
Showing 37 changed files with 885 additions and 492 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ cache:
- packages/preview/node_modules
- packages/process/node_modules
- packages/python/node_modules
- packages/scm-extra/node_modules
- packages/scm/node_modules
- packages/search-in-workspace/node_modules
- packages/task/node_modules
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Breaking changes:
Most browsers define a page as served from secure context if its url has `https` scheme. For local testing `localhost` is treated as a secure context as well.
Unfortunately, it does not work nicely in FireFox, since it does not treat subdomains of localhost as secure as well, compare to Chrome.
If you want to test with FireFox you can configure it as described [here](https://github.com/eclipse-theia/theia/pull/6465#issuecomment-556443218).
- [scm][git] the History view (GitHistoryWidget) has moved from the git package to a new package, scm-extra, and renamed to ScmHistoryWidget. GitNavigableListWidget has also moved. [6381](https://github.com/eclipse-theia/theia/pull/6381)

## v0.12.0

Expand Down
2 changes: 1 addition & 1 deletion examples/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"@theia/preview": "^0.12.0",
"@theia/process": "^0.12.0",
"@theia/python": "^0.12.0",
"@theia/scm": "^0.12.0",
"@theia/scm-extra": "^0.12.0",
"@theia/search-in-workspace": "^0.12.0",
"@theia/task": "^0.12.0",
"@theia/terminal": "^0.12.0",
Expand Down
4 changes: 2 additions & 2 deletions examples/browser/test/left-panel/left-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ export class LeftPanel {
}

isGitHistoryContainerVisible(): boolean {
return (this.driver.isExisting('#git-history') && this.driver.element('#git-history').getAttribute('class').split(' ').indexOf('p-mod-hidden') === -1
return (this.driver.isExisting('#scm-history') && this.driver.element('#scm-history').getAttribute('class').split(' ').indexOf('p-mod-hidden') === -1
&& this.isPanelVisible());
}

waitForGitHistoryViewVisible(): void {
this.driver.waitForVisible('#git-history');
this.driver.waitForVisible('#scm-history');
// Wait for animations to finish
this.driver.pause(300);
}
Expand Down
4 changes: 2 additions & 2 deletions examples/browser/test/top-panel/top-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ export class TopPanel {

toggleScmView(): void {
this.clickMenuTab('View');
this.clickSubMenu('SCM');
this.clickSubMenu('Source Control');
}

toggleGitHistoryView(): void {
this.clickMenuTab('View');
this.clickSubMenu('Git History');
this.clickSubMenu('Source History');
}

toggleOutlineView(): void {
Expand Down
1 change: 1 addition & 0 deletions examples/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"@theia/preview": "^0.12.0",
"@theia/process": "^0.12.0",
"@theia/python": "^0.12.0",
"@theia/scm-extra": "^0.12.0",
"@theia/search-in-workspace": "^0.12.0",
"@theia/task": "^0.12.0",
"@theia/terminal": "^0.12.0",
Expand Down
1 change: 1 addition & 0 deletions packages/git/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"@theia/languages": "^0.12.0",
"@theia/navigator": "^0.12.0",
"@theia/scm": "^0.12.0",
"@theia/scm-extra": "^0.12.0",
"@theia/workspace": "^0.12.0",
"@types/diff": "^3.2.2",
"@types/p-queue": "^2.3.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/git/src/browser/blame/blame-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { BlameDecorator } from './blame-decorator';
import { EditorManager, EditorKeybindingContexts, EditorWidget, EditorTextFocusContext, StrictEditorTextFocusContext } from '@theia/editor/lib/browser';
import { BlameManager } from './blame-manager';
import URI from '@theia/core/lib/common/uri';
import { EDITOR_CONTEXT_MENU_GIT } from '../git-contribution';
import { EDITOR_CONTEXT_MENU_SCM } from '@theia/scm-extra/lib/browser/scm-extra-contribution';

import debounce = require('lodash.debounce');

Expand Down Expand Up @@ -136,7 +136,7 @@ export class BlameContribution implements CommandContribution, KeybindingContrib
}

registerMenus(menus: MenuModelRegistry): void {
menus.registerMenuAction(EDITOR_CONTEXT_MENU_GIT, {
menus.registerMenuAction(EDITOR_CONTEXT_MENU_SCM, {
commandId: BlameCommands.TOGGLE_GIT_ANNOTATIONS.id,
});
}
Expand Down
20 changes: 14 additions & 6 deletions packages/git/src/browser/diff/git-diff-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { FrontendApplication, AbstractViewContribution } from '@theia/core/lib/b
import { WidgetManager } from '@theia/core/lib/browser/widget-manager';
import { injectable, inject } from 'inversify';
import { GitDiffWidget, GIT_DIFF } from './git-diff-widget';
import { ScmService } from '@theia/scm/lib/browser/scm-service';
import { open, OpenerService } from '@theia/core/lib/browser';
import { NavigatorContextMenu, FileNavigatorContribution } from '@theia/navigator/lib/browser/navigator-contribution';
import { UriCommandHandler } from '@theia/core/lib/common/uri-command-handler';
Expand All @@ -27,8 +28,7 @@ import { FileSystem } from '@theia/filesystem/lib/common';
import { DiffUris } from '@theia/core/lib/browser/diff-uris';
import URI from '@theia/core/lib/common/uri';
import { GIT_RESOURCE_SCHEME } from '../git-resource';
import { Git } from '../../common';
import { GitRepositoryProvider } from '../git-repository-provider';
import { Git, Repository } from '../../common';
import { WorkspaceRootUriAwareCommandHandler } from '@theia/workspace/lib/browser/workspace-commands';
import { WorkspaceService } from '@theia/workspace/lib/browser';
import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
Expand Down Expand Up @@ -65,7 +65,7 @@ export class GitDiffContribution extends AbstractViewContribution<GitDiffWidget>
@inject(FileSystem) protected readonly fileSystem: FileSystem,
@inject(OpenerService) protected openerService: OpenerService,
@inject(MessageService) protected readonly notifications: MessageService,
@inject(GitRepositoryProvider) protected readonly repositoryProvider: GitRepositoryProvider
@inject(ScmService) protected readonly scmService: ScmService
) {
super({
widgetId: GIT_DIFF,
Expand All @@ -85,8 +85,8 @@ export class GitDiffContribution extends AbstractViewContribution<GitDiffWidget>

registerCommands(commands: CommandRegistry): void {
commands.registerCommand(GitDiffCommands.OPEN_FILE_DIFF, this.newWorkspaceRootUriAwareCommandHandler({
isVisible: uri => !!this.repositoryProvider.findRepository(uri),
isEnabled: uri => !!this.repositoryProvider.findRepository(uri),
isVisible: uri => !!this.findGitRepository(uri),
isEnabled: uri => !!this.findGitRepository(uri),
execute: async fileUri => {
await this.quickOpenService.chooseTagsAndBranches(
async (fromRevision, toRevision) => {
Expand All @@ -112,7 +112,7 @@ export class GitDiffContribution extends AbstractViewContribution<GitDiffWidget>
}
}
}
}, this.repositoryProvider.findRepository(fileUri));
}, this.findGitRepository(fileUri));
}
}));
}
Expand All @@ -126,6 +126,14 @@ export class GitDiffContribution extends AbstractViewContribution<GitDiffWidget>
});
}

protected findGitRepository(uri: URI): Repository | undefined {
const repo = this.scmService.findRepository(uri);
if (repo && repo.provider.id === 'git') {
return { localUri: repo.provider.rootUri };
}
return undefined;
}

async showWidget(options: Git.Options.Diff): Promise<GitDiffWidget> {
const widget = await this.widget;
await widget.setContent(options);
Expand Down
51 changes: 34 additions & 17 deletions packages/git/src/browser/diff/git-diff-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,24 @@ import { inject, injectable, postConstruct } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { StatefulWidget, SELECTED_CLASS, DiffUris, Message } from '@theia/core/lib/browser';
import { EditorManager, EditorOpenerOptions, EditorWidget, DiffNavigatorProvider, DiffNavigator } from '@theia/editor/lib/browser';
import { ScmRepository } from '@theia/scm/lib/browser/scm-repository';
import { ScmService } from '@theia/scm/lib/browser/scm-service';
import { GitFileChange, GitFileStatus, Git, WorkingDirectoryStatus } from '../../common';
import { GitScmProvider, GitScmFileChange } from '../git-scm-provider';
import { GitWatcher } from '../../common';
import { GIT_RESOURCE_SCHEME } from '../git-resource';
import { GitNavigableListWidget } from '../git-navigable-list-widget';
import { ScmNavigableListWidget } from '@theia/scm-extra/lib/browser/scm-navigable-list-widget';
import { GitFileChangeNode } from '../git-file-change-node';
import { Deferred } from '@theia/core/lib/common/promise-util';
import { GitRepositoryProvider } from '../git-repository-provider';
import * as React from 'react';
import { MaybePromise } from '@theia/core/lib/common/types';

// tslint:disable:no-null-keyword

export const GIT_DIFF = 'git-diff';
@injectable()
export class GitDiffWidget extends GitNavigableListWidget<GitFileChangeNode> implements StatefulWidget {
export class GitDiffWidget extends ScmNavigableListWidget<GitFileChangeNode> implements StatefulWidget {

protected readonly GIT_DIFF_TITLE = 'Diff';

Expand All @@ -45,9 +49,11 @@ export class GitDiffWidget extends GitNavigableListWidget<GitFileChangeNode> imp
protected deferredListContainer = new Deferred<HTMLElement>();

@inject(Git) protected readonly git: Git;
@inject(GitRepositoryProvider) protected readonly repositoryProvider: GitRepositoryProvider;
@inject(DiffNavigatorProvider) protected readonly diffNavigatorProvider: DiffNavigatorProvider;
@inject(EditorManager) protected readonly editorManager: EditorManager;
@inject(GitWatcher) protected readonly gitWatcher: GitWatcher;
@inject(ScmService) protected readonly sucmService: ScmService;

constructor() {
super();
Expand Down Expand Up @@ -90,8 +96,10 @@ export class GitDiffWidget extends GitNavigableListWidget<GitFileChangeNode> imp

async setContent(options: Git.Options.Diff): Promise<void> {
this.options = options;
const repository = this.repositoryProvider.findRepositoryOrSelected(options);
if (repository) {
const scmRepository = this.findRepositoryOrSelected(options.uri);
if (scmRepository && scmRepository.provider.id === 'git') {
const provider = scmRepository.provider as GitScmProvider;
const repository = { localUri: scmRepository.provider.rootUri };
const fileChanges: GitFileChange[] = await this.git.diff(repository, {
range: options.range,
uri: options.uri
Expand All @@ -105,16 +113,25 @@ export class GitDiffWidget extends GitNavigableListWidget<GitFileChangeNode> imp
this.relativePath(fileChangeUri.parent)
]);

const caption = this.computeCaption(fileChange);
const gitScmFileChange = new GitScmFileChange(fileChange, provider, options.range);
const caption = this.computeCaption(gitScmFileChange);
const statusCaption = gitScmFileChange.getStatusCaption();
fileChangeNodes.push({
...fileChange, icon, label, description, caption
...fileChange, icon, label, description, caption, statusCaption
});
}
this.fileChangeNodes = fileChangeNodes;
this.update();
}
}

protected findRepositoryOrSelected(uri?: string): ScmRepository | undefined {
if (uri) {
return this.scmService.findRepository(new URI(uri));
}
return this.scmService.selectedRepository;
}

storeState(): object {
const { fileChangeNodes, options } = this;
return {
Expand All @@ -138,7 +155,7 @@ export class GitDiffWidget extends GitNavigableListWidget<GitFileChangeNode> imp
}

protected render(): React.ReactNode {
this.gitNodes = this.fileChangeNodes;
this.scmNodes = this.fileChangeNodes;
const commitishBar = this.renderDiffListHeader();
const fileChangeList = this.renderFileChangeList();
return <div className='git-diff-container'>{commitishBar}{fileChangeList}</div>;
Expand Down Expand Up @@ -255,7 +272,7 @@ export class GitDiffWidget extends GitNavigableListWidget<GitFileChangeNode> imp
protected doAddGitDiffListKeyListeners(id: string): void {
const container = document.getElementById(id);
if (container) {
this.addGitListNavigationKeyListeners(container);
this.addListNavigationKeyListeners(container);
}
}

Expand Down Expand Up @@ -283,7 +300,7 @@ export class GitDiffWidget extends GitNavigableListWidget<GitFileChangeNode> imp
<div
title={change.caption}
className={'status staged ' + GitFileStatus[change.status].toLowerCase()}>
{this.getStatusCaption(change.status, true).charAt(0)}
{change.statusCaption ? change.statusCaption.charAt(0) : undefined}
</div>
</div>;
}
Expand All @@ -305,8 +322,8 @@ export class GitDiffWidget extends GitNavigableListWidget<GitFileChangeNode> imp
this.revealChange(selected);
}
});
} else if (this.gitNodes.length > 0) {
this.selectNode(this.gitNodes[0]);
} else if (this.scmNodes.length > 0) {
this.selectNode(this.scmNodes[0]);
this.openSelected();
}
}
Expand All @@ -333,19 +350,19 @@ export class GitDiffWidget extends GitNavigableListWidget<GitFileChangeNode> imp

protected selectNextNode(): void {
const idx = this.indexOfSelected;
if (idx >= 0 && idx < this.gitNodes.length - 1) {
this.selectNode(this.gitNodes[idx + 1]);
} else if (this.gitNodes.length > 0 && (idx === -1 || idx === this.gitNodes.length - 1)) {
this.selectNode(this.gitNodes[0]);
if (idx >= 0 && idx < this.scmNodes.length - 1) {
this.selectNode(this.scmNodes[idx + 1]);
} else if (this.scmNodes.length > 0 && (idx === -1 || idx === this.scmNodes.length - 1)) {
this.selectNode(this.scmNodes[0]);
}
}

protected selectPreviousNode(): void {
const idx = this.indexOfSelected;
if (idx > 0) {
this.selectNode(this.gitNodes[idx - 1]);
this.selectNode(this.scmNodes[idx - 1]);
} else if (idx === 0) {
this.selectNode(this.gitNodes[this.gitNodes.length - 1]);
this.selectNode(this.scmNodes[this.scmNodes.length - 1]);
}
}

Expand Down
4 changes: 1 addition & 3 deletions packages/git/src/browser/git-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import URI from '@theia/core/lib/common/uri';
import { Command, CommandContribution, CommandRegistry, DisposableCollection, MenuContribution, MenuModelRegistry, Mutable, MenuAction } from '@theia/core';
import { DiffUris, Widget } from '@theia/core/lib/browser';
import { TabBarToolbarContribution, TabBarToolbarRegistry, TabBarToolbarItem } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
import { EDITOR_CONTEXT_MENU, EditorContextMenu, EditorManager, EditorOpenerOptions, EditorWidget } from '@theia/editor/lib/browser';
import { EditorContextMenu, EditorManager, EditorOpenerOptions, EditorWidget } from '@theia/editor/lib/browser';
import { Git, GitFileChange, GitFileStatus } from '../common';
import { GitRepositoryTracker } from './git-repository-tracker';
import { GitAction, GitQuickOpenService } from './git-quick-open-service';
Expand All @@ -31,8 +31,6 @@ import { ScmResource, ScmCommand } from '@theia/scm/lib/browser/scm-provider';
import { ProgressService } from '@theia/core/lib/common/progress-service';
import { GitPreferences } from './git-preferences';

export const EDITOR_CONTEXT_MENU_GIT = [...EDITOR_CONTEXT_MENU, '3_git'];

export namespace GIT_COMMANDS {
export const CLONE = {
id: 'git.clone',
Expand Down
1 change: 1 addition & 0 deletions packages/git/src/browser/git-file-change-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface GitFileChangeNode extends GitFileChange {
readonly label: string;
readonly description: string;
readonly caption?: string;
readonly statusCaption?: string;
readonly extraIconClassName?: string;
readonly commitSha?: string;
selected?: boolean;
Expand Down
11 changes: 10 additions & 1 deletion packages/git/src/browser/git-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import { GitCommitMessageValidator } from './git-commit-message-validator';
import { GitSyncService } from './git-sync-service';
import { GitErrorHandler } from './git-error-handler';
import { GitScmProvider } from './git-scm-provider';
import { GitHistorySupport } from './history/git-history-support';
import { ScmHistorySupport } from '@theia/scm-extra/lib/browser/history/scm-history-widget';

export default new ContainerModule(bind => {
bindGitPreferences(bind);
Expand All @@ -64,9 +66,16 @@ export default new ContainerModule(bind => {
bind(GitResourceResolver).toSelf().inSingletonScope();
bind(ResourceResolver).toService(GitResourceResolver);

bind(GitScmProvider.Factory).toFactory(GitScmProvider.createFactory);
bind(GitScmProvider.ContainerFactory).toFactory(GitScmProvider.createFactory);
bind(GitRepositoryProvider).toSelf().inSingletonScope();
bind(GitQuickOpenService).toSelf().inSingletonScope();
bind(GitScmProvider.ScmTypeContainer).toDynamicValue(({ container }) => {
const child = container.createChild();
child.bind(GitScmProvider).toSelf().inTransientScope();
child.bind(GitHistorySupport).toSelf().inTransientScope();
child.bind(ScmHistorySupport).toService(GitHistorySupport);
return child;
}).inSingletonScope();

bind(LabelProviderContribution).to(GitUriLabelProviderContribution).inSingletonScope();
bind(NavigatorTreeDecorator).to(GitDecorator).inSingletonScope();
Expand Down
7 changes: 6 additions & 1 deletion packages/git/src/browser/git-repository-provider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,12 @@ describe('GitRepositoryProvider', () => {
testContainer.bind(FileSystemWatcher).toConstantValue(mockFileSystemWatcher);
testContainer.bind(StorageService).toConstantValue(mockStorageService);
testContainer.bind(ScmService).toSelf().inSingletonScope();
testContainer.bind(GitScmProvider.Factory).toFactory(GitScmProvider.createFactory);
testContainer.bind(GitScmProvider.ContainerFactory).toFactory(GitScmProvider.createFactory);
testContainer.bind(GitScmProvider.ScmTypeContainer).toDynamicValue(({ container }) => {
const child = container.createChild();
child.bind(GitScmProvider).toSelf().inTransientScope();
return child;
}).inSingletonScope();
testContainer.bind(ScmContextKeyService).toSelf().inSingletonScope();
testContainer.bind(ContextKeyService).toSelf().inSingletonScope();
testContainer.bind(GitCommitMessageValidator).toSelf().inSingletonScope();
Expand Down
Loading

0 comments on commit c008384

Please sign in to comment.