Skip to main content

treeboot_core/
status.rs

1use std::path::PathBuf;
2
3use crate::context;
4use crate::{Config, InitScriptDiscovery, Result, Worktree, WorktreeOptions};
5
6/// Options for inspecting treeboot discovery status.
7#[derive(Debug, Clone, Default, PartialEq, Eq)]
8pub struct StatusOptions {
9    /// Directory from which status discovery starts.
10    pub cwd: Option<PathBuf>,
11    /// Overrides the root checkout used for discovery.
12    pub root: Option<PathBuf>,
13    /// Uses one specific config file instead of config discovery.
14    pub config: Option<PathBuf>,
15    /// Skips init script discovery.
16    pub no_init_script: bool,
17}
18
19/// Init script discovery status for a worktree.
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub enum InitScriptStatus {
22    /// Init script discovery was skipped by options.
23    Skipped,
24    /// No executable init script was found.
25    Missing {
26        /// Existing init script paths ignored because they are not executable.
27        ignored: Vec<PathBuf>,
28    },
29    /// An executable init script was found.
30    Found {
31        /// Init script path.
32        path: PathBuf,
33    },
34}
35
36/// Result summary for a `treeboot status` invocation.
37#[derive(Debug, Clone, PartialEq, Eq)]
38pub struct StatusReport {
39    /// Runtime context discovered for the current worktree.
40    pub context: Worktree,
41    /// Init script discovery result.
42    pub init_script: InitScriptStatus,
43    /// Selected config path, when one was requested or discovered.
44    pub config: Option<PathBuf>,
45}
46
47/// Inspects worktree, root, init script, and config discovery status.
48///
49/// This function does not execute init scripts, parse config, or run configured
50/// commands.
51///
52/// # Errors
53///
54/// Returns an error if context discovery fails or a requested config file does
55/// not exist.
56pub fn inspect_status(options: StatusOptions) -> Result<StatusReport> {
57    let context = context::resolve(&WorktreeOptions {
58        cwd: options.cwd,
59        root: options.root,
60    })?;
61    let init_script = if options.no_init_script || options.config.is_some() {
62        InitScriptStatus::Skipped
63    } else {
64        inspect_init_script(&context)
65    };
66    let config = Config::discover_path(&context, options.config.as_deref())?;
67
68    Ok(StatusReport {
69        context,
70        init_script,
71        config,
72    })
73}
74
75fn inspect_init_script(context: &Worktree) -> InitScriptStatus {
76    let scripts = InitScriptDiscovery::discover(context);
77
78    if let Some(path) = scripts.executable {
79        InitScriptStatus::Found { path }
80    } else {
81        InitScriptStatus::Missing {
82            ignored: scripts.ignored,
83        }
84    }
85}