Skip to content

Commit

Permalink
Merge 66c1686 into e85b45e
Browse files Browse the repository at this point in the history
  • Loading branch information
doudou committed Sep 3, 2018
2 parents e85b45e + 66c1686 commit 490dfb0
Show file tree
Hide file tree
Showing 10 changed files with 435 additions and 260 deletions.
489 changes: 263 additions & 226 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "rock",
"displayName": "rock",
"description": "Base support for Rock workspaces",
"version": "0.2.2",
"version": "0.3.0",
"publisher": "rock-robotics",
"license": "SEE LICENSE IN LICENSE.txt",
"icon": "images/icon.png",
Expand Down
27 changes: 26 additions & 1 deletion src/autoproj.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as vscode from 'vscode';
import * as syskit from './syskit';
import * as wrappers from './wrappers';
import { EventEmitter } from 'events';
import * as url from 'url';

export function findWorkspaceRoot(rootPath: string): string | null
{
Expand All @@ -27,6 +28,10 @@ export function autoprojExePath(workspacePath: string): string
{
return path.join(workspacePath, '.autoproj', 'bin', 'autoproj')
}
export function configFilePath(workspacePath: string): string
{
return path.join(workspacePath, '.autoproj', 'config.yml')
}
export function installationManifestPath(workspacePath: string): string
{
return path.join(workspacePath, '.autoproj', 'installation-manifest')
Expand Down Expand Up @@ -187,6 +192,26 @@ export class Workspace
this.syskitDefaultStop();
}

syncRemote(name: string) : url.Url | undefined {
let autoprojConfig = this.config();
let syncConfig = autoprojConfig['sync'];
if (!syncConfig)
return;
let config = syncConfig[name];
if (!config)
return;

return new url.URL(config['uri']);
}

config() : object {
let data = fs.readFileSync(configFilePath(this.root)).toString();
let config = yaml.safeLoad(data.toString());
if (config)
return config;
else return {};
}

onInfoUpdated(callback: (info: WorkspaceInfo) => any) : vscode.Disposable {
return this._infoUpdatedEvent.event(callback);
}
Expand Down Expand Up @@ -583,7 +608,7 @@ export class Workspaces
return { added, workspace };
}

/** De-registers a folder
/** De-registers a folderuri.host
*
* Removes a folder, and removes the corresponding workspace
* if it was the last folder of this workspace - in which case
Expand Down
49 changes: 36 additions & 13 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,29 @@ export class ConfigManager

return data;
}
private tasksConfigurationPath(pkgPath: string)
{
return path.join(pkgPath, ".vscode", "tasks.json");
}
private writeConfigFile(path, data)
{
fs.writeFileSync(path, JSON.stringify(data, null, 4), this._defaultWriteOptions);
}
private updateTasksConfig(path: string, config: vscode.TaskDefinition)
{
const data = this.loadJsonFile(path);

if (!data.tasks)
data.tasks = [];
if (!Array.isArray(data.tasks))
throw new Error("Invalid tasks in tasks.json");
if (!data.version)
data.version = "2.0.0";

data.tasks = data.tasks.filter(t => t.name != config.name)
(data.tasks as Array<any>).unshift(config);
this.writeConfigFile(path, data);
}
private launchConfigurationPath(pkgPath: string)
{
return path.join(pkgPath, ".vscode", "launch.json");
Expand All @@ -122,32 +145,32 @@ export class ConfigManager
}
return candidate;
}
private updateLaunchConfig(pkgPath: string, config: vscode.DebugConfiguration)
private updateLaunchConfig(path: string, config: vscode.DebugConfiguration)
{
const data = this.loadJsonFile(this.launchConfigurationPath(pkgPath));
const data = this.loadJsonFile(path);

if (!data.configurations) data.configurations = [];
if (!data.configurations)
data.configurations = [];
if (!Array.isArray(data.configurations))
throw new Error("Invalid configuration in launch.json");
if (!data.version)
data.version = "0.2.0";

config.name = this.uniqueLaunchConfigName(config.name, data.configurations);
(data.configurations as Array<any>).unshift(config);
if (!data.version) data.version = "0.2.0";
fs.writeFileSync(this.launchConfigurationPath(pkgPath),
JSON.stringify(data, null, 4), this._defaultWriteOptions);
this.writeConfigFile(path, data);
}
addLaunchConfig(pkgPath: string, config: vscode.DebugConfiguration)
{
if (fs.existsSync(this.launchConfigurationPath(pkgPath))) {
this.updateLaunchConfig(pkgPath, config);
const path = this.launchConfigurationPath(pkgPath);
if (fs.existsSync(path)) {
this.updateLaunchConfig(path, config);
} else {
const data = {
this.createVscodeFolder(pkgPath);
this.writeConfigFile(path, {
version: "0.2.0",
configurations: [config]
}
this.createVscodeFolder(pkgPath);
fs.writeFileSync(this.launchConfigurationPath(pkgPath),
JSON.stringify(data, null, 4), this._defaultWriteOptions);
});
}
}
suggestedSettings(): any
Expand Down
60 changes: 48 additions & 12 deletions src/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ import * as packages from './packages'
import * as autoproj from './autoproj'
import * as child_process from 'child_process';
import * as syskit from './syskit';
import * as config from './config';

export class ConfigurationProvider implements vscode.DebugConfigurationProvider
{
protected _context : context.Context;
protected readonly _configManager: config.ConfigManager;

constructor(context : context.Context) {
constructor(context : context.Context, configManager : config.ConfigManager) {
this._context = context;
this._configManager = configManager;
}

async resolveDebugConfiguration(folder : vscode.WorkspaceFolder | undefined, config : vscode.DebugConfiguration, token : vscode.CancellationToken | undefined) : Promise<vscode.DebugConfiguration>
Expand Down Expand Up @@ -111,18 +114,51 @@ export class CXXConfigurationProvider extends ConfigurationProvider
config = await this.performExpansionsInObject(config,
(value) => this.expandAutoprojPaths((name) => ws.which(name), pkg.info, value));

config.miDebuggerPath = stubScript;
if (!config.environment) {
config.environment = [];
let debuggerServer = config.miDebuggerServerAddress;
if (debuggerServer) {
if (debuggerServer.startsWith("rock:")) {
this.setupDebugServer(ws, config, pkg.path);
}
}
else {
config.miDebuggerPath = stubScript;
if (!config.environment) {
config.environment = [];
}
config.environment = config.environment.concat([
{ name: "VSCODE_ROCK_AUTOPROJ_PATH", value: ws.autoprojExePath() },
{ name: "VSCODE_ROCK_AUTOPROJ_DEBUGGER", value: debuggerPath },
{ name: 'AUTOPROJ_CURRENT_ROOT', value: ws.root }
])

}
config.environment = config.environment.concat([
{ name: "VSCODE_ROCK_AUTOPROJ_PATH", value: ws.autoprojExePath() },
{ name: "VSCODE_ROCK_AUTOPROJ_DEBUGGER", value: debuggerPath },
{ name: 'AUTOPROJ_CURRENT_ROOT', value: ws.root }
])

return config;
}

private setupDebugServer(ws : autoproj.Workspace, config, pkgPath) {
let debuggerServer = config.miDebuggerServerAddress;
let syncNameAndPort = debuggerServer.slice(5);
let portIndex = syncNameAndPort.indexOf(":");
if (!portIndex) {
throw new Error("no port given");
}
let port = syncNameAndPort.slice(portIndex + 1);
let syncName = syncNameAndPort.slice(0, portIndex);

let uri = ws.syncRemote(syncName);
if (!uri) {
throw new Error(`no Autoproj Sync host ${syncName} in configuration`);
}

config.debugServerPath = ws.autoprojExePath();
let debugServerArgs = `sync exec ${syncName} -- gdbserver --once :${port} "${config.program}"`;
if (config.args && config.args.length > 0) {
debugServerArgs = debugServerArgs + ` "${config.args.join("\" \"")}"`;
}
config.debugServerArgs = debugServerArgs;
config.miDebuggerServerAddress = `${uri.hostname}:${port}`;
}
}

export class RubyConfigurationProvider extends ConfigurationProvider
Expand Down Expand Up @@ -150,9 +186,9 @@ export class RubyConfigurationProvider extends ConfigurationProvider
export class OrogenConfigurationProvider extends CXXConfigurationProvider
{
private readonly _vscode: wrappers.VSCode;
constructor(context : context.Context, wrapper: wrappers.VSCode)
constructor(context : context.Context, wrapper: wrappers.VSCode, configManager: config.ConfigManager)
{
super(context);
super(context, configManager);
this._vscode = wrapper;
}

Expand Down Expand Up @@ -195,7 +231,7 @@ export class OrogenConfigurationProvider extends CXXConfigurationProvider
for(let key in commandLine.env) {
config.environment.push({ name: key, value: commandLine.env[key] })
}

if (config.start || config.confDir) {
this.setupTask(ws, config.deployAs, config.start, config.confDir).
catch(err => {
Expand Down
6 changes: 3 additions & 3 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,11 @@ export function activate(extensionContext: vscode.ExtensionContext) {
extensionContext.subscriptions.push(workspaces);
extensionContext.subscriptions.push(outputChannel);

let cppDebugProvider = new debug.CXXConfigurationProvider(rockContext);
let cppDebugProvider = new debug.CXXConfigurationProvider(rockContext, configManager);
extensionContext.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('cppdbg', cppDebugProvider));
let rubyDebugProvider = new debug.RubyConfigurationProvider(rockContext);
let rubyDebugProvider = new debug.RubyConfigurationProvider(rockContext, configManager);
extensionContext.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('Ruby', rubyDebugProvider));
let orogenDebugProvider = new debug.OrogenConfigurationProvider(rockContext, vscodeWrapper);
let orogenDebugProvider = new debug.OrogenConfigurationProvider(rockContext, vscodeWrapper, configManager);
extensionContext.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('orogen', orogenDebugProvider));

extensionContext.subscriptions.push(rockContext);
Expand Down
2 changes: 1 addition & 1 deletion stubs/gdb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#! /bin/sh

exec "$VSCODE_ROCK_AUTOPROJ_PATH" exec "$VSCODE_ROCK_AUTOPROJ_DEBUGGER" "$@"
exec "$VSCODE_ROCK_AUTOPROJ_PATH" exec "$VSCODE_ROCK_AUTOPROJ_DEBUGGER" "$@"
24 changes: 24 additions & 0 deletions test/autoproj.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as autoproj from '../src/autoproj';
import * as helpers from './helpers';
import * as TypeMoq from 'typemoq'
import * as events from 'events';
import * as url from 'url';

async function assertProcessIsShown(shortname, cmd, promise, subprocess, channel)
{
Expand Down Expand Up @@ -239,6 +240,29 @@ describe("Autoproj helpers tests", function () {
})
})

describe("syncRemote", function() {
let ws : autoproj.Workspace;
beforeEach(async function() {
helpers.mkdir('.autoproj');
helpers.mkfile(MANIFEST_TEST_FILE, ".autoproj", "installation-manifest");
ws = autoproj.Workspace.fromDir(root, false) as autoproj.Workspace;
})
it("returns undefined if there is no sync configuration", function() {
helpers.createConfigFile({});
assert.strictEqual(undefined, ws.syncRemote("test"));
})
it("returns undefined if the sync target does not exist", function() {
helpers.createConfigFile({sync: {}});
assert.strictEqual(undefined, ws.syncRemote("test"));
})
it("returns an existing target's sync URI", function() {
helpers.createConfigFile({sync: {test: {uri: 'ssh://host/'}}});
let uri = ws.syncRemote("test") as url.Url;
assert.equal('host', uri.hostname);
assert.equal('ssh:', uri.protocol);
})
})

describe("envsh", function() {
const processMock = helpers.createProcessMock();
let outputChannel : helpers.OutputChannel;
Expand Down
29 changes: 26 additions & 3 deletions test/debug.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as helpers from './helpers'
import * as path from 'path'
import * as packages from '../src/packages'
import { basename, join as joinPath } from 'path'
import * as url from 'url'

describe("ConfigurationProvider", function() {
let root: string;
Expand All @@ -19,7 +20,7 @@ describe("ConfigurationProvider", function() {
beforeEach(function() {
root = helpers.init();
s = new helpers.TestSetup();
subject = new debug.ConfigurationProvider(s.context);
subject = new debug.ConfigurationProvider(s.context, s.configManager);
let result = s.createAndRegisterWorkspace('test');
ws = result.ws;
})
Expand Down Expand Up @@ -166,7 +167,7 @@ describe("CXXConfigurationProvider", function() {
beforeEach(function() {
root = helpers.init();
s = new helpers.TestSetup();
subject = new debug.CXXConfigurationProvider(s.context);
subject = new debug.CXXConfigurationProvider(s.context, s.configManager);
folder = {
name: "folder",
uri: vscode.Uri.file("/path/to/folder"),
Expand Down Expand Up @@ -203,6 +204,7 @@ describe("CXXConfigurationProvider", function() {
let stub: string;
beforeEach(async function() {
let result = s.createAndRegisterWorkspace('test');
mock = result.mock;
ws = result.ws;
pkg = await s.registerPackage(ws, ['test'], { type: 'Autobuild::CMake' });
folder = {
Expand Down Expand Up @@ -284,6 +286,27 @@ describe("CXXConfigurationProvider", function() {
config, undefined);
assert.equal(resolvedConfig.cwd, "expanded");
})

describe("handling of Sync remotes", function() {
it("leaves plain remote targets alone", async function() {
config.miDebuggerServerAddress = "localhost:4242";
let resolvedConfig = await subject.resolveDebugConfiguration(folder,
config, undefined);
assert.equal("localhost:4242", resolvedConfig.miDebuggerServerAddress);
assert.equal("/path/to/gdb", resolvedConfig.miDebuggerPath);
})
it("resolves sync targets and sets up server startup", async function() {
config.miDebuggerServerAddress = "rock:target:4242";
mock.setup(x => x.syncRemote("target")).
returns(() => new url.URL("ssh://target.local/"))
let resolvedConfig = await subject.resolveDebugConfiguration(folder,
config, undefined);
assert.equal("target.local:4242", resolvedConfig.miDebuggerServerAddress);
assert.equal(ws.autoprojExePath(), resolvedConfig.debugServerPath);
assert.deepEqual('sync exec target -- gdbserver --once :4242 "/path/to/target"',
resolvedConfig.debugServerArgs);
})
})
})
})
})
Expand All @@ -297,7 +320,7 @@ describe("RubyConfigurationProvider", function() {
beforeEach(function() {
root = helpers.init();
s = new helpers.TestSetup();
subject = new debug.RubyConfigurationProvider(s.context);
subject = new debug.RubyConfigurationProvider(s.context, s.configManager);
folder = {
name: "folder",
uri: vscode.Uri.file("/path/to/folder"),
Expand Down
7 changes: 7 additions & 0 deletions test/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ export function registerFile(...path) {
let joinedPath = fullPath(...path);
createdFS.push([joinedPath, 'file']);
}
export function createConfigFile(data: any, ...workspacePath): string {
let joinedPath = fullPath(...workspacePath, '.autoproj', 'config.yml');
mkdir(...workspacePath, '.autoproj')
FS.writeFileSync(joinedPath, YAML.safeDump(data));
createdFS.push([joinedPath, 'file']);
return joinedPath;
}
export function createInstallationManifest(data: any, ...workspacePath): string {
let joinedPath = fullPath(...workspacePath);
joinedPath = Autoproj.installationManifestPath(joinedPath);
Expand Down

0 comments on commit 490dfb0

Please sign in to comment.