Skip to content

Commit c481f95

Browse files
authored
Fix extension installation from location - check for valid manifest (microsoft#203785)
1 parent 4dcce9b commit c481f95

File tree

3 files changed

+28
-20
lines changed

3 files changed

+28
-20
lines changed

src/vs/platform/extensionManagement/node/extensionManagementService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi
169169
async installFromLocation(location: URI, profileLocation: URI): Promise<ILocalExtension> {
170170
this.logService.trace('ExtensionManagementService#installFromLocation', location.toString());
171171
const local = await this.extensionsScanner.scanUserExtensionAtLocation(location);
172-
if (!local) {
172+
if (!local || !local.manifest.name || !local.manifest.version) {
173173
throw new Error(`Cannot find a valid extension from the location ${location.toString()}`);
174174
}
175175
await this.addExtensionsToProfile([[local, undefined]], profileLocation);

src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -866,22 +866,30 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
866866
run: async (accessor: ServicesAccessor) => {
867867
const extensionManagementService = accessor.get(IWorkbenchExtensionManagementService);
868868
if (isWeb) {
869-
const quickInputService = accessor.get(IQuickInputService);
870-
const disposables = new DisposableStore();
871-
const quickPick = disposables.add(quickInputService.createQuickPick());
872-
quickPick.title = localize('installFromLocation', "Install Extension from Location");
873-
quickPick.customButton = true;
874-
quickPick.customLabel = localize('install button', "Install");
875-
quickPick.placeholder = localize('installFromLocationPlaceHolder', "Location of the web extension");
876-
quickPick.ignoreFocusOut = true;
877-
disposables.add(Event.any(quickPick.onDidAccept, quickPick.onDidCustom)(() => {
878-
quickPick.hide();
879-
if (quickPick.value) {
880-
extensionManagementService.installFromLocation(URI.parse(quickPick.value));
881-
}
882-
}));
883-
disposables.add(quickPick.onDidHide(() => disposables.dispose()));
884-
quickPick.show();
869+
return new Promise<void>((c, e) => {
870+
const quickInputService = accessor.get(IQuickInputService);
871+
const disposables = new DisposableStore();
872+
const quickPick = disposables.add(quickInputService.createQuickPick());
873+
quickPick.title = localize('installFromLocation', "Install Extension from Location");
874+
quickPick.customButton = true;
875+
quickPick.customLabel = localize('install button', "Install");
876+
quickPick.placeholder = localize('installFromLocationPlaceHolder', "Location of the web extension");
877+
quickPick.ignoreFocusOut = true;
878+
disposables.add(Event.any(quickPick.onDidAccept, quickPick.onDidCustom)(async () => {
879+
quickPick.hide();
880+
if (quickPick.value) {
881+
try {
882+
await extensionManagementService.installFromLocation(URI.parse(quickPick.value));
883+
} catch (error) {
884+
e(error);
885+
return;
886+
}
887+
}
888+
c();
889+
}));
890+
disposables.add(quickPick.onDidHide(() => disposables.dispose()));
891+
quickPick.show();
892+
});
885893
} else {
886894
const fileDialogService = accessor.get(IFileDialogService);
887895
const extensionLocation = await fileDialogService.showOpenDialog({
@@ -891,7 +899,7 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
891899
title: localize('installFromLocation', "Install Extension from Location"),
892900
});
893901
if (extensionLocation?.[0]) {
894-
extensionManagementService.installFromLocation(extensionLocation[0]);
902+
await extensionManagementService.installFromLocation(extensionLocation[0]);
895903
}
896904
}
897905
}

src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe
102102
async install(location: URI, options: InstallOptions = {}): Promise<ILocalExtension> {
103103
this.logService.trace('ExtensionManagementService#install', location.toString());
104104
const manifest = await this.webExtensionsScannerService.scanExtensionManifest(location);
105-
if (!manifest) {
106-
throw new Error(`Cannot find packageJSON from the location ${location.toString()}`);
105+
if (!manifest || !manifest.name || !manifest.version) {
106+
throw new Error(`Cannot find a valid extension from the location ${location.toString()}`);
107107
}
108108
const result = await this.installExtensions([{ manifest, extension: location, options }]);
109109
if (result[0]?.local) {

0 commit comments

Comments
 (0)