Skip to content

Commit

Permalink
Add git post commit command provider (#3723)
Browse files Browse the repository at this point in the history
* Post create command work in progress

* Add git post commit command provider
Part of microsoft/vscode#151589
  • Loading branch information
alexr00 committed Jul 13, 2022
1 parent 1d65e38 commit 0685fb3
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/@types/git.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ export interface PublishEvent {
branch?: string;
}

export interface PostCommitCommandsProvider {
getCommands(repository: Repository): Command[];
}

export interface GitAPI {
readonly state: APIState;
readonly onDidChangeState: Event<APIState>;
Expand All @@ -265,6 +269,7 @@ export interface GitAPI {
init(root: Uri): Promise<Repository | null>;
openRepository(root: Uri): Promise<Repository | null>

registerPostCommitCommandsProvider?(provider: PostCommitCommandsProvider): Disposable;
registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable;
registerCredentialsProvider(provider: CredentialsProvider): Disposable;
registerPushErrorHandler(handler: PushErrorHandler): Disposable;
Expand Down
6 changes: 6 additions & 0 deletions src/api/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ export interface LogOptions {
readonly path?: string;
}

export interface PostCommitCommandsProvider {
getCommands(repository: Repository): Command[];
}

export { GitErrorCodes } from './api1';

export interface IGit {
Expand All @@ -241,6 +245,8 @@ export interface IGit {
readonly state?: APIState;
readonly onDidChangeState?: Event<APIState>;
readonly onDidPublish?: Event<PublishEvent>;

registerPostCommitCommandsProvider?(provider: PostCommitCommandsProvider): Disposable;
}

export interface API {
Expand Down
14 changes: 13 additions & 1 deletion src/api/api1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as vscode from 'vscode';
import { APIState, PublishEvent } from '../@types/git';
import Logger from '../common/logger';
import { TernarySearchTree } from '../common/utils';
import { API, IGit, Repository } from './api';
import { API, IGit, PostCommitCommandsProvider, Repository } from './api';

export const enum RefType {
Head,
Expand Down Expand Up @@ -150,6 +150,18 @@ export class GitApiImpl implements API, IGit, vscode.Disposable {
return foldersMap.findSubstr(uri);
}

registerPostCommitCommandsProvider(provider: PostCommitCommandsProvider): vscode.Disposable {
const disposables = Array.from(this._providers.values()).map(gitProvider => {
if (gitProvider.registerPostCommitCommandsProvider) {
return gitProvider.registerPostCommitCommandsProvider(provider);
}
return { dispose: () => { } };
});
return {
dispose: () => disposables.forEach(disposable => disposable.dispose())
};
}

private _nextHandle(): number {
return GitApiImpl._handlePool++;
}
Expand Down
37 changes: 35 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import TelemetryReporter from '@vscode/extension-telemetry';
import * as vscode from 'vscode';
import { LiveShare } from 'vsls/vscode.js';
import { Repository } from './api/api';
import { PostCommitCommandsProvider, Repository } from './api/api';
import { GitApiImpl } from './api/api1';
import { registerCommands } from './commands';
import { commands } from './common/executeCommands';
Expand Down Expand Up @@ -214,7 +214,7 @@ async function init(
const experimentationService = await createExperimentationService(context, telemetry);
await experimentationService.initializePromise;
await experimentationService.isCachedFlightEnabled('githubaa');

registerPostCommitCommandsProvider(reposManager, git);
/* __GDPR__
"startup" : {}
*/
Expand Down Expand Up @@ -265,6 +265,39 @@ async function doRegisterBuiltinGitProvider(context: vscode.ExtensionContext, cr
return false;
}

function registerPostCommitCommandsProvider(reposManager: RepositoriesManager, git: GitApiImpl) {
class Provider implements PostCommitCommandsProvider {
getCommands(repository: Repository) {
const found = reposManager.folderManagers.find(folderManager => folderManager.findRepo(githubRepo => {
return !!repository.state.remotes.find(remote => remote.fetchUrl?.toLowerCase() === githubRepo.remote.url.toLowerCase());
}));
return found ? [{
command: 'pr.create',
title: 'Commit & Create Pull Request'
}] : [];
}
}

function hasGitHubRepos(): boolean {
return reposManager.folderManagers.some(folderManager => folderManager.gitHubRepositories.length > 0);
}
function tryRegister(): boolean {
if (hasGitHubRepos()) {
git.registerPostCommitCommandsProvider(new Provider());
return true;
}
return false;
}

if (!tryRegister()) {
const reposDisposable = reposManager.onDidLoadAnyRepositories(() => {
if (tryRegister()) {
reposDisposable.dispose();
}
});
}
}

async function deferredActivate(context: vscode.ExtensionContext, apiImpl: GitApiImpl, showPRController: ShowPullRequest) {
Logger.debug('Initializing state.', 'Activation');
PersistentState.init(context);
Expand Down
9 changes: 9 additions & 0 deletions src/gitProviders/builtinGit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ export class BuiltinGitProvider implements IGit, vscode.Disposable {
return undefined;
}

registerPostCommitCommandsProvider?(provider: any): vscode.Disposable {
if (this._gitAPI.registerPostCommitCommandsProvider) {
return this._gitAPI.registerPostCommitCommandsProvider(provider);
}
return {
dispose: () => { }
};
}

dispose() {
this._disposables.forEach(disposable => disposable.dispose());
}
Expand Down
8 changes: 7 additions & 1 deletion src/github/repositoriesManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ export class RepositoriesManager implements vscode.Disposable {
private _onDidChangeFolderRepositories = new vscode.EventEmitter<void>();
readonly onDidChangeFolderRepositories = this._onDidChangeFolderRepositories.event;

private _onDidLoadAnyRepositories = new vscode.EventEmitter<void>();
readonly onDidLoadAnyRepositories = this._onDidLoadAnyRepositories.event;

private _state: ReposManagerState = ReposManagerState.Initializing;

constructor(
Expand All @@ -88,7 +91,10 @@ export class RepositoriesManager implements vscode.Disposable {

this._subs.push(
..._folderManagers.map(folderManager => {
return folderManager.onDidLoadRepositories(state => (this.state = state));
return folderManager.onDidLoadRepositories(state => {
this.state = state;
this._onDidLoadAnyRepositories.fire();
});
}),
);
}
Expand Down

0 comments on commit 0685fb3

Please sign in to comment.