提交 3ea2c216 编写于 作者: D Dirk Baeumer

More work to make v2 the default

上级 de5bca37
......@@ -192,26 +192,26 @@ namespace ProblemMatcher {
}
namespace RevealKind {
export function from(value: vscode.RevealKind): TaskSystem.ShowOutput {
export function from(value: vscode.RevealKind): TaskSystem.RevealKind {
if (value === void 0 || value === null) {
return TaskSystem.ShowOutput.Always;
return TaskSystem.RevealKind.Always;
}
switch (value) {
case types.RevealKind.Silent:
return TaskSystem.ShowOutput.Silent;
return TaskSystem.RevealKind.Silent;
case types.RevealKind.Never:
return TaskSystem.ShowOutput.Never;
return TaskSystem.RevealKind.Never;
}
return TaskSystem.ShowOutput.Always;
return TaskSystem.RevealKind.Always;
}
}
namespace TerminalBehaviour {
export function from(value: vscode.TerminalBehaviour): { showOutput: TaskSystem.ShowOutput, echo: boolean } {
export function from(value: vscode.TerminalBehaviour): TaskSystem.TerminalBehavior {
if (value === void 0 || value === null) {
return { showOutput: TaskSystem.ShowOutput.Always, echo: false };
return { reveal: TaskSystem.RevealKind.Always, echo: false };
}
return { showOutput: RevealKind.from(value.reveal), echo: !!value.echo };
return { reveal: RevealKind.from(value.reveal), echo: !!value.echo };
}
}
......@@ -302,8 +302,6 @@ namespace Tasks {
if (command === void 0) {
return undefined;
}
let behaviour = TerminalBehaviour.from(task.terminal);
command.echo = behaviour.echo;
let result: TaskSystem.Task = {
_id: uuidMap.getUUID(task.identifier),
_source: { kind: TaskSystem.TaskSourceKind.Extension, detail: extension.id },
......@@ -311,7 +309,6 @@ namespace Tasks {
identifier: task.identifier,
group: types.TaskGroup.is(task.group) ? task.group : undefined,
command: command,
showOutput: behaviour.showOutput,
isBackground: !!task.isBackground,
suppressTaskName: true,
problemMatchers: ProblemMatcher.from(task.problemMatchers)
......@@ -327,7 +324,7 @@ namespace Tasks {
name: value.process,
args: Strings.from(value.args),
isShellCommand: false,
echo: false,
terminal: TerminalBehaviour.from(value.terminal)
};
if (value.options) {
result.options = CommandOptions.from(value.options);
......@@ -342,7 +339,7 @@ namespace Tasks {
let result: TaskSystem.CommandConfiguration = {
name: value.commandLine,
isShellCommand: ShellConfiguration.from(value.options),
echo: false
terminal: TerminalBehaviour.from(value.terminal)
};
if (value.options) {
result.options = CommandOptions.from(value.options);
......
......@@ -7,6 +7,7 @@
import nls = require('vs/nls');
import Filters = require('vs/base/common/filters');
import { TPromise } from 'vs/base/common/winjs.base';
import { Action, IAction } from 'vs/base/common/actions';
import Quickopen = require('vs/workbench/browser/quickopen');
import QuickOpen = require('vs/base/parts/quickopen/common/quickOpen');
import Model = require('vs/base/parts/quickopen/browser/quickOpenModel');
......@@ -14,21 +15,26 @@ import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
import { Task, TaskSourceKind } from 'vs/workbench/parts/tasks/common/tasks';
import { ITaskService } from 'vs/workbench/parts/tasks/common/taskService';
import { ActionBarContributor } from 'vs/workbench/browser/actionBarRegistry';
export class TaskEntry extends Model.QuickOpenEntry {
constructor(protected taskService: ITaskService, protected task: Task, highlights: Model.IHighlight[] = []) {
constructor(protected taskService: ITaskService, protected _task: Task, highlights: Model.IHighlight[] = []) {
super(highlights);
this.task = task;
this._task = _task;
}
public getLabel(): string {
return this.task.name;
return this._task.name;
}
public getAriaLabel(): string {
return nls.localize('entryAriaLabel', "{0}, tasks", this.getLabel());
}
public get task(): Task {
return this._task;
}
}
export class TaskGroupEntry extends Model.QuickOpenEntryGroup {
......@@ -112,4 +118,53 @@ export abstract class QuickOpenHandler extends Quickopen.QuickOpenHandler {
autoFocusFirstEntry: !!input
};
}
}
class CustomizeTaskAction extends Action {
private static ID = 'workbench.action.tasks.customizeTask';
private static LABEL = nls.localize('customizeTask', "Customize Task");
constructor() {
super(CustomizeTaskAction.ID, CustomizeTaskAction.LABEL);
this.updateClass();
}
public updateClass(): void {
this.class = 'quick-open-sidebyside-vertical';
}
public run(context: any): TPromise<any> {
return TPromise.as(false);
}
}
export class QuickOpenActionContributor extends ActionBarContributor {
constructor() {
super();
}
public hasActions(context: any): boolean {
const entry = this.getEntry(context);
return !!entry;
}
public getActions(context: any): IAction[] {
const actions: Action[] = [];
const entry = this.getEntry(context);
if (entry && entry.task._source.kind === TaskSourceKind.Extension) {
actions.push(new CustomizeTaskAction());
}
return actions;
}
private getEntry(context: any): TaskEntry {
if (!context || !(context.element instanceof TaskEntry)) {
return undefined;
}
return context.element as TaskEntry;
}
}
\ No newline at end of file
......@@ -24,7 +24,7 @@ class TaskEntry extends base.TaskEntry {
if (mode === QuickOpen.Mode.PREVIEW) {
return false;
}
this.taskService.restart(this.task._id);
this.taskService.restart(this._task._id);
return true;
}
}
......
......@@ -26,7 +26,7 @@ class TaskEntry extends base.TaskEntry {
if (mode === QuickOpen.Mode.PREVIEW) {
return false;
}
this.taskService.run(this.task);
this.taskService.run(this._task);
return true;
}
}
......
......@@ -24,7 +24,7 @@ class TaskEntry extends base.TaskEntry {
if (mode === QuickOpen.Mode.PREVIEW) {
return false;
}
this.taskService.terminate(this.task._id);
this.taskService.terminate(this._task._id);
return true;
}
}
......
......@@ -189,6 +189,21 @@ export interface BaseTaskRunnerConfiguration {
*/
echoCommand?: boolean;
/**
* Controls the behavior of the used terminal
*/
terminal?: {
/**
* The terminal should echo the run command.
*/
echo?: boolean;
/**
* Controls whether or not the terminal is reveal if a task
* is executed.
*/
reveal?: string;
};
/**
* If set to false the task name is added as an additional argument to the
* command when executed. If set to true the task name is suppressed. If
......@@ -402,12 +417,19 @@ namespace ShellConfiguration {
}
namespace CommandConfiguration {
interface TerminalBehavior {
echo?: boolean;
reveal?: string;
}
interface BaseCommandConfiguationShape {
command?: string;
isShellCommand?: boolean | ShellConfiguration;
args?: string[];
options?: ProcessConfig.CommandOptions;
echoCommand?: boolean;
showOutput?: string;
terminal?: TerminalBehavior;
taskSelector?: string;
}
......@@ -417,6 +439,70 @@ namespace CommandConfiguration {
linux?: BaseCommandConfiguationShape;
}
export namespace TerminalBehavior {
export function from(this: void, config: BaseCommandConfiguationShape, context: ParseContext): Tasks.TerminalBehavior {
let echo: boolean = undefined;
let reveal: Tasks.RevealKind = undefined;
if (Types.isBoolean(config.echoCommand)) {
echo = config.echoCommand;
}
if (Types.isString(config.showOutput)) {
reveal = Tasks.RevealKind.fromString(config.showOutput);
}
if (config.terminal) {
if (Types.isBoolean(config.terminal.echo)) {
echo = config.terminal.echo;
}
if (Types.isString(config.terminal.reveal)) {
reveal = Tasks.RevealKind.fromString(config.terminal.reveal);
}
}
if (echo === void 0 && reveal === void 0) {
return undefined;
}
return { echo, reveal };
}
export function merge(target: Tasks.TerminalBehavior, source: Tasks.TerminalBehavior): Tasks.TerminalBehavior {
if (isEmpty(source)) {
return target;
}
if (isEmpty(target)) {
return source;
}
mergeProperty(target, source, 'echo');
mergeProperty(target, source, 'reveal');
return target;
}
export function fillDefault(value: Tasks.TerminalBehavior): Tasks.TerminalBehavior {
if (value && Object.isFrozen(value)) {
return value;
}
if (value === void 0) {
return { echo: false, reveal: Tasks.RevealKind.Always };
}
if (value.echo === void 0) {
value.echo = false;
}
if (value.reveal === void 0) {
value.reveal = Tasks.RevealKind.Always;
}
return value;
}
export function freeze(value: Tasks.TerminalBehavior): void {
if (value === void 0) {
return;
}
Object.freeze(value);
}
function isEmpty(this: void, value: Tasks.TerminalBehavior): boolean {
return !value || value.echo === void 0 && value.reveal === void 0;
}
}
export function from(this: void, config: CommandConfiguationShape, context: ParseContext): Tasks.CommandConfiguration {
let result: Tasks.CommandConfiguration = fromBase(config, context);
......@@ -439,7 +525,7 @@ namespace CommandConfiguration {
let result: Tasks.CommandConfiguration = {
name: undefined,
isShellCommand: undefined,
echo: undefined
terminal: undefined
};
if (Types.isString(config.command)) {
result.name = config.command;
......@@ -464,8 +550,9 @@ namespace CommandConfiguration {
if (config.options !== void 0) {
result.options = CommandOptions.from(config.options, context);
}
if (Types.isBoolean(config.echoCommand)) {
result.echo = config.echoCommand;
let terminal = TerminalBehavior.from(config, context);
if (terminal) {
result.terminal = terminal;
}
if (Types.isString(config.taskSelector)) {
result.taskSelector = config.taskSelector;
......@@ -474,11 +561,13 @@ namespace CommandConfiguration {
}
export function isEmpty(value: Tasks.CommandConfiguration): boolean {
return !value || value.name === void 0 && value.isShellCommand === void 0 && value.args === void 0 && CommandOptions.isEmpty(value.options) && value.echo === void 0;
return !value || value.name === void 0 && value.isShellCommand === void 0 && value.args === void 0 && CommandOptions.isEmpty(value.options) && value.terminal === void 0;
}
export function onlyEcho(value: Tasks.CommandConfiguration): boolean {
return value && value.echo !== void 0 && value.name === void 0 && value.isShellCommand === void 0 && value.args === void 0 && CommandOptions.isEmpty(value.options);
export function onlyTerminalBehaviour(value: Tasks.CommandConfiguration): boolean {
return value &&
value.terminal && (value.terminal.echo !== void 0 || value.terminal.reveal === void 0) &&
value.name === void 0 && value.isShellCommand === void 0 && value.args === void 0 && CommandOptions.isEmpty(value.options);
}
export function merge(target: Tasks.CommandConfiguration, source: Tasks.CommandConfiguration): Tasks.CommandConfiguration {
......@@ -500,7 +589,7 @@ namespace CommandConfiguration {
target.isShellCommand = source.isShellCommand;
}
mergeProperty(target, source, 'echo');
target.terminal = TerminalBehavior.merge(target.terminal, source.terminal);
mergeProperty(target, source, 'taskSelector');
if (source.args !== void 0) {
if (target.args === void 0) {
......@@ -520,9 +609,7 @@ namespace CommandConfiguration {
if (value.name !== void 0 && value.isShellCommand === void 0) {
value.isShellCommand = false;
}
if (value.echo === void 0) {
value.echo = false;
}
value.terminal = TerminalBehavior.fillDefault(value.terminal);
if (value.args === void 0) {
value.args = EMPTY_ARRAY;
}
......@@ -539,6 +626,9 @@ namespace CommandConfiguration {
if (value.options) {
CommandOptions.freeze(value.options);
}
if (value.terminal) {
TerminalBehavior.freeze(value.terminal);
}
if (ShellConfiguration.is(value.isShellCommand)) {
ShellConfiguration.freeze(value.isShellCommand);
}
......@@ -660,15 +750,16 @@ namespace TaskDescription {
let problemMatchers = ProblemMatcherConverter.from(externalTask.problemMatcher, context);
let command: Tasks.CommandConfiguration = externalTask.command !== void 0
? CommandConfiguration.from(externalTask, context)
: externalTask.echoCommand !== void 0 ? { name: undefined, isShellCommand: undefined, echo: !!externalTask.echoCommand } : undefined;
: externalTask.echoCommand !== void 0
? { name: undefined, isShellCommand: undefined, terminal: CommandConfiguration.TerminalBehavior.from(externalTask, context) }
: undefined;
let identifer = Types.isString(externalTask.identifier) ? externalTask.identifier : taskName;
let task: Tasks.Task = {
_id: UUID.generateUuid(),
_source: source,
name: taskName,
identifier: identifer,
command,
showOutput: undefined
command
};
if (externalTask.command === void 0 && Types.isStringArray(externalTask.args)) {
task.args = externalTask.args.slice();
......@@ -682,9 +773,6 @@ namespace TaskDescription {
if (externalTask.promptOnClose !== void 0) {
task.promptOnClose = !!externalTask.promptOnClose;
}
if (Types.isString(externalTask.showOutput)) {
task.showOutput = Tasks.ShowOutput.fromString(externalTask.showOutput);
}
if (externalTask.command !== void 0) {
// if the task has its own command then we suppress the
// task name by default.
......@@ -793,13 +881,13 @@ namespace TaskDescription {
if (CommandConfiguration.isEmpty(task.command) && !CommandConfiguration.isEmpty(globals.command) && globals.command.name !== void 0) {
task.command = globals.command;
}
if (CommandConfiguration.onlyEcho(task.command)) {
if (CommandConfiguration.onlyTerminalBehaviour(task.command)) {
// The globals can have a echo set which would override the local echo
// Saves the need of a additional fill method. But might be necessary
// at some point.
let oldEcho = task.command.echo;
let oldTerminal = Objects.clone(task.command.terminal);
CommandConfiguration.merge(task.command, globals.command);
task.command.echo = oldEcho;
task.command.terminal = oldTerminal;
}
}
// promptOnClose is inferred from isBackground if available
......@@ -809,9 +897,6 @@ namespace TaskDescription {
if (task.suppressTaskName === void 0 && globals.suppressTaskName !== void 0) {
task.suppressTaskName = globals.suppressTaskName;
}
if (task.showOutput === void 0 && globals.showOutput !== void 0) {
task.showOutput = globals.showOutput;
}
}
export function fillDefaults(task: Tasks.Task): void {
......@@ -828,9 +913,6 @@ namespace TaskDescription {
if (task.isBackground === void 0) {
task.isBackground = false;
}
if (task.showOutput === void 0) {
task.showOutput = Tasks.ShowOutput.Always;
}
if (task.problemMatchers === void 0) {
task.problemMatchers = EMPTY_ARRAY;
}
......@@ -876,7 +958,6 @@ namespace TaskDescription {
mergeProperty(target, source, 'args');
mergeProperty(target, source, 'isBackground');
mergeProperty(target, source, 'promptOnClose');
mergeProperty(target, source, 'showOutput');
mergeProperty(target, source, 'dependsOn');
mergeProperty(target, source, 'problemMatchers');
return target;
......@@ -887,7 +968,6 @@ interface Globals {
command?: Tasks.CommandConfiguration;
promptOnClose?: boolean;
suppressTaskName?: boolean;
showOutput?: Tasks.ShowOutput;
}
namespace Globals {
......@@ -916,9 +996,6 @@ namespace Globals {
export function fromBase(this: void, config: BaseTaskRunnerConfiguration, context: ParseContext): Globals {
let result: Globals = {};
if (Types.isString(config.showOutput)) {
result.showOutput = Tasks.ShowOutput.fromString(config.showOutput);
}
if (config.suppressTaskName !== void 0) {
result.suppressTaskName = !!config.suppressTaskName;
}
......@@ -929,7 +1006,7 @@ namespace Globals {
}
export function isEmpty(value: Globals): boolean {
return !value || value.command === void 0 && value.promptOnClose === void 0 && value.showOutput === void 0 && value.suppressTaskName === void 0;
return !value || value.command === void 0 && value.promptOnClose === void 0 && value.suppressTaskName === void 0;
}
export function merge(target: Globals, source: Globals): Globals {
......@@ -941,7 +1018,6 @@ namespace Globals {
}
mergeProperty(target, source, 'promptOnClose');
mergeProperty(target, source, 'suppressTaskName');
mergeProperty(target, source, 'showOutput');
return target;
}
......@@ -952,9 +1028,6 @@ namespace Globals {
if (value.suppressTaskName === void 0) {
value.suppressTaskName = false;
}
if (value.showOutput === void 0) {
value.showOutput = Tasks.ShowOutput.Always;
}
if (value.promptOnClose === void 0) {
value.promptOnClose = true;
}
......@@ -1059,7 +1132,6 @@ class ConfigurationParser {
group: Tasks.TaskGroup.Build,
command: undefined,
isBackground: isBackground,
showOutput: undefined,
suppressTaskName: true, // this must be true since we infer the task from the global data.
problemMatchers: matchers
};
......
......@@ -179,8 +179,13 @@ const command: TaskEntry = {
'\t// See https://go.microsoft.com/fwlink/?LinkId=733558',
'\t// for the documentation about the tasks.json format',
'\t"version": "2.0.0",',
'\t"command": "echo \"Hello World\"",',
'\t"isShellCommand": true,',
'\t"tasks": [',
'\t\t{',
'\t\t\t"taskName": "echo",',
'\t\t\t"command": "echo Hello",',
'\t\t\t"isShellCommand": true',
'\t\t}',
'\t]',
'}'
].join('\n')
};
......
......@@ -41,6 +41,52 @@ export namespace ShellConfiguration {
}
}
export enum RevealKind {
/**
* Always brings the terminal to front if the task is executed.
*/
Always = 1,
/**
* Only brings the terminal to front if a problem is detected executing the task
* (e.g. the task couldn't be started because).
*/
Silent = 2,
/**
* The terminal never comes to front when the task is executed.
*/
Never = 3
}
export namespace RevealKind {
export function fromString(value: string): RevealKind {
switch (value.toLowerCase()) {
case 'always':
return RevealKind.Always;
case 'silent':
return RevealKind.Silent;
case 'never':
return RevealKind.Never;
default:
return RevealKind.Always;
}
}
}
export interface TerminalBehavior {
/**
* Controls whether the terminal executing a task is brought to front or not.
* Defaults to `RevealKind.Always`.
*/
reveal: RevealKind;
/**
* Controls whether the executed command is printed to the output window or terminal as well.
*/
echo: boolean;
}
export interface CommandConfiguration {
/**
* The command to execute
......@@ -68,30 +114,9 @@ export interface CommandConfiguration {
taskSelector?: string;
/**
* Controls whether the executed command is printed to the output windows as well.
* Describes how the terminal is supposed to behave.
*/
echo: boolean;
}
export enum ShowOutput {
Always = 1,
Silent = 2,
Never = 3
}
export namespace ShowOutput {
export function fromString(value: string): ShowOutput {
value = value.toLowerCase();
if (value === 'always') {
return ShowOutput.Always;
} else if (value === 'silent') {
return ShowOutput.Silent;
} else if (value === 'never') {
return ShowOutput.Never;
} else {
return undefined;
}
}
terminal: TerminalBehavior;
}
export namespace TaskGroup {
......@@ -177,12 +202,6 @@ export interface Task {
*/
promptOnClose?: boolean;
/**
* Controls whether the output of the running tasks is shown or not. Default
* value is "always".
*/
showOutput: ShowOutput;
/**
* The other tasks this task depends on.
*/
......
......@@ -65,11 +65,12 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IOutputService, IOutputChannelRegistry, Extensions as OutputExt, IOutputChannel } from 'vs/workbench/parts/output/common/output';
import { Scope, IActionBarRegistry, Extensions as ActionBarExtensions } from 'vs/workbench/browser/actionBarRegistry';
import { ITerminalService } from 'vs/workbench/parts/terminal/common/terminal';
import { ITaskSystem, ITaskResolver, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, TaskSystemEvents } from 'vs/workbench/parts/tasks/common/taskSystem';
import { Task, TaskSet, TaskGroup, ExecutionEngine, ShowOutput, TaskSourceKind } from 'vs/workbench/parts/tasks/common/tasks';
import { Task, TaskSet, TaskGroup, ExecutionEngine, TaskSourceKind } from 'vs/workbench/parts/tasks/common/tasks';
import { ITaskService, TaskServiceEvents, ITaskProvider } from 'vs/workbench/parts/tasks/common/taskService';
import { templates as taskTemplates } from 'vs/workbench/parts/tasks/common/taskTemplates';
......@@ -77,6 +78,7 @@ import * as TaskConfig from 'vs/workbench/parts/tasks/common/taskConfiguration';
import { ProcessTaskSystem } from 'vs/workbench/parts/tasks/node/processTaskSystem';
import { TerminalTaskSystem } from './terminalTaskSystem';
import { ProcessRunnerDetector } from 'vs/workbench/parts/tasks/node/processRunnerDetector';
import { QuickOpenActionContributor } from '../browser/quickOpen';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
......@@ -758,7 +760,6 @@ class TaskService extends EventEmitter implements ITaskService {
identifier: id,
dependsOn: primaryTasks.map(task => task._id),
command: undefined,
showOutput: ShowOutput.Never
};
return { task, resolver };
}
......@@ -867,30 +868,32 @@ class TaskService extends EventEmitter implements ITaskService {
}
private getTaskSets(): TPromise<TaskSet[]> {
return new TPromise<TaskSet[]>((resolve, reject) => {
let result: TaskSet[] = [];
let counter: number = 0;
let done = (value: TaskSet) => {
if (value) {
result.push(value);
}
if (--counter === 0) {
resolve(result);
}
};
let error = () => {
if (--counter === 0) {
return this.extensionService.activateByEvent('onCommand:workbench.action.tasks.runTask').then(() => {
return new TPromise<TaskSet[]>((resolve, reject) => {
let result: TaskSet[] = [];
let counter: number = 0;
let done = (value: TaskSet) => {
if (value) {
result.push(value);
}
if (--counter === 0) {
resolve(result);
}
};
let error = () => {
if (--counter === 0) {
resolve(result);
}
};
if (this.getExecutionEngine() === ExecutionEngine.Terminal && this._providers.size > 0) {
this._providers.forEach((provider) => {
counter++;
provider.provideTasks().done(done, error);
});
} else {
resolve(result);
}
};
if (this.getExecutionEngine() === ExecutionEngine.Terminal && this._providers.size > 0) {
this._providers.forEach((provider) => {
counter++;
provider.provideTasks().done(done, error);
});
} else {
resolve(result);
}
});
}).then((result) => {
return this.getWorkspaceTasks().then((workspaceTaskResult) => {
let workspaceTasksToDelete: Task[] = [];
......@@ -1018,10 +1021,7 @@ class TaskService extends EventEmitter implements ITaskService {
configPromise = TPromise.as({ config, hasErrors: false });
}
} else {
configPromise = new ProcessRunnerDetector(this.fileService, this.contextService, this.configurationResolverService).detect(true).then((value) => {
let hasErrors = this.printStderr(value.stderr);
return { config: value.config, hasErrors };
});
configPromise = TPromise.as({ config, hasErrors: false });
}
}
return configPromise.then((resolved) => {
......@@ -1326,6 +1326,9 @@ quickOpenRegistry.registerQuickOpenHandler(
)
);
const actionBarRegistry = Registry.as<IActionBarRegistry>(ActionBarExtensions.Actionbar);
actionBarRegistry.registerActionBarContributor(Scope.VIEWER, QuickOpenActionContributor);
// Status bar
let statusbarRegistry = <IStatusbarRegistry>Registry.as(StatusbarExtensions.Statusbar);
statusbarRegistry.registerStatusbarItem(new StatusbarItemDescriptor(StatusBarItem, StatusbarAlignment.LEFT, 50 /* Medium Priority */));
......
......@@ -33,7 +33,7 @@ import { IConfigurationResolverService } from 'vs/workbench/services/configurati
import { ITerminalService, ITerminalInstance, IShellLaunchConfig } from 'vs/workbench/parts/terminal/common/terminal';
import { IOutputService, IOutputChannel } from 'vs/workbench/parts/output/common/output';
import { StartStopProblemCollector, WatchingProblemCollector, ProblemCollectorEvents } from 'vs/workbench/parts/tasks/common/problemCollectors';
import { Task, ShowOutput, CommandOptions, ShellConfiguration } from 'vs/workbench/parts/tasks/common/tasks';
import { Task, RevealKind, CommandOptions, ShellConfiguration } from 'vs/workbench/parts/tasks/common/tasks';
import {
ITaskSystem, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, ITaskResolver,
TelemetryEvent, Triggers, TaskSystemEvents, TaskEvent, TaskType
......@@ -134,7 +134,8 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
public run(task: Task, resolver: ITaskResolver, trigger: string = Triggers.command): ITaskExecuteResult {
let terminalData = this.activeTasks[task._id];
if (terminalData && terminalData.promise) {
if (task.showOutput === ShowOutput.Always) {
let reveal = task.command.terminal.reveal;
if (reveal === RevealKind.Always) {
terminalData.terminal.setVisible(true);
}
return { kind: TaskExecuteKind.Active, active: { same: true, background: task.isBackground }, promise: terminalData.promise };
......@@ -288,7 +289,8 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
this.emit(TaskSystemEvents.Inactive, event);
}
eventCounter = 0;
if (exitCode && exitCode === 1 && watchingProblemMatcher.numberOfMatches === 0 && task.showOutput !== ShowOutput.Never) {
let reveal = task.command.terminal.reveal;
if (exitCode && exitCode === 1 && watchingProblemMatcher.numberOfMatches === 0 && reveal !== RevealKind.Never) {
this.terminalService.setActiveInstance(terminal);
this.terminalService.showPanel(false);
}
......@@ -330,7 +332,7 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
});
}
this.terminalService.setActiveInstance(terminal);
if (task.showOutput === ShowOutput.Always) {
if (task.command.terminal.reveal === RevealKind.Always) {
this.terminalService.showPanel(false);
}
this.activeTasks[task._id] = { terminal, task, promise };
......@@ -364,7 +366,7 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
let options = this.resolveOptions(task.command.options);
let { command, args } = this.resolveCommandAndArgs(task);
let terminalName = nls.localize('TerminalTaskSystem.terminalName', 'Task - {0}', task.name);
let waitOnExit = task.showOutput !== ShowOutput.Never || !task.isBackground;
let waitOnExit = task.command.terminal.reveal !== RevealKind.Never || !task.isBackground;
let shellLaunchConfig: IShellLaunchConfig = undefined;
if (task.command.isShellCommand) {
if (Platform.isWindows && ((options.cwd && TPath.isUNC(options.cwd)) || (!options.cwd && TPath.isUNC(process.cwd())))) {
......@@ -413,7 +415,7 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
});
shellArgs.push(commandLine);
shellLaunchConfig.args = Platform.isWindows ? shellArgs.join(' ') : shellArgs;
if (task.command.echo) {
if (task.command.terminal.echo) {
shellLaunchConfig.initialText = `> ${commandLine}`;
}
} else {
......@@ -427,7 +429,7 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
args,
waitOnExit
};
if (task.command.echo) {
if (task.command.terminal.echo) {
let getArgsToEcho = (args: string | string[]): string => {
if (!args || args.length === 0) {
return '';
......
......@@ -29,7 +29,7 @@ import { StartStopProblemCollector, WatchingProblemCollector, ProblemCollectorEv
import {
ITaskSystem, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, TelemetryEvent, Triggers, TaskSystemEvents, TaskEvent, TaskType
} from 'vs/workbench/parts/tasks/common/taskSystem';
import { Task, CommandOptions, ShowOutput, CommandConfiguration } from 'vs/workbench/parts/tasks/common/tasks';
import { Task, CommandOptions, RevealKind, CommandConfiguration } from 'vs/workbench/parts/tasks/common/tasks';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
......@@ -178,11 +178,12 @@ export class ProcessTaskSystem extends EventEmitter implements ITaskSystem {
this.childProcess = new LineProcess(command, args, !!commandConfig.isShellCommand, this.resolveOptions(commandConfig.options));
telemetryEvent.command = this.childProcess.getSanitizedCommand();
// we have no problem matchers defined. So show the output log
if (task.showOutput === ShowOutput.Always || (task.showOutput === ShowOutput.Silent && task.problemMatchers.length === 0)) {
let reveal = task.command.terminal.reveal;
if (reveal === RevealKind.Always || (reveal === RevealKind.Silent && task.problemMatchers.length === 0)) {
this.showOutput();
}
if (commandConfig.echo) {
if (commandConfig.terminal.echo) {
let prompt: string = Platform.isWindows ? '>' : '$';
this.log(`running command${prompt} ${command} ${args.join(' ')}`);
}
......@@ -214,7 +215,7 @@ export class ProcessTaskSystem extends EventEmitter implements ITaskSystem {
if (!this.checkTerminated(task, success)) {
this.log(nls.localize('TaskRunnerSystem.watchingBuildTaskFinished', '\nWatching build tasks has finished.'));
}
if (success.cmdCode && success.cmdCode === 1 && watchingProblemMatcher.numberOfMatches === 0 && task.showOutput !== ShowOutput.Never) {
if (success.cmdCode && success.cmdCode === 1 && watchingProblemMatcher.numberOfMatches === 0 && reveal !== RevealKind.Never) {
this.showOutput();
}
taskSummary.exitCode = success.cmdCode;
......@@ -258,7 +259,7 @@ export class ProcessTaskSystem extends EventEmitter implements ITaskSystem {
startStopProblemMatcher.dispose();
this.checkTerminated(task, success);
this.emit(TaskSystemEvents.Inactive, event);
if (success.cmdCode && success.cmdCode === 1 && startStopProblemMatcher.numberOfMatches === 0 && task.showOutput !== ShowOutput.Never) {
if (success.cmdCode && success.cmdCode === 1 && startStopProblemMatcher.numberOfMatches === 0 && reveal !== RevealKind.Never) {
this.showOutput();
}
taskSummary.exitCode = success.cmdCode;
......
......@@ -68,10 +68,32 @@ class ConfiguationBuilder {
}
}
class TerminalBehaviorBuilder {
public result: Tasks.TerminalBehavior;
constructor(public parent: CommandConfigurationBuilder) {
this.result = { echo: false, reveal: Tasks.RevealKind.Always };
}
public echo(value: boolean): TerminalBehaviorBuilder {
this.result.echo = value;
return this;
}
public reveal(value: Tasks.RevealKind): TerminalBehaviorBuilder {
this.result.reveal = value;
return this;
}
}
class CommandConfigurationBuilder {
public result: Tasks.CommandConfiguration;
private terminalBuilder: TerminalBehaviorBuilder;
constructor(public parent: TaskBuilder, command: string) {
this.terminalBuilder = new TerminalBehaviorBuilder(this);
this.result = {
name: command,
isShellCommand: false,
......@@ -79,7 +101,7 @@ class CommandConfigurationBuilder {
options: {
cwd: '${workspaceRoot}'
},
echo: false
terminal: this.terminalBuilder.result
};
}
......@@ -103,15 +125,14 @@ class CommandConfigurationBuilder {
return this;
}
public echo(value: boolean): CommandConfigurationBuilder {
this.result.echo = value;
return this;
}
public taskSelector(value: string): CommandConfigurationBuilder {
this.result.taskSelector = value;
return this;
}
public terminal(): TerminalBehaviorBuilder {
return this.terminalBuilder;
}
}
class TaskBuilder {
......@@ -127,7 +148,6 @@ class TaskBuilder {
identifier: name,
name: name,
command: this.commandBuilder.result,
showOutput: Tasks.ShowOutput.Always,
suppressTaskName: false,
isBackground: false,
promptOnClose: true,
......@@ -150,11 +170,6 @@ class TaskBuilder {
return this;
}
public showOutput(value: Tasks.ShowOutput): TaskBuilder {
this.result.showOutput = value;
return this;
}
public suppressTaskName(value: boolean): TaskBuilder {
this.result.suppressTaskName = value;
return this;
......@@ -401,7 +416,6 @@ function assertTask(actual: Tasks.Task, expected: Tasks.Task) {
assert.ok(actual._id);
assert.strictEqual(actual.name, expected.name, 'name');
assertCommandConfiguration(actual.command, expected.command);
assert.strictEqual(actual.showOutput, expected.showOutput, 'showOutput');
assert.strictEqual(actual.suppressTaskName, expected.suppressTaskName, 'suppressTaskName');
assert.strictEqual(actual.isBackground, expected.isBackground, 'isBackground');
assert.strictEqual(actual.promptOnClose, expected.promptOnClose, 'promptOnClose');
......@@ -417,6 +431,7 @@ function assertTask(actual: Tasks.Task, expected: Tasks.Task) {
function assertCommandConfiguration(actual: Tasks.CommandConfiguration, expected: Tasks.CommandConfiguration) {
assert.strictEqual(typeof actual, typeof expected);
if (actual && expected) {
assertTerminalBehavior(actual.terminal, expected.terminal);
assert.strictEqual(actual.name, expected.name, 'name');
assert.strictEqual(actual.isShellCommand, expected.isShellCommand, 'isShellCommand');
assert.deepEqual(actual.args, expected.args, 'args');
......@@ -428,11 +443,18 @@ function assertCommandConfiguration(actual: Tasks.CommandConfiguration, expected
assert.deepEqual(actual.options.env, expected.options.env, 'env');
}
}
assert.strictEqual(actual.echo, expected.echo, 'echo');
assert.strictEqual(actual.taskSelector, expected.taskSelector, 'taskSelector');
}
}
function assertTerminalBehavior(actual: Tasks.TerminalBehavior, expected: Tasks.TerminalBehavior) {
assert.strictEqual(typeof actual, typeof expected);
if (actual && expected) {
assert.strictEqual(actual.echo, expected.echo);
assert.strictEqual(actual.reveal, expected.reveal);
}
}
function assertProblemMatcher(actual: string | ProblemMatcher, expected: string | ProblemMatcher) {
assert.strictEqual(typeof actual, typeof expected);
if (typeof actual === 'string' && typeof expected === 'string') {
......@@ -525,7 +547,7 @@ suite('Tasks Configuration parsing tests', () => {
task('tsc', 'tsc').
group(Tasks.TaskGroup.Build).
suppressTaskName(true).
showOutput(Tasks.ShowOutput.Silent);
command().terminal().reveal(Tasks.RevealKind.Silent);
testConfiguration(
{
version: '0.1.0',
......@@ -590,7 +612,7 @@ suite('Tasks Configuration parsing tests', () => {
task('tsc', 'tsc').
group(Tasks.TaskGroup.Build).
suppressTaskName(true).
showOutput(Tasks.ShowOutput.Never);
command().terminal().reveal(Tasks.RevealKind.Never);
testConfiguration(
{
version: '0.1.0',
......@@ -607,7 +629,7 @@ suite('Tasks Configuration parsing tests', () => {
task('tsc', 'tsc').
group(Tasks.TaskGroup.Build).
suppressTaskName(true).
command().
command().terminal().
echo(true);
testConfiguration(
{
......@@ -759,8 +781,8 @@ suite('Tasks Configuration parsing tests', () => {
builder.
task('tsc', 'tsc').
group(Tasks.TaskGroup.Build).
showOutput(Platform.isWindows ? Tasks.ShowOutput.Always : Tasks.ShowOutput.Never).
suppressTaskName(true);
suppressTaskName(true).
command().terminal().reveal(Platform.isWindows ? Tasks.RevealKind.Always : Tasks.RevealKind.Never);
let external: ExternalTaskRunnerConfiguration = {
version: '0.1.0',
command: 'tsc',
......@@ -778,7 +800,7 @@ suite('Tasks Configuration parsing tests', () => {
task('tsc', 'tsc').
group(Tasks.TaskGroup.Build).
suppressTaskName(true).
command().
command().terminal().
echo(Platform.isWindows ? false : true);
let external: ExternalTaskRunnerConfiguration = {
version: '0.1.0',
......@@ -903,12 +925,11 @@ suite('Tasks Configuration parsing tests', () => {
let builder = new ConfiguationBuilder();
builder.task('test', 'tsc').
group(Tasks.TaskGroup.Test).
showOutput(Tasks.ShowOutput.Never).
args(['--p']).
isBackground(true).
promptOnClose(false).
command().
echo(true);
command().terminal().
echo(true).reveal(Tasks.RevealKind.Never);
testConfiguration(external, builder);
});
......@@ -928,9 +949,8 @@ suite('Tasks Configuration parsing tests', () => {
let builder = new ConfiguationBuilder();
builder.task('test', 'tsc').
group(Tasks.TaskGroup.Test).
showOutput(Tasks.ShowOutput.Never).
command().
echo(true);
command().terminal().
echo(true).reveal(Tasks.RevealKind.Never);
testConfiguration(external, builder);
});
......@@ -1392,15 +1412,17 @@ suite('Bugs / regression tests', () => {
let builder = new ConfiguationBuilder();
if (Platform.isWindows) {
builder.task('composeForDebug', 'powershell').
suppressTaskName(true).showOutput(Tasks.ShowOutput.Always).
suppressTaskName(true).
args(['-ExecutionPolicy', 'RemoteSigned', '.\\dockerTask.ps1', '-ComposeForDebug', '-Environment', 'debug']).
command().echo(true).options({ cwd: '${workspaceRoot}' });
command().options({ cwd: '${workspaceRoot}' }).
terminal().echo(true).reveal(Tasks.RevealKind.Always);
testConfiguration(external, builder);
} else if (Platform.isMacintosh) {
builder.task('composeForDebug', '/bin/bash').
suppressTaskName(true).showOutput(Tasks.ShowOutput.Always).
suppressTaskName(true).
args(['-c', './dockerTask.sh composeForDebug debug']).
command().options({ cwd: '${workspaceRoot}' });
command().options({ cwd: '${workspaceRoot}' }).
terminal().reveal(Tasks.RevealKind.Always);
testConfiguration(external, builder);
}
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册