@@ -56,7 +56,7 @@ import {
5656 TaskSorter , TaskIdentifier , KeyedTaskIdentifier , TASK_RUNNING_STATE , TaskRunSource ,
5757 KeyedTaskIdentifier as NKeyedTaskIdentifier , TaskDefinition
5858} from 'vs/workbench/contrib/tasks/common/tasks' ;
59- import { ITaskService , ITaskProvider , ProblemMatcherRunOptions , CustomizationProperties , TaskFilter , WorkspaceFolderTaskResult , USER_TASKS_GROUP_KEY } from 'vs/workbench/contrib/tasks/common/taskService' ;
59+ import { ITaskService , ITaskProvider , ProblemMatcherRunOptions , CustomizationProperties , TaskFilter , WorkspaceFolderTaskResult , USER_TASKS_GROUP_KEY , CustomExecutionSupportedContext , ShellExecutionSupportedContext , ProcessExecutionSupportedContext } from 'vs/workbench/contrib/tasks/common/taskService' ;
6060import { getTemplates as getTaskTemplates } from 'vs/workbench/contrib/tasks/common/taskTemplates' ;
6161
6262import * as TaskConfig from '../common/taskConfiguration' ;
@@ -248,7 +248,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
248248 @IHostService private readonly _hostService : IHostService ,
249249 @IDialogService private readonly dialogService : IDialogService ,
250250 @INotificationService private readonly notificationService : INotificationService ,
251- @IContextKeyService contextKeyService : IContextKeyService ,
251+ @IContextKeyService protected readonly contextKeyService : IContextKeyService ,
252252 @IWorkbenchEnvironmentService private readonly environmentService : IWorkbenchEnvironmentService ,
253253 @ITerminalInstanceService private readonly terminalInstanceService : ITerminalInstanceService ,
254254 @IPathService private readonly pathService : IPathService ,
@@ -331,6 +331,16 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
331331 }
332332 return task . _label ;
333333 } ) ;
334+ this . setExecutionContexts ( ) ;
335+ }
336+
337+ protected setExecutionContexts ( custom : boolean = true , shell : boolean = false , process : boolean = false ) : void {
338+ const customContext = CustomExecutionSupportedContext . bindTo ( this . contextKeyService ) ;
339+ customContext . set ( custom ) ;
340+ const shellContext = ShellExecutionSupportedContext . bindTo ( this . contextKeyService ) ;
341+ shellContext . set ( shell ) ;
342+ const processContext = ProcessExecutionSupportedContext . bindTo ( this . contextKeyService ) ;
343+ processContext . set ( process ) ;
334344 }
335345
336346 public get onDidStateChange ( ) : Event < TaskEvent > {
@@ -556,14 +566,27 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
556566 public async tryResolveTask ( configuringTask : ConfiguringTask ) : Promise < Task | undefined > {
557567 await Promise . all ( [ this . extensionService . activateByEvent ( 'onCommand:workbench.action.tasks.runTask' ) , this . extensionService . whenInstalledExtensionsRegistered ( ) ] ) ;
558568 let matchingProvider : ITaskProvider | undefined ;
569+ let matchingProviderUnavailable : boolean = false ;
559570 for ( const [ handle , provider ] of this . _providers ) {
560- if ( configuringTask . type === this . _providerTypes . get ( handle ) ) {
571+ const providerType = this . _providerTypes . get ( handle ) ;
572+ if ( configuringTask . type === providerType ) {
573+ if ( providerType && ! this . isTaskProviderEnabled ( providerType ) ) {
574+ matchingProviderUnavailable = true ;
575+ continue ;
576+ }
561577 matchingProvider = provider ;
562578 break ;
563579 }
564580 }
565581
566582 if ( ! matchingProvider ) {
583+ if ( matchingProviderUnavailable ) {
584+ this . _outputChannel . append ( nls . localize (
585+ 'TaskService.providerUnavailable' ,
586+ 'Warning: {0} tasks are unavailable in the current environment.\n' ,
587+ configuringTask . configures . type
588+ ) ) ;
589+ }
567590 return ;
568591 }
569592
@@ -624,7 +647,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
624647 if ( this . isProvideTasksEnabled ( ) ) {
625648 for ( const [ handle ] of this . _providers ) {
626649 const type = this . _providerTypes . get ( handle ) ;
627- if ( type ) {
650+ if ( type && this . isTaskProviderEnabled ( type ) ) {
628651 types . push ( type ) ;
629652 }
630653 }
@@ -1559,6 +1582,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
15591582
15601583 protected abstract getTaskSystem ( ) : ITaskSystem ;
15611584
1585+ private isTaskProviderEnabled ( type : string ) {
1586+ const definition = TaskDefinitionRegistry . get ( type ) ;
1587+ return ! definition . when || this . contextKeyService . contextMatchesRules ( definition . when ) ;
1588+ }
1589+
15621590 private getGroupedTasks ( type ?: string ) : Promise < TaskMap > {
15631591 const needsRecentTasksMigration = this . needsRecentTasksMigration ( ) ;
15641592 return Promise . all ( [ this . extensionService . activateByEvent ( 'onCommand:workbench.action.tasks.runTask' ) , this . extensionService . whenInstalledExtensionsRegistered ( ) ] ) . then ( ( ) => {
@@ -1596,7 +1624,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
15961624 } ;
15971625 if ( this . isProvideTasksEnabled ( ) && ( this . schemaVersion === JsonSchemaVersion . V2_0_0 ) && ( this . _providers . size > 0 ) ) {
15981626 for ( const [ handle , provider ] of this . _providers ) {
1599- if ( ( type === undefined ) || ( type === this . _providerTypes . get ( handle ) ) ) {
1627+ const providerType = this . _providerTypes . get ( handle ) ;
1628+ if ( ( type === undefined ) || ( type === providerType ) ) {
1629+ if ( providerType && ! this . isTaskProviderEnabled ( providerType ) ) {
1630+ continue ;
1631+ }
16001632 counter ++ ;
16011633 provider . provideTasks ( validTypes ) . then ( ( taskSet : TaskSet ) => {
16021634 // Check that the tasks provided are of the correct type
@@ -1699,8 +1731,16 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
16991731 return ;
17001732 }
17011733
1734+ let requiredTaskProviderUnavailable : boolean = false ;
1735+
17021736 for ( const [ handle , provider ] of this . _providers ) {
1703- if ( configuringTask . type === this . _providerTypes . get ( handle ) ) {
1737+ const providerType = this . _providerTypes . get ( handle ) ;
1738+ if ( configuringTask . type === providerType ) {
1739+ if ( providerType && ! this . isTaskProviderEnabled ( providerType ) ) {
1740+ requiredTaskProviderUnavailable = true ;
1741+ continue ;
1742+ }
1743+
17041744 try {
17051745 const resolvedTask = await provider . resolveTask ( configuringTask ) ;
17061746 if ( resolvedTask && ( resolvedTask . _id === configuringTask . _id ) ) {
@@ -1713,13 +1753,21 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
17131753 }
17141754 }
17151755
1716- this . _outputChannel . append ( nls . localize (
1717- 'TaskService.noConfiguration' ,
1718- 'Error: The {0} task detection didn\'t contribute a task for the following configuration:\n{1}\nThe task will be ignored.\n' ,
1719- configuringTask . configures . type ,
1720- JSON . stringify ( configuringTask . _source . config . element , undefined , 4 )
1721- ) ) ;
1722- this . showOutput ( ) ;
1756+ if ( requiredTaskProviderUnavailable ) {
1757+ this . _outputChannel . append ( nls . localize (
1758+ 'TaskService.providerUnavailable' ,
1759+ 'Warning: {0} tasks are unavailable in the current environment.\n' ,
1760+ configuringTask . configures . type
1761+ ) ) ;
1762+ } else {
1763+ this . _outputChannel . append ( nls . localize (
1764+ 'TaskService.noConfiguration' ,
1765+ 'Error: The {0} task detection didn\'t contribute a task for the following configuration:\n{1}\nThe task will be ignored.\n' ,
1766+ configuringTask . configures . type ,
1767+ JSON . stringify ( configuringTask . _source . config . element , undefined , 4 )
1768+ ) ) ;
1769+ this . showOutput ( ) ;
1770+ }
17231771 } ) ;
17241772
17251773 await Promise . all ( unUsedConfigurationPromises ) ;
@@ -1831,9 +1879,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
18311879 return ProblemMatcherRegistry . onReady ( ) . then ( async ( ) : Promise < WorkspaceFolderTaskResult > => {
18321880 let taskSystemInfo : TaskSystemInfo | undefined = this . _taskSystemInfos . get ( workspaceFolder . uri . scheme ) ;
18331881 let problemReporter = new ProblemReporter ( this . _outputChannel ) ;
1834- let parseResult = TaskConfig . parse ( workspaceFolder , undefined , taskSystemInfo ? taskSystemInfo . platform : Platform . platform , workspaceFolderConfiguration . config ! , problemReporter , TaskConfig . TaskConfigSource . TasksJson ) ;
1882+ let parseResult = TaskConfig . parse ( workspaceFolder , undefined , taskSystemInfo ? taskSystemInfo . platform : Platform . platform , workspaceFolderConfiguration . config ! , problemReporter , TaskConfig . TaskConfigSource . TasksJson , this . contextKeyService ) ;
18351883 let hasErrors = false ;
1836- if ( ! parseResult . validationStatus . isOK ( ) ) {
1884+ if ( ! parseResult . validationStatus . isOK ( ) && ( parseResult . validationStatus . state !== ValidationState . Info ) ) {
18371885 hasErrors = true ;
18381886 this . showOutput ( runSource ) ;
18391887 }
@@ -1928,9 +1976,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
19281976 }
19291977 let taskSystemInfo : TaskSystemInfo | undefined = workspaceFolder ? this . _taskSystemInfos . get ( workspaceFolder . uri . scheme ) : undefined ;
19301978 let problemReporter = new ProblemReporter ( this . _outputChannel ) ;
1931- let parseResult = TaskConfig . parse ( workspaceFolder , this . _workspace , taskSystemInfo ? taskSystemInfo . platform : Platform . platform , config , problemReporter , source , isRecentTask ) ;
1979+ let parseResult = TaskConfig . parse ( workspaceFolder , this . _workspace , taskSystemInfo ? taskSystemInfo . platform : Platform . platform , config , problemReporter , source , this . contextKeyService , isRecentTask ) ;
19321980 let hasErrors = false ;
1933- if ( ! parseResult . validationStatus . isOK ( ) ) {
1981+ if ( ! parseResult . validationStatus . isOK ( ) && ( parseResult . validationStatus . state !== ValidationState . Info ) ) {
19341982 this . showOutput ( runSource ) ;
19351983 hasErrors = true ;
19361984 }
0 commit comments