Skip to content

Commit

Permalink
Refactored back-end classes to inherit and utilise a custom Disposabl…
Browse files Browse the repository at this point in the history
…e superclass.
  • Loading branch information
mhutchie committed Aug 17, 2020
1 parent 6f6289b commit c3646ee
Show file tree
Hide file tree
Showing 20 changed files with 226 additions and 210 deletions.
3 changes: 2 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
}
},
collectCoverageFrom: [
"src/*.ts"
'src/utils/*.ts',
'src/*.ts'
]
};
30 changes: 19 additions & 11 deletions src/askpass/askpassManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import * as os from 'os';
import * as path from 'path';
import * as vscode from 'vscode';
import { getNonce } from '../utils';
import { Disposable, toDisposable } from '../utils/disposable';

export interface AskpassEnvironment {
GIT_ASKPASS: string;
Expand All @@ -26,12 +27,13 @@ export interface AskpassRequest {
request: string;
}

export class AskpassManager implements vscode.Disposable {
export class AskpassManager extends Disposable {
private ipcHandlePath: string;
private server: http.Server;
private enabled = true;

constructor() {
super();
this.ipcHandlePath = getIPCHandlePath(getNonce());
this.server = http.createServer((req, res) => this.onRequest(req, res));
try {
Expand All @@ -42,6 +44,18 @@ export class AskpassManager implements vscode.Disposable {
}
fs.chmod(path.join(__dirname, 'askpass.sh'), '755', () => { });
fs.chmod(path.join(__dirname, 'askpass-empty.sh'), '755', () => { });

this.registerDisposable(
// Close the Askpass Server
toDisposable(() => {
try {
this.server.close();
if (process.platform !== 'win32') {
fs.unlinkSync(this.ipcHandlePath);
}
} catch (e) { }
})
);
}

private onRequest(req: http.IncomingMessage, res: http.ServerResponse): void {
Expand All @@ -61,24 +75,18 @@ export class AskpassManager implements vscode.Disposable {
}

public getEnv(): AskpassEnvironment {
return this.enabled ?
{
return this.enabled
? {
ELECTRON_RUN_AS_NODE: '1',
GIT_ASKPASS: path.join(__dirname, 'askpass.sh'),
VSCODE_GIT_GRAPH_ASKPASS_NODE: process.execPath,
VSCODE_GIT_GRAPH_ASKPASS_MAIN: path.join(__dirname, 'askpassMain.js'),
VSCODE_GIT_GRAPH_ASKPASS_HANDLE: this.ipcHandlePath
} : {
}
: {
GIT_ASKPASS: path.join(__dirname, 'askpass-empty.sh')
};
}

public dispose(): void {
this.server.close();
if (process.platform !== 'win32') {
fs.unlinkSync(this.ipcHandlePath);
}
}
}

function getIPCHandlePath(nonce: string): string {
Expand Down
17 changes: 9 additions & 8 deletions src/avatarManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import * as fs from 'fs';
import * as http from 'http';
import * as https from 'https';
import * as url from 'url';
import * as vscode from 'vscode';
import { DataSource } from './dataSource';
import { ExtensionState } from './extensionState';
import { GitGraphView } from './gitGraphView';
import { Logger, maskEmail } from './logger';
import { Disposable, toDisposable } from './utils/disposable';

/**
* Manages fetching and caching Avatars.
*/
export class AvatarManager implements vscode.Disposable {
export class AvatarManager extends Disposable {
private readonly dataSource: DataSource;
private readonly extensionState: ExtensionState;
private readonly logger: Logger;
Expand All @@ -34,6 +34,7 @@ export class AvatarManager implements vscode.Disposable {
* @param logger The Git Graph Logger instance.
*/
constructor(dataSource: DataSource, extensionState: ExtensionState, logger: Logger) {
super();
this.dataSource = dataSource;
this.extensionState = extensionState;
this.logger = logger;
Expand All @@ -47,13 +48,13 @@ export class AvatarManager implements vscode.Disposable {
}, 10000);
this.fetchAvatarsInterval();
});
}

/**
* Disposes the resources used by the AvatarManager.
*/
public dispose() {
this.stopInterval();
this.registerDisposable(
// Stop fetching avatars when disposed
toDisposable(() => {
this.stopInterval();
})
);
}

/**
Expand Down
27 changes: 12 additions & 15 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ import * as vscode from 'vscode';
import { AvatarManager } from './avatarManager';
import { getConfig } from './config';
import { DataSource } from './dataSource';
import { Event } from './event';
import { CodeReviewData, CodeReviews, ExtensionState } from './extensionState';
import { GitGraphView } from './gitGraphView';
import { Logger } from './logger';
import { RepoManager } from './repoManager';
import { GitExecutable, UNABLE_TO_FIND_GIT_MSG, abbrevCommit, abbrevText, getPathFromUri, getRelativeTimeDiff, getRepoName, isPathInWorkspace, resolveToSymbolicPath, showErrorMessage, showInformationMessage } from './utils';
import { Disposable } from './utils/disposable';
import { Event } from './utils/event';

/**
* Manages the registration and execution of Git Graph Commands.
*/
export class CommandManager implements vscode.Disposable {
export class CommandManager extends Disposable {
private readonly extensionPath: string;
private readonly avatarManager: AvatarManager;
private readonly dataSource: DataSource;
private readonly extensionState: ExtensionState;
private readonly logger: Logger;
private readonly repoManager: RepoManager;
private gitExecutable: GitExecutable | null;
private disposables: vscode.Disposable[] = [];

/**
* Creates the Git Graph Command Manager.
Expand All @@ -34,6 +34,7 @@ export class CommandManager implements vscode.Disposable {
* @param logger The Git Graph Logger instance.
*/
constructor(extensionPath: string, avatarManger: AvatarManager, dataSource: DataSource, extensionState: ExtensionState, repoManager: RepoManager, gitExecutable: GitExecutable | null, onDidChangeGitExecutable: Event<GitExecutable>, logger: Logger) {
super();
this.extensionPath = extensionPath;
this.avatarManager = avatarManger;
this.dataSource = dataSource;
Expand All @@ -50,17 +51,11 @@ export class CommandManager implements vscode.Disposable {
this.registerCommand('git-graph.endSpecificWorkspaceCodeReview', () => this.endSpecificWorkspaceCodeReview());
this.registerCommand('git-graph.resumeWorkspaceCodeReview', () => this.resumeWorkspaceCodeReview());

onDidChangeGitExecutable((gitExecutable) => {
this.gitExecutable = gitExecutable;
}, this.disposables);
}

/**
* Disposes the resources used by the CommandManager.
*/
public dispose() {
this.disposables.forEach((disposable) => disposable.dispose());
this.disposables = [];
this.registerDisposable(
onDidChangeGitExecutable((gitExecutable) => {
this.gitExecutable = gitExecutable;
})
);
}

/**
Expand All @@ -69,7 +64,9 @@ export class CommandManager implements vscode.Disposable {
* @param callback A command handler function.
*/
private registerCommand(command: string, callback: (...args: any[]) => any) {
this.disposables.push(vscode.commands.registerCommand(command, callback));
this.registerDisposable(
vscode.commands.registerCommand(command, callback)
);
}


Expand Down
44 changes: 19 additions & 25 deletions src/dataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import * as path from 'path';
import * as vscode from 'vscode';
import { AskpassEnvironment, AskpassManager } from './askpass/askpassManager';
import { getConfig } from './config';
import { Event } from './event';
import { Logger } from './logger';
import { CommitOrdering, DateType, DeepWriteable, ErrorInfo, GitCommit, GitCommitDetails, GitCommitStash, GitConfigLocation, GitFileChange, GitFileStatus, GitPushBranchMode, GitRepoSettings, GitResetMode, GitSignatureStatus, GitStash, MergeActionOn, RebaseActionOn, SquashMessageFormat, Writeable } from './types';
import { GitExecutable, UNABLE_TO_FIND_GIT_MSG, UNCOMMITTED, abbrevCommit, constructIncompatibleGitVersionMessage, getPathFromStr, getPathFromUri, isGitAtLeastVersion, openGitTerminal, realpath, resolveSpawnOutput } from './utils';
import { Disposable } from './utils/disposable';
import { Event } from './utils/event';

const EOL_REGEX = /\r\n|\r|\n/g;
const INVALID_BRANCH_REGEX = /^\(.* .*\)$/;
Expand All @@ -20,15 +21,14 @@ export const GIT_CONFIG_USER_EMAIL = 'user.email';
/**
* Interfaces Git Graph with the Git executable to provide all Git integrations.
*/
export class DataSource implements vscode.Disposable {
export class DataSource extends Disposable {
private readonly logger: Logger;
private readonly askpassEnv: AskpassEnvironment;
private gitExecutable!: GitExecutable | null;
private gitExecutableSupportsGpgInfo!: boolean;
private gitFormatCommitDetails!: string;
private gitFormatLog!: string;
private gitFormatStash!: string;
private disposables: vscode.Disposable[] = [];

/**
* Creates the Git Graph Data Source.
Expand All @@ -37,26 +37,28 @@ export class DataSource implements vscode.Disposable {
* @param logger The Git Graph Logger instance.
*/
constructor(gitExecutable: GitExecutable | null, onDidChangeConfiguration: Event<vscode.ConfigurationChangeEvent>, onDidChangeGitExecutable: Event<GitExecutable>, logger: Logger) {
super();
this.logger = logger;
this.setGitExecutable(gitExecutable);

const askpassManager = new AskpassManager();
this.askpassEnv = askpassManager.getEnv();
this.disposables.push(askpassManager);

onDidChangeConfiguration((event) => {
if (
event.affectsConfiguration('git-graph.date.type') || event.affectsConfiguration('git-graph.dateType') ||
event.affectsConfiguration('git-graph.repository.commits.showSignatureStatus') || event.affectsConfiguration('git-graph.showSignatureStatus') ||
event.affectsConfiguration('git-graph.repository.useMailmap') || event.affectsConfiguration('git-graph.useMailmap')
) {
this.generateGitCommandFormats();
}
}, this.disposables);

onDidChangeGitExecutable((gitExecutable) => {
this.setGitExecutable(gitExecutable);
}, this.disposables);
this.registerDisposables(
onDidChangeConfiguration((event) => {
if (
event.affectsConfiguration('git-graph.date.type') || event.affectsConfiguration('git-graph.dateType') ||
event.affectsConfiguration('git-graph.repository.commits.showSignatureStatus') || event.affectsConfiguration('git-graph.showSignatureStatus') ||
event.affectsConfiguration('git-graph.repository.useMailmap') || event.affectsConfiguration('git-graph.useMailmap')
) {
this.generateGitCommandFormats();
}
}),
onDidChangeGitExecutable((gitExecutable) => {
this.setGitExecutable(gitExecutable);
}),
askpassManager
);
}

/**
Expand Down Expand Up @@ -105,14 +107,6 @@ export class DataSource implements vscode.Disposable {
].join(GIT_LOG_SEPARATOR);
}

/**
* Disposes the resources used by the DataSource.
*/
public dispose() {
this.disposables.forEach((disposable) => disposable.dispose());
this.disposables = [];
}


/* Get Data Methods - Core */

Expand Down
22 changes: 9 additions & 13 deletions src/diffDocProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as vscode from 'vscode';
import { DataSource } from './dataSource';
import { GitFileStatus } from './types';
import { UNCOMMITTED, getPathFromStr, showErrorMessage } from './utils';
import { Disposable, toDisposable } from './utils/disposable';

export const enum DiffSide {
Old,
Expand All @@ -12,30 +13,25 @@ export const enum DiffSide {
/**
* Manages providing a specific revision of a repository file for use in the Visual Studio Code Diff View.
*/
export class DiffDocProvider implements vscode.TextDocumentContentProvider, vscode.Disposable {
export class DiffDocProvider extends Disposable implements vscode.TextDocumentContentProvider {
public static scheme = 'git-graph';
private readonly dataSource: DataSource;
private readonly docs = new Map<string, DiffDocument>();
private readonly closeDocSubscription: vscode.Disposable;

private onDidChangeEventEmitter = new vscode.EventEmitter<vscode.Uri>();
private readonly onDidChangeEventEmitter = new vscode.EventEmitter<vscode.Uri>();

/**
* Creates the Git Graph Diff Document Provider.
* @param dataSource The Git Graph DataSource instance.
*/
constructor(dataSource: DataSource) {
super();
this.dataSource = dataSource;
this.closeDocSubscription = vscode.workspace.onDidCloseTextDocument((doc) => this.docs.delete(doc.uri.toString()));
}

/**
* Disposes the resources used by the DiffDocProvider.
*/
public dispose() {
this.closeDocSubscription.dispose();
this.docs.clear();
this.onDidChangeEventEmitter.dispose();
this.registerDisposables(
vscode.workspace.onDidCloseTextDocument((doc) => this.docs.delete(doc.uri.toString())),
this.onDidChangeEventEmitter,
toDisposable(() => this.docs.clear())
);
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { CommandManager } from './commands';
import { getConfig } from './config';
import { DataSource } from './dataSource';
import { DiffDocProvider } from './diffDocProvider';
import { EventEmitter } from './event';
import { ExtensionState } from './extensionState';
import { onStartUp } from './life-cycle/startup';
import { Logger } from './logger';
import { RepoManager } from './repoManager';
import { StatusBarItem } from './statusBarItem';
import { GitExecutable, UNABLE_TO_FIND_GIT_MSG, findGit, getGitExecutable, showErrorMessage, showInformationMessage } from './utils';
import { EventEmitter } from './utils/event';

/**
* Activate Git Graph.
Expand Down Expand Up @@ -44,9 +44,10 @@ export async function activate(context: vscode.ExtensionContext) {
const repoManager = new RepoManager(dataSource, extensionState, onDidChangeConfiguration, logger);
const statusBarItem = new StatusBarItem(repoManager.getNumRepos(), repoManager.onDidChangeRepos, onDidChangeConfiguration, logger);
const commandManager = new CommandManager(context.extensionPath, avatarManager, dataSource, extensionState, repoManager, gitExecutable, onDidChangeGitExecutable, logger);
const diffDocProvider = new DiffDocProvider(dataSource);

context.subscriptions.push(
vscode.workspace.registerTextDocumentContentProvider(DiffDocProvider.scheme, new DiffDocProvider(dataSource)),
vscode.workspace.registerTextDocumentContentProvider(DiffDocProvider.scheme, diffDocProvider),
vscode.workspace.onDidChangeConfiguration((event) => {
if (event.affectsConfiguration('git-graph')) {
configurationEmitter.emit(event);
Expand All @@ -67,6 +68,7 @@ export async function activate(context: vscode.ExtensionContext) {
});
}
}),
diffDocProvider,
commandManager,
statusBarItem,
repoManager,
Expand Down
Loading

0 comments on commit c3646ee

Please sign in to comment.