1
0
Fork 0
mirror of https://gitlab.com/famedly/conduit.git synced 2025-06-27 16:35:59 +00:00

Enhance admin commands parsing

This commit is contained in:
Curious 2025-05-06 02:08:44 +08:00 committed by Matthias Ahouansou
parent 04fb4f62b8
commit a1886a1396
3 changed files with 18 additions and 7 deletions

7
Cargo.lock generated
View file

@ -507,6 +507,7 @@ dependencies = [
"serde_yaml", "serde_yaml",
"sha-1", "sha-1",
"sha2", "sha2",
"shell-words",
"thiserror 2.0.12", "thiserror 2.0.12",
"thread_local", "thread_local",
"threadpool", "threadpool",
@ -3009,6 +3010,12 @@ dependencies = [
"lazy_static", "lazy_static",
] ]
[[package]]
name = "shell-words"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.3.0" version = "1.3.0"

View file

@ -138,6 +138,7 @@ clap = { version = "4", default-features = false, features = [
"usage", "usage",
] } ] }
humantime = "2" humantime = "2"
shell-words = "1.1.0"
futures-util = { version = "0.3", default-features = false } futures-util = { version = "0.3", default-features = false }
# Used for reading the configuration from conduit.toml & environment variables # Used for reading the configuration from conduit.toml & environment variables

View file

@ -539,23 +539,26 @@ impl Service {
// Parse chat messages from the admin room into an AdminCommand object // Parse chat messages from the admin room into an AdminCommand object
fn parse_admin_command(&self, command_line: &str) -> std::result::Result<AdminCommand, String> { fn parse_admin_command(&self, command_line: &str) -> std::result::Result<AdminCommand, String> {
// Note: argv[0] is `@conduit:servername:`, which is treated as the main command // Note: argv[0] is `@conduit:servername:`, which is treated as the main command
let mut argv: Vec<_> = command_line.split_whitespace().collect(); let mut argv = match shell_words::split(command_line) {
Ok(args) => args,
Err(e) => return Err(format!("Failed to parse admin command: {e}")),
};
// Replace `help command` with `command --help` // Replace `help command` with `command --help`
// Clap has a help subcommand, but it omits the long help description. // Clap has a help subcommand, but it omits the long help description.
if argv.len() > 1 && argv[1] == "help" { if argv.len() > 1 && argv[1] == "help" {
argv.remove(1); argv.remove(1);
argv.push("--help"); argv.push("--help".to_owned());
} }
// Backwards compatibility with `register_appservice`-style commands // Backwards compatibility with `register_appservice`-style commands
let command_with_dashes; if let Some(command) = argv.get_mut(1) {
if argv.len() > 1 && argv[1].contains('_') { if command.contains('_') {
command_with_dashes = argv[1].replace('_', "-"); *command = command.replace('_', "-");
argv[1] = &command_with_dashes; }
} }
AdminCommand::try_parse_from(argv).map_err(|error| error.to_string()) AdminCommand::try_parse_from(&argv).map_err(|error| error.to_string())
} }
async fn process_admin_command( async fn process_admin_command(