Skip to main content

dodot_lib/handlers/
shell.rs

1//! Shell handler — stages shell scripts for sourcing via dodot-init.sh.
2
3use std::path::Path;
4
5use crate::datastore::DataStore;
6use crate::fs::Fs;
7use crate::handlers::{ExecutionPhase, Handler, HandlerConfig, HandlerStatus, HANDLER_SHELL};
8use crate::operations::HandlerIntent;
9use crate::paths::Pather;
10use crate::rules::RuleMatch;
11use crate::Result;
12
13pub struct ShellHandler;
14
15impl Handler for ShellHandler {
16    fn name(&self) -> &str {
17        HANDLER_SHELL
18    }
19
20    fn phase(&self) -> ExecutionPhase {
21        ExecutionPhase::ShellInit
22    }
23
24    fn to_intents(
25        &self,
26        matches: &[RuleMatch],
27        _config: &HandlerConfig,
28        _paths: &dyn Pather,
29        _fs: &dyn Fs,
30    ) -> Result<Vec<HandlerIntent>> {
31        Ok(matches
32            .iter()
33            .filter(|m| !m.is_dir)
34            .map(|m| HandlerIntent::Stage {
35                pack: m.pack.clone(),
36                handler: HANDLER_SHELL.into(),
37                source: m.absolute_path.clone(),
38            })
39            .collect())
40    }
41
42    fn check_status(
43        &self,
44        file: &Path,
45        pack: &str,
46        datastore: &dyn DataStore,
47    ) -> Result<HandlerStatus> {
48        let has_state = datastore.has_handler_state(pack, HANDLER_SHELL)?;
49        Ok(HandlerStatus {
50            file: file.to_string_lossy().into_owned(),
51            handler: HANDLER_SHELL.into(),
52            deployed: has_state,
53            message: if has_state {
54                "sourced in shell".into()
55            } else {
56                "not sourced in shell".into()
57            },
58        })
59    }
60}