JetBrains Bazel Plugin

repository·262·Indexed 40 days ago

https://github.com/jetbrains/hirschgarten

Development repository for the JetBrains Bazel plugin, providing comprehensive Bazel integration for IntelliJ IDEA. Features include Starlark support, target execution, and project import capabilities. Includes documentation on .bazelproject view files for configuring target imports, indexing, and sharding to prevent OOM, as well as guides for managing e2e test matrices using ide_starter_e2e_matrix and ide_starter_e2e_host_test.

Tokens
13.6K
Snippets
43
Records
78
Agent score
98%

What's inside JetBrains Bazel Plugin

  1. Overview of the Hirschgarten Project

    262

    Hirschgarten is the development project for the official JetBrains Bazel plugin for IntelliJ IDEA. It provides deep integration for Bazel users, allowing them to manage Bazel-based projects directly within the IDE.

    Key capabilities include:

    • Project Import: Import Bazel projects supporting multiple languages.
    • Execution: Run and debug Bazel targets and tests either through the Bazel toolchain or directly from the IDE.
    • Starlark Support: Highlighting, navigation, and debugging for Starlark code.
    • Project Management: Configure specific project subsets for import to optimize IDE performance.
  2. What is a .bazelproject view file?

    262

    A .bazelproject view file is used to import a specific subset of Bazel targets into the IDE and configure how the project is imported. It is an adaptation of the Bazel Plugin for IntelliJ project view mechanism.

    Format Rules:

    • Uses a Python-like format.
    • Requires 2 spaces for indentation.
    • Supports # for comments.
    • You can share *.bazelproject files between projects or use local copies.

    Composition Logic:

    • List-type sections (e.g., targets, directories) compose/merge.
    • Single-value sections (e.g., bazel_binary) override previous values using a depth-first parse order (the last one encountered wins).
  3. Expression evaluation in Starlark debugging

    262

    You can evaluate expressions during a debug session, but they are subject to the following constraints:

    • Stack Position: Evaluation can only be performed at the top of the execution stack. Bazel does not allow specifying a different stack frame for evaluation.
    • Scope: Evaluation is performed entirely by Bazel. Consequently, only top-level variables and functions are available for use.
    • Error Handling: If an evaluation fails due to the stack position constraint, an error is reported. However, for other types of errors, Bazel returns an empty result without providing specific error details.
  4. Understand Phased Sync for Bazel projects

    262

    Phased sync is an experimental feature that splits the Bazel project synchronization into two distinct stages to improve developer productivity by providing immediate access to code editing.

    1. Query Phase: Runs a Bazel query to determine project structure (targets, sources, and dependencies). This phase is significantly faster (10x-100x) than the aspect phase. While active, you can perform rudimentary highlighting, code completions, and navigation between project sources.
    2. Aspect Phase: Runs Bazel aspects to resolve the full set of dependencies and generated sources. This phase enables full IDE features, such as highlighting dependency-related problems and navigating to dependency sources. It begins automatically once the query phase completes.
  5. Understanding debug session termination

    262

    A debug session can terminate in two ways:

    1. Socket Break (Automatic)

    Commonly occurs when the Bazel process finishes. This triggers a chain reaction:

    • An exception occurs in the StarlarkDebugManager loop.
    • The manager's stop() method is called, terminating the debug task.
    • The StarlarkDebugMessenger is closed.

    2. UI Termination (Manual)

    When you manually stop debugging via the IntelliJ interface:

    • StarlarkDebugProcess.stop() is executed.
    • StarlarkDebugMessenger.close() is called.
    • StarlarkSocketConnector.close() is called, which breaks the socket and triggers the automatic termination sequence.
  6. Understand Starlark Debug limitations

    262

    While Starlark Debug supports standard IDE debug functions (start/pause/stop, step into/over/out), it has the following current limitations:

    • Expression Evaluation: You can only evaluate expressions for top-level values. Variables residing in other scopes may not be visible for evaluation.
    • Value Setting: The ability to change or set variable values during a debug session is not supported.
  7. How Bazel version selection works in tests

    262

    The test matrix uses the USE_BAZEL_VERSION environment variable, which is read natively by Bazelisk inside the launched IDE. This value takes precedence over the fixture's committed .bazelversion.

    • Default behavior: The committed .bazelversion and MODULE.bazel.lock act as the defaults when running tests without a specific matrix selection.
    • Version switching: When a matrix cell selects a different version, Bazel regenerates any stale files in the disposable checkout (using --lockfile_mode=update).
    • Windows isolation: On Windows, nested Bazel invocations use isolated roots (keyed by project root and selected version) to ensure cells do not share server state.
  8. How Starlark debugging connection works

    262

    The debugging process follows these steps:

    1. The BSP server is instructed to build a target in debug mode (note: only the analysis phase can be debugged).
    2. A connection is established to localhost:<port> using Java socket infrastructure.
    3. The port is chosen automatically to avoid collisions and is not stored in the run configuration.

    Note: Bazel does not support debugging between different hosts; the connection must be to localhost.

  9. How Project Sync Hooks work

    262

    To support multiple languages and JetBrains products with varying capabilities, the project uses a three-stage sync process called Project Sync Hooks. This allows the plugin to handle basic information, official BSP (Build Server Protocol) flows, and specialized build-tool-specific flows independently.

    The sync process is split into these stages:

    1. Base Project Sync: Performs essential queries that are almost always required. It fetches all targets via workspace/buildTargets, sources via buildTarget/sources, and resources via buildTarget/resources. The results (such as target IDs) are passed to all subsequent hooks.
    2. Default / BSP Project Syncs: Implements the official BSP flow. This is used for build tools like SBT or for languages with simple requirements (e.g., Python) that do not need custom endpoints.
    3. Additional Project Syncs: Handles specialized, build-tool-specific flows (e.g., Bazel-specific logic) that require custom server endpoints.

    Note on overriding flows: There is an extension point available to disable Default Syncs. This is necessary when a custom build-tool-specific sync provides a more comprehensive or different implementation of the default flow (for example, when a custom endpoint like workspace/directories covers buildTarget/outputPaths and more, or when Java support uses workspace/libraries instead of buildTarget/dependencySources).

  10. Inspecting paused execution and values

    262

    When execution is paused (via a breakpoint or the IntelliJ pause functionality), you can inspect the state through:

    • Threads: A list of threads (typically one) is provided.
    • Execution Stack: Each thread shows its current execution stack.
    • Values: Each stack frame contains a list of values.

    Lazy Loading: Compound values such as lists and dictionaries can be expanded, but their children are computed lazily to optimize performance.

  11. Compare pre-commit_format and pre-commit_check_format

    262

    The two available hooks differ in how they handle formatting violations:

    Featurepre-commit_formatpre-commit_check_format
    Primary ActionAuto-formats filesVerifies formatting
    Bazel Commandbazel run :formatbazel run //tools/format:format.check
    File ModificationRewrites and restages filesDoes not change files
    Commit OutcomeFails only if Bazel returns an errorFails if formatting is non-compliant

    Both hooks use a guard to ensure they only run when staged changes include files under plugins/bazel/.