-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix confusing error and docs wrt. virtual manifests #4492
Conversation
r? @matklad (rust_highfive has picked a reviewer for you, use r? to override) |
src/cargo/core/workspace.rs
Outdated
command requires running against an actual package in \ | ||
this workspace", self.current_manifest.display()).into() | ||
format!("manifest path `{}` contains no package: The manifest is virtual, \ | ||
and the workspace has no members.", self.current_manifest.display()).into() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be surprised if only a single tests needs to be fixed after this change. However, if this is the case, that probably means that current
function is almost not used anymore, and it might be a good idea to try to get rid of it altogether: probably all commands should work with virtual manifests just fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cargo test
says this is the only one that needs fixing.
The code flow is a little spaghetti-esque currently, but I didn't want to change that as I have no idea how this is all architectured. Before #4335, when calling cargo build
, what happens is that Packages::from_flags
returns Packages::Packages(&Vec::new())
, which then leads in compile_ws
(at
cargo/src/cargo/ops/cargo_compile.rs
Line 234 in bf0b81a
let root_package = ws.current()?; |
current()
, which errored on virtual manifests. However, it seems we can also end up in that branch of there is a workspace but it is empty.With #4335 merged, that's in fact the only way to end up there, as
all
will always be set (unless -p
is given). I have no idea if there are other ways to have compile_ws
call current
, or if other places call current
; grepping for such calls is doesn't really work due to the rather generic name of the function.
Looking at into_package_id_specs
(which has to return an empty list to end up in this branch of compile_ws
), the only way it can return empty is if ws.members()
is empty or if there was no -p
flag and this is not a workspace -- so, it seems actually that in compile_ws
, that branch will always trigger an error. If you want I can change that, and then see if there are other users of current
remaining, but notice that I have no idea what I am doing here. The question is do you trust the test suite coverage enough to let me still do such changes.^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out my analysis is incorrect. For non-virtual packages, we can still get Packages::Packages(&[])
, and then it still uses that other path. current
will however of course always succeed, then.
I suppose one could change from_flags
to not ever return Packages::Packages(&[])
, but instead fill in the current package name there or so; not sure how that would look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So turns out there are a handful usages left:
Function
current
Found usages (8 usages found)
cargo.ops (8 usages found)
cargo_compile.rs (1 usage found)
234 let root_package = ws.current()?;
cargo_doc.rs (1 usage found)
31 let root_package = ws.current()?;
cargo_package.rs (3 usages found)
30 let pkg = ws.current()?;
201 let pkg = ws.current()?;
279 let pkg = ws.current()?;
cargo_pkgid.rs (1 usage found)
13 None => ws.current()?.package_id(),
cargo_run.rs (1 usage found)
17 0 => ws.current()?,
registry.rs (1 usage found)
42 let pkg = ws.current()?;
Originally, ws.current()
appeared as a stop gap to make workspace implementation feasible: with .current()
, it was possible to make Cargo workspace aware incrementally. So it would be great to get rid of it altogether some time in the future, but probably not right now.
It seems to me that cargo publish
still may hit this function from virtual manifest, and so this error message might be wrong in that case (and presumably this is not tested :( ).
So... I think we definitely should update the documentation, however, I am not sure that updating this particular error message is correct for all cases... The simplest tactical fix would be to add a if ws.members().is_empty()
check, and emit either old or new error message.
The strategic fix (which should not be part of this PR) would be to look at the usages of current
and try to get rid of them: I think those insidecargo_package
are unnecessary because it seems to me that we'll have a current package higher in the call stack anyway, and those in cargo_compile, cargo_run and cargo_doc should probably be folded into into_package_id_specs
function.
What about this? Tests all pass, locally at least... |
This looks great! I feel a bit uneasy about that hunk of dead code in the else branch, which seemed to do something useful, but we should have good test coverage in that area. What happens if we remove that |
It was an error so far, just with a confusing error message. So this seemed like the most compatible choice. I will see what happens.
Yeah, I was somewhat unsure. However, notice that |
As expected, the only test that fails is However, I don't think there is ever a situation where you'd want an entirely empty project. And this is an error now. If such a situation ever comes up, this can still be trivially changed. |
📌 Commit 682af71 has been approved by |
☀️ Test successful - status-appveyor, status-travis |
Fixes #3966
Contains updated version of #3967