src/cli/command.rs: pass parsed parameters to completion function
This commit is contained in:
parent
b5fa28251c
commit
496a67846f
@ -4,7 +4,7 @@ use failure::*;
|
|||||||
//use std::os::unix::io::AsRawFd;
|
//use std::os::unix::io::AsRawFd;
|
||||||
use chrono::{DateTime, Local, TimeZone};
|
use chrono::{DateTime, Local, TimeZone};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::ffi::OsString;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use proxmox_backup::tools;
|
use proxmox_backup::tools;
|
||||||
use proxmox_backup::cli::*;
|
use proxmox_backup::cli::*;
|
||||||
@ -379,7 +379,7 @@ fn create_backup(
|
|||||||
Ok(Value::Null)
|
Ok(Value::Null)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn complete_backup_source(arg: &str) -> Vec<String> {
|
pub fn complete_backup_source(arg: &str, param: &HashMap<String, String>) -> Vec<String> {
|
||||||
|
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
|
|
||||||
@ -387,7 +387,7 @@ pub fn complete_backup_source(arg: &str) -> Vec<String> {
|
|||||||
|
|
||||||
if data.len() != 2 { return result; }
|
if data.len() != 2 { return result; }
|
||||||
|
|
||||||
let files = tools::complete_file_name(data[1]);
|
let files = tools::complete_file_name(data[1], param);
|
||||||
|
|
||||||
for file in files {
|
for file in files {
|
||||||
result.push(format!("{}:{}", data[0], file));
|
result.push(format!("{}:{}", data[0], file));
|
||||||
@ -592,4 +592,5 @@ fn main() {
|
|||||||
.insert("snapshots".to_owned(), snapshots_cmd_def.into());
|
.insert("snapshots".to_owned(), snapshots_cmd_def.into());
|
||||||
|
|
||||||
run_cli_command(cmd_def.into());
|
run_cli_command(cmd_def.into());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -399,10 +399,11 @@ fn print_property_completion(
|
|||||||
schema: &Schema,
|
schema: &Schema,
|
||||||
name: &str,
|
name: &str,
|
||||||
completion_functions: &HashMap<String, CompletionFunction>,
|
completion_functions: &HashMap<String, CompletionFunction>,
|
||||||
arg: &str)
|
arg: &str,
|
||||||
{
|
param: &HashMap<String, String>,
|
||||||
|
) {
|
||||||
if let Some(callback) = completion_functions.get(name) {
|
if let Some(callback) = completion_functions.get(name) {
|
||||||
let list = (callback)(arg);
|
let list = (callback)(arg, param);
|
||||||
for value in list {
|
for value in list {
|
||||||
if value.starts_with(arg) {
|
if value.starts_with(arg) {
|
||||||
println!("{}", value);
|
println!("{}", value);
|
||||||
@ -424,24 +425,19 @@ fn print_property_completion(
|
|||||||
println!("");
|
println!("");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_done_arguments(done: &mut HashSet<String>, parameters: &ObjectSchema, list: &[String]) {
|
fn record_done_argument(done: &mut HashMap<String, String>, parameters: &ObjectSchema, key: &str, value: &str) {
|
||||||
|
|
||||||
for arg in list {
|
if let Some((_, schema)) = parameters.properties.get::<str>(key) {
|
||||||
if arg.starts_with("--") && arg.len() > 2 {
|
|
||||||
let prop_name = arg[2..].to_owned();
|
|
||||||
if let Some((_, schema)) = parameters.properties.get::<str>(&prop_name) {
|
|
||||||
match schema.as_ref() {
|
match schema.as_ref() {
|
||||||
Schema::Array(_) => { /* do nothing */ }
|
Schema::Array(_) => { /* do nothing ?? */ }
|
||||||
_ => { done.insert(prop_name); }
|
_ => { done.insert(key.to_owned(), value.to_owned()); }
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_simple_completion(
|
fn print_simple_completion(
|
||||||
cli_cmd: &CliCommand,
|
cli_cmd: &CliCommand,
|
||||||
done: &mut HashSet<String>,
|
done: &mut HashMap<String, String>,
|
||||||
arg_param: &[&str],
|
arg_param: &[&str],
|
||||||
args: &[String],
|
args: &[String],
|
||||||
) {
|
) {
|
||||||
@ -450,20 +446,28 @@ fn print_simple_completion(
|
|||||||
|
|
||||||
if !arg_param.is_empty() {
|
if !arg_param.is_empty() {
|
||||||
let prop_name = arg_param[0];
|
let prop_name = arg_param[0];
|
||||||
done.insert(prop_name.into());
|
|
||||||
if args.len() > 1 {
|
if args.len() > 1 {
|
||||||
|
record_done_argument(done, &cli_cmd.info.parameters, prop_name, &args[0]);
|
||||||
print_simple_completion(cli_cmd, done, &arg_param[1..], &args[1..]);
|
print_simple_completion(cli_cmd, done, &arg_param[1..], &args[1..]);
|
||||||
return;
|
return;
|
||||||
} else if args.len() == 1 {
|
} else if args.len() == 1 {
|
||||||
|
record_done_argument(done, &cli_cmd.info.parameters, prop_name, &args[0]);
|
||||||
if let Some((_, schema)) = cli_cmd.info.parameters.properties.get(prop_name) {
|
if let Some((_, schema)) = cli_cmd.info.parameters.properties.get(prop_name) {
|
||||||
print_property_completion(schema, prop_name, &cli_cmd.completion_functions, &args[0]);
|
print_property_completion(schema, prop_name, &cli_cmd.completion_functions, &args[0], done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if args.is_empty() { return; }
|
if args.is_empty() { return; }
|
||||||
|
|
||||||
record_done_arguments(done, &cli_cmd.info.parameters, &args);
|
// Try to parse all argumnets but last, record args already done
|
||||||
|
if args.len() > 1 {
|
||||||
|
let mut errors = ParameterError::new(); // we simply ignore any parsing errors here
|
||||||
|
let (data, rest) = getopts::parse_argument_list(&args[0..args.len()-1], &cli_cmd.info.parameters, &mut errors);
|
||||||
|
for (key, value) in &data {
|
||||||
|
record_done_argument(done, &cli_cmd.info.parameters, key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let prefix = &args[args.len()-1]; // match on last arg
|
let prefix = &args[args.len()-1]; // match on last arg
|
||||||
|
|
||||||
@ -473,14 +477,14 @@ fn print_simple_completion(
|
|||||||
if last.starts_with("--") && last.len() > 2 {
|
if last.starts_with("--") && last.len() > 2 {
|
||||||
let prop_name = &last[2..];
|
let prop_name = &last[2..];
|
||||||
if let Some((_, schema)) = cli_cmd.info.parameters.properties.get(prop_name) {
|
if let Some((_, schema)) = cli_cmd.info.parameters.properties.get(prop_name) {
|
||||||
print_property_completion(schema, prop_name, &cli_cmd.completion_functions, &prefix);
|
print_property_completion(schema, prop_name, &cli_cmd.completion_functions, &prefix, done);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name, (_optional, _schema)) in &cli_cmd.info.parameters.properties {
|
for (name, (_optional, _schema)) in &cli_cmd.info.parameters.properties {
|
||||||
if done.contains(*name) { continue; }
|
if done.contains_key(*name) { continue; }
|
||||||
let option = String::from("--") + name;
|
let option = String::from("--") + name;
|
||||||
if option.starts_with(prefix) {
|
if option.starts_with(prefix) {
|
||||||
println!("{}", option);
|
println!("{}", option);
|
||||||
@ -490,7 +494,7 @@ fn print_simple_completion(
|
|||||||
|
|
||||||
fn print_help_completion(def: &CommandLineInterface, help_cmd: &CliCommand, args: &[String]) {
|
fn print_help_completion(def: &CommandLineInterface, help_cmd: &CliCommand, args: &[String]) {
|
||||||
|
|
||||||
let mut done = HashSet::new();
|
let mut done = HashMap::new();
|
||||||
|
|
||||||
match def {
|
match def {
|
||||||
CommandLineInterface::Simple(_) => {
|
CommandLineInterface::Simple(_) => {
|
||||||
@ -530,9 +534,10 @@ fn print_nested_completion(def: &CommandLineInterface, args: &[String]) {
|
|||||||
|
|
||||||
match def {
|
match def {
|
||||||
CommandLineInterface::Simple(cli_cmd) => {
|
CommandLineInterface::Simple(cli_cmd) => {
|
||||||
let mut done = HashSet::new();
|
let mut done: HashMap<String, String> = HashMap::new();
|
||||||
let fixed: Vec<String> = cli_cmd.fixed_param.keys().map(|s| s.to_string()).collect();
|
cli_cmd.fixed_param.iter().map(|(key, value)| {
|
||||||
record_done_arguments(&mut done, &cli_cmd.info.parameters, &fixed);
|
record_done_argument(&mut done, &cli_cmd.info.parameters, &key, &value);
|
||||||
|
});
|
||||||
print_simple_completion(cli_cmd, &mut done, &cli_cmd.arg_param, args);
|
print_simple_completion(cli_cmd, &mut done, &cli_cmd.arg_param, args);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -650,7 +655,7 @@ pub fn run_cli_command(def: CommandLineInterface) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type CompletionFunction = fn(&str) -> Vec<String>;
|
pub type CompletionFunction = fn(&str, &HashMap<String, String>) -> Vec<String>;
|
||||||
|
|
||||||
pub struct CliCommand {
|
pub struct CliCommand {
|
||||||
pub info: ApiMethod,
|
pub info: ApiMethod,
|
||||||
|
@ -2,6 +2,7 @@ use failure::*;
|
|||||||
|
|
||||||
//use std::fs::{OpenOptions};
|
//use std::fs::{OpenOptions};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
//use std::sync::Arc;
|
//use std::sync::Arc;
|
||||||
use crate::tools;
|
use crate::tools;
|
||||||
@ -66,7 +67,7 @@ pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// shell completion helper
|
// shell completion helper
|
||||||
pub fn complete_datastore_name(_arg: &str) -> Vec<String> {
|
pub fn complete_datastore_name(_arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
|
||||||
match config() {
|
match config() {
|
||||||
Ok(data) => data.sections.iter().map(|(id,_)| id.to_string()).collect(),
|
Ok(data) => data.sections.iter().map(|(id,_)| id.to_string()).collect(),
|
||||||
Err(_) => return vec![],
|
Err(_) => return vec![],
|
||||||
|
@ -17,6 +17,8 @@ use std::time::Duration;
|
|||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
pub mod timer;
|
pub mod timer;
|
||||||
@ -385,7 +387,7 @@ pub fn required_array_param<'a>(param: &'a Value, name: &str) -> Result<Vec<Valu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn complete_file_name(arg: &str) -> Vec<String> {
|
pub fn complete_file_name(arg: &str, _param: &HashMap<String, String>) -> Vec<String> {
|
||||||
|
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user