relay_knowledge/bootstrap/
cli.rs1use crate::{
8 application::{KnowledgeMapService, ProcessRuntimeConfig},
9 env::windows_system_root_from_process,
10 interfaces::cli::{CliAction, CliCommand, OutputFormat},
11 paths::discover_repository_root,
12 project::{KNOWLEDGE_MAP_RELATIVE_PATH, PROJECT_NAME},
13};
14
15pub use crate::interfaces::cli::{CliError, CliProcessOutput};
16
17pub async fn run_process<I, S>(
24 args: I,
25 interactive_text_output: bool,
26) -> Result<CliProcessOutput, CliError>
27where
28 I: IntoIterator<Item = S>,
29 S: Into<String>,
30{
31 let command = CliCommand::parse(args)?;
32 let stdout = run_command(command, interactive_text_output).await?;
33
34 Ok(CliProcessOutput {
35 stdout,
36 stderr: String::new(),
37 })
38}
39
40pub async fn process_update_notice<I, S>(args: I, interactive_text_output: bool) -> Option<String>
46where
47 I: IntoIterator<Item = S>,
48 S: Into<String>,
49{
50 let _command = crate::interfaces::cli::update_notice_command(args, interactive_text_output)?;
51 let runtime = super::runtime_configuration_from_process_environment()
52 .await
53 .ok()?;
54 crate::interfaces::cli::update_notice_for_runtime(&runtime).await
55}
56
57async fn run_command(
58 command: CliCommand,
59 _interactive_text_output: bool,
60) -> Result<String, CliError> {
61 let service = match &command.action {
62 CliAction::Map(map_command) if map_command.needs_repository_root() => {
63 Some(knowledge_map_service(command.format)?)
64 }
65 _ => None,
66 };
67 crate::interfaces::cli::run_command(command, service.as_ref(), process_context()).await
68}
69
70fn process_context() -> ProcessRuntimeConfig {
71 let current_executable =
72 std::env::current_exe().unwrap_or_else(|_| std::path::PathBuf::from(PROJECT_NAME));
73 ProcessRuntimeConfig::from_bootstrap_inputs(
74 current_executable,
75 windows_system_root_from_process(),
76 )
77}
78
79fn knowledge_map_service(format: OutputFormat) -> Result<KnowledgeMapService, CliError> {
80 let current = std::env::current_dir().map_err(|error| {
81 CliError::invalid_api_argument(
82 format!("failed to resolve current directory: {error}"),
83 format,
84 )
85 })?;
86 let root = discover_repository_root(¤t)
87 .map_err(|error| CliError::invalid_api_argument(error.to_string(), format))?
88 .ok_or_else(|| {
89 CliError::invalid_api_argument(
90 format!("failed to find repository root for {KNOWLEDGE_MAP_RELATIVE_PATH}"),
91 format,
92 )
93 })?;
94
95 Ok(KnowledgeMapService::new(root))
96}
97
98#[cfg(test)]
99#[allow(deprecated)]
100#[path = "cli_tests.rs"]
101mod tests;