mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode bead496a613e475819f89f08e9e882b841bc1fe8 (#14883)
* Merge from vscode bead496a613e475819f89f08e9e882b841bc1fe8 * Bump distro * Upgrade GCC to 4.9 due to yarn install errors * Update build image * Fix bootstrap base url * Bump distro * Fix build errors * Update source map file * Disable checkbox for blocking migration issues (#15131) * disable checkbox for blocking issues * wip * disable checkbox fixes * fix strings * Remove duplicate tsec command * Default to off for tab color if settings not present * re-skip failing tests * Fix mocha error * Bump sqlite version & fix notebooks search view * Turn off esbuild warnings * Update esbuild log level * Fix overflowactionbar tests * Fix ts-ignore in dropdown tests * cleanup/fixes * Fix hygiene * Bundle in entire zone.js module * Remove extra constructor param * bump distro for web compile break * bump distro for web compile break v2 * Undo log level change * New distro * Fix integration test scripts * remove the "no yarn.lock changes" workflow * fix scripts v2 * Update unit test scripts * Ensure ads-kerberos2 updates in .vscodeignore * Try fix unit tests * Upload crash reports * remove nogpu * always upload crashes * Use bash script * Consolidate data/ext dir names * Create in tmp directory Co-authored-by: chlafreniere <hichise@gmail.com> Co-authored-by: Christopher Suh <chsuh@microsoft.com> Co-authored-by: chgagnon <chgagnon@microsoft.com>
This commit is contained in:
@@ -11,8 +11,8 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { INotificationService, IPromptChoice, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { createDecorator, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Action2, registerAction2 } from 'vs/platform/actions/common/actions';
|
||||
import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
|
||||
import { ContextKeyEqualsExpr, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
@@ -21,6 +21,7 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
|
||||
// --- bisect service
|
||||
|
||||
@@ -47,21 +48,18 @@ class BisectState {
|
||||
try {
|
||||
interface Raw extends BisectState { }
|
||||
const data: Raw = JSON.parse(raw);
|
||||
return new BisectState(data.extensions, data.low, data.high);
|
||||
return new BisectState(data.extensions, data.low, data.high, data.mid);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
readonly mid: number;
|
||||
|
||||
constructor(
|
||||
readonly extensions: string[],
|
||||
readonly low: number,
|
||||
readonly high: number,
|
||||
) {
|
||||
this.mid = ((low + high) / 2) | 0;
|
||||
}
|
||||
readonly mid: number = ((low + high) / 2) | 0
|
||||
) { }
|
||||
}
|
||||
|
||||
class ExtensionBisectService implements IExtensionBisectService {
|
||||
@@ -76,6 +74,7 @@ class ExtensionBisectService implements IExtensionBisectService {
|
||||
constructor(
|
||||
@ILogService logService: ILogService,
|
||||
@IStorageService private readonly _storageService: IStorageService,
|
||||
@IWorkbenchEnvironmentService private readonly _envService: IWorkbenchEnvironmentService
|
||||
) {
|
||||
const raw = _storageService.get(ExtensionBisectService._storageKey, StorageScope.GLOBAL);
|
||||
this._state = BisectState.fromJSON(raw);
|
||||
@@ -100,18 +99,32 @@ class ExtensionBisectService implements IExtensionBisectService {
|
||||
|
||||
isDisabledByBisect(extension: IExtension): boolean {
|
||||
if (!this._state) {
|
||||
// bisect isn't active
|
||||
return false;
|
||||
}
|
||||
if (this._isRemoteResolver(extension)) {
|
||||
// the current remote resolver extension cannot be disabled
|
||||
return false;
|
||||
}
|
||||
const disabled = this._disabled.get(extension.identifier.id);
|
||||
return disabled ?? false;
|
||||
}
|
||||
|
||||
private _isRemoteResolver(extension: IExtension): boolean {
|
||||
if (extension.manifest.enableProposedApi !== true) {
|
||||
return false;
|
||||
}
|
||||
const idx = this._envService.remoteAuthority?.indexOf('+');
|
||||
const activationEvent = `onResolveRemoteAuthority:${this._envService.remoteAuthority?.substr(0, idx)}`;
|
||||
return Boolean(extension.manifest.activationEvents?.find(e => e === activationEvent));
|
||||
}
|
||||
|
||||
async start(extensions: ILocalExtension[]): Promise<void> {
|
||||
if (this._state) {
|
||||
throw new Error('invalid state');
|
||||
}
|
||||
const extensionIds = extensions.map(ext => ext.identifier.id);
|
||||
const newState = new BisectState(extensionIds, 0, extensionIds.length);
|
||||
const newState = new BisectState(extensionIds, 0, extensionIds.length, 0);
|
||||
this._storageService.store(ExtensionBisectService._storageKey, JSON.stringify(newState), StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
await this._storageService.flush();
|
||||
}
|
||||
@@ -120,6 +133,10 @@ class ExtensionBisectService implements IExtensionBisectService {
|
||||
if (!this._state) {
|
||||
throw new Error('invalid state');
|
||||
}
|
||||
// check if bad when all extensions are disabled
|
||||
if (seeingBad && this._state.mid === 0 && this._state.high === this._state.extensions.length) {
|
||||
return { bad: true, id: '' };
|
||||
}
|
||||
// check if there is only one left
|
||||
if (this._state.low === this._state.high - 1) {
|
||||
await this.reset();
|
||||
@@ -196,10 +213,16 @@ registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'extension.bisect.start',
|
||||
title: localize('title.start', "Start Extension Bisect"),
|
||||
title: { value: localize('title.start', "Start Extension Bisect"), original: 'Start Extension Bisect' },
|
||||
category: localize('help', "Help"),
|
||||
f1: true,
|
||||
precondition: ExtensionBisectUi.ctxIsBisectActive.negate()
|
||||
precondition: ExtensionBisectUi.ctxIsBisectActive.negate(),
|
||||
menu: {
|
||||
id: MenuId.ViewContainerTitle,
|
||||
when: ContextKeyEqualsExpr.create('viewContainer', 'workbench.view.extensions'),
|
||||
group: '2_enablement',
|
||||
order: 3
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -215,7 +238,7 @@ registerAction2(class extends Action2 {
|
||||
|
||||
const res = await dialogService.confirm({
|
||||
message: localize('msg.start', "Extension Bisect"),
|
||||
detail: localize('detail.start', "Extension Bisect will use binary search to find an extension that causes a problem. During the process the window reloads repeatedly (~{0} times). Each time you must confirm if you are still seeing problems.", 1 + Math.log2(extensions.length) | 0),
|
||||
detail: localize('detail.start', "Extension Bisect will use binary search to find an extension that causes a problem. During the process the window reloads repeatedly (~{0} times). Each time you must confirm if you are still seeing problems.", 2 + Math.log2(extensions.length) | 0),
|
||||
primaryButton: localize('msg2', "Start Extension Bisect")
|
||||
});
|
||||
|
||||
@@ -249,7 +272,11 @@ registerAction2(class extends Action2 {
|
||||
return;
|
||||
}
|
||||
if (seeingBad === undefined) {
|
||||
seeingBad = await this._checkForBad(dialogService);
|
||||
const goodBadStopCancel = await this._checkForBad(dialogService, bisectService);
|
||||
if (goodBadStopCancel === null) {
|
||||
return;
|
||||
}
|
||||
seeingBad = goodBadStopCancel;
|
||||
}
|
||||
if (seeingBad === undefined) {
|
||||
await bisectService.reset();
|
||||
@@ -265,7 +292,7 @@ registerAction2(class extends Action2 {
|
||||
if (done.bad) {
|
||||
// DONE but nothing found
|
||||
await dialogService.show(Severity.Info, localize('done.msg', "Extension Bisect"), [], {
|
||||
detail: localize('done.detail2', "Extension Bisect is done but no extension has been identified. This might be a problem with {0}", productService.nameShort)
|
||||
detail: localize('done.detail2', "Extension Bisect is done but no extension has been identified. This might be a problem with {0}.", productService.nameShort)
|
||||
});
|
||||
|
||||
} else {
|
||||
@@ -290,21 +317,23 @@ registerAction2(class extends Action2 {
|
||||
hostService.reload();
|
||||
}
|
||||
|
||||
private async _checkForBad(dialogService: IDialogService) {
|
||||
private async _checkForBad(dialogService: IDialogService, bisectService: IExtensionBisectService): Promise<boolean | undefined | null> {
|
||||
const options = {
|
||||
cancelId: 2,
|
||||
detail: localize('detail.next', "Are you still seeing the problem for which you have started extension bisect?")
|
||||
cancelId: 3,
|
||||
detail: localize('bisect', "Extension Bisect is active and has disabled {0} extensions. Check if you can still reproduce the problem and proceed by selecting from these options.", bisectService.disabledCount),
|
||||
};
|
||||
const res = await dialogService.show(
|
||||
Severity.Info,
|
||||
localize('msg.next', "Extension Bisect"),
|
||||
[localize('next.good', "Good now"), localize('next.bad', "This is bad"), localize('next.stop', "Stop Bisect")],
|
||||
[localize('next.good', "Good now"), localize('next.bad', "This is bad"), localize('next.stop', "Stop Bisect"), localize('next.cancel', "Cancel")],
|
||||
options
|
||||
);
|
||||
if (res.choice === options.cancelId) {
|
||||
return undefined;
|
||||
switch (res.choice) {
|
||||
case 0: return false; //good now
|
||||
case 1: return true; //bad
|
||||
case 2: return undefined; //stop
|
||||
}
|
||||
return res.choice === 1;
|
||||
return null; //cancel
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecyc
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IExtensionBisectService } from 'vs/workbench/services/extensionManagement/browser/extensionBisect';
|
||||
import { Promises } from 'vs/base/common/async';
|
||||
|
||||
const SOURCE = 'IWorkbenchExtensionEnablementService';
|
||||
|
||||
@@ -79,10 +80,10 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
|
||||
|
||||
getEnablementState(extension: IExtension): EnablementState {
|
||||
if (this.extensionBisectService.isDisabledByBisect(extension)) {
|
||||
return EnablementState.DisabledByEnvironemt;
|
||||
return EnablementState.DisabledByEnvironment;
|
||||
}
|
||||
if (this._isDisabledInEnv(extension)) {
|
||||
return EnablementState.DisabledByEnvironemt;
|
||||
return EnablementState.DisabledByEnvironment;
|
||||
}
|
||||
if (this._isDisabledByExtensionKind(extension)) {
|
||||
return EnablementState.DisabledByExtensionKind;
|
||||
@@ -97,7 +98,7 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
|
||||
return false;
|
||||
}
|
||||
const enablementState = this.getEnablementState(extension);
|
||||
if (enablementState === EnablementState.DisabledByEnvironemt || enablementState === EnablementState.DisabledByExtensionKind) {
|
||||
if (enablementState === EnablementState.DisabledByEnvironment || enablementState === EnablementState.DisabledByExtensionKind) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -146,7 +147,7 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
|
||||
}
|
||||
}
|
||||
|
||||
const result = await Promise.all(extensions.map(e => this._setEnablement(e, newState)));
|
||||
const result = await Promises.settled(extensions.map(e => this._setEnablement(e, newState)));
|
||||
const changedExtensions = extensions.filter((e, index) => result[index]);
|
||||
if (changedExtensions.length) {
|
||||
this._onEnablementChanged.fire(changedExtensions);
|
||||
@@ -215,14 +216,16 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
|
||||
}
|
||||
}
|
||||
if (extensionKind === 'web') {
|
||||
const enableLocalWebWorker = this.configurationService.getValue<boolean>(webWorkerExtHostConfig);
|
||||
if (enableLocalWebWorker) {
|
||||
// Web extensions are enabled on all configurations
|
||||
return false;
|
||||
}
|
||||
if (this.extensionManagementServerService.localExtensionManagementServer === null) {
|
||||
// Web extensions run only in the web
|
||||
return false;
|
||||
if (this.extensionManagementServerService.webExtensionManagementServer) {
|
||||
if (server === this.extensionManagementServerService.webExtensionManagementServer) {
|
||||
return false;
|
||||
}
|
||||
} else if (server === this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
const enableLocalWebWorker = this.configurationService.getValue<boolean>(webWorkerExtHostConfig);
|
||||
if (enableLocalWebWorker) {
|
||||
// Web extensions are enabled on all configurations
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ export interface IWorkbenchExtensioManagementService extends IExtensionManagemen
|
||||
|
||||
export const enum EnablementState {
|
||||
DisabledByExtensionKind,
|
||||
DisabledByEnvironemt,
|
||||
DisabledByEnvironment,
|
||||
DisabledGlobally,
|
||||
DisabledWorkspace,
|
||||
EnabledGlobally,
|
||||
@@ -127,7 +127,7 @@ export interface IWebExtensionsScannerService {
|
||||
scanExtensions(type?: ExtensionType): Promise<IScannedExtension[]>;
|
||||
scanAndTranslateExtensions(type?: ExtensionType): Promise<ITranslatedScannedExtension[]>;
|
||||
scanAndTranslateSingleExtension(extensionLocation: URI, extensionType: ExtensionType): Promise<ITranslatedScannedExtension | null>;
|
||||
canAddExtension(galleryExtension: IGalleryExtension): Promise<boolean>;
|
||||
canAddExtension(galleryExtension: IGalleryExtension): boolean;
|
||||
addExtension(galleryExtension: IGalleryExtension): Promise<IScannedExtension>;
|
||||
removeExtension(identifier: IExtensionIdentifier, version?: string): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { canceled } from 'vs/base/common/errors';
|
||||
import { IUserDataAutoSyncEnablementService, IUserDataSyncResourceEnablementService, SyncResource } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { Promises } from 'vs/base/common/async';
|
||||
|
||||
export class ExtensionManagementService extends Disposable implements IWorkbenchExtensioManagementService {
|
||||
|
||||
@@ -160,7 +161,7 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
|
||||
}
|
||||
|
||||
unzip(zipLocation: URI): Promise<IExtensionIdentifier> {
|
||||
return Promise.all(this.servers
|
||||
return Promises.settled(this.servers
|
||||
// Filter out web server
|
||||
.filter(server => server !== this.extensionManagementServerService.webExtensionManagementServer)
|
||||
.map(({ extensionManagementService }) => extensionManagementService.unzip(zipLocation))).then(([extensionIdentifier]) => extensionIdentifier);
|
||||
@@ -171,7 +172,7 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
|
||||
const manifest = await this.getManifest(vsix);
|
||||
if (isLanguagePackExtension(manifest)) {
|
||||
// Install on both servers
|
||||
const [local] = await Promise.all([this.extensionManagementServerService.localExtensionManagementServer, this.extensionManagementServerService.remoteExtensionManagementServer].map(server => this.installVSIX(vsix, server)));
|
||||
const [local] = await Promises.settled([this.extensionManagementServerService.localExtensionManagementServer, this.extensionManagementServerService.remoteExtensionManagementServer].map(server => this.installVSIX(vsix, server)));
|
||||
return local;
|
||||
}
|
||||
if (prefersExecuteOnUI(manifest, this.productService, this.configurationService)) {
|
||||
@@ -228,7 +229,7 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
|
||||
servers.push(server);
|
||||
}
|
||||
|
||||
return Promise.all(servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(([local]) => local);
|
||||
return Promises.settled(servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(([local]) => local);
|
||||
}
|
||||
|
||||
async installExtensions(extensions: IGalleryExtension[], installOptions?: InstallOptions): Promise<ILocalExtension[]> {
|
||||
@@ -236,7 +237,7 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
|
||||
const isMachineScoped = await this.hasToFlagExtensionsMachineScoped(extensions);
|
||||
installOptions = { isMachineScoped, isBuiltin: false };
|
||||
}
|
||||
return Promise.all(extensions.map(extension => this.installFromGallery(extension, installOptions)));
|
||||
return Promises.settled(extensions.map(extension => this.installFromGallery(extension, installOptions)));
|
||||
}
|
||||
|
||||
async installFromGallery(gallery: IGalleryExtension, installOptions?: InstallOptions): Promise<ILocalExtension> {
|
||||
@@ -263,21 +264,15 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
|
||||
const isMachineScoped = await this.hasToFlagExtensionsMachineScoped([gallery]);
|
||||
installOptions = { isMachineScoped, isBuiltin: false };
|
||||
}
|
||||
if (!installOptions.isMachineScoped) {
|
||||
if (!installOptions.isMachineScoped && this.isExtensionsSyncEnabled()) {
|
||||
if (this.extensionManagementServerService.localExtensionManagementServer && !servers.includes(this.extensionManagementServerService.localExtensionManagementServer)) {
|
||||
servers.push(this.extensionManagementServerService.localExtensionManagementServer);
|
||||
}
|
||||
}
|
||||
return Promise.all(servers.map(server => server.extensionManagementService.installFromGallery(gallery, installOptions))).then(([local]) => local);
|
||||
return Promises.settled(servers.map(server => server.extensionManagementService.installFromGallery(gallery, installOptions))).then(([local]) => local);
|
||||
}
|
||||
|
||||
if (this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
const error = new Error(localize('cannot be installed', "Cannot install '{0}' because this extension has defined that it cannot run on the remote server.", gallery.displayName || gallery.name));
|
||||
error.name = INSTALL_ERROR_NOT_SUPPORTED;
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
const error = new Error(localize('cannot be installed on web', "Cannot install '{0}' because this extension has defined that it cannot run on the web server.", gallery.displayName || gallery.name));
|
||||
const error = new Error(localize('cannot be installed', "Cannot install the '{0}' extension because it is declared to not run in this setup.", gallery.displayName || gallery.name));
|
||||
error.name = INSTALL_ERROR_NOT_SUPPORTED;
|
||||
return Promise.reject(error);
|
||||
}
|
||||
@@ -306,32 +301,36 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
|
||||
return this.extensionManagementServerService.localExtensionManagementServer;
|
||||
}
|
||||
|
||||
private isExtensionsSyncEnabled(): boolean {
|
||||
return this.userDataAutoSyncEnablementService.isEnabled() && this.userDataSyncResourceEnablementService.isResourceEnabled(SyncResource.Extensions);
|
||||
}
|
||||
|
||||
private async hasToFlagExtensionsMachineScoped(extensions: IGalleryExtension[]): Promise<boolean> {
|
||||
if (!this.userDataAutoSyncEnablementService.isEnabled() || !this.userDataSyncResourceEnablementService.isResourceEnabled(SyncResource.Extensions)) {
|
||||
return false;
|
||||
}
|
||||
const result = await this.dialogService.show(
|
||||
Severity.Info,
|
||||
extensions.length === 1 ? localize('install extension', "Install Extension") : localize('install extensions', "Install Extensions"),
|
||||
[
|
||||
localize('install', "Install"),
|
||||
localize('install and do no sync', "Install (Do not sync)"),
|
||||
localize('cancel', "Cancel"),
|
||||
],
|
||||
{
|
||||
cancelId: 2,
|
||||
detail: extensions.length === 1
|
||||
? localize('install single extension', "Would you like to install and synchronize '{0}' extension across your devices?", extensions[0].displayName)
|
||||
: localize('install multiple extensions', "Would you like to install and synchronize extensions across your devices?")
|
||||
if (this.isExtensionsSyncEnabled()) {
|
||||
const result = await this.dialogService.show(
|
||||
Severity.Info,
|
||||
extensions.length === 1 ? localize('install extension', "Install Extension") : localize('install extensions', "Install Extensions"),
|
||||
[
|
||||
localize('install', "Install"),
|
||||
localize('install and do no sync', "Install (Do not sync)"),
|
||||
localize('cancel', "Cancel"),
|
||||
],
|
||||
{
|
||||
cancelId: 2,
|
||||
detail: extensions.length === 1
|
||||
? localize('install single extension', "Would you like to install and synchronize '{0}' extension across your devices?", extensions[0].displayName)
|
||||
: localize('install multiple extensions', "Would you like to install and synchronize extensions across your devices?")
|
||||
}
|
||||
);
|
||||
switch (result.choice) {
|
||||
case 0:
|
||||
return false;
|
||||
case 1:
|
||||
return true;
|
||||
}
|
||||
);
|
||||
switch (result.choice) {
|
||||
case 0:
|
||||
return false;
|
||||
case 1:
|
||||
return true;
|
||||
throw canceled();
|
||||
}
|
||||
throw canceled();
|
||||
return false;
|
||||
}
|
||||
|
||||
getExtensionsReport(): Promise<IReportedExtension[]> {
|
||||
|
||||
@@ -238,12 +238,12 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten
|
||||
};
|
||||
}
|
||||
|
||||
async canAddExtension(galleryExtension: IGalleryExtension): Promise<boolean> {
|
||||
canAddExtension(galleryExtension: IGalleryExtension): boolean {
|
||||
return !!galleryExtension.properties.webExtension && !!galleryExtension.webResource;
|
||||
}
|
||||
|
||||
async addExtension(galleryExtension: IGalleryExtension): Promise<IScannedExtension> {
|
||||
if (!(await this.canAddExtension(galleryExtension))) {
|
||||
if (!this.canAddExtension(galleryExtension)) {
|
||||
const error = new Error(localize('cannot be installed', "Cannot install '{0}' because this extension is not a web extension.", galleryExtension.displayName || galleryExtension.name));
|
||||
error.name = INSTALL_ERROR_NOT_SUPPORTED;
|
||||
throw error;
|
||||
|
||||
@@ -21,6 +21,7 @@ import { joinPath } from 'vs/base/common/resources';
|
||||
import { WebRemoteExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/remoteExtensionManagementService';
|
||||
import { IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService';
|
||||
import { Promises } from 'vs/base/common/async';
|
||||
|
||||
export class NativeRemoteExtensionManagementService extends WebRemoteExtensionManagementService implements IExtensionManagementService {
|
||||
|
||||
@@ -82,7 +83,7 @@ export class NativeRemoteExtensionManagementService extends WebRemoteExtensionMa
|
||||
const manifest = await this.galleryService.getManifest(compatible, CancellationToken.None);
|
||||
if (manifest) {
|
||||
const workspaceExtensions = await this.getAllWorkspaceDependenciesAndPackedExtensions(manifest, CancellationToken.None);
|
||||
await Promise.all(workspaceExtensions.map(e => this.downloadAndInstall(e, installed)));
|
||||
await Promises.settled(workspaceExtensions.map(e => this.downloadAndInstall(e, installed)));
|
||||
}
|
||||
return this.downloadAndInstall(extension, installed);
|
||||
}
|
||||
@@ -97,7 +98,7 @@ export class NativeRemoteExtensionManagementService extends WebRemoteExtensionMa
|
||||
const uiExtensions = await this.getAllUIDependenciesAndPackedExtensions(local.manifest, CancellationToken.None);
|
||||
const installed = await this.localExtensionManagementService.getInstalled();
|
||||
const toInstall = uiExtensions.filter(e => installed.every(i => !areSameExtensions(i.identifier, e.identifier)));
|
||||
await Promise.all(toInstall.map(d => this.localExtensionManagementService.installFromGallery(d)));
|
||||
await Promises.settled(toInstall.map(d => this.localExtensionManagementService.installFromGallery(d)));
|
||||
}
|
||||
|
||||
private async getAllUIDependenciesAndPackedExtensions(manifest: IExtensionManifest, token: CancellationToken): Promise<IGalleryExtension[]> {
|
||||
|
||||
@@ -458,7 +458,7 @@ suite('ExtensionEnablementService Test', () => {
|
||||
instantiationService.stub(IExtensionManagementService, { onDidUninstallExtension: didUninstallEvent.event, getInstalled: () => Promise.resolve([extension, aLocalExtension('pub.b')]) } as IExtensionManagementService);
|
||||
testObject = new TestExtensionEnablementService(instantiationService);
|
||||
assert.ok(!testObject.isEnabled(extension));
|
||||
assert.deepEqual(testObject.getEnablementState(extension), EnablementState.DisabledByEnvironemt);
|
||||
assert.deepEqual(testObject.getEnablementState(extension), EnablementState.DisabledByEnvironment);
|
||||
});
|
||||
|
||||
test('test local workspace extension is disabled by kind', async () => {
|
||||
@@ -545,36 +545,48 @@ suite('ExtensionEnablementService Test', () => {
|
||||
assert.equal(testObject.canChangeEnablement(localWorkspaceExtension), true);
|
||||
});
|
||||
|
||||
test('test web extension on local server is disabled by kind', async () => {
|
||||
test('test web extension on local server is disabled by kind when web worker is not enabled', async () => {
|
||||
instantiationService.stub(IExtensionManagementServerService, aMultiExtensionManagementServerService(instantiationService));
|
||||
const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`) });
|
||||
(<TestConfigurationService>instantiationService.get(IConfigurationService)).setUserConfiguration('extensions', { webWorker: false });
|
||||
testObject = new TestExtensionEnablementService(instantiationService);
|
||||
assert.ok(!testObject.isEnabled(localWorkspaceExtension));
|
||||
assert.equal(testObject.isEnabled(localWorkspaceExtension), false);
|
||||
assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.DisabledByExtensionKind);
|
||||
});
|
||||
|
||||
test('test web extension on remote server is not disabled by kind when there is no local server', async () => {
|
||||
instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(null, anExtensionManagementServer('vscode-remote', instantiationService), anExtensionManagementServer('web', instantiationService)));
|
||||
const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
|
||||
test('test web extension on local server is not disabled by kind when web worker is enabled', async () => {
|
||||
instantiationService.stub(IExtensionManagementServerService, aMultiExtensionManagementServerService(instantiationService));
|
||||
const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`) });
|
||||
(<TestConfigurationService>instantiationService.get(IConfigurationService)).setUserConfiguration('extensions', { webWorker: true });
|
||||
testObject = new TestExtensionEnablementService(instantiationService);
|
||||
assert.ok(testObject.isEnabled(localWorkspaceExtension));
|
||||
assert.equal(testObject.isEnabled(localWorkspaceExtension), true);
|
||||
assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.EnabledGlobally);
|
||||
});
|
||||
|
||||
test('test web extension with no server is not disabled by kind when there is no local server', async () => {
|
||||
instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(null, anExtensionManagementServer('vscode-remote', instantiationService), anExtensionManagementServer('web', instantiationService)));
|
||||
const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: Schemas.https }) });
|
||||
test('test web extension on remote server is disabled by kind when web worker is not enabled', async () => {
|
||||
instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(anExtensionManagementServer('vscode-local', instantiationService), anExtensionManagementServer('vscode-remote', instantiationService), anExtensionManagementServer('web', instantiationService)));
|
||||
const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: 'vscode-remote' }) });
|
||||
(<TestConfigurationService>instantiationService.get(IConfigurationService)).setUserConfiguration('extensions', { webWorker: false });
|
||||
testObject = new TestExtensionEnablementService(instantiationService);
|
||||
assert.ok(testObject.isEnabled(localWorkspaceExtension));
|
||||
assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.EnabledGlobally);
|
||||
assert.equal(testObject.isEnabled(localWorkspaceExtension), false);
|
||||
assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.DisabledByExtensionKind);
|
||||
});
|
||||
|
||||
test('test web extension with no server is not disabled by kind when there is no local and remote server', async () => {
|
||||
instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(null, null, anExtensionManagementServer('web', instantiationService)));
|
||||
const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: Schemas.https }) });
|
||||
test('test web extension on remote server is disabled by kind when web worker is enabled', async () => {
|
||||
instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(anExtensionManagementServer('vscode-local', instantiationService), anExtensionManagementServer('vscode-remote', instantiationService), anExtensionManagementServer('web', instantiationService)));
|
||||
const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: 'vscode-remote' }) });
|
||||
(<TestConfigurationService>instantiationService.get(IConfigurationService)).setUserConfiguration('extensions', { webWorker: true });
|
||||
testObject = new TestExtensionEnablementService(instantiationService);
|
||||
assert.ok(testObject.isEnabled(localWorkspaceExtension));
|
||||
assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.EnabledGlobally);
|
||||
assert.equal(testObject.isEnabled(localWorkspaceExtension), false);
|
||||
assert.deepEqual(testObject.getEnablementState(localWorkspaceExtension), EnablementState.DisabledByExtensionKind);
|
||||
});
|
||||
|
||||
test('test web extension on web server is not disabled by kind', async () => {
|
||||
instantiationService.stub(IExtensionManagementServerService, anExtensionManagementServerService(anExtensionManagementServer('vscode-local', instantiationService), anExtensionManagementServer('vscode-remote', instantiationService), anExtensionManagementServer('web', instantiationService)));
|
||||
const webExtension = aLocalExtension2('pub.a', { extensionKind: ['web'] }, { location: URI.file(`pub.a`).with({ scheme: 'web' }) });
|
||||
testObject = new TestExtensionEnablementService(instantiationService);
|
||||
assert.equal(testObject.isEnabled(webExtension), true);
|
||||
assert.deepEqual(testObject.getEnablementState(webExtension), EnablementState.EnabledGlobally);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -598,7 +610,7 @@ function anExtensionManagementServerService(localExtensionManagementServer: IExt
|
||||
_serviceBrand: undefined,
|
||||
localExtensionManagementServer,
|
||||
remoteExtensionManagementServer,
|
||||
webExtensionManagementServer: null,
|
||||
webExtensionManagementServer,
|
||||
getExtensionManagementServer: (extension: IExtension) => {
|
||||
if (extension.location.scheme === Schemas.file) {
|
||||
return localExtensionManagementServer;
|
||||
|
||||
Reference in New Issue
Block a user