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