stow_contents: fix bugs and corner cases with type mismatch conflicts

If the target directory as a file named X and a package has a
directory named X, or vice-versa, then it is impossible for Stow
to stow that entry X from the package, even if --adopt is supplied.

However we were previously only handling the former case, and not the
latter, and the test for the former was actually broken.  So fix
stow_contents() to handle both cases correctly, fix the broken test,
and add a new test for the latter case.
This commit is contained in:
Adam Spiers 2024-04-02 00:06:38 +01:00
parent 8ed799a3a3
commit 34421ba5cf
2 changed files with 66 additions and 16 deletions

View file

@ -603,23 +603,45 @@ sub stow_node {
elsif ($self->is_a_node($target_subpath)) {
debug(4, 1, "Evaluate existing node: $target_subpath");
if ($self->is_a_dir($target_subpath)) {
$self->stow_contents(
$self->{stow_path},
$package,
$pkg_subpath,
$target_subpath,
);
if (! -d $pkg_path_from_cwd) {
# FIXME: why wasn't this ever needed before?
$self->conflict(
'stow',
$package,
"cannot stow non-directory $pkg_path_from_cwd over existing directory target $target_subpath"
);
}
else {
$self->stow_contents(
$self->{stow_path},
$package,
$pkg_subpath,
$target_subpath,
);
}
}
else {
# If we're here, $target_subpath is not a current or
# planned directory.
if ($self->{adopt}) {
$self->do_mv($target_subpath, $pkg_path_from_cwd);
$self->do_link($link_dest, $target_subpath);
if (-d $pkg_path_from_cwd) {
$self->conflict(
'stow',
$package,
"cannot stow directory $pkg_path_from_cwd over existing non-directory target $target_subpath"
);
}
else {
$self->do_mv($target_subpath, $pkg_path_from_cwd);
$self->do_link($link_dest, $target_subpath);
}
}
else {
$self->conflict(
'stow',
$package,
"existing target is neither a link nor a directory: $target_subpath"
"cannot stow $pkg_path_from_cwd over existing target $target_subpath since neither a link nor a directory and --adopt not specified"
);
}
}