Skip to main content

opal/
history.rs

1use anyhow::{Context, Result};
2use serde::{Deserialize, Serialize};
3use std::fs;
4use std::path::Path;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct HistoryEntry {
8    pub run_id: String,
9    pub finished_at: String,
10    pub status: HistoryStatus,
11    pub jobs: Vec<HistoryJob>,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct HistoryJob {
16    pub name: String,
17    pub stage: String,
18    pub status: HistoryStatus,
19    pub log_hash: String,
20    #[serde(default)]
21    pub log_path: Option<String>,
22    #[serde(default)]
23    pub artifact_dir: Option<String>,
24    #[serde(default)]
25    pub artifacts: Vec<String>,
26    #[serde(default)]
27    pub caches: Vec<HistoryCache>,
28    #[serde(default)]
29    pub container_name: Option<String>,
30    #[serde(default)]
31    pub service_network: Option<String>,
32    #[serde(default)]
33    pub service_containers: Vec<String>,
34    #[serde(default)]
35    pub runtime_summary_path: Option<String>,
36    #[serde(default)]
37    pub env_vars: Vec<String>,
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize, Default)]
41pub struct HistoryCache {
42    pub key: String,
43    pub policy: String,
44    pub host: String,
45    #[serde(default)]
46    pub paths: Vec<String>,
47}
48
49#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
50pub enum HistoryStatus {
51    Success,
52    Failed,
53    Skipped,
54    Running,
55}
56
57pub fn load(path: &Path) -> Result<Vec<HistoryEntry>> {
58    if !path.exists() {
59        return Ok(Vec::new());
60    }
61    let contents =
62        fs::read_to_string(path).with_context(|| format!("failed to read {:?}", path))?;
63    let entries: Vec<HistoryEntry> = serde_json::from_str(&contents)
64        .with_context(|| format!("failed to parse history {:?}", path))?;
65    Ok(entries)
66}
67
68pub fn save(path: &Path, entries: &[HistoryEntry]) -> Result<()> {
69    let serialized =
70        serde_json::to_string_pretty(entries).context("failed to serialize history")?;
71    fs::write(path, serialized).with_context(|| format!("failed to write {:?}", path))
72}