qtcloud_devops_cli/
commands.rs1use crate::model::SubmoduleStatus;
2use std::path::Path;
3
4pub mod cancel;
5pub mod code;
6pub mod publish;
7pub mod release;
8pub mod retire;
9pub mod stage;
10
11#[derive(Debug, Clone)]
12pub struct HealthIssue {
13 pub submodule_name: String,
14 pub status: SubmoduleStatus,
15 pub description: String,
16 pub suggested_action: String,
17}
18
19pub trait SubmoduleEditor {
20 fn root(&self) -> &Path;
21
22 fn sync_to_parent(&self, name: &str) -> Result<(), Box<dyn std::error::Error>>;
24 fn sync_all_to_parent(&self) -> Result<(), Box<dyn std::error::Error>>;
25
26 fn retire_submodule(&self, name: &str) -> Result<(), Box<dyn std::error::Error>>;
28
29 fn status(&self) -> Result<Vec<HealthIssue>, Box<dyn std::error::Error>>;
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36
37 #[test]
38 fn test_health_issue_builder() {
39 let issue = HealthIssue {
40 submodule_name: "libs/foo".into(),
41 status: SubmoduleStatus::Dirty,
42 description: "有未提交的修改".into(),
43 suggested_action: "提交或 stash".into(),
44 };
45 assert_eq!(issue.submodule_name, "libs/foo");
46 assert_eq!(issue.status, SubmoduleStatus::Dirty);
47 }
48
49 #[test]
50 fn test_health_issue_clone() {
51 let a = HealthIssue {
52 submodule_name: "a".into(),
53 status: SubmoduleStatus::Clean,
54 description: "d".into(),
55 suggested_action: "s".into(),
56 };
57 let b = a.clone();
58 assert_eq!(a.submodule_name, b.submodule_name);
59 assert_eq!(a.status, b.status);
60 }
61
62 #[test]
63 fn test_health_issue_debug() {
64 let issue = HealthIssue {
65 submodule_name: "m".into(),
66 status: SubmoduleStatus::Orphaned,
67 description: "x".into(),
68 suggested_action: "y".into(),
69 };
70 let debug = format!("{:?}", issue);
71 assert!(debug.contains("Orphaned"));
72 assert!(debug.contains("m"));
73 }
74}