Skip to content

Commit 49b5b92

Browse files
committed
add actions on process_lines
1 parent 0d3c2f6 commit 49b5b92

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
}
@@ -475,7 +477,7 @@ impl OutputKind {
475477

476478
fn log_command(
477479
mut cmd: StdCommand,
478-
mut process_lines: Option<&mut dyn FnMut(&str)>,
480+
mut process_lines: Option<&mut dyn FnMut(&str, &mut Actions)>,
479481
capture: bool,
480482
timeout: Option<Duration>,
481483
no_output_timeout: Option<Duration>,
@@ -507,6 +509,7 @@ fn log_command(
507509
.map(|line| (OutputKind::Stderr, line));
508510

509511
let start = Instant::now();
512+
let mut actions = Actions::new();
510513

511514
let output = stdout
512515
.select(stderr)
@@ -536,13 +539,15 @@ fn log_command(
536539
.fold(
537540
(Vec::new(), Vec::new()),
538541
move |mut res, (kind, line)| -> Result<_, Error> {
542+
actions.next_input(&line);
543+
539544
if let Some(f) = &mut process_lines {
540-
f(&line);
545+
f(&line, &mut actions);
541546
}
542547
if capture {
543548
match kind {
544-
OutputKind::Stdout => res.0.push(line),
545-
OutputKind::Stderr => res.1.push(line),
549+
OutputKind::Stdout => res.0.append(&mut actions.take_lines()),
550+
OutputKind::Stderr => res.1.append(&mut actions.take_lines()),
546551
}
547552
}
548553
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
@@ -98,7 +98,7 @@ impl<'a> Prepare<'a> {
9898
}
9999
let res = cmd
100100
.cd(self.source_dir)
101-
.process_lines(&mut |line| {
101+
.process_lines(&mut |line, _| {
102102
if line.contains("failed to select a version for the requirement") {
103103
yanked_deps = true;
104104
}
@@ -119,7 +119,7 @@ impl<'a> Prepare<'a> {
119119
let res = Command::new(self.workspace, self.toolchain.cargo())
120120
.args(&["fetch", "--locked", "--manifest-path", "Cargo.toml"])
121121
.cd(&self.source_dir)
122-
.process_lines(&mut |line| {
122+
.process_lines(&mut |line, _| {
123123
if line.ends_with(
124124
"Cargo.lock needs to be updated but --locked was passed to prevent this",
125125
) {

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)