Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support specifying the ROS setup script #678

Merged
merged 4 commits into from
Feb 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@
"ros.distro": {
"type": "string",
"description": "ROS installation distro to be sourced."
},
"ros.rosSetupScript": {
"type": "string",
"description": "ROS workspace setup script. Overrides ros.distro."
},
"ros.isolateEnvironment": {
"type": "bool",
"default": false,
"description": "Specify if the extension should not capture the environment VSCode is running in to pass to child processes."
}
}
},
Expand Down
13 changes: 10 additions & 3 deletions src/debugger/configuration/resolvers/ros2/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ export class LaunchResolver implements vscode.DebugConfigurationProvider {
},
};

console.log("Executing dumper with the following environment:");
console.log(rosExecOptions.env);

let ros2_launch_dumper = getExtensionFilePath(path.join("assets", "scripts", "ros2_launch_dumper.py"));

let args = []
Expand All @@ -91,10 +94,14 @@ export class LaunchResolver implements vscode.DebugConfigurationProvider {
`/usr/bin/env python3 ${ros2_launch_dumper} "${config.target}" ${flatten_args}`;

let result = await promisifiedExec(ros2_launch_dumper_cmdLine, rosExecOptions);

if (result.stderr) {
throw (new Error(`Error from ROS2 launch dumper:\r\n ${result.stderr}`));
} else if (result.stdout.length == 0) {
throw (new Error(`ROS2 launch dumper unexpectedly produced no output.`));
// Having stderr output is not nessesarily a problem, but it is useful for debugging
console.log(`ROS2 launch processor produced stderr output:\r\n ${result.stderr}`);
}

if (result.stdout.length == 0) {
throw (new Error(`ROS2 launch processor was unable to produce a node list.\r\n ${result.stderr}`));
}

let commands = result.stdout.split(os.EOL);
Expand Down
91 changes: 60 additions & 31 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,50 +276,79 @@ async function sourceRosAndWorkspace(): Promise<void> {

const kWorkspaceConfigTimeout = 30000; // ms

const config = vscode_utils.getExtensionConfiguration();
let distro = config.get("distro", "");
let setupScriptExt: string;
if (process.platform === "win32") {
setupScriptExt = ".bat";
} else {
setupScriptExt = ".bash";
}

// Is there a distro defined either by setting or environment?
if (!distro && !process.env.ROS_DISTRO)
{
// No? Try to find one.
const installedDistros = await ros_utils.getDistros();
if (!installedDistros.length) {
throw new Error("ROS has not been found on this system.");
} else if (installedDistros.length === 1) {
// if there is only one distro installed, directly choose it
config.update("distro", installedDistros[0]);
} else {
const message = "Multiple ROS distros found. Configure this workspace by setting \"ros.distro\": \"<ROS Distro>\" in settings.json or in the ROS extension settings.";
await vscode.window.setStatusBarMessage(message, kWorkspaceConfigTimeout);
const config = vscode_utils.getExtensionConfiguration();
let isolateEnvironment = config.get("isolateEnvironment", "");
if (!isolateEnvironment) {
// Capture the host environment unless specifically isolated
env = process.env;
}


let rosSetupScript = config.get("rosSetupScript", "");

// If the workspace setup script is not set, try to find the ROS setup script in the environment
let attemptWorkspaceDiscovery = true;

if (rosSetupScript) {
// Try to support cases where the setup script doesn't make sense on different environments, such as host vs container.
if (await pfs.exists(rosSetupScript)){
try {
env = await ros_utils.sourceSetupFile(rosSetupScript, env);

attemptWorkspaceDiscovery = false;
} catch (err) {
vscode.window.showErrorMessage(`A workspace setup script was provided in the configuration, but could not source "${rosSetupScript}". Attempting standard discovery.`);
}
}
}

if (attemptWorkspaceDiscovery) {
let distro = config.get("distro", "");

if (distro) {
try {
let globalInstallPath: string;
if (process.platform === "win32") {
globalInstallPath = path.join("C:", "opt", "ros", `${distro}`, "x64");
// Is there a distro defined either by setting or environment?
if (!distro && !process.env.ROS_DISTRO)
{
// No? Try to find one.
const installedDistros = await ros_utils.getDistros();
if (!installedDistros.length) {
throw new Error("ROS has not been found on this system.");
} else if (installedDistros.length === 1) {
// if there is only one distro installed, directly choose it
config.update("distro", installedDistros[0]);
} else {
globalInstallPath = path.join("/", "opt", "ros", `${distro}`);
const message = "Unable to determine ROS distribution, please configure this workspace by adding \"ros.distro\": \"<ROS Distro>\" in settings.json";
await vscode.window.setStatusBarMessage(message, kWorkspaceConfigTimeout);
}
let setupScript: string = path.format({
dir: globalInstallPath,
name: "setup",
ext: setupScriptExt,
});
env = await ros_utils.sourceSetupFile(setupScript, {});
} catch (err) {
vscode.window.showErrorMessage(`Could not source the setup file for ROS distro "${distro}".`);
}
} else if (process.env.ROS_DISTRO) {
env = process.env;

if (distro) {
let setupScript: string;
try {
let globalInstallPath: string;
if (process.platform === "win32") {
globalInstallPath = path.join("C:", "opt", "ros", `${distro}`, "x64");
} else {
globalInstallPath = path.join("/", "opt", "ros", `${distro}`);
}
setupScript = path.format({
dir: globalInstallPath,
name: "setup",
ext: setupScriptExt,
});
env = await ros_utils.sourceSetupFile(setupScript, env);
} catch (err) {
vscode.window.showErrorMessage(`Could not source ROS setup script at "${setupScript}".`);
}
} else if (process.env.ROS_DISTRO) {
env = process.env;
}
}
// Source the workspace setup over the top.
// TODO: we should test what's the build tool (catkin vs colcon).
Expand Down
3 changes: 2 additions & 1 deletion src/ros/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export function sourceSetupFile(filename: string, env?: any): Promise<any> {
}
else {
exportEnvCommand = `bash -c "source '${filename}' && env"`;
console.log ("executing " + exportEnvCommand);
}

let processOptions: child_process.ExecOptions = {
Expand All @@ -34,7 +35,7 @@ export function sourceSetupFile(filename: string, env?: any): Promise<any> {
if (index !== -1) {
env[line.substr(0, index)] = line.substr(index + 1);
}

return env;
}, {}));
} else {
Expand Down