Skip to content

Support module discovery for lib.rs crate roots#25

Open
isaacparker0 wants to merge 3 commits intoCalsign:mainfrom
isaacparker0:main
Open

Support module discovery for lib.rs crate roots#25
isaacparker0 wants to merge 3 commits intoCalsign:mainfrom
isaacparker0:main

Conversation

@isaacparker0
Copy link
Contributor

@isaacparker0 isaacparker0 commented Dec 24, 2025

In "pure bazel" mode, when Gazelle encounters a lib.rs file, it should follow mod declarations to discover all module files and includes them in a single rust_library target. Also remove deleted source files from targets.

EDIT: After reading the discussion in #13 (Gazelle creating broken BUILD files in subdirectories hadn't occurred to me because I typically use update_only generation mode), I took a stab at handling claimed files in subdirectories. The approach is O(depth), and handles both traditional subdir/mod.rs style and Rust 2018+ adjacent subdir.rs style, all with generation test coverage. @Calsign let me know if this aligns with what you were imagining, or if there are any other edge cases that need to be handled.

@isaacparker0 isaacparker0 marked this pull request as ready for review December 24, 2025 17:03
@isaacparker0 isaacparker0 force-pushed the main branch 2 times, most recently from 19b41e2 to a093aea Compare December 24, 2025 17:13
@Calsign
Copy link
Owner

Calsign commented Jan 3, 2026

Thanks for the PR!

I think subdirs still aren't handled correctly by this approach. The test case you provided won't work. The parent package references subdir/mod.rs, but subdir is its own package because it contains a build file. Packages aren't allowed to directly reference source files from another package (unless exports_files is used, but then a full label must be used). This is the crux of why nested module support is difficult.

I haven't read the implementation in your PR, but I'd like to pin down the correct way to handle this first.

Some options:

  1. Don't do anything, allow gazelle to generate broken build files and make the user fix it
  2. Detect when an invalid build file would be created and fail gazelle early with a helpful error message
  3. Don't create targets for sources in subpackages if this would invalidate a target in a parent package
  4. If a subdirectory already has a source referenced by a package, create all targets for sources in that subdirectory in the parent package
  5. Create the subpackage, and use exports_files with a label to reference the sources in the subpackage from the parent package

I'm not sure which of these I like best, presumably 4 or 5 but I think these are also more difficult to implement. I'm curious if you have other suggestions or which idea among these you prefer.

When I worked in a bazel monorepo, whenever we had singular targets that contained sources for subdirectories, this was an exceptional circumstance and we generally didn't create more than one target containing sources in those subdirectories. We would often use gazelle directives to prevent the creation of targets in the subdirectories (something like # gazelle:rust_ignore subdir_name).

Perhaps rust encourages more subdirectories than other languages due to the implicit creation of modules, so maybe this is more of a problem for gazelle_rust than it was for the languages we used primarily at my former company.

I would also believe that not supporting this properly for now is the correct course of action since most users won't need it anyway. I would just like to cap this off with useful error messages, i.e. option 2 rather than option 1. This would likely be in combination with a directive like # gazelle:rust_ignore subdir_name to control where gazelle_rust chooses to create targets.

@Calsign Calsign mentioned this pull request Jan 3, 2026
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants