Merge VS Code 1.31.1 (#4283)

This commit is contained in:
Matt Irvine
2019-03-15 13:09:45 -07:00
committed by GitHub
parent 7d31575149
commit 86bac90001
1716 changed files with 53308 additions and 48375 deletions

View File

@@ -3,9 +3,8 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event, NodeEventEmitter } from 'vs/base/common/event';
import { Event } from 'vs/base/common/event';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { TPromise } from 'vs/base/common/winjs.base';
export interface IUpdate {
version: string;
@@ -74,10 +73,10 @@ export const State = {
Ready: (update: IUpdate) => ({ type: StateType.Ready, update } as Ready),
};
export interface IAutoUpdater extends NodeEventEmitter {
export interface IAutoUpdater extends Event.NodeEventEmitter {
setFeedURL(url: string): void;
checkForUpdates(): void;
applyUpdate?(): TPromise<void>;
applyUpdate?(): Promise<void>;
quitAndInstall(): void;
}
@@ -89,10 +88,10 @@ export interface IUpdateService {
readonly onStateChange: Event<State>;
readonly state: State;
checkForUpdates(context: any): TPromise<void>;
downloadUpdate(): TPromise<void>;
applyUpdate(): TPromise<void>;
quitAndInstall(): TPromise<void>;
checkForUpdates(context: any): Promise<void>;
downloadUpdate(): Promise<void>;
applyUpdate(): Promise<void>;
quitAndInstall(): Promise<void>;
isLatestVersion(): TPromise<boolean | undefined>;
isLatestVersion(): Promise<boolean | undefined>;
}

View File

@@ -40,47 +40,52 @@ export abstract class AbstractUpdateService implements IUpdateService {
}
constructor(
@ILifecycleService private lifecycleService: ILifecycleService,
@ILifecycleService private readonly lifecycleService: ILifecycleService,
@IConfigurationService protected configurationService: IConfigurationService,
@IEnvironmentService private environmentService: IEnvironmentService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IRequestService protected requestService: IRequestService,
@ILogService protected logService: ILogService,
) {
if (this.environmentService.disableUpdates) {
this.logService.info('update#ctor - updates are disabled');
this.logService.info('update#ctor - updates are disabled by the environment');
return;
}
if (!product.updateUrl || !product.commit) {
this.logService.info('update#ctor - updates are disabled');
this.logService.info('update#ctor - updates are disabled as there is no update URL');
return;
}
const quality = this.getProductQuality();
const updateChannel = this.configurationService.getValue<string>('update.channel');
const quality = this.getProductQuality(updateChannel);
if (!quality) {
this.logService.info('update#ctor - updates are disabled');
this.logService.info('update#ctor - updates are disabled by user preference');
return;
}
this.url = this.buildUpdateFeedUrl(quality);
if (!this.url) {
this.logService.info('update#ctor - updates are disabled');
this.logService.info('update#ctor - updates are disabled as the update URL is badly formed');
return;
}
this.setState(State.Idle(this.getUpdateType()));
if (updateChannel === 'manual') {
this.logService.info('update#ctor - manual checks only; automatic updates are disabled by user preference');
return;
}
// Start checking for updates after 30 seconds
this.scheduleCheckForUpdates(30 * 1000).then(undefined, err => this.logService.error(err));
}
private getProductQuality(): string | undefined {
const quality = this.configurationService.getValue<string>('update.channel');
return quality === 'none' ? undefined : product.quality;
private getProductQuality(updateChannel: string): string | undefined {
return updateChannel === 'none' ? undefined : product.quality;
}
private scheduleCheckForUpdates(delay = 60 * 60 * 1000): Thenable<void> {
private scheduleCheckForUpdates(delay = 60 * 60 * 1000): Promise<void> {
return timeout(delay)
.then(() => this.checkForUpdates(null))
.then(() => {
@@ -127,11 +132,11 @@ export abstract class AbstractUpdateService implements IUpdateService {
// noop
}
quitAndInstall(): Thenable<void> {
quitAndInstall(): Promise<void> {
this.logService.trace('update#quitAndInstall, state = ', this.state.type);
if (this.state.type !== StateType.Ready) {
return Promise.resolve(void 0);
return Promise.resolve(undefined);
}
this.logService.trace('update#quitAndInstall(): before lifecycle quit()');
@@ -146,10 +151,10 @@ export abstract class AbstractUpdateService implements IUpdateService {
this.doQuitAndInstall();
});
return Promise.resolve(void 0);
return Promise.resolve(undefined);
}
isLatestVersion(): Thenable<boolean | undefined> {
isLatestVersion(): Promise<boolean | undefined> {
if (!this.url) {
return Promise.resolve(undefined);
}

View File

@@ -5,7 +5,7 @@
import * as electron from 'electron';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Event, fromNodeEventEmitter } from 'vs/base/common/event';
import { Event } from 'vs/base/common/event';
import { memoize } from 'vs/base/common/decorators';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
@@ -22,15 +22,15 @@ export class DarwinUpdateService extends AbstractUpdateService {
private disposables: IDisposable[] = [];
@memoize private get onRawError(): Event<string> { return fromNodeEventEmitter(electron.autoUpdater, 'error', (_, message) => message); }
@memoize private get onRawUpdateNotAvailable(): Event<void> { return fromNodeEventEmitter<void>(electron.autoUpdater, 'update-not-available'); }
@memoize private get onRawUpdateAvailable(): Event<IUpdate> { return fromNodeEventEmitter(electron.autoUpdater, 'update-available', (_, url, version) => ({ url, version, productVersion: version })); }
@memoize private get onRawUpdateDownloaded(): Event<IUpdate> { return fromNodeEventEmitter(electron.autoUpdater, 'update-downloaded', (_, releaseNotes, version, date) => ({ releaseNotes, version, productVersion: version, date })); }
@memoize private get onRawError(): Event<string> { return Event.fromNodeEventEmitter(electron.autoUpdater, 'error', (_, message) => message); }
@memoize private get onRawUpdateNotAvailable(): Event<void> { return Event.fromNodeEventEmitter<void>(electron.autoUpdater, 'update-not-available'); }
@memoize private get onRawUpdateAvailable(): Event<IUpdate> { return Event.fromNodeEventEmitter(electron.autoUpdater, 'update-available', (_, url, version) => ({ url, version, productVersion: version })); }
@memoize private get onRawUpdateDownloaded(): Event<IUpdate> { return Event.fromNodeEventEmitter(electron.autoUpdater, 'update-downloaded', (_, releaseNotes, version, date) => ({ releaseNotes, version, productVersion: version, date })); }
constructor(
@ILifecycleService lifecycleService: ILifecycleService,
@IConfigurationService configurationService: IConfigurationService,
@ITelemetryService private telemetryService: ITelemetryService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IEnvironmentService environmentService: IEnvironmentService,
@IRequestService requestService: IRequestService,
@ILogService logService: ILogService
@@ -107,14 +107,6 @@ export class DarwinUpdateService extends AbstractUpdateService {
}
protected doQuitAndInstall(): void {
// for some reason updating on Mac causes the local storage not to be flushed.
// we workaround this issue by forcing an explicit flush of the storage data.
// see also https://github.com/Microsoft/vscode/issues/172
this.logService.trace('update#quitAndInstall(): calling flushStorageData()');
if (electron.session.defaultSession) {
electron.session.defaultSession.flushStorageData();
}
this.logService.trace('update#quitAndInstall(): running raw#quitAndInstall()');
electron.autoUpdater.quitAndInstall();
}

View File

@@ -26,7 +26,7 @@ export class LinuxUpdateService extends AbstractUpdateService {
constructor(
@ILifecycleService lifecycleService: ILifecycleService,
@IConfigurationService configurationService: IConfigurationService,
@ITelemetryService private telemetryService: ITelemetryService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IEnvironmentService environmentService: IEnvironmentService,
@IRequestService requestService: IRequestService,
@ILogService logService: ILogService
@@ -64,7 +64,7 @@ export class LinuxUpdateService extends AbstractUpdateService {
this.setState(State.AvailableForDownload(update));
}
})
.then(null, err => {
.then(undefined, err => {
this.logService.error(err);
/* __GDPR__
@@ -125,9 +125,11 @@ export class LinuxUpdateService extends AbstractUpdateService {
}
// Allow 3 seconds for VS Code to close
spawn('bash', ['-c', path.join(snap, `usr/share/${product.applicationName}/snapUpdate.sh`)], {
spawn('sleep 3 && $SNAP_NAME', {
shell: true,
detached: true,
stdio: ['ignore', 'ignore', 'ignore']
stdio: 'ignore',
});
}
}

View File

@@ -3,10 +3,9 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event, Emitter, fromNodeEventEmitter, filterEvent, debounceEvent } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { timeout } from 'vs/base/common/async';
import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
import product from 'vs/platform/node/product';
import { IUpdateService, State, StateType, AvailableForDownload, UpdateType } from 'vs/platform/update/common/update';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ILogService } from 'vs/platform/log/common/log';
@@ -35,7 +34,7 @@ abstract class AbstractUpdateService2 implements IUpdateService {
}
constructor(
@ILifecycleService private lifecycleService: ILifecycleService,
@ILifecycleService private readonly lifecycleService: ILifecycleService,
@IEnvironmentService environmentService: IEnvironmentService,
@ILogService protected logService: ILogService,
) {
@@ -50,7 +49,7 @@ abstract class AbstractUpdateService2 implements IUpdateService {
this.scheduleCheckForUpdates(30 * 1000).then(undefined, err => this.logService.error(err));
}
private scheduleCheckForUpdates(delay = 60 * 60 * 1000): Thenable<void> {
private scheduleCheckForUpdates(delay = 60 * 60 * 1000): Promise<void> {
return timeout(delay)
.then(() => this.checkForUpdates(null))
.then(() => {
@@ -80,7 +79,7 @@ abstract class AbstractUpdateService2 implements IUpdateService {
}
protected doDownloadUpdate(state: AvailableForDownload): Promise<void> {
return Promise.resolve(void 0);
return Promise.resolve(undefined);
}
async applyUpdate(): Promise<void> {
@@ -93,15 +92,15 @@ abstract class AbstractUpdateService2 implements IUpdateService {
await this.doApplyUpdate();
}
protected doApplyUpdate(): Thenable<void> {
return Promise.resolve(void 0);
protected doApplyUpdate(): Promise<void> {
return Promise.resolve(undefined);
}
quitAndInstall(): Thenable<void> {
quitAndInstall(): Promise<void> {
this.logService.trace('update#quitAndInstall, state = ', this.state.type);
if (this.state.type !== StateType.Ready) {
return Promise.resolve(void 0);
return Promise.resolve(undefined);
}
this.logService.trace('update#quitAndInstall(): before lifecycle quit()');
@@ -116,7 +115,7 @@ abstract class AbstractUpdateService2 implements IUpdateService {
this.doQuitAndInstall();
});
return Promise.resolve(void 0);
return Promise.resolve(undefined);
}
@@ -128,7 +127,7 @@ abstract class AbstractUpdateService2 implements IUpdateService {
// noop
}
abstract isLatestVersion(): Thenable<boolean | undefined>;
abstract isLatestVersion(): Promise<boolean | undefined>;
protected abstract doCheckForUpdates(context: any): void;
}
@@ -137,20 +136,19 @@ export class SnapUpdateService extends AbstractUpdateService2 {
_serviceBrand: any;
constructor(
private snap: string,
private snapRevision: string,
@ILifecycleService lifecycleService: ILifecycleService,
@IEnvironmentService environmentService: IEnvironmentService,
@ILogService logService: ILogService,
@ITelemetryService private telemetryService: ITelemetryService
@ITelemetryService private readonly telemetryService: ITelemetryService
) {
super(lifecycleService, environmentService, logService);
if (typeof process.env.SNAP === 'undefined') {
throw new Error(`'SNAP' environment variable not set`);
}
const watcher = watch(path.dirname(process.env.SNAP));
const onChange = fromNodeEventEmitter(watcher, 'change', (_, fileName: string) => fileName);
const onCurrentChange = filterEvent(onChange, n => n === 'current');
const onDebouncedCurrentChange = debounceEvent(onCurrentChange, (_, e) => e, 2000);
const watcher = watch(path.dirname(this.snap));
const onChange = Event.fromNodeEventEmitter(watcher, 'change', (_, fileName: string) => fileName);
const onCurrentChange = Event.filter(onChange, n => n === 'current');
const onDebouncedCurrentChange = Event.debounce(onCurrentChange, (_, e) => e, 2000);
const listener = onDebouncedCurrentChange(this.checkForUpdates, this);
lifecycleService.onWillShutdown(() => {
@@ -164,7 +162,7 @@ export class SnapUpdateService extends AbstractUpdateService2 {
this.isUpdateAvailable().then(result => {
if (result) {
this.setState(State.Ready({ version: 'something', productVersion: 'someting' }));
this.setState(State.Ready({ version: 'something', productVersion: 'something' }));
} else {
/* __GDPR__
"update:notAvailable" : {
@@ -191,29 +189,21 @@ export class SnapUpdateService extends AbstractUpdateService2 {
protected doQuitAndInstall(): void {
this.logService.trace('update#quitAndInstall(): running raw#quitAndInstall()');
if (typeof process.env.SNAP === 'undefined') {
return;
}
// Allow 3 seconds for VS Code to close
spawn('bash', ['-c', path.join(process.env.SNAP, `usr/share/${product.applicationName}/snapUpdate.sh`)], {
spawn('sleep 3 && $SNAP_NAME', {
shell: true,
detached: true,
stdio: ['ignore', 'ignore', 'ignore']
stdio: 'ignore',
});
}
private isUpdateAvailable(): Thenable<boolean> {
return new Promise((c, e) => {
realpath(`/snap/${product.applicationName}/current`, (err, resolvedCurrentSnapPath) => {
if (err) { return e(err); }
const currentRevision = path.basename(resolvedCurrentSnapPath);
c(process.env.SNAP_REVISION !== currentRevision);
});
});
private async isUpdateAvailable(): Promise<boolean> {
const resolvedCurrentSnapPath = await new Promise<string>((c, e) => realpath(`${path.dirname(this.snap)}/current`, (err, r) => err ? e(err) : c(r)));
const currentRevision = path.basename(resolvedCurrentSnapPath);
return this.snapRevision !== currentRevision;
}
isLatestVersion(): Thenable<boolean | undefined> {
isLatestVersion(): Promise<boolean | undefined> {
return this.isUpdateAvailable().then(undefined, err => {
this.logService.error('update#checkForSnapUpdate(): Could not get realpath of application.');
return undefined;

View File

@@ -53,16 +53,16 @@ export class Win32UpdateService extends AbstractUpdateService {
private availableUpdate: IAvailableUpdate | undefined;
@memoize
get cachePath(): Thenable<string> {
get cachePath(): Promise<string> {
// {{SQL CARBON EDIT}}
const result = path.join(tmpdir(), `sqlops-update-${product.target}-${process.arch}`);
return pfs.mkdirp(result, null).then(() => result);
return pfs.mkdirp(result, undefined).then(() => result);
}
constructor(
@ILifecycleService lifecycleService: ILifecycleService,
@IConfigurationService configurationService: IConfigurationService,
@ITelemetryService private telemetryService: ITelemetryService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IEnvironmentService environmentService: IEnvironmentService,
@IRequestService requestService: IRequestService,
@ILogService logService: ILogService
@@ -144,7 +144,7 @@ export class Win32UpdateService extends AbstractUpdateService {
return this.requestService.request({ url }, CancellationToken.None)
.then(context => download(downloadPath, context))
.then(hash ? () => checksum(downloadPath, update.hash) : () => null)
.then(hash ? () => checksum(downloadPath, update.hash) : () => undefined)
.then(() => pfs.rename(downloadPath, updatePackagePath))
.then(() => updatePackagePath);
});
@@ -165,7 +165,7 @@ export class Win32UpdateService extends AbstractUpdateService {
});
});
})
.then(null, err => {
.then(undefined, err => {
this.logService.error(err);
/* __GDPR__
"update:notAvailable" : {
@@ -181,7 +181,9 @@ export class Win32UpdateService extends AbstractUpdateService {
}
protected async doDownloadUpdate(state: AvailableForDownload): Promise<void> {
shell.openExternal(state.update.url);
if (state.update.url) {
shell.openExternal(state.update.url);
}
this.setState(State.Idle(getUpdateType()));
}
@@ -210,11 +212,11 @@ export class Win32UpdateService extends AbstractUpdateService {
protected async doApplyUpdate(): Promise<void> {
if (this.state.type !== StateType.Downloaded && this.state.type !== StateType.Downloading) {
return Promise.resolve(null);
return Promise.resolve(undefined);
}
if (!this.availableUpdate) {
return Promise.resolve(null);
return Promise.resolve(undefined);
}
const update = this.state.update;
@@ -245,7 +247,7 @@ export class Win32UpdateService extends AbstractUpdateService {
}
protected doQuitAndInstall(): void {
if (this.state.type !== StateType.Ready) {
if (this.state.type !== StateType.Ready || !this.availableUpdate) {
return;
}

View File

@@ -3,37 +3,42 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
import { localize } from 'vs/nls';
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
configurationRegistry.registerConfiguration({
'id': 'update',
'order': 15,
'title': nls.localize('updateConfigurationTitle', "Update"),
'type': 'object',
'properties': {
id: 'update',
order: 15,
title: localize('updateConfigurationTitle', "Update"),
type: 'object',
properties: {
'update.channel': {
'type': 'string',
'enum': ['none', 'default'],
'default': 'default',
'scope': ConfigurationScope.APPLICATION,
'description': nls.localize('updateChannel', "Configure whether you receive automatic updates from an update channel. Requires a restart after change. The updates are fetched from a Microsoft online service."),
'tags': ['usesOnlineServices']
type: 'string',
enum: ['none', 'manual', 'default'],
default: 'default',
scope: ConfigurationScope.APPLICATION,
description: localize('updateChannel', "Configure whether you receive automatic updates from an update channel. Requires a restart after change. The updates are fetched from a Microsoft online service."),
tags: ['usesOnlineServices'],
enumDescriptions: [
localize('none', "Disable updates."),
localize('manual', "Disable automatic background update checks. Updates will be available if you manually check for updates."),
localize('default', "Enable automatic update checks. Code will check for updates automatically and periodically.")
]
},
'update.enableWindowsBackgroundUpdates': {
'type': 'boolean',
'default': true,
'scope': ConfigurationScope.APPLICATION,
'description': nls.localize('enableWindowsBackgroundUpdates', "Enables Windows background updates. The updates are fetched from a Microsoft online service."),
'tags': ['usesOnlineServices']
type: 'boolean',
default: true,
scope: ConfigurationScope.APPLICATION,
description: localize('enableWindowsBackgroundUpdates', "Enables Windows background updates. The updates are fetched from a Microsoft online service."),
tags: ['usesOnlineServices']
},
'update.showReleaseNotes': {
'type': 'boolean',
'default': true,
'description': nls.localize('showReleaseNotes', "Show Release Notes after an update. The Release Notes are fetched from a Microsoft online service."),
'tags': ['usesOnlineServices']
type: 'boolean',
default: true,
description: localize('showReleaseNotes', "Show Release Notes after an update. The Release Notes are fetched from a Microsoft online service."),
tags: ['usesOnlineServices']
}
}
});

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { TPromise } from 'vs/base/common/winjs.base';
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/node/ipc';
import { Event, Emitter } from 'vs/base/common/event';
import { IUpdateService, State } from 'vs/platform/update/common/update';
@@ -20,13 +19,13 @@ export class UpdateChannel implements IServerChannel {
throw new Error(`Event not found: ${event}`);
}
call(_, command: string, arg?: any): TPromise<any> {
call(_, command: string, arg?: any): Promise<any> {
switch (command) {
case 'checkForUpdates': return this.service.checkForUpdates(arg);
case 'downloadUpdate': return this.service.downloadUpdate();
case 'applyUpdate': return this.service.applyUpdate();
case 'quitAndInstall': return this.service.quitAndInstall();
case '_getInitialState': return TPromise.as(this.service.state);
case '_getInitialState': return Promise.resolve(this.service.state);
case 'isLatestVersion': return this.service.isLatestVersion();
}
@@ -58,23 +57,23 @@ export class UpdateChannelClient implements IUpdateService {
});
}
checkForUpdates(context: any): TPromise<void> {
checkForUpdates(context: any): Promise<void> {
return this.channel.call('checkForUpdates', context);
}
downloadUpdate(): TPromise<void> {
downloadUpdate(): Promise<void> {
return this.channel.call('downloadUpdate');
}
applyUpdate(): TPromise<void> {
applyUpdate(): Promise<void> {
return this.channel.call('applyUpdate');
}
quitAndInstall(): TPromise<void> {
quitAndInstall(): Promise<void> {
return this.channel.call('quitAndInstall');
}
isLatestVersion(): TPromise<boolean> {
isLatestVersion(): Promise<boolean> {
return this.channel.call('isLatestVersion');
}
}