Skip to content

Commit

Permalink
Allow merging when migrating from z (#33)
Browse files Browse the repository at this point in the history
If the user passes the `--merge` flag to the `migrate` subcommand, all
duplicate entries will have their ranks and epochs updated: the rank
will be the sum of the stored rank and the newly-parsed rank, while the
epoch will be the maximum of the stored epoch and the newly-parsed
epoch.

This allows one to import from the `z` database even after having used
`zoxide` for any amount of time. This also permits a user who has
already sourced the init script to import their old database without
needing to do something like `rm ~/.zo && zoxide migrate ~/.z`.
  • Loading branch information
cole-h authored Mar 15, 2020
1 parent f4cd115 commit 083a834
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
24 changes: 19 additions & 5 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ impl DB {
Ok(())
}

pub fn migrate<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
if !self.dirs.is_empty() {
pub fn migrate<P: AsRef<Path>>(&mut self, path: P, merge: bool) -> Result<()> {
if !self.dirs.is_empty() && !merge {
bail!(
"To prevent conflicts, you can only migrate from z with an empty \
zoxide database!"
"To prevent conflicts, you can only migrate from z with an empty zoxide database!
If you wish to merge the two, specify the `--merge` flag."
);
}

Expand All @@ -87,7 +87,10 @@ impl DB {
let line = if let Ok(line) = read_line {
line
} else {
eprintln!("could not read line {}: {:?}", line_number, read_line);
eprintln!(
"could not read entry at line {}: {:?}",
line_number, read_line
);
continue;
};

Expand Down Expand Up @@ -131,6 +134,17 @@ impl DB {
}
};

if merge {
// If the path exists in the database, add the ranks and set the epoch to
// the largest of the parsed epoch and the already present epoch.
if let Some(dir) = self.dirs.iter_mut().find(|dir| dir.path == path_str) {
dir.rank += rank;
dir.last_accessed = Epoch::max(epoch, dir.last_accessed);

continue;
};
}

// FIXME: When we switch to PathBuf for storing directories inside Dir, just
// pass `PathBuf::from(path_str)`
self.dirs.push(Dir {
Expand Down
5 changes: 4 additions & 1 deletion src/subcommand/migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ use structopt::StructOpt;
#[structopt(about = "Migrate from z database")]
pub struct Migrate {
path: String,

#[structopt(long, help = "Merge entries into existing database")]
merge: bool,
}

impl Migrate {
pub fn run(&self, env: &Env) -> Result<()> {
util::get_db(env)?.migrate(&self.path)
util::get_db(env)?.migrate(&self.path, self.merge)
}
}

0 comments on commit 083a834

Please sign in to comment.