- Feature Name: workspace-member-autodiscovery
- Start Date: 2021-9-22
- RFC PR: N/A
- Rust Issue: N/A
Summary
If a directory named members
is present in the root of a crate without an explicit workspace members declaration, and the members
directory contains one or more subdirectories, those subdirectories will be inferred to be workspace members, as if
[workspace]
members = ["members/*"]
were present in the root's Cargo.toml
.
Motivation
By providing a convenient default, we encourage uniformity of workspace layouts, making workspaces easier to navigate and identify as workspaces. Additionally, it becomes slightly easier to create a workspace crate, or transition an existing crate to a workspace, as there is no need for a [workspace]
declaration in the root Cargo.toml
.
Guide-level explanation
(First part stolen from The Cargo Book.)
Root package
A workspace can be created by adding a [workspace]
section to Cargo.toml
. This can be added to a Cargo.toml
that already defines a [package]
, in which case the package is the root package of the workspace. The workspace root is the directory where the workspace's Cargo.toml
is located. Alternatively, workspace members can be placed in a directory called members
, and cargo
will automatically add them as workspace members.
For example, given the following directory layout:
foo/
Cargo.toml
members/
bar
baz
…
Crates in foo/members/bar
and foo/members/baz
will be inferred to be workspace members. Note that it is an error for these directories to exist but not contain valid crate manifests, i.e., in foo/members/bar/Cargo.toml
and foo/members/baz/Cargo.toml
.
This behavior can be overridden by including an explicit workspace members declaration.
Reference-level explanation
If a directory named members
is present in the crate root, and the root manifest does not contain an explicit workspace members declaration, cargo
will behave as if the crate's root manifest contained:
[workspace]
members = ["members/*"]
Drawbacks
cargo
would complain when invoked in pre-existing crates with a members
directory with subdirectories that are not valid rust crates.
If a crate did contain a members
directory that did contain rust crates, the root crate might unexpectedly become a workspace with those crates as members.
Rationale and alternatives
We could not do this, with the downside of requiring users to explicitly add a workspace members declaration, and not encouraging crate layout uniformity.
We could also use an alternative method of auto-discovery of workspace members, for example treating all directories in the root crate which contain Cargo.toml
files as workspace members. However, this has the disadvantage of not promoting crate layout uniformity, and of causing false-positives from crates which are in the root, but are not workspace members.
Prior art
Prior art includes the existing auto-discovered targets, including binary targets in src/bin
, examples in examples
, integration tests in tests
, and benchmarks in benches
. These seem to be useful and widely used, so supporting automatic workspace member discovery seems likely to be well received.
Unresolved questions
Some projects use crates
as the name of the subdirectory that contains workspace members, so we could consider using that instead, although members
is arguably clearer, since it contains workspace members, not just arbitrary crates.
Future possibilities
There are a number of steps required to set up a new workspace, or to transition an existing crate to being a workspace, for example adding and keeping the members
declaration up-to-date, mirroring manifest metadata in multiple places, figuring out how to publish members, and adding path dependencies between members.
These barriers to using workspaces might inadvertently deter crate authors from using them.
This RFC is quite a modest improvement, but combined with other changes, for example:
- Inferring workspace path dependencies, so they need not be declared in the manifest.
- Allowing manifest entries such as
license
andrepository
to be placed under the[workspace]
section, to apply to all members. - Adding support to
cargo
for publishing an entire workspace atomically. - Allowing crates to serve as namespaces, so that crate members can have non-global names like
foo/bar
, perhaps accessed asworkspace::bar
, wherefoo
is the root crate andbar
is a workspace member, to alleviate the need for workspace members to have globally unique names.
would make it much easier to use workspaces, and thus encourage crate authors to use them where appropriate.