mod clip;
mod commands;
mod creds;
mod engines;
mod history;
mod ini;
mod reach;
mod settings;
mod snippets;
mod sshhosts;
mod tui;
mod tunnels;
mod vias;
use clap::{Parser, Subcommand};
const TEMPLATE: &str =
"{about-with-newline}\n{usage-heading} {usage}\n\n{before-help}{all-args}{after-help}\n";
const WAYS: &str = "\x1b[1mWays to run it (not subcommands):\x1b[0m
esql open the toolbox (TUI): connections, passwords, tunnels, saved queries
esql <name> open a saved connection (e.g. `esql prod`, or `esql pg:prod`)
esql <name>/<db> the same connection, another database on that server
esql <name> 'select 1' run one query and exit, the way `ssh host 'cmd'` does
esql <name> :<query> run a saved query (see the Snippets tab)
esql <name> [client args] anything else goes to the client (`esql prod -c 'select 1'`)";
const AFTER: &str = concat!(
"\
Rows go to stdout and easysql's own words to stderr. Once the client starts,
the exit code is the client's; before that easysql exits 2 for a name, snippet
or `/db` it cannot use, 127 when there is no client to run, and 1 when a tunnel
it needs will not open or a read-only connection would not be read-only.
Everything after `--` reaches the client untouched.
Run `esql <command> --help` for a command's details.",
"\n\n",
env!("CARGO_PKG_REPOSITORY"),
"\ncontributors: ",
env!("CARGO_PKG_AUTHORS"),
);
const LONG_VERSION: &str = concat!(
env!("CARGO_PKG_VERSION"),
"\n",
env!("CARGO_PKG_LICENSE"),
" ",
env!("CARGO_PKG_REPOSITORY"),
"\ncontributors: ",
env!("CARGO_PKG_AUTHORS"),
);
#[derive(Parser)]
#[command(
name = "easysql",
bin_name = "esql",
version,
long_version = LONG_VERSION,
about,
help_template = TEMPLATE,
before_help = WAYS,
after_help = AFTER
)]
struct Cli {
#[command(subcommand)]
command: Option<Cmd>,
}
#[derive(Subcommand)]
enum Cmd {
#[command(verbatim_doc_comment)]
Ls(commands::ls::Args),
#[command(name = "self", subcommand)]
Selfie(commands::selfcmd::Cmd),
#[command(external_subcommand)]
Connect(Vec<String>),
}
fn main() {
let cli = Cli::parse();
match cli.command {
None => {
if let Err(e) = tui::run() {
eprintln!("esql: {e}");
std::process::exit(1);
}
}
Some(Cmd::Ls(args)) => commands::ls::run(args),
Some(Cmd::Selfie(cmd)) => commands::selfcmd::run(cmd),
Some(Cmd::Connect(args)) => commands::connect::run(args),
}
}