From 9af0251bd6606729f5e862d19e0c0d7404f7fd2c Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Sun, 29 Mar 2020 13:42:51 -0700 Subject: [PATCH] Rework database fallback for v0.3 (#47) Support migration from old database --- README.md | 5 ++++- src/config.rs | 24 ++++++++++++------------ src/db.rs | 2 +- src/util.rs | 18 +++++++++++++++--- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 9cbe0e6..6b59dda 100644 --- a/README.md +++ b/README.md @@ -116,9 +116,12 @@ NOTE: There is no PWD hook provided for POSIX shells. ### Environment variables -- `$_ZO_DATA`: sets the location of the database (default: `~/.zo`) +- `$_ZO_DATA_DIR`: directory where `zoxide` will store its data files (default: + platform-specific; see the [`dirs` documentation] for more information) - `$_ZO_ECHO`: `z` will print the matched directory before navigating to it - `$_ZO_EXCLUDE_DIRS`: list of directories separated by platform-specific characters (`:` on Linux and macOS, and `;` on Windows) to be excluded from the database - `$_ZO_MAXAGE`: sets the maximum total rank after which entries start getting deleted + +[`dirs` documentation]: https://docs.rs/dirs/latest/dirs/fn.data_local_dir.html diff --git a/src/config.rs b/src/config.rs index 6e41b1b..2376fff 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,27 +8,26 @@ use std::fs; use std::path::PathBuf; pub const DB_MAX_SIZE: u64 = 8 * 1024 * 1024; // 8 MiB - pub const DB_VERSION: DBVersion = 3; -pub fn zo_data() -> Result { - let path = match env::var_os("_ZO_DATA") { +pub fn zo_data_dir() -> Result { + let data_dir = match env::var_os("_ZO_DATA_DIR") { Some(data_osstr) => PathBuf::from(data_osstr), None => { - if let Some(mut cache_dir) = dirs::cache_dir() { - cache_dir.push("zoxide"); - cache_dir - } else if let Some(mut home_dir) = dirs::home_dir() { - home_dir.push(".zoxide"); - home_dir + if let Some(mut data_dir) = dirs::data_local_dir() { + data_dir.push("zoxide"); + data_dir } else { - bail!("could not generate default directory, please set _ZO_DATA manually"); + bail!("could not find database directory, please set _ZO_DATA_DIR manually"); } } }; - fs::create_dir_all(&path).context("could not create _ZO_DATA directory")?; - Ok(path) + // This will fail when `data_dir` points to a file or a broken symlink, but + // will no-op on a valid symlink (to a directory), or an actual directory. + fs::create_dir_all(&data_dir).context("could not create data directory")?; + + Ok(data_dir) } pub fn zo_exclude_dirs() -> Vec { @@ -45,6 +44,7 @@ pub fn zo_maxage() -> Result { let maxage = maxage_str .parse::() .context("unable to parse _ZO_MAXAGE as integer")?; + Ok(maxage as Rank) } None => bail!("invalid Unicode in _ZO_MAXAGE"), diff --git a/src/db.rs b/src/db.rs index 9712366..758865c 100644 --- a/src/db.rs +++ b/src/db.rs @@ -48,7 +48,7 @@ impl DB { }) } - pub fn open_old(path_old: P1, path: P2) -> Result + pub fn open_and_migrate(path_old: P1, path: P2) -> Result where P1: AsRef, P2: AsRef, diff --git a/src/util.rs b/src/util.rs index c9e4057..80dcccd 100644 --- a/src/util.rs +++ b/src/util.rs @@ -22,9 +22,21 @@ pub fn path_to_bytes>(path: &P) -> Option<&[u8]> { } pub fn get_db() -> Result { - let mut path = config::zo_data()?; - path.push("db.zo"); - DB::open(path) + let mut db_path = config::zo_data_dir()?; + db_path.push("db.zo"); + + // FIXME: fallback to old database location; remove in next breaking version + if !db_path.is_file() { + if let Some(mut old_db_path) = dirs::home_dir() { + old_db_path.push(".zo"); + + if old_db_path.is_file() { + return DB::open_and_migrate(old_db_path, db_path); + } + } + } + + DB::open(db_path) } pub fn get_current_time() -> Result {