mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-13 15:35:20 +01:00
Merge branch 'master' into dbaeumer/TS2.0
This commit is contained in:
@@ -38,7 +38,8 @@ const nodeModules = ['electron', 'original-fs']
|
||||
// Build
|
||||
|
||||
const builtInExtensions = [
|
||||
{ name: 'ms-vscode.node-debug', version: '1.6.2' }
|
||||
{ name: 'ms-vscode.node-debug', version: '1.6.5' },
|
||||
{ name: 'ms-vscode.node-debug2', version: '0.0.1' }
|
||||
];
|
||||
|
||||
const vscodeEntryPoints = _.flatten([
|
||||
|
||||
@@ -151,14 +151,14 @@ gulp.task('clean-vscode-linux-arm-rpm', util.rimraf('.build/linux/rpm/armhf'));
|
||||
|
||||
gulp.task('vscode-linux-ia32-prepare-deb', ['clean-vscode-linux-ia32-deb', 'vscode-linux-ia32-min'], prepareDebPackage('ia32'));
|
||||
gulp.task('vscode-linux-x64-prepare-deb', ['clean-vscode-linux-x64-deb', 'vscode-linux-x64-min'], prepareDebPackage('x64'));
|
||||
gulp.task('vscode-linux-arm-prepare-deb', ['clean-vscode-linux-arm-deb', 'vscode-linux-arm-min'], prepareDebPackage('armhf'));
|
||||
gulp.task('vscode-linux-arm-prepare-deb', ['clean-vscode-linux-arm-deb', 'vscode-linux-arm-min'], prepareDebPackage('arm'));
|
||||
gulp.task('vscode-linux-ia32-build-deb', ['vscode-linux-ia32-prepare-deb'], buildDebPackage('ia32'));
|
||||
gulp.task('vscode-linux-x64-build-deb', ['vscode-linux-x64-prepare-deb'], buildDebPackage('x64'));
|
||||
gulp.task('vscode-linux-arm-build-deb', ['vscode-linux-arm-prepare-deb'], buildDebPackage('armhf'));
|
||||
gulp.task('vscode-linux-arm-build-deb', ['vscode-linux-arm-prepare-deb'], buildDebPackage('arm'));
|
||||
|
||||
gulp.task('vscode-linux-ia32-prepare-rpm', ['clean-vscode-linux-ia32-rpm', 'vscode-linux-ia32-min'], prepareRpmPackage('ia32'));
|
||||
gulp.task('vscode-linux-x64-prepare-rpm', ['clean-vscode-linux-x64-rpm', 'vscode-linux-x64-min'], prepareRpmPackage('x64'));
|
||||
gulp.task('vscode-linux-arm-prepare-rpm', ['clean-vscode-linux-arm-rpm', 'vscode-linux-arm-min'], prepareRpmPackage('armhf'));
|
||||
gulp.task('vscode-linux-arm-prepare-rpm', ['clean-vscode-linux-arm-rpm', 'vscode-linux-arm-min'], prepareRpmPackage('arm'));
|
||||
gulp.task('vscode-linux-ia32-build-rpm', ['vscode-linux-ia32-prepare-rpm'], buildRpmPackage('ia32'));
|
||||
gulp.task('vscode-linux-x64-build-rpm', ['vscode-linux-x64-prepare-rpm'], buildRpmPackage('x64'));
|
||||
gulp.task('vscode-linux-arm-build-rpm', ['vscode-linux-arm-prepare-rpm'], buildRpmPackage('armhf'));
|
||||
gulp.task('vscode-linux-arm-build-rpm', ['vscode-linux-arm-prepare-rpm'], buildRpmPackage('arm'));
|
||||
|
||||
Binary file not shown.
@@ -6,7 +6,6 @@
|
||||
'use strict';
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import * as fs from 'original-fs';
|
||||
import { app, ipcMain as ipc } from 'electron';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
@@ -39,11 +38,15 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
||||
import { ConfigurationService } from 'vs/platform/configuration/node/configurationService';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
import { RequestService } from 'vs/platform/request/node/requestService';
|
||||
import * as cp from 'child_process';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { getPathLabel } from 'vs/base/common/labels';
|
||||
import { URLChannel } from 'vs/platform/url/common/urlIpc';
|
||||
import { URLService } from 'vs/platform/url/electron-main/urlService';
|
||||
|
||||
import * as fs from 'original-fs';
|
||||
import * as cp from 'child_process';
|
||||
import * as path from 'path';
|
||||
|
||||
function quit(accessor: ServicesAccessor, error?: Error);
|
||||
function quit(accessor: ServicesAccessor, message?: string);
|
||||
function quit(accessor: ServicesAccessor, arg?: any) {
|
||||
@@ -193,25 +196,54 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: IProce
|
||||
|
||||
// Install JumpList on Windows
|
||||
if (platform.isWindows) {
|
||||
app.setJumpList([
|
||||
{
|
||||
type: 'tasks',
|
||||
items: [
|
||||
{
|
||||
const jumpList: Electron.JumpListCategory[] = [];
|
||||
|
||||
// Tasks
|
||||
jumpList.push({
|
||||
type: 'tasks',
|
||||
items: [
|
||||
{
|
||||
type: 'task',
|
||||
title: nls.localize('newWindow', "New Window"),
|
||||
description: nls.localize('newWindowDesc', "Opens a new window"),
|
||||
program: process.execPath,
|
||||
args: '-n', // force new window
|
||||
iconPath: process.execPath,
|
||||
iconIndex: 0
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Recent Folders
|
||||
const folders = windowsService.getRecentPathsList().folders;
|
||||
if (folders.length > 0) {
|
||||
jumpList.push({
|
||||
type: 'custom',
|
||||
name: 'Recent Folders',
|
||||
items: windowsService.getRecentPathsList().folders.slice(0, 7 /* limit number of entries here */).map(folder => {
|
||||
return <Electron.JumpListItem>{
|
||||
type: 'task',
|
||||
title: nls.localize('newWindow', "New Window"),
|
||||
description: nls.localize('newWindowDesc', "Opens a new window"),
|
||||
title: getPathLabel(folder),
|
||||
description: nls.localize('folderDesc', "{0} {1}", path.basename(folder), getPathLabel(path.dirname(folder))),
|
||||
program: process.execPath,
|
||||
args: '-n', // force new window
|
||||
args: folder, // open folder,
|
||||
iconPath: process.execPath,
|
||||
iconIndex: 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'recent' // this enables to show files in the "recent" category
|
||||
}
|
||||
]);
|
||||
};
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Recent
|
||||
jumpList.push({
|
||||
type: 'recent' // this enables to show files in the "recent" category
|
||||
});
|
||||
|
||||
try {
|
||||
app.setJumpList(jumpList);
|
||||
} catch (error) {
|
||||
logService.log('#setJumpList', error); // since setJumpList is relatively new API, make sure to guard for errors
|
||||
}
|
||||
}
|
||||
|
||||
// Setup auto update
|
||||
|
||||
@@ -103,6 +103,10 @@ export interface IExtensionIdentity {
|
||||
publisher: string;
|
||||
}
|
||||
|
||||
export interface IGalleryExtensionProperties {
|
||||
dependencies?: string[];
|
||||
}
|
||||
|
||||
export interface IGalleryExtensionAssets {
|
||||
manifest: string;
|
||||
readme: string;
|
||||
@@ -126,6 +130,7 @@ export interface IGalleryExtension {
|
||||
rating: number;
|
||||
ratingCount: number;
|
||||
assets: IGalleryExtensionAssets;
|
||||
properties: IGalleryExtensionProperties;
|
||||
downloadHeaders: { [key: string]: string; };
|
||||
}
|
||||
|
||||
@@ -184,6 +189,8 @@ export interface IExtensionGalleryService {
|
||||
query(options?: IQueryOptions): TPromise<IPager<IGalleryExtension>>;
|
||||
download(extension: IGalleryExtension): TPromise<string>;
|
||||
getAsset(url: string): TPromise<IRequestContext>;
|
||||
loadCompatibleVersion(extension: IGalleryExtension): TPromise<IGalleryExtension>;
|
||||
getAllDependencies(extension: IGalleryExtension): TPromise<IGalleryExtension[]>;
|
||||
}
|
||||
|
||||
export interface InstallExtensionEvent {
|
||||
|
||||
@@ -7,6 +7,8 @@ import { localize } from 'vs/nls';
|
||||
import { tmpdir } from 'os';
|
||||
import * as path from 'path';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { distinct } from 'vs/base/common/arrays';
|
||||
import { ArraySet } from 'vs/base/common/set';
|
||||
import { IGalleryExtension, IExtensionGalleryService, IQueryOptions, SortBy, SortOrder, IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { getGalleryExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionTelemetry';
|
||||
import { isUndefined } from 'vs/base/common/types';
|
||||
@@ -26,11 +28,17 @@ interface IRawGalleryExtensionFile {
|
||||
source: string;
|
||||
}
|
||||
|
||||
interface IRawGalleryExtensionProperty {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface IRawGalleryExtensionVersion {
|
||||
version: string;
|
||||
lastUpdated: string;
|
||||
assetUri: string;
|
||||
files: IRawGalleryExtensionFile[];
|
||||
properties: IRawGalleryExtensionProperty[];
|
||||
}
|
||||
|
||||
interface IRawGalleryExtensionStatistics {
|
||||
@@ -90,7 +98,11 @@ const AssetType = {
|
||||
Details: 'Microsoft.VisualStudio.Services.Content.Details',
|
||||
Manifest: 'Microsoft.VisualStudio.Code.Manifest',
|
||||
VSIX: 'Microsoft.VisualStudio.Services.VSIXPackage',
|
||||
License: 'Microsoft.VisualStudio.Services.Content.License'
|
||||
License: 'Microsoft.VisualStudio.Services.Content.License',
|
||||
};
|
||||
|
||||
const PropertyType = {
|
||||
Dependency: 'Microsoft.VisualStudio.Code.ExtensionDependencies'
|
||||
};
|
||||
|
||||
interface ICriterium {
|
||||
@@ -178,7 +190,13 @@ function getAssetSource(files: IRawGalleryExtensionFile[], type: string): string
|
||||
const result = files.filter(f => f.assetType === type)[0];
|
||||
return result && result.source;
|
||||
}
|
||||
|
||||
function getDependencies(properties: IRawGalleryExtensionProperty[]): string[] {
|
||||
const values = properties.filter(p => p.key === PropertyType.Dependency);
|
||||
if (values.length && values[0].value) {
|
||||
return values[0].value.split(',');
|
||||
}
|
||||
return [];
|
||||
}
|
||||
function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUrl: string, downloadHeaders: { [key: string]: string; }): IGalleryExtension {
|
||||
const [version] = galleryExtension.versions;
|
||||
|
||||
@@ -203,6 +221,8 @@ function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUr
|
||||
license: getAssetSource(version.files, AssetType.License)
|
||||
};
|
||||
|
||||
const dependencies = version.properties ? getDependencies(version.properties) : void 0;
|
||||
|
||||
return {
|
||||
id: galleryExtension.extensionId,
|
||||
name: galleryExtension.extensionName,
|
||||
@@ -217,6 +237,9 @@ function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUr
|
||||
rating: getStatistic(galleryExtension.statistics, 'averagerating'),
|
||||
ratingCount: getStatistic(galleryExtension.statistics, 'ratingcount'),
|
||||
assets,
|
||||
properties: {
|
||||
dependencies
|
||||
},
|
||||
downloadHeaders
|
||||
};
|
||||
}
|
||||
@@ -337,8 +360,35 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
||||
}
|
||||
|
||||
download(extension: IGalleryExtension): TPromise<string> {
|
||||
return this.loadCompatibleVersion(extension).then(extension => {
|
||||
const url = extension.assets.download;
|
||||
const zipPath = path.join(tmpdir(), extension.id);
|
||||
const data = getGalleryExtensionTelemetryData(extension);
|
||||
const startTime = new Date().getTime();
|
||||
const log = duration => this.telemetryService.publicLog('galleryService:downloadVSIX', assign(data, { duration }));
|
||||
|
||||
return this.getCommonHeaders()
|
||||
.then(headers => this._getAsset({ url, headers }))
|
||||
.then(context => download(zipPath, context))
|
||||
.then(() => log(new Date().getTime() - startTime))
|
||||
.then(() => zipPath);
|
||||
});
|
||||
}
|
||||
|
||||
getAsset(url: string): TPromise<IRequestContext> {
|
||||
return this._getAsset({ url });
|
||||
}
|
||||
|
||||
getAllDependencies(extension: IGalleryExtension): TPromise<IGalleryExtension[]> {
|
||||
return this.loadCompatibleVersion(<IGalleryExtension>extension)
|
||||
.then(compatible => this.getDependenciesReccursively(compatible.properties.dependencies, [extension]))
|
||||
.then(dependencies => dependencies.slice(1));
|
||||
}
|
||||
|
||||
loadCompatibleVersion(extension: IGalleryExtension): TPromise<IGalleryExtension> {
|
||||
// TODO:sandy: Check if the given version is compatible
|
||||
const query = new Query()
|
||||
.withFlags(Flags.IncludeVersions, Flags.IncludeFiles)
|
||||
.withFlags(Flags.IncludeVersions, Flags.IncludeFiles, Flags.IncludeVersionProperties)
|
||||
.withPage(1, 1)
|
||||
.withFilter(FilterType.Target, 'Microsoft.VisualStudio.Code')
|
||||
.withAssetTypes(AssetType.Manifest, AssetType.VSIX)
|
||||
@@ -346,29 +396,64 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
||||
|
||||
return this.queryGallery(query).then(({ galleryExtensions }) => {
|
||||
const [rawExtension] = galleryExtensions;
|
||||
|
||||
if (!rawExtension) {
|
||||
return TPromise.wrapError(new Error(localize('notFound', "Extension not found")));
|
||||
}
|
||||
|
||||
return this.getLastValidExtensionVersion(rawExtension, rawExtension.versions).then(rawVersion => {
|
||||
const url = `${ getAssetSource(rawVersion.files, AssetType.VSIX) }?install=true`;
|
||||
const zipPath = path.join(tmpdir(), extension.id);
|
||||
const data = getGalleryExtensionTelemetryData(extension);
|
||||
const startTime = new Date().getTime();
|
||||
const log = duration => this.telemetryService.publicLog('galleryService:downloadVSIX', assign(data, { duration }));
|
||||
|
||||
return this.getCommonHeaders()
|
||||
.then(headers => this._getAsset({ url, headers }))
|
||||
.then(context => download(zipPath, context))
|
||||
.then(() => log(new Date().getTime() - startTime))
|
||||
.then(() => zipPath);
|
||||
});
|
||||
return this.getLastValidExtensionVersion(rawExtension, rawExtension.versions)
|
||||
.then(rawVersion => {
|
||||
extension.properties.dependencies = getDependencies(rawVersion.properties);
|
||||
extension.assets.download = `${ getAssetSource(rawVersion.files, AssetType.VSIX) }?install=true`;
|
||||
return extension;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getAsset(url: string): TPromise<IRequestContext> {
|
||||
return this._getAsset({ url });
|
||||
private loadDependencies(extensionNames: string[]): TPromise<IGalleryExtension[]> {
|
||||
let query = new Query()
|
||||
.withFlags(Flags.IncludeVersions, Flags.IncludeAssetUri, Flags.IncludeStatistics, Flags.IncludeFiles, Flags.IncludeVersionProperties)
|
||||
.withPage(1, extensionNames.length)
|
||||
.withFilter(FilterType.Target, 'Microsoft.VisualStudio.Code')
|
||||
.withAssetTypes(AssetType.Icon, AssetType.License, AssetType.Details, AssetType.Manifest, AssetType.VSIX);
|
||||
query = extensionNames.reduce((query, name) => query.withFilter(FilterType.ExtensionName, name), query);
|
||||
|
||||
return this.queryGallery(query)
|
||||
.then(result => this.getCommonHeaders()
|
||||
.then(downloadHeaders => {
|
||||
const dependencies = [];
|
||||
const ids = [];
|
||||
for (const galleryExtension of result.galleryExtensions) {
|
||||
if (ids.indexOf(galleryExtension.extensionId) === -1) {
|
||||
dependencies.push(toExtension(galleryExtension, this.extensionsGalleryUrl, downloadHeaders));
|
||||
ids.push(galleryExtension.extensionId);
|
||||
}
|
||||
}
|
||||
return dependencies;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private getDependenciesReccursively(toGet: string[], result: IGalleryExtension[]): TPromise<IGalleryExtension[]> {
|
||||
if (!toGet || !toGet.length) {
|
||||
return TPromise.wrap(result);
|
||||
}
|
||||
toGet = result.length ? toGet.filter(e => !ExtensionGalleryService.hasExtensionByName(result, e)) : toGet;
|
||||
if (!toGet.length) {
|
||||
return TPromise.wrap(result);
|
||||
}
|
||||
|
||||
|
||||
return this.loadDependencies(toGet)
|
||||
.then(loadedDependencies => {
|
||||
const dependenciesSet = new ArraySet<string>();
|
||||
for (const dep of loadedDependencies) {
|
||||
if (dep.properties.dependencies) {
|
||||
dep.properties.dependencies.forEach(d => dependenciesSet.set(d));
|
||||
}
|
||||
}
|
||||
result = distinct(result.concat(loadedDependencies), d => d.id);
|
||||
const dependencies = dependenciesSet.elements.filter(d => !ExtensionGalleryService.hasExtensionByName(result, d));
|
||||
return this.getDependenciesReccursively(dependencies, result);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -416,4 +501,13 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
||||
return version;
|
||||
});
|
||||
}
|
||||
|
||||
private static hasExtensionByName(extensions: IGalleryExtension[], name: string): boolean {
|
||||
for (const extension of extensions) {
|
||||
if (`${extension.publisher}.${extension.name}` === name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
import nls = require('vs/nls');
|
||||
import * as path from 'path';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { flatten } from 'vs/base/common/arrays';
|
||||
@@ -24,6 +25,7 @@ import Event, { Emitter } from 'vs/base/common/event';
|
||||
import * as semver from 'semver';
|
||||
import { groupBy, values } from 'vs/base/common/collections';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IChoiceService, Severity } from 'vs/platform/message/common/message';
|
||||
|
||||
const SystemExtensionsRoot = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', 'extensions'));
|
||||
|
||||
@@ -106,6 +108,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
|
||||
|
||||
constructor(
|
||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||
@IChoiceService private choiceService: IChoiceService,
|
||||
@IExtensionGalleryService private galleryService: IExtensionGalleryService
|
||||
) {
|
||||
this.extensionsPath = environmentService.extensionsPath;
|
||||
@@ -135,30 +138,97 @@ export class ExtensionManagementService implements IExtensionManagementService {
|
||||
});
|
||||
}
|
||||
|
||||
installFromGallery(extension: IGalleryExtension): TPromise<void> {
|
||||
installFromGallery(extension: IGalleryExtension, checkDependecies: boolean = true): TPromise<void> {
|
||||
const id = getExtensionId(extension, extension.version);
|
||||
|
||||
return this.isObsolete(id).then(isObsolete => {
|
||||
if (isObsolete) {
|
||||
return TPromise.wrapError<void>(new Error(nls.localize('restartCode', "Please restart Code before reinstalling {0}.", extension.displayName || extension.name)));
|
||||
}
|
||||
|
||||
this._onInstallExtension.fire({ id, gallery: extension });
|
||||
return this.galleryService.loadCompatibleVersion(extension)
|
||||
.then(compatibleVersion => this.installCompatibleVersion(compatibleVersion, checkDependecies))
|
||||
.then(
|
||||
local => this._onDidInstallExtension.fire({ id, local, gallery: extension }),
|
||||
error => {
|
||||
this._onDidInstallExtension.fire({ id, gallery: extension, error });
|
||||
return TPromise.wrapError(error);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const metadata = {
|
||||
private installCompatibleVersion(extension: IGalleryExtension, checkDependecies: boolean): TPromise<ILocalExtension> {
|
||||
const dependencies = checkDependecies ? this.getDependenciesToInstall(extension) : [];
|
||||
if (!dependencies.length) {
|
||||
return this.downloadAndInstall(extension);
|
||||
}
|
||||
|
||||
const message = nls.localize('installDependecies', "This extension has dependencies. Would you like to install them along with it?");
|
||||
const options = [
|
||||
nls.localize('installWithDependenices', "Install With Dependencies"),
|
||||
nls.localize('installWithoutDependenices', "Install only this"),
|
||||
nls.localize('close', "Close")
|
||||
];
|
||||
return this.choiceService.choose(Severity.Info, message, options)
|
||||
.then(value => {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return this.installWithDependencies(extension);
|
||||
case 1:
|
||||
return this.downloadAndInstall(extension);
|
||||
default:
|
||||
return TPromise.wrapError(errors.canceled());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getDependenciesToInstall(extension: IGalleryExtension): string[] {
|
||||
const extensionName = `${extension.publisher}.${extension.name}`;
|
||||
return extension.properties.dependencies ? extension.properties.dependencies.filter(name => name !== extensionName) : [];
|
||||
}
|
||||
|
||||
private installWithDependencies(extension: IGalleryExtension): TPromise<ILocalExtension> {
|
||||
return this.galleryService.getAllDependencies(extension)
|
||||
.then(allDependencies => this.filterOutInstalled(allDependencies))
|
||||
.then(toInstall => this.bulkInstallWithDependencies(extension, toInstall));
|
||||
}
|
||||
|
||||
private bulkInstallWithDependencies(extension: IGalleryExtension, dependecies: IGalleryExtension[]): TPromise<ILocalExtension> {
|
||||
return this.downloadAndInstall(extension)
|
||||
.then(localExtension => TPromise.join(dependecies.map((dep) => this.installFromGallery(dep, false)))
|
||||
.then(() => localExtension, error => this.rollback(localExtension, dependecies).then(() => error)));
|
||||
}
|
||||
|
||||
private rollback(localExtension: ILocalExtension, dependecies: IGalleryExtension[]): TPromise<void> {
|
||||
return this.uninstall(localExtension)
|
||||
.then(() => this.filterOutUnInstalled(dependecies))
|
||||
.then(installed => TPromise.join(installed.map((i) => this.uninstall(i))))
|
||||
.then(() => null);
|
||||
}
|
||||
|
||||
private filterOutInstalled(extensions: IGalleryExtension[]): TPromise<IGalleryExtension[]> {
|
||||
return this.getInstalled().then(local => {
|
||||
return extensions.filter(extension => local.every(local => local.id !== extension.id));
|
||||
});
|
||||
}
|
||||
|
||||
private filterOutUnInstalled(extensions: IGalleryExtension[]): TPromise<ILocalExtension[]> {
|
||||
return this.getInstalled().then(installed => {
|
||||
return installed.filter(local => extensions.every(extension => extension.id === local.id));
|
||||
});
|
||||
}
|
||||
|
||||
private downloadAndInstall(extension: IGalleryExtension): TPromise<ILocalExtension> {
|
||||
const id = getExtensionId(extension, extension.version);
|
||||
const metadata = {
|
||||
id: extension.id,
|
||||
publisherId: extension.publisherId,
|
||||
publisherDisplayName: extension.publisherDisplayName
|
||||
};
|
||||
|
||||
return this.galleryService.download(extension)
|
||||
.then(zipPath => validate(zipPath).then(() => zipPath))
|
||||
.then(zipPath => this.installExtension(zipPath, id, metadata))
|
||||
.then(
|
||||
local => this._onDidInstallExtension.fire({ id, local, gallery: extension }),
|
||||
error => { this._onDidInstallExtension.fire({ id, gallery: extension, error }); return TPromise.wrapError(error); }
|
||||
);
|
||||
});
|
||||
return this.galleryService.download(extension)
|
||||
.then(zipPath => validate(zipPath).then(() => zipPath))
|
||||
.then(zipPath => this.installExtension(zipPath, id, metadata));
|
||||
}
|
||||
|
||||
private installExtension(zipPath: string, id: string, metadata: IGalleryMetadata = null): TPromise<ILocalExtension> {
|
||||
|
||||
Reference in New Issue
Block a user