diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b00d11a84..71d97a65c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -127,6 +127,21 @@ jobs: exit 1 fi + # check that we update the pantry for unknown programs + # this works by deleting the entry for git then forcing + # pkgx to update the db, then trying to get git again + - run: | + set -x + rm -rf ~/.pkgx + rm -rf ~/.cache/pkgx/pantry/projects/git-scm.org + rm ~/.cache/pkgx/pantry.2.db + pkgx curl --version + test -f ~/.cache/pkgx/pantry.2.db + ! test -d ~/.cache/pkgx/pantry/projects/git-scm.org + pkgx git --version + test -d ~/.cache/pkgx/pantry/projects/git-scm.org + if: ${{ matrix.os == 'ubuntu-latest' }} + - name: generate coverage run: | cargo install rustfilt diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index a0a340e2c..68bf369ed 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -60,7 +60,7 @@ async fn main() -> Result<(), Box> { if let Some(spinner) = &spinner { spinner.set_message("syncing pkg-db…"); } - sync::replace(&config, &mut conn).await?; + sync::ensure(&config, &mut conn).await?; true } else { false @@ -112,7 +112,7 @@ async fn main() -> Result<(), Box> { spinner.set_message(msg); } // cmd not found ∴ sync in case it is new - sync::replace(&config, &mut conn).await?; + sync::update(&config, &mut conn).await?; if let Some(spinner) = &spinner { spinner.set_message("resolving pkg graph…"); } diff --git a/crates/lib/src/sync.rs b/crates/lib/src/sync.rs index 76d47168a..3d660a6ca 100644 --- a/crates/lib/src/sync.rs +++ b/crates/lib/src/sync.rs @@ -19,7 +19,35 @@ pub fn should(config: &Config) -> Result> { } } -pub async fn replace(config: &Config, conn: &mut Connection) -> Result<(), Box> { +// doesn’t replace pantry clone, will build db +// essential for working in a local pantry clone with PKGX_PANTRY_DIR set +pub async fn ensure(config: &Config, conn: &mut Connection) -> Result<(), Box> { + if !config.pantry_dir.join("projects").is_dir() { + replace(config, conn).await + } else { + let dest = &config.pantry_dir; + std::fs::create_dir_all(dest.clone())?; + let dir = OpenOptions::new() + .read(true) // Open in read-only mode; no need to write. + .open(dest)?; + dir.lock_exclusive()?; + + pantry_db::cache(config, conn)?; + + FileExt::unlock(&dir)?; + + Ok(()) + } +} + +pub async fn update(config: &Config, conn: &mut Connection) -> Result<(), Box> { + if std::env::var("PKGX_PANTRY_DIR").is_ok() { + return Err("PKGX_PANTRY_DIR is set, refusing to update pantry")?; + } + replace(config, conn).await +} + +async fn replace(config: &Config, conn: &mut Connection) -> Result<(), Box> { let url = env!("PKGX_PANTRY_TARBALL_URL"); let dest = &config.pantry_dir;