diff --git a/src/pull.rs b/src/pull.rs index 7cf1d1b..8666670 100644 --- a/src/pull.rs +++ b/src/pull.rs @@ -173,6 +173,7 @@ fn unwrap_into(dir: &Path, wrapper: &Path, addon: Option<&str>) -> Result<(), Bo if target.is_dir() { std::fs::remove_dir_all(&target)?; } + std::fs::create_dir_all(&target)?; target } None => dir.to_path_buf(), @@ -1396,19 +1397,26 @@ mod tests { #[test] fn test_unwrap_wrapper_of_second_multi_orig_component() { // Regression: multi-orig packages (e.g. dovecot) extract a second - // component into a tree root the first component already filled; - // recognizing the wrapper from the shape of the root skipped the - // second component's unwrap and left its sources nested one level - // too deep + // component into a tree root the first component already filled, + // and dpkg-source expects the component's content at + // '/' ('pigeonhole' for '...orig-pigeonhole.tar.gz'), + // not the wrapper's own layout at the root. The addon directory + // used to never be created: every move into it failed with ENOENT + // and the pull aborted. let temp_dir = tempfile::tempdir().unwrap(); let tree = temp_dir.path().join("tree"); let main = temp_dir.path().join("main.orig.tar"); std::fs::write(&main, build_tar(&[("dovecot-2.4.5/README", b"main")])).unwrap(); let extracted = extract_tar_archive(&main, &tree, None, |f| f).unwrap(); - unwrap_wrapper(&tree, &extracted.wrapper.unwrap()).unwrap(); + unwrap_into( + &tree, + &extracted.wrapper.unwrap(), + component_addon("main.orig.tar"), + ) + .unwrap(); - let component = temp_dir.path().join("component.orig.tar"); + let component = temp_dir.path().join("pkg_1.0.orig-pigeonhole.tar.gz"); std::fs::write( &component, build_tar(&[ @@ -1418,20 +1426,26 @@ mod tests { ) .unwrap(); let extracted = extract_tar_archive(&component, &tree, None, |f| f).unwrap(); - unwrap_wrapper(&tree, &extracted.wrapper.unwrap()).unwrap(); + unwrap_into( + &tree, + &extracted.wrapper.unwrap(), + component_addon("pkg_1.0.orig-pigeonhole.tar.gz"), + ) + .unwrap(); assert_eq!( std::fs::read_to_string(tree.join("README")).unwrap(), "main" ); assert_eq!( - std::fs::read_to_string(tree.join("update-version.sh")).unwrap(), + std::fs::read_to_string(tree.join("pigeonhole/update-version.sh")).unwrap(), "sh" ); assert_eq!( - std::fs::read_to_string(tree.join("pigeonhole/x")).unwrap(), + std::fs::read_to_string(tree.join("pigeonhole/pigeonhole/x")).unwrap(), "ph" ); + assert!(!tree.join("update-version.sh").exists()); assert!(!tree.join("dovecot-2.4.5").exists()); assert!(!tree.join("dovecot-pigeonhole-2.4.5").exists()); }