@@ -7,11 +7,10 @@ import {
77 TerminalShellExecutionStartEvent ,
88 TerminalShellIntegration ,
99} from 'vscode' ;
10- import { PythonEnvironment } from '../../api' ;
10+ import { PythonCommandRunConfiguration , PythonEnvironment } from '../../api' ;
1111import { onDidEndTerminalShellExecution , onDidStartTerminalShellExecution } from '../../common/window.apis' ;
1212import { traceError , traceInfo , traceVerbose } from '../../common/logging' ;
1313import { isTaskTerminal } from './utils' ;
14- import { createDeferred } from '../../common/utils/deferred' ;
1514import { getActivationCommand , getDeactivationCommand } from '../common/activation' ;
1615import { quoteArgs } from '../execution/execUtils' ;
1716
@@ -229,46 +228,14 @@ export class TerminalActivationImpl implements TerminalActivationInternal {
229228 if ( activationCommands ) {
230229 try {
231230 for ( const command of activationCommands ) {
232- const execPromise = createDeferred < void > ( ) ;
233- const execution = shellIntegration . executeCommand ( command . executable , command . args ?? [ ] ) ;
234- const disposables : Disposable [ ] = [ ] ;
235- let timer : NodeJS . Timeout | undefined = setTimeout ( ( ) => {
236- execPromise . resolve ( ) ;
237- traceError ( `Shell execution timed out: ${ command . executable } ${ command . args ?. join ( ' ' ) } ` ) ;
238- } , 2000 ) ;
239- disposables . push (
240- this . onTerminalShellExecutionEnd ( ( e : TerminalShellExecutionEndEvent ) => {
241- if ( e . execution === execution ) {
242- execPromise . resolve ( ) ;
243- if ( timer ) {
244- clearTimeout ( timer ) ;
245- timer = undefined ;
246- }
247- }
248- } ) ,
249- this . onTerminalShellExecutionStart ( ( e : TerminalShellExecutionStartEvent ) => {
250- if ( e . execution === execution ) {
251- traceVerbose (
252- `Shell execution started: ${ command . executable } ${ command . args ?. join ( ' ' ) } ` ,
253- ) ;
254- }
255- } ) ,
256- new Disposable ( ( ) => {
257- if ( timer ) {
258- clearTimeout ( timer ) ;
259- timer = undefined ;
260- }
261- } ) ,
262- ) ;
263- try {
264- await execPromise . promise ;
265- } finally {
266- disposables . forEach ( ( d ) => d . dispose ( ) ) ;
267- }
231+ await this . executeTerminalShellCommandInternal ( shellIntegration , command ) ;
268232 }
269- } finally {
270233 this . activatedTerminals . set ( terminal , environment ) ;
234+ } catch {
235+ traceError ( 'Failed to activate environment using shell integration' ) ;
271236 }
237+ } else {
238+ traceVerbose ( 'No activation commands found for terminal.' ) ;
272239 }
273240 }
274241
@@ -281,43 +248,53 @@ export class TerminalActivationImpl implements TerminalActivationInternal {
281248 if ( deactivationCommands ) {
282249 try {
283250 for ( const command of deactivationCommands ) {
284- const execPromise = createDeferred < void > ( ) ;
285- const execution = shellIntegration . executeCommand ( command . executable , command . args ?? [ ] ) ;
286- const disposables : Disposable [ ] = [ ] ;
287- let timer : NodeJS . Timeout | undefined = setTimeout ( ( ) => {
288- execPromise . resolve ( ) ;
289- traceError ( `Shell execution timed out: ${ command . executable } ${ command . args ?. join ( ' ' ) } ` ) ;
290- } , 2000 ) ;
291- disposables . push (
292- this . onTerminalShellExecutionEnd ( ( e : TerminalShellExecutionEndEvent ) => {
293- if ( e . execution === execution ) {
294- execPromise . resolve ( ) ;
295- if ( timer ) {
296- clearTimeout ( timer ) ;
297- timer = undefined ;
298- }
299- }
300- } ) ,
301- this . onTerminalShellExecutionStart ( ( e : TerminalShellExecutionStartEvent ) => {
302- if ( e . execution === execution ) {
303- traceVerbose (
304- `Shell execution started: ${ command . executable } ${ command . args ?. join ( ' ' ) } ` ,
305- ) ;
306- }
307- } ) ,
308- new Disposable ( ( ) => {
309- if ( timer ) {
310- clearTimeout ( timer ) ;
311- timer = undefined ;
312- }
313- } ) ,
314- ) ;
315-
316- await execPromise . promise ;
251+ await this . executeTerminalShellCommandInternal ( shellIntegration , command ) ;
317252 }
318- } finally {
319253 this . activatedTerminals . delete ( terminal ) ;
254+ } catch {
255+ traceError ( 'Failed to deactivate environment using shell integration' ) ;
320256 }
257+ } else {
258+ traceVerbose ( 'No deactivation commands found for terminal.' ) ;
259+ }
260+ }
261+
262+ private async executeTerminalShellCommandInternal (
263+ shellIntegration : TerminalShellIntegration ,
264+ command : PythonCommandRunConfiguration ,
265+ ) : Promise < boolean > {
266+ const execution = shellIntegration . executeCommand ( command . executable , command . args ?? [ ] ) ;
267+ const disposables : Disposable [ ] = [ ] ;
268+
269+ const promise = new Promise < void > ( ( resolve ) => {
270+ const timer = setTimeout ( ( ) => {
271+ traceError ( `Shell execution timed out: ${ command . executable } ${ command . args ?. join ( ' ' ) } ` ) ;
272+ resolve ( ) ;
273+ } , 2000 ) ;
274+
275+ disposables . push (
276+ new Disposable ( ( ) => clearTimeout ( timer ) ) ,
277+ this . onTerminalShellExecutionEnd ( ( e : TerminalShellExecutionEndEvent ) => {
278+ if ( e . execution === execution ) {
279+ resolve ( ) ;
280+ }
281+ } ) ,
282+ this . onTerminalShellExecutionStart ( ( e : TerminalShellExecutionStartEvent ) => {
283+ if ( e . execution === execution ) {
284+ traceVerbose ( `Shell execution started: ${ command . executable } ${ command . args ?. join ( ' ' ) } ` ) ;
285+ }
286+ } ) ,
287+ ) ;
288+ } ) ;
289+
290+ try {
291+ await promise ;
292+ return true ;
293+ } catch {
294+ traceError ( `Failed to execute shell command: ${ command . executable } ${ command . args ?. join ( ' ' ) } ` ) ;
295+ return false ;
296+ } finally {
297+ disposables . forEach ( ( d ) => d . dispose ( ) ) ;
321298 }
322299 }
323300}
0 commit comments