Use `tar` to extract relevant package metadata and script files from packages files. This function attempts to extract ".MTREE", ".BUILDINFO", ".PKGINFO" and ".INSTALL" files. Extracted files are placed in a directory structure that reflects the package's association with a package repository. ## Note Since some files are optional, we have to take a look at the files in that tarball to determin
(pkg: &Path, target_dir: &Path, repo_name: &str)
| 398 | /// |
| 399 | /// Panics if `pkg` points to a directory. |
| 400 | fn extract_pkg_files(pkg: &Path, target_dir: &Path, repo_name: &str) -> Result<(), Error> { |
| 401 | let pkg_file_name = pkg |
| 402 | .file_name() |
| 403 | .expect("got directory when expecting file") |
| 404 | .to_string_lossy() |
| 405 | .to_string(); |
| 406 | let pkg_name = remove_tarball_suffix(pkg_file_name)?; |
| 407 | |
| 408 | // Peek into the pkg tar to see what kind of files we need to extract. |
| 409 | let files = get_tar_file_list(pkg)?; |
| 410 | |
| 411 | // Create the target directory where all the files should be extracted to. |
| 412 | let pkg_target_dir = target_dir.join(repo_name).join(pkg_name); |
| 413 | create_dir_all(&pkg_target_dir).map_err(|source| Error::IoPath { |
| 414 | path: pkg_target_dir.clone(), |
| 415 | context: "recursively creating the directory".to_string(), |
| 416 | source, |
| 417 | })?; |
| 418 | |
| 419 | let mut cmd_args = vec![ |
| 420 | "-C".to_string(), |
| 421 | pkg_target_dir.to_string_lossy().to_string(), |
| 422 | "-xf".to_string(), |
| 423 | pkg.to_string_lossy().to_string(), |
| 424 | ]; |
| 425 | |
| 426 | // Check for each of the known filetypes, whether it exists in the package. |
| 427 | // If it does, add it to the tar command for extraction. |
| 428 | for filetype in [ |
| 429 | MetadataFileName::Mtree.as_ref(), |
| 430 | MetadataFileName::BuildInfo.as_ref(), |
| 431 | MetadataFileName::PackageInfo.as_ref(), |
| 432 | INSTALL_SCRIPTLET_FILE_NAME, |
| 433 | ] { |
| 434 | if files.contains(filetype) { |
| 435 | cmd_args.push(filetype.to_string()); |
| 436 | } |
| 437 | } |
| 438 | |
| 439 | // Run the extraction command |
| 440 | let mut tar_command = Command::new("tar"); |
| 441 | tar_command.args(cmd_args); |
| 442 | |
| 443 | trace!("Running command: {tar_command:?}"); |
| 444 | let output = tar_command.output().map_err(|source| Error::IoPath { |
| 445 | path: pkg.to_path_buf(), |
| 446 | context: "extracting files".to_string(), |
| 447 | source, |
| 448 | })?; |
| 449 | ensure_success(&output, format!("Extracting files from tar file {pkg:?}"))?; |
| 450 | |
| 451 | Ok(()) |
| 452 | } |
| 453 | |
| 454 | /// A small helper function that removes the `.pkg.tar.*` suffix of a tarball. |
| 455 | /// This is necessary to get the actual package name from a packages full file name. |
no test coverage detected