Incooperate API feedback

This commit is contained in:
Dirk Baeumer 2017-06-22 17:03:52 +02:00
parent 2ef8e48de4
commit 22fa494aee
17 changed files with 428 additions and 435 deletions

2
.vscode/tasks.json vendored
View file

@ -40,7 +40,7 @@
"command": ".\\scripts\\test.bat"
},
"group": "test",
"terminal": {
"presentation": {
"echo": true,
"reveal": "always"
}

View file

@ -44,7 +44,7 @@
},
"taskTypes": [
{
"taskType": "grunt",
"type": "grunt",
"required": ["task"],
"properties": {
"task": {

View file

@ -34,12 +34,15 @@ export function activate(_context: vscode.ExtensionContext): void {
taskProvider.dispose();
taskProvider = undefined;
} else if (!taskProvider && autoDetect === 'on') {
taskProvider = vscode.workspace.registerTaskProvider({
taskProvider = vscode.workspace.registerTaskProvider('grunt', {
provideTasks: () => {
if (!detectorPromise) {
detectorPromise = getGruntTasks();
}
return detectorPromise;
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
return undefined;
}
});
}
@ -81,7 +84,7 @@ function getOutputChannel(): vscode.OutputChannel {
return _channel;
}
interface GruntTaskIdentifier extends vscode.TaskIdentifier {
interface GruntTaskKind extends vscode.TaskKind {
task: string;
file?: string;
}
@ -150,13 +153,13 @@ async function getGruntTasks(): Promise<vscode.Task[]> {
let matches = regExp.exec(line);
if (matches && matches.length === 2) {
let taskName = matches[1];
let identifier: GruntTaskIdentifier = {
let kind: GruntTaskKind = {
type: 'grunt',
task: taskName
};
let task = taskName.indexOf(' ') === -1
? new vscode.ShellTask(identifier, taskName, `${command} ${taskName}`)
: new vscode.ShellTask(identifier, taskName, `${command} "${taskName}"`);
? new vscode.Task(kind, taskName, new vscode.ShellExecution(`${command} ${taskName}`))
: new vscode.Task(kind, taskName, new vscode.ShellExecution(`${command} "${taskName}"`));
result.push(task);
let lowerCaseTaskName = taskName.toLowerCase();
if (lowerCaseTaskName === 'build') {

View file

@ -41,6 +41,22 @@
"description": "%config.gulp.autoDetect%"
}
}
}
},
"taskTypes": [
{
"type": "gulp",
"required": ["task"],
"properties": {
"task": {
"type": "string",
"description": "The Gulp task to customize"
},
"file": {
"type": "string",
"description": "The Gulp file that provides the task. Can be omitted."
}
}
}
]
}
}

View file

@ -34,12 +34,15 @@ export function activate(_context: vscode.ExtensionContext): void {
taskProvider.dispose();
taskProvider = undefined;
} else if (!taskProvider && autoDetect === 'on') {
taskProvider = vscode.workspace.registerTaskProvider({
taskProvider = vscode.workspace.registerTaskProvider('gulp', {
provideTasks: () => {
if (!gulpPromise) {
gulpPromise = getGulpTasks();
}
return gulpPromise;
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
return undefined;
}
});
}
@ -81,7 +84,7 @@ function getOutputChannel(): vscode.OutputChannel {
return _channel;
}
interface GulpTaskIdentifier extends vscode.TaskIdentifier {
interface GulpTaskKind extends vscode.TaskKind {
task: string;
file?: string;
}
@ -126,11 +129,11 @@ async function getGulpTasks(): Promise<vscode.Task[]> {
if (line.length === 0) {
continue;
}
let identifier: GulpTaskIdentifier = {
let kind: GulpTaskKind = {
type: 'gulp',
task: line
};
let task = new vscode.ShellTask(identifier, line, `${gulpCommand} ${line}`);
let task = new vscode.Task(kind, line, new vscode.ShellExecution(`${gulpCommand} ${line}`));
result.push(task);
let lowerCaseLine = line.toLowerCase();
if (lowerCaseLine === 'build') {

View file

@ -44,7 +44,7 @@
},
"taskTypes": [
{
"taskType": "jake",
"type": "jake",
"required": ["task"],
"properties": {
"task": {

View file

@ -34,12 +34,15 @@ export function activate(_context: vscode.ExtensionContext): void {
taskProvider.dispose();
taskProvider = undefined;
} else if (!taskProvider && autoDetect === 'on') {
taskProvider = vscode.workspace.registerTaskProvider({
taskProvider = vscode.workspace.registerTaskProvider('jake', {
provideTasks: () => {
if (!jakePromise) {
jakePromise = getJakeTasks();
}
return jakePromise;
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
return undefined;
}
});
}
@ -81,7 +84,7 @@ function getOutputChannel(): vscode.OutputChannel {
return _channel;
}
interface JakeTaskIdentifier extends vscode.TaskIdentifier {
interface JakeTaskKind extends vscode.TaskKind {
task: string;
file?: string;
}
@ -130,11 +133,11 @@ async function getJakeTasks(): Promise<vscode.Task[]> {
let matches = regExp.exec(line);
if (matches && matches.length === 2) {
let taskName = matches[1];
let identifier: JakeTaskIdentifier = {
let kind: JakeTaskKind = {
type: 'jake',
task: taskName
};
let task = new vscode.ShellTask(identifier, taskName, `${jakeCommand} ${taskName}`);
let task = new vscode.Task(kind, taskName, new vscode.ShellExecution(`${jakeCommand} ${taskName}`));
result.push(task);
let lowerCaseLine = line.toLowerCase();
if (lowerCaseLine === 'build') {

View file

@ -41,6 +41,22 @@
"description": "%config.npm.autoDetect%"
}
}
}
},
"taskTypes": [
{
"type": "npm",
"required": ["script"],
"properties": {
"script": {
"type": "string",
"description": "The npm script to customize"
},
"file": {
"type": "string",
"description": "The package.json file that provides the task. Can be omitted."
}
}
}
]
}
}

View file

@ -23,9 +23,12 @@ export function activate(_context: vscode.ExtensionContext): void {
taskProvider.dispose();
taskProvider = undefined;
} else if (!taskProvider && autoDetect === 'on') {
taskProvider = vscode.workspace.registerTaskProvider({
taskProvider = vscode.workspace.registerTaskProvider('npm', {
provideTasks: () => {
return getNpmScriptsAsTasks();
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
return undefined;
}
});
}
@ -59,7 +62,7 @@ async function readFile(file: string): Promise<string> {
});
}
interface NpmTaskIdentifier extends vscode.TaskIdentifier {
interface NpmTaskKind extends vscode.TaskKind {
script: string;
file?: string;
}
@ -87,11 +90,11 @@ async function getNpmScriptsAsTasks(): Promise<vscode.Task[]> {
const result: vscode.Task[] = [];
Object.keys(json.scripts).forEach(each => {
const identifier: NpmTaskIdentifier = {
const kind: NpmTaskKind = {
type: 'npm',
script: each
};
const task = new vscode.ShellTask(identifier, `run ${each}`, `npm run ${each}`);
const task = new vscode.Task(kind, `run ${each}`, new vscode.ShellExecution(`npm run ${each}`));
const lowerCaseTaskName = each.toLowerCase();
if (lowerCaseTaskName === 'build') {
task.group = vscode.TaskGroup.Build;
@ -101,7 +104,7 @@ async function getNpmScriptsAsTasks(): Promise<vscode.Task[]> {
result.push(task);
});
// add some 'well known' npm tasks
result.push(new vscode.ShellTask({ type: 'npm', script: 'install' } as NpmTaskIdentifier, `install`, `npm install`));
result.push(new vscode.Task({ type: 'npm', script: 'install' } as NpmTaskKind, `install`, new vscode.ShellExecution(`npm install`)));
return Promise.resolve(result);
} catch (e) {
return Promise.resolve(emptyTasks);

View file

@ -458,6 +458,18 @@
"url": "http://json.schemastore.org/typings"
}
],
"taskTypes": [
{
"type": "typescript",
"required": ["tsconfig"],
"properties": {
"tsconfig": {
"type": "string",
"description": "The tsconfig file that defines the TS build"
}
}
}
],
"problemPatterns": [
{
"name": "tsc",

View file

@ -22,8 +22,8 @@ const exists = (file: string): Promise<boolean> =>
});
interface TypeScriptTaskIdentifier extends vscode.TaskIdentifier {
configFile: string;
interface TypeScriptTaskIdentifier extends vscode.TaskKind {
tsconfig: string;
}
/**
@ -53,14 +53,18 @@ class TscTaskProvider implements vscode.TaskProvider {
return projects.map(configFile => {
const configFileName = path.relative(rootPath, configFile);
const identifier: TypeScriptTaskIdentifier = { type: 'typescript', configFile: configFileName };
const buildTask = new vscode.ShellTask(identifier, `build ${configFileName}`, `${command} -p "${configFile}"`, '$tsc');
const identifier: TypeScriptTaskIdentifier = { type: 'typescript', tsconfig: configFileName };
const buildTask = new vscode.Task(identifier, `build ${configFileName}`, new vscode.ShellExecution(`${command} -p "${configFile}"`), '$tsc');
buildTask.source = 'tsc';
buildTask.group = vscode.TaskGroup.Build;
return buildTask;
});
}
public resolveTask(_task: vscode.Task): vscode.Task | undefined {
return undefined;
}
private async getAllTsConfigs(token: vscode.CancellationToken): Promise<string[]> {
const out = new Set<string>();
const configs = (await this.getTsConfigForActiveFile(token)).concat(await this.getTsConfigsInWorkspace());
@ -158,7 +162,7 @@ export default class TypeScriptTaskProviderManager {
this.taskProviderSub.dispose();
this.taskProviderSub = undefined;
} else if (!this.taskProviderSub && autoDetect === 'on') {
this.taskProviderSub = vscode.workspace.registerTaskProvider(new TscTaskProvider(this.lazyClient));
this.taskProviderSub = vscode.workspace.registerTaskProvider('typescript', new TscTaskProvider(this.lazyClient));
}
}
}

View file

@ -86,7 +86,55 @@ declare module 'vscode' {
panel?: TaskPanelKind;
}
export interface ProcessTaskOptions {
/**
* A grouping for tasks. The editor by default supports the
* 'Clean', 'Build', 'RebuildAll' and 'Test' group.
*/
export class TaskGroup {
/**
* The clean task group;
*/
public static Clean: TaskGroup;
/**
* The build task group;
*/
public static Build: TaskGroup;
/**
* The rebuild all task group;
*/
public static RebuildAll: TaskGroup;
/**
* The test all task group;
*/
public static Test: TaskGroup;
private constructor(id: string, label: string);
}
/**
* A structure that defines a task kind in the system.
* The value must be JSON-stringifyable.
*/
export interface TaskKind {
/**
* The task type as defined by the extension implementing a
* task provider. Examples are 'grunt', 'npm' or 'tsc'.
* Usually a task provider defines more properties to identify
* a task. They need to be defined in the package.json of the
* extension under the 'taskKinds' extension point.
*/
readonly type: string;
}
/**
* Options for a process execution
*/
export interface ProcessExecutionOptions {
/**
* The current working directory of the executed program or shell.
* If omitted the tools current workspace root is used.
@ -101,100 +149,28 @@ declare module 'vscode' {
env?: { [key: string]: string };
}
export namespace TaskGroup {
/**
* The clean task group
*/
export const Clean: 'clean';
/**
* The build task group. If a task is part of the build task group
* it can be executed via the run build short cut.
*/
export const Build: 'build';
/**
* The rebuild all task group
*/
export const RebuildAll: 'rebuildAll';
/**
* The test task group. If a task is part of the test task group
* it can be executed via the run test short cut.
*/
export const Test: 'test';
}
/**
* An identifer to uniquely identify a task in the system.
* The value must be JSON-stringifyable.
* The execution of a task happens as a external process
* without shell interaction.
*/
export interface TaskIdentifier {
/**
* The task type as defined by the extension implementing a
* task provider. Examples are 'grunt', 'npm' or 'tsc'.
* Usually a task provider defines more properties to identify
* a task. They need to be defined in the package.json of the
* extension under the 'taskTypes' extension point.
*/
readonly type: string;
}
/**
* A task that starts an external process.
*/
export class ProcessTask {
export class ProcessExecution {
/**
* Creates a process task.
* Creates a process execution.
*
* @param identifier: the task's identifier as defined in the 'taskTypes' extension point.
* @param name the task's name. Is presented in the user interface.
* @param process the process to start.
* @param problemMatchers the names of problem matchers to use, like '$tsc'
* or '$eslint'. Problem matchers can be contributed by an extension using
* the `problemMatchers` extension point.
* @param process The process to start.
* @param options Optional options for the started process.
*/
constructor(identifier: TaskIdentifier, name: string, process: string, problemMatchers?: string | string[]);
constructor(process: string, options?: ProcessExecutionOptions);
/**
* Creates a process task.
* Creates a process execution.
*
* @param identifier: the task's identifier as defined in the 'taskTypes' extension point.
* @param name the task's name. Is presented in the user interface.
* @param process the process to start.
* @param args arguments to be passed to the process.
* @param problemMatchers the names of problem matchers to use, like '$tsc'
* or '$eslint'. Problem matchers can be contributed by an extension using
* the `problemMatchers` extension point.
* @param process The process to start.
* @param args Arguments to be passed to the process.
* @param options Optional options for the started process.
*/
constructor(identifier: TaskIdentifier, name: string, process: string, args: string[], problemMatchers?: string | string[]);
/**
* Creates a process task.
*
* @param identifier: the task's identifier as defined in the 'taskTypes' extension point.
* @param name the task's name. Is presented in the user interface.
* @param process the process to start.
* @param args arguments to be passed to the process.
* @param options additional options for the started process.
* @param problemMatchers the names of problem matchers to use, like '$tsc'
* or '$eslint'. Problem matchers can be contributed by an extension using
* the `problemMatchers` extension point.
*/
constructor(identifier: TaskIdentifier, name: string, process: string, args: string[], options: ProcessTaskOptions, problemMatchers?: string | string[]);
/**
* The task's identifier.
*/
identifier: TaskIdentifier;
/**
* The task's name
*/
name: string;
/**
* Whether the task is a background task or not.
*/
isBackground: boolean;
constructor(process: string, args: string[], options?: ProcessExecutionOptions);
/**
* The process to be executed.
@ -206,43 +182,21 @@ declare module 'vscode' {
*/
args: string[];
/**
* A human-readable string describing the source of this
* shell task, e.g. 'gulp' or 'npm'.
*/
source: string | undefined;
/**
* The task group this tasks belongs to. See TaskGroup
* for a predefined set of available groups.
* Defaults to undefined meaning that the task doesn't
* belong to any special group.
*/
group: string | undefined;
/**
* The process options used when the process is executed.
* Defaults to an empty object literal.
* Defaults to undefined.
*/
options: ProcessTaskOptions;
/**
* The presentation options. Defaults to an empty literal.
*/
presentationOptions: TaskPresentationOptions;
/**
* The problem matchers attached to the task. Defaults to an empty
* array.
*/
problemMatchers: string[];
options?: ProcessExecutionOptions;
}
export type ShellTaskOptions = {
/**
* Options for a shell execution
*/
export type ShellExecutionOptions = {
/**
* The shell executable.
*/
executable: string;
executable?: string;
/**
* The arguments to be passed to the shell executable used to run the task.
@ -261,89 +215,90 @@ declare module 'vscode' {
* the parent process' environment.
*/
env?: { [key: string]: string };
} | {
/**
* The current working directory of the executed shell.
* If omitted the tools current workspace root is used.
*/
cwd: string;
};
/**
* The additional environment of the executed shell. If omitted
* the parent process' environment is used. If provided it is merged with
* the parent process' environment.
*/
env?: { [key: string]: string };
} | {
/**
* The current working directory of the executed shell.
* If omitted the tools current workspace root is used.
*/
cwd?: string;
/**
* The additional environment of the executed shell. If omitted
* the parent process' environment is used. If provided it is merged with
* the parent process' environment.
*/
env: { [key: string]: string };
};
export class ShellExecution {
/**
* Creates a process execution.
*
* @param commandLine The command line to execute.
* @param options Optional options for the started the shell.
*/
constructor(commandLine: string, options?: ShellExecutionOptions);
/**
* The shell command line
*/
commandLine: string;
/**
* The shell options used when the command line is executed in a shell.
* Defaults to undefined.
*/
options?: ShellExecutionOptions;
}
/**
* A task that executes a shell command.
* A task to execute
*/
export class ShellTask {
export class Task {
/**
* Creates a shell task.
* Creates a new task. A task without an exection set is resolved
* before executed.
*
* @param identifier: the task's identifier as defined in the 'taskTypes' extension point.
* @param name the task's name. Is presented in the user interface.
* @param commandLine the command line to execute.
* @param kind The task kind as defined in the 'taskKinds' extension point.
* @param name The task's name. Is presented in the user interface.
*/
constructor(kind: TaskKind, name: string);
/**
* Creates a new task.
*
* @param kind The task kind as defined in the 'taskKinds' extension point.
* @param name The task's name. Is presented in the user interface.
* @param execution The process or shell execution.
*/
constructor(kind: TaskKind, name: string, execution: ProcessExecution | ShellExecution);
/**
* Creates a new task.
*
* @param kind The task kind as defined in the 'taskKinds' extension point.
* @param name The task's name. Is presented in the user interface.
* @param execution The process or shell execution.
* @param problemMatchers the names of problem matchers to use, like '$tsc'
* or '$eslint'. Problem matchers can be contributed by an extension using
* the `problemMatchers` extension point.
*/
constructor(identifier: TaskIdentifier, name: string, commandLine: string, problemMatchers?: string | string[]);
constructor(kind: TaskKind, name: string, execution: ProcessExecution | ShellExecution, problemMatchers?: string | string[]);
/**
* Creates a shell task.
*
* @param identifier: the task's identifier as defined in the 'taskTypes' extension point.
* @param name the task's name. Is presented in the user interface.
* @param commandLine the command line to execute.
* @param options additional options used when creating the shell.
* @param problemMatchers the names of problem matchers to use, like '$tsc'
* or '$eslint'. Problem matchers can be contributed by an extension using
* the `problemMatchers` extension point.
* The task's kind.
*/
constructor(identifier: TaskIdentifier, name: string, commandLine: string, options: ShellTaskOptions, problemMatchers?: string | string[]);
/**
* The task's identifier.
*/
identifier: TaskIdentifier;
kind: TaskKind;
/**
* The task's name
*/
name: string;
/**
* The task's execution engine
*/
execution: ProcessExecution | ShellExecution;
/**
* Whether the task is a background task or not.
*/
isBackground: boolean;
/**
* The command line to execute.
*/
commandLine: string;
/**
* A human-readable string describing the source of this
* shell task, e.g. 'gulp' or 'npm'.
*/
source: string | undefined;
source?: string;
/**
* The task group this tasks belongs to. See TaskGroup
@ -351,13 +306,7 @@ declare module 'vscode' {
* Defaults to undefined meaning that the task doesn't
* belong to any special group.
*/
group: string | undefined;
/**
* The shell options used when the shell is executed. Defaults to an
* empty object literal.
*/
options: ShellTaskOptions;
group?: TaskGroup;
/**
* The presentation options. Defaults to an empty literal.
@ -371,29 +320,36 @@ declare module 'vscode' {
problemMatchers: string[];
}
export type Task = ProcessTask | ShellTask;
/**
* A task provider allows to add tasks to the task service.
* A task provider is registerd via #workspace.registerTaskProvider.
*/
export interface TaskProvider {
/**
* Provides additional tasks.
* Provides tasks.
* @param token A cancellation token.
* @return a #TaskSet
* @return an array of tasks
*/
provideTasks(token: CancellationToken): ProviderResult<Task[]>;
/**
* Resolves a task the has no execution set.
* @param task The task to resolve.
* @param token A cancellation token.
* @return the resolved task
*/
resolveTask(task: Task, token: CancellationToken): ProviderResult<Task>;
}
export namespace workspace {
/**
* Register a task provider.
*
* @param type The task kind type this provider is registered for.
* @param provider A task provider.
* @return A [disposable](#Disposable) that unregisters this provider when being disposed.
*/
export function registerTaskProvider(provider: TaskProvider): Disposable;
export function registerTaskProvider(type: string, provider: TaskProvider): Disposable;
}
export namespace window {

View file

@ -429,7 +429,7 @@ export function createApiFactory(
getConfiguration: (section?: string): vscode.WorkspaceConfiguration => {
return extHostConfiguration.getConfiguration(section);
},
registerTaskProvider: proposedApiFunction(extension, (provider: vscode.TaskProvider) => {
registerTaskProvider: proposedApiFunction(extension, (type: string, provider: vscode.TaskProvider) => {
return extHostTask.registerTaskProvider(extension, provider);
})
};
@ -518,8 +518,9 @@ export function createApiFactory(
TaskRevealKind: extHostTypes.TaskRevealKind,
TaskPanelKind: extHostTypes.TaskPanelKind,
TaskGroup: extHostTypes.TaskGroup,
ShellTask: extHostTypes.ShellTask,
ProcessTask: extHostTypes.ProcessTask
ProcessExecution: extHostTypes.ProcessExecution,
ShellExecution: extHostTypes.ShellExecution,
Task: extHostTypes.Task
};
};
}

View file

@ -256,7 +256,7 @@ namespace CommandOptions {
function isShellConfiguration(value: any): value is { executable: string; shellArgs?: string[] } {
return value && typeof value.executable === 'string';
}
export function from(value: vscode.ShellTaskOptions | vscode.ProcessTaskOptions): TaskSystem.CommandOptions {
export function from(value: vscode.ShellExecutionOptions | vscode.ProcessExecutionOptions): TaskSystem.CommandOptions {
if (value === void 0 || value === null) {
return undefined;
}
@ -321,37 +321,41 @@ namespace Tasks {
return undefined;
}
let command: TaskSystem.CommandConfiguration;
if (task instanceof types.ProcessTask) {
command = getProcessCommand(task);
} else if (task instanceof types.ShellTask) {
command = getShellCommand(task);
let execution = task.execution;
if (execution instanceof types.ProcessExecution) {
command = getProcessCommand(execution);
} else if (execution instanceof types.ShellExecution) {
command = getShellCommand(execution);
} else {
return undefined;
}
if (command === void 0) {
return undefined;
}
command.presentation = PresentationOptions.from(task.presentationOptions);
let source = {
kind: TaskSystem.TaskSourceKind.Extension,
label: typeof task.source === 'string' ? task.source : extension.name,
detail: extension.id
};
let label = nls.localize('task.label', '{0}: {1}', source.label, task.name);
let id = `${extension.id}.${task.identifierKey}`;
let identifier: TaskSystem.TaskIdentifier = {
_key: task.identifierKey,
type: task.identifier.type
let key = (task as types.Task).kindKey;
let kind = (task as types.Task).kind;
let id = `${extension.id}.${key}`;
let taskKind: TaskSystem.TaskIdentifier = {
_key: key,
type: kind.type
};
Objects.assign(identifier, task.identifier);
Objects.assign(taskKind, kind);
let result: TaskSystem.ContributedTask = {
_id: id, // uuidMap.getUUID(identifier),
_source: source,
_label: label,
type: task.identifier.type,
defines: identifier,
type: kind.type,
defines: taskKind,
name: task.name,
identifier: label,
group: types.TaskGroup.is(task.group) ? task.group : undefined,
group: task.group ? (task.group as types.TaskGroup).id : undefined,
command: command,
isBackground: !!task.isBackground,
problemMatchers: task.problemMatchers.slice()
@ -359,7 +363,7 @@ namespace Tasks {
return result;
}
function getProcessCommand(value: vscode.ProcessTask): TaskSystem.CommandConfiguration {
function getProcessCommand(value: vscode.ProcessExecution): TaskSystem.CommandConfiguration {
if (typeof value.process !== 'string') {
return undefined;
}
@ -368,7 +372,7 @@ namespace Tasks {
args: Strings.from(value.args),
runtime: TaskSystem.RuntimeType.Process,
suppressTaskName: true,
presentation: PresentationOptions.from(value.presentationOptions)
presentation: undefined
};
if (value.options) {
result.options = CommandOptions.from(value.options);
@ -376,14 +380,14 @@ namespace Tasks {
return result;
}
function getShellCommand(value: vscode.ShellTask): TaskSystem.CommandConfiguration {
function getShellCommand(value: vscode.ShellExecution): TaskSystem.CommandConfiguration {
if (typeof value.commandLine !== 'string') {
return undefined;
}
let result: TaskSystem.CommandConfiguration = {
name: value.commandLine,
runtime: TaskSystem.RuntimeType.Shell,
presentation: PresentationOptions.from(value.presentationOptions)
presentation: undefined
};
if (value.options) {
result.options = CommandOptions.from(value.options);

View file

@ -1015,22 +1015,6 @@ export class DocumentLink {
}
}
export enum FileLocationKind {
Auto = 1,
Relative = 2,
Absolute = 3
}
export enum ApplyToKind {
AllDocuments = 1,
OpenDocuments = 2,
ClosedDocuments = 3
}
export enum TaskRevealKind {
Always = 1,
@ -1047,44 +1031,170 @@ export enum TaskPanelKind {
New = 3
}
export class BaseTask {
export class TaskGroup implements vscode.TaskGroup {
private _id: string;
private _label: string;
public static Clean: TaskGroup = new TaskGroup('clean', 'Clean');
public static Build: TaskGroup = new TaskGroup('build', 'Build');
public static RebuildAll: TaskGroup = new TaskGroup('rebuildAll', 'RebuildAll');
public static Test: TaskGroup = new TaskGroup('clean', 'Clean');
constructor(id: string, label: string) {
if (typeof id !== 'string') {
throw illegalArgument('name');
}
if (typeof label !== 'string') {
throw illegalArgument('name');
}
this._id = id;
this._label = label;
}
get id(): string {
return this._id;
}
}
export class ProcessExecution implements vscode.ProcessExecution {
private _process: string;
private _args: string[];
private _options: vscode.ProcessExecutionOptions;
constructor(process: string, options?: vscode.ProcessExecutionOptions);
constructor(process: string, args: string[], options?: vscode.ProcessExecutionOptions);
constructor(process: string, varg1?: string[] | vscode.ProcessExecutionOptions, varg2?: vscode.ProcessExecutionOptions) {
if (typeof process !== 'string') {
throw illegalArgument('process');
}
this._process = process;
if (varg1 !== void 0) {
if (Array.isArray(varg1)) {
this._args = varg1;
this._options = varg2;
} else {
this._options = varg1;
}
}
if (this._args === void 0) {
this._args = [];
}
}
get process(): string {
return this._process;
}
set process(value: string) {
if (typeof value !== 'string') {
throw illegalArgument('process');
}
this._process = value;
}
get args(): string[] {
return this._args;
}
set args(value: string[]) {
if (!Array.isArray(value)) {
value = [];
}
this._args = value;
}
get options(): vscode.ProcessExecutionOptions {
return this._options;
}
set options(value: vscode.ProcessExecutionOptions) {
this._options = value;
}
}
export class ShellExecution implements vscode.ShellExecution {
private _commandLine: string;
private _options: vscode.ShellExecutionOptions;
constructor(commandLine: string, options?: vscode.ShellExecutionOptions) {
if (typeof commandLine !== 'string') {
throw illegalArgument('commandLine');
}
this._commandLine = commandLine;
this._options = options;
}
get commandLine(): string {
return this._commandLine;
}
set commandLine(value: string) {
if (typeof value !== 'string') {
throw illegalArgument('commandLine');
}
this._commandLine = value;
}
get options(): vscode.ShellExecutionOptions {
return this._options;
}
set options(value: vscode.ShellExecutionOptions) {
this._options = value;
}
}
export class Task implements vscode.Task {
private _kind: vscode.TaskKind;
private _kindKey: string;
private _name: string;
private _execution: ProcessExecution | ShellExecution;
private _problemMatchers: string[];
private _identifier: vscode.TaskIdentifier;
private _identifierKey: string;
private _isBackground: boolean;
private _source: string;
private _group: string;
private _group: TaskGroup;
private _presentationOptions: vscode.TaskPresentationOptions;
constructor(identifier: vscode.TaskIdentifier, name: string, problemMatchers: string[]) {
this.identifier = identifier;
constructor(kind: vscode.TaskKind, name: string);
constructor(kind: vscode.TaskKind, name: string, execution: ProcessExecution | ShellExecution);
constructor(kind: vscode.TaskKind, name: string, execution: ProcessExecution | ShellExecution, problemMatchers?: string | string[]);
constructor(kind: vscode.TaskKind, name: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string[]) {
this.kind = kind;
this.name = name;
this.execution = execution;
this._problemMatchers = problemMatchers || [];
this._isBackground = false;
this._presentationOptions = Object.create(null);
}
get identifier(): vscode.TaskIdentifier {
return this._identifier;
get kind(): vscode.TaskKind {
return this._kind;
}
set identifier(value: vscode.TaskIdentifier) {
set kind(value: vscode.TaskKind) {
if (value === void 0 || value === null) {
throw illegalArgument('Identifier can\'t be undefined or null');
throw illegalArgument('Kind can\'t be undefined or null');
}
this._identifierKey = undefined;
this._identifier = value;
this._kindKey = undefined;
this._kind = value;
}
get identifierKey(): string {
if (!this._identifierKey) {
get kindKey(): string {
if (!this._kindKey) {
const hash = crypto.createHash('md5');
hash.update(JSON.stringify(this._identifier));
this._identifierKey = hash.digest('hex');
hash.update(JSON.stringify(this._kind));
this._kindKey = hash.digest('hex');
}
return this._identifierKey;
return this._kindKey;
}
get name(): string {
@ -1098,6 +1208,28 @@ export class BaseTask {
this._name = value;
}
get execution(): ProcessExecution | ShellExecution {
return this._execution;
}
set execution(value: ProcessExecution | ShellExecution) {
if (value === null) {
value = undefined;
}
this._execution = value;
}
get problemMatchers(): string[] {
return this._problemMatchers;
}
set problemMatchers(value: string[]) {
if (!Array.isArray(value)) {
value = [];
}
this._problemMatchers = value;
}
get isBackground(): boolean {
return this._isBackground;
}
@ -1124,18 +1256,15 @@ export class BaseTask {
this._source = value;
}
get group(): string {
get group(): TaskGroup {
return this._group;
}
set group(value: string) {
set group(value: TaskGroup) {
if (value === void 0 || value === null) {
this._group = undefined;
return;
}
if (typeof value !== 'string' || value.length === 0) {
throw illegalArgument('group must be a string of length > 0');
}
this._group = value;
}
@ -1144,176 +1273,13 @@ export class BaseTask {
}
set presentationOptions(value: vscode.TaskPresentationOptions) {
if (value === void 0 || value === null) {
value = Object.create(null);
if (value === null) {
value = undefined;
}
this._presentationOptions = value;
}
get problemMatchers(): string[] {
return this._problemMatchers;
}
set problemMatchers(value: string[]) {
if (!Array.isArray(value)) {
value = [];
}
this._problemMatchers = value;
}
}
/*
namespace ProblemMatcher {
export function is(value: any): value is vscode.ProblemMatcher {
let candidate: vscode.ProblemMatcher = value;
return candidate && !!candidate.pattern;
}
}
*/
namespace ShellOptions {
export function is(value: any): value is vscode.ShellTaskOptions {
return value && ((typeof value.executable === 'string') || (typeof value.cwd === 'string') || !!value.env);
}
}
export namespace TaskGroup {
/**
* The clean task group
*/
export const Clean: 'clean' = 'clean';
/**
* The build task group
*/
export const Build: 'build' = 'build';
/**
* The rebuild all task group
*/
export const RebuildAll: 'rebuildAll' = 'rebuildAll';
/**
* The test task group
*/
export const Test: 'test' = 'test';
export function is(value: string): value is string {
return value === Clean || value === Build || value === RebuildAll || value === Test;
}
}
export class ProcessTask extends BaseTask {
private _process: string;
private _args: string[];
private _options: vscode.ProcessTaskOptions;
constructor(identifier: vscode.TaskIdentifier, name: string, process: string, args?: string[], problemMatchers?: string | string[]);
constructor(identifier: vscode.TaskIdentifier, name: string, process: string, args: string[] | undefined, options: vscode.ProcessTaskOptions, problemMatchers?: string | string[]);
constructor(identifier: vscode.TaskIdentifier, name: string, process: string, varg1?: string[], varg2?: vscode.ProcessTaskOptions | string | string[], varg3?: string | string[]) {
if (typeof process !== 'string') {
throw illegalArgument('process');
}
let args: string[];
let options: vscode.ProcessTaskOptions;
let problemMatchers: string | string[];
args = varg1 || [];
if (varg2) {
if (Array.isArray(varg2) || typeof varg2 === 'string') {
problemMatchers = varg2;
} else {
options = varg2;
}
}
if (varg3 && !problemMatchers) {
problemMatchers = varg3;
}
let pm: string[];
if (problemMatchers && (typeof problemMatchers === 'string')) {
pm = [problemMatchers];
} else if (Array.isArray(problemMatchers)) {
pm = problemMatchers;
}
pm = pm || [];
super(identifier, name, pm);
this._process = process;
this._args = args;
this._options = options || Object.create(null);
}
get process(): string {
return this._process;
}
get args(): string[] {
return this._args;
}
set args(value: string[]) {
if (!Array.isArray(value)) {
value = [];
}
this._args = value;
}
get options(): vscode.ProcessTaskOptions {
return this._options;
}
set options(value: vscode.ProcessTaskOptions) {
if (value === void 0 || value === null) {
value = Object.create(null);
}
this._options = value;
}
}
export class ShellTask extends BaseTask implements vscode.ShellTask {
private _commandLine: string;
private _options: vscode.ShellTaskOptions;
constructor(identifier: vscode.TaskIdentifier, name: string, commandLine: string, problemMatchers?: string | string[]);
constructor(identifier: vscode.TaskIdentifier, name: string, commandLine: string, options: vscode.ShellTaskOptions, problemMatchers?: string | string[]);
constructor(identifier: vscode.TaskIdentifier, name: string, commandLine: string, optionsOrProblemMatchers?: vscode.ShellTaskOptions | string | string[], problemMatchers?: string | string[]) {
if (typeof commandLine !== 'string') {
throw illegalArgument('commandLine');
}
let options: vscode.ShellTaskOptions = undefined;
let pm: string[];
if (ShellOptions.is(optionsOrProblemMatchers)) {
options = optionsOrProblemMatchers;
} else {
problemMatchers = optionsOrProblemMatchers;
}
if (problemMatchers && (typeof problemMatchers === 'string')) {
pm = [problemMatchers];
} else if (Array.isArray(problemMatchers)) {
pm = problemMatchers;
}
pm = pm || [];
super(identifier, name, pm);
this._commandLine = commandLine;
this._options = options || Object.create(null);
}
get commandLine(): string {
return this._commandLine;
}
get options(): vscode.ShellTaskOptions {
return this._options;
}
set options(value: vscode.ShellTaskOptions) {
if (value === void 0 || value === null) {
value = Object.create(null);
}
this._options = value;
}
}
export enum ProgressLocation {
SourceControl = 1,

View file

@ -0,0 +1,6 @@
Allow configuring of problem matchers for auto detected build tasks
Run Build > list of build tasks > user selected task with PM > show UI to select problem matcher > open tasks.json
Task Menu only in insider
Telemetry for task
Polish task menu.

View file

@ -20,7 +20,7 @@ const taskTypeSchema: IJSONSchema = {
type: 'object',
additionalProperties: false,
properties: {
taskType: {
type: {
type: 'string',
description: nls.localize('TaskType.description', 'The actual task type')
},
@ -36,7 +36,7 @@ const taskTypeSchema: IJSONSchema = {
namespace Configuration {
export interface TaskTypeDescription {
taskType?: string;
type?: string;
required?: string[];
properties?: IJSONSchemaMap;
}
@ -45,7 +45,7 @@ namespace Configuration {
if (!value) {
return undefined;
}
let taskType = Types.isString(value.taskType) ? value.taskType : undefined;
let taskType = Types.isString(value.type) ? value.type : undefined;
if (!taskType || taskType.length === 0) {
messageCollector.error(nls.localize('TaskTypeConfiguration.noType', 'The task type configuration is missing the required \'taskType\' property'));
return undefined;
@ -64,7 +64,7 @@ namespace Configuration {
const taskTypesExtPoint = ExtensionsRegistry.registerExtensionPoint<Configuration.TaskTypeDescription[]>('taskTypes', [], {
description: nls.localize('TaskTypeExtPoint', 'Contributes task types'),
description: nls.localize('TaskTypeExtPoint', 'Contributes task kinds'),
type: 'array',
items: taskTypeSchema
});