1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! # Host Environment Handler.
//!
//! This module handles command-not-found errors that occur while executing on the host OS.
//! Currently this means that the command is forwarded to a Toolbx container of choice, preferrably
//! one specified in the configuration file or the default one otherwise.
use crate::{config, error::CnfError};
use std::process::Command;
use which;

static TOOLBX_EXEC: &str = "toolbox";

/// Detect if the current execution environment is the host.
///
/// Currently returns true regardless due to the ordering in the main execution function.
pub fn detect() -> bool {
    true
}

/// Executes given command in a Toolbx container.
///
/// Takes as argument a slice of the command that wasn't found. The command is then forwarded to a
/// Toolbx container via `toolbox run`.
pub fn run(args: &[String]) -> Result<(), CnfError> {
    let toolbx =
        which::which(TOOLBX_EXEC).map_err(|_| CnfError::NotFound(TOOLBX_EXEC.to_string()))?;

    let cfg = config::get();

    // Assemble toolbx arguments
    let toolbx_name = cfg.toolbx_name;
    let mut envargs = vec!["run"];
    if !toolbx_name.is_empty() {
        envargs.push("-c");
        envargs.push(&toolbx_name);
    }
    for s in args {
        envargs.push(s.as_ref());
    }

    if cfg.verbose {
        println!("Args: {:?}", envargs);
        println!("Running command in toolbx {}", toolbx_name);
    }

    let status = Command::new(toolbx)
        .args(&envargs)
        .status()
        .map_err(CnfError::ApplicationError)?;
    if status.success() {
        Ok(())
    } else {
        Err(CnfError::Execution {
            env: "toolbx".to_string(),
            error: status,
        })
    }
}