hammer_cli/
tasks.rs

1use colored::Colorize;
2use std::collections::HashMap;
3use std::io::Write;
4use std::io::{BufRead, BufReader};
5use std::path::Path;
6use std::process::{Command, Stdio};
7use std::{env, io};
8
9use crate::errors::BeautifulErrors;
10use crate::npm_process::NpmProcessContext;
11
12fn handle_process_stdout(process_name: &String, msg: &str) {
13    if msg.len() > 0 {
14        print!("{}: {}", process_name.blue().bold(), msg);
15        io::stdout().flush().expect("Could not flush stdout");
16    }
17}
18
19pub fn start_npm_process(context: NpmProcessContext) {
20    let path = Path::new(&context.dir);
21    let mut root_env: HashMap<String, String> = env::vars().collect();
22
23    if let Some(envs) = context.args.env {
24        envs.iter().for_each(|var| {
25            let key_value: Vec<&str> = var.split(":").collect();
26            let key = key_value.get(0).expect_or_err(
27                &format!("Invalid environment variable provided: {} - Usage: hammer dev -e node_env:development", var)
28            );
29
30            let val = key_value.get(1).expect_or_err(
31                &format!("Invalid environment variable provided: {} - Usage: hammer dev -e node_env:development", var)
32            );
33
34            root_env.insert(key.to_string(), val.to_string());
35        });
36    }
37    let mut child = Command::new("npm")
38        .current_dir(path)
39        .envs(&root_env)
40        .arg("run")
41        .arg(context.args.script)
42        .stdout(Stdio::piped())
43        .spawn()
44        .expect(&format!(
45            "Could not start child process on directory {}",
46            path.display()
47        ));
48
49    tokio::spawn(async move {
50        let mut f = BufReader::new(
51            child
52                .stdout
53                .take()
54                .expect("Could not retrieve child std output"),
55        );
56        loop {
57            let mut buf = String::new();
58            match f.read_line(&mut buf) {
59                Ok(_) => {
60                    handle_process_stdout(&context.name, buf.as_str());
61                }
62                Err(e) => println!("child err: {:?}", e),
63            }
64            if let Ok(status) = child.try_wait() {
65                if let Some(_status) = status {
66                    break;
67                }
68            }
69        }
70    });
71}