libpybuild 0.0.2

Python src+dependency bundler library
Documentation
use std::{fs, io::prelude::*, path::Path};

use anyhow::{Context, Result};
use log::debug;
use walkdir::WalkDir;
use zip::{ZipWriter, write::SimpleFileOptions};

pub(crate) fn zip_dir(src: &Path, dest: &Path, prefix: &str) -> Result<()> {
  let file = fs::File::create(dest)?;
  let walkdir = WalkDir::new(src);

  let mut zip = ZipWriter::new(file);
  let options = SimpleFileOptions::default().unix_permissions(0o755);

  let mut buffer = Vec::new();
  for entry in walkdir.into_iter().filter_map(|e| e.ok()) {
    let path =
      fs::canonicalize(entry.path()).with_context(|| format!("Failed to canonicalize path: {:?}", entry.path()))?;

    let name = path.strip_prefix(prefix).unwrap_or(path.as_path());
    let os_name = match name.as_os_str().to_str() {
      Some(s) => s,
      None => {
        debug!("{} did not convert to os_str", name.display());
        continue;
      }
    };

    if path.is_file() {
      debug!("Zipping {:?} ...", os_name);
      zip.start_file(os_name, options)?;
      let mut f = fs::File::open(path)?;

      f.read_to_end(&mut buffer)?;
      zip.write_all(&buffer)?;
      buffer.clear();
    } else if !os_name.is_empty() {
      zip.add_directory(os_name, options)?;
    }
  }

  zip.finish()?;
  Result::Ok(())
}