Skip to content

Commit

Permalink
Allow customization of build tool tasks
Browse files Browse the repository at this point in the history
Add `args` parameter to all build tool tasks that allows customization in the workspaces's tasks.json by users
Implement generic task of `ros` type
Add `roscore` and `roslaunch` commands using `ros` task that allows user to run and customize them in `tasks.json`
Add `roscore and  `roslaunch` problem matchers that allow corresponding tasks to run in background
  • Loading branch information
anton-matosov committed Oct 3, 2020
1 parent 5889eb9 commit b0dcf8d
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 105 deletions.
3 changes: 1 addition & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
"typescript.tsdk": "./node_modules/typescript/lib", // we want to use the TS server from our node_modules folder to control its version
"python.pythonPath": "C:\\opt\\python27amd64\\python.exe"
"typescript.tsdk": "./node_modules/typescript/lib"
}
79 changes: 74 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,20 +239,89 @@
"severity": 4,
"message": 5
}
},
{
"name": "roscore",
"pattern": {
"regexp": ".",
"file": 1,
"line": 2,
"message": 3
},
"background": {
"activeOnStart": true,
"beginsPattern": ".",
"endsPattern": "(process[master]: started with pid|master is already running)"
}
},
{
"name": "roslaunch",
"pattern": {
"regexp": "^(.*):\\s+(.*):\\s+line\\s+(\\d+),\\s+column\\s+(\\d+)$",
"line": 3,
"column": 4,
"message": 2,
"severity": 1
},
"background": {
"activeOnStart": true,
"beginsPattern": "started roslaunch server",
"endsPattern": "ROS_MASTER_URI="
}
}
],
"taskDefinitions": [
{
"type": "catkin_make"
"type": "ros",
"required": [
"command"
],
"properties": {
"command": {
"type": "string",
"description": "command to execute in ROS environment"
},
"args": {
"type": "array",
"description": "Commadn line arguments to command"
}
}
},
{
"type": "catkin_make_isolated"
"type": "catkin_make",
"properties": {
"args": {
"type": "array",
"description": "Commadn line arguments to catkin_make"
}
}
},
{
"type": "catkin"
"type": "catkin_make_isolated",
"properties": {
"args": {
"type": "array",
"description": "Commadn line arguments to catkin_make_isolated"
}
}
},
{
"type": "colcon"
"type": "catkin",
"properties": {
"args": {
"type": "array",
"description": "Commadn line arguments to catkin"
}
}
},
{
"type": "colcon",
"properties": {
"args": {
"type": "array",
"description": "Commadn line arguments to colcon"
}
}
}
]
},
Expand Down Expand Up @@ -294,4 +363,4 @@
"ms-python.python",
"ms-vscode.cpptools"
]
}
}
27 changes: 11 additions & 16 deletions src/build-tool/catkin-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,31 @@ import * as vscode from "vscode";

import * as extension from "../extension";
import * as common from "./common";
import * as rosShell from "./ros-shell";

function makeCatkin(command: string, args: string[], category?: string): vscode.Task {
const task = rosShell.make({type: command, command, args: ['--workspace', extension.baseDir, ...args]}, category)
task.problemMatchers = ["$catkin-gcc"];

return task;
}

/**
* Provides catkin tools build and test tasks.
*/
export class CatkinToolsProvider implements vscode.TaskProvider {
public provideTasks(token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task[]> {
let buildCommand: string;
let testCommand: string;

buildCommand = `catkin build --workspace "${extension.baseDir}"`;
testCommand = `${buildCommand} --catkin-make-args run_tests`;

const make = new vscode.Task({ type: "catkin" }, "make", "catkin");
make.execution = new vscode.ShellExecution(buildCommand, {
env: extension.env,
});
const make = makeCatkin('catkin', [], 'build');
make.group = vscode.TaskGroup.Build;
make.problemMatchers = ["$catkin-gcc"];

const test = new vscode.Task({ type: "catkin" }, "run_tests", "catkin");
test.execution = new vscode.ShellExecution(testCommand, {
env: extension.env,
});
const test = makeCatkin('catkin', ['--catkin-make-args', 'run_tests'], 'run_tests');
test.group = vscode.TaskGroup.Test;

return [make, test];
}

public resolveTask(task: vscode.Task, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task> {
return undefined;
return rosShell.resolve(task);
}
}

Expand Down
75 changes: 20 additions & 55 deletions src/build-tool/catkin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,84 +5,49 @@ import * as vscode from "vscode";

import * as extension from "../extension";
import * as common from "./common";
import * as rosShell from "./ros-shell";

function makeCatkin(command: string, args: string[], category?: string): vscode.Task {
const task = rosShell.make({type: command, command, args: ['--directory', extension.baseDir, ...args]}, category)
task.problemMatchers = ["$catkin-gcc"];

return task;
}
/**
* Provides catkin_make build and test tasks
*/
export class CatkinMakeProvider implements vscode.TaskProvider {
public provideTasks(token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task[]> {
const tasksCatkinMake = this.provideCatkinMakeTasks();
return [...tasksCatkinMake];
}

public resolveTask(task: vscode.Task, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task> {
return undefined;
}

private provideCatkinMakeTasks(): vscode.Task[] {
const catkinMakeDefinition: vscode.TaskDefinition = {
type: "catkin_make",
};
const make = new vscode.Task(catkinMakeDefinition, "build", "catkin_make");
const buildCommand = `catkin_make --directory "${extension.baseDir}"`;
make.execution = new vscode.ShellExecution(buildCommand, {
env: extension.env,
});
const make = makeCatkin('catkin_make', [], 'build');
make.group = vscode.TaskGroup.Build;
make.problemMatchers = ["$catkin-gcc"];

const catkinMakeRunTestsDefinition: vscode.TaskDefinition = {
type: "catkin_make",
};
const test = new vscode.Task(catkinMakeRunTestsDefinition, "run_tests", "catkin_make");
const testCommand = `${buildCommand} run_tests`;
test.execution = new vscode.ShellExecution(testCommand, {
env: extension.env,
});
const test = makeCatkin('catkin_make', ['run_tests'], 'run_tests');
test.group = vscode.TaskGroup.Test;

return [make, test];
}
}

public resolveTask(task: vscode.Task, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task> {
return rosShell.resolve(task);
}
}
/**
* Provides catkin_make_isolated build and test tasks
* Provides catkin_make build and test tasks
*/
// tslint:disable-next-line: max-classes-per-file
export class CatkinMakeIsolatedProvider implements vscode.TaskProvider {
public provideTasks(token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task[]> {
const tasksCatkinMakeIsolated = this.provideCatkinMakeIsolatedTasks();
return [...tasksCatkinMakeIsolated];
}

public resolveTask(task: vscode.Task, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task> {
return undefined;
}

private provideCatkinMakeIsolatedTasks(): vscode.Task[] {
const catkinMakeIsolatedDefinition: vscode.TaskDefinition = {
type: "catkin_make_isolated",
};
const make = new vscode.Task(catkinMakeIsolatedDefinition, "build", "catkin_make_isolated");
const buildCommand = `catkin_make_isolated --directory "${extension.baseDir}"`;
make.execution = new vscode.ShellExecution(buildCommand, {
env: extension.env,
});
const make = makeCatkin('catkin_make_isolated', [], 'build');
make.group = vscode.TaskGroup.Build;
make.problemMatchers = ["$catkin-gcc"];

const catkinMakeIsolatedRunTestsDefinition: vscode.TaskDefinition = {
type: "catkin_make_isolated",
};
const test = new vscode.Task(catkinMakeIsolatedRunTestsDefinition, "run_tests", "catkin_make_isolated");
const testCommand = `${buildCommand} --catkin-make-args run_tests`;
test.execution = new vscode.ShellExecution(testCommand, {
env: extension.env,
});
const test = makeCatkin('catkin_make_isolated', ['--catkin-make-args', 'run_tests'], 'run_tests');
test.group = vscode.TaskGroup.Test;

return [make, test];
}

public resolveTask(task: vscode.Task, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task> {
return rosShell.resolve(task);
}
}

/**
Expand Down
53 changes: 26 additions & 27 deletions src/build-tool/colcon.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,48 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import * as child_process from "child_process";
import * as vscode from "vscode";

import * as child_process from "child_process";
import * as extension from "../extension";
import * as common from "./common";
import * as rosShell from "./ros-shell";

function makeColcon(command: string, args: string[], category?: string): vscode.Task {
const task = rosShell.make({type: command, command, args: ['--workspace', extension.baseDir, ...args]}, category)

return task;
}

/**
* Provides colcon build and test tasks.
* Provides catkin tools build and test tasks.
*/
export class ColconProvider implements vscode.TaskProvider {
public provideTasks(token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task[]> {
const buildCommand = "colcon build";
const testCommand = "colcon test";

const build = new vscode.Task(
{ type: "colcon" },
vscode.TaskScope.Workspace,
"build",
"colcon",
new vscode.ShellExecution(buildCommand, {
env: extension.env,
}),
[]);
build.group = vscode.TaskGroup.Build;

const test = new vscode.Task(
{ type: "colcon" },
vscode.TaskScope.Workspace,
"test",
"colcon",
new vscode.ShellExecution(testCommand, {
env: extension.env,
}),
[]);
const make = makeColcon('colcon', ['build'], 'build');
make.group = vscode.TaskGroup.Build;

const test = makeColcon('colcon', ['test'], 'test');
test.group = vscode.TaskGroup.Test;

return [build, test];
return [make, test];
}

public resolveTask(task: vscode.Task, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task> {
return undefined;
return rosShell.resolve(task);
}
}

/**
* Interacts with the user to run a `catkin create pkg` command.
*/
export async function createPackage(uri?: vscode.Uri) {
const createPkgCommand = (dependencies: string, name: string): string => {
return `catkin create pkg --catkin-deps ${dependencies} -- ${name}`;
};
return common._createPackage(createPkgCommand);
}

export async function isApplicable(dir: string): Promise<boolean> {
const opts = { dir, env: extension.env };
const { stdout, stderr } = await child_process.exec("colcon -h", opts);
Expand Down
60 changes: 60 additions & 0 deletions src/build-tool/ros-shell.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import * as vscode from "vscode";

import * as extension from "../extension";

export interface RosTaskDefinition extends vscode.TaskDefinition {
command: string;
args?: string[];
}

export class RosShellTaskProvider implements vscode.TaskProvider {
public provideTasks(token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task[]> {
return this.defaultRosTasks();
}

public defaultRosTasks(): vscode.Task[] {
const rosCore = make({type: 'ros', command: 'roscore'}, 'roscore');
rosCore.isBackground = true;
rosCore.problemMatchers = ['$roscore'];

const rosLaunch = make({type: 'ros', command: 'roslaunch', args: ['package_name', 'launch_file.launch']}, 'roslaunch');
rosLaunch.isBackground = true;
rosLaunch.problemMatchers = ['$roslaunch'];

return [rosCore, rosLaunch];
}

public resolveTask(task: vscode.Task, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.Task> {
return resolve(task);
}
}

export function registerRosShellTaskProvider(): vscode.Disposable[] {
return [
vscode.tasks.registerTaskProvider('ros', new RosShellTaskProvider()),
];
}

export function resolve(task: vscode.Task): vscode.Task {
const resolvedTask = make(task.definition as RosTaskDefinition);

resolvedTask.isBackground = task.isBackground;
resolvedTask.problemMatchers = task.problemMatchers;
return resolvedTask;
}

export function make(definition: RosTaskDefinition, category?: string): vscode.Task {
definition.command = definition.command || definition.type; // Command can be missing in build tasks that have type==command

const args = definition.args || [];
const name = category ? category : args.join(' ');
const task = new vscode.Task(definition, vscode.TaskScope.Workspace, name, definition.command);

task.execution = new vscode.ShellExecution(definition.command, args, {
env: extension.env,
});
return task;
}
Loading

0 comments on commit b0dcf8d

Please sign in to comment.