forked from jelson.rodrigues/piperun-bot
70 lines
2.4 KiB
Rust
70 lines
2.4 KiB
Rust
pub mod zip_directory_util {
|
|
|
|
use std::io::prelude::*;
|
|
use zip::write::SimpleFileOptions;
|
|
|
|
use std::fs::File;
|
|
use std::path::Path;
|
|
use walkdir::{DirEntry, WalkDir};
|
|
|
|
fn zip_dir<T>(
|
|
it: &mut dyn Iterator<Item = DirEntry>,
|
|
prefix: &Path,
|
|
writer: T,
|
|
method: zip::CompressionMethod,
|
|
) where
|
|
T: Write + Seek,
|
|
{
|
|
let mut zip = zip::ZipWriter::new(writer);
|
|
let options = SimpleFileOptions::default()
|
|
.compression_method(method)
|
|
.unix_permissions(0o755);
|
|
|
|
let prefix = Path::new(prefix);
|
|
let mut buffer = Vec::new();
|
|
for entry in it {
|
|
let path = entry.path();
|
|
let name = path.strip_prefix(prefix).unwrap();
|
|
let path_as_string = name
|
|
.to_str()
|
|
.map(str::to_owned)
|
|
.expect("Failed to parse path");
|
|
|
|
// Write file or directory explicitly
|
|
// Some unzip tools unzip files with directory paths correctly, some do not!
|
|
if path.is_file() {
|
|
println!("adding file {path:?} as {name:?} ...");
|
|
zip.start_file(path_as_string, options)
|
|
.expect("Failed to add file");
|
|
let mut f = File::open(path).unwrap();
|
|
|
|
f.read_to_end(&mut buffer).expect("Failed to read file");
|
|
zip.write_all(&buffer).expect("Failed to write file");
|
|
buffer.clear();
|
|
} else if !name.as_os_str().is_empty() {
|
|
// Only if not root! Avoids path spec / warning
|
|
// and mapname conversion failed error on unzip
|
|
println!("adding dir {path_as_string:?} as {name:?} ...");
|
|
zip.add_directory(path_as_string, options)
|
|
.expect("Failed to add directory");
|
|
}
|
|
}
|
|
zip.finish().expect("Failed to ZIP");
|
|
}
|
|
|
|
pub fn zip_source_dir_to_dst_file(src_dir: &Path, dst_file: &Path) {
|
|
if !Path::new(src_dir).is_dir() {
|
|
panic!("src_dir must be a directory");
|
|
}
|
|
|
|
let method = zip::CompressionMethod::Stored;
|
|
let path = Path::new(dst_file);
|
|
let file = File::create(path).unwrap();
|
|
|
|
let walkdir = WalkDir::new(src_dir);
|
|
let it = walkdir.into_iter();
|
|
|
|
zip_dir(&mut it.filter_map(|e| e.ok()), src_dir, file, method);
|
|
}
|
|
}
|