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

Devtool support #29

Merged
merged 9 commits into from
Dec 18, 2023
91 changes: 78 additions & 13 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,29 @@
"command": "bitbake.parse-recipes",
"title": "BitBake: Parse all recipes",
"description": "This command runs bitbake in parse-only mode."
},
{
"command": "bitbake.devtool-modify",
"title": "BitBake: Devtool: Modify recipe",
"description": "Open a new devtool workspace to modify a recipe's sources."
},
{
"command": "bitbake.devtool-open-workspace",
"title": "BitBake: Devtool: Open Workspace",
"description": "Open a devtool sources workspace in a new VSCode window.",
"icon": "$(file-symlink-directory)"
},
{
"command": "bitbake.devtool-reset",
"title": "BitBake: Devtool: Reset",
"description": "Remove a devtool workspace.",
"icon": "$(trash)"
},
{
"command": "bitbake.devtool-update",
"title": "BitBake: Devtool: Update recipe",
"description": "Update a recipe from a devtool workspace's modifications.",
"icon": "$(save-as)"
}
],
"viewsContainers": {
Expand All @@ -300,8 +323,16 @@
"bitbakeView": [
{
"id": "bitbakeRecipes",
"name": "Recipes",
"contextualTitle": "Recipes Explorer",
"name": "Recipes Explorer",
"contextualTitle": "Recipes explorer",
"icon": "$(library)",
"when": "bitbake.active"
},
{
"id": "devtoolWorkspaces",
"name": "Devtool Workspaces",
"contextualTitle": "Devtool workspaces",
"icon": "$(symbol-property)",
"when": "bitbake.active"
}
]
Expand All @@ -316,15 +347,19 @@
"bitbake/main": [
{
"command": "bitbake.clean-recipe",
"group": "bitbake_recipe@1"
"group": "0@bitbake_recipe@1"
},
{
"command": "bitbake.build-recipe",
"group": "bitbake_recipe@0"
"group": "0@bitbake_recipe@0"
},
{
"command": "bitbake.run-task",
"group": "bitbake_recipe@2"
"group": "0@bitbake_recipe@2"
},
{
"command": "bitbake.devtool-modify",
"group": "1@bitbake_devtool@0"
}
],
"explorer/context": [
Expand Down Expand Up @@ -358,28 +393,28 @@
"view/item/context": [
{
"command": "bitbake.clean-recipe",
"group": "bitbake_recipe@1",
"when": "view == bitbakeRecipeCtx"
"group": "0@bitbake_recipe@1",
"when": "viewItem == bitbakeRecipeCtx || viewItem == devtoolWorskpaceCtx"
},
{
"command": "bitbake.build-recipe",
"group": "bitbake_recipe@0",
"when": "viewItem == bitbakeRecipeCtx"
"group": "0@bitbake_recipe@0",
"when": "viewItem == bitbakeRecipeCtx || viewItem == devtoolWorskpaceCtx"
},
{
"command": "bitbake.run-task",
"group": "bitbake_recipe@2",
"when": "viewItem == bitbakeRecipeCtx"
"group": "0@bitbake_recipe@2",
"when": "viewItem == bitbakeRecipeCtx || viewItem == devtoolWorskpaceCtx"
},
{
"command": "bitbake.drop-recipe",
"group": "bitbake_recipe@3",
"group": "0@bitbake_recipe@3",
"when": "viewItem == bitbakeRecipeCtx"
},
{
"command": "bitbake.build-recipe",
"group": "inline@0",
"when": "viewItem == bitbakeRecipeCtx"
"when": "viewItem == bitbakeRecipeCtx || viewItem == devtoolWorskpaceCtx"
},
{
"command": "bitbake.clean-recipe",
Expand All @@ -390,6 +425,36 @@
"command": "bitbake.drop-recipe",
"group": "inline@2",
"when": "viewItem == bitbakeRecipeCtx"
},
{
"command": "bitbake.devtool-modify",
"group": "1@bitbake_devtool@0",
"when": "viewItem == bitbakeRecipeCtx"
},
{
"command": "bitbake.devtool-open-workspace",
"group": "1@bitbake_devtool@1",
"when": "viewItem == devtoolWorskpaceCtx"
},
{
"command": "bitbake.devtool-reset",
"group": "1@bitbake_devtool@3",
"when": "viewItem == devtoolWorskpaceCtx"
},
{
"command": "bitbake.devtool-update",
"group": "1@bitbake_devtool@2",
"when": "viewItem == devtoolWorskpaceCtx"
},
{
"command": "bitbake.devtool-reset",
"group": "inline@5",
"when": "viewItem == devtoolWorskpaceCtx"
},
{
"command": "bitbake.devtool-update",
"group": "inline@4",
"when": "viewItem == devtoolWorskpaceCtx"
}
]
}
Expand Down
38 changes: 35 additions & 3 deletions client/src/__tests__/unit-tests/driver/scanner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
* ------------------------------------------------------------------------------------------ */

import path from 'path'
import { bitBakeProjectScanner } from '../../../driver/BitBakeProjectScanner'
import { BitBakeProjectScanner } from '../../../driver/BitBakeProjectScanner'
import { BitbakeDriver } from '../../../driver/BitbakeDriver'

let bitBakeProjectScanner: BitBakeProjectScanner

const pathToBitbakeFolder = path.join(__dirname, '../../../../../integration-tests/project-folder/sources/poky/bitbake')
const pathToBuildFolder = path.join(__dirname, '../../../../../integration-tests/project-folder/build')
const pathToEnvScript = path.join(__dirname, '../../../../../integration-tests/project-folder/sources/poky/oe-init-build-env')
Expand All @@ -25,11 +27,27 @@ describe('BitBakeProjectScanner', () => {
},
workspaceFolder
)
bitBakeProjectScanner.setDriver(bitbakeDriver)
bitBakeProjectScanner = new BitBakeProjectScanner(bitbakeDriver)
bitBakeProjectScanner.onChange.on(('scanReady'), () => {
DoneCallback()
})
void bitBakeProjectScanner.rescanProject()
bitBakeProjectScanner.bitbakeDriver.spawnBitbakeProcess('devtool modify busybox').then((child) => {
child.on('close', () => {
void bitBakeProjectScanner.rescanProject()
})
}, (error) => {
throw error
})
}, 300000)

afterAll((done) => {
bitBakeProjectScanner.bitbakeDriver.spawnBitbakeProcess('devtool reset busybox').then((child) => {
child.on('close', () => {
done()
})
}, (error) => {
throw error
})
}, 300000)

it('can get a list of layers', async () => {
Expand Down Expand Up @@ -84,4 +102,18 @@ describe('BitBakeProjectScanner', () => {
])
)
})

it('can get a list of devtool workspaces', async () => {
const devtoolWorkspaces = bitBakeProjectScanner.scanResult._workspaces
expect(devtoolWorkspaces.length).toBeGreaterThan(0)
expect(devtoolWorkspaces).toEqual(
expect.arrayContaining([
expect.objectContaining(
{
name: 'busybox'
}
)
])
)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
import * as vscode from 'vscode'
import { type BitbakeRecipeTreeItem, BitbakeRecipesView } from '../../../ui/BitbakeRecipesView'
import { BitbakeWorkspace } from '../../../ui/BitbakeWorkspace'
import { bitBakeProjectScanner } from '../../../driver/BitBakeProjectScanner'
import { BitBakeProjectScanner } from '../../../driver/BitBakeProjectScanner'
import { type BitbakeScanResult } from '../../../lib/src/types/BitbakeScanResult'
import { BitbakeDriver } from '../../../driver/BitbakeDriver'

jest.mock('vscode')

describe('BitbakeDriver Recipes View', () => {
it('should list recipes', (done) => {
const bitbakeWorkspace = new BitbakeWorkspace()
const bitBakeProjectScanner = new BitBakeProjectScanner(new BitbakeDriver())
bitbakeWorkspace.addActiveRecipe('base-files')

const contextMock: vscode.ExtensionContext = {
Expand Down Expand Up @@ -47,7 +49,8 @@ describe('BitbakeDriver Recipes View', () => {
_includes: [],
_layers: [],
_classes: [],
_overrides: []
_overrides: [],
_workspaces: []
}

vscode.window.registerTreeDataProvider = jest.fn().mockImplementation(
Expand Down
53 changes: 53 additions & 0 deletions client/src/__tests__/unit-tests/ui/devtool-workspaces-view.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) 2023 Savoir-faire Linux. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

import * as vscode from 'vscode'
import { type DevtoolWorkspaceTreeItem, DevtoolWorkspacesView } from '../../../ui/DevtoolWorkspacesView'
import { BitBakeProjectScanner } from '../../../driver/BitBakeProjectScanner'
import { type BitbakeScanResult } from '../../../lib/src/types/BitbakeScanResult'
import { BitbakeDriver } from '../../../driver/BitbakeDriver'

jest.mock('vscode')

describe('Devtool Worskapces View', () => {
it('should list devtool workspaces', (done) => {
const contextMock: vscode.ExtensionContext = {
subscriptions: {
push: jest.fn()
}
} as any

const scanResult: BitbakeScanResult = {
_recipes: [],
_includes: [],
_layers: [],
_classes: [],
_overrides: [],
_workspaces: [
{
name: 'dropbear',
path: '/build/workspace/dropbear'
}
]
}

const bitBakeProjectScanner = new BitBakeProjectScanner(new BitbakeDriver())

vscode.window.registerTreeDataProvider = jest.fn().mockImplementation(
async (viewId: string, treeDataProvider: vscode.TreeDataProvider<DevtoolWorkspaceTreeItem>): Promise<void> => {
const rootTreeItem = await treeDataProvider.getChildren(undefined)
expect(rootTreeItem).toBeDefined()
expect(rootTreeItem?.length).toStrictEqual(2)
const recipeItem = (rootTreeItem as DevtoolWorkspaceTreeItem[])[0]
expect(recipeItem.workspace.name).toStrictEqual('dropbear')

done()
})

const devtoolWorkspacesView = new DevtoolWorkspacesView(bitBakeProjectScanner)
bitBakeProjectScanner.onChange.emit('scanReady', scanResult)
devtoolWorkspacesView.registerView(contextMock)
})
})
28 changes: 22 additions & 6 deletions client/src/driver/BitBakeProjectScanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { logger } from '../lib/src/utils/OutputLogger'

import type {
BitbakeScanResult,
DevtoolWorkspaceInfo,
ElementInfo,
LayerInfo,
PathInfo
Expand All @@ -38,16 +39,16 @@ export class BitBakeProjectScanner {
private readonly _recipesFileExtension: string = 'bb'
onChange: EventEmitter = new EventEmitter()

private readonly _bitbakeScanResult: BitbakeScanResult = { _classes: [], _includes: [], _layers: [], _overrides: [], _recipes: [] }
private readonly _bitbakeScanResult: BitbakeScanResult = { _classes: [], _includes: [], _layers: [], _overrides: [], _recipes: [], _workspaces: [] }
private _shouldDeepExamine: boolean = false
private _bitbakeDriver: BitbakeDriver | undefined
private readonly _bitbakeDriver: BitbakeDriver
private _languageClient: LanguageClient | undefined

/// These attributes map bind mounts of the workDir to the host system if a docker container commandWrapper is used (-v).
private containerMountPoint: string | undefined
private hostMountPoint: string | undefined

setDriver (bitbakeDriver: BitbakeDriver): void {
constructor (bitbakeDriver: BitbakeDriver) {
this._bitbakeDriver = bitbakeDriver
}

Expand All @@ -72,7 +73,7 @@ export class BitBakeProjectScanner {
this._shouldDeepExamine = shouldDeepExamine
}

get bitbakeDriver (): BitbakeDriver | undefined {
get bitbakeDriver (): BitbakeDriver {
return this._bitbakeDriver
}

Expand All @@ -91,6 +92,7 @@ export class BitBakeProjectScanner {
await this.scanForRecipes()
await this.scanRecipesAppends()
await this.scanOverrides()
await this.scanDevtoolWorkspaces()
this.parseAllRecipes()

logger.info('scan ready')
Expand Down Expand Up @@ -165,6 +167,7 @@ export class BitBakeProjectScanner {
logger.info(`Inc-Files: ${this._bitbakeScanResult._includes.length}`)
logger.info(`bbclass: ${this._bitbakeScanResult._classes.length}`)
logger.info(`overrides: ${this._bitbakeScanResult._overrides.length}`)
logger.info(`Devtool-workspaces: ${this._bitbakeScanResult._workspaces.length}`)
}

private scanForClasses (): void {
Expand Down Expand Up @@ -315,6 +318,21 @@ export class BitBakeProjectScanner {
this._bitbakeScanResult._overrides = output.match(outerReg)?.[1].split(':') ?? []
}

private async scanDevtoolWorkspaces (): Promise<void> {
this._bitbakeScanResult._workspaces = new Array < DevtoolWorkspaceInfo >()
const commandResult = await this.executeBitBakeCommand('devtool status')
if (commandResult.status !== 0) {
logger.error(`Failed to scan devtool workspaces: ${commandResult.stderr.toString()}`)
return
}
const output = commandResult.output.toString()
const regex = /^([^\s]+):\s([^\s]+)$/gm
let match
while ((match = regex.exec(output)) !== null) {
this._bitbakeScanResult._workspaces.push({ name: match[1], path: match[2] })
}
}

parseAllRecipes (): void {
void vscode.commands.executeCommand('bitbake.parse-recipes')
}
Expand Down Expand Up @@ -406,8 +424,6 @@ export class BitBakeProjectScanner {
}
}

export const bitBakeProjectScanner = new BitBakeProjectScanner()

function bbappendVersionMatches (bbappendVersion: string | undefined, recipeVersion: string | undefined): boolean {
if (bbappendVersion === undefined) {
return true
Expand Down
Loading
Loading