Skip to content

Commit 26492bb

Browse files
committed
Reimagine PR #18 (follow-symlinks support)
1 parent 39dfa92 commit 26492bb

File tree

7 files changed

+49
-15
lines changed

7 files changed

+49
-15
lines changed

Changes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Revision history for File-Find
22

33
{{$NEXT}}
4+
- Add support for :follow-symlinks argument (re-imagined
5+
from PR #18, Garland-g++)
46
- Modernize pod, META and test-file extensions
57
- Add coverage tests (at 100%)
68
- Add CI badge for each OS

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,22 @@ Exclude is meant to be used for skipping certain big and uninteresting directori
4545

4646
The value of `exclude` will be smartmatched against each IO object found by File::Find. It's recommended that it's passed as an IO object (or a Junction of those) so we avoid silly things like slashes vs backslashes on different platforms.
4747

48+
Default is `False`, which means that no files will be excluded.
49+
4850
keep-going
4951
----------
5052

51-
Parameter `keep-going` tells `find()` to not stop finding files on errors such as 'Access is denied', but rather ignore the errors and keep going.
53+
Parameter `keep-going` tells `find()` to not stop finding files on errors such as 'Access is denied', but rather ignore the errors and keep going. Default is `False`
5254

5355
recursive
5456
---------
5557

56-
By default, `find` will recursively traverse a directory tree, descending into any subdirectories it finds. This behaviour can be changed by setting `recursive` to a false value. In this case, only the first level entries will be processed.
58+
By default, `find` will recursively traverse a directory tree, descending into any subdirectories it finds. This behaviour can be changed by setting `recursive` to a false value. In this case, only the first level entries will be processed. Default is `True`.
59+
60+
follow-symlinks
61+
---------------
62+
63+
Parameter `follow-symlinks` tells `find()` whether or not it should follow symlinks during recursive searches. This will still return symlinks in its results, if the type parameter allows. The default is `True`.
5764

5865
CAVEATS
5966
=======

doc/File-Find.rakudoc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,27 @@ found by File::Find. It's recommended that it's passed as an IO object
5757
(or a Junction of those) so we avoid silly things like slashes
5858
vs backslashes on different platforms.
5959

60+
Default is C<False>, which means that no files will be excluded.
61+
6062
=head2 keep-going
6163

6264
Parameter C<keep-going> tells C<find()> to not stop finding files
6365
on errors such as 'Access is denied', but rather ignore the errors
64-
and keep going.
66+
and keep going. Default is C<False>
6567

6668
=head2 recursive
6769

6870
By default, C<find> will recursively traverse a directory tree, descending
6971
into any subdirectories it finds. This behaviour can be changed by setting
7072
C<recursive> to a false value. In this case, only the first level entries
71-
will be processed.
73+
will be processed. Default is C<True>.
74+
75+
=head2 follow-symlinks
76+
77+
Parameter C<follow-symlinks> tells C<find()> whether or not it should
78+
follow symlinks during recursive searches. This will still return
79+
symlinks in its results, if the type parameter allows. The default
80+
is C<True>.
7281

7382
=head1 CAVEATS
7483

lib/File/Find.rakumod

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ my sub find(
2424
:$dir!,
2525
Mu :$name,
2626
:$type,
27-
Mu :$exclude = False,
28-
Bool :$recursive = True,
29-
Bool :$keep-going = False
27+
Mu :$exclude = False,
28+
Bool :$recursive = True,
29+
Bool :$keep-going = False,
30+
Bool :$follow-symlinks = True
3031
) is export {
3132

3233
my @targets = dir($dir);
@@ -35,14 +36,19 @@ my sub find(
3536
# exclude is special because it also stops traversing inside,
3637
# which checkrules does not
3738
next if $elem ~~ $exclude;
39+
3840
take $elem if checkrules($elem, { :$name, :$type, :$exclude });
41+
3942
if $recursive {
40-
if $elem.IO.d {
41-
@targets.append: dir($elem);
42-
CATCH {
43-
when X::IO::Dir {
44-
$_.throw unless $keep-going;
45-
next;
43+
my $io := $elem.IO;
44+
if $follow-symlinks || !$io.l {
45+
if $io.d {
46+
@targets.append: dir($elem);
47+
CATCH {
48+
when X::IO::Dir {
49+
.rethrow unless $keep-going;
50+
next;
51+
}
4652
}
4753
}
4854
}
@@ -52,6 +58,6 @@ my sub find(
5258

5359
#- hack ------------------------------------------------------------------------
5460
# To allow version fetching in test files
55-
unit module File::Find:ver<0.2.0>:auth<zef:raku-community-modules>;
61+
unit module File::Find:ver<0.2.1>:auth<zef:raku-community-modules>;
5662

5763
# vim: expandtab shiftwidth=4

t/01-file-find.rakutest

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use Test;
22
use File::Find;
33

4-
plan 25;
4+
plan 29;
55

66
my $res = find(:dir<t/dir1>);
77
my @test = $res.map({ .Str }).sort;
@@ -70,6 +70,15 @@ dies-ok { find(:dir<t/dir1>, :type<foo>) }, "dies on incorrect type";
7070
my $skip-first = True;
7171
my $throw = True;
7272

73+
#follow-symlinks
74+
$res = find(:dir<t/dir2>);
75+
@test = $res.map({ .Str }).sort;
76+
equals @test, <t/dir2/file.foo t/dir2/symdir t/dir2/symdir/empty_file t/dir2/symdir/file.bar>, 'follow-syminks is True';
77+
78+
$res = find(:dir<t/dir2>, follow-symlinks => False);
79+
@test = $res.map({ .Str }).sort;
80+
equals @test, <t/dir2/file.foo t/dir2/symdir>, 'follow-symlinks is False';
81+
7382
# Wrap dir to throw when we want it to.
7483
my $w = &dir.wrap(sub ($_) {
7584
if $skip-first {

t/dir2/file.foo

Whitespace-only changes.

t/dir2/symdir

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../dir1/another_dir

0 commit comments

Comments
 (0)