diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 115f0e32..8092bd8b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -107,7 +107,10 @@ jobs: - run: pkgx /usr/bin/awk --version - run: pkgx +yarnpkg.com yarn --version - run: pkgx +yarnpkg.com -- yarn --version + # coverage for conflict error messages - run: '! pkgx yarn --version' + # coverage for display-name resolution + - run: pkgx +agg - name: generate coverage run: | diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 2b4f2b2a..19bc451e 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -41,7 +41,7 @@ async fn main() -> Result<(), Box> { let cache_dir = config.pantry_dir.parent().unwrap(); std::fs::create_dir_all(cache_dir)?; - let mut conn = Connection::open(cache_dir.join("pantry.db"))?; + let mut conn = Connection::open(cache_dir.join("pantry.2.db"))?; let spinner = if flags.silent || flags.quiet { None @@ -51,7 +51,7 @@ async fn main() -> Result<(), Box> { Some(spinner) }; - let did_sync = if sync::should(&config) { + let did_sync = if sync::should(&config)? { if let Some(spinner) = &spinner { spinner.set_message("syncing pkg-db…"); } @@ -263,7 +263,7 @@ impl std::fmt::Display for WhichError { impl std::error::Error for WhichError {} async fn which(cmd: &String, conn: &Connection, pkgs: &[PackageReq]) -> Result { - let candidates = pantry_db::which(cmd, conn).map_err(WhichError::DbError)?; + let candidates = pantry_db::projects_for_symbol(cmd, conn).map_err(WhichError::DbError)?; if candidates.len() == 1 { Ok(candidates[0].clone()) } else if candidates.is_empty() { diff --git a/crates/lib/src/pantry.rs b/crates/lib/src/pantry.rs index 55a1bd99..3b7d90c4 100644 --- a/crates/lib/src/pantry.rs +++ b/crates/lib/src/pantry.rs @@ -12,6 +12,7 @@ pub struct PantryEntry { pub programs: Vec, pub companions: Vec, pub env: HashMap, + pub display_name: Option, } impl PantryEntry { @@ -73,12 +74,15 @@ impl PantryEntry { HashMap::new() }; + let display_name = entry.display_name; + Ok(Self { deps, project, env, companions, programs, + display_name, }) } } @@ -131,6 +135,8 @@ struct RawPantryEntry { provides: Option, companions: Option, runtime: Option, + #[serde(rename = "display-name")] + display_name: Option, } #[derive(Debug)] diff --git a/crates/lib/src/pantry_db.rs b/crates/lib/src/pantry_db.rs index e2e872c2..9cc1ad6a 100644 --- a/crates/lib/src/pantry_db.rs +++ b/crates/lib/src/pantry_db.rs @@ -30,10 +30,15 @@ pub fn cache(config: &Config, conn: &mut Connection) -> Result<(), Box Result<(), Box Result, rusqlite::E Ok(rv) } +pub fn projects_for_symbol( + symbol: &String, + conn: &Connection, +) -> Result, rusqlite::Error> { + let mut stmt = conn.prepare( + " + SELECT project FROM provides WHERE program = ?1 + UNION + SELECT project FROM aliases WHERE LOWER(alias) = LOWER(?1);", + )?; + let mut rv = Vec::new(); + let mut rows = stmt.query(params![symbol])?; + while let Some(row) = rows.next()? { + rv.push(row.get(0)?); + } + Ok(rv) +} + pub fn runtime_env_for_project( project: &String, conn: &Connection, diff --git a/crates/lib/src/sync.rs b/crates/lib/src/sync.rs index c52dcf79..76d47168 100644 --- a/crates/lib/src/sync.rs +++ b/crates/lib/src/sync.rs @@ -8,19 +8,14 @@ use tokio_tar::Archive; use tokio_util::compat::FuturesAsyncReadCompatExt; #[allow(clippy::all)] -pub fn should(config: &Config) -> bool { +pub fn should(config: &Config) -> Result> { if !config.pantry_dir.join("projects").is_dir() { - true - } else if !config - .pantry_dir - .parent() - .unwrap() - .join("pantry.db") - .is_file() - { - true + Ok(true) } else { - false + let path = config.pantry_dir.parent().unwrap().join("pantry.2.db"); + // the file always exists because we create the connection + // but will be 0 bytes if we need to fill it + Ok(std::fs::metadata(&path)?.len() == 0) } }