quanttide_devops/contract/
mod.rs1pub mod core;
2pub mod error;
6pub mod platform;
7pub mod scope;
8pub mod source;
9pub mod stage;
10pub mod version;
11
12pub use core::Contract;
13pub use error::ContractError;
14pub use platform::{Pipeline, Platform, Registry, SourceControl};
15pub use scope::{BuildTool, Language, Scope};
16pub use source::{Source, SourceType};
17pub use stage::{Stage, StageBuild, StageRelease, StageTest};
18pub use version::{
19 VersionState, check_version_consistency, normalize_version, validate_version, verify_version,
20};
21
22use std::path::Path;
23
24pub fn load(repo_path: &Path) -> Result<Contract, ContractError> {
26 let path = repo_path.join(".quanttide/devops/contract.yaml");
27 let content = std::fs::read_to_string(&path)?;
28 let mut contract: Contract = load_from_str(&content)?;
29 if contract.sources.version.source_type == SourceType::Auto {
31 contract.sources.version.source_type = SourceType::detect(repo_path);
32 }
33 Ok(contract)
34}
35
36pub fn load_from_str(s: &str) -> Result<Contract, ContractError> {
38 serde_yaml::from_str::<Contract>(s).map_err(|e| ContractError::Parse(e.to_string()))
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn test_load_from_str_valid() {
47 let yaml = r#"
48stages:
49 test:
50 threshold: 80
51
52scopes:
53 cli:
54 dir: src/cli
55"#;
56 let c = load_from_str(yaml).unwrap();
57 assert_eq!(c.scopes.len(), 1);
58 assert_eq!(c.scopes[0].name, "cli");
59 assert_eq!(c.scopes[0].dir, "src/cli");
60 assert_eq!(c.stages.test.threshold, 80.0);
61 }
62
63 #[test]
64 fn test_load_from_str_empty() {
65 let c = load_from_str("").unwrap();
66 assert!(c.scopes.is_empty());
67 }
68
69 #[test]
70 fn test_load_from_str_invalid() {
71 let err = load_from_str("invalid: [").unwrap_err();
72 assert!(err.to_string().contains("解析失败"));
73 }
74}