aboutsummaryrefslogtreecommitdiffstats
path: root/crates/turtle/src/command/client.rs
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-06-12 01:54:21 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-06-12 01:54:21 +0200
commitbbdf38018b47328b5faa2cef635c37095045be72 (patch)
tree8983817d547551ae12508a8ae8731b622d990af4 /crates/turtle/src/command/client.rs
parentfeat(server): Make user stuff stateless (diff)
downloadatuin-bbdf38018b47328b5faa2cef635c37095045be72.zip
feat(server): Really make users stateless (with tests)
This commit also remove another load of unneeded features.
Diffstat (limited to 'crates/turtle/src/command/client.rs')
-rw-r--r--crates/turtle/src/command/client.rs56
1 files changed, 25 insertions, 31 deletions
diff --git a/crates/turtle/src/command/client.rs b/crates/turtle/src/command/client.rs
index 9d5b4605..9ab28e15 100644
--- a/crates/turtle/src/command/client.rs
+++ b/crates/turtle/src/command/client.rs
@@ -5,7 +5,7 @@ use clap::Subcommand;
use eyre::{Result, WrapErr};
use crate::atuin_client::{
- database::Sqlite, record::sqlite_store::SqliteStore, settings::Settings, theme,
+ database::ClientSqlite, record::sqlite_store::SqliteStore, settings::Settings, theme,
};
use tracing_appender::rolling::{RollingFileAppender, Rotation};
use tracing_subscriber::{
@@ -48,9 +48,7 @@ mod daemon;
mod config;
mod default_config;
-mod doctor;
mod history;
-mod import;
mod info;
mod init;
mod search;
@@ -66,18 +64,12 @@ pub(crate) enum Cmd {
#[command(subcommand)]
History(history::Cmd),
- /// Import shell history from file
- #[command(subcommand)]
- Import(import::Cmd),
-
- /// Calculate statistics for your history
- Stats(stats::Cmd),
-
/// Interactive history search
Search(search::Cmd),
#[cfg(feature = "sync")]
- #[command(flatten)]
+ #[command(subcommand)]
+ /// Request a sync or view sync status
Sync(sync::Cmd),
/// Manage the atuin server
@@ -96,11 +88,11 @@ pub(crate) enum Cmd {
#[command()]
Info,
- /// Run the doctor to check for common issues
- #[command()]
- Doctor,
+ /// Calculate statistics for your history
+ Stats(stats::Cmd),
#[command()]
+ /// Display a recap of your last year's history
Wrapped { year: Option<i32> },
/// *Experimental* Manage the background daemon
@@ -113,6 +105,7 @@ pub(crate) enum Cmd {
DefaultConfig,
#[command(subcommand)]
+ /// Manage your configuration
Config(config::Cmd),
}
@@ -131,19 +124,27 @@ impl Cmd {
let runtime = runtime.enable_all().build().unwrap();
- // For non-history commands, we want to initialize logging and the theme manager before
- // doing anything else. History commands are performance-sensitive and run before and after
- // every shell command, so we want to skip any unnecessary initialization for them.
- let settings = Settings::new().wrap_err("could not load client settings")?;
- let theme_manager = theme::ThemeManager::new(settings.theme.debug, None);
- let res = runtime.block_on(self.run_inner(settings, theme_manager));
+ // Start the server before descending into the client-specific setup code.
+ // We simply cannot setup settings or a theme on the server, because the client-specific
+ // stuff will error out.
+ let res = if let Self::Server(server) = self {
+ runtime.block_on(server.run())
+ } else {
+ // For non-history commands, we want to initialize logging and the theme manager before
+ // doing anything else. History commands are performance-sensitive and run before and after
+ // every shell command, so we want to skip any unnecessary initialization for them.
+ let settings = Settings::new().wrap_err("could not load client settings")?;
+ let theme_manager = theme::ThemeManager::new(settings.theme.debug, None);
+
+ runtime.block_on(self.run_inner(settings, theme_manager))
+ };
runtime.shutdown_timeout(std::time::Duration::from_millis(50));
res
}
- #[expect(clippy::too_many_lines, clippy::future_not_send)]
+ #[expect(clippy::too_many_lines)]
async fn run_inner(
self,
mut settings: Settings,
@@ -306,7 +307,6 @@ impl Cmd {
init.run(&settings);
return Ok(());
}
- Self::Doctor => return doctor::run(&settings).await,
Self::Config(config) => return config.run(&settings).await,
_ => {}
}
@@ -314,14 +314,13 @@ impl Cmd {
let db_path = PathBuf::from(settings.db_path.as_str());
let record_store_path = PathBuf::from(settings.record_store_path.as_str());
- let db = Sqlite::new(db_path, settings.local_timeout).await?;
+ let db = ClientSqlite::new(db_path, settings.local_timeout).await?;
let sqlite_store = SqliteStore::new(record_store_path, settings.local_timeout).await?;
let theme_name = settings.theme.name.clone();
let theme = theme_manager.load_theme(theme_name.as_str(), settings.theme.max_depth);
match self {
- Self::Import(import) => import.run(&db).await,
Self::Stats(stats) => stats.run(&db, &settings, theme).await,
Self::Search(search) => search.run(db, &mut settings, sqlite_store, theme).await,
@@ -330,12 +329,7 @@ impl Cmd {
Self::Store(store) => store.run(&settings, &db, sqlite_store).await,
- Self::Server(server) => server.run().await,
-
- Self::Info => {
- info::run(&settings);
- Ok(())
- }
+ Self::Info => info::run(&settings),
Self::DefaultConfig => {
default_config::run();
@@ -347,7 +341,7 @@ impl Cmd {
#[cfg(feature = "daemon")]
Self::Daemon(cmd) => cmd.run(settings, sqlite_store, db).await,
- Self::History(_) | Self::Init(_) | Self::Doctor | Self::Config(_) => {
+ Self::History(_) | Self::Init(_) | Self::Config(_) | Self::Server(_) => {
unreachable!()
}
}