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