Skip to content
Open
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
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ this extension does not automatically _fix_ lint warnings during formatting,
but you can opt into this by enabling the **Bazel: Buildifier Fix on Format**
setting.

### Disabling Bazel Queries

If you experience performance issues or want to reduce Bazel server load, you can disable all Bazel queries by setting **Bazel: Enable Queries** to `false`. When disabled, the following features will not work:

- Bazel Targets tree view
- Target completion in quick pick dialogs
- CodeLens actions in BUILD files
- Go-to-definition for Bazel targets
- Symbol provider for BUILD files

This setting is enabled by default to provide the full feature set, but disabling it can significantly improve performance in large workspaces.

### Using a separate output base

By default this extension will use the default output base for running queries. This will cause builds to block queries, potentially causing degraded performance. In Bazel versions since 7.1 it is safe to disable this by changing the `bazel.queriesShareServer` setting to `false`. In earlier versions it can be safely disabled after adding the convenience symlinks to `.bazelignore`, for example:
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@
"default": false,
"markdownDescription": "Whether to add a CodeLens to `BUILD`/`BUILD.bazel` files to provide actions while browsing the file."
},
"bazel.enableQueries": {
"type": "boolean",
"default": true,
"markdownDescription": "Whether to enable Bazel queries. When disabled, all query-dependent features (workspace tree, target completion, code lens, go-to-definition) will be disabled to improve performance and reduce Bazel server load."
},
"bazel.pathsToIgnore": {
"type": "array",
"items": {
Expand Down
13 changes: 12 additions & 1 deletion src/bazel/bazel_quickpick.ts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bazel queries are used in 3 contexts:

  1. In the background, to power codelens and goto definition
  2. Upon request, e.g. if a user ran the "Build Target" command
  3. When explicitly requested via command variables (configured as part of the tasks configuration)

I see how (1) can trigger a lot of background queries and can lead to unresponsiveness. As such, I do see why we would want to disable them.

For (3), I am pretty sure that we want to keep queries enabled, even if queries for (1) are disabled. After all, the user himself configured those exact queries in his own task configuration.

For (2), I am somewhat on the edge. Commands like "Build Target" need to be explicitly triggered by the user. As such, they don't negatively impact the experience by default. I think we might want to keep the Bazel queries for those enabeld, too

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@

import * as vscode from "vscode";

import { getDefaultBazelExecutablePath } from "../extension/configuration";
import {
getDefaultBazelExecutablePath,
areBazelQueriesEnabled,
} from "../extension/configuration";
import { IBazelCommandAdapter, IBazelCommandOptions } from "./bazel_command";
import { BazelQuery } from "./bazel_query";
import { BazelWorkspaceInfo } from "./bazel_workspace_info";
Expand Down Expand Up @@ -97,6 +100,10 @@ export async function queryQuickPickTargets({
query,
workspaceInfo,
}: QuickPickParams): Promise<BazelTargetQuickPick[]> {
if (!areBazelQueriesEnabled()) {
return [];
}

if (workspaceInfo === undefined) {
// Ask the user to pick a workspace, if we don't have one, yet
workspaceInfo = await pickBazelWorkspace();
Expand Down Expand Up @@ -133,6 +140,10 @@ export async function queryQuickPickPackage({
query,
workspaceInfo,
}: QuickPickParams): Promise<BazelTargetQuickPick[]> {
if (!areBazelQueriesEnabled()) {
return [];
}

if (workspaceInfo === undefined) {
// Ask the user to pick a workspace, if we don't have one, yet
workspaceInfo = await pickBazelWorkspace();
Expand Down
14 changes: 12 additions & 2 deletions src/codelens/bazel_build_code_lens_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import * as vscode from "vscode";

import { BazelWorkspaceInfo, QueryLocation } from "../bazel";
import { getTargetsForBuildFile } from "../bazel";
import { getDefaultBazelExecutablePath } from "../extension/configuration";
import {
getDefaultBazelExecutablePath,
areBazelQueriesEnabled,
} from "../extension/configuration";
import { blaze_query } from "../protos";
import { CodeLensCommandAdapter } from "./code_lens_command_adapter";

Expand Down Expand Up @@ -69,7 +72,10 @@ export class BazelBuildCodeLensProvider implements vscode.CodeLensProvider {
);

vscode.workspace.onDidChangeConfiguration((change) => {
if (change.affectsConfiguration("bazel.enableCodeLens")) {
if (
change.affectsConfiguration("bazel.enableCodeLens") ||
change.affectsConfiguration("bazel.enableQueries")
) {
this.onDidChangeCodeLensesEmitter.fire();
}
});
Expand All @@ -91,6 +97,10 @@ export class BazelBuildCodeLensProvider implements vscode.CodeLensProvider {
return [];
}

if (!areBazelQueriesEnabled()) {
return [];
}

if (document.isDirty) {
// Don't show code lenses for dirty BUILD files; we can't reliably
// determine what the build targets in it are until it is saved and we can
Expand Down
9 changes: 8 additions & 1 deletion src/definition/bazel_goto_definition_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import {
} from "vscode";
import { Utils } from "vscode-uri";
import { BazelQuery, BazelWorkspaceInfo, QueryLocation } from "../bazel";
import { getDefaultBazelExecutablePath } from "../extension/configuration";
import {
getDefaultBazelExecutablePath,
areBazelQueriesEnabled,
} from "../extension/configuration";
import { blaze_query } from "../protos";

// LABEL_REGEX matches label strings, e.g. @r//x/y/z:abc
Expand All @@ -32,6 +35,10 @@ export async function targetToUri(
targetText: string,
workingDirectory: Uri,
): Promise<QueryLocation | undefined> {
if (!areBazelQueriesEnabled()) {
return null;
}

const match = LABEL_REGEX.exec(targetText);

const targetName = match[1];
Expand Down
10 changes: 10 additions & 0 deletions src/extension/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,13 @@ export function getDefaultBazelExecutablePath(): string {
}
return bazelExecutable;
}

/**
* Checks if Bazel queries are enabled in the workspace configuration.
*
* @returns True if Bazel queries are enabled (default), false otherwise.
*/
export function areBazelQueriesEnabled(): boolean {
const bazelConfig = vscode.workspace.getConfiguration("bazel");
return bazelConfig.get<boolean>("enableQueries", true);
}
9 changes: 8 additions & 1 deletion src/symbols/bazel_target_symbol_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,21 @@ import { DocumentSymbolProvider } from "vscode";

import { BazelWorkspaceInfo, QueryLocation } from "../bazel";
import { getTargetsForBuildFile } from "../bazel";
import { getDefaultBazelExecutablePath } from "../extension/configuration";
import {
getDefaultBazelExecutablePath,
areBazelQueriesEnabled,
} from "../extension/configuration";
import { blaze_query } from "../protos";

/** Provids Symbols for targets in Bazel BUILD files. */
export class BazelTargetSymbolProvider implements DocumentSymbolProvider {
public async provideDocumentSymbols(
document: vscode.TextDocument,
): Promise<vscode.SymbolInformation[] | vscode.DocumentSymbol[]> {
if (!areBazelQueriesEnabled()) {
return [];
}

const workspaceInfo = BazelWorkspaceInfo.fromDocument(document);
if (workspaceInfo === undefined) {
// Not in a Bazel Workspace.
Expand Down
10 changes: 9 additions & 1 deletion src/workspace-tree/bazel_package_tree_item.ts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

afaict, this will lead to us showing an empty tree in the target list.

Instead, we should hide the target list completely, if bazel queries are disabled

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import {
IBazelCommandAdapter,
IBazelCommandOptions,
} from "../bazel";
import { getDefaultBazelExecutablePath } from "../extension/configuration";
import {
getDefaultBazelExecutablePath,
areBazelQueriesEnabled,
} from "../extension/configuration";
import { blaze_query } from "../protos";
import { BazelTargetTreeItem } from "./bazel_target_tree_item";
import { IBazelTreeItem } from "./bazel_tree_item";
Expand Down Expand Up @@ -56,6 +59,11 @@ export class BazelPackageTreeItem
}

public async getChildren(): Promise<IBazelTreeItem[]> {
// If queries are disabled, just return subpackages
if (!areBazelQueriesEnabled()) {
return this.directSubpackages as IBazelTreeItem[];
}

const queryResult = await new BazelQuery(
getDefaultBazelExecutablePath(),
this.workspaceInfo.bazelWorkspacePath,
Expand Down
9 changes: 8 additions & 1 deletion src/workspace-tree/bazel_workspace_folder_tree_item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@

import * as vscode from "vscode";
import { BazelWorkspaceInfo, BazelQuery } from "../bazel";
import { getDefaultBazelExecutablePath } from "../extension/configuration";
import {
getDefaultBazelExecutablePath,
areBazelQueriesEnabled,
} from "../extension/configuration";
import { blaze_query } from "../protos";
import { BazelPackageTreeItem } from "./bazel_package_tree_item";
import { BazelTargetTreeItem } from "./bazel_target_tree_item";
Expand Down Expand Up @@ -150,6 +153,10 @@ export class BazelWorkspaceFolderTreeItem implements IBazelTreeItem {
* Returns a promise for an array of tree items representing build items.
*/
private async getDirectoryItems(): Promise<IBazelTreeItem[]> {
if (!areBazelQueriesEnabled()) {
return Promise.resolve([] as IBazelTreeItem[]);
}

// Retrieve the list of all packages underneath the current workspace
// folder. Note that if the workspace folder is not the root of a Bazel
// workspace but is instead a folder underneath it, we query for *only* the
Expand Down