@@ -8,6 +8,8 @@ import '../extensions';
88import { IInterpreterService } from '../../interpreter/contracts' ;
99import { IServiceContainer } from '../../ioc/types' ;
1010import { EnvironmentType , PythonEnvironment } from '../../pythonEnvironments/info' ;
11+ import { sendTelemetryEvent } from '../../telemetry' ;
12+ import { EventName } from '../../telemetry/constants' ;
1113import { IApplicationShell , IWorkspaceService } from '../application/types' ;
1214import { STANDARD_OUTPUT_CHANNEL } from '../constants' ;
1315import { traceError , traceInfo } from '../logger' ;
@@ -26,6 +28,7 @@ import {
2628} from '../types' ;
2729import { Installer } from '../utils/localize' ;
2830import { isResource , noop } from '../utils/misc' ;
31+ import { translateProductToModule } from './moduleInstaller' ;
2932import { ProductNames } from './productNames' ;
3033import {
3134 IInstallationChannelManager ,
@@ -101,17 +104,25 @@ abstract class BaseInstaller {
101104 const channels = this . serviceContainer . get < IInstallationChannelManager > ( IInstallationChannelManager ) ;
102105 const installer = await channels . getInstallationChannel ( product , resource ) ;
103106 if ( ! installer ) {
107+ sendTelemetryEvent ( EventName . PYTHON_INSTALL_PACKAGE , undefined , {
108+ installer : 'unavailable' ,
109+ productName : ProductNames . get ( product ) ,
110+ } ) ;
104111 return InstallerResponse . Ignore ;
105112 }
106113
107- const moduleName = translateProductToModule ( product , ModuleNamePurpose . install ) ;
108114 await installer
109- . installModule ( moduleName , resource , cancel , isUpgrade )
110- . catch ( ( ex ) => traceError ( `Error in installing the module '${ moduleName } ', ${ ex } ` ) ) ;
111-
112- return this . isInstalled ( product , resource ) . then ( ( isInstalled ) =>
113- isInstalled ? InstallerResponse . Installed : InstallerResponse . Ignore ,
114- ) ;
115+ . installModule ( product , resource , cancel , isUpgrade )
116+ . catch ( ( ex ) => traceError ( `Error in installing the product '${ ProductNames . get ( product ) } ', ${ ex } ` ) ) ;
117+
118+ return this . isInstalled ( product , resource ) . then ( ( isInstalled ) => {
119+ sendTelemetryEvent ( EventName . PYTHON_INSTALL_PACKAGE , undefined , {
120+ installer : installer . displayName ,
121+ productName : ProductNames . get ( product ) ,
122+ isInstalled,
123+ } ) ;
124+ return isInstalled ? InstallerResponse . Installed : InstallerResponse . Ignore ;
125+ } ) ;
115126 }
116127
117128 /**
@@ -355,7 +366,7 @@ class DataScienceInstaller extends BaseInstaller {
355366
356367 // Pick an installerModule based on whether the interpreter is conda or not. Default is pip.
357368 const moduleName = translateProductToModule ( product , ModuleNamePurpose . install ) ;
358- let installerModule ;
369+ let installerModule : IModuleInstaller | undefined ;
359370 const isAvailableThroughConda = ! UnsupportedChannelsForProduct . get ( product ) ?. has ( EnvironmentType . Conda ) ;
360371 if ( interpreter . envType === EnvironmentType . Conda && isAvailableThroughConda ) {
361372 installerModule = channels . find ( ( v ) => v . name === EnvironmentType . Conda ) ;
@@ -371,16 +382,25 @@ class DataScienceInstaller extends BaseInstaller {
371382
372383 if ( ! installerModule ) {
373384 this . appShell . showErrorMessage ( Installer . couldNotInstallLibrary ( ) . format ( moduleName ) ) . then ( noop , noop ) ;
385+ sendTelemetryEvent ( EventName . PYTHON_INSTALL_PACKAGE , undefined , {
386+ installer : 'unavailable' ,
387+ productName : ProductNames . get ( product ) ,
388+ } ) ;
374389 return InstallerResponse . Ignore ;
375390 }
376391
377392 await installerModule
378- . installModule ( moduleName , interpreter , cancel , isUpgrade )
393+ . installModule ( product , interpreter , cancel , isUpgrade )
379394 . catch ( ( ex ) => traceError ( `Error in installing the module '${ moduleName } ', ${ ex } ` ) ) ;
380395
381- return this . isInstalled ( product , interpreter ) . then ( ( isInstalled ) =>
382- isInstalled ? InstallerResponse . Installed : InstallerResponse . Ignore ,
383- ) ;
396+ return this . isInstalled ( product , interpreter ) . then ( ( isInstalled ) => {
397+ sendTelemetryEvent ( EventName . PYTHON_INSTALL_PACKAGE , undefined , {
398+ installer : installerModule ?. displayName || '' ,
399+ isInstalled,
400+ productName : ProductNames . get ( product ) ,
401+ } ) ;
402+ return isInstalled ? InstallerResponse . Installed : InstallerResponse . Ignore ;
403+ } ) ;
384404 }
385405
386406 /**
@@ -483,60 +503,3 @@ export class ProductInstaller implements IInstaller {
483503 throw new Error ( `Unknown product ${ product } ` ) ;
484504 }
485505}
486-
487- function translateProductToModule ( product : Product , purpose : ModuleNamePurpose ) : string {
488- switch ( product ) {
489- case Product . mypy :
490- return 'mypy' ;
491- case Product . nosetest : {
492- return purpose === ModuleNamePurpose . install ? 'nose' : 'nosetests' ;
493- }
494- case Product . pylama :
495- return 'pylama' ;
496- case Product . prospector :
497- return 'prospector' ;
498- case Product . pylint :
499- return 'pylint' ;
500- case Product . pytest :
501- return 'pytest' ;
502- case Product . autopep8 :
503- return 'autopep8' ;
504- case Product . black :
505- return 'black' ;
506- case Product . pycodestyle :
507- return 'pycodestyle' ;
508- case Product . pydocstyle :
509- return 'pydocstyle' ;
510- case Product . yapf :
511- return 'yapf' ;
512- case Product . flake8 :
513- return 'flake8' ;
514- case Product . unittest :
515- return 'unittest' ;
516- case Product . rope :
517- return 'rope' ;
518- case Product . bandit :
519- return 'bandit' ;
520- case Product . jupyter :
521- return 'jupyter' ;
522- case Product . notebook :
523- return 'notebook' ;
524- case Product . pandas :
525- return 'pandas' ;
526- case Product . ipykernel :
527- return 'ipykernel' ;
528- case Product . nbconvert :
529- return 'nbconvert' ;
530- case Product . kernelspec :
531- return 'kernelspec' ;
532- case Product . tensorboard :
533- return 'tensorboard' ;
534- case Product . torchProfilerInstallName :
535- return 'torch-tb-profiler' ;
536- case Product . torchProfilerImportName :
537- return 'torch_tb_profiler' ;
538- default : {
539- throw new Error ( `Product ${ product } cannot be installed as a Python Module.` ) ;
540- }
541- }
542- }
0 commit comments