refactor commands for better separation (#313)
* refactor commands for better separation * fmt
This commit is contained in:
parent
24e2971787
commit
d57f549855
14 changed files with 226 additions and 204 deletions
133
src/command/client.rs
Normal file
133
src/command/client.rs
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
use clap::CommandFactory;
|
||||||
|
use clap::Subcommand;
|
||||||
|
use clap_complete::Shell;
|
||||||
|
use clap_complete::{generate, generate_to};
|
||||||
|
use eyre::{Result, WrapErr};
|
||||||
|
|
||||||
|
use atuin_client::database::Sqlite;
|
||||||
|
use atuin_client::settings::Settings;
|
||||||
|
use atuin_common::utils::uuid_v4;
|
||||||
|
|
||||||
|
mod event;
|
||||||
|
mod history;
|
||||||
|
mod import;
|
||||||
|
mod init;
|
||||||
|
mod login;
|
||||||
|
mod logout;
|
||||||
|
mod register;
|
||||||
|
mod search;
|
||||||
|
mod stats;
|
||||||
|
mod sync;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
#[clap(infer_subcommands = true)]
|
||||||
|
pub enum Cmd {
|
||||||
|
/// Manipulate shell history
|
||||||
|
#[clap(subcommand)]
|
||||||
|
History(history::Cmd),
|
||||||
|
|
||||||
|
/// Import shell history from file
|
||||||
|
#[clap(subcommand)]
|
||||||
|
Import(import::Cmd),
|
||||||
|
|
||||||
|
/// Calculate statistics for your history
|
||||||
|
#[clap(subcommand)]
|
||||||
|
Stats(stats::Cmd),
|
||||||
|
|
||||||
|
/// Output shell setup
|
||||||
|
#[clap(subcommand)]
|
||||||
|
Init(init::Cmd),
|
||||||
|
|
||||||
|
/// Generate a UUID
|
||||||
|
Uuid,
|
||||||
|
|
||||||
|
/// Interactive history search
|
||||||
|
Search(search::Cmd),
|
||||||
|
|
||||||
|
/// Sync with the configured server
|
||||||
|
Sync {
|
||||||
|
/// Force re-download everything
|
||||||
|
#[clap(long, short)]
|
||||||
|
force: bool,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Login to the configured server
|
||||||
|
Login(login::Cmd),
|
||||||
|
|
||||||
|
/// Log out
|
||||||
|
Logout,
|
||||||
|
|
||||||
|
/// Register with the configured server
|
||||||
|
Register(register::Cmd),
|
||||||
|
|
||||||
|
/// Print the encryption key for transfer to another machine
|
||||||
|
Key,
|
||||||
|
|
||||||
|
/// Generate shell completions
|
||||||
|
GenCompletions {
|
||||||
|
/// Set the shell for generating completions
|
||||||
|
#[clap(long, short)]
|
||||||
|
shell: Shell,
|
||||||
|
|
||||||
|
/// Set the output directory
|
||||||
|
#[clap(long, short)]
|
||||||
|
out_dir: Option<String>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cmd {
|
||||||
|
pub async fn run(self) -> Result<()> {
|
||||||
|
pretty_env_logger::init();
|
||||||
|
|
||||||
|
let settings = Settings::new().wrap_err("could not load client settings")?;
|
||||||
|
|
||||||
|
let db_path = PathBuf::from(settings.db_path.as_str());
|
||||||
|
let mut db = Sqlite::new(db_path).await?;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Self::History(history) => history.run(&settings, &mut db).await,
|
||||||
|
Self::Import(import) => import.run(&mut db).await,
|
||||||
|
Self::Stats(stats) => stats.run(&mut db, &settings).await,
|
||||||
|
Self::Init(init) => {
|
||||||
|
init.run();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Self::Search(search) => search.run(&mut db, &settings).await,
|
||||||
|
Self::Sync { force } => sync::run(&settings, force, &mut db).await,
|
||||||
|
Self::Login(l) => l.run(&settings).await,
|
||||||
|
Self::Logout => logout::run(),
|
||||||
|
Self::Register(r) => r.run(&settings).await,
|
||||||
|
Self::Key => {
|
||||||
|
use atuin_client::encryption::{encode_key, load_key};
|
||||||
|
let key = load_key(&settings).wrap_err("could not load encryption key")?;
|
||||||
|
let encode = encode_key(key).wrap_err("could not encode encryption key")?;
|
||||||
|
println!("{}", encode);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Self::Uuid => {
|
||||||
|
println!("{}", uuid_v4());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Self::GenCompletions { shell, out_dir } => {
|
||||||
|
let mut cli = crate::Atuin::command();
|
||||||
|
|
||||||
|
match out_dir {
|
||||||
|
Some(out_dir) => {
|
||||||
|
generate_to(shell, &mut cli, env!("CARGO_PKG_NAME"), &out_dir)?;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
generate(
|
||||||
|
shell,
|
||||||
|
&mut cli,
|
||||||
|
env!("CARGO_PKG_NAME"),
|
||||||
|
&mut std::io::stdout(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,17 +11,17 @@ pub enum Cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_zsh() {
|
fn init_zsh() {
|
||||||
let full = include_str!("../shell/atuin.zsh");
|
let full = include_str!("../../shell/atuin.zsh");
|
||||||
println!("{}", full);
|
println!("{}", full);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_bash() {
|
fn init_bash() {
|
||||||
let full = include_str!("../shell/atuin.bash");
|
let full = include_str!("../../shell/atuin.bash");
|
||||||
println!("{}", full);
|
println!("{}", full);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_fish() {
|
fn init_fish() {
|
||||||
let full = include_str!("../shell/atuin.fish");
|
let full = include_str!("../../shell/atuin.fish");
|
||||||
println!("{}", full);
|
println!("{}", full);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
|
use eyre::{Context, Result};
|
||||||
use fs_err::remove_file;
|
use fs_err::remove_file;
|
||||||
|
|
||||||
pub fn run() {
|
pub fn run() -> Result<()> {
|
||||||
let session_path = atuin_common::utils::data_dir().join("session");
|
let session_path = atuin_common::utils::data_dir().join("session");
|
||||||
|
|
||||||
if session_path.exists() {
|
if session_path.exists() {
|
||||||
remove_file(session_path.as_path()).expect("Failed to remove session file");
|
remove_file(session_path.as_path()).context("Failed to remove session file")?;
|
||||||
println!("You have logged out!");
|
println!("You have logged out!");
|
||||||
} else {
|
} else {
|
||||||
println!("You are not logged in");
|
println!("You are not logged in");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
|
@ -19,6 +19,12 @@ pub struct Cmd {
|
||||||
pub password: Option<String>,
|
pub password: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Cmd {
|
||||||
|
pub async fn run(self, settings: &Settings) -> Result<()> {
|
||||||
|
run(settings, &self.username, &self.email, &self.password).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn run(
|
pub async fn run(
|
||||||
settings: &Settings,
|
settings: &Settings,
|
||||||
username: &Option<String>,
|
username: &Option<String>,
|
|
@ -1,7 +1,7 @@
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
|
use clap::Parser;
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
use std::{io::stdout, ops::Sub, time::Duration};
|
use std::{io::stdout, ops::Sub, time::Duration};
|
||||||
|
|
||||||
use termion::{event::Key, input::MouseTerminal, raw::IntoRawMode, screen::AlternateScreen};
|
use termion::{event::Key, input::MouseTerminal, raw::IntoRawMode, screen::AlternateScreen};
|
||||||
use tui::{
|
use tui::{
|
||||||
backend::{Backend, TermionBackend},
|
backend::{Backend, TermionBackend},
|
||||||
|
@ -19,10 +19,75 @@ use atuin_client::{
|
||||||
settings::{SearchMode, Settings},
|
settings::{SearchMode, Settings},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::command::event::{Event, Events};
|
use super::event::{Event, Events};
|
||||||
|
|
||||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
pub struct Cmd {
|
||||||
|
/// Filter search result by directory
|
||||||
|
#[clap(long, short)]
|
||||||
|
cwd: Option<String>,
|
||||||
|
|
||||||
|
/// Exclude directory from results
|
||||||
|
#[clap(long = "exclude-cwd")]
|
||||||
|
exclude_cwd: Option<String>,
|
||||||
|
|
||||||
|
/// Filter search result by exit code
|
||||||
|
#[clap(long, short)]
|
||||||
|
exit: Option<i64>,
|
||||||
|
|
||||||
|
/// Exclude results with this exit code
|
||||||
|
#[clap(long = "exclude-exit")]
|
||||||
|
exclude_exit: Option<i64>,
|
||||||
|
|
||||||
|
/// Only include results added before this date
|
||||||
|
#[clap(long, short)]
|
||||||
|
before: Option<String>,
|
||||||
|
|
||||||
|
/// Only include results after this date
|
||||||
|
#[clap(long)]
|
||||||
|
after: Option<String>,
|
||||||
|
|
||||||
|
/// Open interactive search UI
|
||||||
|
#[clap(long, short)]
|
||||||
|
interactive: bool,
|
||||||
|
|
||||||
|
/// Use human-readable formatting for time
|
||||||
|
#[clap(long)]
|
||||||
|
human: bool,
|
||||||
|
|
||||||
|
query: Vec<String>,
|
||||||
|
|
||||||
|
/// Show only the text of the command
|
||||||
|
#[clap(long)]
|
||||||
|
cmd_only: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cmd {
|
||||||
|
pub async fn run(
|
||||||
|
self,
|
||||||
|
db: &mut (impl Database + Send + Sync),
|
||||||
|
settings: &Settings,
|
||||||
|
) -> Result<()> {
|
||||||
|
run(
|
||||||
|
settings,
|
||||||
|
self.cwd,
|
||||||
|
self.exit,
|
||||||
|
self.interactive,
|
||||||
|
self.human,
|
||||||
|
self.exclude_exit,
|
||||||
|
self.exclude_cwd,
|
||||||
|
self.before,
|
||||||
|
self.after,
|
||||||
|
self.cmd_only,
|
||||||
|
&self.query,
|
||||||
|
db,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
input: String,
|
input: String,
|
||||||
|
|
|
@ -1,212 +1,25 @@
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use clap::CommandFactory;
|
|
||||||
use clap::Subcommand;
|
use clap::Subcommand;
|
||||||
use clap_complete::Shell;
|
use eyre::Result;
|
||||||
use clap_complete::{generate, generate_to};
|
|
||||||
use eyre::{Result, WrapErr};
|
|
||||||
|
|
||||||
use atuin_client::database::Sqlite;
|
mod client;
|
||||||
use atuin_client::settings::Settings as ClientSettings;
|
|
||||||
use atuin_common::utils::uuid_v4;
|
|
||||||
use atuin_server::settings::Settings as ServerSettings;
|
|
||||||
|
|
||||||
mod event;
|
|
||||||
mod history;
|
|
||||||
mod import;
|
|
||||||
mod init;
|
|
||||||
mod login;
|
|
||||||
mod logout;
|
|
||||||
mod register;
|
|
||||||
mod search;
|
|
||||||
mod server;
|
mod server;
|
||||||
mod stats;
|
|
||||||
mod sync;
|
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
#[clap(infer_subcommands = true)]
|
#[clap(infer_subcommands = true)]
|
||||||
pub enum AtuinCmd {
|
pub enum AtuinCmd {
|
||||||
/// Manipulate shell history
|
#[clap(flatten)]
|
||||||
#[clap(subcommand)]
|
Client(client::Cmd),
|
||||||
History(history::Cmd),
|
|
||||||
|
|
||||||
/// Import shell history from file
|
|
||||||
#[clap(subcommand)]
|
|
||||||
Import(import::Cmd),
|
|
||||||
|
|
||||||
/// Start an atuin server
|
/// Start an atuin server
|
||||||
#[clap(subcommand)]
|
#[clap(subcommand)]
|
||||||
Server(server::Cmd),
|
Server(server::Cmd),
|
||||||
|
|
||||||
/// Calculate statistics for your history
|
|
||||||
#[clap(subcommand)]
|
|
||||||
Stats(stats::Cmd),
|
|
||||||
|
|
||||||
/// Output shell setup
|
|
||||||
#[clap(subcommand)]
|
|
||||||
Init(init::Cmd),
|
|
||||||
|
|
||||||
/// Generate a UUID
|
|
||||||
Uuid,
|
|
||||||
|
|
||||||
/// Interactive history search
|
|
||||||
Search {
|
|
||||||
/// Filter search result by directory
|
|
||||||
#[clap(long, short)]
|
|
||||||
cwd: Option<String>,
|
|
||||||
|
|
||||||
/// Exclude directory from results
|
|
||||||
#[clap(long = "exclude-cwd")]
|
|
||||||
exclude_cwd: Option<String>,
|
|
||||||
|
|
||||||
/// Filter search result by exit code
|
|
||||||
#[clap(long, short)]
|
|
||||||
exit: Option<i64>,
|
|
||||||
|
|
||||||
/// Exclude results with this exit code
|
|
||||||
#[clap(long = "exclude-exit")]
|
|
||||||
exclude_exit: Option<i64>,
|
|
||||||
|
|
||||||
/// Only include results added before this date
|
|
||||||
#[clap(long, short)]
|
|
||||||
before: Option<String>,
|
|
||||||
|
|
||||||
/// Only include results after this date
|
|
||||||
#[clap(long)]
|
|
||||||
after: Option<String>,
|
|
||||||
|
|
||||||
/// Open interactive search UI
|
|
||||||
#[clap(long, short)]
|
|
||||||
interactive: bool,
|
|
||||||
|
|
||||||
/// Use human-readable formatting for time
|
|
||||||
#[clap(long)]
|
|
||||||
human: bool,
|
|
||||||
|
|
||||||
query: Vec<String>,
|
|
||||||
|
|
||||||
/// Show only the text of the command
|
|
||||||
#[clap(long)]
|
|
||||||
cmd_only: bool,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// Sync with the configured server
|
|
||||||
Sync {
|
|
||||||
/// Force re-download everything
|
|
||||||
#[clap(long, short)]
|
|
||||||
force: bool,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// Login to the configured server
|
|
||||||
Login(login::Cmd),
|
|
||||||
|
|
||||||
/// Log out
|
|
||||||
Logout,
|
|
||||||
|
|
||||||
/// Register with the configured server
|
|
||||||
Register(register::Cmd),
|
|
||||||
|
|
||||||
/// Print the encryption key for transfer to another machine
|
|
||||||
Key,
|
|
||||||
|
|
||||||
/// Generate shell completions
|
|
||||||
GenCompletions {
|
|
||||||
/// Set the shell for generating completions
|
|
||||||
#[clap(long, short)]
|
|
||||||
shell: Shell,
|
|
||||||
|
|
||||||
/// Set the output directory
|
|
||||||
#[clap(long, short)]
|
|
||||||
out_dir: Option<String>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AtuinCmd {
|
impl AtuinCmd {
|
||||||
pub async fn run(self) -> Result<()> {
|
pub async fn run(self) -> Result<()> {
|
||||||
let client_settings = ClientSettings::new().wrap_err("could not load client settings")?;
|
|
||||||
let server_settings = ServerSettings::new().wrap_err("could not load server settings")?;
|
|
||||||
|
|
||||||
let db_path = PathBuf::from(client_settings.db_path.as_str());
|
|
||||||
|
|
||||||
let mut db = Sqlite::new(db_path).await?;
|
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::History(history) => history.run(&client_settings, &mut db).await,
|
Self::Client(client) => client.run().await,
|
||||||
Self::Import(import) => import.run(&mut db).await,
|
Self::Server(server) => server.run().await,
|
||||||
Self::Server(server) => server.run(server_settings).await,
|
|
||||||
Self::Stats(stats) => stats.run(&mut db, &client_settings).await,
|
|
||||||
Self::Init(init) => {
|
|
||||||
init.run();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Self::Search {
|
|
||||||
cwd,
|
|
||||||
exit,
|
|
||||||
interactive,
|
|
||||||
human,
|
|
||||||
exclude_exit,
|
|
||||||
exclude_cwd,
|
|
||||||
before,
|
|
||||||
after,
|
|
||||||
query,
|
|
||||||
cmd_only,
|
|
||||||
} => {
|
|
||||||
search::run(
|
|
||||||
&client_settings,
|
|
||||||
cwd,
|
|
||||||
exit,
|
|
||||||
interactive,
|
|
||||||
human,
|
|
||||||
exclude_exit,
|
|
||||||
exclude_cwd,
|
|
||||||
before,
|
|
||||||
after,
|
|
||||||
cmd_only,
|
|
||||||
&query,
|
|
||||||
&mut db,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
Self::Sync { force } => sync::run(&client_settings, force, &mut db).await,
|
|
||||||
Self::Login(l) => l.run(&client_settings).await,
|
|
||||||
Self::Logout => {
|
|
||||||
logout::run();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Self::Register(r) => {
|
|
||||||
register::run(&client_settings, &r.username, &r.email, &r.password).await
|
|
||||||
}
|
|
||||||
Self::Key => {
|
|
||||||
use atuin_client::encryption::{encode_key, load_key};
|
|
||||||
let key = load_key(&client_settings).wrap_err("could not load encryption key")?;
|
|
||||||
let encode = encode_key(key).wrap_err("could not encode encryption key")?;
|
|
||||||
println!("{}", encode);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Self::Uuid => {
|
|
||||||
println!("{}", uuid_v4());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Self::GenCompletions { shell, out_dir } => {
|
|
||||||
let mut cli = crate::Atuin::command();
|
|
||||||
|
|
||||||
match out_dir {
|
|
||||||
Some(out_dir) => {
|
|
||||||
generate_to(shell, &mut cli, env!("CARGO_PKG_NAME"), &out_dir)?;
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
generate(
|
|
||||||
shell,
|
|
||||||
&mut cli,
|
|
||||||
env!("CARGO_PKG_NAME"),
|
|
||||||
&mut std::io::stdout(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use eyre::Result;
|
use eyre::{Context, Result};
|
||||||
|
|
||||||
use atuin_server::launch;
|
use atuin_server::launch;
|
||||||
use atuin_server::settings::Settings;
|
use atuin_server::settings::Settings;
|
||||||
|
@ -20,7 +20,11 @@ pub enum Cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cmd {
|
impl Cmd {
|
||||||
pub async fn run(&self, settings: Settings) -> Result<()> {
|
pub async fn run(self) -> Result<()> {
|
||||||
|
pretty_env_logger::init();
|
||||||
|
|
||||||
|
let settings = Settings::new().wrap_err("could not load server settings")?;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::Start { host, port } => {
|
Self::Start { host, port } => {
|
||||||
let host = host
|
let host = host
|
||||||
|
|
|
@ -33,7 +33,5 @@ impl Atuin {
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
pretty_env_logger::init();
|
|
||||||
|
|
||||||
Atuin::parse().run().await
|
Atuin::parse().run().await
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue