Skip to content
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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ The extension is still under active development, but initial development release
3. View the "Testing" panel, which will show progress of the load, and show available test targets once the load is complete.

### Adjusting project scope
By default, the generated project view includes a placeholder target pattern for manual editing. If `bazelbsp.projectViewScopeDirectoryMinDepth` is configured and VS Code is opened to a workspace folder deep enough under the repository root, the generated project view is scoped to that folder. Otherwise, adjust the project view before syncing:

1. Click on the top level test case to open the .bazelproject that is in use.
2. Adjust the "targets" entry to include desired targets.
2. Adjust the `directories` or `targets` entries to include the desired scope.
3. Click the refresh (circular arrow) icon at the top of the "testing" panel to re-sync available targets.

### Syncing changes to targets
Expand Down
10 changes: 5 additions & 5 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ As you interact with the VS Code UI, the client sends requests to this server ov
1. Launch a workspace that contains .py or .java files, which will trigger extension activation.
2. Accept the prompt to install the build server in the repo
3. Go to the "Testing" ![image](https://github.com/uber/vscode-bazel-bsp/assets/92764374/536205bd-6908-4184-9620-292aa2dfe7f6) panel in VS Code
4. Adjust the project scope. See "Adjusting Project Scope" section below.
5. Let the sync process complete. See "Sync Process" section below.
4. Let the sync process complete. See "Sync Process" section below.

### Adjusting Project Scope
By default, the generated project view includes a placeholder target pattern for manual editing. If `bazelbsp.projectViewScopeDirectoryMinDepth` is configured and VS Code is opened to a workspace folder deep enough under the repository root, the generated project view is scoped to that folder. Otherwise, adjust the project view before syncing:

1. Open Project View file: click on the file icon next to the "Bazel Test Targets" root test item
![image](https://github.com/uber/vscode-bazel-bsp/assets/92764374/795baab9-ec42-4b7d-9b1a-2e4033731b64)
2. Adjust Targets: In the .bazelproject file that launches, specify one or more target patterns to be included in the sync scope
2. Adjust Scope: In the .bazelproject file that launches, specify one or more directories or target patterns to be included in the sync scope
3. Click the "Refresh Tests" Button: Wait for the sync process to complete.

![image](https://github.com/uber/vscode-bazel-bsp/assets/92764374/bdbf80ad-485f-464b-b728-cdd86c42f0e5)
Expand Down Expand Up @@ -103,6 +104,7 @@ To run with coverage, use the "Run with Coverage" option appearing next to the r
### Key Settings
- `bazelBinaryPath`: If you have a specific Bazel binary to be used, set it here. This will only be used when generating a new .bazelproject file to set the bazel_binary field.
- `bazelProjectFilePath`: If you already have an existing project view file that you would prefer to use, point this setting to that location instead. Be sure to reinstall the BSP server (Cmd+Shift+P → Install BSP Server) and reload the window to begin indexing based on the updated file.
- `projectViewScopeDirectoryMinDepth`: If set, generated project views use the opened workspace folder as `directories` scope only when that folder is at least this many path segments under the repository root. Leave unset to generate the manual placeholder target instead.
- `serverInstallMode`: Can be set to 'Auto' to install automatically in a new repo.
- `serverVersion`: Determines which version of Bazel BSP will be installed.

Expand All @@ -121,5 +123,3 @@ To run with coverage, use the "Run with Coverage" option appearing next to the r
![image](https://github.com/uber/vscode-bazel-bsp/assets/92764374/d9c376b8-74e8-4981-a400-ae2fb70ec2ae)

- If a test is located under a different root node, or none, it may be coming a different extension.


9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@
],
"description": "Installation behavior for the build server."
},
"bazelbsp.projectViewScopeDirectoryMinDepth": {
"type": [
"number",
"null"
],
"default": null,
"minimum": 1,
"description": "Minimum number of workspace path segments under the repository root required to generate a project view scope from the opened workspace folder. Leave unset to use the manual placeholder target."
},
"bazelbsp.autoExpandTarget": {
"type": "boolean",
"default": true,
Expand Down
56 changes: 50 additions & 6 deletions src/server/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface InstallConfig {
bazelProjectFilePath: string
serverVersion: string
bazelBinaryPath: string
projectViewScopeDirectory?: string
}

export class BazelBSPInstaller {
Expand Down Expand Up @@ -86,7 +87,7 @@ export class BazelBSPInstaller {
return false
}

const installConfig = await this.getInstallConfig()
const installConfig = await this.getInstallConfig(root)
if (!installConfig) {
this.outputChannel.appendLine(
'Installation interrupted: failed to get settings.'
Expand Down Expand Up @@ -184,12 +185,21 @@ export class BazelBSPInstaller {
// Set Bazel project details to be used if a project file is not already present.
['--project-view-file', config.bazelProjectFilePath],
['--bazel-binary', bazelPath],
['--targets', '//your/targets/here/...'],
])
const installFlagSwitches: string[] = []
if (config.projectViewScopeDirectory) {
installFlags.set('--directories', config.projectViewScopeDirectory)
installFlagSwitches.push('--derive-targets-from-directories')
} else {
installFlags.set('--targets', '//your/targets/here/...')
}
Comment thread
harunaOseni marked this conversation as resolved.

const flagsString = Array.from(installFlags.entries())
.map(([key, value]) => `${key} "${value}"`)
.join(' ')
const flagsString = [
...Array.from(installFlags.entries()).map(
([key, value]) => `${key} "${value}"`
),
...installFlagSwitches,
].join(' ')
const additionalInstallFlags = getExtensionSetting(
SettingName.ADDITIONAL_INSTALL_FLAGS
)
Expand Down Expand Up @@ -226,7 +236,7 @@ export class BazelBSPInstaller {
})
}

private async getInstallConfig(): Promise<InstallConfig | null> {
private async getInstallConfig(root: string): Promise<InstallConfig | null> {
const settingError = (setting: SettingName) => {
this.outputChannel.appendLine(
`Install interrupted. Please check the ${setting} setting to ensure a valid value.`
Expand Down Expand Up @@ -268,7 +278,41 @@ export class BazelBSPInstaller {
bazelProjectFilePath: projectFilePath,
serverVersion: bazelBspVersion,
bazelBinaryPath: bazelBinaryPath,
projectViewScopeDirectory: this.getProjectViewScopeDirectory(
root,
getExtensionSetting(SettingName.PROJECT_VIEW_SCOPE_DIRECTORY_MIN_DEPTH)
),
}
}

private getProjectViewScopeDirectory(
root: string,
minDepth: number | null | undefined
): string | undefined {
if (minDepth === undefined || minDepth === null || minDepth < 1) {
return undefined
}

const workspaceRoot = Utils.getWorkspaceRoot()
if (!workspaceRoot) {
return undefined
}

const relativePath = path.relative(root, workspaceRoot.fsPath)
if (
relativePath === '' ||
relativePath.startsWith('..') ||
path.isAbsolute(relativePath)
) {
return undefined
}

const pathSegments = relativePath.split(path.sep).filter(Boolean)
Comment thread
mnoah1 marked this conversation as resolved.
if (pathSegments.length < minDepth) {
return undefined
}

return pathSegments.join('/')
}

/**
Expand Down
79 changes: 79 additions & 0 deletions src/test/suite/install.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ suite('BSP Installer', () => {
isGzipped: boolean
javaVersion: string
additionalInstallFlags?: string[]
projectViewScopeDirectoryMinDepth?: number | null
}

const setupInstallTest = (config: InstallTestConfig) => {
Expand All @@ -54,6 +55,8 @@ suite('BSP Installer', () => {
.returns('Prompt')
.withArgs(settings.SettingName.ADDITIONAL_INSTALL_FLAGS)
.returns(config.additionalInstallFlags || [])
.withArgs(settings.SettingName.PROJECT_VIEW_SCOPE_DIRECTORY_MIN_DEPTH)
.returns(config.projectViewScopeDirectoryMinDepth ?? null)

sandbox.stub(fs, 'readFile').resolves(
`#if( $pythonEnabled == "true" && $bazel8OrAbove == "true" )
Expand Down Expand Up @@ -164,6 +167,13 @@ load("//aspects:utils/utils.bzl", "create_struct", "file_location", "to_file_loc
assert.ok(spawnCall.args[0].includes(coursierPath))
assert.ok(spawnCall.args[0].includes(`--jvm ${config.javaVersion}`))
assert.ok(spawnCall.args[0].includes('org.virtuslab:bazel-bsp:2.0.0'))
assert.ok(!spawnCall.args[0].includes('--directories'))
assert.ok(
!spawnCall.args[0].includes('--derive-targets-from-directories')
)
assert.ok(
spawnCall.args[0].includes('--targets "//your/targets/here/..."')
)
assert.deepStrictEqual(spawnCall.args[1], {
cwd: '/repo/root',
shell: true,
Expand All @@ -172,6 +182,75 @@ load("//aspects:utils/utils.bzl", "create_struct", "file_location", "to_file_loc
})
})

test('uses workspace folder as generated project directory when min depth is configured', async () => {
setupInstallTest({
...testConfigs.macArm64,
projectViewScopeDirectoryMinDepth: 2,
})
sandbox
.stub(Utils, 'getWorkspaceRoot')
.returns(vscode.Uri.file('/repo/root/packages/service'))

await bazelBSPInstaller.install()

assert.equal(spawnStub.callCount, 1)
const commandString = spawnStub.getCalls()[0].args[0]
assert.ok(commandString.includes('--directories "packages/service"'))
assert.ok(commandString.includes('--derive-targets-from-directories'))
assert.ok(!commandString.includes('--targets'))
})

test('does not derive targets when min depth is unset', async () => {
setupInstallTest(testConfigs.macArm64)
sandbox
.stub(Utils, 'getWorkspaceRoot')
.returns(vscode.Uri.file('/repo/root/packages/service'))

await bazelBSPInstaller.install()

assert.equal(spawnStub.callCount, 1)
const commandString = spawnStub.getCalls()[0].args[0]
assert.ok(!commandString.includes('--directories "packages/service"'))
assert.ok(!commandString.includes('--derive-targets-from-directories'))
assert.ok(commandString.includes('--targets "//your/targets/here/..."'))
})

test('does not derive targets from repo root workspace', async () => {
setupInstallTest({
...testConfigs.macArm64,
projectViewScopeDirectoryMinDepth: 2,
})
sandbox
.stub(Utils, 'getWorkspaceRoot')
.returns(vscode.Uri.file('/repo/root'))

await bazelBSPInstaller.install()

assert.equal(spawnStub.callCount, 1)
const commandString = spawnStub.getCalls()[0].args[0]
assert.ok(!commandString.includes('--directories "."'))
assert.ok(!commandString.includes('--derive-targets-from-directories'))
assert.ok(commandString.includes('--targets "//your/targets/here/..."'))
})

test('does not derive targets from top-level workspace directory', async () => {
setupInstallTest({
...testConfigs.macArm64,
projectViewScopeDirectoryMinDepth: 2,
})
sandbox
.stub(Utils, 'getWorkspaceRoot')
.returns(vscode.Uri.file('/repo/root/src'))

await bazelBSPInstaller.install()

assert.equal(spawnStub.callCount, 1)
const commandString = spawnStub.getCalls()[0].args[0]
assert.ok(!commandString.includes('--directories "src"'))
assert.ok(!commandString.includes('--derive-targets-from-directories'))
assert.ok(commandString.includes('--targets "//your/targets/here/..."'))
})

test('failed coursier download', async () => {
sandbox
.stub(vscode.window, 'showErrorMessage')
Expand Down
2 changes: 2 additions & 0 deletions src/utils/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export enum SettingName {
BSP_SERVER_VERSION = 'serverVersion',
BAZEL_BINARY_PATH = 'bazelBinaryPath',
SERVER_INSTALL_MODE = 'serverInstallMode',
PROJECT_VIEW_SCOPE_DIRECTORY_MIN_DEPTH = 'projectViewScopeDirectoryMinDepth',
AUTO_EXPAND_TARGET = 'autoExpandTarget',
DEBUG_ENABLED = 'debug.enabled',
DEBUG_BAZEL_FLAGS = 'debug.bazelFlags',
Expand All @@ -23,6 +24,7 @@ export interface SettingTypes {
[SettingName.BSP_SERVER_VERSION]: string
[SettingName.BAZEL_BINARY_PATH]: string
[SettingName.SERVER_INSTALL_MODE]: string
[SettingName.PROJECT_VIEW_SCOPE_DIRECTORY_MIN_DEPTH]: number | null
[SettingName.AUTO_EXPAND_TARGET]: boolean
[SettingName.DEBUG_ENABLED]: boolean
[SettingName.DEBUG_BAZEL_FLAGS]: string[]
Expand Down