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() {
|
if target.is_dir() {
|
||||||
std::fs::remove_dir_all(&target)?;
|
std::fs::remove_dir_all(&target)?;
|
||||||
}
|
}
|
||||||
|
std::fs::create_dir_all(&target)?;
|
||||||
target
|
target
|
||||||
}
|
}
|
||||||
None => dir.to_path_buf(),
|
None => dir.to_path_buf(),
|
||||||
@@ -1396,19 +1397,26 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_unwrap_wrapper_of_second_multi_orig_component() {
|
fn test_unwrap_wrapper_of_second_multi_orig_component() {
|
||||||
// Regression: multi-orig packages (e.g. dovecot) extract a second
|
// Regression: multi-orig packages (e.g. dovecot) extract a second
|
||||||
// component into a tree root the first component already filled;
|
// component into a tree root the first component already filled,
|
||||||
// recognizing the wrapper from the shape of the root skipped the
|
// and dpkg-source expects the component's content at
|
||||||
// second component's unwrap and left its sources nested one level
|
// '<root>/<addon>' ('pigeonhole' for '...orig-pigeonhole.tar.gz'),
|
||||||
// too deep
|
// 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 temp_dir = tempfile::tempdir().unwrap();
|
||||||
let tree = temp_dir.path().join("tree");
|
let tree = temp_dir.path().join("tree");
|
||||||
|
|
||||||
let main = temp_dir.path().join("main.orig.tar");
|
let main = temp_dir.path().join("main.orig.tar");
|
||||||
std::fs::write(&main, build_tar(&[("dovecot-2.4.5/README", b"main")])).unwrap();
|
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();
|
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(
|
std::fs::write(
|
||||||
&component,
|
&component,
|
||||||
build_tar(&[
|
build_tar(&[
|
||||||
@@ -1418,20 +1426,26 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let extracted = extract_tar_archive(&component, &tree, None, |f| f).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!(
|
assert_eq!(
|
||||||
std::fs::read_to_string(tree.join("README")).unwrap(),
|
std::fs::read_to_string(tree.join("README")).unwrap(),
|
||||||
"main"
|
"main"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
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"
|
"sh"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
std::fs::read_to_string(tree.join("pigeonhole/x")).unwrap(),
|
std::fs::read_to_string(tree.join("pigeonhole/pigeonhole/x")).unwrap(),
|
||||||
"ph"
|
"ph"
|
||||||
);
|
);
|
||||||
|
assert!(!tree.join("update-version.sh").exists());
|
||||||
assert!(!tree.join("dovecot-2.4.5").exists());
|
assert!(!tree.join("dovecot-2.4.5").exists());
|
||||||
assert!(!tree.join("dovecot-pigeonhole-2.4.5").exists());
|
assert!(!tree.join("dovecot-pigeonhole-2.4.5").exists());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user