diff options
author | Ellie Huxtable <e@elm.sh> | 2021-04-26 11:50:31 +0100 |
---|---|---|
committer | Ellie Huxtable <e@elm.sh> | 2021-04-26 11:57:30 +0100 |
commit | 7b5c3d543d198a18884c990d540f5debc8a4d8d5 (patch) | |
tree | ffc6b9121f1b1299f1b30a26322e1988683c06c7 /atuin-client | |
parent | 4f16e8411e24891b140690798c47747f5c9bb91e (diff) |
Support bash, resolves #3
Diffstat (limited to 'atuin-client')
-rw-r--r-- | atuin-client/src/import/bash.rs | 79 | ||||
-rw-r--r-- | atuin-client/src/import/mod.rs | 15 | ||||
-rw-r--r-- | atuin-client/src/import/zsh.rs (renamed from atuin-client/src/import.rs) | 69 | ||||
-rw-r--r-- | atuin-client/src/sync.rs | 2 |
4 files changed, 126 insertions, 39 deletions
diff --git a/atuin-client/src/import/bash.rs b/atuin-client/src/import/bash.rs new file mode 100644 index 000000000..d5fbef460 --- /dev/null +++ b/atuin-client/src/import/bash.rs @@ -0,0 +1,79 @@ +use std::io::{BufRead, BufReader}; +use std::{fs::File, path::Path}; + +use eyre::{eyre, Result}; + +use super::count_lines; +use crate::history::History; + +#[derive(Debug)] +pub struct Bash { + file: BufReader<File>, + + pub loc: u64, + pub counter: i64, +} + +impl Bash { + pub fn new(path: impl AsRef<Path>) -> Result<Self> { + let file = File::open(path)?; + let mut buf = BufReader::new(file); + let loc = count_lines(&mut buf)?; + + Ok(Self { + file: buf, + loc: loc as u64, + counter: 0, + }) + } + + fn read_line(&mut self) -> Option<Result<String>> { + let mut line = String::new(); + + match self.file.read_line(&mut line) { + Ok(0) => None, + Ok(_) => Some(Ok(line)), + Err(e) => Some(Err(eyre!("failed to read line: {}", e))), // we can skip past things like invalid utf8 + } + } +} + +impl Iterator for Bash { + type Item = Result<History>; + + fn next(&mut self) -> Option<Self::Item> { + let line = self.read_line()?; + + if let Err(e) = line { + return Some(Err(e)); // :( + } + + let mut line = line.unwrap(); + + while line.ends_with("\\\n") { + let next_line = self.read_line()?; + + if next_line.is_err() { + break; + } + + line.push_str(next_line.unwrap().as_str()); + } + + let time = chrono::Utc::now(); + let offset = chrono::Duration::seconds(self.counter); + let time = time - offset; + + self.counter += 1; + + Some(Ok(History::new( + time, + line.trim_end().to_string(), + String::from("unknown"), + -1, + -1, + None, + None, + ))) + } +} diff --git a/atuin-client/src/import/mod.rs b/atuin-client/src/import/mod.rs new file mode 100644 index 000000000..3f8ea3559 --- /dev/null +++ b/atuin-client/src/import/mod.rs @@ -0,0 +1,15 @@ +use std::fs::File; +use std::io::{BufRead, BufReader, Seek, SeekFrom}; + +use eyre::Result; + +pub mod bash; +pub mod zsh; + +// this could probably be sped up +fn count_lines(buf: &mut BufReader<File>) -> Result<usize> { + let lines = buf.lines().count(); + buf.seek(SeekFrom::Start(0))?; + + Ok(lines) +} diff --git a/atuin-client/src/import.rs b/atuin-client/src/import/zsh.rs index 3b0b2a692..46e9af633 100644 --- a/atuin-client/src/import.rs +++ b/atuin-client/src/import/zsh.rs @@ -1,7 +1,7 @@ // import old shell history! // automatically hoover up all that we can find -use std::io::{BufRead, BufReader, Seek, SeekFrom}; +use std::io::{BufRead, BufReader}; use std::{fs::File, path::Path}; use chrono::prelude::*; @@ -9,7 +9,8 @@ use chrono::Utc; use eyre::{eyre, Result}; use itertools::Itertools; -use super::history::History; +use super::count_lines; +use crate::history::History; #[derive(Debug)] pub struct Zsh { @@ -19,14 +20,6 @@ pub struct Zsh { pub counter: i64, } -// this could probably be sped up -fn count_lines(buf: &mut BufReader<File>) -> Result<usize> { - let lines = buf.lines().count(); - buf.seek(SeekFrom::Start(0))?; - - Ok(lines) -} - impl Zsh { pub fn new(path: impl AsRef<Path>) -> Result<Self> { let file = File::open(path)?; @@ -39,36 +32,7 @@ impl Zsh { counter: 0, }) } -} - -fn parse_extended(line: &str, counter: i64) -> History { - let line = line.replacen(": ", "", 2); - let (time, duration) = line.splitn(2, ':').collect_tuple().unwrap(); - let (duration, command) = duration.splitn(2, ';').collect_tuple().unwrap(); - - let time = time - .parse::<i64>() - .unwrap_or_else(|_| chrono::Utc::now().timestamp()); - - let offset = chrono::Duration::milliseconds(counter); - let time = Utc.timestamp(time, 0); - let time = time + offset; - - let duration = duration.parse::<i64>().map_or(-1, |t| t * 1_000_000_000); - // use nanos, because why the hell not? we won't display them. - History::new( - time, - command.trim_end().to_string(), - String::from("unknown"), - 0, // assume 0, we have no way of knowing :( - duration, - None, - None, - ) -} - -impl Zsh { fn read_line(&mut self) -> Option<Result<String>> { let mut line = String::new(); @@ -140,6 +104,33 @@ impl Iterator for Zsh { } } +fn parse_extended(line: &str, counter: i64) -> History { + let line = line.replacen(": ", "", 2); + let (time, duration) = line.splitn(2, ':').collect_tuple().unwrap(); + let (duration, command) = duration.splitn(2, ';').collect_tuple().unwrap(); + + let time = time + .parse::<i64>() + .unwrap_or_else(|_| chrono::Utc::now().timestamp()); + + let offset = chrono::Duration::milliseconds(counter); + let time = Utc.timestamp(time, 0); + let time = time + offset; + + let duration = duration.parse::<i64>().map_or(-1, |t| t * 1_000_000_000); + + // use nanos, because why the hell not? we won't display them. + History::new( + time, + command.trim_end().to_string(), + String::from("unknown"), + 0, // assume 0, we have no way of knowing :( + duration, + None, + None, + ) +} + #[cfg(test)] mod test { use chrono::prelude::*; diff --git a/atuin-client/src/sync.rs b/atuin-client/src/sync.rs index 813c2ed4f..5c6405dfe 100644 --- a/atuin-client/src/sync.rs +++ b/atuin-client/src/sync.rs @@ -123,6 +123,8 @@ async fn sync_upload( client.post_history(&buffer).await?; cursor = buffer.last().unwrap().timestamp; remote_count = client.count().await?; + + debug!("upload cursor: {:?}", cursor); } Ok(()) |