rust-lang / rust-lang/cargo

Workspace `exclude` doesn't work if nested under a `member` path

Open
#6,745 11 comments 12 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-workspaces C-bug S-needs-design
Dominant language
Rust
Stars
15.5k
Forks
3k
Avg merge
23h 30m
Merged PRs (30d)
51

Description

Problem

It doesn't appear as though the workspace.exclude key works for paths that are nested under a path included in workspace.members

Steps

  1. Create a nested package structure:
/tmp % cargo new outer
     Created binary (application) `outer` package
/tmp % cd outer
/tmp/outer % cargo new middle      
     Created binary (application) `middle` package
/tmp/outer % cd middle
/tmp/outer/middle % cargo new inner
     Created binary (application) `inner` package
  1. Add a workspace.members key to the outermost level, and observe that the workspace build succeeds:
/tmp/outer/middle % cd /tmp/outer
/tmp/outer % echo "[workspace]\n  members = [\".\", \"middle\"]" >> Cargo.toml
/tmp/outer % cargo build --all
   Compiling middle v0.1.0 (/tmp/outer/middle)                                                                                                                                                                                                                                            
   Compiling outer v0.1.0 (/tmp/outer)                                                                                                                                                                                                                                                    
    Finished dev [unoptimized + debuginfo] target(s) in 0.34s
  1. Now go to the inner package and observe that the build fails:
/tmp/outer % cd /tmp/outer/middle/inner 
/tmp/outer/middle/inner % cargo build
error: current package believes it's in a workspace when it's not:
current:   /tmp/outer/middle/inner/Cargo.toml
workspace: /tmp/outer/Cargo.toml

this may be fixable by adding `middle/inner` to the `workspace.members` array of the manifest located at: /tmp/outer/Cargo.toml
  1. Fair enough; let's explicitly exclude this package instead, and try again:
/tmp/outer/middle/inner % cd /tmp/outer
/tmp/outer % echo "exclude = [\"middle/inner\"]" >> Cargo.toml
/tmp/outer % cd /tmp/outer/middle/inner
/tmp/outer/middle/inner % cargo build
error: current package believes it's in a workspace when it's not:
current:   /tmp/outer/middle/inner/Cargo.toml
workspace: /tmp/outer/Cargo.toml

this may be fixable by adding `middle/inner` to the `workspace.members` array of the manifest located at: /tmp/outer/Cargo.toml

It still wants to be in the workspace! We're stuck.

Possible Solution(s)

If there's overlap between paths in members and exclude, I would expect the more-specific path to win. In this case, the excluded path "middle/inner" is more specific than the member paths "." or "middle", so the exclusion should win. This is probably not so simple if the paths contain globs, though.

Notes

Output of cargo version:

% cargo version
cargo 1.31.0 (339d9f9c8 2018-11-16)

Thanks for your looking into this 🦀

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the nested packages using the outer, middle, and inner Cargo.toml files, then run cargo build from the inner package with workspace.members and workspace.exclude configured as shown. Trace Cargo's workspace member and exclusion resolution; done means the excluded middle/inner package builds independently without the workspace error.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
build-system
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.