core_lib/cli/
builders.rs

1use std::path::Path;
2
3use anyhow::{Ok, Result};
4
5use crate::{
6    cli::{Cli, Commands, client::send_watch_request, stats::interface::display_stats_interface},
7    config::parser::load_config,
8    daemon::server::DaemonRequest,
9    git::{remote::branch_wildcard, repo::Repo},
10};
11
12/// Handles watch-related CLI commands by delegating to subfunctions
13/// that build the appropriate [`DaemonRequest`].
14pub async fn handle_watch(cli: &Cli) -> Result<()> {
15    let watch_req = build_watch_request(cli).await?;
16    send_watch_request(watch_req).await?;
17    Ok(())
18}
19
20/// Builds the appropriate [`DaemonRequest`] for the given CLI command.
21pub async fn build_watch_request(cli: &Cli) -> Result<DaemonRequest> {
22    match &cli.command {
23        Commands::Watch => build_add_watch_request(),
24        Commands::Ps { all } => Ok(DaemonRequest::ListWatches { all: *all }),
25        Commands::Logs { id_or_name, follow } => build_logs_request(id_or_name, *follow),
26        Commands::Stop { id } => Ok(DaemonRequest::StopWatch { id: id.to_string() }),
27        Commands::Up { id } => Ok(DaemonRequest::UpWatch { id: id.to_string() }),
28        Commands::Rm { id } => Ok(DaemonRequest::RmWatch { id: id.to_string() }),
29        Commands::Stats => {
30            display_stats_interface().await?;
31            Ok(DaemonRequest::None)
32        }
33        Commands::Run { id } => Ok(DaemonRequest::RunPipeline { id: id.clone() }),
34    }
35}
36
37/// Builds an [`AddWatch`] request after validating configuration.
38fn build_add_watch_request() -> Result<DaemonRequest> {
39    let config_path = Path::new("./fleet.yml");
40    if !config_path.exists() {
41        return Err(anyhow::anyhow!(
42            "File `fleet.yml` missing from current directory."
43        ));
44    }
45
46    let config = load_config(config_path)?;
47
48    let (branches, b_name) = if config.branches[0] == "*" {
49        (branch_wildcard()?, "*".to_string()) // if is wildcard branch we use '*' as branch name
50    } else {
51        // else if is one or more branch we use the last branch name
52        // e.g: ["main", "test", "abc"] -> b_name will be "abc"
53        (
54            config.branches.clone(),
55            config
56                .branches
57                .last()
58                .ok_or_else(|| anyhow::anyhow!("No branch defined in fleet.yml"))?
59                .clone(),
60        )
61    };
62
63    let mut repo = Repo::build(branches.clone())?;
64
65    repo.branches.name = b_name; //  asigne default name
66    repo.branches.last_commit = repo.branches.default_last_commit()?;
67    println!("debug: repo branches: {:#?}", repo.branches);
68
69    Ok(DaemonRequest::AddWatch {
70        project_dir: std::env::current_dir()?.to_string_lossy().into_owned(),
71        repo: Box::new(repo),
72        config: Box::new(config),
73    })
74}
75
76/// Builds a [`LogsWatches`] request from CLI or repository defaults.
77fn build_logs_request(id_or_name: &Option<String>, follow: bool) -> Result<DaemonRequest> {
78    match id_or_name {
79        Some(s) => Ok(DaemonRequest::LogsWatches {
80            id: s.to_string(),
81            f: follow,
82        }),
83        None => {
84            let repo = Repo::default_build()?;
85            Ok(DaemonRequest::LogsWatches {
86                id: repo.name,
87                f: follow,
88            })
89        }
90    }
91}