Skip to content

Commit 77cdae7

Browse files
committed
Refactored all Git & Visual Studio Code version requirements, and Git config keys, to use enums.
1 parent b9112e6 commit 77cdae7

File tree

6 files changed

+131
-92
lines changed

6 files changed

+131
-92
lines changed

src/commands.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { CodeReviewData, CodeReviews, ExtensionState } from './extensionState';
88
import { GitGraphView } from './gitGraphView';
99
import { Logger } from './logger';
1010
import { RepoManager } from './repoManager';
11-
import { GitExecutable, UNABLE_TO_FIND_GIT_MSG, abbrevCommit, abbrevText, copyToClipboard, doesVersionMeetRequirement, getExtensionVersion, getPathFromUri, getRelativeTimeDiff, getRepoName, getSortedRepositoryPaths, isPathInWorkspace, openFile, resolveToSymbolicPath, showErrorMessage, showInformationMessage } from './utils';
11+
import { GitExecutable, UNABLE_TO_FIND_GIT_MSG, VsCodeVersionRequirement, abbrevCommit, abbrevText, copyToClipboard, doesVersionMeetRequirement, getExtensionVersion, getPathFromUri, getRelativeTimeDiff, getRepoName, getSortedRepositoryPaths, isPathInWorkspace, openFile, resolveToSymbolicPath, showErrorMessage, showInformationMessage } from './utils';
1212
import { Disposable } from './utils/disposable';
1313
import { Event } from './utils/event';
1414

@@ -65,7 +65,7 @@ export class CommandManager extends Disposable {
6565

6666
// Register Extension Contexts
6767
try {
68-
this.registerContext('git-graph:codiconsSupported', doesVersionMeetRequirement(vscode.version, '1.42.0'));
68+
this.registerContext('git-graph:codiconsSupported', doesVersionMeetRequirement(vscode.version, VsCodeVersionRequirement.Codicons));
6969
} catch (_) {
7070
this.logger.logError('Unable to set Visual Studio Code Context "git-graph:codiconsSupported"');
7171
}

src/dataSource.ts

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { AskpassEnvironment, AskpassManager } from './askpass/askpassManager';
77
import { getConfig } from './config';
88
import { Logger } from './logger';
99
import { CommitOrdering, DateType, DeepWriteable, ErrorInfo, GitCommit, GitCommitDetails, GitCommitStash, GitConfigLocation, GitFileChange, GitFileStatus, GitPushBranchMode, GitRepoConfig, GitRepoConfigBranches, GitResetMode, GitSignature, GitSignatureStatus, GitStash, GitTagDetails, MergeActionOn, RebaseActionOn, SquashMessageFormat, TagType, Writeable } from './types';
10-
import { GitExecutable, UNABLE_TO_FIND_GIT_MSG, UNCOMMITTED, abbrevCommit, constructIncompatibleGitVersionMessage, doesVersionMeetRequirement, getPathFromStr, getPathFromUri, openGitTerminal, pathWithTrailingSlash, realpath, resolveSpawnOutput, showErrorMessage } from './utils';
10+
import { GitExecutable, GitVersionRequirement, UNABLE_TO_FIND_GIT_MSG, UNCOMMITTED, abbrevCommit, constructIncompatibleGitVersionMessage, doesVersionMeetRequirement, getPathFromStr, getPathFromUri, openGitTerminal, pathWithTrailingSlash, realpath, resolveSpawnOutput, showErrorMessage } from './utils';
1111
import { Disposable } from './utils/disposable';
1212
import { Event } from './utils/event';
1313

@@ -17,21 +17,15 @@ const INVALID_BRANCH_REGEXP = /^\(.* .*\)$/;
1717
const REMOTE_HEAD_BRANCH_REGEXP = /^remotes\/.*\/HEAD$/;
1818
const GIT_LOG_SEPARATOR = 'XX7Nal-YARtTpjCikii9nJxER19D6diSyk-AWkPb';
1919

20-
export const GIT_CONFIG = {
21-
DIFF: {
22-
GUI_TOOL: 'diff.guitool',
23-
TOOL: 'diff.tool'
24-
},
25-
REMOTE: {
26-
PUSH_DEFAULT: 'remote.pushdefault'
27-
},
28-
USER: {
29-
EMAIL: 'user.email',
30-
NAME: 'user.name'
31-
}
32-
};
20+
export const enum GitConfigKey {
21+
DiffGuiTool = 'diff.guitool',
22+
DiffTool = 'diff.tool',
23+
RemotePushDefault = 'remote.pushdefault',
24+
UserEmail = 'user.email',
25+
UserName = 'user.name'
26+
}
3327

34-
const GPG_STATUS_CODE_PARSING_DETAILS: { [statusCode: string]: GpgStatusCodeParsingDetails } = {
28+
const GPG_STATUS_CODE_PARSING_DETAILS: Readonly<{ [statusCode: string]: GpgStatusCodeParsingDetails }> = {
3529
'GOODSIG': { status: GitSignatureStatus.GoodAndValid, uid: true },
3630
'BADSIG': { status: GitSignatureStatus.Bad, uid: true },
3731
'ERRSIG': { status: GitSignatureStatus.CannotBeChecked, uid: false },
@@ -95,9 +89,9 @@ export class DataSource extends Disposable {
9589
* Set the Git executable used by the DataSource.
9690
* @param gitExecutable The Git executable.
9791
*/
98-
public setGitExecutable(gitExecutable: GitExecutable | null) {
92+
private setGitExecutable(gitExecutable: GitExecutable | null) {
9993
this.gitExecutable = gitExecutable;
100-
this.gitExecutableSupportsGpgInfo = gitExecutable !== null ? doesVersionMeetRequirement(gitExecutable.version, '2.4.0') : false;
94+
this.gitExecutableSupportsGpgInfo = gitExecutable !== null && doesVersionMeetRequirement(gitExecutable.version, GitVersionRequirement.GpgInfo);
10195
this.generateGitCommandFormats();
10296
}
10397

@@ -314,22 +308,22 @@ export class DataSource extends Disposable {
314308
return {
315309
config: {
316310
branches: branches,
317-
diffTool: getConfigValue(consolidatedConfigs, GIT_CONFIG.DIFF.TOOL),
318-
guiDiffTool: getConfigValue(consolidatedConfigs, GIT_CONFIG.DIFF.GUI_TOOL),
319-
pushDefault: getConfigValue(consolidatedConfigs, GIT_CONFIG.REMOTE.PUSH_DEFAULT),
311+
diffTool: getConfigValue(consolidatedConfigs, GitConfigKey.DiffTool),
312+
guiDiffTool: getConfigValue(consolidatedConfigs, GitConfigKey.DiffGuiTool),
313+
pushDefault: getConfigValue(consolidatedConfigs, GitConfigKey.RemotePushDefault),
320314
remotes: remotes.map((remote) => ({
321315
name: remote,
322316
url: getConfigValue(localConfigs, 'remote.' + remote + '.url'),
323317
pushUrl: getConfigValue(localConfigs, 'remote.' + remote + '.pushurl')
324318
})),
325319
user: {
326320
name: {
327-
local: getConfigValue(localConfigs, GIT_CONFIG.USER.NAME),
328-
global: getConfigValue(globalConfigs, GIT_CONFIG.USER.NAME)
321+
local: getConfigValue(localConfigs, GitConfigKey.UserName),
322+
global: getConfigValue(globalConfigs, GitConfigKey.UserName)
329323
},
330324
email: {
331-
local: getConfigValue(localConfigs, GIT_CONFIG.USER.EMAIL),
332-
global: getConfigValue(globalConfigs, GIT_CONFIG.USER.EMAIL)
325+
local: getConfigValue(localConfigs, GitConfigKey.UserEmail),
326+
global: getConfigValue(globalConfigs, GitConfigKey.UserEmail)
333327
}
334328
}
335329
},
@@ -503,8 +497,8 @@ export class DataSource extends Disposable {
503497
* @returns The tag details.
504498
*/
505499
public getTagDetails(repo: string, tagName: string): Promise<GitTagDetailsData> {
506-
if (this.gitExecutable !== null && !doesVersionMeetRequirement(this.gitExecutable.version, '1.7.8')) {
507-
return Promise.resolve({ details: null, error: constructIncompatibleGitVersionMessage(this.gitExecutable, '1.7.8', 'retrieving Tag Details') });
500+
if (this.gitExecutable !== null && !doesVersionMeetRequirement(this.gitExecutable.version, GitVersionRequirement.TagDetails)) {
501+
return Promise.resolve({ details: null, error: constructIncompatibleGitVersionMessage(this.gitExecutable, GitVersionRequirement.TagDetails, 'retrieving Tag Details') });
508502
}
509503

510504
const ref = 'refs/tags/' + tagName;
@@ -758,8 +752,8 @@ export class DataSource extends Disposable {
758752
if (pruneTags) {
759753
if (!prune) {
760754
return Promise.resolve('In order to Prune Tags, pruning must also be enabled when fetching from ' + (remote !== null ? 'a remote' : 'remote(s)') + '.');
761-
} else if (this.gitExecutable !== null && !doesVersionMeetRequirement(this.gitExecutable.version, '2.17.0')) {
762-
return Promise.resolve(constructIncompatibleGitVersionMessage(this.gitExecutable, '2.17.0', 'pruning tags when fetching'));
755+
} else if (this.gitExecutable !== null && !doesVersionMeetRequirement(this.gitExecutable.version, GitVersionRequirement.FetchAndPruneTags)) {
756+
return Promise.resolve(constructIncompatibleGitVersionMessage(this.gitExecutable, GitVersionRequirement.FetchAndPruneTags, 'pruning tags when fetching'));
763757
}
764758
args.push('--prune-tags');
765759
}
@@ -1139,23 +1133,23 @@ export class DataSource extends Disposable {
11391133
/**
11401134
* Set a configuration value for a repository.
11411135
* @param repo The path of the repository.
1142-
* @param key The key to be set.
1136+
* @param key The Git Config Key to be set.
11431137
* @param value The value to be set.
11441138
* @param location The location where the configuration value should be set.
11451139
* @returns The ErrorInfo from the executed command.
11461140
*/
1147-
public setConfigValue(repo: string, key: string, value: string, location: GitConfigLocation) {
1141+
public setConfigValue(repo: string, key: GitConfigKey, value: string, location: GitConfigLocation) {
11481142
return this.runGitCommand(['config', '--' + location, key, value], repo);
11491143
}
11501144

11511145
/**
11521146
* Unset a configuration value for a repository.
11531147
* @param repo The path of the repository.
1154-
* @param key The key to be unset.
1148+
* @param key The Git Config Key to be unset.
11551149
* @param location The location where the configuration value should be unset.
11561150
* @returns The ErrorInfo from the executed command.
11571151
*/
1158-
public unsetConfigValue(repo: string, key: string, location: GitConfigLocation) {
1152+
public unsetConfigValue(repo: string, key: GitConfigKey, location: GitConfigLocation) {
11591153
return this.runGitCommand(['config', '--' + location, '--unset-all', key], repo);
11601154
}
11611155

@@ -1236,8 +1230,8 @@ export class DataSource extends Disposable {
12361230
public pushStash(repo: string, message: string, includeUntracked: boolean): Promise<ErrorInfo> {
12371231
if (this.gitExecutable === null) {
12381232
return Promise.resolve(UNABLE_TO_FIND_GIT_MSG);
1239-
} else if (!doesVersionMeetRequirement(this.gitExecutable.version, '2.13.2')) {
1240-
return Promise.resolve(constructIncompatibleGitVersionMessage(this.gitExecutable, '2.13.2'));
1233+
} else if (!doesVersionMeetRequirement(this.gitExecutable.version, GitVersionRequirement.PushStash)) {
1234+
return Promise.resolve(constructIncompatibleGitVersionMessage(this.gitExecutable, GitVersionRequirement.PushStash));
12411235
}
12421236

12431237
let args = ['stash', 'push'];
@@ -1994,6 +1988,6 @@ interface GitTagDetailsData {
19941988
}
19951989

19961990
interface GpgStatusCodeParsingDetails {
1997-
status: GitSignatureStatus,
1998-
uid: boolean
1991+
readonly status: GitSignatureStatus,
1992+
readonly uid: boolean
19991993
}

src/gitGraphView.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as path from 'path';
22
import * as vscode from 'vscode';
33
import { AvatarManager } from './avatarManager';
44
import { getConfig } from './config';
5-
import { DataSource, GIT_CONFIG, GitCommitDetailsData } from './dataSource';
5+
import { DataSource, GitCommitDetailsData, GitConfigKey } from './dataSource';
66
import { ExtensionState } from './extensionState';
77
import { Logger } from './logger';
88
import { RepoFileWatcher } from './repoFileWatcher';
@@ -325,10 +325,10 @@ export class GitGraphView extends Disposable {
325325
case 'deleteUserDetails':
326326
errorInfos = [];
327327
if (msg.name) {
328-
errorInfos.push(await this.dataSource.unsetConfigValue(msg.repo, GIT_CONFIG.USER.NAME, msg.location));
328+
errorInfos.push(await this.dataSource.unsetConfigValue(msg.repo, GitConfigKey.UserName, msg.location));
329329
}
330330
if (msg.email) {
331-
errorInfos.push(await this.dataSource.unsetConfigValue(msg.repo, GIT_CONFIG.USER.EMAIL, msg.location));
331+
errorInfos.push(await this.dataSource.unsetConfigValue(msg.repo, GitConfigKey.UserEmail, msg.location));
332332
}
333333
this.sendMessage({
334334
command: 'deleteUserDetails',
@@ -355,15 +355,15 @@ export class GitGraphView extends Disposable {
355355
break;
356356
case 'editUserDetails':
357357
errorInfos = [
358-
await this.dataSource.setConfigValue(msg.repo, GIT_CONFIG.USER.NAME, msg.name, msg.location),
359-
await this.dataSource.setConfigValue(msg.repo, GIT_CONFIG.USER.EMAIL, msg.email, msg.location)
358+
await this.dataSource.setConfigValue(msg.repo, GitConfigKey.UserName, msg.name, msg.location),
359+
await this.dataSource.setConfigValue(msg.repo, GitConfigKey.UserEmail, msg.email, msg.location)
360360
];
361361
if (errorInfos[0] === null && errorInfos[1] === null) {
362362
if (msg.deleteLocalName) {
363-
errorInfos.push(await this.dataSource.unsetConfigValue(msg.repo, GIT_CONFIG.USER.NAME, GitConfigLocation.Local));
363+
errorInfos.push(await this.dataSource.unsetConfigValue(msg.repo, GitConfigKey.UserName, GitConfigLocation.Local));
364364
}
365365
if (msg.deleteLocalEmail) {
366-
errorInfos.push(await this.dataSource.unsetConfigValue(msg.repo, GIT_CONFIG.USER.EMAIL, GitConfigLocation.Local));
366+
errorInfos.push(await this.dataSource.unsetConfigValue(msg.repo, GitConfigKey.UserEmail, GitConfigLocation.Local));
367367
}
368368
}
369369
this.sendMessage({

src/utils.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -772,15 +772,26 @@ export async function getGitExecutableFromPaths(paths: string[]): Promise<GitExe
772772
}
773773

774774

775-
/* Version Handling */
775+
/* Version Handling / Requirements */
776+
777+
export const enum GitVersionRequirement {
778+
FetchAndPruneTags = '2.17.0',
779+
GpgInfo = '2.4.0',
780+
PushStash = '2.13.2',
781+
TagDetails = '1.7.8'
782+
}
783+
784+
export const enum VsCodeVersionRequirement {
785+
Codicons = '1.42.0'
786+
}
776787

777788
/**
778789
* Checks whether a version is at least a required version.
779790
* @param version The version to check.
780791
* @param requiredVersion The minimum required version.
781792
* @returns TRUE => `version` is at least `requiredVersion`, FALSE => `version` is older than `requiredVersion`.
782793
*/
783-
export function doesVersionMeetRequirement(version: string, requiredVersion: string) {
794+
export function doesVersionMeetRequirement(version: string, requiredVersion: GitVersionRequirement | VsCodeVersionRequirement) {
784795
const v1 = parseVersion(version);
785796
const v2 = parseVersion(requiredVersion);
786797

@@ -824,10 +835,10 @@ function parseVersion(version: string) {
824835
/**
825836
* Construct a message that explains to the user that the Git executable is not compatible with a feature.
826837
* @param executable The Git executable.
827-
* @param version The minimum required version number.
838+
* @param version The minimum required version.
828839
* @param feature An optional name for the feature.
829840
* @returns The message for the user.
830841
*/
831-
export function constructIncompatibleGitVersionMessage(executable: GitExecutable, version: string, feature?: string) {
842+
export function constructIncompatibleGitVersionMessage(executable: GitExecutable, version: GitVersionRequirement, feature?: string) {
832843
return 'A newer version of Git (>= ' + version + ') is required for ' + (feature ? feature : 'this feature') + '. Git ' + executable.version + ' is currently installed. Please install a newer version of Git to use this feature.';
833844
}

0 commit comments

Comments
 (0)