-
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
Add --message-format flag. #3000
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
Not sure why appveyor fails: looks like it uses an older nightly, which requires |
Thanks for the PR @matklad! This looks pretty good to me in terms of plumbing. I think this is important over cc @rust-lang/tools, what would your expectations here be? If we're emitting JSON, should Cargo emit everything as JSON (e.g. status messages as well). Additionally, should Cargo always wrap the compiler's error messages with its own JSON documents? That way we could attribute what crate's being compiled, what version, etc. |
Yes, I totally missed this effect, this is a huge argument in favor of custom flag.
Are there any tools which already require this info? |
I would like this as a long-term goal, but in the short-term, tools should handle the mix (to be defensive, they'll have to handle a mix in any case).
I would like this. Not sure it has to block, but it should certainly happen at some point. |
I don't think so, but it provides us a lot of flexibility where we could just send "status reports" every so often from Cargo for when something is happening.
I kind of agree, and I feel like it's best to get it out of the way sooner rather than later. @matklad would you be open to exploring this? The final product would look similar to this where you'd basically read the output in a streaming fashion line-by-line. Each line of JSON would then be wrapped in our own, and otherwise all other output would be forwarded to the console. |
I would think we could start out with a simple schema like: {
"crate": "crate-name",
"version": "crate-version",
"source": "url",
"message": { ... },
"reason": "rustc-message"<
} We could expand that over time, but we should always have all those pieces of information at least |
I agree that it would be best for cargo to wrap rustc's json. But if it's too onerous to do that now it could be designed in a way that tools can detect whether they are seeing rustc-json or cargo-json. cc @jonathandturner another json error format being proposed. |
☔ The latest upstream changes (presumably #3038) made this pull request unmergeable. Please resolve the merge conflicts. |
dc6ee7a
to
c16f8b1
Compare
@alexcrichton what do you think about including only |
@matklad sounds good to me! |
And one more question: what stream should be used for JSON? I think that it should be stdout, because it is intended for machines (see also comments by @kamalmarhubi and @kevincox on this issue). An immediate practical benefit is that the consumers wouldn't need to filter JSON from diagnostic messages. But |
I would argue that stdout is the right place. Because this becomes the output and it's intended for machines. Then you "could" put human readable warnings and errors on stderr without breaking the JSON. However in this case that's probably not very useful because the JSON output specifically includes errors and warnings. |
@matklad I'm pretty sure I am really excited for this PR, but it's a a bit sad it won't be included in the same stable version as new and JSON errors are. |
There are diagnostic messages from the Cargo itself, which are not JSON at the moment.
Yep, Cargo naturally lags behind rustc for some features because they have to be implemented in the compiler first. However you could use nightly Cargo with stable rustc! |
74af75d
to
4537d66
Compare
Move stream_output to ProcessBuilder Make `stream_output` method more reusable (I intend to use it in #3000). Unrelated question: what is that `ExecEngine` thing? Looks like it does nothing at the moment and can be removed.
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.
Thanks @matklad! Could you also add some documentation on this feature as well?
Also cc @rust-lang/tools and @jonathandturner, JSON errors plumbed through Cargo along with future extensibility so we can add more JSON to the output stream of Cargo.
Right now this is exposed through cargo build --message-format json-v1
. The v1
is in theory so we can change the JSON format later, but the compiler doesn't have this, so maybe it's just wishful thinking?
&mut |line| assert!(line.is_empty()), | ||
&mut |line| { | ||
let rustc_message = json::Json::from_str(line).unwrap_or_else(|_| { | ||
panic!("Compiler produced invalid json: `{}`", line) |
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.
This should probably get translated to a normal error instead of a panic
Json | ||
} | ||
|
||
impl MessageFormat { |
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.
You can probably get away from directly implementing rustc_serialize::Decodable
here as that'll thread all the way through docopt I think.
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.
thoughts on this?
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.
Yep, I'll do this when I have time (soonish). I think I'll leave json
instead of json-v1
. v1
was intended for "let's output compiler messages as is, and wrap them later", but we are already do the streaming.
message: json::Json, | ||
} | ||
process_builder.exec_with_streaming( | ||
&mut |line| assert!(line.is_empty()), |
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.
(same with below, this'll want to be a normal error not a panic)
let process_builder = rustc.into_process_builder(); | ||
try!(if json_errors { | ||
#[derive(RustcEncodable)] | ||
struct Message<'a> { |
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.
Perhaps this could be defined in a more central location? This'd in theory I guess actually be some sort of enum for the messages that get emitted, and all of them have a reason
.
What do you think about
|
I personally feel like stdout is the best option here, but I don't want to rail up against the compiler and we should follow suit there. |
@@ -110,13 +110,13 @@ pub struct ProcessError { | |||
pub desc: String, | |||
pub exit: Option<ExitStatus>, | |||
pub output: Option<Output>, | |||
cause: Option<io::Error>, | |||
cause: Option<Box<Error + Send>>, |
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.
Perhaps Box<CargoError>
?
|
||
pub fn emit(self) { | ||
let json = json::encode(&self).unwrap(); | ||
println!("{}", json); |
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.
@alexcrichton is this the right way to print JSON to stdout? There is no error reporting, and it bypasses config.shell altogether, but I think both of these are OK: we don't use colors, so we don't need shell, println
does necessary synchronization, and it is probably OK to panic if we fail to write to stdout.
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.
Yeah this is fine!
@bors: r+ |
📌 Commit b9ec2b1 has been approved by |
⌛ Testing commit b9ec2b1 with merge 964afba... |
@bors: retry force clean |
⌛ Testing commit b9ec2b1 with merge c9c8a6e... |
@bors: retry force clean |
Add --message-format flag. Closes #2982 This adds a `--message-format` flag with values `human` or `json-v1` to commands that may trigger compilation. After the discussion in the issue I am no longer sure that this is a way to go: * Looks like it buys nothing compared to `RUST_FLAGS` approach: a flag is more useful on the command line, but from the tool point of view there should be no significant differences between a flag and an environmental variable. * Looks like we really want to wrap compiler's messages into our own json to tie them to particular compilation.
☀️ Test successful - cargo-cross-linux, cargo-linux-32, cargo-linux-64, cargo-mac-32, cargo-mac-64, cargo-win-gnu-32, cargo-win-gnu-64, cargo-win-msvc-32, cargo-win-msvc-64 |
Is there an ETA for the next release that will include this feature? |
@jplatte this'll be released with Rust 1.14 on 2016-12-22 |
Closes #2982
This adds a
--message-format
flag with valueshuman
orjson-v1
to commands that may trigger compilation.After the discussion in the issue I am no longer sure that this is a way to go:
RUST_FLAGS
approach: a flag is more useful on the command line, but from the tool point of view there should be no significant differences between a flag and an environmental variable.