#workspace #nested #nested-workspace

bin+lib nested_workspace

Run Cargo commands on workspaces in workspaces

2 releases

Uses new Rust 2024

new 0.1.1 May 11, 2025
0.1.0 May 11, 2025

#353 in Cargo plugins

Download history 118/week @ 2025-05-05

122 downloads per month

MIT/Apache

19KB
333 lines

nested_workspace

Run Cargo commands on workspaces in workspaces

Nested Workspace supports the following Cargo subcommands directly:

  • cargo build
  • cargo check
  • cargo test

Additional Cargo subcommands are supported via the nw subcommand, installed with the following command:[^1]

cargo install nested_workspace

[^1]: cargo install cargo-nw will install a different subcommand, unrelated to Nested Workspace.

For example, the follow command runs cargo clean on the current package or workspace and each nested workspace:

cargo nw clean

Note: cargo nw build and cargo nw test should also work. However, they may result in extra calls to cargo build and cargo test (respectively) if direct support for these commands is configured (as describe next).

Usage

Nested Workspace requires that each nested workspace appear under a containing package as follows (example):

containing package
├─ nested workspace A
└─ nested workspace B

Furthermore, the following steps are required:

  1. In the containing package's Cargo.toml file, create a nest_workspace metadata table. The table should contain a roots array with the name of each nested workspace. Example:

    [package.metadata.nested_workspace]
    roots = [
       "nested_workspace_a",
       "nested_workspace_b",
       ...
    ]
    
  2. To enable direct support for cargo build and cargo check, add nested_workspace as build-dependency to the containing package's Cargo.toml:

    [build-dependencies]
    nested_workspace = "0.1"
    

    And create a build script (build.rs) with the following contents:

    fn main() {
        nested_workspace::build();
    }
    
  3. To enable direct support for cargo test, add nested_workspace as dev-dependency to the containing package's Cargo.toml:

    [dev-dependencies]
    nested_workspace = "0.1"
    

    And create a test like the following:

    #[test]
    fn nested_workspace() {
        nested_workspace::test();
    }
    

Why would one need multiple workspaces?

  • Multiple toolchains: Cargo builds all targets in workspace with the same toolchain. If a project needs multiple toolchains, then multiple workspaces are needed. (Dylint is an example of such a project.)

  • Conflicting features: Cargo performs feature unification across the packages in a workspace. Features are meant to be additive, but some packages have conflicting features (gix-transport is an example). Multiple workspaces can be used to build targets with features that conflict.

Why aren't more subcommands supported directly?

Nested Workspace needs a trigger to run a subcommand:

  • For cargo build and cargo check, the trigger is a build script containing nested_workspace::build().
  • For cargo test, the trigger is a test containing nested_workspace::test().

For other subcommands, there is no obvious trigger. Hence, other subcommands must be run with cargo nw <subcommand>.

Dependencies

~1.3–2.2MB
~45K SLoC