Skip to content

Commit 8133bb0

Browse files
committed
Merge branch 'master'
2 parents 260bdfc + 9b099e0 commit 8133bb0

File tree

7 files changed

+1855
-1171
lines changed

7 files changed

+1855
-1171
lines changed

server/src/cli/cli.rs

Lines changed: 122 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,66 @@
11
// server/src/cli/cli.rs
22

3-
// This file serves as the main entry point for the GraphDB CLI executable.
4-
// It parses command-line arguments and dispatches them to appropriate handlers
5-
// in other modules.
6-
7-
use anyhow::Result;
8-
use clap::{CommandFactory, Parser};
3+
use clap::Parser;
94
use std::process;
10-
use std::env; // Import std::env for accessing command-line arguments
5+
use std::env;
6+
use std::collections::HashMap;
7+
use tokio::sync::{oneshot, Mutex};
8+
use tokio::task::JoinHandle;
9+
use std::sync::Arc;
1110

12-
// Import necessary items from the cli module (which re-exports from its sub-modules)
1311
use crate::cli::{
14-
commands::{CliArgs, GraphDbCommands},
15-
handlers,
16-
interactive,
12+
commands::{CliArgs, GraphDbCommands, StartAction, DaemonCliCommand, RestCliCommand, StorageAction, StatusArgs, StopArgs, ReloadArgs},
13+
handlers::{self as handlers_mod, print_welcome_screen},
14+
interactive::{self as interactive_mod, run_cli_interactive},
1715
daemon_management,
18-
config,
19-
help_display,
16+
config::{self as config_mod},
17+
help_display::{self as help_display_mod},
2018
};
2119

20+
use anyhow::Result;
21+
use clap::CommandFactory;
22+
use lib::storage_engine::config::StorageEngineType as LibStorageEngineType;
23+
2224
/// The main entry point for the CLI logic, called by server/src/main.rs
2325
/// This function parses command-line arguments and dispatches to appropriate handlers.
2426
#[tokio::main]
2527
pub async fn start_cli() -> Result<()> {
2628
// --- Custom Help Command Handling ---
27-
// Manually check for "help" as the first argument to bypass clap's default parsing
2829
let args_vec: Vec<String> = env::args().collect();
2930
if args_vec.len() > 1 && args_vec[1].to_lowercase() == "help" {
30-
let help_command_args: Vec<String> = args_vec.into_iter().skip(2).collect(); // Get args after "graphdb-cli help"
31+
let help_command_args: Vec<String> = args_vec.into_iter().skip(2).collect();
3132
let filter_command = if help_command_args.is_empty() {
32-
"".to_string() // No filter, show general help
33+
"".to_string()
3334
} else {
34-
help_command_args.join(" ") // Join all subsequent arguments as the filter string
35+
help_command_args.join(" ")
3536
};
36-
let mut cmd = CliArgs::command(); // Get the top-level Command object for clap's help generation
37-
help_display::print_filtered_help_clap_generated(&mut cmd, &filter_command);
38-
process::exit(0); // Exit after displaying help
37+
let mut cmd = CliArgs::command();
38+
help_display_mod::print_filtered_help_clap_generated(&mut cmd, &filter_command);
39+
process::exit(0);
3940
}
4041
// --- End Custom Help Command Handling ---
4142

42-
4343
let args = CliArgs::parse();
4444

45-
// Handle internal daemon runs first. These are special invocations
46-
// where the CLI executable is run as a background daemon.
4745
if args.internal_rest_api_run || args.internal_storage_daemon_run {
46+
let converted_storage_engine = args.internal_storage_engine.map(|se_cli| {
47+
match se_cli {
48+
config_mod::StorageEngineType::Sled => LibStorageEngineType::Sled,
49+
config_mod::StorageEngineType::RocksDB => LibStorageEngineType::RocksDB,
50+
config_mod::StorageEngineType::InMemory => LibStorageEngineType::InMemory,
51+
}
52+
});
53+
4854
return daemon_management::handle_internal_daemon_run(
4955
args.internal_rest_api_run,
5056
args.internal_storage_daemon_run,
5157
args.internal_port,
5258
args.internal_storage_config_path,
53-
args.internal_storage_engine,
59+
converted_storage_engine,
5460
).await;
5561
}
5662

57-
// Load CLI configuration. If it fails, print an error and exit.
58-
let config = match config::load_cli_config() {
63+
let config = match config_mod::load_cli_config() {
5964
Ok(cfg) => cfg,
6065
Err(e) => {
6166
eprintln!("Error loading configuration: {}", e);
@@ -68,10 +73,8 @@ pub async fn start_cli() -> Result<()> {
6873
}
6974
};
7075

71-
// Handle direct query execution if the `--query` flag is present.
7276
if let Some(query_string) = args.query {
7377
println!("Executing direct query: {}", query_string);
74-
// Assuming lib::query_parser is accessible and QueryType is defined
7578
use lib::query_parser::{parse_query_from_string, QueryType};
7679
match parse_query_from_string(&query_string) {
7780
Ok(parsed_query) => match parsed_query {
@@ -81,10 +84,17 @@ pub async fn start_cli() -> Result<()> {
8184
},
8285
Err(e) => eprintln!("Error parsing query: {}", e),
8386
}
84-
return Ok(()); // Exit after processing a direct query
87+
return Ok(());
8588
}
8689

87-
// Handle explicit command execution if a subcommand is provided.
90+
// Shared state for interactive mode to manage daemon processes
91+
let daemon_handles: Arc<Mutex<HashMap<u16, (JoinHandle<()>, oneshot::Sender<()>)>>> = Arc::new(Mutex::new(HashMap::new()));
92+
let rest_api_shutdown_tx_opt: Arc<Mutex<Option<oneshot::Sender<()>>>> = Arc::new(Mutex::new(None));
93+
let rest_api_port_arc: Arc<Mutex<Option<u16>>> = Arc::new(Mutex::new(None));
94+
let rest_api_handle: Arc<Mutex<Option<JoinHandle<()>>>> = Arc::new(Mutex::new(None));
95+
96+
let should_enter_interactive_mode = args.cli || args.command.is_none();
97+
8898
if let Some(command) = args.command {
8999
if args.enable_plugins {
90100
println!("Experimental plugins are enabled.");
@@ -128,53 +138,108 @@ pub async fn start_cli() -> Result<()> {
128138
println!("Executing cache-node-state with no node ID specified");
129139
}
130140
}
131-
GraphDbCommands::Start { port, cluster, listen_port, storage_port, storage_config_file } => {
132-
// Delegate to the handler module for 'start' command logic
133-
handlers::handle_start_command(port, cluster, listen_port, storage_port, storage_config_file, &config).await?;
141+
GraphDbCommands::Start(start_args) => {
142+
match start_args.action {
143+
StartAction::All { port, cluster, listen_port, storage_port, storage_config_file } => {
144+
handlers_mod::handle_start_all_interactive(
145+
port,
146+
cluster,
147+
listen_port,
148+
storage_port,
149+
storage_config_file,
150+
daemon_handles.clone(),
151+
rest_api_shutdown_tx_opt.clone(),
152+
rest_api_port_arc.clone(),
153+
rest_api_handle.clone(),
154+
).await?;
155+
}
156+
StartAction::Daemon { port, cluster } => {
157+
handlers_mod::handle_daemon_command_interactive(
158+
DaemonCliCommand::Start { port, cluster },
159+
daemon_handles.clone(),
160+
).await?;
161+
}
162+
StartAction::Rest { port, listen_port } => {
163+
handlers_mod::handle_rest_command_interactive(
164+
RestCliCommand::Start { port, listen_port },
165+
rest_api_shutdown_tx_opt.clone(),
166+
rest_api_port_arc.clone(),
167+
rest_api_handle.clone(),
168+
).await?;
169+
}
170+
StartAction::Storage { port, config_file } => {
171+
handlers_mod::handle_storage_command_interactive(
172+
StorageAction::Start { port, config_file },
173+
).await?;
174+
}
175+
}
134176
}
135177
GraphDbCommands::Stop(stop_args) => {
136-
// Delegate to the handler module for 'stop' command logic
137-
handlers::handle_stop_command(stop_args).await?;
178+
handlers_mod::handle_stop_command(stop_args).await?;
138179
}
139180
GraphDbCommands::Status(status_args) => {
140-
// Delegate to the handler module for 'status' command logic
141-
handlers::handle_status_command(status_args).await?;
181+
handlers_mod::handle_status_command(status_args).await?;
182+
}
183+
GraphDbCommands::Reload(reload_args) => {
184+
handlers_mod::handle_reload_command(
185+
reload_args,
186+
daemon_handles.clone(),
187+
rest_api_shutdown_tx_opt.clone(),
188+
rest_api_port_arc.clone(),
189+
rest_api_handle.clone(),
190+
).await?;
142191
}
143192
GraphDbCommands::Storage(storage_action) => {
144-
// Delegate to the handler module for 'storage' command logic
145-
handlers::handle_storage_command(storage_action).await?;
193+
handlers_mod::handle_storage_command_interactive(storage_action).await?;
146194
}
147195
GraphDbCommands::Daemon(daemon_cmd) => {
148-
// Delegate to the handler module for 'daemon' command logic
149-
handlers::handle_daemon_command(daemon_cmd).await?;
196+
handlers_mod::handle_daemon_command_interactive(daemon_cmd, daemon_handles.clone()).await?;
150197
}
151198
GraphDbCommands::Rest(rest_cmd) => {
152-
// Delegate to the handler module for 'rest' command logic
153-
handlers::handle_rest_command(rest_cmd).await?;
199+
handlers_mod::handle_rest_command_interactive(
200+
rest_cmd,
201+
rest_api_shutdown_tx_opt.clone(),
202+
rest_api_port_arc.clone(),
203+
rest_api_handle.clone(),
204+
).await?;
205+
}
206+
GraphDbCommands::Auth(auth_args) => {
207+
println!("Auth command received: {:?}", auth_args);
208+
}
209+
GraphDbCommands::Authenticate(auth_args) => {
210+
println!("Authenticate command received: {:?}", auth_args);
211+
}
212+
GraphDbCommands::Register(register_args) => {
213+
println!("Register command received: {:?}", register_args);
214+
}
215+
GraphDbCommands::Version => {
216+
println!("Version command received.");
217+
}
218+
GraphDbCommands::Health => {
219+
println!("Health command received.");
220+
}
221+
GraphDbCommands::Clear | GraphDbCommands::Clean => {
222+
handlers_mod::clear_terminal_screen().await?;
154223
}
155-
// The GraphDbCommands::Help variant is removed, as 'help' is now handled manually.
156224
}
157-
return Ok(()); // Exit after processing a direct command
225+
return Ok(());
158226
}
159227

160-
// If no specific command or query is given, and `--cli` flag is present,
161-
// or if no arguments are given at all, enter interactive CLI mode.
162-
if args.cli {
228+
if should_enter_interactive_mode {
163229
if args.enable_plugins {
164230
println!("Experimental plugins are enabled.");
165231
}
166-
interactive::run_cli_interactive().await?;
167-
return Ok(());
168-
}
169-
170-
// If only `--enable-plugins` is given without other commands.
171-
if args.enable_plugins {
232+
// print_welcome_screen(); // Removed: This is now handled by interactive_mod::run_cli_interactive
233+
interactive_mod::run_cli_interactive(
234+
daemon_handles,
235+
rest_api_shutdown_tx_opt,
236+
rest_api_port_arc,
237+
rest_api_handle,
238+
).await?;
239+
} else if args.enable_plugins {
172240
println!("Experimental plugins is enabled.");
173-
return Ok(());
174241
}
175242

176-
// Default to interactive CLI if no other commands/args are given
177-
interactive::run_cli_interactive().await?;
178243
Ok(())
179244
}
180245

0 commit comments

Comments
 (0)