display name in clap is buggy

This commit is contained in:
pedrocarlo
2025-03-07 15:27:14 -03:00
parent 02c466cb1f
commit fe25035c7c
7 changed files with 78 additions and 143 deletions

View File

@@ -20,7 +20,7 @@ path = "main.rs"
[dependencies]
anyhow = "1.0.75"
clap = { version = "4.5", features = ["derive"] }
clap = { version = "4.5.31", features = ["derive", "debug"] }
comfy-table = "7.1.4"
dirs = "5.0.1"
env_logger = "0.10.1"

View File

@@ -1,7 +1,7 @@
use crate::{
commands::{args::EchoMode, import::ImportFile, Command, CommandParser},
helper::LimboHelper,
input::{get_io, get_writer, DbLocation, OutputMode, Settings},
input::{get_io, get_writer, DbLocation, Io, OutputMode, Settings},
opcodes_dictionary::OPCODE_DESCRIPTIONS,
};
use comfy_table::{Attribute, Cell, CellAlignment, Color, ContentArrangement, Row, Table};
@@ -308,11 +308,6 @@ impl<'a> Limbo<'a> {
EchoMode::On => self.opts.echo = true,
EchoMode::Off => self.opts.echo = false,
}
// match arg.trim().to_lowercase().as_str() {
// "on" => self.opts.echo = true,
// "off" => self.opts.echo = false,
// _ => {}
// }
}
fn open_db(&mut self, path: &str, vfs_name: Option<&str>) -> anyhow::Result<()> {
@@ -471,18 +466,12 @@ impl<'a> Limbo<'a> {
if args.is_empty() {
return;
}
// else {
// // let _ = self.write_fmt(format_args!(
// // "Unknown command: {}\nenter: .help for all available commands",
// // args[0]
// // ));
match CommandParser::try_parse_from(args) {
Err(err) => {
let _ = self.write_fmt(format_args!("{err}"));
}
Ok(cmd) => match cmd.command {
Command::Exit(args) => {
// let code = args.get(1).and_then(|c| c.parse::<i32>().ok()).unwrap_or(0);
std::process::exit(args.code);
}
Command::Quit => {
@@ -526,16 +515,6 @@ impl<'a> Limbo<'a> {
let _ = self.write_fmt(format_args!("{}", e));
}
}
// OutputMode::from_str(args[1], true) {
// Ok(mode) => {
// if let Err(e) = self.set_mode(mode) {
// let _ = self.write_fmt(format_args!("Error: {}", e));
// }
// }
// Err(e) => {
// let _ = self.writeln(e);
// }
// },
Command::SetOutput(args) => {
if let Some(path) = args.path {
if let Err(e) = self.set_output_file(&path) {
@@ -554,16 +533,10 @@ impl<'a> Limbo<'a> {
Command::ShowInfo => {
let _ = self.show_info();
}
// Command::Help => {
// let _ = self.writeln(HELP_MSG);
// }
Command::Import(args) => {
let mut import_file =
ImportFile::new(self.conn.clone(), self.io.clone(), &mut self.writer);
import_file.import(args)
// if let Err(e) = import_file.import(args) {
// let _ = self.writeln(e.to_string());
// };
}
Command::LoadExtension(args) => {
#[cfg(not(target_family = "wasm"))]

View File

@@ -1,19 +1,6 @@
use anyhow::Error;
use clap::{Parser, Subcommand, Args};
use clap::Args;
use limbo_core::Connection;
use std::{
fs::File,
io::Write,
path::PathBuf,
rc::Rc,
sync::{Arc, LazyLock},
};
// pub static IMPORT_HELP: LazyLock<String> = LazyLock::new(|| {
// let empty: [&'static str; 2] = [".import", "--help"];
// let opts = ImportArgs::try_parse_from(empty);
// opts.map_err(|e| e.to_string()).unwrap_err()
// });
use std::{fs::File, io::Write, path::PathBuf, rc::Rc, sync::Arc};
#[derive(Debug, Clone, Args)]
pub struct ImportArgs {
@@ -47,14 +34,6 @@ impl<'a> ImportFile<'a> {
pub fn import(&mut self, args: ImportArgs) {
self.import_csv(args);
// let import_args = ImportArgs::try_parse_from(args.iter());
// match import_args {
// Ok(args) => {
// self.import_csv(args);
// Ok(())
// }
// Err(err) => Err(anyhow::anyhow!(err.to_string())),
// }
}
pub fn import_csv(&mut self, args: ImportArgs) {

View File

@@ -15,7 +15,8 @@ use crate::input::{AFTER_HELP_MSG, BEFORE_HELP_MSG};
multicall = true,
arg_required_else_help(false),
before_help(BEFORE_HELP_MSG),
after_help(AFTER_HELP_MSG)
after_help(AFTER_HELP_MSG),
// help_template(HELP_TEMPLATE)
)]
pub struct CommandParser {
#[command(subcommand)]
@@ -26,126 +27,69 @@ pub struct CommandParser {
#[command(disable_help_flag(false), disable_version_flag(true))]
pub enum Command {
/// Exit this program with return-code CODE
#[command(subcommand_value_name = ".exit")]
#[command(display_name = ".exit")]
Exit(ExitArgs),
/// Quit the shell
#[command(subcommand_value_name = ".quit")]
#[command(display_name = ".quit")]
Quit,
/// Open a database file
#[command(subcommand_value_name = ".open")]
#[command(display_name = ".open")]
Open(OpenArgs),
// Display help message
/// Print this message or the help of the given subcommand(s)
// #[command(display_name = ".help")]
// Help,
/// Display schema for a table
#[command(subcommand_value_name = ".schema")]
#[command(display_name = ".schema")]
Schema(SchemaArgs),
/// Set output file (or stdout if empty)
#[command(name = "output", subcommand_value_name = ".output")]
#[command(name = "output", display_name = ".output")]
SetOutput(SetOutputArgs),
/// Set output display mode
#[command(
name = "mode",
subcommand_value_name = ".mode",
arg_required_else_help(false)
)]
#[command(name = "mode", display_name = ".mode", arg_required_else_help(false))]
OutputMode(OutputModeArgs),
/// Show vdbe opcodes
#[command(subcommand_value_name = ".opcodes")]
#[command(name = "opcodes", display_name = ".opcodes")]
Opcodes(OpcodesArgs),
/// Change the current working directory
#[command(name = "cd", subcommand_value_name = ".cd")]
#[command(name = "cd", display_name = ".cd")]
Cwd(CwdArgs),
/// Display information about settings
#[command(name = "show")]
#[command(name = "show", display_name = ".show")]
ShowInfo,
/// Set the value of NULL to be printed in 'list' mode
#[command(name = "nullvalue", subcommand_value_name = ".nullvalue")]
#[command(name = "nullvalue", display_name = ".nullvalue")]
NullValue(NullValueArgs),
/// Toggle 'echo' mode to repeat commands before execution
#[command(subcommand_value_name = ".echo")]
#[command(display_name = ".echo")]
Echo(EchoArgs),
/// Display tables
#[command(subcommand_value_name = ".tables")]
Tables(TablesArgs),
/// Import data from FILE into TABLE
#[command(subcommand_value_name = ".import")]
#[command(name = "import", display_name = ".import")]
Import(ImportArgs),
/// Loads an extension library
#[command(name = "load", subcommand_value_name = ".load")]
#[command(name = "load", display_name = ".load")]
LoadExtension(LoadExtensionArgs),
/// Dump the current database as a list of SQL statements
#[command(subcommand_value_name = ".dump")]
Dump,
/// List vfs modules available
#[command(name = "listvfs", subcommand_value_name = ".dump")]
ListVfs,
}
// impl Command {
// pub fn min_args(&self) -> usize {
// 1 + match self {
// Self::Exit
// | Self::Quit
// | Self::Schema
// | Self::Help
// | Self::Opcodes
// | Self::ShowInfo
// | Self::Tables
// | Self::SetOutput
// | Self::Dump => 0,
// Self::Open
// | Self::OutputMode
// | Self::Cwd
// | Self::Echo
// | Self::NullValue
// | Self::LoadExtension => 1,
// Self::Import => 2,
// }
// }
const _HELP_TEMPLATE: &str = "{before-help}{name}
{usage-heading} {usage}
// pub fn usage(&self) -> &str {
// match self {
// Self::Exit => ".exit ?<CODE>",
// Self::Quit => ".quit",
// Self::Open => ".open <file>",
// Self::Help => ".help",
// Self::Schema => ".schema ?<table>?",
// Self::Opcodes => ".opcodes",
// Self::OutputMode => ".mode list|pretty",
// Self::SetOutput => ".output ?file?",
// Self::Cwd => ".cd <directory>",
// Self::ShowInfo => ".show",
// Self::NullValue => ".nullvalue <string>",
// Self::Echo => ".echo on|off",
// Self::Tables => ".tables",
// Self::LoadExtension => ".load",
// Self::Dump => ".dump",
// Self::Import => &IMPORT_HELP,
// }
// }
// }
{all-args}{after-help}
";
// impl FromStr for Command {
// type Err = String;
// fn from_str(s: &str) -> Result<Self, Self::Err> {
// match s {
// ".exit" => Ok(Self::Exit),
// ".quit" => Ok(Self::Quit),
// ".open" => Ok(Self::Open),
// ".help" => Ok(Self::Help),
// ".schema" => Ok(Self::Schema),
// ".tables" => Ok(Self::Tables),
// ".opcodes" => Ok(Self::Opcodes),
// ".mode" => Ok(Self::OutputMode),
// ".output" => Ok(Self::SetOutput),
// ".cd" => Ok(Self::Cwd),
// ".show" => Ok(Self::ShowInfo),
// ".nullvalue" => Ok(Self::NullValue),
// ".echo" => Ok(Self::Echo),
// ".import" => Ok(Self::Import),
// ".load" => Ok(Self::LoadExtension),
// ".dump" => Ok(Self::Dump),
// _ => Err("Unknown command".to_string()),
// }
// }
// }
#[cfg(test)]
mod tests {
use super::CommandParser;
#[test]
fn cli_assert() {
use clap::CommandFactory;
CommandParser::command().debug_assert();
}
}

View File

@@ -168,7 +168,7 @@ pub fn get_io(db_location: DbLocation, io_choice: &str) -> anyhow::Result<Arc<dy
})
}
pub const HELP_MSG: &str = r#"
pub const _HELP_MSG: &str = r#"
Limbo SQL Shell Help
==============
Welcome to the Limbo SQL Shell! You can execute any standard SQL command here.
@@ -239,6 +239,44 @@ Limbo SQL Shell Help
==============
Welcome to the Limbo SQL Shell! You can execute any standard SQL command here.
In addition to standard SQL commands, the following special commands are available:"#;
pub const AFTER_HELP_MSG: &str = r#"Note:
pub const AFTER_HELP_MSG: &str = r#"Usage Examples:
---------------
1. To quit the Limbo SQL Shell:
.quit
2. To open a database file at path './employees.db':
.open employees.db
3. To view the schema of a table named 'employees':
.schema employees
4. To list all tables:
.tables
5. To list all available SQL opcodes:
.opcodes
6. To change the current output mode to 'pretty':
.mode pretty
7. Send output to STDOUT if no file is specified:
.output
8. To change the current working directory to '/tmp':
.cd /tmp
9. Show the current values of settings:
.show
10. To import csv file 'sample.csv' into 'csv_table' table:
.import --csv sample.csv csv_table
11. To display the database contents as SQL:
.dump
12. To load an extension library:
.load /target/debug/liblimbo_regexp
Note:
- All SQL commands must end with a semicolon (;).
- Special commands start with a dot and do not require a semicolon."#;
- Special commands start with a dot (.) and are not required to end with a semicolon."#;

View File

@@ -1,9 +1,9 @@
#![allow(clippy::arc_with_non_send_sync)]
mod app;
mod commands;
mod helper;
mod input;
mod opcodes_dictionary;
mod commands;
use rustyline::{error::ReadlineError, Config, Editor};
use std::sync::atomic::Ordering;