@@ -30,14 +30,14 @@ import { URI } from 'vs/base/common/uri';
30
30
import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
31
31
import { ILogService } from 'vs/platform/log/common/log' ;
32
32
import { INotificationService } from 'vs/platform/notification/common/notification' ;
33
- import { IShellLaunchConfig , TerminalLocation , TerminalSettingId } from 'vs/platform/terminal/common/terminal' ;
33
+ import { IShellLaunchConfig , TerminalLocation , TerminalSettingId , WaitOnExitValue } from 'vs/platform/terminal/common/terminal' ;
34
34
import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings' ;
35
35
import { ThemeIcon } from 'vs/platform/theme/common/themeService' ;
36
36
import { IViewDescriptorService , IViewsService , ViewContainerLocation } from 'vs/workbench/common/views' ;
37
37
import { TaskTerminalStatus } from 'vs/workbench/contrib/tasks/browser/taskTerminalStatus' ;
38
38
import { ProblemCollectorEventKind , ProblemHandlingStrategy , StartStopProblemCollector , WatchingProblemCollector } from 'vs/workbench/contrib/tasks/common/problemCollectors' ;
39
39
import { GroupKind } from 'vs/workbench/contrib/tasks/common/taskConfiguration' ;
40
- import { CommandOptions , CommandString , ContributedTask , CustomTask , DependsOrder , ICommandConfiguration , IExtensionTaskSource , InMemoryTask , IShellConfiguration , IShellQuotingOptions , ITaskEvent , PanelKind , RevealKind , RevealProblemKind , RuntimeType , ShellQuoting , Task , TaskEvent , TaskEventKind , TaskScope , TaskSettingId , TaskSourceKind } from 'vs/workbench/contrib/tasks/common/tasks' ;
40
+ import { CommandOptions , CommandString , ContributedTask , CustomTask , DependsOrder , ICommandConfiguration , IConfigurationProperties , IExtensionTaskSource , InMemoryTask , IPresentationOptions , IShellConfiguration , IShellQuotingOptions , ITaskEvent , PanelKind , RevealKind , RevealProblemKind , RuntimeType , ShellQuoting , Task , TaskEvent , TaskEventKind , TaskScope , TaskSettingId , TaskSourceKind } from 'vs/workbench/contrib/tasks/common/tasks' ;
41
41
import { ITaskService } from 'vs/workbench/contrib/tasks/common/taskService' ;
42
42
import { IResolvedVariables , IResolveSet , ITaskExecuteResult , ITaskResolver , ITaskSummary , ITaskSystem , ITaskSystemInfo , ITaskSystemInfoResolver , ITaskTerminateResponse , TaskError , TaskErrors , TaskExecuteKind , Triggers } from 'vs/workbench/contrib/tasks/common/taskSystem' ;
43
43
import { ITerminalGroupService , ITerminalInstance , ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal' ;
@@ -284,6 +284,11 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
284
284
}
285
285
if ( this . _tasksToReconnect . includes ( task . _id ) ) {
286
286
this . _terminalForTask = terminals . find ( t => t . shellLaunchConfig . attachPersistentProcess ?. task ?. id === task . _id ) ;
287
+ // Restore the waitOnExit value of the terminal because it may have been a function
288
+ // that cannot be persisted in the pty host
289
+ if ( 'command' in task && task . command . presentation && this . _terminalForTask ) {
290
+ this . _terminalForTask . waitOnExit = getWaitOnExitValue ( task . command . presentation , task . configurationProperties ) ;
291
+ }
287
292
this . run ( task , resolver , trigger ) ;
288
293
}
289
294
return undefined ;
@@ -541,35 +546,38 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
541
546
alreadyResolved = alreadyResolved ?? new Map < string , string > ( ) ;
542
547
const promises : Promise < ITaskSummary > [ ] = [ ] ;
543
548
if ( task . configurationProperties . dependsOn ) {
544
- for ( const dependency of task . configurationProperties . dependsOn ) {
545
- const dependencyTask = await resolver . resolve ( dependency . uri , dependency . task ! ) ;
546
- if ( dependencyTask ) {
547
- this . _adoptConfigurationForDependencyTask ( dependencyTask , task ) ;
548
- const key = dependencyTask . getMapKey ( ) ;
549
- let promise = this . _activeTasks [ key ] ? this . _getDependencyPromise ( this . _activeTasks [ key ] ) : undefined ;
550
- if ( ! promise ) {
551
- this . _fireTaskEvent ( TaskEvent . create ( TaskEventKind . DependsOnStarted , task ) ) ;
552
- encounteredDependencies . add ( task . getCommonTaskId ( ) ) ;
553
- promise = this . _executeDependencyTask ( dependencyTask , resolver , trigger , encounteredDependencies , alreadyResolved ) ;
554
- }
555
- promises . push ( promise ) ;
556
- if ( task . configurationProperties . dependsOrder === DependsOrder . sequence ) {
557
- const promiseResult = await promise ;
558
- if ( promiseResult . exitCode === 0 ) {
559
- promise = Promise . resolve ( promiseResult ) ;
560
- } else {
561
- promise = Promise . reject ( promiseResult ) ;
562
- break ;
549
+ if ( ! this . _terminalForTask ) {
550
+ // we already handle dependent tasks when reconnecting, don't create extras
551
+ for ( const dependency of task . configurationProperties . dependsOn ) {
552
+ const dependencyTask = await resolver . resolve ( dependency . uri , dependency . task ! ) ;
553
+ if ( dependencyTask ) {
554
+ this . _adoptConfigurationForDependencyTask ( dependencyTask , task ) ;
555
+ const key = dependencyTask . getMapKey ( ) ;
556
+ let promise = this . _activeTasks [ key ] ? this . _getDependencyPromise ( this . _activeTasks [ key ] ) : undefined ;
557
+ if ( ! promise ) {
558
+ this . _fireTaskEvent ( TaskEvent . create ( TaskEventKind . DependsOnStarted , task ) ) ;
559
+ encounteredDependencies . add ( task . getCommonTaskId ( ) ) ;
560
+ promise = this . _executeDependencyTask ( dependencyTask , resolver , trigger , encounteredDependencies , alreadyResolved ) ;
561
+ }
562
+ promises . push ( promise ) ;
563
+ if ( task . configurationProperties . dependsOrder === DependsOrder . sequence ) {
564
+ const promiseResult = await promise ;
565
+ if ( promiseResult . exitCode === 0 ) {
566
+ promise = Promise . resolve ( promiseResult ) ;
567
+ } else {
568
+ promise = Promise . reject ( promiseResult ) ;
569
+ break ;
570
+ }
563
571
}
572
+ promises . push ( promise ) ;
573
+ } else {
574
+ this . _log ( nls . localize ( 'dependencyFailed' ,
575
+ 'Couldn\'t resolve dependent task \'{0}\' in workspace folder \'{1}\'' ,
576
+ Types . isString ( dependency . task ) ? dependency . task : JSON . stringify ( dependency . task , undefined , 0 ) ,
577
+ dependency . uri . toString ( )
578
+ ) ) ;
579
+ this . _showOutput ( ) ;
564
580
}
565
- promises . push ( promise ) ;
566
- } else {
567
- this . _log ( nls . localize ( 'dependencyFailed' ,
568
- 'Couldn\'t resolve dependent task \'{0}\' in workspace folder \'{1}\'' ,
569
- Types . isString ( dependency . task ) ? dependency . task : JSON . stringify ( dependency . task , undefined , 0 ) ,
570
- dependency . uri . toString ( )
571
- ) ) ;
572
- this . _showOutput ( ) ;
573
581
}
574
582
}
575
583
}
@@ -1065,7 +1073,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
1065
1073
return needsFolderQualification ? task . getQualifiedLabel ( ) : ( task . configurationProperties . name || '' ) ;
1066
1074
}
1067
1075
1068
- private async _createShellLaunchConfig ( task : CustomTask | ContributedTask , workspaceFolder : IWorkspaceFolder | undefined , variableResolver : VariableResolver , platform : Platform . Platform , options : CommandOptions , command : CommandString , args : CommandString [ ] , waitOnExit : boolean | string | ( ( exitCode : number ) => string ) ) : Promise < IShellLaunchConfig | undefined > {
1076
+ private async _createShellLaunchConfig ( task : CustomTask | ContributedTask , workspaceFolder : IWorkspaceFolder | undefined , variableResolver : VariableResolver , platform : Platform . Platform , options : CommandOptions , command : CommandString , args : CommandString [ ] , waitOnExit : WaitOnExitValue ) : Promise < IShellLaunchConfig | undefined > {
1069
1077
let shellLaunchConfig : IShellLaunchConfig ;
1070
1078
const isShellCommand = task . command . runtime === RuntimeType . Shell ;
1071
1079
const needsFolderQualification = this . _contextService . getWorkbenchState ( ) === WorkbenchState . WORKSPACE ;
@@ -1338,24 +1346,10 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
1338
1346
const options = await this . _resolveOptions ( resolver , task . command . options ) ;
1339
1347
const presentationOptions = task . command . presentation ;
1340
1348
1341
- let waitOnExit : boolean | string | ( ( exitCode : number ) => string ) = false ;
1342
1349
if ( ! presentationOptions ) {
1343
1350
throw new Error ( 'Task presentation options should not be undefined here.' ) ;
1344
1351
}
1345
-
1346
- if ( ( presentationOptions . close === undefined ) || ( presentationOptions . close === false ) ) {
1347
- if ( ( presentationOptions . reveal !== RevealKind . Never ) || ! task . configurationProperties . isBackground || ( presentationOptions . close === false ) ) {
1348
- if ( presentationOptions . panel === PanelKind . New ) {
1349
- waitOnExit = taskShellIntegrationWaitOnExitSequence ( nls . localize ( 'closeTerminal' , 'Press any key to close the terminal.' ) ) ;
1350
- } else if ( presentationOptions . showReuseMessage ) {
1351
- waitOnExit = taskShellIntegrationWaitOnExitSequence ( nls . localize ( 'reuseTerminal' , 'Terminal will be reused by tasks, press any key to close it.' ) ) ;
1352
- } else {
1353
- waitOnExit = true ;
1354
- }
1355
- }
1356
- } else {
1357
- waitOnExit = ! presentationOptions . close ;
1358
- }
1352
+ const waitOnExit = getWaitOnExitValue ( presentationOptions , task . configurationProperties ) ;
1359
1353
1360
1354
let command : CommandString | undefined ;
1361
1355
let args : CommandString [ ] | undefined ;
@@ -1384,7 +1378,6 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
1384
1378
return [ undefined , new TaskError ( Severity . Error , nls . localize ( 'TerminalTaskSystem' , 'Can\'t execute a shell command on an UNC drive using cmd.exe.' ) , TaskErrors . UnknownError ) ] ;
1385
1379
}
1386
1380
}
1387
-
1388
1381
const prefersSameTerminal = presentationOptions . panel === PanelKind . Dedicated ;
1389
1382
const allowsSharedTerminal = presentationOptions . panel === PanelKind . Shared ;
1390
1383
const group = presentationOptions . group ;
@@ -1787,6 +1780,21 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
1787
1780
}
1788
1781
}
1789
1782
1783
+ function getWaitOnExitValue ( presentationOptions : IPresentationOptions , configurationProperties : IConfigurationProperties ) {
1784
+ if ( ( presentationOptions . close === undefined ) || ( presentationOptions . close === false ) ) {
1785
+ if ( ( presentationOptions . reveal !== RevealKind . Never ) || ! configurationProperties . isBackground || ( presentationOptions . close === false ) ) {
1786
+ if ( presentationOptions . panel === PanelKind . New ) {
1787
+ return taskShellIntegrationWaitOnExitSequence ( nls . localize ( 'closeTerminal' , 'Press any key to close the terminal.' ) ) ;
1788
+ } else if ( presentationOptions . showReuseMessage ) {
1789
+ return taskShellIntegrationWaitOnExitSequence ( nls . localize ( 'reuseTerminal' , 'Terminal will be reused by tasks, press any key to close it.' ) ) ;
1790
+ } else {
1791
+ return true ;
1792
+ }
1793
+ }
1794
+ }
1795
+ return ! presentationOptions . close ;
1796
+ }
1797
+
1790
1798
function taskShellIntegrationWaitOnExitSequence ( message : string ) : ( exitCode : number ) => string {
1791
1799
return ( exitCode ) => {
1792
1800
return `${ VSCodeSequence ( VSCodeOscPt . CommandFinished , exitCode . toString ( ) ) } ${ message } ` ;
0 commit comments