zoi/project/
runner.rs

1use super::{config, executor};
2use crate::utils;
3use anyhow::{Result, anyhow};
4use colored::*;
5use dialoguer::{Select, theme::ColorfulTheme};
6
7pub fn run(cmd_alias: Option<&str>, args: &[String], config: &config::ProjectConfig) -> Result<()> {
8    if config.commands.is_empty() {
9        return Err(anyhow!("No commands defined in zoi.yaml"));
10    }
11
12    let command_to_run = match cmd_alias {
13        Some(alias) => config
14            .commands
15            .iter()
16            .find(|c| c.cmd == alias)
17            .ok_or_else(|| anyhow!("Command alias '{}' not found in zoi.yaml", alias))?
18            .clone(),
19        None => {
20            if !args.is_empty() {
21                return Err(anyhow!("Cannot pass arguments when in interactive mode."));
22            }
23            let selections: Vec<&str> = config.commands.iter().map(|c| c.cmd.as_str()).collect();
24            let selection = Select::with_theme(&ColorfulTheme::default())
25                .with_prompt("Choose a command to run")
26                .items(&selections)
27                .default(0)
28                .interact_opt()?
29                .ok_or(anyhow!("No command chosen."))?;
30
31            config.commands[selection].clone()
32        }
33    };
34
35    let platform = utils::get_platform()?;
36
37    let run_cmd = match &command_to_run.run {
38        config::PlatformOrString::String(s) => s.clone(),
39        config::PlatformOrString::Platform(p) => p
40            .get(&platform)
41            .or_else(|| p.get("default"))
42            .cloned()
43            .ok_or_else(|| {
44                anyhow!(
45                    "No command found for platform '{}' and no default specified",
46                    platform
47                )
48            })?,
49    };
50
51    let env_vars = match &command_to_run.env {
52        config::PlatformOrEnvMap::EnvMap(m) => m.clone(),
53        config::PlatformOrEnvMap::Platform(p) => p
54            .get(&platform)
55            .or_else(|| p.get("default"))
56            .cloned()
57            .unwrap_or_default(),
58    };
59
60    println!("--- Running command: {} ---", command_to_run.cmd.bold());
61    let mut full_command = run_cmd;
62    if !args.is_empty() {
63        full_command.push(' ');
64        full_command.push_str(&args.join(" "));
65    }
66    executor::run_shell_command(&full_command, &env_vars)
67}