Skip to main content

harmont_cli/
context.rs

1use std::io::IsTerminal;
2
3use anyhow::{Context, Result};
4
5use crate::cli::Cli;
6use crate::config::Config;
7use hm_render::OutputMode;
8
9/// Runtime context that bundles resolved config and output preferences.
10///
11/// After the plan-4 cloud-plugin cutover this is intentionally thin:
12/// API client, credential store, and active-org resolution moved into
13/// `hm-plugin-cloud`. The host context retains the config file (for
14/// future use) and the output mode.
15#[derive(Debug)]
16pub struct RunContext {
17    pub config: Config,
18    /// Output mode for the residual built-in verbs (the legacy global
19    /// `--format` flag was retired in plan 3; per-subcommand `--format`
20    /// is the only currently-wired source, so this defaults to human).
21    pub output: OutputMode,
22}
23
24impl RunContext {
25    /// Build a [`RunContext`] from parsed CLI args.
26    ///
27    /// # Errors
28    ///
29    /// Returns an error if the config file is unreadable or malformed.
30    pub fn from_cli(cli: &Cli) -> Result<Self> {
31        let start_dir = std::env::current_dir().context("cannot determine current directory")?;
32        let project_root = hm_util::dirs::find_project_root(&start_dir);
33        let config = Config::load(project_root.as_deref())?;
34
35        let output = OutputMode::Human {
36            // Single source of truth for the color/TTY rule (still honors --no-color).
37            color: hm_render::color_enabled(cli.no_color),
38            // Interactive prompts/spinners key off stdout being a TTY.
39            interactive: std::io::stdout().is_terminal(),
40        };
41
42        Ok(Self { config, output })
43    }
44}