tomato·bazeldocs v0 · latest
Docs/Reference/Modules/rules_vscode

rules_vscode

rules_vscode is a Bazel ruleset published to the tomato-bazel registry.

Latest0.0.2
Versions1
CategoryBazel rules
MaintainersMatt Marshall
Registryhttps://registry.tbzl.dev/modules/rules_vscode/
Sourcegithub.com/tomato-bazel/rules_vscode
MODULE.bazelstarlark
bazel_dep(name = "rules_vscode", version = "0.0.2")

View source & releases on GitHub ↗

Bazel-idiomatic, deterministic generation of VSCode artifacts — multi-root .code-workspace files and settings.json — with aspect-driven folder assembly and workspace merging (“single pane of glass”) for org-root Bazel workspaces.

Emission is pure ctx.actions.write of canonical JSON (folders ordered by path, root . first; setting keys sorted) — bit-exact for a given input, so write_source_files diffs stay minimal. The emitted document conforms to a pinned JSON Schema (see //schema).

Install

MODULE.bazel:

bazel_dep(name = "rules_vscode", version = "0.0.1")

Public API — @rules_vscode//vscode:defs.bzl

SymbolPurpose
vscode_workspaceEmit a multi-root .code-workspace; provides VscodeWorkspaceInfo.
vscode_workspace_mergeMerge N workspaces (under path prefixes) into one — the “single pane of glass”.
vscode_settingsEmit a canonical settings.json.
vscode_folder / vscode_folder_aspectDeclare folder contributions assembled from the build graph.

Per-org workspace generator

load("@rules_vscode//vscode:defs.bzl", "vscode_workspace")

vscode_workspace(
    name = "workspace",
    root_label = "fastverk (meta)",
    folders = {
        "repos/rules_uv": "rules_uv",
        "repos/bazel-registry": "bazel-registry",
    },
    settings = {"files.exclude": {"**/bazel-*": True}},
    extensions = ["BazelBuild.vscode-bazel"],
    # `bazel run //:workspace.update` writes the file into the source tree;
    # `bazel test //:workspace.update` checks it is current.
    write_to = "fastverk.code-workspace",
)

Single pane of glass

load("@rules_vscode//vscode:defs.bzl", "vscode_workspace_merge")

vscode_workspace_merge(
    name = "ecosystem",
    workspaces = {
        ":fastverk_ws": "fastverk",   # value = path prefix applied to that
        ":other_ws": "other",         # workspace's folders
    },
    write_to = "ecosystem.code-workspace",
)

Graph-assembled folders

vscode_folder targets (and vscode_folder_aspect on folder_deps) let a workspace gather its folder list from the build graph instead of hand-listing paths. Each folder may carry recommended settings/extensions that merge into the workspace.

Determinism & the pinned schema

  • Folder order is canonical (root . first, then lexicographic by path); duplicates are removed (first wins). Settings’ top-level keys are sorted.
  • //schema/code-workspace.schema.json pins the document structure; a rules_jsonschema codegen + diff_test (bazel run //schema:update) keeps a typed Starlark layer in sync with the schema.

Examples

See examples/ — a per-org workspace, a graph-assembled folder chain, a merged ecosystem workspace, and golden tests.

Usage#

Real usage, taken from the module’s examples/.

examples/BUILD.bazel

load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
load("//vscode:defs.bzl", "vscode_folder", "vscode_settings", "vscode_workspace", "vscode_workspace_merge")

package(default_visibility = ["//visibility:public"])

# A standalone settings.json.
vscode_settings(
    name = "settings",
    out = "settings.json",
    settings = {
        "editor.formatOnSave": True,
        "files.exclude": {
            "**/bazel-*": True,
            "**/target": True,
        },
    },
)

# Folder contributions assembled through the graph (app -> core).
vscode_folder(
    name = "core_folder",
    display_name = "core",
    extensions = ["rust-lang.rust-analyzer"],
    path = "repos/core",
)

vscode_folder(
    name = "app_folder",
    display_name = "app",
    path = "repos/app",
    deps = [":core_folder"],
)

# A per-org workspace: explicit folders + graph-assembled folder_deps.
vscode_workspace(
    name = "fastverk_ws",
    out = "fastverk.code-workspace",
    extensions = ["BazelBuild.vscode-bazel"],
    folder_deps = [":app_folder"],
    folders = {
        "repos/bazel-registry": "bazel-registry",
        "repos/rules_uv": "rules_uv",
    },
    root_label = "fastverk (meta)",
    settings = {"files.exclude": {"**/bazel-*": True}},
    # Demonstrates the generator UX: `bazel run //examples:fastverk_ws.update`
    # writes the file back into the source tree (here, the committed golden),
    # and `bazel test //examples:fastverk_ws.update` checks it is current.
    write_to = "golden/fastverk.code-workspace",
)

vscode_workspace(
    name = "acme_ws",
    out = "acme.code-workspace",
    folders = {
        "lib": "lib",
        "services": "services",
    },
    root_label = "acme",
)

# Demonstrates the `worktrees` attr: a gitignored per-org worktrees root,
# surfaced in the workspace alongside the repo folders (sorts last).
vscode_workspace(
    name = "worktrees_ws",
    out = "worktrees.code-workspace",
    folders = {"repos/app": "app"},
    root_label = "org",
    worktrees = "worktrees",
    write_to = "golden/worktrees.code-workspace",
)

# The "single pane of glass": merge org workspaces under path prefixes.
vscode_workspace_merge(
    name = "ecosystem",
    out = "ecosystem.code-workspace",
    workspaces = {
        ":fastverk_ws": "fastverk",
        ":acme_ws": "acme",
    },
)

# Golden tests — the generated artifacts must match the committed goldens.
diff_test(
    name = "fastverk_ws_golden_test",
    file1 = ":fastverk_ws",
    file2 = "golden/fastverk.code-workspace",
)

diff_test(
    name = "ecosystem_golden_test",
    file1 = ":ecosystem",
    file2 = "golden/ecosystem.code-workspace",
)

diff_test(
    name = "settings_golden_test",
    file1 = ":settings",
    file2 = "golden/settings.json",
)

diff_test(
    name = "worktrees_ws_golden_test",
    file1 = ":worktrees_ws",
    file2 = "golden/worktrees.code-workspace",
)

Conformance#

No gate findings. 17 contested atoms. See how gating works or the full report.

Contested atoms

Third-party modules where this module resolves a different version than others do. Not a violation of anything this module did — it is the actionable form of a registry-level convergence finding, and the sentence a maintainer can act on.

AtomResolved hereElsewhere
apple_support 1.24.2 2.2.0 ×1
aspect_bazel_lib 2.22.5 2.8.1 ×1
bazel_lib 3.0.0 3.2.2 ×17
bazel_skylib 1.8.2 1.9.0 ×2
gawk 5.3.2.bcr.1 5.3.2.bcr.3 ×17
gazelle 0.36.0 0.30.0 ×50.44.0 ×10.51.0 ×3
jq.bzl 0.1.0 0.4.0 ×17
nlohmann_json 3.6.1 3.12.0.bcr.1 ×1
package_metadata 0.0.2 0.0.5 ×3
protobuf 33.4 34.0.bcr.1 ×2
rules_go 0.60.0 0.39.1 ×5
rules_jvm_external 6.7 6.8 ×4
rules_python 1.7.0 2.0.1 ×1
rules_swift 3.1.2 3.6.1 ×1
tar.bzl 0.5.1 0.10.4 ×170.6.0 ×1
upb 0.0.0-20220923-a547704 0.0.0-20230516-61a97ef ×1
yq.bzl 0.1.1 0.3.4 ×17

Dependencies#

rules_vscode in the registry graph — what it depends on (left) and what depends on it (right).

Depends on

platforms1.0.0bazel_skylib1.8.2aspect_bazel_lib2.22.5rules_shell0.6.1devstardoc0.7.2devrules_jsonschema0.3.0dev

Versions#

1 published version, newest first. Each resolves to an immutable, integrity-checked archive.

VersionIntegrity (sha256)Source archive
0.0.2 latest 4VFp98g7NSo7I0KZ… tag archive ↗

Changelog#

All notable changes to rules_vscode. The format is loosely Keep a Changelog — version headers mirror the published bazel-registry entries.

0.0.2

  • vscode_workspace gains a worktrees attr: when set (e.g. worktrees), the generated workspace includes a per-org worktrees folder (sorts last) housing every repo’s git worktrees. The rule only adds the folder entry; the directory is created + gitignored at the org root.

0.0.1

  • Initial public API in @rules_vscode//vscode:defs.bzl:
    • vscode_workspace — emit a deterministic multi-root .code-workspace; provides VscodeWorkspaceInfo. Optional write_to wires the bazel run //:<name>.update write-back + up-to-date check (aspect_bazel_lib write_source_files).
    • vscode_workspace_merge — merge N workspaces under path prefixes into one ecosystem workspace (“single pane of glass”).
    • vscode_settings — emit a canonical settings.json.
    • vscode_folder + vscode_folder_aspect — assemble folders (with their recommended settings/extensions) from the build graph.
  • Canonical JSON emission (folders root-.-first then path-sorted; settings keys sorted) — bit-exact for a given input.
  • //schema/code-workspace.schema.json pins the document structure; a rules_jsonschema Starlark codegen + diff_test gates schema drift.
  • Golden tests in examples/.

← All modules