Skip to content

Commit d45ce51

Browse files
authored
Merge pull request #32765 from joaomoreno/uninstall-telemetry
Uninstall telemetry
2 parents bb55f06 + 40145f5 commit d45ce51

File tree

3 files changed

+51
-20
lines changed

3 files changed

+51
-20
lines changed

src/vs/platform/extensionManagement/common/extensionManagement.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,17 @@ export interface IQueryOptions {
195195
sortOrder?: SortOrder;
196196
}
197197

198+
export enum StatisticType {
199+
Uninstall = 'uninstall'
200+
}
201+
198202
export interface IExtensionGalleryService {
199203
_serviceBrand: any;
200204
isEnabled(): boolean;
201205
getRequestHeaders(): TPromise<{ [key: string]: string; }>;
202206
query(options?: IQueryOptions): TPromise<IPager<IGalleryExtension>>;
203207
download(extension: IGalleryExtension): TPromise<string>;
208+
reportStatistic(publisher: string, name: string, version: string, type: StatisticType): TPromise<void>;
204209
getReadme(extension: IGalleryExtension): TPromise<string>;
205210
getManifest(extension: IGalleryExtension): TPromise<IExtensionManifest>;
206211
getChangelog(extension: IGalleryMetadata): TPromise<string>;

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
1010
import * as uuid from 'vs/base/common/uuid';
1111
import { distinct } from 'vs/base/common/arrays';
1212
import { getErrorMessage } from 'vs/base/common/errors';
13-
import { IGalleryExtension, IExtensionGalleryService, IGalleryExtensionAsset, IQueryOptions, SortBy, SortOrder, IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement';
13+
import { StatisticType, IGalleryExtension, IExtensionGalleryService, IGalleryExtensionAsset, IQueryOptions, SortBy, SortOrder, IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement';
1414
import { getGalleryExtensionId, getGalleryExtensionTelemetryData, adoptToGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
1515
import { assign, getOrDefault } from 'vs/base/common/objects';
1616
import { IRequestService } from 'vs/platform/request/node/request';
@@ -385,6 +385,27 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
385385
return { galleryExtensions, total };
386386
}
387387

388+
async reportStatistic(publisher: string, name: string, version: string, type: StatisticType): TPromise<void> {
389+
if (!this.isEnabled()) {
390+
return;
391+
}
392+
393+
try {
394+
const headers = {
395+
...await this.commonHTTPHeaders,
396+
Accept: '*/*;api-version=4.0-preview.1'
397+
};
398+
399+
await this.requestService.request({
400+
type: 'POST',
401+
url: this.api(`/publishers/${publisher}/extensions/${name}/${version}/stats?statType=${type}`),
402+
headers
403+
});
404+
} catch (err) {
405+
// noop
406+
}
407+
}
408+
388409
download(extension: IGalleryExtension): TPromise<string> {
389410
return this.loadCompatibleVersion(extension).then(extension => {
390411
const zipPath = path.join(tmpdir(), uuid.generateUuid());

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

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import { assign } from 'vs/base/common/objects';
1313
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
1414
import { flatten, distinct } from 'vs/base/common/arrays';
1515
import { extract, buffer } from 'vs/base/node/zip';
16-
import { Promise, TPromise } from 'vs/base/common/winjs.base';
16+
import { TPromise } from 'vs/base/common/winjs.base';
1717
import {
1818
IExtensionManagementService, IExtensionGalleryService, ILocalExtension,
1919
IGalleryExtension, IExtensionManifest, IGalleryMetadata,
20-
InstallExtensionEvent, DidInstallExtensionEvent, DidUninstallExtensionEvent, LocalExtensionType
20+
InstallExtensionEvent, DidInstallExtensionEvent, DidUninstallExtensionEvent, LocalExtensionType,
21+
StatisticType
2122
} from 'vs/platform/extensionManagement/common/extensionManagement';
2223
import { getLocalExtensionIdFromGallery, getLocalExtensionIdFromManifest, getGalleryExtensionIdFromLocal, getIdAndVersionFromLocalExtensionId, adoptToGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
2324
import { localizeManifest } from '../common/extensionNls';
@@ -223,9 +224,9 @@ export class ExtensionManagementService implements IExtensionManagementService {
223224
}
224225

225226
private rollback(localExtension: ILocalExtension, dependecies: IGalleryExtension[]): TPromise<void> {
226-
return this.doUninstall(localExtension.id)
227+
return this.doUninstall(localExtension)
227228
.then(() => this.filterOutUninstalled(dependecies))
228-
.then(installed => TPromise.join(installed.map((i) => this.doUninstall(i.id))))
229+
.then(installed => TPromise.join(installed.map((i) => this.doUninstall(i))))
229230
.then(() => null);
230231
}
231232

@@ -304,11 +305,11 @@ export class ExtensionManagementService implements IExtensionManagementService {
304305
}
305306

306307
private checkForDependenciesAndUninstall(extension: ILocalExtension, installed: ILocalExtension[], force: boolean): TPromise<void> {
307-
return this.preUninstallExtension(extension.id)
308+
return this.preUninstallExtension(extension)
308309
.then(() => this.hasDependencies(extension, installed) ? this.promptForDependenciesAndUninstall(extension, installed, force) : this.promptAndUninstall(extension, installed, force))
309-
.then(() => this.postUninstallExtension(extension.id),
310+
.then(() => this.postUninstallExtension(extension),
310311
error => {
311-
this.postUninstallExtension(extension.id, error);
312+
this.postUninstallExtension(extension, error);
312313
return TPromise.wrapError(error);
313314
});
314315
}
@@ -370,7 +371,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
370371
if (dependents.length) {
371372
return TPromise.wrapError<void>(new Error(this.getDependentsErrorMessage(extension, dependents)));
372373
}
373-
return TPromise.join([this.uninstallExtension(extension.id), ...dependenciesToUninstall.map(d => this.doUninstall(d.id))]).then(() => null);
374+
return TPromise.join([this.uninstallExtension(extension.id), ...dependenciesToUninstall.map(d => this.doUninstall(d))]).then(() => null);
374375
}
375376

376377
private getDependentsErrorMessage(extension: ILocalExtension, dependents: ILocalExtension[]): string {
@@ -419,21 +420,21 @@ export class ExtensionManagementService implements IExtensionManagementService {
419420
return installed.filter(e => e.manifest.extensionDependencies && e.manifest.extensionDependencies.indexOf(getGalleryExtensionIdFromLocal(extension)) !== -1);
420421
}
421422

422-
private doUninstall(id: string): TPromise<void> {
423-
return this.preUninstallExtension(id)
424-
.then(() => this.uninstallExtension(id))
425-
.then(() => this.postUninstallExtension(id),
423+
private doUninstall(extension: ILocalExtension): TPromise<void> {
424+
return this.preUninstallExtension(extension)
425+
.then(() => this.uninstallExtension(extension.id))
426+
.then(() => this.postUninstallExtension(extension),
426427
error => {
427-
this.postUninstallExtension(id, error);
428+
this.postUninstallExtension(extension, error);
428429
return TPromise.wrapError(error);
429430
});
430431
}
431432

432-
private preUninstallExtension(id: string): TPromise<void> {
433-
const extensionPath = path.join(this.extensionsPath, id);
433+
private preUninstallExtension(extension: ILocalExtension): TPromise<void> {
434+
const extensionPath = path.join(this.extensionsPath, extension.id);
434435
return pfs.exists(extensionPath)
435436
.then(exists => exists ? null : TPromise.wrapError(new Error(nls.localize('notExists', "Could not find extension"))))
436-
.then(() => this._onUninstallExtension.fire(id));
437+
.then(() => this._onUninstallExtension.fire(extension.id));
437438
}
438439

439440
private uninstallExtension(id: string): TPromise<void> {
@@ -443,8 +444,12 @@ export class ExtensionManagementService implements IExtensionManagementService {
443444
.then(() => this.unsetObsolete(id));
444445
}
445446

446-
private postUninstallExtension(id: string, error?: any): TPromise<void> {
447-
return this._onDidUninstallExtension.fire({ id, error });
447+
private async postUninstallExtension(extension: ILocalExtension, error?: any): TPromise<void> {
448+
if (!error) {
449+
await this.galleryService.reportStatistic(extension.manifest.publisher, extension.manifest.name, extension.manifest.version, StatisticType.Uninstall);
450+
}
451+
452+
this._onDidUninstallExtension.fire({ id: extension.id, error });
448453
}
449454

450455
getInstalled(type: LocalExtensionType = null): TPromise<ILocalExtension[]> {
@@ -476,7 +481,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
476481
const limiter = new Limiter(10);
477482

478483
return this.scanExtensionFolders(root)
479-
.then(extensionIds => Promise.join(extensionIds.map(id => {
484+
.then(extensionIds => TPromise.join(extensionIds.map(id => {
480485
const extensionPath = path.join(root, id);
481486

482487
const each = () => pfs.readdir(extensionPath).then(children => {

0 commit comments

Comments
 (0)