Add importer for resh_history file (#69)
* Added resh history importer * Silence trivial clippy warnings for the PR CI
This commit is contained in:
parent
56b75bc7bf
commit
bb086808b1
3 changed files with 131 additions and 1 deletions
|
@ -4,6 +4,7 @@ use std::io::{BufRead, BufReader, Seek, SeekFrom};
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
|
|
||||||
pub mod bash;
|
pub mod bash;
|
||||||
|
pub mod resh;
|
||||||
pub mod zsh;
|
pub mod zsh;
|
||||||
|
|
||||||
// this could probably be sped up
|
// this could probably be sped up
|
||||||
|
|
56
atuin-client/src/import/resh.rs
Normal file
56
atuin-client/src/import/resh.rs
Normal file
|
@ -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,
|
||||||
|
}
|
|
@ -1,13 +1,15 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use atuin_common::utils::uuid_v4;
|
||||||
|
use chrono::{TimeZone, Utc};
|
||||||
use directories::UserDirs;
|
use directories::UserDirs;
|
||||||
use eyre::{eyre, Result};
|
use eyre::{eyre, Result};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
use atuin_client::database::Database;
|
|
||||||
use atuin_client::history::History;
|
use atuin_client::history::History;
|
||||||
use atuin_client::import::{bash::Bash, zsh::Zsh};
|
use atuin_client::import::{bash::Bash, zsh::Zsh};
|
||||||
|
use atuin_client::{database::Database, import::resh::ReshEntry};
|
||||||
use indicatif::ProgressBar;
|
use indicatif::ProgressBar;
|
||||||
|
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
|
@ -29,6 +31,12 @@ pub enum Cmd {
|
||||||
aliases=&["b", "ba", "bas"],
|
aliases=&["b", "ba", "bas"],
|
||||||
)]
|
)]
|
||||||
Bash,
|
Bash,
|
||||||
|
|
||||||
|
#[structopt(
|
||||||
|
about="import history from the resh history file",
|
||||||
|
aliases=&["r", "re", "res"],
|
||||||
|
)]
|
||||||
|
Resh,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cmd {
|
impl Cmd {
|
||||||
|
@ -56,10 +64,75 @@ impl Cmd {
|
||||||
|
|
||||||
Self::Zsh => import_zsh(db).await,
|
Self::Zsh => import_zsh(db).await,
|
||||||
Self::Bash => import_bash(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<()> {
|
async fn import_zsh(db: &mut (impl Database + Send + Sync)) -> Result<()> {
|
||||||
// oh-my-zsh sets HISTFILE=~/.zhistory
|
// oh-my-zsh sets HISTFILE=~/.zhistory
|
||||||
// zsh has no default value for this var, but uses ~/.zhistory.
|
// zsh has no default value for this var, but uses ~/.zhistory.
|
||||||
|
|
Loading…
Add table
Reference in a new issue