(
compressed_file: &str,
target: &Path,
log: &Logger,
single_file: Option<String>,
)
| 462 | } |
| 463 | |
| 464 | pub fn unzip( |
| 465 | compressed_file: &str, |
| 466 | target: &Path, |
| 467 | log: &Logger, |
| 468 | single_file: Option<String>, |
| 469 | ) -> Result<(), Error> { |
| 470 | let file = File::open(compressed_file)?; |
| 471 | let compressed_path = Path::new(compressed_file); |
| 472 | let tmp_path = compressed_path |
| 473 | .parent() |
| 474 | .unwrap_or(compressed_path) |
| 475 | .to_path_buf(); |
| 476 | let final_path = if single_file.is_some() { |
| 477 | target.parent().unwrap_or(target).to_path_buf() |
| 478 | } else { |
| 479 | target.to_path_buf() |
| 480 | }; |
| 481 | log.trace(format!( |
| 482 | "Unzipping {} to {}", |
| 483 | compressed_file, |
| 484 | final_path.display() |
| 485 | )); |
| 486 | let mut zip_archive = ZipArchive::new(file)?; |
| 487 | let mut unzipped_files = 0; |
| 488 | |
| 489 | for i in 0..zip_archive.len() { |
| 490 | let mut file = zip_archive.by_index(i)?; |
| 491 | let path: PathBuf = match file.enclosed_name() { |
| 492 | // This logic is required since some zip files (e.g. chromedriver 115+) |
| 493 | // are zipped with a parent folder, while others (e.g. chromedriver 114-) |
| 494 | // are zipped without a parent folder |
| 495 | Some(p) => { |
| 496 | let iter = p.iter(); |
| 497 | if iter.to_owned().count() > 1 { |
| 498 | iter.skip(1).collect() |
| 499 | } else { |
| 500 | iter.collect() |
| 501 | } |
| 502 | } |
| 503 | None => continue, |
| 504 | }; |
| 505 | if file.name().ends_with('/') { |
| 506 | log.trace(format!("File extracted to {}", tmp_path.display())); |
| 507 | fs::create_dir_all(&tmp_path)?; |
| 508 | } else { |
| 509 | let target_path = tmp_path.join(path.clone()); |
| 510 | create_parent_path_if_not_exists(target_path.as_path())?; |
| 511 | let mut outfile = File::create(&target_path)?; |
| 512 | |
| 513 | // Set permissions in Unix-like systems |
| 514 | #[cfg(unix)] |
| 515 | { |
| 516 | use std::os::unix::fs::PermissionsExt; |
| 517 | |
| 518 | if single_file.is_some() { |
| 519 | fs::set_permissions(&target_path, fs::Permissions::from_mode(0o755))?; |
| 520 | } else if let Some(mode) = file.unix_mode() { |
| 521 | fs::set_permissions(&target_path, fs::Permissions::from_mode(mode))?; |
no test coverage detected