nu_test_support/playground/
nu_process.rs

1use super::EnvironmentVariable;
2use crate::fs::{binaries as test_bins_path, executable_path};
3use std::{
4    ffi::{OsStr, OsString},
5    fmt,
6    process::{Command, ExitStatus},
7};
8
9pub trait Executable {
10    fn execute(&mut self) -> Result<Outcome, NuError>;
11}
12
13#[derive(Clone, Debug)]
14pub struct Outcome {
15    pub out: Vec<u8>,
16    pub err: Vec<u8>,
17}
18
19impl Outcome {
20    pub fn new(out: &[u8], err: &[u8]) -> Outcome {
21        Outcome {
22            out: out.to_vec(),
23            err: err.to_vec(),
24        }
25    }
26}
27
28#[derive(Debug)]
29pub struct NuError {
30    pub desc: String,
31    pub exit: Option<ExitStatus>,
32    pub output: Option<Outcome>,
33}
34
35#[derive(Clone, Debug, Default)]
36pub struct NuProcess {
37    pub arguments: Vec<OsString>,
38    pub environment_vars: Vec<EnvironmentVariable>,
39    pub cwd: Option<OsString>,
40}
41
42impl fmt::Display for NuProcess {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        write!(f, "`nu")?;
45
46        for arg in &self.arguments {
47            write!(f, " {}", arg.to_string_lossy())?;
48        }
49
50        write!(f, "`")
51    }
52}
53
54impl NuProcess {
55    pub fn arg<T: AsRef<OsStr>>(&mut self, arg: T) -> &mut Self {
56        self.arguments.push(arg.as_ref().to_os_string());
57        self
58    }
59
60    pub fn args<T: AsRef<OsStr>>(&mut self, arguments: &[T]) -> &mut NuProcess {
61        self.arguments
62            .extend(arguments.iter().map(|t| t.as_ref().to_os_string()));
63        self
64    }
65
66    pub fn cwd<T: AsRef<OsStr>>(&mut self, path: T) -> &mut NuProcess {
67        self.cwd = Some(path.as_ref().to_os_string());
68        self
69    }
70
71    pub fn construct(&self) -> Command {
72        let mut command = Command::new(executable_path());
73
74        if let Some(cwd) = &self.cwd {
75            command.current_dir(cwd);
76        }
77
78        command.env_clear();
79
80        let paths = [test_bins_path()];
81
82        let paths_joined = match std::env::join_paths(paths) {
83            Ok(all) => all,
84            Err(_) => panic!("Couldn't join paths for PATH var."),
85        };
86
87        command.env(crate::NATIVE_PATH_ENV_VAR, paths_joined);
88
89        for env_var in &self.environment_vars {
90            command.env(&env_var.name, &env_var.value);
91        }
92
93        for arg in &self.arguments {
94            command.arg(arg);
95        }
96
97        command
98    }
99}