Vscode merge (#4582)

* Merge from vscode 37cb23d3dd4f9433d56d4ba5ea3203580719a0bd

* fix issues with merges

* bump node version in azpipe

* replace license headers

* remove duplicate launch task

* fix build errors

* fix build errors

* fix tslint issues

* working through package and linux build issues

* more work

* wip

* fix packaged builds

* working through linux build errors

* wip

* wip

* wip

* fix mac and linux file limits

* iterate linux pipeline

* disable editor typing

* revert series to parallel

* remove optimize vscode from linux

* fix linting issues

* revert testing change

* add work round for new node

* readd packaging for extensions

* fix issue with angular not resolving decorator dependencies
This commit is contained in:
Anthony Dresser
2019-03-19 17:44:35 -07:00
committed by GitHub
parent 833d197412
commit 87765e8673
1879 changed files with 54505 additions and 38058 deletions

View File

@@ -3,12 +3,16 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/node/ipc';
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc';
import { Event, Emitter } from 'vs/base/common/event';
import { StorageMainService, IStorageChangeEvent } from 'vs/platform/storage/node/storageMainService';
import { IUpdateRequest, IStorageDatabase, IStorageItemsChangeEvent } from 'vs/base/node/storage';
import { mapToSerializable, serializableToMap, values } from 'vs/base/common/map';
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import { onUnexpectedError } from 'vs/base/common/errors';
import { ILogService } from 'vs/platform/log/common/log';
import { generateUuid } from 'vs/base/common/uuid';
import { instanceStorageKey, firstSessionDateStorageKey, lastSessionDateStorageKey, currentSessionDateStorageKey } from 'vs/platform/telemetry/node/workbenchCommonProperties';
type Key = string;
type Value = string;
@@ -27,13 +31,51 @@ export class GlobalStorageDatabaseChannel extends Disposable implements IServerC
private static STORAGE_CHANGE_DEBOUNCE_TIME = 100;
private _onDidChangeItems: Emitter<ISerializableItemsChangeEvent> = this._register(new Emitter<ISerializableItemsChangeEvent>());
private readonly _onDidChangeItems: Emitter<ISerializableItemsChangeEvent> = this._register(new Emitter<ISerializableItemsChangeEvent>());
get onDidChangeItems(): Event<ISerializableItemsChangeEvent> { return this._onDidChangeItems.event; }
constructor(private storageMainService: StorageMainService) {
private whenReady: Promise<void>;
constructor(
private logService: ILogService,
private storageMainService: StorageMainService
) {
super();
this.registerListeners();
this.whenReady = this.init();
}
private init(): Promise<void> {
return this.storageMainService.initialize().then(undefined, error => {
onUnexpectedError(error);
this.logService.error(error);
}).then(() => {
// Apply global telemetry values as part of the initialization
// These are global across all windows and thereby should be
// written from the main process once.
this.initTelemetry();
// Setup storage change listeners
this.registerListeners();
});
}
private initTelemetry(): void {
const instanceId = this.storageMainService.get(instanceStorageKey, undefined);
if (instanceId === undefined) {
this.storageMainService.store(instanceStorageKey, generateUuid());
}
const firstSessionDate = this.storageMainService.get(firstSessionDateStorageKey, undefined);
if (firstSessionDate === undefined) {
this.storageMainService.store(firstSessionDateStorageKey, new Date().toUTCString());
}
const lastSessionDate = this.storageMainService.get(currentSessionDateStorageKey, undefined); // previous session date was the "current" one at that time
const currentSessionDate = new Date().toUTCString(); // current session date is "now"
this.storageMainService.store(lastSessionDateStorageKey, typeof lastSessionDate === 'undefined' ? null : lastSessionDate);
this.storageMainService.store(currentSessionDateStorageKey, currentSessionDate);
}
private registerListeners(): void {
@@ -73,26 +115,26 @@ export class GlobalStorageDatabaseChannel extends Disposable implements IServerC
call(_, command: string, arg?: any): Promise<any> {
switch (command) {
case 'getItems': {
return Promise.resolve(mapToSerializable(this.storageMainService.items));
return this.whenReady.then(() => mapToSerializable(this.storageMainService.items));
}
case 'updateItems': {
const items = arg as ISerializableUpdateRequest;
if (items.insert) {
for (const [key, value] of items.insert) {
this.storageMainService.store(key, value);
return this.whenReady.then(() => {
const items = arg as ISerializableUpdateRequest;
if (items.insert) {
for (const [key, value] of items.insert) {
this.storageMainService.store(key, value);
}
}
}
if (items.delete) {
items.delete.forEach(key => this.storageMainService.remove(key));
}
return Promise.resolve(); // do not wait for modifications to complete
if (items.delete) {
items.delete.forEach(key => this.storageMainService.remove(key));
}
});
}
case 'checkIntegrity': {
return this.storageMainService.checkIntegrity(arg);
return this.whenReady.then(() => this.storageMainService.checkIntegrity(arg));
}
}
@@ -104,7 +146,7 @@ export class GlobalStorageDatabaseChannelClient extends Disposable implements IS
_serviceBrand: any;
private _onDidChangeItemsExternal: Emitter<IStorageItemsChangeEvent> = this._register(new Emitter<IStorageItemsChangeEvent>());
private readonly _onDidChangeItemsExternal: Emitter<IStorageItemsChangeEvent> = this._register(new Emitter<IStorageItemsChangeEvent>());
get onDidChangeItemsExternal(): Event<IStorageItemsChangeEvent> { return this._onDidChangeItemsExternal.event; }
private onDidChangeItemsOnMainListener: IDisposable;

View File

@@ -9,9 +9,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { ILogService, LogLevel } from 'vs/platform/log/common/log';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IStorage, Storage, SQLiteStorageDatabase, ISQLiteStorageDatabaseLoggingOptions, InMemoryStorageDatabase } from 'vs/base/node/storage';
import { join } from 'path';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { mark, getDuration } from 'vs/base/common/performance';
import { join } from 'vs/base/common/path';
import { exists, readdir } from 'vs/base/node/pfs';
import { Database } from 'vscode-sqlite3';
import { endsWith, startsWith } from 'vs/base/common/strings';
@@ -54,8 +52,8 @@ export interface IStorageMainService {
* the provided defaultValue if the element is null or undefined. The element
* will be converted to a number using parseInt with a base of 10.
*/
getInteger(key: string, fallbackValue: number): number;
getInteger(key: string, fallbackValue?: number): number | undefined;
getNumber(key: string, fallbackValue: number): number;
getNumber(key: string, fallbackValue?: number): number | undefined;
/**
* Store a string value under the given key to storage. The value will
@@ -79,20 +77,21 @@ export class StorageMainService extends Disposable implements IStorageMainServic
private static STORAGE_NAME = 'state.vscdb';
private _onDidChangeStorage: Emitter<IStorageChangeEvent> = this._register(new Emitter<IStorageChangeEvent>());
private readonly _onDidChangeStorage: Emitter<IStorageChangeEvent> = this._register(new Emitter<IStorageChangeEvent>());
get onDidChangeStorage(): Event<IStorageChangeEvent> { return this._onDidChangeStorage.event; }
private _onWillSaveState: Emitter<void> = this._register(new Emitter<void>());
private readonly _onWillSaveState: Emitter<void> = this._register(new Emitter<void>());
get onWillSaveState(): Event<void> { return this._onWillSaveState.event; }
get items(): Map<string, string> { return this.storage.items; }
private storage: IStorage;
private initializePromise: Promise<void>;
constructor(
@ILogService private readonly logService: ILogService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@ITelemetryService private readonly telemetryService: ITelemetryService
@IEnvironmentService private readonly environmentService: IEnvironmentService
) {
super();
@@ -101,7 +100,7 @@ export class StorageMainService extends Disposable implements IStorageMainServic
}
private get storagePath(): string {
if (!!this.environmentService.extensionTestsPath) {
if (!!this.environmentService.extensionTestsLocationURI) {
return SQLiteStorageDatabase.IN_MEMORY_PATH; // no storage during extension tests!
}
@@ -109,31 +108,21 @@ export class StorageMainService extends Disposable implements IStorageMainServic
}
private createLogginOptions(): ISQLiteStorageDatabaseLoggingOptions {
const loggedStorageErrors = new Set<string>();
return {
logTrace: (this.logService.getLevel() === LogLevel.Trace) ? msg => this.logService.trace(msg) : undefined,
logError: error => {
this.logService.error(error);
const errorStr = `${error}`;
if (!loggedStorageErrors.has(errorStr)) {
loggedStorageErrors.add(errorStr);
/* __GDPR__
"sqliteMainStorageError" : {
"storageError": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('sqliteMainStorageError', {
'storageError': errorStr
});
}
}
logError: error => this.logService.error(error)
} as ISQLiteStorageDatabaseLoggingOptions;
}
initialize(): Promise<void> {
if (!this.initializePromise) {
this.initializePromise = this.doInitialize();
}
return this.initializePromise;
}
private doInitialize(): Promise<void> {
const useInMemoryStorage = this.storagePath === SQLiteStorageDatabase.IN_MEMORY_PATH;
let globalStorageExists: Promise<boolean>;
@@ -151,14 +140,7 @@ export class StorageMainService extends Disposable implements IStorageMainServic
this._register(this.storage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key })));
mark('main:willInitGlobalStorage');
return this.storage.init().then(() => {
mark('main:didInitGlobalStorage');
}, error => {
mark('main:didInitGlobalStorage');
return Promise.reject(error);
}).then(() => {
// Migrate storage if this is the first start and we are not using in-memory
let migrationPromise: Promise<void>;
@@ -240,6 +222,10 @@ export class StorageMainService extends Disposable implements IStorageMainServic
'update/updateNotificationTime'
].forEach(key => supportedKeys.set(key.toLowerCase(), key));
// https://github.com/Microsoft/vscode/issues/68468
const wellKnownPublishers = ['Microsoft', 'GitHub'];
const wellKnownExtensions = ['ms-vscode.Go', 'WallabyJs.quokka-vscode', 'Telerik.nativescript', 'Shan.code-settings-sync', 'ritwickdey.LiveServer', 'PKief.material-icon-theme', 'PeterJausovec.vscode-docker', 'ms-vscode.PowerShell', 'LaurentTreguier.vscode-simple-icons', 'KnisterPeter.vscode-github', 'DotJoshJohnson.xml', 'Dart-Code.dart-code', 'alefragnani.Bookmarks'];
// Support extension storage as well (always the ID of the extension)
extensions.forEach(extension => {
let extensionId: string;
@@ -250,13 +236,29 @@ export class StorageMainService extends Disposable implements IStorageMainServic
}
if (extensionId) {
for (let i = 0; i < wellKnownPublishers.length; i++) {
const publisher = wellKnownPublishers[i];
if (startsWith(extensionId, `${publisher.toLowerCase()}.`)) {
extensionId = `${publisher}${extensionId.substr(publisher.length)}`;
break;
}
}
for (let j = 0; j < wellKnownExtensions.length; j++) {
const wellKnownExtension = wellKnownExtensions[j];
if (extensionId === wellKnownExtension.toLowerCase()) {
extensionId = wellKnownExtension;
break;
}
}
supportedKeys.set(extensionId.toLowerCase(), extensionId);
}
});
return import('vscode-sqlite3').then(sqlite3 => {
return new Promise((resolve, reject) => {
return new Promise<void>((resolve, reject) => {
const handleSuffixKey = (row, key: string, suffix: string) => {
if (endsWith(key, suffix.toLowerCase())) {
const value: string = row.value.toString('utf16le');
@@ -360,10 +362,10 @@ export class StorageMainService extends Disposable implements IStorageMainServic
return this.storage.getBoolean(key, fallbackValue);
}
getInteger(key: string, fallbackValue: number): number;
getInteger(key: string, fallbackValue?: number): number | undefined;
getInteger(key: string, fallbackValue?: number): number | undefined {
return this.storage.getInteger(key, fallbackValue);
getNumber(key: string, fallbackValue: number): number;
getNumber(key: string, fallbackValue?: number): number | undefined;
getNumber(key: string, fallbackValue?: number): number | undefined {
return this.storage.getNumber(key, fallbackValue);
}
store(key: string, value: any): Promise<void> {
@@ -375,21 +377,15 @@ export class StorageMainService extends Disposable implements IStorageMainServic
}
close(): Promise<void> {
this.logService.trace('StorageMainService#close() - begin');
// Signal as event so that clients can still store data
this._onWillSaveState.fire();
// Do it
mark('main:willCloseGlobalStorage');
return this.storage.close().then(() => {
mark('main:didCloseGlobalStorage');
this.logService.trace(`StorageMainService#close() - finished in ${getDuration('main:willCloseGlobalStorage', 'main:didCloseGlobalStorage')}ms`);
});
return this.storage.close();
}
checkIntegrity(full: boolean): Promise<string> {
return this.storage.checkIntegrity(full);
}
}
}

View File

@@ -12,7 +12,7 @@ import { Action } from 'vs/base/common/actions';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { localize } from 'vs/nls';
import { mark, getDuration } from 'vs/base/common/performance';
import { join } from 'path';
import { join } from 'vs/base/common/path';
import { copy, exists, mkdirp, writeFile } from 'vs/base/node/pfs';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWorkspaceInitializationPayload, isWorkspaceIdentifier, isSingleFolderWorkspaceInitializationPayload } from 'vs/platform/workspaces/common/workspaces';
@@ -24,39 +24,20 @@ export class StorageService extends Disposable implements IStorageService {
private static WORKSPACE_STORAGE_NAME = 'state.vscdb';
private static WORKSPACE_META_NAME = 'workspace.json';
private _onDidChangeStorage: Emitter<IWorkspaceStorageChangeEvent> = this._register(new Emitter<IWorkspaceStorageChangeEvent>());
private readonly _onDidChangeStorage: Emitter<IWorkspaceStorageChangeEvent> = this._register(new Emitter<IWorkspaceStorageChangeEvent>());
get onDidChangeStorage(): Event<IWorkspaceStorageChangeEvent> { return this._onDidChangeStorage.event; }
private _onWillSaveState: Emitter<IWillSaveStateEvent> = this._register(new Emitter<IWillSaveStateEvent>());
private readonly _onWillSaveState: Emitter<IWillSaveStateEvent> = this._register(new Emitter<IWillSaveStateEvent>());
get onWillSaveState(): Event<IWillSaveStateEvent> { return this._onWillSaveState.event; }
private _hasErrors = false;
get hasErrors(): boolean { return this._hasErrors; }
private bufferedWorkspaceStorageErrors?: Array<string | Error> = [];
private _onWorkspaceStorageError: Emitter<string | Error> = this._register(new Emitter<string | Error>());
get onWorkspaceStorageError(): Event<string | Error> {
if (Array.isArray(this.bufferedWorkspaceStorageErrors)) {
// todo@ben cleanup after a while
if (this.bufferedWorkspaceStorageErrors.length > 0) {
const bufferedStorageErrors = this.bufferedWorkspaceStorageErrors;
setTimeout(() => {
this._onWorkspaceStorageError.fire(`[startup errors] ${bufferedStorageErrors.join('\n')}`);
}, 0);
}
this.bufferedWorkspaceStorageErrors = undefined;
}
return this._onWorkspaceStorageError.event;
}
private globalStorage: IStorage;
private workspaceStoragePath: string;
private workspaceStorage: IStorage;
private workspaceStorageListener: IDisposable;
private initializePromise: Promise<void>;
constructor(
globalStorageDatabase: IStorageDatabase,
@ILogService private readonly logService: ILogService,
@@ -74,6 +55,14 @@ export class StorageService extends Disposable implements IStorageService {
}
initialize(payload: IWorkspaceInitializationPayload): Promise<void> {
if (!this.initializePromise) {
this.initializePromise = this.doInitialize(payload);
}
return this.initializePromise;
}
private doInitialize(payload: IWorkspaceInitializationPayload): Promise<void> {
return Promise.all([
this.initializeGlobalStorage(),
this.initializeWorkspaceStorage(payload)
@@ -81,22 +70,14 @@ export class StorageService extends Disposable implements IStorageService {
}
private initializeGlobalStorage(): Promise<void> {
mark('willInitGlobalStorage');
return this.globalStorage.init().then(() => {
mark('didInitGlobalStorage');
}, error => {
mark('didInitGlobalStorage');
return Promise.reject(error);
});
return this.globalStorage.init();
}
private initializeWorkspaceStorage(payload: IWorkspaceInitializationPayload): Promise<void> {
// Prepare workspace storage folder for DB
return this.prepareWorkspaceStorageFolder(payload).then(result => {
const useInMemoryStorage = !!this.environmentService.extensionTestsPath; // no storage during extension tests!
const useInMemoryStorage = !!this.environmentService.extensionTestsLocationURI; // no storage during extension tests!
// Create workspace storage and initalize
mark('willInitWorkspaceStorage');
@@ -120,17 +101,7 @@ export class StorageService extends Disposable implements IStorageService {
// Logger for workspace storage
const workspaceLoggingOptions: ISQLiteStorageDatabaseLoggingOptions = {
logTrace: (this.logService.getLevel() === LogLevel.Trace) ? msg => this.logService.trace(msg) : undefined,
logError: error => {
this.logService.error(error);
this._hasErrors = true;
if (Array.isArray(this.bufferedWorkspaceStorageErrors)) {
this.bufferedWorkspaceStorageErrors.push(error);
} else {
this._onWorkspaceStorageError.fire(error);
}
}
logError: error => this.logService.error(error)
};
// Dispose old (if any)
@@ -152,7 +123,7 @@ export class StorageService extends Disposable implements IStorageService {
private prepareWorkspaceStorageFolder(payload: IWorkspaceInitializationPayload): Promise<{ path: string, wasCreated: boolean }> {
const workspaceStorageFolderPath = this.getWorkspaceStorageFolderPath(payload);
return exists(workspaceStorageFolderPath).then(exists => {
return exists(workspaceStorageFolderPath).then<{ path: string, wasCreated: boolean }>(exists => {
if (exists) {
return { path: workspaceStorageFolderPath, wasCreated: false };
}
@@ -199,10 +170,10 @@ export class StorageService extends Disposable implements IStorageService {
return this.getStorage(scope).getBoolean(key, fallbackValue);
}
getInteger(key: string, scope: StorageScope, fallbackValue: number): number;
getInteger(key: string, scope: StorageScope): number | undefined;
getInteger(key: string, scope: StorageScope, fallbackValue?: number): number | undefined {
return this.getStorage(scope).getInteger(key, fallbackValue);
getNumber(key: string, scope: StorageScope, fallbackValue: number): number;
getNumber(key: string, scope: StorageScope): number | undefined;
getNumber(key: string, scope: StorageScope, fallbackValue?: number): number | undefined {
return this.getStorage(scope).getNumber(key, fallbackValue);
}
store(key: string, value: string | boolean | number, scope: StorageScope): void {
@@ -219,14 +190,10 @@ export class StorageService extends Disposable implements IStorageService {
this._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN });
// Do it
mark('willCloseGlobalStorage');
mark('willCloseWorkspaceStorage');
return Promise.all([
this.globalStorage.close().then(() => mark('didCloseGlobalStorage')),
this.workspaceStorage.close().then(() => mark('didCloseWorkspaceStorage'))
]).then(() => {
this.logService.trace(`[storage] closing took ${getDuration('willCloseGlobalStorage', 'didCloseGlobalStorage')}ms global / ${getDuration('willCloseWorkspaceStorage', 'didCloseWorkspaceStorage')}ms workspace`);
});
this.globalStorage.close(),
this.workspaceStorage.close()
]).then(() => undefined);
}
private getStorage(scope: StorageScope): IStorage {
@@ -270,7 +237,7 @@ export class StorageService extends Disposable implements IStorageService {
workspaceItemsParsed.set(key, safeParse(value));
});
console.group(`Storage: Global (integrity: ${result[2]}, load: ${getDuration('main:willInitGlobalStorage', 'main:didInitGlobalStorage')}, path: ${this.environmentService.globalStorageHome})`);
console.group(`Storage: Global (integrity: ${result[2]}, path: ${this.environmentService.globalStorageHome})`);
let globalValues: { key: string, value: string }[] = [];
globalItems.forEach((value, key) => {
globalValues.push({ key, value });