add self-import to merge multiple zoxide databases
This commit is contained in:
parent
1d64ae0b87
commit
4cbab9b812
|
|
@ -94,7 +94,7 @@ esac
|
|||
;;
|
||||
(import)
|
||||
_arguments "${_arguments_options[@]}" \
|
||||
'--from=[Application to import from]:FROM:(autojump z)' \
|
||||
'--from=[Application to import from]:FROM:(autojump z zoxide)' \
|
||||
'--merge[Merge into existing database]' \
|
||||
'-h[Print help]' \
|
||||
'--help[Print help]' \
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ _zoxide() {
|
|||
fi
|
||||
case "${prev}" in
|
||||
--from)
|
||||
COMPREPLY=($(compgen -W "autojump z" -- "${cur}"))
|
||||
COMPREPLY=($(compgen -W "autojump z zoxide" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ complete -c zoxide -n "__fish_seen_subcommand_from edit; and __fish_seen_subcomm
|
|||
complete -c zoxide -n "__fish_seen_subcommand_from edit; and __fish_seen_subcommand_from increment" -s V -l version -d 'Print version'
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from edit; and __fish_seen_subcommand_from reload" -s h -l help -d 'Print help'
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from edit; and __fish_seen_subcommand_from reload" -s V -l version -d 'Print version'
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from import" -l from -d 'Application to import from' -r -f -a "{autojump ,z }"
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from import" -l from -d 'Application to import from' -r -f -a "{autojump ,z ,zoxide }"
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from import" -l merge -d 'Merge into existing database'
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from import" -s h -l help -d 'Print help'
|
||||
complete -c zoxide -n "__fish_seen_subcommand_from import" -s V -l version -d 'Print version'
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ const completion: Fig.Spec = {
|
|||
suggestions: [
|
||||
"autojump",
|
||||
"z",
|
||||
"zoxide",
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ pub enum ImportFrom {
|
|||
Autojump,
|
||||
#[clap(alias = "fasd")]
|
||||
Z,
|
||||
Zoxide,
|
||||
}
|
||||
|
||||
/// Generate shell configuration
|
||||
|
|
|
|||
|
|
@ -7,25 +7,41 @@ use crate::db::Database;
|
|||
|
||||
impl Run for Import {
|
||||
fn run(&self) -> Result<()> {
|
||||
let buffer = fs::read_to_string(&self.path).with_context(|| {
|
||||
format!("could not open database for importing: {}", &self.path.display())
|
||||
})?;
|
||||
|
||||
let mut db = Database::open()?;
|
||||
if !self.merge && !db.dirs().is_empty() {
|
||||
bail!("current database is not empty, specify --merge to continue anyway");
|
||||
}
|
||||
|
||||
match self.from {
|
||||
ImportFrom::Autojump => import_autojump(&mut db, &buffer),
|
||||
ImportFrom::Z => import_z(&mut db, &buffer),
|
||||
let buffer = fs::read(&self.path).with_context(|| {
|
||||
format!("could not open database for importing: {}", &self.path.display())
|
||||
})?;
|
||||
|
||||
if matches!(self.from, ImportFrom::Zoxide) {
|
||||
from_self(&mut db, &buffer)?;
|
||||
} else {
|
||||
let buffer = std::str::from_utf8(&buffer).with_context(|| {
|
||||
format!("could not open database for importing: {}", &self.path.display())
|
||||
})?;
|
||||
match self.from {
|
||||
ImportFrom::Autojump => import_autojump(&mut db, buffer),
|
||||
ImportFrom::Z => import_z(&mut db, buffer),
|
||||
ImportFrom::Zoxide => unreachable!(),
|
||||
}
|
||||
.context("import error")?;
|
||||
}
|
||||
.context("import error")?;
|
||||
|
||||
db.save()
|
||||
}
|
||||
}
|
||||
|
||||
fn from_self(db: &mut Database, buffer: &[u8]) -> Result<()> {
|
||||
for dir in Database::deserialize(buffer).context("could not deserialize database")? {
|
||||
db.add_unchecked(dir.path, dir.rank, dir.last_accessed);
|
||||
}
|
||||
db.dedup();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn import_autojump(db: &mut Database, buffer: &str) -> Result<()> {
|
||||
for line in buffer.lines() {
|
||||
if line.is_empty() {
|
||||
|
|
@ -80,8 +96,10 @@ fn sigmoid(x: f64) -> f64 {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::db::Dir;
|
||||
use std::fs;
|
||||
|
||||
use super::{sigmoid, *};
|
||||
use crate::db::{Database, Dir};
|
||||
|
||||
#[test]
|
||||
fn from_autojump() {
|
||||
|
|
@ -163,4 +181,44 @@ mod tests {
|
|||
assert_eq!(dir1.last_accessed, dir2.last_accessed);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_self() {
|
||||
let path = if cfg!(windows) { r"C:\foo\bar" } else { "/foo/bar" };
|
||||
let second_path = if cfg!(windows) { r"C:\bar\foo" } else { "/bar/foo" };
|
||||
let now = 946684800;
|
||||
let before = 946684700;
|
||||
|
||||
let source_data_dir = tempfile::tempdir().unwrap();
|
||||
{
|
||||
let mut db = Database::open_dir(source_data_dir.path()).unwrap();
|
||||
db.add(path, 1.0, now);
|
||||
db.save().unwrap();
|
||||
assert_eq!(db.dirs().len(), 1);
|
||||
let dir = &db.dirs()[0];
|
||||
assert_eq!(dir.path, path);
|
||||
assert_eq!(dir.last_accessed, now);
|
||||
assert_eq!(dir.rank, 1.0);
|
||||
}
|
||||
|
||||
let dest_data_dir = tempfile::tempdir().unwrap();
|
||||
let mut db = Database::open_dir(dest_data_dir.path()).unwrap();
|
||||
db.add(path, 1.0, before);
|
||||
db.add(second_path, 1.0, before);
|
||||
db.save().unwrap();
|
||||
|
||||
let source_buf = fs::read(source_data_dir.path().join("db.zo")).unwrap();
|
||||
|
||||
super::from_self(&mut db, &source_buf).unwrap();
|
||||
|
||||
assert_eq!(db.dirs().len(), 2);
|
||||
let dir = &db.dirs()[0];
|
||||
assert_eq!(dir.path, second_path);
|
||||
assert_eq!(dir.last_accessed, before);
|
||||
assert_eq!(dir.rank, 1.0);
|
||||
let dir2 = &db.dirs()[1];
|
||||
assert_eq!(dir2.path, path);
|
||||
assert_eq!(dir2.last_accessed, now);
|
||||
assert_eq!(dir2.rank, 2.0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ impl Database {
|
|||
.context("could not serialize database")
|
||||
}
|
||||
|
||||
fn deserialize(bytes: &[u8]) -> Result<Vec<Dir>> {
|
||||
pub(crate) fn deserialize(bytes: &[u8]) -> Result<Vec<Dir>> {
|
||||
// Assume a maximum size for the database. This prevents bincode from throwing
|
||||
// strange errors when it encounters invalid data.
|
||||
const MAX_SIZE: u64 = 32 << 20; // 32 MiB
|
||||
|
|
|
|||
Loading…
Reference in New Issue