pull: create the addon directory when unwrapping a multi-orig component
unwrap_into pointed the component's unwrap at '<root>/<addon>' but never created that directory: unwrap_wrapper moves the wrapper's entries into it by rename, and a rename whose target parent is missing fails with ENOENT - every entry, aborting the whole pull. The multi-orig unit test exercised unwrap_wrapper directly and could not see it (dovecot). Also exercise the component through unwrap_into in the test, and assert the wrapper's own layout does not leak to the root - the shape dpkg-source -b rejects as unexpected upstream changes.
This commit is contained in:
+23
-9
@@ -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
|
||||
// '<root>/<addon>' ('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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user