From cf08f29017eceea6b8e1337e94dbb905df2581a6 Mon Sep 17 00:00:00 2001 From: Jacob Heider Date: Fri, 27 Mar 2026 13:32:43 -0400 Subject: [PATCH 1/2] fix finding binaries in the PKGX_PANTRY_DIR reported by Boom on discord update the db using the pantry dir, if set. this ensures newly developed binaries are usable (and local pantries). --- crates/lib/src/sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lib/src/sync.rs b/crates/lib/src/sync.rs index 65f5694e8..eb639b949 100644 --- a/crates/lib/src/sync.rs +++ b/crates/lib/src/sync.rs @@ -33,7 +33,7 @@ pub async fn ensure(config: &Config, conn: &mut Connection) -> Result<(), Box Result<(), Box> { if std::env::var("PKGX_PANTRY_DIR").is_ok() { - return Err("PKGX_PANTRY_DIR is set, refusing to update pantry")?; + return ensure(config, conn).await; } replace(config, conn).await } From 1745529471843e464cbadaade78020faadf54916 Mon Sep 17 00:00:00 2001 From: Jacob Heider Date: Fri, 27 Mar 2026 14:10:16 -0400 Subject: [PATCH 2/2] address review concerns about bad pantry paths. --- Cargo.lock | 1 + crates/cli/Cargo.toml | 3 ++ crates/cli/src/tests/mod.rs | 1 + crates/cli/src/tests/sync.rs | 64 ++++++++++++++++++++++++++++++++++++ crates/lib/src/sync.rs | 11 ++++++- 5 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 crates/cli/src/tests/sync.rs diff --git a/Cargo.lock b/Cargo.lock index 289d0afeb..8b8f2d334 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1213,6 +1213,7 @@ dependencies = [ "rusqlite", "serde", "serde_json", + "tempfile", "tokio", ] diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index c187e65b4..28488f8e5 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -20,6 +20,9 @@ console = { version = "0.16", default-features = false, features = [ "ansi-parsing", ] } +[dev-dependencies] +tempfile = "3" + [target.'cfg(not(target_os = "macos"))'.dependencies] rusqlite = { workspace = true, features = ["bundled"] } native-tls = { version = "0.2", features = ["vendored"] } diff --git a/crates/cli/src/tests/mod.rs b/crates/cli/src/tests/mod.rs index d18669ad9..17967aba3 100644 --- a/crates/cli/src/tests/mod.rs +++ b/crates/cli/src/tests/mod.rs @@ -1 +1,2 @@ mod main; +mod sync; diff --git a/crates/cli/src/tests/sync.rs b/crates/cli/src/tests/sync.rs new file mode 100644 index 000000000..064270f1d --- /dev/null +++ b/crates/cli/src/tests/sync.rs @@ -0,0 +1,64 @@ +use libpkgx::config::Config; +use libpkgx::sync; +use rusqlite::Connection; +use std::sync::Mutex; +use tempfile::TempDir; + +// serialize tests that mutate PKGX_PANTRY_DIR +static ENV_MUTEX: Mutex<()> = Mutex::new(()); + +fn test_config(pantry_dir: &std::path::Path, db_file: &std::path::Path) -> Config { + Config { + pantry_dir: pantry_dir.to_path_buf(), + pantry_db_file: db_file.to_path_buf(), + dist_url: "http://localhost:0".to_string(), + pkgx_dir: pantry_dir.to_path_buf(), + } +} + +#[tokio::test] +async fn test_update_with_pantry_dir_rebuilds_db_when_projects_exists() { + let _lock = ENV_MUTEX.lock().unwrap(); + let tmp = TempDir::new().unwrap(); + let pantry_dir = tmp.path().join("pantry"); + std::fs::create_dir_all(pantry_dir.join("projects")).unwrap(); + let db_file = tmp.path().join("pantry.2.db"); + + let config = test_config(&pantry_dir, &db_file); + let mut conn = Connection::open(&db_file).unwrap(); + + std::env::set_var("PKGX_PANTRY_DIR", &pantry_dir); + let result = sync::update(&config, &mut conn).await; + std::env::remove_var("PKGX_PANTRY_DIR"); + + assert!( + result.is_ok(), + "update should succeed when projects/ exists" + ); +} + +#[tokio::test] +async fn test_update_with_pantry_dir_errors_when_projects_missing() { + let _lock = ENV_MUTEX.lock().unwrap(); + let tmp = TempDir::new().unwrap(); + let pantry_dir = tmp.path().join("pantry"); + std::fs::create_dir_all(&pantry_dir).unwrap(); + let db_file = tmp.path().join("pantry.2.db"); + + let config = test_config(&pantry_dir, &db_file); + let mut conn = Connection::open(&db_file).unwrap(); + + std::env::set_var("PKGX_PANTRY_DIR", &pantry_dir); + let result = sync::update(&config, &mut conn).await; + std::env::remove_var("PKGX_PANTRY_DIR"); + + assert!( + result.is_err(), + "update should fail when projects/ is missing" + ); + let err = result.unwrap_err().to_string(); + assert!( + err.contains("missing projects/"), + "error should mention missing projects/, got: {err}" + ); +} diff --git a/crates/lib/src/sync.rs b/crates/lib/src/sync.rs index eb639b949..629597811 100644 --- a/crates/lib/src/sync.rs +++ b/crates/lib/src/sync.rs @@ -33,7 +33,16 @@ pub async fn ensure(config: &Config, conn: &mut Connection) -> Result<(), Box Result<(), Box> { if std::env::var("PKGX_PANTRY_DIR").is_ok() { - return ensure(config, conn).await; + if config.pantry_dir.join("projects").is_dir() { + let lockfile = lock(config)?; + pantry_db::cache(config, conn)?; + FileExt::unlock(&lockfile)?; + return Ok(()); + } else { + return Err( + "PKGX_PANTRY_DIR is set but does not contain a pantry (missing projects/)", + )?; + } } replace(config, conn).await }