From de7b06e8375c20e4ab00ec75e8b3c35ebf7ffae8 Mon Sep 17 00:00:00 2001 From: vince-fugnitto Date: Thu, 2 Jan 2020 16:24:04 -0500 Subject: [PATCH] Add ability to restart running task Fixes #5330 - adds a new command and menu item to `restart running task`. - updates the task-service methods `restartTask` and `terminateTask` to make them public so others may call them. Signed-off-by: vince-fugnitto --- packages/task/src/browser/quick-open-task.ts | 97 ++++++++++++++++++- .../src/browser/task-frontend-contribution.ts | 26 ++++- .../task/src/browser/task-frontend-module.ts | 3 +- packages/task/src/browser/task-service.ts | 4 +- 4 files changed, 124 insertions(+), 6 deletions(-) diff --git a/packages/task/src/browser/quick-open-task.ts b/packages/task/src/browser/quick-open-task.ts index 46f14373d2ddf..8fd334c4d4d64 100644 --- a/packages/task/src/browser/quick-open-task.ts +++ b/packages/task/src/browser/quick-open-task.ts @@ -19,7 +19,7 @@ import { TaskService } from './task-service'; import { TaskInfo, TaskConfiguration, TaskCustomization } from '../common/task-protocol'; import { TaskDefinitionRegistry } from './task-definition-registry'; import URI from '@theia/core/lib/common/uri'; -import { QuickOpenHandler, QuickOpenService, QuickOpenOptions, QuickOpenBaseAction } from '@theia/core/lib/browser'; +import { QuickOpenHandler, QuickOpenService, QuickOpenOptions, QuickOpenBaseAction, LabelProvider } from '@theia/core/lib/browser'; import { WorkspaceService } from '@theia/workspace/lib/browser'; import { TerminalService } from '@theia/terminal/lib/browser/base/terminal-service'; import { FileSystem } from '@theia/filesystem/lib/common'; @@ -721,3 +721,98 @@ export class TaskRunningQuickOpen implements QuickOpenModel { }); } } + +export class TaskRestartRunningQuickOpenItem extends QuickOpenItem { + + constructor( + protected readonly taskInfo: TaskInfo, + protected readonly taskService: TaskService, + protected readonly taskNameResolver: TaskNameResolver, + protected readonly taskSourceResolver: TaskSourceResolver, + protected readonly taskDefinitionRegistry: TaskDefinitionRegistry, + protected readonly labelProvider: LabelProvider, + protected readonly isMulti: boolean, + public readonly options: QuickOpenGroupItemOptions, + ) { + super(options); + } + + getLabel(): string { + return this.taskNameResolver.resolve(this.taskInfo.config); + } + + getDescription(): string { + if (!this.isMulti) { + return ''; + } + const source = this.taskSourceResolver.resolve(this.taskInfo.config); + return source ? this.labelProvider.getName(new URI(source)) : ''; + } + + run(mode: QuickOpenMode): boolean { + if (mode !== QuickOpenMode.OPEN) { + return false; + } + this.taskService.restartTask(this.taskInfo); + return true; + } +} + +@injectable() +export class TaskRestartRunningQuickOpen implements QuickOpenModel { + + @inject(LabelProvider) + protected readonly labelProvider: LabelProvider; + + @inject(QuickOpenService) + protected readonly quickOpenService: QuickOpenService; + + @inject(TaskDefinitionRegistry) + protected readonly taskDefinitionRegistry: TaskDefinitionRegistry; + + @inject(TaskNameResolver) + protected readonly taskNameResolver: TaskNameResolver; + + @inject(TaskSourceResolver) + protected readonly taskSourceResolver: TaskSourceResolver; + + @inject(TaskService) + protected readonly taskService: TaskService; + + @inject(WorkspaceService) + protected readonly workspaceService: WorkspaceService; + + async onType(_lookFor: string, acceptor: (items: QuickOpenItem[]) => void): Promise { + const items = []; + const runningTasks: TaskInfo[] = await this.taskService.getRunningTasks(); + const isMulti: boolean = this.workspaceService.isMultiRootWorkspaceOpened; + if (runningTasks.length <= 0) { + items.push(new QuickOpenItem({ + label: 'No task to restart', + run: (): boolean => false, + })); + } else { + runningTasks.forEach((task: TaskInfo) => { + items.push(new TaskRestartRunningQuickOpenItem( + task, + this.taskService, + this.taskNameResolver, + this.taskSourceResolver, + this.taskDefinitionRegistry, + this.labelProvider, + isMulti, + {}, + )); + }); + } + acceptor(items); + } + + async open(): Promise { + this.quickOpenService.open(this, { + placeholder: 'Select task to restart', + fuzzyMatchLabel: true, + fuzzyMatchDescription: true, + }); + } +} diff --git a/packages/task/src/browser/task-frontend-contribution.ts b/packages/task/src/browser/task-frontend-contribution.ts index 2106c0af76a0d..acfd7e21ae957 100644 --- a/packages/task/src/browser/task-frontend-contribution.ts +++ b/packages/task/src/browser/task-frontend-contribution.ts @@ -16,7 +16,7 @@ import { inject, injectable, named, postConstruct } from 'inversify'; import { ILogger, ContributionProvider } from '@theia/core/lib/common'; -import { QuickOpenTask, TaskTerminateQuickOpen, TaskRunningQuickOpen } from './quick-open-task'; +import { QuickOpenTask, TaskTerminateQuickOpen, TaskRunningQuickOpen, TaskRestartRunningQuickOpen } from './quick-open-task'; import { CommandContribution, Command, CommandRegistry, MenuContribution, MenuModelRegistry } from '@theia/core/lib/common'; import { FrontendApplication, FrontendApplicationContribution, QuickOpenContribution, @@ -97,6 +97,12 @@ export namespace TaskCommands { category: TASK_CATEGORY, label: 'Terminate Task' }; + + export const TASK_RESTART_RUNNING: Command = { + id: 'task:restart-running', + category: TASK_CATEGORY, + label: 'Restart Running Task...' + }; } const TASKS_STORAGE_KEY = 'tasks'; @@ -142,6 +148,9 @@ export class TaskFrontendContribution implements CommandContribution, MenuContri @inject(TaskTerminateQuickOpen) protected readonly taskTerminateQuickOpen: TaskTerminateQuickOpen; + @inject(TaskRestartRunningQuickOpen) + protected readonly taskRestartRunningQuickOpen: TaskRestartRunningQuickOpen; + @inject(TaskWatcher) protected readonly taskWatcher: TaskWatcher; @@ -293,6 +302,13 @@ export class TaskFrontendContribution implements CommandContribution, MenuContri execute: () => this.taskTerminateQuickOpen.open() } ); + + registry.registerCommand( + TaskCommands.TASK_RESTART_RUNNING, + { + execute: () => this.taskRestartRunningQuickOpen.open() + } + ); } registerMenus(menus: MenuModelRegistry): void { @@ -332,10 +348,16 @@ export class TaskFrontendContribution implements CommandContribution, MenuContri order: '0' }); + menus.registerMenuAction(TerminalMenus.TERMINAL_TASKS_INFO, { + commandId: TaskCommands.TASK_RESTART_RUNNING.id, + label: TaskCommands.TASK_RESTART_RUNNING.label, + order: '1' + }); + menus.registerMenuAction(TerminalMenus.TERMINAL_TASKS_INFO, { commandId: TaskCommands.TASK_TERMINATE.id, label: 'Terminate Task...', - order: '1' + order: '2' }); menus.registerMenuAction(TerminalMenus.TERMINAL_TASKS_CONFIG, { diff --git a/packages/task/src/browser/task-frontend-module.ts b/packages/task/src/browser/task-frontend-module.ts index 38c99f291eab0..71e002c103aa0 100644 --- a/packages/task/src/browser/task-frontend-module.ts +++ b/packages/task/src/browser/task-frontend-module.ts @@ -18,7 +18,7 @@ import { ContainerModule } from 'inversify'; import { FrontendApplicationContribution, QuickOpenContribution, KeybindingContribution } from '@theia/core/lib/browser'; import { CommandContribution, MenuContribution, bindContributionProvider } from '@theia/core/lib/common'; import { WebSocketConnectionProvider } from '@theia/core/lib/browser/messaging'; -import { QuickOpenTask, TaskTerminateQuickOpen, TaskRunningQuickOpen, TaskActionProvider, ConfigureTaskAction } from './quick-open-task'; +import { QuickOpenTask, TaskTerminateQuickOpen, TaskRestartRunningQuickOpen, TaskRunningQuickOpen, TaskActionProvider, ConfigureTaskAction } from './quick-open-task'; import { TaskContribution, TaskProviderRegistry, TaskResolverRegistry } from './task-contribution'; import { TaskService } from './task-service'; import { TaskConfigurations } from './task-configurations'; @@ -53,6 +53,7 @@ export default new ContainerModule(bind => { bind(QuickOpenTask).toSelf().inSingletonScope(); bind(TaskRunningQuickOpen).toSelf().inSingletonScope(); bind(TaskTerminateQuickOpen).toSelf().inSingletonScope(); + bind(TaskRestartRunningQuickOpen).toSelf().inSingletonScope(); bind(TaskConfigurations).toSelf().inSingletonScope(); bind(ProvidedTaskConfigurations).toSelf().inSingletonScope(); bind(TaskConfigurationManager).toSelf().inSingletonScope(); diff --git a/packages/task/src/browser/task-service.ts b/packages/task/src/browser/task-service.ts index 71ebe1bb9f528..9a8add08576c2 100644 --- a/packages/task/src/browser/task-service.ts +++ b/packages/task/src/browser/task-service.ts @@ -674,7 +674,7 @@ export class TaskService implements TaskConfigurationClient { * Terminates a task that is actively running. * @param activeTaskInfo the TaskInfo of the task that is actively running */ - protected async terminateTask(activeTaskInfo: TaskInfo): Promise { + async terminateTask(activeTaskInfo: TaskInfo): Promise { const taskId = activeTaskInfo.taskId; return this.kill(taskId); } @@ -683,7 +683,7 @@ export class TaskService implements TaskConfigurationClient { * Terminates a task that is actively running, and restarts it. * @param activeTaskInfo the TaskInfo of the task that is actively running */ - protected async restartTask(activeTaskInfo: TaskInfo, option?: RunTaskOption): Promise { + async restartTask(activeTaskInfo: TaskInfo, option?: RunTaskOption): Promise { await this.terminateTask(activeTaskInfo); return this.doRunTask(activeTaskInfo.config, option); }