systemprompt_cli/commands/admin/config/
paths.rs1use anyhow::Result;
9use clap::Subcommand;
10use std::path::Path;
11use systemprompt_config::ProfileBootstrap;
12use systemprompt_logging::CliService;
13
14use super::types::{PathInfo, PathValidation, PathsConfigOutput, PathsValidateOutput};
15use crate::CliConfig;
16use crate::cli_settings::OutputFormat;
17use crate::shared::{CommandOutput, render_result};
18
19#[derive(Debug, Clone, Copy, Subcommand)]
20pub enum PathsCommands {
21 #[command(about = "Show paths configuration", alias = "list")]
22 Show,
23
24 #[command(about = "Validate that all configured paths exist")]
25 Validate,
26}
27
28pub fn execute(command: PathsCommands, config: &CliConfig) -> Result<()> {
29 match command {
30 PathsCommands::Show => execute_show(),
31 PathsCommands::Validate => execute_validate(config),
32 }
33}
34
35pub(super) fn execute_show() -> Result<()> {
36 let profile = ProfileBootstrap::get()?;
37
38 let output = PathsConfigOutput {
39 system: PathInfo {
40 path: profile.paths.system.clone(),
41 exists: Path::new(&profile.paths.system).exists(),
42 },
43 services: PathInfo {
44 path: profile.paths.services.clone(),
45 exists: Path::new(&profile.paths.services).exists(),
46 },
47 bin: PathInfo {
48 path: profile.paths.bin.clone(),
49 exists: Path::new(&profile.paths.bin).exists(),
50 },
51 web_path: profile.paths.web_path.as_ref().map(|p| PathInfo {
52 path: p.clone(),
53 exists: Path::new(p).exists(),
54 }),
55 storage: profile.paths.storage.as_ref().map(|p| PathInfo {
56 path: p.clone(),
57 exists: Path::new(p).exists(),
58 }),
59 geoip_database: profile.paths.geoip_database.as_ref().map(|p| PathInfo {
60 path: p.clone(),
61 exists: Path::new(p).exists(),
62 }),
63 };
64
65 render_result(&CommandOutput::card_value("Paths Configuration", &output));
66
67 Ok(())
68}
69
70pub(super) fn execute_validate(config: &CliConfig) -> Result<()> {
71 let profile = ProfileBootstrap::get()?;
72
73 let mut validations: Vec<PathValidation> = Vec::new();
74
75 validations.push(PathValidation {
76 name: "system".to_owned(),
77 path: profile.paths.system.clone(),
78 exists: Path::new(&profile.paths.system).exists(),
79 required: true,
80 });
81
82 validations.push(PathValidation {
83 name: "services".to_owned(),
84 path: profile.paths.services.clone(),
85 exists: Path::new(&profile.paths.services).exists(),
86 required: true,
87 });
88
89 validations.push(PathValidation {
90 name: "bin".to_owned(),
91 path: profile.paths.bin.clone(),
92 exists: Path::new(&profile.paths.bin).exists(),
93 required: true,
94 });
95
96 if let Some(web_path) = &profile.paths.web_path {
97 validations.push(PathValidation {
98 name: "web_path".to_owned(),
99 path: web_path.clone(),
100 exists: Path::new(web_path).exists(),
101 required: false,
102 });
103 }
104
105 if let Some(storage) = &profile.paths.storage {
106 validations.push(PathValidation {
107 name: "storage".to_owned(),
108 path: storage.clone(),
109 exists: Path::new(storage).exists(),
110 required: false,
111 });
112 }
113
114 if let Some(geoip) = &profile.paths.geoip_database {
115 validations.push(PathValidation {
116 name: "geoip_database".to_owned(),
117 path: geoip.clone(),
118 exists: Path::new(geoip).exists(),
119 required: false,
120 });
121 }
122
123 let config_path = profile.paths.config();
124 validations.push(PathValidation {
125 name: "config".to_owned(),
126 path: config_path.clone(),
127 exists: Path::new(&config_path).exists(),
128 required: false,
129 });
130
131 let ai_config_path = profile.paths.ai_config();
132 validations.push(PathValidation {
133 name: "ai_config".to_owned(),
134 path: ai_config_path.clone(),
135 exists: Path::new(&ai_config_path).exists(),
136 required: false,
137 });
138
139 let content_config_path = profile.paths.content_config();
140 validations.push(PathValidation {
141 name: "content_config".to_owned(),
142 path: content_config_path.clone(),
143 exists: Path::new(&content_config_path).exists(),
144 required: false,
145 });
146
147 let valid = validations.iter().filter(|v| v.required).all(|v| v.exists);
148
149 let output = PathsValidateOutput {
150 valid,
151 paths: validations,
152 };
153
154 render_result(
155 &CommandOutput::table_of(vec!["name", "path", "exists", "required"], &output.paths)
156 .with_title("Paths Validation"),
157 );
158
159 if config.output_format() == OutputFormat::Table {
160 if valid {
161 CliService::success("All required paths exist");
162 } else {
163 CliService::error("Some required paths are missing");
164 }
165 }
166
167 Ok(())
168}