Skip to content

Commit c96bdd0

Browse files
EverlastingBugstoppertrevorbladessachindshindejwangnzpatrick91
authored andcommitted
Merge branch 'main' into camille/update-format-option (#1403)
Co-authored-by: Trevor Blades <[email protected]> Co-authored-by: Sachin D. Shinde <[email protected]> Co-authored-by: Jesse Wang <[email protected]> Co-authored-by: Patrick Arminio <[email protected]> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
1 parent 7db960e commit c96bdd0

File tree

5 files changed

+106
-10
lines changed

5 files changed

+106
-10
lines changed

src/cli.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,14 @@ pub struct Rover {
6161
#[serde(serialize_with = "option_from_display")]
6262
log_level: Option<Level>,
6363

64-
/// Specify Rover's output type
65-
#[arg(long = "output", default_value = "plain", global = true)]
66-
output_type: OutputType,
67-
68-
#[clap(long = "format", default_value = "plain", global = true)]
64+
/// Specify Rover's format type
65+
#[arg(long = "format", default_value = "plain", global = true)]
6966
format_type: FormatType,
7067

68+
/// Specify a file to write Rover's output to
69+
#[arg(long = "output", global = true)]
70+
output_type: OutputType,
71+
7172
/// Accept invalid certificates when performing HTTPS requests.
7273
///
7374
/// You should think very carefully before using this flag.

src/command/dev/command.rs

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
use std::{
2+
io::{BufRead, BufReader},
3+
process::{Child, Command, Stdio},
4+
};
5+
6+
use anyhow::{anyhow, Context};
7+
use crossbeam_channel::Sender;
8+
9+
use crate::{command::dev::do_dev::log_err_and_continue, RoverError, RoverResult};
10+
11+
#[derive(Debug)]
12+
pub struct BackgroundTask {
13+
child: Child,
14+
}
15+
16+
pub enum BackgroundTaskLog {
17+
Stdout(String),
18+
Stderr(String),
19+
}
20+
21+
impl BackgroundTask {
22+
pub fn new(command: String, log_sender: Sender<BackgroundTaskLog>) -> RoverResult<Self> {
23+
let args: Vec<&str> = command.split(' ').collect();
24+
let (bin, args) = match args.len() {
25+
0 => Err(anyhow!("the command you passed is empty")),
26+
1 => Ok((args[0], Vec::new())),
27+
_ => Ok((args[0], Vec::from_iter(args[1..].iter()))),
28+
}?;
29+
tracing::info!("starting `{}`", &command);
30+
if which::which(bin).is_err() {
31+
return Err(anyhow!("{} is not installed on this machine", &bin).into());
32+
}
33+
34+
let mut command = Command::new(bin);
35+
command.args(args).env("APOLLO_ROVER", "true");
36+
37+
command.stdout(Stdio::piped()).stderr(Stdio::piped());
38+
39+
let mut child = command
40+
.spawn()
41+
.with_context(|| "could not spawn child process")?;
42+
43+
if let Some(stdout) = child.stdout.take() {
44+
let log_sender = log_sender.clone();
45+
rayon::spawn(move || {
46+
let stdout = BufReader::new(stdout);
47+
stdout.lines().for_each(|line| {
48+
if let Ok(line) = line {
49+
log_sender
50+
.send(BackgroundTaskLog::Stdout(line))
51+
.expect("could not update stdout logs for command");
52+
}
53+
});
54+
});
55+
}
56+
57+
if let Some(stderr) = child.stderr.take() {
58+
rayon::spawn(move || {
59+
let stderr = BufReader::new(stderr);
60+
stderr.lines().for_each(|line| {
61+
if let Ok(line) = line {
62+
log_sender
63+
.send(BackgroundTaskLog::Stderr(line))
64+
.expect("could not update stderr logs for command");
65+
}
66+
});
67+
});
68+
}
69+
70+
Ok(Self { child })
71+
}
72+
73+
pub fn kill(&mut self) {
74+
let pid = self.id();
75+
tracing::info!("killing child with pid {}", &pid);
76+
let _ = self.child.kill().map_err(|_| {
77+
log_err_and_continue(RoverError::new(anyhow!(
78+
"could not kill child with pid {}",
79+
&pid
80+
)));
81+
});
82+
}
83+
84+
pub fn id(&self) -> u32 {
85+
self.child.id()
86+
}
87+
}
88+
89+
impl Drop for BackgroundTask {
90+
fn drop(&mut self) {
91+
self.kill()
92+
}
93+
}

src/options/output.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use std::str::FromStr;
22

3-
use saucer::{clap, Parser, Utf8PathBuf};
3+
use camino::Utf8PathBuf;
4+
use clap::Parser;
45

5-
use crate::{cli::FormatType};
6+
use crate::cli::FormatType;
67

78
#[derive(Debug, Parser)]
89
pub struct Output {
@@ -18,7 +19,7 @@ pub enum OutputType {
1819
}
1920

2021
impl FromStr for OutputType {
21-
type Err = saucer::Error;
22+
type Err = anyhow::Error;
2223

2324
fn from_str(s: &str) -> Result<Self, Self::Err> {
2425
if let Ok(format_type) = FormatType::from_str(s) {

xtask/src/tools/cargo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use camino::Utf8PathBuf;
44
use crate::commands::version::RoverVersion;
55
use crate::target::Target;
66
use crate::tools::{GitRunner, Runner};
7-
use crate::utils::{CommandOutput, PKG_PROJECT_ROOT};
7+
use crate::utils::{self, CommandOutput, PKG_PROJECT_ROOT};
88

99
use std::fs;
1010

xtask/src/tools/runner.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
use anyhow::{anyhow, Context, Result};
12
use camino::Utf8PathBuf;
23
use shell_candy::{ShellTask, ShellTaskBehavior, ShellTaskLog, ShellTaskOutput};
3-
44
use std::collections::HashMap;
5+
use which::which;
56

67
use crate::{utils::CommandOutput, Result};
78

0 commit comments

Comments
 (0)