Skip to content

Commit d55f7cd

Browse files
committed
Merge remote-tracking branch 'AitorATuin/bug-56727'
aspiers#70
2 parents 4ef5eca + a41118d commit d55f7cd

File tree

2 files changed

+98
-11
lines changed

2 files changed

+98
-11
lines changed

lib/Stow.pm.in

+17-10
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ sub plan_unstow {
284284
$self->{stow_path},
285285
$package,
286286
'.',
287+
$path,
287288
);
288289
}
289290
debug(2, "Planning unstow of package $package... done");
@@ -316,6 +317,7 @@ sub plan_stow {
316317
$package,
317318
'.',
318319
$path, # source from target
320+
0,
319321
);
320322
debug(2, "Planning stow of package $package... done");
321323
$self->{action_count}++;
@@ -367,10 +369,12 @@ sub within_target_do {
367369
#============================================================================
368370
sub stow_contents {
369371
my $self = shift;
370-
my ($stow_path, $package, $target, $source) = @_;
371-
372-
my $path = join_paths($stow_path, $package, $target);
372+
my ($stow_path, $package, $target, $source, $level) = @_;
373373

374+
# Remove leading $level times .. from $source
375+
my $n = 0;
376+
my $path = join '/', map { (++$n <= $level) ? ( ) : $_ } (split m{/+}, $source);
377+
374378
return if $self->should_skip_target_which_is_stow_dir($target);
375379

376380
my $cwd = getcwd();
@@ -407,6 +411,7 @@ sub stow_contents {
407411
$package,
408412
$node_target, # target
409413
join_paths($source, $node), # source
414+
$level
410415
);
411416
}
412417
}
@@ -429,7 +434,7 @@ sub stow_contents {
429434
#============================================================================
430435
sub stow_node {
431436
my $self = shift;
432-
my ($stow_path, $package, $target, $source) = @_;
437+
my ($stow_path, $package, $target, $source, $level) = @_;
433438

434439
my $path = join_paths($stow_path, $package, $target);
435440

@@ -499,12 +504,14 @@ sub stow_node {
499504
$existing_package,
500505
$target,
501506
join_paths('..', $existing_source),
507+
$level + 1,
502508
);
503509
$self->stow_contents(
504510
$self->{stow_path},
505511
$package,
506512
$target,
507513
join_paths('..', $source),
514+
$level + 1,
508515
);
509516
}
510517
else {
@@ -531,6 +538,7 @@ sub stow_node {
531538
$package,
532539
$target,
533540
join_paths('..', $source),
541+
$level + 1,
534542
);
535543
}
536544
else {
@@ -554,6 +562,7 @@ sub stow_node {
554562
$package,
555563
$target,
556564
join_paths('..', $source),
565+
$level + 1,
557566
);
558567
}
559568
else {
@@ -740,9 +749,7 @@ sub unstow_node_orig {
740749
#============================================================================
741750
sub unstow_contents {
742751
my $self = shift;
743-
my ($stow_path, $package, $target) = @_;
744-
745-
my $path = join_paths($stow_path, $package, $target);
752+
my ($stow_path, $package, $target, $path) = @_;
746753

747754
return if $self->should_skip_target_which_is_stow_dir($target);
748755

@@ -778,7 +785,7 @@ sub unstow_contents {
778785
$node_target = $adj_node_target;
779786
}
780787

781-
$self->unstow_node($stow_path, $package, $node_target);
788+
$self->unstow_node($stow_path, $package, $node_target, join_paths($path, $node));
782789
}
783790
if (-d $target) {
784791
$self->cleanup_invalid_links($target);
@@ -798,7 +805,7 @@ sub unstow_contents {
798805
#============================================================================
799806
sub unstow_node {
800807
my $self = shift;
801-
my ($stow_path, $package, $target) = @_;
808+
my ($stow_path, $package, $target, $source) = @_;
802809

803810
my $path = join_paths($stow_path, $package, $target);
804811

@@ -872,7 +879,7 @@ sub unstow_node {
872879
elsif (-e $target) {
873880
debug(4, " Evaluate existing node: $target");
874881
if (-d $target) {
875-
$self->unstow_contents($stow_path, $package, $target);
882+
$self->unstow_contents($stow_path, $package, $target, $source);
876883

877884
# This action may have made the parent directory foldable
878885
if (my $parent = $self->foldable($target)) {

t/dotfiles.t

+81-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use warnings;
2424

2525
use testutil;
2626

27-
use Test::More tests => 6;
27+
use Test::More tests => 10;
2828
use English qw(-no_match_vars);
2929

3030
use testutil;
@@ -86,6 +86,64 @@ is(
8686
=> 'processed dotfile folder'
8787
);
8888

89+
#
90+
# process folder marked with 'dot' prefix
91+
# when directory exists is target
92+
#
93+
94+
$stow = new_Stow(dir => '../stow', dotfiles => 1);
95+
96+
make_path('../stow/dotfiles/dot-emacs.d');
97+
make_file('../stow/dotfiles/dot-emacs.d/init.el');
98+
make_path('.emacs.d');
99+
100+
$stow->plan_stow('dotfiles');
101+
$stow->process_tasks();
102+
is(
103+
readlink('.emacs.d/init.el'),
104+
'../../stow/dotfiles/dot-emacs.d/init.el',
105+
=> 'processed dotfile folder when folder exists (1 level)'
106+
);
107+
108+
#
109+
# process folder marked with 'dot' prefix
110+
# when directory exists is target (2 levels)
111+
#
112+
113+
$stow = new_Stow(dir => '../stow', dotfiles => 1);
114+
115+
make_path('../stow/dotfiles/dot-emacs.d/dot-emacs.d');
116+
make_file('../stow/dotfiles/dot-emacs.d/dot-emacs.d/init.el');
117+
make_path('.emacs.d');
118+
119+
$stow->plan_stow('dotfiles');
120+
$stow->process_tasks();
121+
is(
122+
readlink('.emacs.d/.emacs.d'),
123+
'../../stow/dotfiles/dot-emacs.d/dot-emacs.d',
124+
=> 'processed dotfile folder exists (2 levels)'
125+
);
126+
127+
#
128+
# process folder marked with 'dot' prefix
129+
# when directory exists is target
130+
#
131+
132+
$stow = new_Stow(dir => '../stow', dotfiles => 1);
133+
134+
make_path('../stow/dotfiles/dot-one/dot-two');
135+
make_file('../stow/dotfiles/dot-one/dot-two/three');
136+
make_path('.one/.two');
137+
138+
$stow->plan_stow('dotfiles');
139+
$stow->process_tasks();
140+
is(
141+
readlink('./.one/.two/three'),
142+
'../../../stow/dotfiles/dot-one/dot-two/three',
143+
=> 'processed dotfile 2 folder exists (2 levels)'
144+
);
145+
146+
89147
#
90148
# corner case: paths that have a part in them that's just "$DOT_PREFIX" or
91149
# "$DOT_PREFIX." should not have that part expanded.
@@ -129,3 +187,25 @@ ok(
129187
-f '../stow/dotfiles/dot-bar' && ! -e '.bar'
130188
=> 'unstow a simple dotfile'
131189
);
190+
191+
#
192+
# unstow process folder marked with 'dot' prefix
193+
# when directory exists is target
194+
#
195+
196+
$stow = new_Stow(dir => '../stow', dotfiles => 1);
197+
198+
make_path('../stow/dotfiles/dot-emacs.d');
199+
make_file('../stow/dotfiles/dot-emacs.d/init.el');
200+
make_path('.emacs.d');
201+
make_link('.emacs.d/init.el', '../../stow/dotfiles/dot-emacs.d/init.el');
202+
203+
$stow->plan_unstow('dotfiles');
204+
$stow->process_tasks();
205+
ok(
206+
$stow->get_conflict_count == 0 &&
207+
-f '../stow/dotfiles/dot-emacs.d/init.el' &&
208+
! -e '.emacs.d/init.el' &&
209+
-d '.emacs.d/'
210+
=> 'unstow dotfile folder when folder already exists'
211+
);

0 commit comments

Comments
 (0)