diff options
| author | Ellie Huxtable <ellie@elliehuxtable.com> | 2024-05-08 12:09:04 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-08 12:09:04 +0100 |
| commit | bce0faa1c2dc221b0ff77d2cd647bfb2a48ffa7e (patch) | |
| tree | 4d66bd95b151d3bab4cabf8799805c739f608bc4 /crates/atuin-client/src | |
| parent | fix(config): add quotes for strategy value in comment (#1993) (diff) | |
| download | atuin-bce0faa1c2dc221b0ff77d2cd647bfb2a48ffa7e.zip | |
feat: add background daemon (#2006)
* init daemon crate
* wip
* minimal functioning daemon, needs cleanup for sure
* better errors
* add signal cleanup
* logging
* things
* add sync worker
* move daemon crate
* 30s -> 5mins
* make clippy happy
* fix stuff maybe?
* fmt
* trim packages
* rate limit fix
* more protoc huh
* this makes no sense, why linux why
* can it install literally just curl
* windows in ci is slow, and all the newer things will not work there. disable the daemon feature and it will build
* add daemon feature
* maybe this
* ok wut where is protoc
* try setting protoc
* hm
* try copying protoc
* remove optional
* add cross config
* idk nix
* does nix want this?
* some random pkg I found does this
* uh oh
* hack, be gone!
* update contributing
Diffstat (limited to '')
| -rw-r--r-- | crates/atuin-client/src/database.rs | 1 | ||||
| -rw-r--r-- | crates/atuin-client/src/history.rs | 42 | ||||
| -rw-r--r-- | crates/atuin-client/src/history/builder.rs | 33 | ||||
| -rw-r--r-- | crates/atuin-client/src/settings.rs | 31 |
4 files changed, 107 insertions, 0 deletions
diff --git a/crates/atuin-client/src/database.rs b/crates/atuin-client/src/database.rs index 7faa3802..33156077 100644 --- a/crates/atuin-client/src/database.rs +++ b/crates/atuin-client/src/database.rs @@ -120,6 +120,7 @@ pub trait Database: Send + Sync + 'static { // Intended for use on a developer machine and not a sync server. // TODO: implement IntoIterator +#[derive(Debug)] pub struct Sqlite { pub pool: SqlitePool, } diff --git a/crates/atuin-client/src/history.rs b/crates/atuin-client/src/history.rs index 1b590e88..0503b43d 100644 --- a/crates/atuin-client/src/history.rs +++ b/crates/atuin-client/src/history.rs @@ -303,6 +303,48 @@ impl History { builder::HistoryCaptured::builder() } + /// Builder for a history entry that is captured via hook, and sent to the daemon. + /// + /// This builder is used only at the `start` step of the hook, + /// so it doesn't have any fields which are known only after + /// the command is finished, such as `exit` or `duration`. + /// + /// It does, however, include information that can usually be inferred. + /// + /// This is because the daemon we are sending a request to lacks the context of the command + /// + /// ## Examples + /// ```rust + /// use atuin_client::history::History; + /// + /// let history: History = History::daemon() + /// .timestamp(time::OffsetDateTime::now_utc()) + /// .command("ls -la") + /// .cwd("/home/user") + /// .session("018deb6e8287781f9973ef40e0fde76b") + /// .hostname("computer:ellie") + /// .build() + /// .into(); + /// ``` + /// + /// Command without any required info cannot be captured, which is forced at compile time: + /// + /// ```compile_fail + /// use atuin_client::history::History; + /// + /// // this will not compile because `hostname` is missing + /// let history: History = History::daemon() + /// .timestamp(time::OffsetDateTime::now_utc()) + /// .command("ls -la") + /// .cwd("/home/user") + /// .session("018deb6e8287781f9973ef40e0fde76b") + /// .build() + /// .into(); + /// ``` + pub fn daemon() -> builder::HistoryDaemonCaptureBuilder { + builder::HistoryDaemonCapture::builder() + } + /// Builder for a history entry that is imported from the database. /// /// All fields are required, as they are all present in the database. diff --git a/crates/atuin-client/src/history/builder.rs b/crates/atuin-client/src/history/builder.rs index 4e69cf66..2b28339f 100644 --- a/crates/atuin-client/src/history/builder.rs +++ b/crates/atuin-client/src/history/builder.rs @@ -97,3 +97,36 @@ impl From<HistoryFromDb> for History { } } } + +/// Builder for a history entry that is captured via hook and sent to the daemon +/// +/// This builder is similar to Capture, but we just require more information up front. +/// For the old setup, we could just rely on History::new to read some of the missing +/// data. This is no longer the case. +#[derive(Debug, Clone, TypedBuilder)] +pub struct HistoryDaemonCapture { + timestamp: time::OffsetDateTime, + #[builder(setter(into))] + command: String, + #[builder(setter(into))] + cwd: String, + #[builder(setter(into))] + session: String, + #[builder(setter(into))] + hostname: String, +} + +impl From<HistoryDaemonCapture> for History { + fn from(captured: HistoryDaemonCapture) -> Self { + History::new( + captured.timestamp, + captured.command, + captured.cwd, + -1, + -1, + Some(captured.session), + Some(captured.hostname), + None, + ) + } +} diff --git a/crates/atuin-client/src/settings.rs b/crates/atuin-client/src/settings.rs index 675fb307..ad7f95fc 100644 --- a/crates/atuin-client/src/settings.rs +++ b/crates/atuin-client/src/settings.rs @@ -342,6 +342,19 @@ pub struct Preview { pub strategy: PreviewStrategy, } +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Daemon { + /// Use the daemon to sync + /// If enabled, requires a running daemon with `atuin daemon` + pub enabled: bool, + + /// The daemon will handle sync on an interval. How often to sync, in seconds. + pub sync_frequency: u64, + + /// The path to the unix socket used by the daemon + pub socket_path: String, +} + impl Default for Preview { fn default() -> Self { Self { @@ -350,6 +363,16 @@ impl Default for Preview { } } +impl Default for Daemon { + fn default() -> Self { + Self { + enabled: false, + sync_frequency: 300, + socket_path: "".to_string(), + } + } +} + // The preview height strategy also takes max_preview_height into account. #[derive(Clone, Debug, Deserialize, Copy, PartialEq, Eq, ValueEnum, Serialize)] pub enum PreviewStrategy { @@ -428,6 +451,9 @@ pub struct Settings { #[serde(default)] pub dotfiles: dotfiles::Settings, + #[serde(default)] + pub daemon: Daemon, + // This is automatically loaded when settings is created. Do not set in // config! Keep secrets and settings apart. #[serde(skip)] @@ -622,6 +648,7 @@ impl Settings { let data_dir = atuin_common::utils::data_dir(); let db_path = data_dir.join("history.db"); let record_store_path = data_dir.join("records.db"); + let socket_path = data_dir.join("atuin.sock"); let key_path = data_dir.join("key"); let session_path = data_dir.join("session"); @@ -643,6 +670,7 @@ impl Settings { .set_default("style", "auto")? .set_default("inline_height", 0)? .set_default("show_preview", true)? + .set_default("preview.strategy", "auto")? .set_default("max_preview_height", 4)? .set_default("show_help", true)? .set_default("show_tabs", true)? @@ -675,6 +703,9 @@ impl Settings { .set_default("keymap_cursor", HashMap::<String, String>::new())? .set_default("smart_sort", false)? .set_default("store_failed", true)? + .set_default("daemon.sync_frequency", 300)? + .set_default("daemon.enabled", false)? + .set_default("daemon.socket_path", socket_path.to_str())? .set_default( "prefers_reduced_motion", std::env::var("NO_MOTION") |
