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

@@ -0,0 +1,80 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { flatten } from 'vs/base/common/arrays';
export class Query {
constructor(public value: string, public sortBy: string, public groupBy: string) {
this.value = value.trim();
}
static suggestions(query: string): string[] {
const commands = ['installed', 'outdated', 'enabled', 'disabled', 'builtin', 'recommended', 'sort', 'category', 'tag', 'ext'];
const subcommands = {
'sort': ['installs', 'rating', 'name'],
'category': ['"programming languages"', 'snippets', 'linters', 'themes', 'debuggers', 'formatters', 'keymaps', '"scm providers"', 'other', '"extension packs"', '"language packs"'],
'tag': [''],
'ext': ['']
};
let queryContains = (substr: string) => query.indexOf(substr) > -1;
let hasSort = subcommands.sort.some(subcommand => queryContains(`@sort:${subcommand}`));
let hasCategory = subcommands.category.some(subcommand => queryContains(`@category:${subcommand}`));
return flatten(
commands.map(command => {
if (hasSort && command === 'sort' || hasCategory && command === 'category') {
return [];
}
if (subcommands[command]) {
return subcommands[command].map(subcommand => `@${command}:${subcommand}${subcommand === '' ? '' : ' '}`);
}
else {
return [`@${command} `];
}
}));
}
static parse(value: string): Query {
let sortBy = '';
value = value.replace(/@sort:(\w+)(-\w*)?/g, (match, by: string, order: string) => {
sortBy = by;
return '';
});
let groupBy = '';
value = value.replace(/@group:(\w+)(-\w*)?/g, (match, by: string, order: string) => {
groupBy = by;
return '';
});
return new Query(value, sortBy, groupBy);
}
toString(): string {
let result = this.value;
if (this.sortBy) {
result = `${result}${result ? ' ' : ''}@sort:${this.sortBy}`;
}
if (this.groupBy) {
result = `${result}${result ? ' ' : ''}@group:${this.groupBy}`;
}
return result;
}
isValid(): boolean {
return !/@outdated/.test(this.value);
}
equals(other: Query): boolean {
return this.value === other.value && this.sortBy === other.sortBy;
}
}

View File

@@ -0,0 +1,158 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IViewlet } from 'vs/workbench/common/viewlet';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { Event } from 'vs/base/common/event';
import { IPager } from 'vs/base/common/paging';
import { IQueryOptions, EnablementState, ILocalExtension, IGalleryExtension, IExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IViewContainersRegistry, ViewContainer, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views';
import { Registry } from 'vs/platform/registry/common/platform';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Disposable } from 'vs/base/common/lifecycle';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IExtensionManifest, ExtensionType } from 'vs/platform/extensions/common/extensions';
export const VIEWLET_ID = 'workbench.view.extensions';
export const VIEW_CONTAINER: ViewContainer = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer(VIEWLET_ID);
export const EXTENSIONS_CONFIG = '.azuredatastudio/extensions.json';
export interface IExtensionsViewlet extends IViewlet {
search(text: string): void;
}
export const enum ExtensionState {
Installing,
Installed,
Uninstalling,
Uninstalled
}
export interface IExtension {
type?: ExtensionType;
state: ExtensionState;
name: string;
displayName: string;
identifier: IExtensionIdentifier;
publisher: string;
publisherDisplayName: string;
version: string;
latestVersion: string;
description: string;
url?: string;
// {{SQL CARBON EDIT}}
downloadPage: string;
repository?: string;
iconUrl: string;
iconUrlFallback: string;
licenseUrl?: string;
installCount?: number;
rating?: number;
ratingCount?: number;
outdated: boolean;
enablementState: EnablementState;
dependencies: string[];
extensionPack: string[];
telemetryData: any;
preview: boolean;
getManifest(token: CancellationToken): Promise<IExtensionManifest | null>;
getReadme(token: CancellationToken): Promise<string>;
hasReadme(): boolean;
getChangelog(token: CancellationToken): Promise<string>;
hasChangelog(): boolean;
local?: ILocalExtension;
gallery?: IGalleryExtension;
isMalicious: boolean;
}
export interface IExtensionDependencies {
dependencies: IExtensionDependencies[];
hasDependencies: boolean;
identifier: string;
extension: IExtension;
dependent: IExtensionDependencies | null;
}
export const SERVICE_ID = 'extensionsWorkbenchService';
export const IExtensionsWorkbenchService = createDecorator<IExtensionsWorkbenchService>(SERVICE_ID);
export interface IExtensionsWorkbenchService {
_serviceBrand: any;
onChange: Event<IExtension | undefined>;
local: IExtension[];
queryLocal(): Promise<IExtension[]>;
queryGallery(options?: IQueryOptions): Promise<IPager<IExtension>>;
canInstall(extension: IExtension): boolean;
install(vsix: string): Promise<IExtension>;
install(extension: IExtension, promptToInstallDependencies?: boolean): Promise<IExtension>;
uninstall(extension: IExtension): Promise<void>;
installVersion(extension: IExtension, version: string): Promise<IExtension>;
reinstall(extension: IExtension): Promise<IExtension>;
setEnablement(extensions: IExtension | IExtension[], enablementState: EnablementState): Promise<void>;
loadDependencies(extension: IExtension, token: CancellationToken): Promise<IExtensionDependencies | null>;
open(extension: IExtension, sideByside?: boolean): Promise<any>;
checkForUpdates(): Promise<void>;
allowedBadgeProviders: string[];
}
export const ConfigurationKey = 'extensions';
export const AutoUpdateConfigurationKey = 'extensions.autoUpdate';
export const AutoCheckUpdatesConfigurationKey = 'extensions.autoCheckUpdates';
export const ShowRecommendationsOnlyOnDemandKey = 'extensions.showRecommendationsOnlyOnDemand';
export const CloseExtensionDetailsOnViewChangeKey = 'extensions.closeExtensionDetailsOnViewChange';
// {{SQL CARBON EDIT}}
export const ExtensionsPolicyKey = 'extensions.extensionsPolicy';
export interface IExtensionsConfiguration {
autoUpdate: boolean;
autoCheckUpdates: boolean;
ignoreRecommendations: boolean;
showRecommendationsOnlyOnDemand: boolean;
closeExtensionDetailsOnViewChange: boolean;
// {{SQL CARBON EDIT}}
extensionsPolicy: string;
}
// {{SQL CARBON EDIT}}
export enum ExtensionsPolicy {
allowAll = 'allowAll',
allowNone = 'allowNone',
allowMicrosoft = 'allowMicrosoft'
}
// {{SQL CARBON EDIT}} - End
export interface IExtensionContainer {
extension: IExtension | null;
update(): void;
}
export class ExtensionContainers extends Disposable {
constructor(
private readonly containers: IExtensionContainer[],
@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService
) {
super();
this._register(extensionsWorkbenchService.onChange(this.update, this));
}
set extension(extension: IExtension) {
this.containers.forEach(c => c.extension = extension);
}
private update(extension: IExtension): void {
for (const container of this.containers) {
if (extension && container.extension) {
if (areSameExtensions(container.extension.identifier, extension.identifier)) {
container.extension = extension;
}
} else {
container.update();
}
}
}
}

View File

@@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { localize } from 'vs/nls';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { EXTENSION_IDENTIFIER_PATTERN } from 'vs/platform/extensionManagement/common/extensionManagement';
export const ExtensionsConfigurationSchemaId = 'vscode://schemas/extensions';
export const ExtensionsConfigurationSchema: IJSONSchema = {
id: ExtensionsConfigurationSchemaId,
allowComments: true,
type: 'object',
title: localize('app.extensions.json.title', "Extensions"),
additionalProperties: false,
properties: {
recommendations: {
type: 'array',
description: localize('app.extensions.json.recommendations', "List of extensions which should be recommended for users of this workspace. The identifier of an extension is always '${publisher}.${name}'. For example: 'vscode.csharp'."),
items: {
type: 'string',
pattern: EXTENSION_IDENTIFIER_PATTERN,
errorMessage: localize('app.extension.identifier.errorMessage', "Expected format '${publisher}.${name}'. Example: 'vscode.csharp'.")
},
},
unwantedRecommendations: {
type: 'array',
description: localize('app.extensions.json.unwantedRecommendations', "List of extensions recommended by VS Code that should not be recommended for users of this workspace. The identifier of an extension is always '${publisher}.${name}'. For example: 'vscode.csharp'."),
items: {
type: 'string',
pattern: EXTENSION_IDENTIFIER_PATTERN,
errorMessage: localize('app.extension.identifier.errorMessage', "Expected format '${publisher}.${name}'. Example: 'vscode.csharp'.")
},
},
}
};
export const ExtensionsConfigurationInitialContent: string = [
'{',
'\t// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.',
'\t// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp',
'',
'\t// List of extensions which should be recommended for users of this workspace.',
'\t"recommendations": [',
'\t\t',
'\t],',
'\t// List of extensions recommended by VS Code that should not be recommended for users of this workspace.',
'\t"unwantedRecommendations": [',
'\t\t',
'\t]',
'}'
].join('\n');

View File

@@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { localize } from 'vs/nls';
import { EditorInput } from 'vs/workbench/common/editor';
import { IExtension } from 'vs/workbench/contrib/extensions/common/extensions';
import { URI } from 'vs/base/common/uri';
export class ExtensionsInput extends EditorInput {
static readonly ID = 'workbench.extensions.input2';
get extension(): IExtension { return this._extension; }
constructor(
private _extension: IExtension,
) {
super();
}
getTypeId(): string {
return ExtensionsInput.ID;
}
getName(): string {
return localize('extensionsInputName', "Extension: {0}", this.extension.displayName);
}
matches(other: any): boolean {
if (!(other instanceof ExtensionsInput)) {
return false;
}
const otherExtensionInput = other as ExtensionsInput;
// TODO@joao is this correct?
return this.extension === otherExtensionInput.extension;
}
resolve(): Promise<any> {
return Promise.resolve(null);
}
supportsSplitEditor(): boolean {
return false;
}
getResource(): URI {
return URI.from({
scheme: 'extension',
path: this.extension.identifier.id
});
}
}

View File

@@ -0,0 +1,138 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as arrays from 'vs/base/common/arrays';
import { localize } from 'vs/nls';
import { Event } from 'vs/base/common/event';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IExtensionManagementService, ILocalExtension, IExtensionEnablementService, IExtensionTipsService, IExtensionIdentifier, EnablementState, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { Severity, INotificationService } from 'vs/platform/notification/common/notification';
export interface IExtensionStatus {
identifier: IExtensionIdentifier;
local: ILocalExtension;
globallyEnabled: boolean;
}
export class KeymapExtensions implements IWorkbenchContribution {
private disposables: IDisposable[] = [];
constructor(
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
@IExtensionTipsService private readonly tipsService: IExtensionTipsService,
@ILifecycleService lifecycleService: ILifecycleService,
@INotificationService private readonly notificationService: INotificationService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
) {
this.disposables.push(
lifecycleService.onShutdown(() => this.dispose()),
instantiationService.invokeFunction(onExtensionChanged)((identifiers => {
Promise.all(identifiers.map(identifier => this.checkForOtherKeymaps(identifier)))
.then(undefined, onUnexpectedError);
}))
);
}
private checkForOtherKeymaps(extensionIdentifier: IExtensionIdentifier): Promise<void> {
return this.instantiationService.invokeFunction(getInstalledExtensions).then(extensions => {
const keymaps = extensions.filter(extension => isKeymapExtension(this.tipsService, extension));
const extension = arrays.first(keymaps, extension => areSameExtensions(extension.identifier, extensionIdentifier));
if (extension && extension.globallyEnabled) {
const otherKeymaps = keymaps.filter(extension => !areSameExtensions(extension.identifier, extensionIdentifier) && extension.globallyEnabled);
if (otherKeymaps.length) {
return this.promptForDisablingOtherKeymaps(extension, otherKeymaps);
}
}
return undefined;
});
}
private promptForDisablingOtherKeymaps(newKeymap: IExtensionStatus, oldKeymaps: IExtensionStatus[]): void {
const onPrompt = (confirmed: boolean) => {
const telemetryData: { [key: string]: any; } = {
newKeymap: newKeymap.identifier,
oldKeymaps: oldKeymaps.map(k => k.identifier),
confirmed
};
/* __GDPR__
"disableOtherKeymaps" : {
"newKeymap": { "${inline}": [ "${ExtensionIdentifier}" ] },
"oldKeymaps": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"confirmed" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('disableOtherKeymaps', telemetryData);
if (confirmed) {
this.extensionEnablementService.setEnablement(oldKeymaps.map(keymap => keymap.local), EnablementState.Disabled);
}
};
this.notificationService.prompt(Severity.Info, localize('disableOtherKeymapsConfirmation', "Disable other keymaps ({0}) to avoid conflicts between keybindings?", oldKeymaps.map(k => `'${k.local.manifest.displayName}'`).join(', ')),
[{
label: localize('yes', "Yes"),
run: () => onPrompt(true)
}, {
label: localize('no', "No"),
run: () => onPrompt(false)
}]
);
}
dispose(): void {
this.disposables = dispose(this.disposables);
}
}
export function onExtensionChanged(accessor: ServicesAccessor): Event<IExtensionIdentifier[]> {
const extensionService = accessor.get(IExtensionManagementService);
const extensionEnablementService = accessor.get(IExtensionEnablementService);
const onDidInstallExtension = Event.chain(extensionService.onDidInstallExtension)
.filter(e => e.operation === InstallOperation.Install)
.event;
return Event.debounce<IExtensionIdentifier[], IExtensionIdentifier[]>(Event.any(
Event.chain(Event.any(onDidInstallExtension, extensionService.onDidUninstallExtension))
.map(e => [e.identifier])
.event,
Event.map(extensionEnablementService.onEnablementChanged, extensions => extensions.map(e => e.identifier))
), (result: IExtensionIdentifier[] | undefined, identifiers: IExtensionIdentifier[]) => {
result = result || [];
for (const identifier of identifiers) {
if (result.some(l => !areSameExtensions(l, identifier))) {
result.push(identifier);
}
}
return result;
});
}
export function getInstalledExtensions(accessor: ServicesAccessor): Promise<IExtensionStatus[]> {
const extensionService = accessor.get(IExtensionManagementService);
const extensionEnablementService = accessor.get(IExtensionEnablementService);
return extensionService.getInstalled().then(extensions => {
return extensionEnablementService.getDisabledExtensions()
.then(disabledExtensions => {
return extensions.map(extension => {
return {
identifier: extension.identifier,
local: extension,
globallyEnabled: disabledExtensions.every(disabled => !areSameExtensions(disabled, extension.identifier))
};
});
});
});
}
export function isKeymapExtension(tipsService: IExtensionTipsService, extension: IExtensionStatus): boolean {
const cats = extension.local.manifest.categories;
return cats && cats.indexOf('Keymaps') !== -1 || tipsService.getKeymapRecommendations().some(({ extensionId }) => areSameExtensions({ id: extensionId }, extension.local.identifier));
}