Skip to content

Commit ac0f301

Browse files
committed
feat: Allow process_wrapper to capture exit codes instead of forwarding them
1 parent cdaf15f commit ac0f301

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

rust/private/clippy.bzl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def get_clippy_ready_crate_info(target, aspect_ctx = None):
101101
else:
102102
return None
103103

104-
def rust_clippy_action(ctx, clippy_executable, process_wrapper, crate_info, config, output = None, success_marker = None, cap_at_warnings = False, extra_clippy_flags = [], error_format = None, clippy_diagnostics_file = None):
104+
def rust_clippy_action(ctx, clippy_executable, process_wrapper, crate_info, config, output = None, success_marker = None, exit_code_file = None, forward_clippy_exit_code = True, cap_at_warnings = False, extra_clippy_flags = [], error_format = None, clippy_diagnostics_file = None):
105105
"""Run clippy with the specified parameters.
106106
107107
Args:
@@ -112,6 +112,8 @@ def rust_clippy_action(ctx, clippy_executable, process_wrapper, crate_info, conf
112112
config (File): The clippy configuration file. Reference: https://doc.rust-lang.org/clippy/configuration.html#configuring-clippy
113113
output (File): The output file for clippy stdout/stderr. If None, no output will be captured
114114
success_marker (File): A file that will be written if clippy succeeds
115+
exit_code_file (File): A file that will contain clippy's exit code
116+
forward_clippy_exit_code (bool): If set, let the action exit with the same exit code as clippy
115117
cap_at_warnings (bool): If set, it will cap all reports as warnings, allowing the build to continue even with clippy failures
116118
extra_clippy_flags (List[str]): A list of extra options to pass to clippy. If not set, every warnings will be turned into errors
117119
error_format (str): Which error format to use. Must be acceptable by rustc: https://doc.rust-lang.org/beta/rustc/command-line-arguments.html#--error-format-control-how-errors-are-produced
@@ -200,6 +202,13 @@ def rust_clippy_action(ctx, clippy_executable, process_wrapper, crate_info, conf
200202
args.process_wrapper_flags.add("--touch-file", success_marker)
201203
outputs.append(success_marker)
202204

205+
if forward_clippy_exit_code == False:
206+
args.process_wrapper_flags.add("--forward-exit-code", "false")
207+
208+
if exit_code_file != None:
209+
args.process_wrapper_flags.add("--exit-code-file", exit_code_file)
210+
outputs.append(exit_code_file)
211+
203212
if clippy_flags or lint_files:
204213
args.rustc_flags.add_all(clippy_flags)
205214
else:

util/process_wrapper/main.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use std::collections::HashMap;
2222
use std::fmt;
2323
use std::fs::{copy, OpenOptions};
2424
use std::io;
25+
use std::io::Write;
2526
use std::process::{exit, Command, ExitStatus, Stdio};
2627

2728
use tinyjson::JsonValue;
@@ -215,7 +216,7 @@ fn main() -> Result<(), ProcessWrapperError> {
215216
.create(true)
216217
.truncate(true)
217218
.write(true)
218-
.open(tf)
219+
.open(&tf)
219220
.map_err(|e| ProcessWrapperError(format!("failed to create touch file: {}", e)))?;
220221
}
221222
if let Some((copy_source, copy_dest)) = opts.copy_output {
@@ -228,7 +229,23 @@ fn main() -> Result<(), ProcessWrapperError> {
228229
}
229230
}
230231

231-
exit(code)
232+
if let Some(ecf) = opts.exit_code_file {
233+
let exit_code_file = OpenOptions::new()
234+
.create(true)
235+
.truncate(true)
236+
.write(true)
237+
.open(&ecf)
238+
.map_err(|e| ProcessWrapperError(format!("failed to create exit code file: {}", e)))?;
239+
let mut writer = io::LineWriter::new(exit_code_file);
240+
writeln!(writer, "{}", code)
241+
.map_err(|e| ProcessWrapperError(format!("failed to write exit code to file: {}", e)))?;
242+
}
243+
244+
if opts.forward_exit_code {
245+
exit(code)
246+
} else {
247+
exit(0)
248+
}
232249
}
233250

234251
#[cfg(test)]

util/process_wrapper/options.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ pub(crate) struct Options {
4444
// If set, also logs all unprocessed output from the rustc output to this file.
4545
// Meant to be used to get json output out of rustc for tooling usage.
4646
pub(crate) output_file: Option<String>,
47+
// If set, exit with the same code as the child process.
48+
pub(crate) forward_exit_code: bool,
49+
// If set, writes the exit code of the process into this file.
50+
pub(crate) exit_code_file: Option<String>,
4751
// If set, it configures rustc to emit an rmeta file and then
4852
// quit.
4953
pub(crate) rustc_quit_on_rmeta: bool,
@@ -64,6 +68,8 @@ pub(crate) fn options() -> Result<Options, OptionError> {
6468
let mut stdout_file = None;
6569
let mut stderr_file = None;
6670
let mut output_file = None;
71+
let mut forward_exit_code_raw = None;
72+
let mut exit_code_file = None;
6773
let mut rustc_quit_on_rmeta_raw = None;
6874
let mut rustc_output_format_raw = None;
6975
let mut flags = Flags::new();
@@ -102,6 +108,16 @@ pub(crate) fn options() -> Result<Options, OptionError> {
102108
"Log all unprocessed subprocess stderr in this file.",
103109
&mut output_file,
104110
);
111+
flags.define_flag(
112+
"--forward-exit-code",
113+
"If set, the process_wrapper will exit with the same exit code as the subprocess if it had no internal errors. True by default, disable with `--forward-exit-code=false`",
114+
&mut forward_exit_code_raw,
115+
);
116+
flags.define_flag(
117+
"--exit-code-file",
118+
"Log the exit code of the process to this file.",
119+
&mut exit_code_file,
120+
);
105121
flags.define_flag(
106122
"--rustc-quit-on-rmeta",
107123
"If enabled, this wrapper will terminate rustc after rmeta has been emitted.",
@@ -179,6 +195,8 @@ pub(crate) fn options() -> Result<Options, OptionError> {
179195
})
180196
.transpose()?;
181197

198+
// As we want `true` by default, we accept anything except `"false"` as `"true"`
199+
let forward_exit_code = forward_exit_code_raw.is_some_and(|s| s != "false");
182200
let rustc_quit_on_rmeta = rustc_quit_on_rmeta_raw.is_some_and(|s| s == "true");
183201
let rustc_output_format = rustc_output_format_raw
184202
.map(|v| match v.as_str() {
@@ -227,6 +245,8 @@ pub(crate) fn options() -> Result<Options, OptionError> {
227245
stdout_file,
228246
stderr_file,
229247
output_file,
248+
forward_exit_code,
249+
exit_code_file,
230250
rustc_quit_on_rmeta,
231251
rustc_output_format,
232252
})

0 commit comments

Comments
 (0)