Skip to main content

torrust_tracker_deployer_lib/application/services/rendering/
tracker.rs

1//! Tracker Template Rendering Service
2//!
3//! This service is responsible for rendering Tracker configuration templates.
4//! It's used by multiple contexts (render command, release steps) to prepare
5//! tracker.toml configuration files.
6
7use std::path::PathBuf;
8use std::sync::Arc;
9
10use thiserror::Error;
11use tracing::info;
12
13use crate::domain::template::TemplateManager;
14use crate::domain::tracker::TrackerConfig;
15use crate::infrastructure::templating::tracker::{
16    TrackerProjectGenerator, TrackerProjectGeneratorError,
17};
18use crate::shared::Clock;
19
20/// Errors that can occur during Tracker template rendering
21#[derive(Error, Debug)]
22pub enum TrackerTemplateRenderingServiceError {
23    /// Template rendering failed
24    #[error("Failed to render Tracker templates: {reason}")]
25    RenderingFailed {
26        /// Detailed reason for the failure
27        reason: String,
28    },
29}
30
31impl From<TrackerProjectGeneratorError> for TrackerTemplateRenderingServiceError {
32    fn from(error: TrackerProjectGeneratorError) -> Self {
33        Self::RenderingFailed {
34            reason: error.to_string(),
35        }
36    }
37}
38
39/// Service for rendering Tracker configuration templates
40///
41/// This service encapsulates the logic for rendering tracker.toml configuration
42/// files. It's designed to be shared across command handlers and steps that need
43/// to prepare Tracker configuration.
44pub struct TrackerTemplateRenderingService {
45    build_dir: PathBuf,
46    template_manager: Arc<TemplateManager>,
47    clock: Arc<dyn Clock>,
48}
49
50impl TrackerTemplateRenderingService {
51    /// Build a `TrackerTemplateRenderingService` from environment paths
52    ///
53    /// # Arguments
54    ///
55    /// * `templates_dir` - Directory containing the source templates
56    /// * `build_dir` - Directory where rendered templates will be written
57    /// * `clock` - The clock for generating timestamps
58    ///
59    /// # Returns
60    ///
61    /// Returns a configured `TrackerTemplateRenderingService` ready for template rendering
62    #[must_use]
63    pub fn from_paths(templates_dir: PathBuf, build_dir: PathBuf, clock: Arc<dyn Clock>) -> Self {
64        let template_manager = Arc::new(TemplateManager::new(templates_dir));
65
66        Self {
67            build_dir,
68            template_manager,
69            clock,
70        }
71    }
72
73    /// Render Tracker configuration templates
74    ///
75    /// This renders the tracker.toml configuration file to the build directory.
76    ///
77    /// # Arguments
78    ///
79    /// * `tracker_config` - Tracker configuration from user inputs
80    ///
81    /// # Returns
82    ///
83    /// Returns the path to the rendered tracker build directory
84    ///
85    /// # Errors
86    ///
87    /// Returns `TrackerTemplateRenderingServiceError::RenderingFailed` if template rendering fails.
88    pub fn render(
89        &self,
90        tracker_config: &TrackerConfig,
91    ) -> Result<PathBuf, TrackerTemplateRenderingServiceError> {
92        info!(
93            templates_dir = %self.template_manager.templates_dir().display(),
94            build_dir = %self.build_dir.display(),
95            "Rendering Tracker configuration templates"
96        );
97
98        let generator = TrackerProjectGenerator::new(
99            &self.build_dir,
100            self.template_manager.clone(),
101            self.clock.clone(),
102        );
103
104        generator.render(Some(tracker_config))?;
105
106        let tracker_build_dir = self.build_dir.join("tracker");
107
108        info!(
109            tracker_build_dir = %tracker_build_dir.display(),
110            "Tracker configuration templates rendered successfully"
111        );
112
113        Ok(tracker_build_dir)
114    }
115}