mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 17:19:48 +01:00
Add telemetry for clone action (fixes #20570)
This commit is contained in:
@@ -9,6 +9,7 @@ import { IEventEmitter, EventEmitter } from 'vs/base/common/eventEmitter';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as Events from 'vs/base/common/events';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
export interface IAction extends IDisposable {
|
||||
id: string;
|
||||
@@ -202,7 +203,7 @@ export class Action implements IAction {
|
||||
this._order = value;
|
||||
}
|
||||
|
||||
public run(event?: any): TPromise<any> {
|
||||
public run(event?: any, data?: ITelemetryData): TPromise<any> {
|
||||
if (this._actionCallback !== void 0) {
|
||||
return this._actionCallback(event);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,11 @@ export interface ITelemetryInfo {
|
||||
instanceId: string;
|
||||
}
|
||||
|
||||
export interface ITelemetryData {
|
||||
from?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface ITelemetryExperiments {
|
||||
showNewUserWatermark: boolean;
|
||||
openUntitledFile: boolean;
|
||||
@@ -30,7 +35,7 @@ export interface ITelemetryService {
|
||||
* Sends a telemetry event that has been privacy approved.
|
||||
* Do not call this unless you have been given approval.
|
||||
*/
|
||||
publicLog(eventName: string, data?: any): TPromise<void>;
|
||||
publicLog(eventName: string, data?: ITelemetryData): TPromise<void>;
|
||||
|
||||
getTelemetryInfo(): TPromise<ITelemetryInfo>;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import { escapeRegExpCharacters } from 'vs/base/common/strings';
|
||||
import { ITelemetryService, ITelemetryInfo, ITelemetryExperiments } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ITelemetryService, ITelemetryInfo, ITelemetryExperiments, ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ITelemetryAppender, defaultExperiments } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -100,7 +100,7 @@ export class TelemetryService implements ITelemetryService {
|
||||
this._disposables = dispose(this._disposables);
|
||||
}
|
||||
|
||||
publicLog(eventName: string, data?: any): TPromise<any> {
|
||||
publicLog(eventName: string, data?: ITelemetryData): TPromise<any> {
|
||||
// don't send events when the user is optout
|
||||
if (!this._userOptIn) {
|
||||
return TPromise.as(undefined);
|
||||
|
||||
@@ -14,7 +14,7 @@ import { IKeybindingService, KeybindingSource } from 'vs/platform/keybinding/com
|
||||
import { ILifecycleService, ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { ITelemetryService, ITelemetryExperiments, ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ITelemetryService, ITelemetryExperiments, ITelemetryInfo, ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { StorageService } from 'vs/platform/storage/common/storageService';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
@@ -28,7 +28,7 @@ export const defaultExperiments: ITelemetryExperiments = {
|
||||
export const NullTelemetryService = {
|
||||
_serviceBrand: undefined,
|
||||
_experiments: defaultExperiments,
|
||||
publicLog(eventName: string, data?: any) {
|
||||
publicLog(eventName: string, data?: ITelemetryData) {
|
||||
return TPromise.as<void>(null);
|
||||
},
|
||||
isOptedIn: true,
|
||||
|
||||
@@ -168,14 +168,15 @@ export function triggerAndDisposeAction(instantitationService: IInstantiationSer
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const from = args && args.from || 'keybinding';
|
||||
if (telemetryService) {
|
||||
telemetryService.publicLog('workbenchActionExecuted', { id: actionInstance.id, from: args && args.from || 'keybinding' });
|
||||
telemetryService.publicLog('workbenchActionExecuted', { id: actionInstance.id, from });
|
||||
}
|
||||
|
||||
// run action when workbench is created
|
||||
return partService.joinCreation().then(() => {
|
||||
try {
|
||||
return TPromise.as(actionInstance.run()).then(() => {
|
||||
return TPromise.as(actionInstance.run(undefined, { from })).then(() => {
|
||||
actionInstance.dispose();
|
||||
}, (err) => {
|
||||
actionInstance.dispose();
|
||||
|
||||
@@ -16,6 +16,8 @@ import { IGitService } from 'vs/workbench/parts/git/common/git';
|
||||
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import * as url from 'url';
|
||||
import { remote } from 'electron';
|
||||
import { ITelemetryService, ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
|
||||
const dialog = remote.dialog;
|
||||
|
||||
@@ -29,12 +31,13 @@ export class CloneAction extends Action {
|
||||
@IQuickOpenService private quickOpenService: IQuickOpenService,
|
||||
@IMessageService private messageService: IMessageService,
|
||||
@IWindowsService private windowsService: IWindowsService,
|
||||
@ITelemetryService private telemetryService: ITelemetryService,
|
||||
@IWorkspaceContextService private workspaceService: IWorkspaceContextService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): TPromise<void> {
|
||||
run(event?: any, data?: ITelemetryData): TPromise<void> {
|
||||
return this.quickOpenService.input({
|
||||
prompt: localize('valid', "Provide a valid git repository URL"),
|
||||
placeHolder: localize('url', "Repository URL"),
|
||||
@@ -50,6 +53,7 @@ export class CloneAction extends Action {
|
||||
})
|
||||
.then(url => {
|
||||
if (!url) {
|
||||
this.telemetryService.publicLog('gitClone', { ...data, outcome: 'no_URL' });
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
@@ -59,6 +63,7 @@ export class CloneAction extends Action {
|
||||
});
|
||||
|
||||
if (!result || result.length === 0) {
|
||||
this.telemetryService.publicLog('gitClone', { ...data, outcome: 'no_directory' });
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
@@ -69,14 +74,17 @@ export class CloneAction extends Action {
|
||||
const clone = always(this.gitService.clone(url, result[0]), () => promise.cancel());
|
||||
|
||||
return clone.then(path => {
|
||||
this.telemetryService.publicLog('gitClone', { ...data, outcome: 'success' });
|
||||
const forceNewWindow = this.workspaceService.hasWorkspace();
|
||||
return this.windowsService.openWindow([path], { forceNewWindow, forceReuseWindow: !forceNewWindow });
|
||||
|
||||
}).then<void>(null, e => {
|
||||
if (/already exists and is not an empty directory/.test(e.stderr || '')) {
|
||||
this.telemetryService.publicLog('gitClone', { ...data, outcome: 'directory_not_empty' });
|
||||
return TPromise.wrapError(localize('already exists', "Destination repository already exists, please pick another directory to clone to."));
|
||||
}
|
||||
|
||||
this.telemetryService.publicLog('gitClone', { ...data, outcome: isPromiseCanceledError(e) ? 'canceled' : 'error' });
|
||||
return TPromise.wrapError(e);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user