-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Allow to intercept binaries invoked by Cargo #3866
Conversation
r? @brson (rust_highfive has picked a reviewer for you, use r? to override) |
src/cargo/util/machine_message.rs
Outdated
impl<'a> RunProfile<'a> { | ||
pub fn new(process: &ProcessBuilder) -> RunProfile { | ||
RunProfile { | ||
program: process.get_program().to_string_lossy(), |
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.
Note to self: assert!
that this is an absolute path.
Thanks for working on this! I'm not sure I understand the |
Yep! During build, Cargo writes JSON in a JSON object per line format, so that it does not need to wait until the end of the build to produce a single array of messages. To test this, we don't directly compare cargo/tests/cargotest/support/mod.rs Line 382 in e60ae3d
In this particular case we indeed output a separate JSON message for every binary to be run. |
@matklad Okay, so as a user of |
Yes! In theory, you can also relay on the fact that each line of stdout is a JSON object (we keep non-json output on stderr), but in practice I'd add a |
Regarding
I think cargo might even treat that as an error. I can't think of a situation where setting both |
Yep, that'd be a safe start. Though there are situations where you might want to both show usual output to the user and do something with the binaries: #3855. But that's a general problem that |
If `CARGO_WRAP` environment variable is specified, cargo will just print what it should have executed otherwise during `cargo test` / `cargo run`.
Thanks for the PR @matklad, implementation looks great to me. My only question would be about the interface here. A We may also have an opportunity to hit two birds with one stone here by allowing human message to also provider a wrapper, such as with In general though I'd prefer to call this flag perhaps something along the lines of |
I've must have misinterpreted #3670 (comment) then :) The benefit of environmental variable is that you don't need to mess up with command line, which is provided by the user. That said, you still need to modify the command line for Another advantage of env var is that you don't clutter I am ok with changing this to command line argument, but I like the env var slightly better.
Does |
Oh interesting! Both that I can't make up my mind and I wasn't aware of how IntelliJ passed
This isn't really doing much intercepting though? It's sort of like "don't run final child processes, only the intermediate ones that the compiler does". This also seems like it's definitely toeing the line on #3815 so we may want to be sure to consider that as well. |
That's interesting! I expect we can reuse
I am also not sure what is the best solution here. "Avoid messing up with user's command line" is a weak argument, because it should not be that hard, and because I expect we'll need to understand Cargo's command line eventually anyway. I think not cluttering And I still can't think of the name for the arg/env I really like :) One more option is Am I correct that there are only two unresolved questions:
Oh, one more idea about name: |
I, for one, like that one... Maybe document it in |
Sure! I've think I've finished everything implementation wise, only option name/passing 🚲🏠 is left =) |
Hmm. I think it would be easier if |
It should be possible to implement, but I suspect that for |
I'm a bit confused (I probably don't understand the other bug) - what's the reason we can't have cargo output the human readable output to stderr and json (if any) to stdout? |
Compiler currently produces either only human-readable messages, or JSON. Cargo already prints both JSON and human oriented messages with So we either need a flag |
Uhh, okay, in that case how about doing it the opposite way - have |
Have I gridlocked the discussion with my complaints? Those were just my ¢2, feel free to let me know if I'm bikeshedding too much :-) |
☔ The latest upstream changes (presumably #3893) made this pull request unmergeable. Please resolve the merge conflicts. |
Ok so coming back to this, I'm not 100% sure how to proceed. I feel like we have a few related proposals in flight, but I don't want to block progress. In that sense I'm trying to come up with the most conservative solution with the fewest extensions possible. To that end, I wonder if it'd be helpful to dig in to why this isn't possible today? Is it because the cwd/env aren't known? Is it because binaries cannot be found? I'd be tempted to say that this is roughtly equivalent to translating |
It's 95% percent possible today if you are willing to parse cargo's command line. The worst case will look like this: So, exactly two problems to solve:
On the one hand, I'd be happy to punt on this for now, because 95% workaround exists. On the other hand, I don't want to go the "reimplement tiny bits of Cargo in IntelliJ" road because I fear that even small pieces like @alexcrichton are you not sure about the end result (JSON messages and not running actual processes) or about the interface (environmental variable vs command line flag)? I am rather confident that the end result is right, useful and is not a backwards compatibility hazard. I don't particularly like the interface part myself! @vojtechkral what do you think about the problem from the command-line wrapper perspective? |
Seems to me like we're streching cargo's interface to limits or beyond here. I've given the cli wrappers a bit of rethinking and I think I'll simplify them to not use/mirror cargo's cli iface. Ie. the interface would be simply I still need to get the path to the binary as well as the environment from cargo somehow. I think that trying to bolt this on top of the regular cli interface leads to problems we're seeing. I can think of two ways how to do this without abusing the cli interface:
Does this help? edit: typos, sorry! |
@matklad I wonder if I I'm just too resistant to change right now by accident. In some sense there's no end of features we can add to Cargo and none of them are relatively difficult to support in a backwards-compatible fashion. The drawback is that eventually Cargo could be a giant pile of random bits and pieces, most of which aren't recommended any more but still in use by various tools throughout the ecosystem. In that sense I don't currently think I either agree or disagree with the end goal. I don't see any reason not to generate json message and such, but fitting it into the broader vision of where Cargo will eventually be may be difficult. I don't really want to block this indefinitely though, so I'm tempted to just "oh well" and land the PR as-is. It's clearly solving a use case for IntelliJ today and it's not really that hard to support in a backwards compatible fashion. @vojtechkral it sounds like though from IntelliJ's perspective if a command line is coming in and doesn't want to be looked at then there's not many options here. Using Cargo as a library isn't easy b/c you'd have to parse the CLI, and otherwise using a command like |
What I meant was that the CLI parsing code Cargo uses would be part of that library (and so could be used by others too). |
Oh probably not, doesn't handle user pieces as well. Alas! |
@alexcrichton , this is my concern as well! (I am already not happy with the project model which has grown too many pieces: workspaces, packages, targets like So now I think the best path would be to postpone this for now, parse command line in IntelliJ instead, and revisit this once the debugger support in IntelliJ matures.
@vojtechkral keep in mind that Cargo already has a rather elaborate interface for selecting the binary! There's Deterministic filenames exposed via
I wounder if Cargo should really be a pipeline of independent binaries producing and consuming JSON 😜 |
Yeah, that's true. The problem is that I won't be able to figure out what command is used to build a binary. Which makes extensions like
No, probably not. Seems to me it's a good call to postpone this at this point. I'd say that cargo has already hit some of the problems @alexcrichton mentioned - the interfacing seems to have gotten quite complex :) By and large, cargo reminds me of git - it also has a complex CLI interface and cargo's By consequence, this boils down to designing a comprehensice interface for cargo, both CLI and programmatic, which is of course a huge amount of work. |
Ok postponing sounds good to me, but @matklad please keep me posted on developments. If the need for this arises again I think we'd be ok to merge it. |
Fix #3670.
This adds an environmental variable
CARGO_WRAP
, which prevents cargo from running binaries and allows IDEs and such to take over the wheel.Question: how this should interract with
--message-format=json
? What should Cargo do, if it seesCARGO_WRAP
, but--message_format
is human?