Skip to main content

quanttide_devops/contract/
stage.rs

1//! 阶段配置:构建、测试、发布的默认值与自定义覆盖。
2
3use serde::{Deserialize, Serialize};
4
5// ── Stages(时序维度)────────────────────────────────────────────────
6
7/// 生命周期阶段配置。
8///
9/// 不规定"怎么做",只规定"什么时候检查什么"。
10#[derive(Debug, Clone, Serialize, Deserialize)]
11#[serde(rename_all = "snake_case")]
12pub struct Stage {
13    #[serde(default)]
14    pub build: StageBuild,
15    #[serde(default)]
16    pub test: StageTest,
17    #[serde(default)]
18    pub release: StageRelease,
19}
20
21impl Default for Stage {
22    fn default() -> Self {
23        Self {
24            build: StageBuild { command: None },
25            test: StageTest {
26                command: None,
27                threshold: 80.0,
28            },
29            release: StageRelease {
30                changelog: "CHANGELOG.md".into(),
31                pre_publish: Vec::new(),
32            },
33        }
34    }
35}
36
37/// 构建阶段。
38#[derive(Debug, Clone, Default, Serialize, Deserialize)]
39#[serde(rename_all = "snake_case")]
40pub struct StageBuild {
41    #[serde(default)]
42    pub command: Option<String>,
43}
44
45/// 测试阶段。
46#[derive(Debug, Clone, Serialize, Deserialize)]
47#[serde(rename_all = "snake_case")]
48pub struct StageTest {
49    #[serde(default)]
50    pub command: Option<String>,
51    #[serde(default = "default_threshold")]
52    pub threshold: f64,
53}
54
55impl Default for StageTest {
56    fn default() -> Self {
57        Self {
58            command: None,
59            threshold: 80.0,
60        }
61    }
62}
63
64const fn default_threshold() -> f64 {
65    80.0
66}
67
68/// 发布阶段。
69#[derive(Debug, Clone, Serialize, Deserialize)]
70#[serde(rename_all = "snake_case")]
71pub struct StageRelease {
72    #[serde(default = "default_changelog")]
73    pub changelog: String,
74    #[serde(default)]
75    pub pre_publish: Vec<String>,
76}
77
78fn default_changelog() -> String {
79    "CHANGELOG.md".into()
80}
81
82impl Default for StageRelease {
83    fn default() -> Self {
84        Self {
85            changelog: "CHANGELOG.md".into(),
86            pre_publish: Vec::new(),
87        }
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    use super::*;
94
95    #[test]
96    fn test_stage_build_default() {
97        let s = StageBuild::default();
98        assert_eq!(s.command, None);
99    }
100
101    #[test]
102    fn test_stage_test_default() {
103        let s = StageTest::default();
104        assert_eq!(s.command, None);
105        assert_eq!(s.threshold, 80.0);
106    }
107
108    #[test]
109    fn test_default_threshold_fn() {
110        assert_eq!(default_threshold(), 80.0);
111    }
112
113    #[test]
114    fn test_default_changelog_fn() {
115        assert_eq!(default_changelog(), "CHANGELOG.md");
116    }
117}