1use std::path::PathBuf;
2
3use serde::Serialize;
4
5use crate::check::WorktreeSnapshot;
6use crate::context;
7use crate::{Config, IgnoredInitScript, InitScriptDiscovery, Result, Worktree, WorktreeOptions};
8
9#[derive(Debug, Clone, Default, PartialEq, Eq)]
11pub struct StatusOptions {
12 pub cwd: Option<PathBuf>,
14 pub root: Option<PathBuf>,
16 pub config: Option<PathBuf>,
18 pub no_init_script: bool,
20}
21
22#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
24#[serde(tag = "status", rename_all = "snake_case")]
25pub enum InitScriptStatus {
26 Skipped,
28 NotFound {
30 ignored: Vec<IgnoredInitScript>,
32 },
33 Found {
35 path: PathBuf,
37 },
38}
39
40#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct StatusReport {
43 pub context: Worktree,
45 pub init_script: InitScriptStatus,
47 pub config: Option<PathBuf>,
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
53pub struct StatusSnapshotReport {
54 pub context: WorktreeSnapshot,
56 pub init_script: InitScriptStatus,
58 pub config: Option<PathBuf>,
60}
61
62impl From<&StatusReport> for StatusSnapshotReport {
63 fn from(report: &StatusReport) -> Self {
64 Self {
65 context: WorktreeSnapshot::from(&report.context),
66 init_script: report.init_script.clone(),
67 config: report.config.clone(),
68 }
69 }
70}
71
72pub fn inspect_status(options: StatusOptions) -> Result<StatusReport> {
82 let context = context::resolve(&WorktreeOptions {
83 cwd: options.cwd,
84 root: options.root,
85 })?;
86 let init_script = if options.no_init_script || options.config.is_some() {
87 InitScriptStatus::Skipped
88 } else {
89 inspect_init_script(&context)
90 };
91 let config = Config::discover_path(&context, options.config.as_deref())?;
92
93 Ok(StatusReport {
94 context,
95 init_script,
96 config,
97 })
98}
99
100pub fn inspect_status_snapshot(options: StatusOptions) -> Result<StatusSnapshotReport> {
111 inspect_status(options).map(|report| StatusSnapshotReport::from(&report))
112}
113
114fn inspect_init_script(context: &Worktree) -> InitScriptStatus {
115 let scripts = InitScriptDiscovery::discover(context);
116
117 if let Some(path) = scripts.executable {
118 InitScriptStatus::Found { path }
119 } else {
120 InitScriptStatus::NotFound {
121 ignored: scripts.ignored,
122 }
123 }
124}