Skip to main content

systemprompt_cli/commands/admin/config/
validate.rs

1use anyhow::Result;
2use clap::Args;
3
4use super::types::{read_yaml_file, ConfigFileInfo, ConfigSection, ConfigValidateOutput};
5use crate::shared::CommandResult;
6use crate::CliConfig;
7
8#[derive(Debug, Clone, Args)]
9pub struct ValidateArgs {
10    #[arg(value_name = "PATH_OR_SECTION")]
11    pub target: Option<String>,
12
13    #[arg(long)]
14    pub strict: bool,
15}
16
17pub fn execute(
18    args: &ValidateArgs,
19    _config: &CliConfig,
20) -> Result<CommandResult<ConfigValidateOutput>> {
21    let files_to_validate = if let Some(target) = &args.target {
22        if let Ok(section) = target.parse::<ConfigSection>() {
23            section.all_files()?
24        } else {
25            vec![std::path::PathBuf::from(target)]
26        }
27    } else {
28        let mut all_files = Vec::new();
29        for section in ConfigSection::all() {
30            if let Ok(files) = section.all_files() {
31                all_files.extend(files);
32            }
33        }
34        all_files
35    };
36
37    let mut results = Vec::new();
38    let mut all_valid = true;
39
40    for file_path in files_to_validate {
41        let section = detect_section(&file_path);
42        let exists = file_path.exists();
43
44        let (valid, error) = if exists {
45            match validate_file(&file_path, args.strict) {
46                Ok(()) => (true, None),
47                Err(e) => {
48                    all_valid = false;
49                    (false, Some(e.to_string()))
50                },
51            }
52        } else {
53            all_valid = false;
54            (false, Some("File not found".to_string()))
55        };
56
57        results.push(ConfigFileInfo {
58            path: file_path.display().to_string(),
59            section,
60            exists,
61            valid,
62            error,
63        });
64    }
65
66    let output = ConfigValidateOutput {
67        files: results,
68        all_valid,
69    };
70
71    let title = if all_valid {
72        "Validation Passed"
73    } else {
74        "Validation Failed"
75    };
76
77    Ok(CommandResult::table(output).with_title(title))
78}
79
80fn validate_file(path: &std::path::Path, _strict: bool) -> Result<()> {
81    let _content = read_yaml_file(path)?;
82    Ok(())
83}
84
85fn detect_section(path: &std::path::Path) -> String {
86    let path_str = path.display().to_string();
87
88    if path_str.contains("/ai/") {
89        "ai".to_string()
90    } else if path_str.contains("/content/") {
91        "content".to_string()
92    } else if path_str.contains("/web/") {
93        "web".to_string()
94    } else if path_str.contains("/scheduler/") {
95        "scheduler".to_string()
96    } else if path_str.contains("/agents/") {
97        "agents".to_string()
98    } else if path_str.contains("/mcp/") {
99        "mcp".to_string()
100    } else if path_str.contains("/skills/") {
101        "skills".to_string()
102    } else if path_str.contains("profile.yaml") {
103        "profile".to_string()
104    } else if path_str.contains("/config/config.yaml") {
105        "services".to_string()
106    } else {
107        "unknown".to_string()
108    }
109}