sps_common/
pipeline.rs

1// sps-common/src/pipeline.rs
2use std::path::PathBuf;
3use std::sync::Arc; // Required for Arc<SpsError> in JobProcessingState
4
5use serde::{Deserialize, Serialize};
6
7use crate::dependency::ResolvedGraph; // Needed for planner output
8use crate::error::SpsError;
9use crate::model::InstallTargetIdentifier;
10
11// --- Shared Enums / Structs ---
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
14pub enum PipelinePackageType {
15    Formula,
16    Cask,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] // Added PartialEq, Eq
20pub enum JobAction {
21    Install,
22    Upgrade {
23        from_version: String,
24        old_install_path: PathBuf,
25    },
26    Reinstall {
27        version: String,
28        current_install_path: PathBuf,
29    },
30}
31
32#[derive(Debug, Clone)]
33pub struct PlannedJob {
34    pub target_id: String,
35    pub target_definition: InstallTargetIdentifier,
36    pub action: JobAction,
37    pub is_source_build: bool,
38    pub use_private_store_source: Option<PathBuf>,
39}
40
41#[derive(Debug, Clone)]
42pub struct WorkerJob {
43    pub request: PlannedJob,
44    pub download_path: PathBuf,
45    pub download_size_bytes: u64,
46    pub is_source_from_private_store: bool,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub enum PipelineEvent {
51    PipelineStarted {
52        total_jobs: usize,
53    },
54    PipelineFinished {
55        duration_secs: f64,
56        success_count: usize,
57        fail_count: usize,
58    },
59    PlanningStarted,
60    DependencyResolutionStarted,
61    DependencyResolutionFinished,
62    PlanningFinished {
63        job_count: usize,
64        // Optionally, we can pass the ResolvedGraph here if the status handler needs it,
65        // but it might be too large for a broadcast event.
66        // resolved_graph: Option<Arc<ResolvedGraph>>, // Example
67    },
68    DownloadStarted {
69        target_id: String,
70        url: String,
71    },
72    DownloadFinished {
73        target_id: String,
74        path: PathBuf,
75        size_bytes: u64,
76    },
77    DownloadFailed {
78        target_id: String,
79        url: String,
80        error: String, // Keep as String for simplicity in events
81    },
82    JobProcessingStarted {
83        // From core worker
84        target_id: String,
85    },
86    JobDispatchedToCore {
87        // New: From runner to UI when job sent to worker pool
88        target_id: String,
89    },
90    UninstallStarted {
91        target_id: String,
92        version: String,
93    },
94    UninstallFinished {
95        target_id: String,
96        version: String,
97    },
98    BuildStarted {
99        target_id: String,
100    },
101    InstallStarted {
102        target_id: String,
103        pkg_type: PipelinePackageType,
104    },
105    LinkStarted {
106        target_id: String,
107        pkg_type: PipelinePackageType,
108    },
109    JobSuccess {
110        // From core worker
111        target_id: String,
112        action: JobAction,
113        pkg_type: PipelinePackageType,
114    },
115    JobFailed {
116        // From core worker or runner (propagated)
117        target_id: String,
118        action: JobAction, // Action that was attempted
119        error: String,     // Keep as String
120    },
121    LogInfo {
122        message: String,
123    },
124    LogWarn {
125        message: String,
126    },
127    LogError {
128        message: String,
129    },
130}
131
132impl PipelineEvent {
133    // SpsError kept for internal use, but events use String for error messages
134    pub fn job_failed(target_id: String, action: JobAction, error: &SpsError) -> Self {
135        PipelineEvent::JobFailed {
136            target_id,
137            action,
138            error: error.to_string(),
139        }
140    }
141    pub fn download_failed(target_id: String, url: String, error: &SpsError) -> Self {
142        PipelineEvent::DownloadFailed {
143            target_id,
144            url,
145            error: error.to_string(),
146        }
147    }
148}
149
150// --- New Structs and Enums for Refactored Runner ---
151
152/// Represents the current processing state of a job in the pipeline.
153#[derive(Debug, Clone)]
154pub enum JobProcessingState {
155    /// Waiting for download to be initiated.
156    PendingDownload,
157    /// Download is in progress (managed by DownloadCoordinator).
158    Downloading,
159    /// Download completed successfully, artifact at PathBuf.
160    Downloaded(PathBuf),
161    /// Downloaded, but waiting for dependencies to be in Succeeded state.
162    WaitingForDependencies(PathBuf),
163    /// Dispatched to the core worker pool for installation/processing.
164    DispatchedToCore(PathBuf),
165    /// Installation/processing is in progress by a core worker.
166    Installing(PathBuf), // Path is still relevant
167    /// Job completed successfully.
168    Succeeded,
169    /// Job failed. The String contains the error message. Arc for cheap cloning.
170    Failed(Arc<SpsError>),
171}
172
173/// Outcome of a download attempt, sent from DownloadCoordinator to the main runner loop.
174#[derive(Debug)] // Clone not strictly needed if moved
175pub struct DownloadOutcome {
176    pub planned_job: PlannedJob,           // The job this download was for
177    pub result: Result<PathBuf, SpsError>, // Path to downloaded file or error
178}
179
180/// Structure returned by the planner, now including the ResolvedGraph.
181#[derive(Debug, Default)]
182pub struct PlannedOperations {
183    pub jobs: Vec<PlannedJob>,           // Topologically sorted for formulae
184    pub errors: Vec<(String, SpsError)>, // Errors from planning phase
185    pub already_installed_or_up_to_date: std::collections::HashSet<String>,
186    pub resolved_graph: Option<Arc<ResolvedGraph>>, // Graph for dependency checking in runner
187}