• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pkgxdev / pkgx / 13863219990

14 Mar 2025 06:39PM UTC coverage: 91.235%. First build
13863219990

Pull #1151

github

web-flow
Merge e39b8e6c8 into 35f6bbe1d
Pull Request #1151: --query,-Q

35 of 35 new or added lines in 4 files covered. (100.0%)

1374 of 1506 relevant lines covered (91.24%)

18538506.28 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.31
/crates/lib/src/sync.rs
1
use crate::{client::build_client, config::Config, pantry_db};
2
use async_compression::tokio::bufread::GzipDecoder;
3
use fs2::FileExt;
4
use futures::TryStreamExt;
5
use rusqlite::Connection;
6
use std::{error::Error, fs::OpenOptions, path::PathBuf};
7
use tokio_tar::Archive;
8
use tokio_util::compat::FuturesAsyncReadCompatExt;
9

10
#[allow(clippy::all)]
11
pub fn should(config: &Config) -> Result<bool, Box<dyn Error>> {
30✔
12
    if !config.pantry_dir.join("projects").is_dir() {
30✔
13
        Ok(true)
6✔
14
    } else {
15
        // the file always exists because we create the connection
16
        // but will be 0 bytes if we need to fill it
17
        Ok(std::fs::metadata(&config.pantry_db_file)?.len() == 0)
24✔
18
    }
19
}
30✔
20

21
// doesn’t replace pantry clone, will build db
22
// essential for working in a local pantry clone with PKGX_PANTRY_DIR set
23
pub async fn ensure(config: &Config, conn: &mut Connection) -> Result<(), Box<dyn Error>> {
6✔
24
    if !config.pantry_dir.join("projects").is_dir() {
6✔
25
        replace(config, conn).await
6✔
26
    } else {
27
        let lockfile = lock(config)?;
×
28
        pantry_db::cache(config, conn)?;
×
29
        FileExt::unlock(&lockfile)?;
×
30
        Ok(())
×
31
    }
32
}
6✔
33

34
pub async fn update(config: &Config, conn: &mut Connection) -> Result<(), Box<dyn Error>> {
×
35
    if std::env::var("PKGX_PANTRY_DIR").is_ok() {
×
36
        return Err("PKGX_PANTRY_DIR is set, refusing to update pantry")?;
×
37
    }
38
    replace(config, conn).await
×
39
}
40

41
async fn replace(config: &Config, conn: &mut Connection) -> Result<(), Box<dyn Error>> {
6✔
42
    let url = format!(
6✔
43
        "{}/{}",
6✔
44
        config.dist_url,
6✔
45
        env!("PKGX_PANTRY_TARBALL_FILENAME")
6✔
46
    );
6✔
47

48
    let lockfile = lock(config)?;
6✔
49
    download_and_extract_pantry(&url, &config.pantry_dir).await?;
6✔
50
    pantry_db::cache(config, conn)?;
6✔
51
    FileExt::unlock(&lockfile)?;
6✔
52

53
    Ok(())
6✔
54
}
6✔
55

56
async fn download_and_extract_pantry(url: &str, dest: &PathBuf) -> Result<(), Box<dyn Error>> {
6✔
57
    let rsp = build_client()?.get(url).send().await?.error_for_status()?;
6✔
58

59
    let stream = rsp.bytes_stream();
6✔
60

6✔
61
    let stream = stream
6✔
62
        .map_err(|e| futures::io::Error::new(futures::io::ErrorKind::Other, e))
6✔
63
        .into_async_read();
6✔
64
    let stream = stream.compat();
6✔
65

6✔
66
    let decoder = GzipDecoder::new(stream);
6✔
67

6✔
68
    // Step 3: Extract the tar archive
6✔
69
    let mut archive = Archive::new(decoder);
6✔
70
    archive.unpack(dest).await?;
6✔
71

72
    Ok(())
6✔
73
}
6✔
74

75
fn lock(config: &Config) -> Result<std::fs::File, Box<dyn Error>> {
6✔
76
    std::fs::create_dir_all(&config.pantry_dir)?;
6✔
77
    #[cfg(not(windows))]
78
    let lockfile = OpenOptions::new().read(true).open(&config.pantry_dir)?;
6✔
79
    #[cfg(windows)]
80
    let lockfile = OpenOptions::new()
81
        .read(true)
82
        .create(true)
83
        .truncate(true)
84
        .write(true)
85
        .open(config.pantry_dir.join("lockfile"))?;
86
    lockfile.lock_exclusive()?;
6✔
87
    Ok(lockfile)
6✔
88
}
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc