git-stratum 0.2.3

High(er) level repository for mining git repositories, this library abstracts git2-rs for efficient processing.
Documentation
use std::{
    path::{Path, PathBuf},
    str::FromStr,
};
use tempfile::TempDir;

use once_cell::sync::Lazy;
use std::fs::File;
use zip::ZipArchive;

const ZIP_NAME: &str = "test-repos.zip";
static MAIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR");

/// Find the zip located alongside the Cargo.toml
fn zip_path() -> PathBuf {
    PathBuf::from_str(MAIFEST_DIR).unwrap().join(ZIP_NAME)
}

/// Unzip the given zip file and deposit its contents directly into dest
fn unzip_archive(zip_path: &Path, dest: &Path) {
    let file = File::open(zip_path).expect("Expected a valid zip");
    let mut archive = ZipArchive::new(file).expect("Expected to read zip");

    for i in 0..archive.len() {
        let mut file = archive.by_index(i).unwrap();
        // Without skipping the first element in the path everything is extracted into
        // /tmp/temp_dir/test-repos/*, brittle if the zip file name ever changed
        //
        // So we strip the `test-repos` from the path, extracting everything out
        // into /tmp/temp_dir
        let out_path = dest.join(
            file.mangled_name()
                .components()
                .skip(1)
                .collect::<PathBuf>(),
        );

        if file.is_dir() {
            std::fs::create_dir_all(&out_path).unwrap();
        } else {
            if let Some(parent) = out_path.parent() {
                std::fs::create_dir_all(parent).unwrap();
            }
            let mut out = std::fs::File::create(&out_path).unwrap();
            std::io::copy(&mut file, &mut out).unwrap();
        }
    }
}

/// Lazily construct the test data into a temp fir that will last the length of
/// a single modules test span.
static TEST_DATA_DIR: Lazy<TempDir> = Lazy::new(|| {
    let dir = TempDir::new().expect("Create temp dir");
    let zp = zip_path();

    unzip_archive(&zp, dir.path());

    dir
});

/// The path to the test data directory
pub fn test_data_dir() -> &'static Path {
    TEST_DATA_DIR.path()
}