Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 120 lines (94 sloc) 3.292 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
use v6;

module File::Find;

sub checkrules ($elem, %opts) {
    if %opts<name>.defined {
        given %opts<name> {
            when Regex {
                return False unless $elem ~~ %opts<name>
            }
            when Str {
                return False unless $elem.basename ~~ %opts<name>
            }
            default {
                die "name attribute has to be either Regex or Str"
            }
        }
    }
    if %opts<type>.defined {
        given %opts<type> {
            when 'dir' {
                return False unless $elem.IO ~~ :d
            }
            when 'file' {
                return False unless $elem.IO ~~ :f
            }
            when 'symlink' {
                return False unless $elem.IO ~~ :l
            }
            default {
                die "type attribute has to be dir, file or symlink";
            }
        }
    }
    return True
}

sub find (:$dir!, :$name, :$type, Bool :$recursive = True,
Bool :$keep-going = False) is export {

    my @targets = dir($dir);
    my $list = gather while @targets {
        my $elem = @targets.shift;
        take $elem if checkrules($elem, { :$name, :$type });
        if $recursive {
            if $elem.IO ~~ :d {
                @targets.push: dir($elem);
                CATCH { when X::IO::Dir {
                    $_.throw unless $keep-going;
                    next;
                }}
            }
        }
    }
    return $list;
}

=begin pod

=head1 NAME

File::Find - Get a lazy list of a directory tree

=head1 SYNOPSIS

    use File::Find;

    my @list := find(dir => 'foo');
    say @list[0..3];

    my $list = find(dir => 'foo');
    say $list[0..3];

=head1 DESCRIPTION

C<File::Find> allows you to get the contents of the given directory,
recursively, depth first.
The only exported function, C<find()>, generates a lazy
list of files in given directory. Every element of the list is an
C<IO::Path> object, described below.
C<find()> takes one (or more) named arguments. The C<dir> argument
is mandatory, and sets the directory C<find()> will traverse.
There are also few optional arguments. If more than one is passed,
all of them must match for a file to be returned.

=head2 name

Specify a name of the file C<File::Find> is ought to look for. If you
pass a string here, C<find()> will return only the files with the given
name. When passing a regex, only the files with path matching the
pattern will be returned.

=head2 type

Given a type, C<find()> will only return files being the given type.
The available types are C<file>, C<dir> or C<symlink>.

=head2 keep-going

Parameter C<keep-going> tells C<find()> to not stop finding files
on errors such as 'Access is denied', but rather ignore the errors
and keep going.

=head1 Perl 5's File::Find

Please note, that this module is not trying to be the verbatim port of
Perl 5's File::Find module. Its interface is closer to Perl 5's
File::Find::Rule, and its features are planned to be similar one day.

=head1 CAVEATS

List assignment is eager in Perl 6, so if You assign C<find()> result
to an array, the elements will be copied and the laziness will be
spoiled. For a proper lazy list, use either binding (C<:=>) or assign
a result to a scalar value (see SYNOPSIS).

=end pod

# vim: ft=perl6
Something went wrong with that request. Please try again.