mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-26 19:44:25 +01:00
Fixes #29332: Improve workflow to assign a problem matcher to a build task.
This commit is contained in:
@@ -6,9 +6,11 @@
|
||||
|
||||
import nls = require('vs/nls');
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
||||
import QuickOpen = require('vs/base/parts/quickopen/common/quickOpen');
|
||||
import Model = require('vs/base/parts/quickopen/browser/quickOpenModel');
|
||||
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import { ProblemMatcherRegistry } from 'vs/platform/markers/common/problemMatcher';
|
||||
|
||||
import { Task, TaskGroup } from 'vs/workbench/parts/tasks/common/tasks';
|
||||
import { ITaskService } from 'vs/workbench/parts/tasks/common/taskService';
|
||||
@@ -25,12 +27,14 @@ class TaskEntry extends base.TaskEntry {
|
||||
return false;
|
||||
}
|
||||
let task = this._task;
|
||||
this.taskService.run(task);
|
||||
if (task.command.presentation.focus) {
|
||||
this.quickOpenService.close();
|
||||
return false;
|
||||
if (task.problemMatchers === void 0 || task.problemMatchers.length === 0) {
|
||||
this.attachProblemMatcher(task).then((task) => {
|
||||
this.doRun(task);
|
||||
});
|
||||
return true;
|
||||
} else {
|
||||
return this.doRun(task);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +51,7 @@ export class QuickOpenHandler extends base.QuickOpenHandler {
|
||||
}
|
||||
|
||||
protected getTasks(): TPromise<Task[]> {
|
||||
return this.taskService.getTasksForGroup(TaskGroup.Build);
|
||||
return ProblemMatcherRegistry.onReady().then(() => this.taskService.getTasksForGroup(TaskGroup.Build));
|
||||
}
|
||||
|
||||
protected createEntry(task: Task, highlights: Model.IHighlight[]): base.TaskEntry {
|
||||
|
||||
@@ -9,16 +9,22 @@ import Filters = require('vs/base/common/filters');
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Action, IAction } from 'vs/base/common/actions';
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
import * as Objects from 'vs/base/common/objects';
|
||||
|
||||
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');
|
||||
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import { IQuickOpenService, IPickOpenEntry } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import { ProblemMatcherRegistry, NamedProblemMatcher } from 'vs/platform/markers/common/problemMatcher';
|
||||
|
||||
import { Task, TaskSourceKind } from 'vs/workbench/parts/tasks/common/tasks';
|
||||
import { ITaskService } from 'vs/workbench/parts/tasks/common/taskService';
|
||||
import { ActionBarContributor, ContributableActionProvider } from 'vs/workbench/browser/actions';
|
||||
|
||||
interface ProblemMatcherPickEntry extends IPickOpenEntry {
|
||||
matcher: NamedProblemMatcher;
|
||||
}
|
||||
|
||||
export class TaskEntry extends Model.QuickOpenEntry {
|
||||
|
||||
constructor(protected taskService: ITaskService, protected quickOpenService: IQuickOpenService, protected _task: Task, highlights: Model.IHighlight[] = []) {
|
||||
@@ -36,6 +42,44 @@ export class TaskEntry extends Model.QuickOpenEntry {
|
||||
public get task(): Task {
|
||||
return this._task;
|
||||
}
|
||||
|
||||
protected attachProblemMatcher(task: Task): TPromise<Task> {
|
||||
let entries: ProblemMatcherPickEntry[] = [];
|
||||
for (let key of ProblemMatcherRegistry.keys()) {
|
||||
let matcher = ProblemMatcherRegistry.get(key);
|
||||
if (matcher.name === matcher.label) {
|
||||
entries.push({ label: matcher.name, matcher: matcher });
|
||||
} else {
|
||||
entries.push({ label: nls.localize('entries', '{0} [${1}]', matcher.label, matcher.name), matcher: matcher });
|
||||
}
|
||||
}
|
||||
if (entries.length > 0) {
|
||||
entries.push({ label: 'Continue without scanning the build output', separator: { border: true }, matcher: undefined });
|
||||
return this.quickOpenService.pick(entries, {
|
||||
placeHolder: nls.localize('selectProblemMatcher', 'Select for which kind of errors and warnings to scan the build output')
|
||||
}).then((selected) => {
|
||||
if (selected && selected.matcher) {
|
||||
let newTask = Objects.deepClone(task);
|
||||
let matcherReference = `$${selected.matcher.name}`;
|
||||
newTask.problemMatchers = [matcherReference];
|
||||
this.taskService.customize(task, { problemMatcher: [matcherReference] }, true);
|
||||
return newTask;
|
||||
} else {
|
||||
return task;
|
||||
}
|
||||
});
|
||||
}
|
||||
return TPromise.as(task);
|
||||
}
|
||||
|
||||
protected doRun(task: Task): boolean {
|
||||
this.taskService.run(task);
|
||||
if (task.command.presentation.focus) {
|
||||
this.quickOpenService.close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class TaskGroupEntry extends Model.QuickOpenEntryGroup {
|
||||
@@ -147,7 +191,7 @@ class CustomizeTaskAction extends Action {
|
||||
}
|
||||
|
||||
public run(context: any): TPromise<any> {
|
||||
return this.taskService.customize(this.task, true).then(() => {
|
||||
return this.taskService.customize(this.task, undefined, true).then(() => {
|
||||
this.quickOpenService.close();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import QuickOpen = require('vs/base/parts/quickopen/common/quickOpen');
|
||||
import Model = require('vs/base/parts/quickopen/browser/quickOpenModel');
|
||||
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
|
||||
import { Task } from 'vs/workbench/parts/tasks/common/tasks';
|
||||
import { Task, TaskGroup } from 'vs/workbench/parts/tasks/common/tasks';
|
||||
import { ITaskService } from 'vs/workbench/parts/tasks/common/taskService';
|
||||
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
@@ -27,12 +27,12 @@ class TaskEntry extends base.TaskEntry {
|
||||
return false;
|
||||
}
|
||||
let task = this._task;
|
||||
this.taskService.run(task);
|
||||
if (task.command.presentation.focus) {
|
||||
this.quickOpenService.close();
|
||||
return false;
|
||||
if (task.group === TaskGroup.Build && ((task.problemMatchers === void 0) || task.problemMatchers.length === 0)) {
|
||||
this.attachProblemMatcher(task).then(task => this.doRun(task));
|
||||
return true;
|
||||
} else {
|
||||
return this.doRun(task);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ export interface ITaskService extends IEventEmitter {
|
||||
getTasksForGroup(group: string): TPromise<Task[]>;
|
||||
getRecentlyUsedTasks(): LinkedMap<string, string>;
|
||||
|
||||
customize(task: Task, openConfig?: boolean): TPromise<void>;
|
||||
customize(task: Task, properties?: { problemMatcher: string | string[] }, openConfig?: boolean): TPromise<void>;
|
||||
|
||||
registerTaskProvider(handle: number, taskProvider: ITaskProvider): void;
|
||||
unregisterTaskProvider(handle: number): boolean;
|
||||
|
||||
@@ -362,6 +362,10 @@ export enum ExecutionEngine {
|
||||
Terminal = 2
|
||||
}
|
||||
|
||||
export namespace ExecutionEngine {
|
||||
export const _default: ExecutionEngine = ExecutionEngine.Terminal;
|
||||
}
|
||||
|
||||
export enum JsonSchemaVersion {
|
||||
V0_1_0 = 1,
|
||||
V2_0_0 = 2
|
||||
|
||||
@@ -610,7 +610,7 @@ class TaskService extends EventEmitter implements ITaskService {
|
||||
? ExecutionEngine.Terminal
|
||||
: this._taskSystem instanceof ProcessTaskSystem
|
||||
? ExecutionEngine.Process
|
||||
: undefined;
|
||||
: ExecutionEngine._default;
|
||||
if (currentExecutionEngine !== this.getExecutionEngine()) {
|
||||
this.messageService.show(Severity.Info, nls.localize('TaskSystem.noHotSwap', 'Changing the task execution engine requires restarting VS Code. The change is ignored.'));
|
||||
}
|
||||
@@ -820,7 +820,7 @@ class TaskService extends EventEmitter implements ITaskService {
|
||||
return { configured, detected };
|
||||
}
|
||||
|
||||
public customize(task: Task, openConfig: boolean = false): TPromise<void> {
|
||||
public customize(task: Task, properties?: { problemMatcher: string | string[] }, openConfig?: boolean): TPromise<void> {
|
||||
if (!ContributedTask.is(task)) {
|
||||
return TPromise.as<void>(undefined);
|
||||
}
|
||||
@@ -836,9 +836,19 @@ class TaskService extends EventEmitter implements ITaskService {
|
||||
delete identifier['_key'];
|
||||
Object.keys(identifier).forEach(key => customizes[key] = identifier[key]);
|
||||
|
||||
if (task.problemMatchers === void 0 || task.problemMatchers.length === 0) {
|
||||
customizes.problemMatcher = [];
|
||||
if (properties) {
|
||||
for (let property of Object.getOwnPropertyNames(properties)) {
|
||||
let value = properties[property];
|
||||
if (value !== void 0 && value !== null) {
|
||||
customizes[property] = value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (task.problemMatchers === void 0 || task.problemMatchers.length === 0) {
|
||||
customizes.problemMatcher = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileConfig) {
|
||||
fileConfig = {
|
||||
version: '2.0.0',
|
||||
@@ -901,6 +911,8 @@ class TaskService extends EventEmitter implements ITaskService {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// We can only have extension tasks if we are in version 2.0.0. Then we can even run
|
||||
// multiple build tasks.
|
||||
if (extensionTasks.length === 1) {
|
||||
return { task: extensionTasks[0], resolver };
|
||||
} else {
|
||||
@@ -1152,7 +1164,7 @@ class TaskService extends EventEmitter implements ITaskService {
|
||||
if (hasParseErrors) {
|
||||
return TPromise.as({ set: undefined, hasErrors: true, configurations: undefined });
|
||||
}
|
||||
let engine = TaskConfig.ExecutionEngine._default;
|
||||
let engine = ExecutionEngine._default;
|
||||
if (config) {
|
||||
engine = TaskConfig.ExecutionEngine.from(config);
|
||||
if (engine === ExecutionEngine.Process) {
|
||||
@@ -1229,7 +1241,7 @@ class TaskService extends EventEmitter implements ITaskService {
|
||||
private getExecutionEngine(): ExecutionEngine {
|
||||
let { config } = this.getConfiguration();
|
||||
if (!config) {
|
||||
return ExecutionEngine.Terminal;
|
||||
return ExecutionEngine._default;
|
||||
}
|
||||
return TaskConfig.ExecutionEngine.from(config);
|
||||
}
|
||||
@@ -1429,9 +1441,8 @@ class TaskService extends EventEmitter implements ITaskService {
|
||||
return;
|
||||
}
|
||||
this.getTasksForGroup(TaskGroup.Build).then((tasks) => {
|
||||
let { configured, detected } = this.splitTasks(tasks);
|
||||
let total = configured.length + detected.length;
|
||||
if (total === 0) {
|
||||
if (tasks.length === 0) {
|
||||
// Show no build task message.
|
||||
return;
|
||||
}
|
||||
this.quickOpenService.show('build task ');
|
||||
|
||||
@@ -1473,8 +1473,6 @@ namespace Globals {
|
||||
|
||||
export namespace ExecutionEngine {
|
||||
|
||||
export const _default: Tasks.ExecutionEngine = Tasks.ExecutionEngine.Process;
|
||||
|
||||
export function from(config: ExternalTaskRunnerConfiguration): Tasks.ExecutionEngine {
|
||||
let runner = config.runner || config._runner;
|
||||
let result: Tasks.ExecutionEngine;
|
||||
@@ -1497,12 +1495,11 @@ export namespace ExecutionEngine {
|
||||
throw new Error('Shouldn\'t happen.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export namespace JsonSchemaVersion {
|
||||
|
||||
export const _default: Tasks.JsonSchemaVersion = Tasks.JsonSchemaVersion.V0_1_0;
|
||||
const _default: Tasks.JsonSchemaVersion = Tasks.JsonSchemaVersion.V2_0_0;
|
||||
|
||||
export function from(config: ExternalTaskRunnerConfiguration): Tasks.JsonSchemaVersion {
|
||||
let version = config.version;
|
||||
|
||||
Reference in New Issue
Block a user