nci/
config.rs

1use crate::{
2    agents::Agent,
3    detect::{detect, AGENT_MAP},
4    runner::DetectOptions,
5};
6use dirs::home_dir;
7use ini::Ini;
8use std::{
9    env,
10    path::{Path, PathBuf},
11};
12
13#[derive(PartialEq, Clone, Debug, Eq, Hash)]
14pub enum DefaultAgent {
15    Prompt,
16    Agent(Agent),
17}
18
19pub struct Config {
20    default_agent: DefaultAgent,
21    global_agent: Agent,
22}
23
24impl Default for Config {
25    fn default() -> Self {
26        Config {
27            default_agent: DefaultAgent::Prompt,
28            global_agent: Agent::Npm,
29        }
30    }
31}
32
33impl Config {
34    pub fn assign(&self) -> Self {
35        let home = home_dir().unwrap_or(PathBuf::from("~/"));
36        let custom_rc_path = env::var("NI_CONFIG_FILE");
37        let default_rc_path = home.join(".nirc");
38        let rc_path = if let Ok(custom_rc_path) = custom_rc_path {
39            custom_rc_path
40        } else {
41            default_rc_path.to_string_lossy().to_string()
42        };
43
44        let mut config = Self::default();
45
46        if Path::new(&rc_path).exists() {
47            let conf = Ini::load_from_file(&rc_path).unwrap();
48            let section = conf.section(None::<String>).unwrap();
49            let default_agent = section.get("default_agent");
50            let global_agent = section.get("global_agent");
51            if let Some(default_agent) = default_agent {
52                let default_agent = AGENT_MAP.get(default_agent);
53                if let Some(default_agent) = default_agent {
54                    config.default_agent = DefaultAgent::Agent(default_agent.clone());
55                }
56            }
57            if let Some(global_agent) = global_agent {
58                let global_agent = AGENT_MAP.get(global_agent);
59                if let Some(global_agent) = global_agent {
60                    config.global_agent = global_agent.clone();
61                }
62            }
63        }
64
65        config
66    }
67}
68
69pub fn get_config() -> Config {
70    let mut config = Config::default().assign();
71    let mut options = DetectOptions::default();
72    options.programmatic = true;
73    let agent = detect(options);
74    if let Some(agent) = agent {
75        config.default_agent = DefaultAgent::Agent(agent);
76    }
77    config
78}
79
80pub fn get_default_agent(programmatic: bool) -> DefaultAgent {
81    let Config { default_agent, .. } = get_config();
82    let ci = env::var("CI");
83
84    if default_agent == DefaultAgent::Prompt && (programmatic == true || ci.is_ok()) {
85        return DefaultAgent::Agent(Agent::Npm);
86    }
87    default_agent
88}
89
90pub fn get_global_agent() -> Agent {
91    let Config { global_agent, .. } = get_config();
92    global_agent
93}