1use std::collections::HashMap;
2use std::process::Command;
3
4use crate::error::{AuthyError, Result};
5
6#[derive(Debug, Clone, Default)]
8pub struct NamingOptions {
9 pub uppercase: bool,
10 pub replace_dash: Option<char>,
11 pub prefix: Option<String>,
12}
13
14pub fn transform_name(name: &str, opts: &NamingOptions) -> String {
16 let mut result = name.to_string();
17
18 if let Some(replacement) = opts.replace_dash {
19 result = result.replace('-', &replacement.to_string());
20 }
21
22 if opts.uppercase {
23 result = result.to_uppercase();
24 }
25
26 if let Some(ref prefix) = opts.prefix {
27 result = format!("{}{}", prefix, result);
28 }
29
30 result
31}
32
33pub fn run_with_secrets(
36 command: &[String],
37 secrets: &HashMap<String, String>,
38 naming: &NamingOptions,
39) -> Result<i32> {
40 if command.is_empty() {
41 return Err(AuthyError::Other("No command specified".into()));
42 }
43
44 let env_vars: HashMap<String, String> = secrets
45 .iter()
46 .map(|(name, value)| (transform_name(name, naming), value.clone()))
47 .collect();
48
49 let status = Command::new(&command[0])
50 .args(&command[1..])
51 .envs(&env_vars)
52 .env_remove("AUTHY_PASSPHRASE")
53 .env_remove("AUTHY_TOKEN")
54 .status()
55 .map_err(|e| AuthyError::Other(format!("Failed to run command '{}': {}", command[0], e)))?;
56
57 Ok(status.code().unwrap_or(1))
58}