Merge remote-tracking branch 'origin/ads-master-vscode-2020-03-26T07-08-21'

This commit is contained in:
Anthony Dresser
2020-03-26 13:52:35 -07:00
87 changed files with 942 additions and 631 deletions

View File

@@ -1808,7 +1808,6 @@
},
"dependencies": {
"byline": "^5.0.0",
"dayjs": "1.8.19",
"file-type": "^7.2.0",
"iconv-lite": "^0.4.24",
"jschardet": "2.1.1",
@@ -1821,7 +1820,7 @@
"@types/byline": "4.2.31",
"@types/file-type": "^5.2.1",
"@types/mocha": "2.2.43",
"@types/node": "^12.11.7",
"@types/node": "^12.12.31",
"@types/which": "^1.0.28",
"mocha": "^3.2.0",
"mocha-junit-reporter": "^1.23.3",

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { promises as fs, exists } from 'fs';
import { promises as fs, exists, realpath } from 'fs';
import * as path from 'path';
import * as os from 'os';
import * as cp from 'child_process';
@@ -21,6 +21,7 @@ import { StringDecoder } from 'string_decoder';
// https://github.com/microsoft/vscode/issues/65693
const MAX_CLI_LENGTH = 30000;
const isWindows = process.platform === 'win32';
export interface IGit {
path: string;
@@ -419,8 +420,40 @@ export class Git {
async getRepositoryRoot(repositoryPath: string): Promise<string> {
const result = await this.exec(repositoryPath, ['rev-parse', '--show-toplevel']);
// Keep trailing spaces which are part of the directory name
return path.normalize(result.stdout.trimLeft().replace(/(\r\n|\r|\n)+$/, ''));
const repoPath = path.normalize(result.stdout.trimLeft().replace(/(\r\n|\r|\n)+$/, ''));
if (isWindows) {
// On Git 2.25+ if you call `rev-parse --show-toplevel` on a mapped drive, instead of getting the mapped drive path back, you get the UNC path for the mapped drive.
// So we will try to normalize it back to the mapped drive path, if possible
const repoUri = Uri.file(repoPath);
const pathUri = Uri.file(repositoryPath);
if (repoUri.authority.length !== 0 && pathUri.authority.length === 0) {
let match = /(?<=^\/?)([a-zA-Z])(?=:\/)/.exec(pathUri.path);
if (match !== null) {
const [, letter] = match;
try {
const networkPath = await new Promise<string>(resolve =>
realpath.native(`${letter}:`, { encoding: 'utf8' }, (err, resolvedPath) =>
// eslint-disable-next-line eqeqeq
resolve(err != null ? undefined : resolvedPath),
),
);
if (networkPath !== undefined) {
return path.normalize(
repoUri.fsPath.replace(networkPath, `${letter.toLowerCase()}:`),
);
}
} catch { }
}
return path.normalize(pathUri.fsPath);
}
}
return repoPath;
}
async getRepositoryDotGit(repositoryPath: string): Promise<string> {

View File

@@ -4,19 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vscode-nls';
import * as dayjs from 'dayjs';
import * as advancedFormat from 'dayjs/plugin/advancedFormat';
import { CancellationToken, Disposable, Event, EventEmitter, ThemeIcon, Timeline, TimelineChangeEvent, TimelineItem, TimelineOptions, TimelineProvider, Uri, workspace } from 'vscode';
import { CancellationToken, Disposable, env, Event, EventEmitter, ThemeIcon, Timeline, TimelineChangeEvent, TimelineItem, TimelineOptions, TimelineProvider, Uri, workspace } from 'vscode';
import { Model } from './model';
import { Repository, Resource } from './repository';
import { debounce } from './decorators';
dayjs.extend(advancedFormat);
const localize = nls.loadMessageBundle();
// TODO@eamodio: Localize or use a setting for date format
export class GitTimelineItem extends TimelineItem {
static is(item: TimelineItem): item is GitTimelineItem {
return item instanceof GitTimelineItem;
@@ -145,16 +139,15 @@ export class GitTimelineProvider implements TimelineProvider {
commits.splice(commits.length - 1, 1);
}
let dateFormatter: dayjs.Dayjs;
const dateFormatter = new Intl.DateTimeFormat(env.language, { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric' });
const items = commits.map<GitTimelineItem>((c, i) => {
const date = c.commitDate; // c.authorDate
dateFormatter = dayjs(date);
const item = new GitTimelineItem(c.hash, commits[i + 1]?.hash ?? `${c.hash}^`, c.message, date?.getTime() ?? 0, c.hash, 'git:file:commit');
item.iconPath = new (ThemeIcon as any)('git-commit');
item.description = c.authorName;
item.detail = `${c.authorName} (${c.authorEmail}) \u2014 ${c.hash.substr(0, 8)}\n${dateFormatter.format('MMMM Do, YYYY h:mma')}\n\n${c.message}`;
item.detail = `${c.authorName} (${c.authorEmail}) \u2014 ${c.hash.substr(0, 8)}\n${dateFormatter.format(date)}\n\n${c.message}`;
item.command = {
title: 'Open Comparison',
command: 'git.timeline.openDiff',
@@ -170,13 +163,12 @@ export class GitTimelineProvider implements TimelineProvider {
const index = repo.indexGroup.resourceStates.find(r => r.resourceUri.fsPath === uri.fsPath);
if (index) {
const date = this.repoStatusDate ?? new Date();
dateFormatter = dayjs(date);
const item = new GitTimelineItem('~', 'HEAD', localize('git.timeline.stagedChanges', 'Staged Changes'), date.getTime(), 'index', 'git:file:index');
// TODO@eamodio: Replace with a better icon -- reflecting its status maybe?
item.iconPath = new (ThemeIcon as any)('git-commit');
item.description = '';
item.detail = localize('git.timeline.detail', '{0} \u2014 {1}\n{2}\n\n{3}', you, localize('git.index', 'Index'), dateFormatter.format('MMMM Do, YYYY h:mma'), Resource.getStatusText(index.type));
item.detail = localize('git.timeline.detail', '{0} \u2014 {1}\n{2}\n\n{3}', you, localize('git.index', 'Index'), dateFormatter.format(date), Resource.getStatusText(index.type));
item.command = {
title: 'Open Comparison',
command: 'git.timeline.openDiff',
@@ -189,13 +181,12 @@ export class GitTimelineProvider implements TimelineProvider {
const working = repo.workingTreeGroup.resourceStates.find(r => r.resourceUri.fsPath === uri.fsPath);
if (working) {
const date = new Date();
dateFormatter = dayjs(date);
const item = new GitTimelineItem('', index ? '~' : 'HEAD', localize('git.timeline.uncommitedChanges', 'Uncommited Changes'), date.getTime(), 'working', 'git:file:working');
// TODO@eamodio: Replace with a better icon -- reflecting its status maybe?
item.iconPath = new (ThemeIcon as any)('git-commit');
item.description = '';
item.detail = localize('git.timeline.detail', '{0} \u2014 {1}\n{2}\n\n{3}', you, localize('git.workingTree', 'Working Tree'), dateFormatter.format('MMMM Do, YYYY h:mma'), Resource.getStatusText(working.type));
item.detail = localize('git.timeline.detail', '{0} \u2014 {1}\n{2}\n\n{3}', you, localize('git.workingTree', 'Working Tree'), dateFormatter.format(date), Resource.getStatusText(working.type));
item.command = {
title: 'Open Comparison',
command: 'git.timeline.openDiff',

View File

@@ -26,10 +26,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb"
integrity sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==
"@types/node@^12.11.7":
version "12.11.7"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.7.tgz#57682a9771a3f7b09c2497f28129a0462966524a"
integrity sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==
"@types/node@^12.12.31":
version "12.12.31"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.31.tgz#d6b4f9645fee17f11319b508fb1001797425da51"
integrity sha512-T+wnJno8uh27G9c+1T+a1/WYCHzLeDqtsGJkoEdSp2X8RTh3oOCZQcUnjAx90CS8cmmADX51O0FI/tu9s0yssg==
"@types/which@^1.0.28":
version "1.0.28"
@@ -185,11 +185,6 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
dayjs@1.8.19:
version "1.8.19"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.19.tgz#5117dc390d8f8e586d53891dbff3fa308f51abfe"
integrity sha512-7kqOoj3oQSmqbvtvGFLU5iYqies+SqUiEGNT0UtUPPxcPYgY1BrkXR0Cq2R9HYSimBXN+xHkEN4Hi399W+Ovlg==
debug@2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"

View File

@@ -22,7 +22,8 @@
"postinstall": "node build/postinstall.js"
},
"dependencies": {
"uuid": "^3.3.3"
"uuid": "^3.3.3",
"vscode-nls": "^4.1.2"
},
"devDependencies": {
"@types/keytar": "^4.4.2",

View File

@@ -6,8 +6,11 @@
// keytar depends on a native module shipped in vscode, so this is
// how we load it
import * as keytarType from 'keytar';
import { env } from 'vscode';
import * as vscode from 'vscode';
import Logger from './logger';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
function getKeytar(): Keytar | undefined {
try {
@@ -25,7 +28,7 @@ export type Keytar = {
deletePassword: typeof keytarType['deletePassword'];
};
const SERVICE_ID = `${env.uriScheme}-github.login`;
const SERVICE_ID = `${vscode.env.uriScheme}-github.login`;
const ACCOUNT_ID = 'account';
export class Keychain {
@@ -46,6 +49,11 @@ export class Keychain {
} catch (e) {
// Ignore
Logger.error(`Setting token failed: ${e}`);
const troubleshooting = localize('troubleshooting', "Troubleshooting Guide");
const result = await vscode.window.showErrorMessage(localize('keychainWriteError', "Writing login information to the keychain failed with error '{0}'.", e.message), troubleshooting);
if (result === troubleshooting) {
vscode.env.openExternal(vscode.Uri.parse('https://code.visualstudio.com/docs/editor/settings-sync#_troubleshooting-keychain-issues'));
}
}
}

View File

@@ -436,6 +436,11 @@ uuid@^3.3.3:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
vscode-nls@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.2.tgz#ca8bf8bb82a0987b32801f9fddfdd2fb9fd3c167"
integrity sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==
which-pm-runs@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb"

View File

@@ -205,7 +205,7 @@ export class AzureActiveDirectoryService {
Logger.info('Token expired or unavailable, trying refresh');
const refreshedToken = await this.refreshToken(token.refreshToken, token.scope);
if (refreshedToken.accessToken) {
Promise.resolve(token.accessToken);
return refreshedToken.accessToken;
} else {
throw new Error();
}

View File

@@ -6,8 +6,11 @@
// keytar depends on a native module shipped in vscode, so this is
// how we load it
import * as keytarType from 'keytar';
import { env } from 'vscode';
import * as vscode from 'vscode';
import Logger from './logger';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
function getKeytar(): Keytar | undefined {
try {
@@ -25,7 +28,7 @@ export type Keytar = {
deletePassword: typeof keytarType['deletePassword'];
};
const SERVICE_ID = `${env.uriScheme}-vscode.login`;
const SERVICE_ID = `${vscode.env.uriScheme}-vscode.login`;
const ACCOUNT_ID = 'account';
export class Keychain {
@@ -46,6 +49,11 @@ export class Keychain {
} catch (e) {
// Ignore
Logger.error(`Setting token failed: ${e}`);
const troubleshooting = localize('troubleshooting', "Troubleshooting Guide");
const result = await vscode.window.showErrorMessage(localize('keychainWriteError', "Writing login information to the keychain failed with error '{0}'.", e.message), troubleshooting);
if (result === troubleshooting) {
vscode.env.openExternal(vscode.Uri.parse('https://code.visualstudio.com/docs/editor/settings-sync#_troubleshooting-keychain-issues'));
}
}
}