mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-15 02:48:30 -05:00
SQL Operations Studio Public Preview 1 (0.23) release source code
This commit is contained in:
58
src/vs/platform/update/common/update.ts
Normal file
58
src/vs/platform/update/common/update.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import Event from 'vs/base/common/event';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
||||
export enum State {
|
||||
Uninitialized,
|
||||
Idle,
|
||||
CheckingForUpdate,
|
||||
UpdateAvailable,
|
||||
UpdateDownloaded
|
||||
}
|
||||
|
||||
export enum ExplicitState {
|
||||
Implicit,
|
||||
Explicit
|
||||
}
|
||||
|
||||
export interface IRawUpdate {
|
||||
releaseNotes: string;
|
||||
version: string;
|
||||
date: Date;
|
||||
}
|
||||
|
||||
export interface IUpdate {
|
||||
version: string;
|
||||
date?: Date;
|
||||
releaseNotes?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
export interface IAutoUpdater extends NodeJS.EventEmitter {
|
||||
setFeedURL(url: string): void;
|
||||
checkForUpdates(): void;
|
||||
quitAndInstall(): void;
|
||||
}
|
||||
|
||||
export const IUpdateService = createDecorator<IUpdateService>('updateService');
|
||||
|
||||
export interface IUpdateService {
|
||||
_serviceBrand: any;
|
||||
|
||||
readonly onError: Event<any>;
|
||||
readonly onUpdateAvailable: Event<{ url: string; version: string; }>;
|
||||
readonly onUpdateNotAvailable: Event<boolean>;
|
||||
readonly onUpdateReady: Event<IRawUpdate>;
|
||||
readonly onStateChange: Event<State>;
|
||||
readonly state: State;
|
||||
|
||||
checkForUpdates(explicit: boolean): TPromise<IUpdate>;
|
||||
quitAndInstall(): TPromise<void>;
|
||||
}
|
||||
88
src/vs/platform/update/common/updateIpc.ts
Normal file
88
src/vs/platform/update/common/updateIpc.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IChannel, eventToCall, eventFromCall } from 'vs/base/parts/ipc/common/ipc';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IUpdateService, IRawUpdate, State, IUpdate } from './update';
|
||||
|
||||
export interface IUpdateChannel extends IChannel {
|
||||
call(command: 'event:onError'): TPromise<void>;
|
||||
call(command: 'event:onUpdateAvailable'): TPromise<void>;
|
||||
call(command: 'event:onUpdateNotAvailable'): TPromise<void>;
|
||||
call(command: 'event:onUpdateReady'): TPromise<void>;
|
||||
call(command: 'event:onStateChange'): TPromise<void>;
|
||||
call(command: 'checkForUpdates', arg: boolean): TPromise<IUpdate>;
|
||||
call(command: 'quitAndInstall'): TPromise<void>;
|
||||
call(command: '_getInitialState'): TPromise<State>;
|
||||
call(command: string, arg?: any): TPromise<any>;
|
||||
}
|
||||
|
||||
export class UpdateChannel implements IUpdateChannel {
|
||||
|
||||
constructor(private service: IUpdateService) { }
|
||||
|
||||
call(command: string, arg?: any): TPromise<any> {
|
||||
switch (command) {
|
||||
case 'event:onError': return eventToCall(this.service.onError);
|
||||
case 'event:onUpdateAvailable': return eventToCall(this.service.onUpdateAvailable);
|
||||
case 'event:onUpdateNotAvailable': return eventToCall(this.service.onUpdateNotAvailable);
|
||||
case 'event:onUpdateReady': return eventToCall(this.service.onUpdateReady);
|
||||
case 'event:onStateChange': return eventToCall(this.service.onStateChange);
|
||||
case 'checkForUpdates': return this.service.checkForUpdates(arg);
|
||||
case 'quitAndInstall': return this.service.quitAndInstall();
|
||||
case '_getInitialState': return TPromise.as(this.service.state);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export class UpdateChannelClient implements IUpdateService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private _onError = eventFromCall<any>(this.channel, 'event:onError');
|
||||
get onError(): Event<any> { return this._onError; }
|
||||
|
||||
private _onUpdateAvailable = eventFromCall<{ url: string; version: string; }>(this.channel, 'event:onUpdateAvailable');
|
||||
get onUpdateAvailable(): Event<{ url: string; version: string; }> { return this._onUpdateAvailable; }
|
||||
|
||||
private _onUpdateNotAvailable = eventFromCall<boolean>(this.channel, 'event:onUpdateNotAvailable');
|
||||
get onUpdateNotAvailable(): Event<boolean> { return this._onUpdateNotAvailable; }
|
||||
|
||||
private _onUpdateReady = eventFromCall<IRawUpdate>(this.channel, 'event:onUpdateReady');
|
||||
get onUpdateReady(): Event<IRawUpdate> { return this._onUpdateReady; }
|
||||
|
||||
private _onRemoteStateChange = eventFromCall<State>(this.channel, 'event:onStateChange');
|
||||
private _onStateChange = new Emitter<State>();
|
||||
get onStateChange(): Event<State> { return this._onStateChange.event; }
|
||||
|
||||
private _state: State = State.Uninitialized;
|
||||
get state(): State { return this._state; };
|
||||
|
||||
constructor(private channel: IUpdateChannel) {
|
||||
// always set this._state as the state changes
|
||||
this.onStateChange(state => this._state = state);
|
||||
|
||||
channel.call('_getInitialState').done(state => {
|
||||
// fire initial state
|
||||
this._onStateChange.fire(state);
|
||||
|
||||
// fire subsequent states as they come in from remote
|
||||
this._onRemoteStateChange(state => this._onStateChange.fire(state));
|
||||
}, onUnexpectedError);
|
||||
}
|
||||
|
||||
checkForUpdates(explicit: boolean): TPromise<IUpdate> {
|
||||
return this.channel.call('checkForUpdates', explicit);
|
||||
}
|
||||
|
||||
quitAndInstall(): TPromise<void> {
|
||||
return this.channel.call('quitAndInstall');
|
||||
}
|
||||
}
|
||||
77
src/vs/platform/update/electron-main/auto-updater.linux.ts
Normal file
77
src/vs/platform/update/electron-main/auto-updater.linux.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { EventEmitter } from 'events';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
import { Promise } from 'vs/base/common/winjs.base';
|
||||
import { asJson } from 'vs/base/node/request';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { IAutoUpdater } from 'vs/platform/update/common/update';
|
||||
import product from 'vs/platform/node/product';
|
||||
|
||||
interface IUpdate {
|
||||
url: string;
|
||||
name: string;
|
||||
releaseNotes?: string;
|
||||
version: string;
|
||||
productVersion: string;
|
||||
hash: string;
|
||||
}
|
||||
|
||||
export class LinuxAutoUpdaterImpl extends EventEmitter implements IAutoUpdater {
|
||||
|
||||
private url: string;
|
||||
private currentRequest: Promise;
|
||||
|
||||
constructor(
|
||||
@IRequestService private requestService: IRequestService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.url = null;
|
||||
this.currentRequest = null;
|
||||
}
|
||||
|
||||
setFeedURL(url: string): void {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
checkForUpdates(): void {
|
||||
if (!this.url) {
|
||||
throw new Error('No feed url set.');
|
||||
}
|
||||
|
||||
if (this.currentRequest) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.emit('checking-for-update');
|
||||
|
||||
this.currentRequest = this.requestService.request({ url: this.url })
|
||||
.then<IUpdate>(asJson)
|
||||
.then(update => {
|
||||
if (!update || !update.url || !update.version || !update.productVersion) {
|
||||
this.emit('update-not-available');
|
||||
} else {
|
||||
this.emit('update-available', null, product.downloadUrl, update.productVersion);
|
||||
}
|
||||
})
|
||||
.then(null, e => {
|
||||
if (isString(e) && /^Server returned/.test(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.emit('update-not-available');
|
||||
this.emit('error', e);
|
||||
})
|
||||
.then(() => this.currentRequest = null);
|
||||
}
|
||||
|
||||
quitAndInstall(): void {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
140
src/vs/platform/update/electron-main/auto-updater.win32.ts
Normal file
140
src/vs/platform/update/electron-main/auto-updater.win32.ts
Normal file
@@ -0,0 +1,140 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as path from 'path';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import { checksum } from 'vs/base/node/crypto';
|
||||
import { EventEmitter } from 'events';
|
||||
import { tmpdir } from 'os';
|
||||
import { spawn } from 'child_process';
|
||||
import { mkdirp } from 'vs/base/node/extfs';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
import { Promise, TPromise } from 'vs/base/common/winjs.base';
|
||||
import { download, asJson } from 'vs/base/node/request';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import { IAutoUpdater } from 'vs/platform/update/common/update';
|
||||
import product from 'vs/platform/node/product';
|
||||
|
||||
interface IUpdate {
|
||||
url: string;
|
||||
name: string;
|
||||
releaseNotes?: string;
|
||||
version: string;
|
||||
productVersion: string;
|
||||
hash: string;
|
||||
}
|
||||
|
||||
export class Win32AutoUpdaterImpl extends EventEmitter implements IAutoUpdater {
|
||||
|
||||
private url: string = null;
|
||||
private currentRequest: Promise = null;
|
||||
private updatePackagePath: string = null;
|
||||
|
||||
constructor(
|
||||
@IRequestService private requestService: IRequestService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
get cachePath(): TPromise<string> {
|
||||
const result = path.join(tmpdir(), `vscode-update-${process.arch}`);
|
||||
return new TPromise<string>((c, e) => mkdirp(result, null, err => err ? e(err) : c(result)));
|
||||
}
|
||||
|
||||
setFeedURL(url: string): void {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
checkForUpdates(): void {
|
||||
if (!this.url) {
|
||||
throw new Error('No feed url set.');
|
||||
}
|
||||
|
||||
if (this.currentRequest) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.emit('checking-for-update');
|
||||
|
||||
this.currentRequest = this.requestService.request({ url: this.url })
|
||||
.then<IUpdate>(asJson)
|
||||
.then(update => {
|
||||
if (!update || !update.url || !update.version) {
|
||||
this.emit('update-not-available');
|
||||
return this.cleanup();
|
||||
}
|
||||
|
||||
this.emit('update-available');
|
||||
|
||||
return this.cleanup(update.version).then(() => {
|
||||
return this.getUpdatePackagePath(update.version).then(updatePackagePath => {
|
||||
return pfs.exists(updatePackagePath).then(exists => {
|
||||
if (exists) {
|
||||
return TPromise.as(updatePackagePath);
|
||||
}
|
||||
|
||||
const url = update.url;
|
||||
const hash = update.hash;
|
||||
const downloadPath = `${updatePackagePath}.tmp`;
|
||||
|
||||
return this.requestService.request({ url })
|
||||
.then(context => download(downloadPath, context))
|
||||
.then(hash ? () => checksum(downloadPath, update.hash) : () => null)
|
||||
.then(() => pfs.rename(downloadPath, updatePackagePath))
|
||||
.then(() => updatePackagePath);
|
||||
});
|
||||
}).then(updatePackagePath => {
|
||||
this.updatePackagePath = updatePackagePath;
|
||||
|
||||
this.emit('update-downloaded',
|
||||
{},
|
||||
update.releaseNotes,
|
||||
update.productVersion,
|
||||
new Date(),
|
||||
this.url
|
||||
);
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(null, e => {
|
||||
if (isString(e) && /^Server returned/.test(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.emit('update-not-available');
|
||||
this.emit('error', e);
|
||||
})
|
||||
.then(() => this.currentRequest = null);
|
||||
}
|
||||
|
||||
private getUpdatePackagePath(version: string): TPromise<string> {
|
||||
return this.cachePath.then(cachePath => path.join(cachePath, `CodeSetup-${product.quality}-${version}.exe`));
|
||||
}
|
||||
|
||||
private cleanup(exceptVersion: string = null): Promise {
|
||||
const filter = exceptVersion ? one => !(new RegExp(`${product.quality}-${exceptVersion}\\.exe$`).test(one)) : () => true;
|
||||
|
||||
return this.cachePath
|
||||
.then(cachePath => pfs.readdir(cachePath)
|
||||
.then(all => Promise.join(all
|
||||
.filter(filter)
|
||||
.map(one => pfs.unlink(path.join(cachePath, one)).then(null, () => null))
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
quitAndInstall(): void {
|
||||
if (!this.updatePackagePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
spawn(this.updatePackagePath, ['/silent', '/mergetasks=runcode,!desktopicon,!quicklaunchicon'], {
|
||||
detached: true,
|
||||
stdio: ['ignore', 'ignore', 'ignore']
|
||||
});
|
||||
}
|
||||
}
|
||||
268
src/vs/platform/update/electron-main/updateService.ts
Normal file
268
src/vs/platform/update/electron-main/updateService.ts
Normal file
@@ -0,0 +1,268 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as fs from 'original-fs';
|
||||
import * as path from 'path';
|
||||
import * as electron from 'electron';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import Event, { Emitter, once, filterEvent } from 'vs/base/common/event';
|
||||
import { always, Throttler } from 'vs/base/common/async';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { fromEventEmitter } from 'vs/base/node/event';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { Win32AutoUpdaterImpl } from './auto-updater.win32';
|
||||
import { LinuxAutoUpdaterImpl } from './auto-updater.linux';
|
||||
import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
|
||||
import { IRequestService } from 'vs/platform/request/node/request';
|
||||
import product from 'vs/platform/node/product';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IUpdateService, State, IAutoUpdater, IUpdate, IRawUpdate } from 'vs/platform/update/common/update';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
export class UpdateService implements IUpdateService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private _state: State = State.Uninitialized;
|
||||
private _availableUpdate: IUpdate = null;
|
||||
private raw: IAutoUpdater;
|
||||
private throttler: Throttler = new Throttler();
|
||||
|
||||
private _onError = new Emitter<any>();
|
||||
get onError(): Event<any> { return this._onError.event; }
|
||||
|
||||
private _onCheckForUpdate = new Emitter<void>();
|
||||
get onCheckForUpdate(): Event<void> { return this._onCheckForUpdate.event; }
|
||||
|
||||
private _onUpdateAvailable = new Emitter<{ url: string; version: string; }>();
|
||||
get onUpdateAvailable(): Event<{ url: string; version: string; }> { return this._onUpdateAvailable.event; }
|
||||
|
||||
private _onUpdateNotAvailable = new Emitter<boolean>();
|
||||
get onUpdateNotAvailable(): Event<boolean> { return this._onUpdateNotAvailable.event; }
|
||||
|
||||
private _onUpdateReady = new Emitter<IRawUpdate>();
|
||||
get onUpdateReady(): Event<IRawUpdate> { return this._onUpdateReady.event; }
|
||||
|
||||
private _onStateChange = new Emitter<State>();
|
||||
get onStateChange(): Event<State> { return this._onStateChange.event; }
|
||||
|
||||
@memoize
|
||||
private get onRawError(): Event<string> {
|
||||
return fromEventEmitter(this.raw, 'error', (_, message) => message);
|
||||
}
|
||||
|
||||
@memoize
|
||||
private get onRawUpdateNotAvailable(): Event<void> {
|
||||
return fromEventEmitter<void>(this.raw, 'update-not-available');
|
||||
}
|
||||
|
||||
@memoize
|
||||
private get onRawUpdateAvailable(): Event<{ url: string; version: string; }> {
|
||||
return filterEvent(fromEventEmitter(this.raw, 'update-available', (_, url, version) => ({ url, version })), ({ url }) => !!url);
|
||||
}
|
||||
|
||||
@memoize
|
||||
private get onRawUpdateDownloaded(): Event<IRawUpdate> {
|
||||
return fromEventEmitter(this.raw, 'update-downloaded', (_, releaseNotes, version, date, url) => ({ releaseNotes, version, date }));
|
||||
}
|
||||
|
||||
get state(): State {
|
||||
return this._state;
|
||||
}
|
||||
|
||||
set state(state: State) {
|
||||
this._state = state;
|
||||
this._onStateChange.fire(state);
|
||||
}
|
||||
|
||||
get availableUpdate(): IUpdate {
|
||||
return this._availableUpdate;
|
||||
}
|
||||
|
||||
constructor(
|
||||
@IRequestService requestService: IRequestService,
|
||||
@ILifecycleService private lifecycleService: ILifecycleService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@ITelemetryService private telemetryService: ITelemetryService
|
||||
) {
|
||||
if (process.platform === 'win32') {
|
||||
this.raw = new Win32AutoUpdaterImpl(requestService);
|
||||
} else if (process.platform === 'linux') {
|
||||
this.raw = new LinuxAutoUpdaterImpl(requestService);
|
||||
} else if (process.platform === 'darwin') {
|
||||
this.raw = electron.autoUpdater;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
const channel = this.getUpdateChannel();
|
||||
const feedUrl = this.getUpdateFeedUrl(channel);
|
||||
|
||||
if (!feedUrl) {
|
||||
return; // updates not available
|
||||
}
|
||||
|
||||
try {
|
||||
this.raw.setFeedURL(feedUrl);
|
||||
} catch (e) {
|
||||
return; // application not signed
|
||||
}
|
||||
|
||||
this.state = State.Idle;
|
||||
|
||||
// Start checking for updates after 30 seconds
|
||||
this.scheduleCheckForUpdates(30 * 1000)
|
||||
.done(null, err => console.error(err));
|
||||
}
|
||||
|
||||
private scheduleCheckForUpdates(delay = 60 * 60 * 1000): TPromise<void> {
|
||||
return TPromise.timeout(delay)
|
||||
.then(() => this.checkForUpdates())
|
||||
.then(update => {
|
||||
if (update) {
|
||||
// Update found, no need to check more
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
// Check again after 1 hour
|
||||
return this.scheduleCheckForUpdates(60 * 60 * 1000);
|
||||
});
|
||||
}
|
||||
|
||||
checkForUpdates(explicit = false): TPromise<IUpdate> {
|
||||
return this.throttler.queue(() => this._checkForUpdates(explicit))
|
||||
.then(null, err => {
|
||||
if (explicit) {
|
||||
this._onError.fire(err);
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private _checkForUpdates(explicit: boolean): TPromise<IUpdate> {
|
||||
if (this.state !== State.Idle) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
this._onCheckForUpdate.fire();
|
||||
this.state = State.CheckingForUpdate;
|
||||
|
||||
const listeners: IDisposable[] = [];
|
||||
const result = new TPromise<IUpdate>((c, e) => {
|
||||
once(this.onRawError)(e, null, listeners);
|
||||
once(this.onRawUpdateNotAvailable)(() => c(null), null, listeners);
|
||||
once(this.onRawUpdateAvailable)(({ url, version }) => url && c({ url, version }), null, listeners);
|
||||
once(this.onRawUpdateDownloaded)(({ version, date, releaseNotes }) => c({ version, date, releaseNotes }), null, listeners);
|
||||
|
||||
this.raw.checkForUpdates();
|
||||
}).then(update => {
|
||||
if (!update) {
|
||||
this._onUpdateNotAvailable.fire(explicit);
|
||||
this.state = State.Idle;
|
||||
this.telemetryService.publicLog('update:notAvailable', { explicit });
|
||||
|
||||
} else if (update.url) {
|
||||
const data: IUpdate = {
|
||||
url: update.url,
|
||||
releaseNotes: '',
|
||||
version: update.version,
|
||||
date: new Date()
|
||||
};
|
||||
|
||||
this._availableUpdate = data;
|
||||
this._onUpdateAvailable.fire({ url: update.url, version: update.version });
|
||||
this.state = State.UpdateAvailable;
|
||||
this.telemetryService.publicLog('update:available', { explicit, version: update.version, currentVersion: product.commit });
|
||||
|
||||
} else {
|
||||
const data: IRawUpdate = {
|
||||
releaseNotes: update.releaseNotes,
|
||||
version: update.version,
|
||||
date: update.date
|
||||
};
|
||||
|
||||
this._availableUpdate = data;
|
||||
this._onUpdateReady.fire(data);
|
||||
this.state = State.UpdateDownloaded;
|
||||
this.telemetryService.publicLog('update:downloaded', { version: update.version });
|
||||
}
|
||||
|
||||
return update;
|
||||
}, err => {
|
||||
this.state = State.Idle;
|
||||
return TPromise.wrapError<IUpdate>(err);
|
||||
});
|
||||
|
||||
return always(result, () => dispose(listeners));
|
||||
}
|
||||
|
||||
private getUpdateChannel(): string {
|
||||
const config = this.configurationService.getConfiguration<{ channel: string; }>('update');
|
||||
const channel = config && config.channel;
|
||||
|
||||
return channel === 'none' ? null : product.quality;
|
||||
}
|
||||
|
||||
private getUpdateFeedUrl(channel: string): string {
|
||||
if (!channel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (process.platform === 'win32' && !fs.existsSync(path.join(path.dirname(process.execPath), 'unins000.exe'))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!product.updateUrl || !product.commit) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const platform = this.getUpdatePlatform();
|
||||
|
||||
return `${product.updateUrl}/api/update/${platform}/${channel}/${product.commit}`;
|
||||
}
|
||||
|
||||
private getUpdatePlatform(): string {
|
||||
if (process.platform === 'linux') {
|
||||
return `linux-${process.arch}`;
|
||||
}
|
||||
|
||||
if (process.platform === 'win32' && process.arch === 'x64') {
|
||||
return 'win32-x64';
|
||||
}
|
||||
|
||||
return process.platform;
|
||||
}
|
||||
|
||||
quitAndInstall(): TPromise<void> {
|
||||
if (!this._availableUpdate) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
if (this._availableUpdate.url) {
|
||||
electron.shell.openExternal(this._availableUpdate.url);
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
this.lifecycleService.quit(true /* from update */).done(vetod => {
|
||||
if (vetod) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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
|
||||
if (process.platform === 'darwin') {
|
||||
electron.session.defaultSession.flushStorageData();
|
||||
}
|
||||
|
||||
this.raw.quitAndInstall();
|
||||
});
|
||||
|
||||
return TPromise.as(null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user