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:
parent
8ed799a3a3
commit
34421ba5cf
2 changed files with 66 additions and 16 deletions
|
@ -603,6 +603,15 @@ sub stow_node {
|
||||||
elsif ($self->is_a_node($target_subpath)) {
|
elsif ($self->is_a_node($target_subpath)) {
|
||||||
debug(4, 1, "Evaluate existing node: $target_subpath");
|
debug(4, 1, "Evaluate existing node: $target_subpath");
|
||||||
if ($self->is_a_dir($target_subpath)) {
|
if ($self->is_a_dir($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_contents(
|
||||||
$self->{stow_path},
|
$self->{stow_path},
|
||||||
$package,
|
$package,
|
||||||
|
@ -610,16 +619,29 @@ sub stow_node {
|
||||||
$target_subpath,
|
$target_subpath,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
# If we're here, $target_subpath is not a current or
|
||||||
|
# planned directory.
|
||||||
|
|
||||||
if ($self->{adopt}) {
|
if ($self->{adopt}) {
|
||||||
|
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_mv($target_subpath, $pkg_path_from_cwd);
|
||||||
$self->do_link($link_dest, $target_subpath);
|
$self->do_link($link_dest, $target_subpath);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
$self->conflict(
|
$self->conflict(
|
||||||
'stow',
|
'stow',
|
||||||
$package,
|
$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"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
42
t/stow.t
42
t/stow.t
|
@ -22,7 +22,7 @@
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Test::More tests => 21;
|
use Test::More tests => 22;
|
||||||
use Test::Output;
|
use Test::Output;
|
||||||
use English qw(-no_match_vars);
|
use English qw(-no_match_vars);
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ subtest("Package dir 'bin4' conflicts with existing non-dir so can't unfold", su
|
||||||
is($stow->get_conflict_count, 1);
|
is($stow->get_conflict_count, 1);
|
||||||
like(
|
like(
|
||||||
$conflicts{stow}{pkg4}[0],
|
$conflicts{stow}{pkg4}[0],
|
||||||
qr/existing target is neither a link nor a directory/
|
qr!cannot stow ../stow/pkg4/bin4 over existing target bin4 since neither a link nor a directory and --adopt not specified!
|
||||||
=> 'link to new dir bin4 conflicts with existing non-directory'
|
=> 'link to new dir bin4 conflicts with existing non-directory'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -111,8 +111,7 @@ subtest("Package dir 'bin4' conflicts with existing non-dir so can't unfold", su
|
||||||
subtest("Package dir 'bin4a' conflicts with existing non-dir " .
|
subtest("Package dir 'bin4a' conflicts with existing non-dir " .
|
||||||
"so can't unfold even with --adopt", sub {
|
"so can't unfold even with --adopt", sub {
|
||||||
plan tests => 2;
|
plan tests => 2;
|
||||||
#my $stow = new_Stow(adopt => 1);
|
my $stow = new_Stow(adopt => 1);
|
||||||
my $stow = new_Stow();
|
|
||||||
|
|
||||||
make_file('bin4a'); # this is a file but named like a directory
|
make_file('bin4a'); # this is a file but named like a directory
|
||||||
make_path('../stow/pkg4a/bin4a');
|
make_path('../stow/pkg4a/bin4a');
|
||||||
|
@ -121,8 +120,9 @@ subtest("Package dir 'bin4a' conflicts with existing non-dir " .
|
||||||
$stow->plan_stow('pkg4a');
|
$stow->plan_stow('pkg4a');
|
||||||
%conflicts = $stow->get_conflicts();
|
%conflicts = $stow->get_conflicts();
|
||||||
is($stow->get_conflict_count, 1);
|
is($stow->get_conflict_count, 1);
|
||||||
like($conflicts{stow}{pkg4a}[0],
|
like(
|
||||||
qr/existing target is neither a link nor a directory/
|
$conflicts{stow}{pkg4a}[0],
|
||||||
|
qr!cannot stow directory ../stow/pkg4a/bin4a over existing non-directory target bin4a!
|
||||||
=> 'link to new dir bin4a conflicts with existing non-directory'
|
=> 'link to new dir bin4a conflicts with existing non-directory'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -146,14 +146,42 @@ subtest("Package files 'file4b' and 'bin4b' conflict with existing files", sub {
|
||||||
%conflicts = $stow->get_conflicts();
|
%conflicts = $stow->get_conflicts();
|
||||||
is($stow->get_conflict_count, 2 => 'conflict per file');
|
is($stow->get_conflict_count, 2 => 'conflict per file');
|
||||||
for my $i (0, 1) {
|
for my $i (0, 1) {
|
||||||
|
my $target = $i ? 'file4b' : 'bin4b/file4b';
|
||||||
like(
|
like(
|
||||||
$conflicts{stow}{pkg4b}[$i],
|
$conflicts{stow}{pkg4b}[$i],
|
||||||
qr/existing target is neither a link nor a directory/
|
qr,cannot stow ../stow/pkg4b/$target over existing target $target since neither a link nor a directory and --adopt not specified,
|
||||||
=> 'link to file4b conflicts with existing non-directory'
|
=> 'link to file4b conflicts with existing non-directory'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
subtest("Package files 'file4d' conflicts with existing directories", sub {
|
||||||
|
plan tests => 3;
|
||||||
|
my $stow = new_Stow();
|
||||||
|
|
||||||
|
# Populate target
|
||||||
|
make_path('file4d'); # this is a directory but named like a file to create the conflict
|
||||||
|
make_path('bin4d/file4d'); # same here
|
||||||
|
|
||||||
|
# Populate stow package
|
||||||
|
make_path('../stow/pkg4d');
|
||||||
|
make_file('../stow/pkg4d/file4d', 'file4d - version originally in stow package');
|
||||||
|
make_path('../stow/pkg4d/bin4d');
|
||||||
|
make_file('../stow/pkg4d/bin4d/file4d', 'bin4d/file4d - version originally in stow package');
|
||||||
|
|
||||||
|
$stow->plan_stow('pkg4d');
|
||||||
|
%conflicts = $stow->get_conflicts();
|
||||||
|
is($stow->get_conflict_count, 2 => 'conflict per file');
|
||||||
|
for my $i (0, 1) {
|
||||||
|
my $target = $i ? 'file4d' : 'bin4d/file4d';
|
||||||
|
like(
|
||||||
|
$conflicts{stow}{pkg4d}[$i],
|
||||||
|
qr!cannot stow non-directory ../stow/pkg4d/$target over existing directory target $target!
|
||||||
|
=> 'link to file4d conflicts with existing non-directory'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
subtest("Package files 'file4c' and 'bin4c' can adopt existing versions", sub {
|
subtest("Package files 'file4c' and 'bin4c' can adopt existing versions", sub {
|
||||||
plan tests => 8;
|
plan tests => 8;
|
||||||
my $stow = new_Stow(adopt => 1);
|
my $stow = new_Stow(adopt => 1);
|
||||||
|
|
Loading…
Reference in a new issue