Skip to content

Commit

Permalink
The current Workspace can be initialized as a Git Repository now.
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Bicker <jan.bicker@typefox.io>
  • Loading branch information
jbicker committed Aug 21, 2019
1 parent 4c9b0e0 commit c4d924b
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 5 deletions.
22 changes: 20 additions & 2 deletions packages/git/src/browser/git-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ export namespace GIT_COMMANDS {
iconClass: 'fa fa-refresh',
category: 'Git'
};
export const INIT_REPOSITORY = {
id: 'git-init',
label: 'Initialize Repository',
iconClass: 'fa fa-plus',
category: 'Git'
};
}

@injectable()
Expand Down Expand Up @@ -438,6 +444,11 @@ export class GitContribution implements CommandContribution, MenuContribution, T
execute: () => this.quickOpenService.dropStash(),
isEnabled: () => !!this.repositoryTracker.selectedRepository
});
registry.registerCommand(GIT_COMMANDS.INIT_REPOSITORY, {
execute: () => this.quickOpenService.initRepository(),
isEnabled: widget => (!widget || widget instanceof ScmWidget) && !this.repositoryProvider.selectedRepository,
isVisible: widget => (!widget || widget instanceof ScmWidget) && !this.repositoryProvider.selectedRepository
});
}

protected withProgress<T>(task: () => Promise<T>): Promise<T> {
Expand All @@ -455,6 +466,11 @@ export class GitContribution implements CommandContribution, MenuContribution, T
command: GIT_COMMANDS.OPEN_CHANGES.id,
tooltip: GIT_COMMANDS.OPEN_CHANGES.label
});
registry.registerItem({
id: GIT_COMMANDS.INIT_REPOSITORY.id,
command: GIT_COMMANDS.INIT_REPOSITORY.id,
tooltip: GIT_COMMANDS.INIT_REPOSITORY.label
});

const registerItem = (item: Mutable<TabBarToolbarItem>) => {
const commandId = item.command;
Expand All @@ -463,12 +479,14 @@ export class GitContribution implements CommandContribution, MenuContribution, T
this.commands.registerCommand({ id, iconClass: command && command.iconClass }, {
execute: (widget, ...args) => widget instanceof ScmWidget && this.commands.executeCommand(commandId, ...args),
isEnabled: (widget, ...args) => widget instanceof ScmWidget && this.commands.isEnabled(commandId, ...args),
isVisible: (widget, ...args) => widget instanceof ScmWidget && this.commands.isVisible(commandId, ...args),
isVisible: (widget, ...args) =>
widget instanceof ScmWidget &&
this.commands.isVisible(commandId, ...args) &&
!!this.repositoryProvider.selectedRepository
});
item.command = id;
registry.registerItem(item);
};

registerItem({
id: GIT_COMMANDS.COMMIT.id,
command: GIT_COMMANDS.COMMIT.id,
Expand Down
32 changes: 31 additions & 1 deletion packages/git/src/browser/git-quick-open-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ import { Git, Repository, Branch, BranchType, Tag, Remote, StashEntry } from '..
import { GitRepositoryProvider } from './git-repository-provider';
import { MessageService } from '@theia/core/lib/common/message-service';
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { FileSystem } from '@theia/filesystem/lib/common';
import { FileSystem, FileStat } from '@theia/filesystem/lib/common';
import { GitErrorHandler } from './git-error-handler';
import { ProgressService } from '@theia/core/lib/common/progress-service';
import URI from '@theia/core/lib/common/uri';
import { LabelProvider } from '@theia/core/lib/browser';

export enum GitAction {
PULL,
Expand All @@ -40,6 +42,7 @@ export class GitQuickOpenService {

@inject(GitErrorHandler) protected readonly gitErrorHandler: GitErrorHandler;
@inject(ProgressService) protected readonly progressService: ProgressService;
@inject(LabelProvider) protected readonly labelProvider: LabelProvider;

constructor(
@inject(Git) protected readonly git: Git,
Expand Down Expand Up @@ -474,6 +477,33 @@ export class GitQuickOpenService {
});
}

async initRepository(): Promise<void> {
const wsRoots = await this.workspaceService.roots;
if (wsRoots && wsRoots.length > 1) {
const placeholder = 'Choose workspace root to initialize git repo in';
const items = wsRoots.map<GitQuickOpenItem<URI>>(root => this.toRepositoryPathQuickOpenItem(root));
this.open(items, placeholder);
} else {
const rootUri = new URI(wsRoots[0].uri);
this.doInitRepository(rootUri.toString());
}
}

private async doInitRepository(uri: string): Promise<void> {
this.withProgress(async () => this.git.initRepository(uri));
}

private toRepositoryPathQuickOpenItem(root: FileStat): GitQuickOpenItem<URI> {
const rootUri = new URI(root.uri);
const toLabel = (item: GitQuickOpenItem<URI>) => this.labelProvider.getName(item.ref);
const toDescription = (item: GitQuickOpenItem<URI>) => this.labelProvider.getLongName(item.ref.parent);
const execute = async (item: GitQuickOpenItem<URI>) => {
const wsRoot = item.ref.toString();
this.doInitRepository(wsRoot);
};
return new GitQuickOpenItem<URI>(rootUri, execute, toLabel, toDescription);
}

private open(items: QuickOpenItem | QuickOpenItem[], placeholder: string): void {
this.quickOpenService.open(this.getModel(Array.isArray(items) ? items : [items]), this.getOptions(placeholder));
}
Expand Down
6 changes: 6 additions & 0 deletions packages/git/src/common/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,12 @@ export interface Git extends Disposable {
// tslint:disable-next-line:no-any
lsFiles(repository: Repository, uri: string, options?: Git.Options.LsFiles): Promise<any>;

/**
* Initialises a new git repository in the folder with the given uri.
*
* @param uri the uri of the folder
*/
initRepository(uri: string): Promise<string>;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions packages/git/src/node/dugite-git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,12 @@ export class DugiteGit implements Git {
return blame;
}

async initRepository(uri: string): Promise<string> {
await this.ready.promise;
const result = await git(['init'], FileUri.fsPath(uri), 'init');
return result.stdout;
}

// tslint:disable-next-line:no-any
async lsFiles(repository: Repository, uri: string, options?: Git.Options.LsFiles): Promise<any> {
await this.ready.promise;
Expand Down
4 changes: 2 additions & 2 deletions packages/scm/src/browser/scm-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class ScmWidget extends ReactWidget implements StatefulWidget {
this.toDisposeOnRefresh.dispose();
this.toDispose.push(this.toDisposeOnRefresh);
const repository = this.scmService.selectedRepository;
this.title.label = repository ? repository.provider.label : 'no repository opened';
this.title.label = repository ? repository.provider.label : 'no repository initialized';
this.title.caption = this.title.label;
this.update();
if (repository) {
Expand Down Expand Up @@ -145,7 +145,7 @@ export class ScmWidget extends ReactWidget implements StatefulWidget {
if (!repository) {
return <AlertMessage
type='WARNING'
header='Source control is not available at this time'
header='No repository found'
/>;
}
const input = repository.input;
Expand Down

0 comments on commit c4d924b

Please sign in to comment.