cargo
cargo copied to clipboard
cargo should support glob syntax on workspace excludes
Currently, we can include crates in a workspace with glob syntax (see https://github.com/rust-lang/cargo/issues/3911). However, we can't exclude crates in the same way.
See https://github.com/rust-lang/cargo/blob/master/src/cargo/core/workspace.rs#L826, where it looks as if we're just doing manifest_path.starts_with(self.root_dir.join(exclude)).
We've hit this because we have a set of autogenerated crates with a common suffix that we cannot neatly exclude without glob support.
I believe this has been implemented now.
I believe this is still an issue. The exclude field is still using starts_with.
cc #6745, which is a similar issue.
The exclude key was added in #3837. There doesn't appear to be any discussion at the time about the format to use. It was enhanced in #4297 to support overlapping.
I think it would be good to consider what format and behavior members and exclude should have. Would it make sense to have something more powerful like gitignore? I think it may be confusing if one uses globs and the other uses gitignore. Would we need a transition period since it may result in different behavior (similar to #4268)? Also consider that package include/exclude are mutually exclusive, but workspace members/exclude is not.
See also #4593 for improving members matching.
I was supposed to work on this while back, but didn't find the time to formalize the problem and proposed solution. Let me try to do that:
Now that the file include/exclude rules are on gitignore-style patterns, I think we all agree that having a similar feature for member packages makes the most sense.
The problem, however, is the fact that when working with the files under a package, we already have a root defined (package root is the directory where the manifest file is seating). That allows having the anchor gitignore-style rules need when writing them.
For members, however, we don't have such a well-defined root anchor, since the workspace package (like A), can be in a directory next to a member package (like B). Like this:
<project-root>
|-- A
|-- B
...
I was thinking to add another general rule to gitignore rule-set, which would allow getting outside of the current root (package root = dir of manifest) and point to parent and sibling directories.
This additional rule would be: "If the pattern starts with ../, then it's a relative glob, ...". (We need to figure out the exact details of the rest of the rule to keep it consistent with the rest of gitignore/glob rules.
Having that, then we can have A include (or exclude) B (or a package under it) in the example above.
Hope you find this helpful. Would love to hear what you think!
[This is yet resolved]
I am going to close this. Further discussion could happen in #11405. If you think this is wrong please leave a comment. We could reopen it.
Edit: I think it is better to leave it open.
Linking in #12779 for visibility since this is more of a problem for me now with cargo new adding packages to members if the path is not a direct ~~glob~~ excluded path.
~~i.e for~~
[workspace]
members = []
exclude = ["directory/**"]
~~cargo new in directory/ works as expected since https://github.com/rust-lang/cargo/pull/13261, but cargo new in directory/subdir/ does add the new package to members~~
edit: actually, I don't think it works at all :/
was just bitten by this... my primary use-case for glob exclusions is in a workspace that has no root package, but has many examples that each have to be their own package because the tooling works on the package level.