MCPcopy Index your code
hub / github.com/Calsign/gazelle_rust

github.com/Calsign/gazelle_rust @macro-crate-0.1.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release macro-crate-0.1.0 ↗ · + Follow
155 symbols 322 edges 120 files 4 documented · 3%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

gazelle_rust

A Gazelle language plugin for Rust; automatic dependency management for Rust projects built with Bazel.

References: - Gazelle - rules_rust - Bazel

Setup

example/WORKSPACE shows how to load rules_rust and gazelle_rust together. In a real project, you would need to use http_archive instead of local_repository, for example:

GAZELLE_RUST_COMMIT = "<commit>"
GAZELLE_RUST_SHA256 = "<hash>"

http_archive(
    name = "gazelle_rust",
    sha256 = GAZELLE_RUST_SHA256,
    strip_prefix = "gazelle_rust-{}".format(GAZELLE_RUST_COMMIT),
    url = "https://github.com/Calsign/gazelle_rust/archive/{}.zip".format(GAZELLE_RUST_COMMIT),
)

gazelle_rust doesn't have any releases yet, so please just pick the latest commit on main. To determine the sha256, first set the value to None, then fill in the sha256 that bazel tells you.

gazelle_rust currently requires a patch to rules_rust in order to expose the logic needed to parse crate_universe lockfiles. This is required even if you don't use crate_universe. gazelle_rust provides patches that work both with and without the -p1 flag, and example/WORKSPACE shows how to apply the patch to rules_rust.

The dependencies for gazelle_rust itself are loaded through two repository rule macros, shown in example/WORKSPACE. This includes setting up gazelle, but you may use a different gazelle version by loading the gazelle repo before calling gazelle_rust_dependencies*.

gazelle_rust includes a patch to gazelle which allows for reporting unused crate_universe dependencies. If you do not include the patch, everything else will still work fine but unused crate_universe dependencies will not be reported.

Running gazelle

example/BUILD.bazel shows how to create the gazelle target. With the gazelle target defined, you can run it:

bazel run //:gazelle

This will modify your build files in-place to create and update rust targets for all of the rust files in your project.

gazelle_rust provides a premade gazelle binary, but you can also create your own gazelle_binary target and add @gazelle_rust//rust_language to languages.

Generated targets

example/src/BUILD.bazel shows sample targets generated by gazelle. The following rules are supported:

  • rust_library
  • rust_binary
  • rust_test
  • rust_proc_macro
  • rust_shared_library
  • rust_static_library

When generating targets for new sources (those not already listed in srcs for an existing target), gazelle_rust will infer the rule kind based on information like whether the file has a main and the name of the directory. The full logic is in inferRuleKind in rust_language/generate.go. If you change the rule kind afterward, gazelle_rust will respect the existing rule kind.

By default gazelle_rust will generate one target per source file. You may change the grouping by adding a file to srcs for an existing target, and gazelle will respect that existing grouping.

gazelle_rust does not currently support sources in subdirectories, and will always place targets into build files adjacent to the sources that they correspond to.

Assigning dependencies

gazelle_rust parses each source file and identifies any path that looks like an external crate dependency. For example some_lib::Foobar implies a new dependency on some_lib unless some_lib is already in scope.

This approach is fairly robust. Please see rust_parser/parser.rs for implementation details and the parser tests for the range of cases covered. The only known case that is not handled is paths in macros like println!, which is quite tricky. (Derive macros are handled properly.)

For each dependency, gazelle_rust identifies the crate in the project (or crate universe dependency) providing that crate name. gazelle_rust raises an error if the crate could not be found or more than one crate with that name was found.

This means there is a global namespace of crates within the project. If this poses an issue for you, you can use the gazelle resolve directive to configure which target is selected on a per-directory basis.

Crate universe

The example shows how to handle crate universe dependencies with gazelle_rust. example/WORKSPACE shows how to load crate universe dependencies, please refer to the rules_rust documentation for more information. The example shows the repository rule approach, but gazelle_rust also supports the vendored approach.

example/BUILD.bazel shows how to configure gazelle_rust to resolve crate universe dependencies.

Different configurations of crate universe use either a cargo lockfile (Cargo.lock) or a custom lockfile (Cargo.Bazel.lock), and gazelle_rust supports both. Use the directive gazelle:rust_cargo_lockfile to indicate a cargo lockfile and gazelle:rust_lockfile to indicate a custom lockfile. These options are mutually exclusive.

Additionally, you must tell rules_rust the prefix for all crate universe labels using the gazelle:rust_crates_prefix directive, e.g. @crates//: for a repository rule approach or //3rdparty/crates: for a vendored approach.

Ignoring dependencies

Some situations are too complex for gazelle_rust to handle, such as platform-conditional dependencies. It is possible that fancy support could be added in the future, but for now you must handle this manually by ignoring the dependency in the source file and potentially adding # keep comments in the build file.

To tell gazelle_rust to ignore a dependency, you can add the #[gazelle::ignore] attribute macro to a use item. For example:

// the tokio runtime is not supported in wasm
#[cfg(not(target_arch = "wasm32"))]
#[gazelle::ignore]
use tokio::runtime::Runtime;

Then in the build file:

rust_library(
    name = "maybe_tokio",
    deps = select({
        "@platforms//cpu:wasm32": [],
        "//conditions:default": [
            "//3rdparty/crates:tokio",
        ],
    }),
)

rust_library(
    name = "some_cool_cross_platform_thing",
    deps = [
        ":maybe_tokio",  # keep
    ],
    ...
)

See the macro crate for more information about the ignore macro.

Core symbols most depended-on inside this repo

Name
called by 19
rust_language/lang.go
Log
called by 17
rust_language/utils.go
to_string
called by 9
rust_parser/parser.rs
something
called by 8
rust_parser/test_data/simple.rs
add_import
called by 6
rust_parser/parser.rs
generateCargoRule
called by 5
rust_language/generate.go
insert
called by 5
rust_parser/parser.rs
add_mod
called by 4
rust_parser/parser.rs

Shape

Function 75
Method 62
Class 8
Struct 6
Enum 3
TypeAlias 1

Languages

Rust59%
Go34%
Python7%

Modules by API surface

rust_parser/parser.rs36 symbols
rust_language/lang.go16 symbols
rust_language/generate.go15 symbols
bootstrap_from_cargo.py11 symbols
rust_language/resolve.go8 symbols
rust_language/parser.go7 symbols
rust_parser/main.rs6 symbols
rust_parser/test_data/simple.rs5 symbols
rust_parser/test_data/test_only.rs4 symbols
rust_parser/lockfile_crates.rs4 symbols
rust_language/lockfile_crates.go4 symbols
rust_parser/tests/parse_test.rs3 symbols

For agents

$ claude mcp add gazelle_rust \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact