@@ -17,17 +17,17 @@ export enum Product {
1717 unittest
1818}
1919
20- const ProductInstallScripts = new Map < Product , string > ( ) ;
21- ProductInstallScripts . set ( Product . autopep8 , 'pip install autopep8' ) ;
22- ProductInstallScripts . set ( Product . flake8 , 'pip install flake8' ) ;
23- ProductInstallScripts . set ( Product . mypy , 'pip install mypy-lang' ) ;
24- ProductInstallScripts . set ( Product . nosetest , 'pip install nose' ) ;
25- ProductInstallScripts . set ( Product . pep8 , 'pip install pep8' ) ;
26- ProductInstallScripts . set ( Product . prospector , 'pip install prospector' ) ;
27- ProductInstallScripts . set ( Product . pydocstyle , 'pip install pydocstyle' ) ;
28- ProductInstallScripts . set ( Product . pylint , 'pip install pylint' ) ;
29- ProductInstallScripts . set ( Product . pytest , 'pip install -U pytest' ) ;
30- ProductInstallScripts . set ( Product . yapf , 'pip install yapf' ) ;
20+ const ProductInstallScripts = new Map < Product , string [ ] > ( ) ;
21+ ProductInstallScripts . set ( Product . autopep8 , [ 'pip' , ' install' , ' autopep8'] ) ;
22+ ProductInstallScripts . set ( Product . flake8 , [ 'pip' , ' install' , ' flake8'] ) ;
23+ ProductInstallScripts . set ( Product . mypy , [ 'pip' , ' install' , ' mypy-lang'] ) ;
24+ ProductInstallScripts . set ( Product . nosetest , [ 'pip' , ' install' , ' nose'] ) ;
25+ ProductInstallScripts . set ( Product . pep8 , [ 'pip' , ' install' , ' pep8'] ) ;
26+ ProductInstallScripts . set ( Product . prospector , [ 'pip' , ' install' , ' prospector'] ) ;
27+ ProductInstallScripts . set ( Product . pydocstyle , [ 'pip' , ' install' , ' pydocstyle'] ) ;
28+ ProductInstallScripts . set ( Product . pylint , [ 'pip' , ' install' , ' pylint'] ) ;
29+ ProductInstallScripts . set ( Product . pytest , [ 'pip' , ' install' , '-U' , ' pytest'] ) ;
30+ ProductInstallScripts . set ( Product . yapf , [ 'pip' , ' install' , ' yapf'] ) ;
3131
3232
3333const Linters : Product [ ] = [ Product . flake8 , Product . pep8 , Product . prospector , Product . pylint , Product . mypy , Product . pydocstyle ] ;
@@ -61,7 +61,7 @@ SettingToDisableProduct.set(Product.yapf, 'yapf');
6161export class Installer {
6262 private static terminal : vscode . Terminal ;
6363 private disposables : vscode . Disposable [ ] = [ ] ;
64- constructor ( ) {
64+ constructor ( private outputChannel : vscode . OutputChannel = null ) {
6565 this . disposables . push ( vscode . window . onDidCloseTerminal ( term => {
6666 if ( term === Installer . terminal ) {
6767 Installer . terminal = null ;
@@ -72,7 +72,7 @@ export class Installer {
7272 this . disposables . forEach ( d => d . dispose ( ) ) ;
7373 }
7474
75- promptToInstall ( product : Product ) {
75+ promptToInstall ( product : Product ) : Thenable < any > {
7676 let productType = Linters . indexOf ( product ) >= 0 ? 'Linter' : ( Formatters . indexOf ( product ) >= 0 ? 'Formatter' : 'Test Framework' ) ;
7777 const productName = ProductNames . get ( product ) ;
7878
@@ -87,53 +87,61 @@ export class Installer {
8787 else {
8888 options . push ( ...[ installOption , useOtherFormatter ] ) ;
8989 }
90- vscode . window . showErrorMessage ( `${ productType } ${ productName } is not installed` , ...options ) . then ( item => {
90+ return vscode . window . showErrorMessage ( `${ productType } ${ productName } is not installed` , ...options ) . then ( item => {
9191 switch ( item ) {
9292 case installOption : {
93- this . installProduct ( product ) ;
94- break ;
93+ return this . installProduct ( product ) ;
9594 }
9695 case disableOption : {
9796 if ( Linters . indexOf ( product ) >= 0 ) {
98- disableLinter ( product ) ;
97+ return disableLinter ( product ) ;
9998 }
10099 else {
101100 const pythonConfig = vscode . workspace . getConfiguration ( 'python' ) ;
102101 const settingToDisable = SettingToDisableProduct . get ( product ) ;
103- pythonConfig . update ( settingToDisable , false ) ;
102+ return pythonConfig . update ( settingToDisable , false ) ;
104103 }
105- break ;
106104 }
107105 case useOtherFormatter : {
108106 const pythonConfig = vscode . workspace . getConfiguration ( 'python' ) ;
109- pythonConfig . update ( 'formatting.provider' , alternateFormatter ) ;
110- break ;
107+ return pythonConfig . update ( 'formatting.provider' , alternateFormatter ) ;
111108 }
112109 case 'Help' : {
113- break ;
110+ return Promise . resolve ( ) ;
114111 }
115112 }
116113 } ) ;
117114 }
118115
119- installProduct ( product : Product ) {
120- if ( ! Installer . terminal ) {
116+ installProduct ( product : Product ) : Promise < any > {
117+ if ( ! this . outputChannel && ! Installer . terminal ) {
121118 Installer . terminal = vscode . window . createTerminal ( 'Python Installer' ) ;
122119 }
123120
124- let installScript = ProductInstallScripts . get ( product ) ;
125- if ( installScript . startsWith ( 'pip install' ) ) {
126- const pythonPath = settings . PythonSettings . getInstance ( ) . pythonPath ;
121+ let installArgs = ProductInstallScripts . get ( product ) ;
122+ const pythonPath = settings . PythonSettings . getInstance ( ) . pythonPath ;
123+
124+ if ( this . outputChannel ) {
125+ // Errors are just displayed to the user
126+ this . outputChannel . show ( ) ;
127+ return execPythonFile ( pythonPath , [ '-m' , ...installArgs ] , vscode . workspace . rootPath , true , ( data ) => {
128+ this . outputChannel . append ( data ) ;
129+ } ) ;
130+ }
131+ else {
132+ let installScript = installArgs . join ( ' ' ) ;
127133 if ( pythonPath . indexOf ( ' ' ) >= 0 ) {
128134 installScript = `"${ pythonPath } " -m ${ installScript } ` ;
129135 }
130136 else {
131137 installScript = `${ pythonPath } -m ${ installScript } ` ;
132138 }
133- }
134139
135- Installer . terminal . sendText ( installScript ) ;
136- Installer . terminal . show ( false ) ;
140+ Installer . terminal . sendText ( installScript ) ;
141+ Installer . terminal . show ( false ) ;
142+ // Unfortunately we won't know when the command has completed
143+ return Promise . resolve ( ) ;
144+ }
137145 }
138146
139147 isProductInstalled ( product : Product ) : Promise < boolean > {
0 commit comments