mirror of
https://github.com/facebook/sapling.git
synced 2025-01-08 06:37:26 +03:00
clidispatch: support command name aliases
Summary: Support command name aliases like `config|debugconfig` in Python command definition. Reviewed By: sfilipco Differential Revision: D18108170 fbshipit-source-id: eeb9ec273960d7bd4e4278e55ef8122f200b2f60
This commit is contained in:
parent
7283f8a4da
commit
8f86961b12
@ -8,8 +8,9 @@
|
||||
use crate::{io::IO, repo::Repo};
|
||||
use cliparser::parser::{Flag, ParseOutput, StructFlags};
|
||||
use failure::Fallible;
|
||||
use std::collections::BTreeMap;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::{collections::BTreeMap, ops::Deref};
|
||||
use std::ops::Deref;
|
||||
|
||||
pub enum CommandFunc {
|
||||
NoRepo(Box<dyn Fn(ParseOutput, &mut IO) -> Fallible<u8>>),
|
||||
@ -56,15 +57,36 @@ impl CommandDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CommandTable {
|
||||
commands: BTreeMap<String, CommandDefinition>,
|
||||
|
||||
/// Alias name -> Command name.
|
||||
alias: BTreeMap<String, String>,
|
||||
}
|
||||
|
||||
impl CommandTable {
|
||||
pub fn new() -> Self {
|
||||
CommandTable {
|
||||
commands: BTreeMap::new(),
|
||||
Default::default()
|
||||
}
|
||||
|
||||
/// Insert aliases to `alias` field.
|
||||
///
|
||||
/// For example, `insert_aliases("config|cfg")` will insert
|
||||
/// `{"config": "config|cfg", "cfg": "config|cfg"}` to `alias`.
|
||||
fn insert_aliases<'a>(&mut self, names: &'a str) {
|
||||
if !names.contains("|") {
|
||||
return;
|
||||
}
|
||||
for name in names.split("|") {
|
||||
self.alias.insert(name.to_string(), names.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
/// Look up a command by name. Consider aliases.
|
||||
pub fn get(&self, name: &str) -> Option<&CommandDefinition> {
|
||||
let name = self.alias.get(name).map(AsRef::as_ref).unwrap_or(name);
|
||||
self.commands.get(name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,6 +109,7 @@ where
|
||||
FN: Fn(S, &mut IO) -> Fallible<u8> + 'static,
|
||||
{
|
||||
fn register(&mut self, f: FN, name: &str, doc: &str) {
|
||||
self.insert_aliases(name);
|
||||
let func = move |opts: ParseOutput, io: &mut IO| f(opts.try_into()?, io);
|
||||
let func = CommandFunc::NoRepo(Box::new(func));
|
||||
let def = CommandDefinition::new(name, doc, S::flags, func);
|
||||
@ -101,6 +124,7 @@ where
|
||||
FN: Fn(S, &mut IO, Option<Repo>) -> Fallible<u8> + 'static,
|
||||
{
|
||||
fn register(&mut self, f: FN, name: &str, doc: &str) {
|
||||
self.insert_aliases(name);
|
||||
let func =
|
||||
move |opts: ParseOutput, io: &mut IO, repo: Option<Repo>| f(opts.try_into()?, io, repo);
|
||||
let func = CommandFunc::OptionalRepo(Box::new(func));
|
||||
@ -116,6 +140,7 @@ where
|
||||
FN: Fn(S, &mut IO, Repo) -> Fallible<u8> + 'static,
|
||||
{
|
||||
fn register(&mut self, f: FN, name: &str, doc: &str) {
|
||||
self.insert_aliases(name);
|
||||
let func = move |opts: ParseOutput, io: &mut IO, repo: Repo| f(opts.try_into()?, io, repo);
|
||||
let func = CommandFunc::Repo(Box::new(func));
|
||||
let def = CommandDefinition::new(name, doc, S::flags, func);
|
||||
|
@ -234,16 +234,17 @@ pub fn dispatch(command_table: &CommandTable, args: Vec<String>, io: &mut IO) ->
|
||||
let command_name = first_arg.to_string();
|
||||
let (expanded, _first_arg_index) = expand_aliases(alias_lookup, &args[first_arg_index..])?;
|
||||
let (command_name, command_arg_len) =
|
||||
find_command_name(|name| command_table.contains_key(name), &expanded)
|
||||
find_command_name(|name| command_table.get(name).is_some(), &expanded)
|
||||
.ok_or_else(|| errors::UnknownCommand(command_name))?;
|
||||
|
||||
let mut new_args = Vec::with_capacity(args.len());
|
||||
new_args.extend_from_slice(&args[..first_arg_index]);
|
||||
new_args.push(command_name.clone());
|
||||
new_args.extend_from_slice(&expanded[command_arg_len..]);
|
||||
|
||||
let full_args = new_args;
|
||||
|
||||
let def = &command_table[&command_name];
|
||||
let def = command_table.get(&command_name).unwrap();
|
||||
let parsed = parse(&def, &full_args)?;
|
||||
|
||||
let global_opts: HgGlobalOpts = parsed.clone().try_into()?;
|
||||
|
@ -39,7 +39,7 @@ pub fn table() -> CommandTable {
|
||||
"debugstore",
|
||||
"print information about blobstore",
|
||||
);
|
||||
table.register(debugpython, "debugpython", "run python interpreter");
|
||||
table.register(debugpython, "debugpython|debugpy", "run python interpreter");
|
||||
table.register(debugargs, "debug-args", "print arguments received");
|
||||
table.register(
|
||||
debugindexedlogdump,
|
||||
|
Loading…
Reference in New Issue
Block a user