Skip to content
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 trailing newline check for rustc --print in run-make-support #127887

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 55 additions & 3 deletions src/tools/run-make-support/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,50 @@ use build_helper::drop_bomb::DropBomb;
/// [`run`]: Self::run
/// [`run_fail`]: Self::run_fail
/// [`run_unchecked`]: Self::run_unchecked
#[derive(Debug)]
pub struct Command {
cmd: StdCommand,
stdin: Option<Box<[u8]>>,
completed_process_checks: Vec<(String, Box<dyn Fn(&CompletedProcess)>)>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#[derive(Debug)] // this works now
pub struct Command {
    cmd: StdCommand,
    stdin: Option<Box<[u8]>>,
    assert_stdout_ends_with_newline: bool,
    drop_bomb: DropBomb,
}

and

// Command::command_output
if self.assert_stdout_ends_with_newline {
    completed_process.assert_stdout_ends_with_newline();
}

Let's use a simple bool for now, if there are more check-hooks that we wish to register upon construction, then we can always refactor into the hook form when it comes to it.

@rustbot author

drop_bomb: DropBomb,
}

impl std::fmt::Debug for Command {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Command")
.field("cmd", &self.cmd)
.field("stdin", &self.stdin)
.field(
"completed_process_checks",
&self
.completed_process_checks
.iter()
.map(|(name, _check)| name)
.collect::<Vec<_>>(),
)
.field("drop_bomb", &self.drop_bomb)
.finish()
}
}

impl Command {
#[track_caller]
pub fn new<P: AsRef<OsStr>>(program: P) -> Self {
let program = program.as_ref();
Self { cmd: StdCommand::new(program), stdin: None, drop_bomb: DropBomb::arm(program) }
Self {
cmd: StdCommand::new(program),
stdin: None,
completed_process_checks: vec![],
drop_bomb: DropBomb::arm(program),
}
}

/// Adds a `check` to be completed once the `Command` is run.
pub(crate) fn add_completed_process_check<F>(&mut self, name: &str, check: F) -> &mut Self
where
F: Fn(&CompletedProcess) + 'static,
{
self.completed_process_checks.push((name.to_string(), Box::new(check)));
self
}

/// Specify a stdin input
Expand Down Expand Up @@ -151,7 +183,15 @@ impl Command {
} else {
self.cmd.output().expect("failed to get output of finished process")
};
output.into()

let completed_process = CompletedProcess::from(output);

for (name, check) in self.completed_process_checks.iter() {
eprintln!("checking: {name}");
check(&completed_process);
}

completed_process
}
}

Expand Down Expand Up @@ -199,6 +239,18 @@ impl CompletedProcess {
self
}

/// Checks that `stdout` ends with a newline if it is not empty.
#[track_caller]
pub fn assert_stdout_ends_with_newline(&self) -> &Self {
if !self.stdout_utf8().is_empty() {
assert!(
self.stdout_utf8().ends_with(['\r', '\n'].as_slice()),
"stdout does not end with newline"
);
}
self
}

/// Checks that trimmed `stderr` matches trimmed `expected`.
#[track_caller]
pub fn assert_stderr_equals<S: AsRef<str>>(&self, expected: S) -> &Self {
Expand Down
6 changes: 6 additions & 0 deletions src/tools/run-make-support/src/external_deps/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,15 @@ impl Rustc {
}

/// Specify the print request.
///
/// Also checks that the [`CompletedProcess`](crate::command::CompletedProcess)
/// `stdout` ends with a newline.
pub fn print(&mut self, request: &str) -> &mut Self {
self.cmd.arg("--print");
self.cmd.arg(request);
self.cmd.add_completed_process_check("`--print` ends with newline", |completed_process| {
completed_process.assert_stdout_ends_with_newline();
});
self
}

Expand Down
1 change: 0 additions & 1 deletion tests/run-make/link-arg/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,4 @@ fn main() {
.run_unchecked();
out.assert_stdout_contains("lfoo");
out.assert_stdout_contains("lbar");
assert!(out.stdout_utf8().ends_with('\n'));
}
Loading