summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJamie Quigley <jamie@quigley.xyz>2021-05-08 17:29:46 +0100
committerGitHub <noreply@github.com>2021-05-08 17:29:46 +0100
commitbb086808b1461a586ca249e312d5122c7da3c9c6 (patch)
treedfe2b1572d3cd276986def152d0f3edcb82396fe
parent56b75bc7bf1178f09c5a0e2676a2ae4b58c09b92 (diff)
Add importer for resh_history file (#69)
* Added resh history importer * Silence trivial clippy warnings for the PR CI
-rw-r--r--atuin-client/src/import/mod.rs1
-rw-r--r--atuin-client/src/import/resh.rs56
-rw-r--r--src/command/import.rs75
3 files changed, 131 insertions, 1 deletions
diff --git a/atuin-client/src/import/mod.rs b/atuin-client/src/import/mod.rs
index 3f8ea355..0b21d605 100644
--- a/atuin-client/src/import/mod.rs
+++ b/atuin-client/src/import/mod.rs
@@ -4,6 +4,7 @@ use std::io::{BufRead, BufReader, Seek, SeekFrom};
use eyre::Result;
pub mod bash;
+pub mod resh;
pub mod zsh;
// this could probably be sped up
diff --git a/atuin-client/src/import/resh.rs b/atuin-client/src/import/resh.rs
new file mode 100644
index 00000000..07f02036
--- /dev/null
+++ b/atuin-client/src/import/resh.rs
@@ -0,0 +1,56 @@
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+pub struct ReshEntry {
+ pub cmd_line: String,
+ pub exit_code: i64,
+ pub shell: String,
+ pub uname: String,
+ pub session_id: String,
+ pub home: String,
+ pub lang: String,
+ pub lc_all: String,
+ pub login: String,
+ pub pwd: String,
+ pub pwd_after: String,
+ pub shell_env: String,
+ pub term: String,
+ pub real_pwd: String,
+ pub real_pwd_after: String,
+ pub pid: i64,
+ pub session_pid: i64,
+ pub host: String,
+ pub hosttype: String,
+ pub ostype: String,
+ pub machtype: String,
+ pub shlvl: i64,
+ pub timezone_before: String,
+ pub timezone_after: String,
+ pub realtime_before: f64,
+ pub realtime_after: f64,
+ pub realtime_before_local: f64,
+ pub realtime_after_local: f64,
+ pub realtime_duration: f64,
+ pub realtime_since_session_start: f64,
+ pub realtime_since_boot: f64,
+ pub git_dir: String,
+ pub git_real_dir: String,
+ pub git_origin_remote: String,
+ pub git_dir_after: String,
+ pub git_real_dir_after: String,
+ pub git_origin_remote_after: String,
+ pub machine_id: String,
+ pub os_release_id: String,
+ pub os_release_version_id: String,
+ pub os_release_id_like: String,
+ pub os_release_name: String,
+ pub os_release_pretty_name: String,
+ pub resh_uuid: String,
+ pub resh_version: String,
+ pub resh_revision: String,
+ pub parts_merged: bool,
+ pub recalled: bool,
+ pub recall_last_cmd_line: String,
+ pub cols: String,
+ pub lines: String,
+}
diff --git a/src/command/import.rs b/src/command/import.rs
index 09df5839..c51e918f 100644
--- a/src/command/import.rs
+++ b/src/command/import.rs
@@ -1,13 +1,15 @@
use std::env;
use std::path::PathBuf;
+use atuin_common::utils::uuid_v4;
+use chrono::{TimeZone, Utc};
use directories::UserDirs;
use eyre::{eyre, Result};
use structopt::StructOpt;
-use atuin_client::database::Database;
use atuin_client::history::History;
use atuin_client::import::{bash::Bash, zsh::Zsh};
+use atuin_client::{database::Database, import::resh::ReshEntry};
use indicatif::ProgressBar;
#[derive(StructOpt)]
@@ -29,6 +31,12 @@ pub enum Cmd {
aliases=&["b", "ba", "bas"],
)]
Bash,
+
+ #[structopt(
+ about="import history from the resh history file",
+ aliases=&["r", "re", "res"],
+ )]
+ Resh,
}
impl Cmd {
@@ -56,10 +64,75 @@ impl Cmd {
Self::Zsh => import_zsh(db).await,
Self::Bash => import_bash(db).await,
+ Self::Resh => import_resh(db).await,
}
}
}
+async fn import_resh(db: &mut (impl Database + Send + Sync)) -> Result<()> {
+ let histpath = std::path::Path::new(std::env::var("HOME")?.as_str()).join(".resh_history.json");
+
+ println!("Parsing .resh_history.json...");
+ #[allow(clippy::filter_map)]
+ let history = std::fs::read_to_string(histpath)?
+ .split('\n')
+ .map(str::trim)
+ .map(|x| serde_json::from_str::<ReshEntry>(x))
+ .filter_map(Result::ok)
+ .map(|x| {
+ #[allow(clippy::cast_possible_truncation)]
+ #[allow(clippy::cast_sign_loss)]
+ let timestamp = {
+ let secs = x.realtime_before.floor() as i64;
+ let nanosecs = (x.realtime_before.fract() * 1_000_000_000_f64).round() as u32;
+ Utc.timestamp(secs, nanosecs)
+ };
+ #[allow(clippy::cast_possible_truncation)]
+ #[allow(clippy::cast_sign_loss)]
+ let duration = {
+ let secs = x.realtime_after.floor() as i64;
+ let nanosecs = (x.realtime_after.fract() * 1_000_000_000_f64).round() as u32;
+ let difference = Utc.timestamp(secs, nanosecs) - timestamp;
+ difference.num_nanoseconds().unwrap_or(0)
+ };
+
+ History {
+ id: uuid_v4(),
+ timestamp,
+ duration,
+ exit: x.exit_code,
+ command: x.cmd_line,
+ cwd: x.pwd,
+ session: uuid_v4(),
+ hostname: x.host,
+ }
+ })
+ .collect::<Vec<_>>();
+ println!("Updating database...");
+
+ let progress = ProgressBar::new(history.len() as u64);
+
+ let buf_size = 100;
+ let mut buf = Vec::<_>::with_capacity(buf_size);
+
+ for i in history {
+ buf.push(i);
+
+ if buf.len() == buf_size {
+ db.save_bulk(&buf).await?;
+ progress.inc(buf.len() as u64);
+
+ buf.clear();
+ }
+ }
+
+ if !buf.is_empty() {
+ db.save_bulk(&buf).await?;
+ progress.inc(buf.len() as u64);
+ }
+ Ok(())
+}
+
async fn import_zsh(db: &mut (impl Database + Send + Sync)) -> Result<()> {
// oh-my-zsh sets HISTFILE=~/.zhistory
// zsh has no default value for this var, but uses ~/.zhistory.