Skip to content

Commit f73c106

Browse files
committed
add actions on process_lines
1 parent d3022e2 commit f73c106

File tree

5 files changed

+80
-11
lines changed

5 files changed

+80
-11
lines changed

src/cmd/actions.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/// Represents actions that are available while reading live output from a process
2+
pub struct Actions {
3+
lines: Vec<String>,
4+
}
5+
6+
impl<'a> Actions {
7+
pub(crate) fn new() -> Self {
8+
Actions { lines: Vec::new() }
9+
}
10+
11+
pub(crate) fn next_input(&mut self, input: &str) {
12+
self.lines = vec![input.to_string()];
13+
}
14+
15+
pub(crate) fn take_lines(&mut self) -> Vec<String> {
16+
std::mem::take(&mut self.lines)
17+
}
18+
19+
/// Replace last read line with new_lines
20+
pub fn replace_with_lines(&mut self, new_lines: impl Iterator<Item = &'a str>) {
21+
self.lines = new_lines.map(|str| str.to_string()).collect();
22+
}
23+
24+
/// Remove last read line from output
25+
pub fn remove_line(&mut self) {
26+
self.lines = Vec::new();
27+
}
28+
}
29+
30+
#[cfg(test)]
31+
mod test {
32+
use super::Actions;
33+
#[test]
34+
fn test_replace() {
35+
let mut actions = Actions::new();
36+
37+
actions.next_input("lorem");
38+
actions.replace_with_lines("ipsum".split("\n"));
39+
assert_eq!(actions.take_lines(), vec!["ipsum"]);
40+
41+
actions.next_input("lorem ipsum dolor");
42+
actions.replace_with_lines("lorem ipsum dolor".split(" "));
43+
assert_eq!(actions.take_lines(), vec!["lorem", "ipsum", "dolor"]);
44+
45+
// assert last input is discarded
46+
assert_eq!(actions.take_lines(), Vec::<String>::new());
47+
}
48+
49+
#[test]
50+
fn test_remove() {
51+
let mut actions = Actions::new();
52+
actions.next_input("lorem");
53+
actions.remove_line();
54+
assert_eq!(actions.take_lines(), Vec::<String>::new());
55+
}
56+
57+
#[test]
58+
fn test_no_actions() {
59+
let mut actions = Actions::new();
60+
actions.next_input("lorem ipsum dolor");
61+
assert_eq!(actions.take_lines(), vec!["lorem ipsum dolor"]);
62+
}
63+
}

src/cmd/mod.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
//! Command execution and sandboxing.
22
3+
mod actions;
34
mod sandbox;
45

6+
pub use actions::Actions;
57
pub use sandbox::*;
68

79
use crate::native;
@@ -125,7 +127,7 @@ pub struct Command<'w, 'pl> {
125127
binary: Binary,
126128
args: Vec<OsString>,
127129
env: Vec<(OsString, OsString)>,
128-
process_lines: Option<&'pl mut dyn FnMut(&str)>,
130+
process_lines: Option<&'pl mut dyn FnMut(&str, &mut Actions)>,
129131
cd: Option<PathBuf>,
130132
timeout: Option<Duration>,
131133
no_output_timeout: Option<Duration>,
@@ -240,7 +242,7 @@ impl<'w, 'pl> Command<'w, 'pl> {
240242
/// let mut ice = false;
241243
/// Command::new(&workspace, "cargo")
242244
/// .args(&["build", "--all"])
243-
/// .process_lines(&mut |line| {
245+
/// .process_lines(&mut |line, _| {
244246
/// if line.contains("internal compiler error") {
245247
/// ice = true;
246248
/// }
@@ -249,7 +251,7 @@ impl<'w, 'pl> Command<'w, 'pl> {
249251
/// # Ok(())
250252
/// # }
251253
/// ```
252-
pub fn process_lines(mut self, f: &'pl mut dyn FnMut(&str)) -> Self {
254+
pub fn process_lines(mut self, f: &'pl mut dyn FnMut(&str, &mut Actions)) -> Self {
253255
self.process_lines = Some(f);
254256
self
255257
}
@@ -480,7 +482,7 @@ impl OutputKind {
480482

481483
fn log_command(
482484
mut cmd: StdCommand,
483-
mut process_lines: Option<&mut dyn FnMut(&str)>,
485+
mut process_lines: Option<&mut dyn FnMut(&str, &mut Actions)>,
484486
capture: bool,
485487
timeout: Option<Duration>,
486488
no_output_timeout: Option<Duration>,
@@ -512,6 +514,7 @@ fn log_command(
512514
.map(|line| (OutputKind::Stderr, line));
513515

514516
let start = Instant::now();
517+
let mut actions = Actions::new();
515518

516519
let output = stdout
517520
.select(stderr)
@@ -541,13 +544,15 @@ fn log_command(
541544
.fold(
542545
(Vec::new(), Vec::new()),
543546
move |mut res, (kind, line)| -> Result<_, Error> {
547+
actions.next_input(&line);
548+
544549
if let Some(f) = &mut process_lines {
545-
f(&line);
550+
f(&line, &mut actions);
546551
}
547552
if capture {
548553
match kind {
549-
OutputKind::Stdout => res.0.push(line),
550-
OutputKind::Stderr => res.1.push(line),
554+
OutputKind::Stdout => res.0.append(&mut actions.take_lines()),
555+
OutputKind::Stderr => res.1.append(&mut actions.take_lines()),
551556
}
552557
}
553558
Ok(res)

src/crates/git.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::CrateTrait;
2+
use crate::cmd::Actions;
23
use crate::cmd::Command;
34
use crate::prepare::PrepareError;
45
use crate::Workspace;
@@ -83,7 +84,7 @@ impl CrateTrait for GitRepo {
8384
// fata: credential helper '{path}' told us to quit
8485
//
8586
let mut private_repository = false;
86-
let mut detect_private_repositories = |line: &str| {
87+
let mut detect_private_repositories = |line: &str, _actions: &mut Actions| {
8788
if line.starts_with("fatal: credential helper") && line.ends_with("told us to quit") {
8889
private_repository = true;
8990
}

src/prepare.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ impl<'a> Prepare<'a> {
109109
}
110110
let res = cmd
111111
.cd(self.source_dir)
112-
.process_lines(&mut |line| {
112+
.process_lines(&mut |line, _| {
113113
if line.contains("failed to select a version for the requirement") {
114114
yanked_deps = true;
115115
}
@@ -130,7 +130,7 @@ impl<'a> Prepare<'a> {
130130
let res = Command::new(self.workspace, self.toolchain.cargo())
131131
.args(&["fetch", "--locked", "--manifest-path", "Cargo.toml"])
132132
.cd(&self.source_dir)
133-
.process_lines(&mut |line| {
133+
.process_lines(&mut |line, _| {
134134
if line.ends_with(
135135
"Cargo.lock needs to be updated but --locked was passed to prevent this",
136136
) {

src/toolchain.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ impl Toolchain {
324324
let result = Command::new(workspace, &RUSTUP)
325325
.args(&[thing.as_str(), "list", "--installed", "--toolchain", name])
326326
.log_output(false)
327-
.process_lines(&mut |line| {
327+
.process_lines(&mut |line, _| {
328328
if line.starts_with("error: toolchain ") && line.ends_with(" is not installed") {
329329
not_installed = true;
330330
}

0 commit comments

Comments
 (0)