cc @jonathandturner
cc @matklad
One question is how to untangle Cargo output from the compiler's output. That is, if we simply add --error-format to the flags, we'll get an stderr like
```
Compiling crossbeam v0.1.6
Compiling rand v0.3.14
Compiling memchr v0.1.10
Compiling kernel32-sys v0.2.1
{"message":"transmute called with differently sized types: [usize; 32] (2048 bits) to [std::sync::atomic::AtomicBool; 32] (256 bits)","code":{"code":"E0512","explanation":"\nTransmute with two differently sized types was attempted. Erroneous code\nexample:\n\ncompile_fail,E0512\nfn takes_u8(_: u8) {}\n\nfn main() {\n unsafe { takes_u8(::std::mem::transmute(0u16)); }\n // error: transmute called with differently sized types\n}\n\n\nPlease use types with same size or use the expected type directly. Example:\n\n\nfn takes_u8(_: u8) {}\n\nfn main() {\n unsafe { takes_u8(::std::mem::transmute(0i8)); } // ok!\n // or:\n unsafe { takes_u8(0u8); } // ok!\n}\n``\n"},"level":"error","spans":[{"file_name":"/home/matklad/.cargo/registry/src/github.com-1ecc6299db9ec823/crossbeam-0.1.6/src/sync/seg_queue.rs","byte_start":45628,"byte_end":45642,"line_start":34,"line_end":34,"column_start":29,"column_end":43,"is_primary":true,"text":[{"text":" ready: unsafe { mem::transmute([0usize; SEG_SIZE]) },","highlight_start":29,"highlight_end":43}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}
{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":null}
Build failed, waiting for other jobs to finish...
error: Could not compilecrossbeam`.
To learn more, run the command again with --verbose.
``````
I see three options:
I'd suggest to go with the option 2: it can be evolved into the 1 later and, even if 1 seems to be the correct approach, it may turn out that we don't actually need it.
Option 2 is how we do it in RustyCode right now. If the line doesn't begin with { then it is ignored as a JSON candidate. Ideally option 1 is best, but that would require a significant investment I imagine.
:+1: for option 2
In the case of cargo run there may be some output from the program itself. Should --error-format be used with cargo run at all?
I think that 2 is a fine choice to take for now, it's certainly the most conservative. That being said, though, I'd also like to make Cargo as amenable to external tools as possible, so I wouldn't mind Cargo also printing out json status updates for itself.
I'd personally expect --error-format to be available on all cargo subcommands that could trigger compilations (e.g. those with -j as well). We may also want to consider hooking it up to a more general flag like --output-format which controls all of Cargo's output, not just the errors of the compiler itself.
cc @rust-lang/tools
rustw also basically does option 2, but I'd love for Cargo to output JSON as well as the compiler
It looks to me like there is no way to distinguish which crate the JSON corresponds to. Is that true?
I might expect Cargo itself to have a JSON output format that is a superset of the rustc JSON output. (Edit: I see @nrc said the same thing).
Yes, I think Cargo would need its own JSON format that wraps Rustc's.
Note that Cargo would have a very difficult time _capturing_ the output of the compiler and then adding its own json. It could, but it wouldn't be an easy thing to do.
@alexcrichton why? Is it not just redirecting stdout?
It looks to me like there is no way to distinguish which crate the JSON corresponds to. Is that true?
Yes, looks like it is indeed impossible to trace error messages back to target and package. You can get an approximate answer by inspecting the path to the file, but this will break at least when the same file is used by multiple targets.
This is actually a very compelling reason to wrap compiler's output. But such wrapping would be incompatible with option 2 :frowning:
In the ideal world each compilation may have a unique identity such that it is possible to connect compiler invocation command line, errors, recompilation causality chains, etc.
I've started the work on option 2 variant here: https://github.com/matklad/cargo/commit/c9a6062519c158c79a5aab8c1867402f131a7cf7
@nrc in order to preserve live updates we'd have to stream the output, e.g. capture it on the fly. Cargo does this for build scripts today so some of the work is implemented, but it's in general a pretty hairy prospect. Additionally it unfortunately disables colors, but I guess that doesn't matter for JSON?
ah, streaming, yeah, I'd been thinking about that for the compiler too. It is a pain.It seems solvable in the long term though (and necessary).
Yeah, I'd assume JSON errors would disable colours in any case - it's not meant to be user-readable.
Most helpful comment
ah, streaming, yeah, I'd been thinking about that for the compiler too. It is a pain.It seems solvable in the long term though (and necessary).
Yeah, I'd assume JSON errors would disable colours in any case - it's not meant to be user-readable.