qtcloud_devops_cli/commands/
retire.rs1use std::path::Path;
2
3use crate::model::release::{FileStorage, ReleaseStatus, Storage, TransitionError};
4
5pub fn run(version: &str, repo_path: &Path) -> Result<String, Box<dyn std::error::Error>> {
6 let mut storage = FileStorage::new(repo_path);
7 let mut record = storage
8 .load(version)
9 .ok_or_else(|| format!("版本 {} 不存在", version))?;
10
11 if record.status != ReleaseStatus::Published {
12 return Err(Box::new(TransitionError::NotPublished(version.to_string())));
13 }
14
15 record.status = ReleaseStatus::Retired;
16 record.updated_at = std::time::SystemTime::now()
17 .duration_since(std::time::UNIX_EPOCH)
18 .unwrap_or_default()
19 .as_secs()
20 .to_string();
21 storage.save(&record)?;
22
23 let id = record.id.clone();
24 println!("✓ 版本 {} 已退役 (发布尝试 ID: {})", version, id);
25 Ok(id)
26}
27
28#[cfg(test)]
29mod tests {
30 use super::*;
31 use crate::model::release::{ReleaseRecord, ReleaseStatus, Storage};
32
33 fn make_record(version: &str, status: ReleaseStatus) -> ReleaseRecord {
34 let now = std::time::SystemTime::now()
35 .duration_since(std::time::UNIX_EPOCH)
36 .unwrap_or_default()
37 .as_secs()
38 .to_string();
39 ReleaseRecord {
40 id: uuid::Uuid::new_v4().to_string(),
41 version: version.to_string(),
42 status,
43 created_at: now.clone(),
44 updated_at: now,
45 }
46 }
47
48 #[test]
49 fn test_retire_not_published() {
50 let dir = tempfile::tempdir().unwrap();
51 let mut s = FileStorage::new(dir.path());
52 s.save(&make_record("v1.0.0", ReleaseStatus::Staged))
53 .unwrap();
54 assert!(run("v1.0.0", dir.path()).is_err());
55 }
56
57 #[test]
58 fn test_retire_nonexistent() {
59 let dir = tempfile::tempdir().unwrap();
60 assert!(run("v9.9.9", dir.path()).is_err());
61 }
62
63 #[test]
64 fn test_retire_from_published() {
65 let dir = tempfile::tempdir().unwrap();
66 {
67 let mut s = FileStorage::new(dir.path());
68 s.save(&make_record("v1.0.0", ReleaseStatus::Published))
69 .unwrap();
70 }
71 run("v1.0.0", dir.path()).unwrap();
72 let s = FileStorage::new(dir.path());
73 assert_eq!(
74 s.load("v1.0.0").unwrap().status,
75 ReleaseStatus::Retired
76 );
77 }
78}