@@ -750,27 +750,47 @@ fn add_error_format_and_color(
750
750
if pipelined {
751
751
json. push_str ( ",artifacts" ) ;
752
752
}
753
- if cx. bcx . build_config . message_format == MessageFormat :: Short {
754
- json. push_str ( ",diagnostic-short" ) ;
753
+ match cx. bcx . build_config . message_format {
754
+ MessageFormat :: Short | MessageFormat :: Json { short : true , .. } => {
755
+ json. push_str ( ",diagnostic-short" ) ;
756
+ }
757
+ _ => { }
755
758
}
756
759
cmd. arg ( json) ;
757
760
} else {
761
+ let mut color = true ;
758
762
match cx. bcx . build_config . message_format {
759
763
MessageFormat :: Human => ( ) ,
760
- MessageFormat :: Json => {
764
+ MessageFormat :: Json {
765
+ ansi,
766
+ short,
767
+ render_diagnostics,
768
+ } => {
761
769
cmd. arg ( "--error-format" ) . arg ( "json" ) ;
770
+ // If ansi is explicitly requested, enable it. If we're
771
+ // rendering diagnostics ourselves then also enable it because
772
+ // we'll figure out what to do with the colors later.
773
+ if ansi || render_diagnostics {
774
+ cmd. arg ( "--json=diagnostic-rendered-ansi" ) ;
775
+ }
776
+ if short {
777
+ cmd. arg ( "--json=diagnostic-short" ) ;
778
+ }
779
+ color = false ;
762
780
}
763
781
MessageFormat :: Short => {
764
782
cmd. arg ( "--error-format" ) . arg ( "short" ) ;
765
783
}
766
784
}
767
785
768
- let color = if cx. bcx . config . shell ( ) . supports_color ( ) {
769
- "always"
770
- } else {
771
- "never"
772
- } ;
773
- cmd. args ( & [ "--color" , color] ) ;
786
+ if color {
787
+ let color = if cx. bcx . config . shell ( ) . supports_color ( ) {
788
+ "always"
789
+ } else {
790
+ "never"
791
+ } ;
792
+ cmd. args ( & [ "--color" , color] ) ;
793
+ }
774
794
}
775
795
Ok ( ( ) )
776
796
}
@@ -1090,9 +1110,8 @@ impl Kind {
1090
1110
}
1091
1111
1092
1112
struct OutputOptions {
1093
- /// Get the `"rendered"` field from the JSON output and display it on
1094
- /// stderr instead of the JSON message.
1095
- extract_rendered_messages : bool ,
1113
+ /// What format we're emitting from Cargo itself.
1114
+ format : MessageFormat ,
1096
1115
/// Look for JSON message that indicates .rmeta file is available for
1097
1116
/// pipelined compilation.
1098
1117
look_for_metadata_directive : bool ,
@@ -1106,7 +1125,6 @@ struct OutputOptions {
1106
1125
1107
1126
impl OutputOptions {
1108
1127
fn new < ' a > ( cx : & Context < ' a , ' _ > , unit : & Unit < ' a > ) -> OutputOptions {
1109
- let extract_rendered_messages = cx. bcx . build_config . message_format != MessageFormat :: Json ;
1110
1128
let look_for_metadata_directive = cx. rmeta_required ( unit) ;
1111
1129
let color = cx. bcx . config . shell ( ) . supports_color ( ) ;
1112
1130
let cache_cell = if cx. bcx . build_config . cache_messages ( ) {
@@ -1118,7 +1136,7 @@ impl OutputOptions {
1118
1136
None
1119
1137
} ;
1120
1138
OutputOptions {
1121
- extract_rendered_messages ,
1139
+ format : cx . bcx . build_config . message_format ,
1122
1140
look_for_metadata_directive,
1123
1141
color,
1124
1142
cache_cell,
@@ -1175,55 +1193,66 @@ fn on_stderr_line(
1175
1193
}
1176
1194
} ;
1177
1195
1178
- // In some modes of compilation Cargo switches the compiler to JSON mode
1179
- // but the user didn't request that so we still want to print pretty rustc
1180
- // colorized diagnostics. In those cases (`extract_rendered_messages`) we
1181
- // take a look at the JSON blob we go, see if it's a relevant diagnostics,
1182
- // and if so forward just that diagnostic for us to print.
1183
- if options. extract_rendered_messages {
1184
- #[ derive( serde:: Deserialize ) ]
1185
- struct CompilerMessage {
1186
- rendered : String ,
1196
+ // Depending on what we're emitting from Cargo itself, we figure out what to
1197
+ // do with this JSON message.
1198
+ match options. format {
1199
+ // In the "human" output formats (human/short) or if diagnostic messages
1200
+ // from rustc aren't being included in the output of Cargo's JSON
1201
+ // messages then we extract the diagnostic (if present) here and handle
1202
+ // it ourselves.
1203
+ MessageFormat :: Human
1204
+ | MessageFormat :: Short
1205
+ | MessageFormat :: Json {
1206
+ render_diagnostics : true ,
1207
+ ..
1208
+ } => {
1209
+ #[ derive( serde:: Deserialize ) ]
1210
+ struct CompilerMessage {
1211
+ rendered : String ,
1212
+ }
1213
+ if let Ok ( mut error) = serde_json:: from_str :: < CompilerMessage > ( compiler_message. get ( ) ) {
1214
+ // state.stderr will add a newline
1215
+ if error. rendered . ends_with ( '\n' ) {
1216
+ error. rendered . pop ( ) ;
1217
+ }
1218
+ let rendered = if options. color {
1219
+ error. rendered
1220
+ } else {
1221
+ // Strip only fails if the the Writer fails, which is Cursor
1222
+ // on a Vec, which should never fail.
1223
+ strip_ansi_escapes:: strip ( & error. rendered )
1224
+ . map ( |v| String :: from_utf8 ( v) . expect ( "utf8" ) )
1225
+ . expect ( "strip should never fail" )
1226
+ } ;
1227
+ state. stderr ( rendered) ;
1228
+ return Ok ( ( ) ) ;
1229
+ }
1187
1230
}
1188
- if let Ok ( mut error) = serde_json:: from_str :: < CompilerMessage > ( compiler_message. get ( ) ) {
1189
- // state.stderr will add a newline
1190
- if error. rendered . ends_with ( '\n' ) {
1191
- error. rendered . pop ( ) ;
1231
+
1232
+ // Remove color information from the rendered string. When pipelining is
1233
+ // enabled and/or when cached messages are enabled we're always asking
1234
+ // for ANSI colors from rustc, so unconditionally postprocess here and
1235
+ // remove ansi color codes.
1236
+ MessageFormat :: Json { ansi : false , .. } => {
1237
+ #[ derive( serde:: Deserialize , serde:: Serialize ) ]
1238
+ struct CompilerMessage {
1239
+ rendered : String ,
1240
+ #[ serde( flatten) ]
1241
+ other : std:: collections:: BTreeMap < String , serde_json:: Value > ,
1192
1242
}
1193
- let rendered = if options. color {
1194
- error. rendered
1195
- } else {
1196
- // Strip only fails if the the Writer fails, which is Cursor
1197
- // on a Vec, which should never fail.
1198
- strip_ansi_escapes:: strip ( & error. rendered )
1243
+ if let Ok ( mut error) = serde_json:: from_str :: < CompilerMessage > ( compiler_message. get ( ) ) {
1244
+ error. rendered = strip_ansi_escapes:: strip ( & error. rendered )
1199
1245
. map ( |v| String :: from_utf8 ( v) . expect ( "utf8" ) )
1200
- . expect ( "strip should never fail" )
1201
- } ;
1202
- state. stderr ( rendered) ;
1203
- return Ok ( ( ) ) ;
1204
- }
1205
- } else {
1206
- // Remove color information from the rendered string. rustc has not
1207
- // included color in the past, so to avoid breaking anything, strip it
1208
- // out when --json=diagnostic-rendered-ansi is used. This runs
1209
- // unconditionally under the assumption that Cargo will eventually
1210
- // move to this as the default mode. Perhaps in the future, cargo
1211
- // could allow the user to enable/disable color (such as with a
1212
- // `--json` or `--color` or `--message-format` flag).
1213
- #[ derive( serde:: Deserialize , serde:: Serialize ) ]
1214
- struct CompilerMessage {
1215
- rendered : String ,
1216
- #[ serde( flatten) ]
1217
- other : std:: collections:: BTreeMap < String , serde_json:: Value > ,
1218
- }
1219
- if let Ok ( mut error) = serde_json:: from_str :: < CompilerMessage > ( compiler_message. get ( ) ) {
1220
- error. rendered = strip_ansi_escapes:: strip ( & error. rendered )
1221
- . map ( |v| String :: from_utf8 ( v) . expect ( "utf8" ) )
1222
- . unwrap_or ( error. rendered ) ;
1223
- let new_line = serde_json:: to_string ( & error) ?;
1224
- let new_msg: Box < serde_json:: value:: RawValue > = serde_json:: from_str ( & new_line) ?;
1225
- compiler_message = new_msg;
1246
+ . unwrap_or ( error. rendered ) ;
1247
+ let new_line = serde_json:: to_string ( & error) ?;
1248
+ let new_msg: Box < serde_json:: value:: RawValue > = serde_json:: from_str ( & new_line) ?;
1249
+ compiler_message = new_msg;
1250
+ }
1226
1251
}
1252
+
1253
+ // If ansi colors are desired then we should be good to go! We can just
1254
+ // pass through this message as-is.
1255
+ MessageFormat :: Json { ansi : true , .. } => { }
1227
1256
}
1228
1257
1229
1258
// In some modes of execution we will execute rustc with `-Z
@@ -1274,12 +1303,8 @@ fn replay_output_cache(
1274
1303
color : bool ,
1275
1304
) -> Work {
1276
1305
let target = target. clone ( ) ;
1277
- let extract_rendered_messages = match format {
1278
- MessageFormat :: Human | MessageFormat :: Short => true ,
1279
- MessageFormat :: Json => false ,
1280
- } ;
1281
1306
let mut options = OutputOptions {
1282
- extract_rendered_messages ,
1307
+ format ,
1283
1308
look_for_metadata_directive : false ,
1284
1309
color,
1285
1310
cache_cell : None ,
0 commit comments