Skip to main content

wrale_acdm/application/
status.rs

1// Copyright (c) 2025 Wrale LTD <contact@wrale.com>
2
3use anyhow::{Context, Result};
4use std::path::Path;
5
6use crate::application::dto::DependencyStatusDto;
7use crate::domain::repositories::ConfigurationRepository;
8use crate::domain::DomainError;
9
10/// Query for showing dependency status
11pub struct GetDependencyStatusQuery<C: ConfigurationRepository> {
12    config_repo: C,
13}
14
15impl<C: ConfigurationRepository> GetDependencyStatusQuery<C> {
16    pub fn new(config_repo: C) -> Self {
17        Self { config_repo }
18    }
19
20    /// Get the status of all dependencies
21    pub fn get_all_statuses(&self, config_path: &Path) -> Result<Vec<DependencyStatusDto>> {
22        // Convert the config_path to an absolute path if it's relative
23        let absolute_config_path = if config_path.is_absolute() {
24            config_path.to_path_buf()
25        } else {
26            // Join with current directory to get absolute path
27            std::env::current_dir()
28                .map_err(|e| {
29                    DomainError::ConfigurationError(format!(
30                        "Failed to get current directory: {}",
31                        e
32                    ))
33                })?
34                .join(config_path)
35        };
36
37        // Load the configuration
38        let config = self
39            .config_repo
40            .load(&absolute_config_path)
41            .context("Failed to load configuration")?;
42
43        // Get the repository root - if we have a parent directory, use it, otherwise use the current directory
44        let repo_root = if let Some(parent) = absolute_config_path.parent() {
45            parent.to_path_buf()
46        } else {
47            // This should rarely happen with absolute paths, but handle it anyway
48            std::env::current_dir().map_err(|e| {
49                DomainError::ConfigurationError(format!("Failed to get current directory: {}", e))
50            })?
51        };
52
53        // Create status DTOs for each dependency
54        let mut statuses = Vec::new();
55
56        for dep in &config.dependencies {
57            // Determine the absolute target path
58            let target_path = repo_root.join(&dep.target_location);
59
60            // Determine status
61            let status = if !target_path.exists() {
62                "Not fetched".to_string()
63            } else {
64                "Fetched".to_string()
65            };
66
67            // Create the DTO
68            let dto = DependencyStatusDto {
69                name: dep.name.clone(),
70                repository_url: dep.repository_url.clone(),
71                revision: dep.revision.clone(),
72                target_location: dep.target_location.to_string_lossy().to_string(),
73                sparse_paths: dep.sparse_paths.clone(),
74                status,
75            };
76
77            statuses.push(dto);
78        }
79
80        Ok(statuses)
81    }
82}