tog/commands/run/handlers/
output.rs

1use crate::profile::Profile;
2use crate::commands::run::handlers::monitor;
3use crate::commands::run::processes::stream_read::{PipeStreamReader, PipedLine};
4use crate::commands::run::processes::Process;
5use crate::util::log;
6use crossbeam_channel::Select;
7use std::collections::HashMap;
8
9pub fn handle_output(profile: &Profile, mut proc: Process) {
10    let mut channels: Vec<PipeStreamReader> = Vec::new();
11    channels.push(PipeStreamReader::new(Box::new(
12        proc.child.stdout.take().expect("!stdout"),
13    )));
14    channels.push(PipeStreamReader::new(Box::new(
15        proc.child.stderr.take().expect("!stderr"),
16    )));
17
18    let mut select = Select::new();
19    for channel in channels.iter() {
20        select.recv(&channel.lines);
21    }
22
23    let mut stream_eof = false;
24
25    while !stream_eof {
26        let operation = select.select();
27        let index = operation.index();
28        let received = operation.recv(&channels.get(index).expect("!channel").lines);
29
30        match received {
31            Ok(remote_result) => match remote_result {
32                Ok(piped_line) => match piped_line {
33                    PipedLine::Line(line) => {
34                        handle_output_line(&profile, &mut proc, line);
35                    }
36                    PipedLine::EOF => {
37                        stream_eof = true;
38                        select.remove(index);
39                    }
40                },
41                Err(error) => log::error(&format!("{:?}", error)),
42            },
43            Err(_) => {
44                stream_eof = true;
45                select.remove(index);
46            }
47        }
48    }
49
50    let status = proc.child.wait().expect("!wait");
51    if status.success() {
52        let annotated_message = &format!("[{}] exited with success.", proc.name);
53        log::logger(annotated_message);
54    } else {
55        let annotated_message = &format!("[{}] exited with failure.", proc.name);
56        log::logger(annotated_message);
57    }
58}
59
60pub fn handle_output_line(profile: &Profile, proc: &mut Process, line: String) {
61    let mut log_data = log::LogData {
62        message: &line,
63        snippets: HashMap::new(),
64    };
65
66    monitor::handle_monitor(profile, proc, &mut log_data);
67}