From 2dccb7b86861d008666fd2958fff951ac53efe89 Mon Sep 17 00:00:00 2001 From: Sylvain Joyeux Date: Mon, 21 May 2018 16:25:58 -0300 Subject: [PATCH] improve "Add Package To Workspace" This adds the packages by name (thus having drivers/orogen/iodrivers_base instead of plain iodrivers_base), and keep the package list sorted. --- src/autoproj.ts | 2 ++ src/commands.ts | 37 +++++++++++++++++++++++++++++++------ test/commands.test.ts | 26 +++++++++++++++++++++++--- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/autoproj.ts b/src/autoproj.ts index 2be012f..5b255c5 100644 --- a/src/autoproj.ts +++ b/src/autoproj.ts @@ -120,7 +120,9 @@ export class Workspace return new Workspace(root, loadInfo, outputChannel); } + // The workspace name name: string; + // The workspace root directory readonly root: string; private _info: Promise; private _infoUpdatedEvent : vscode.EventEmitter; diff --git a/src/commands.ts b/src/commands.ts index 4d2d986..c101f48 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1,4 +1,4 @@ -import { basename, relative, dirname } from 'path'; +import { basename, relative, dirname, join as pathjoin } from 'path'; import * as context from './context'; import * as packages from './packages'; import * as wrappers from './wrappers'; @@ -12,6 +12,16 @@ function assertWorkspaceNotEmpty(vscode: wrappers.VSCode) throw new Error("Current workspace is empty"); } +function findInsertIndex(array, predicate) { + for (let i = 0; i < array.length; ++i) { + let element = array[i]; + if (predicate(element)) { + return i + 1; + } + } + return 0 +} + export class Commands { private readonly _context: context.Context; @@ -152,17 +162,25 @@ export class Commands { let choices: { label, description, pkg }[] = []; let fsPathsObj = {}; - const wsInfos: Promise[] = []; + const wsInfos: [autoproj.Workspace, Promise][] = []; - this._context.workspaces.forEachWorkspace((ws) => wsInfos.push(ws.info())); + this._context.workspaces.forEachWorkspace((ws) => wsInfos.push([ws, ws.info()])); if (this._vscode.workspaceFolders) { for (const folder of this._vscode.workspaceFolders) { fsPathsObj[folder.uri.fsPath] = true; } } - for (const wsInfoP of wsInfos) { + for (const [ws, wsInfoP] of wsInfos) { try { const wsInfo = await wsInfoP; + if (!fsPathsObj.hasOwnProperty(ws.root)) { + let name = `autoproj` + choices.push({ + label: name, + description: `${ws.name} Build Configuration`, + pkg: { name: 'autoproj', srcdir: pathjoin(ws.root, 'autoproj') } + }); + } for (const aPkg of wsInfo.packages) { if (!fsPathsObj.hasOwnProperty(aPkg[1].srcdir)) { choices.push({ @@ -182,6 +200,7 @@ export class Commands a.pkg.name < b.pkg.name ? -1 : a.pkg.name > b.pkg.name ? 1 : 0); return choices; } + async addPackageToWorkspace() { const tokenSource = new vscode.CancellationTokenSource(); @@ -199,10 +218,16 @@ export class Commands tokenSource.dispose(); if (selectedOption) { - const folder = { uri: vscode.Uri.file(selectedOption.pkg.srcdir) }; + const name = selectedOption.pkg.name; const wsFolders = this._vscode.workspaceFolders; - const start = wsFolders ? wsFolders.length : 0; + let start = 0; + if (wsFolders) { + start = findInsertIndex(wsFolders, ((f) => f.name < name)) + } + const folder = { + name: name, + uri: vscode.Uri.file(selectedOption.pkg.srcdir) }; if (!this._vscode.updateWorkspaceFolders(start, null, folder)) { this._vscode.showErrorMessage( `Could not add folder: ${selectedOption.pkg.srcdir}`); diff --git a/test/commands.test.ts b/test/commands.test.ts index 4b4b4f2..cd8f3a0 100644 --- a/test/commands.test.ts +++ b/test/commands.test.ts @@ -443,9 +443,10 @@ describe("Commands", function () { await subject.addPackageToWorkspace(); mockWrapper.verify(x => x.updateWorkspaceFolders(1, null, - { uri: vscode.Uri.file('/path/to/two') }), TypeMoq.Times.once()); + { name: 'two', uri: vscode.Uri.file('/path/to/two') }), + TypeMoq.Times.once()); }) - it("adds the selected package to the begining of the workspace", async function () { + it("handles an empty workspace", async function () { const promise = Promise.resolve(choices); mockWrapper.setup(x => x.workspaceFolders).returns(() => undefined); mockSubject.setup(x => x.packagePickerChoices()). @@ -455,7 +456,26 @@ describe("Commands", function () { await subject.addPackageToWorkspace(); mockWrapper.verify(x => x.updateWorkspaceFolders(0, null, - { uri: vscode.Uri.file('/path/to/two') }), TypeMoq.Times.once()); + { name: 'two', uri: vscode.Uri.file('/path/to/two') }), + TypeMoq.Times.once()); + }) + it("keeps the folder list sorted", async function () { + const folder: vscode.WorkspaceFolder = { + uri: vscode.Uri.file('/path/to/two'), + name: 'two', + index: 0 + } + const promise = Promise.resolve(choices); + mockWrapper.setup(x => x.workspaceFolders).returns(() => [folder]); + mockSubject.setup(x => x.packagePickerChoices()). + returns(() => promise); + mockWrapper.setup(x => x.showQuickPick(promise, + options, TypeMoq.It.isAny())).returns(() => Promise.resolve(choices[0])); + await subject.addPackageToWorkspace(); + + mockWrapper.verify(x => x.updateWorkspaceFolders(0, null, + { name: 'one', uri: vscode.Uri.file('/path/to/one') }), + TypeMoq.Times.once()); }) it("shows an error if folder could not be added", async function () { const promise = Promise.resolve(choices);