summaryrefslogtreecommitdiff
path: root/lib/Ultramarine/Model/DirScanner.pm6
blob: 1ab35f6c1f8758527ebd05ea1b44707dd7f609ea (plain)
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
use v6.d.PREVIEW;
 
class Ultramarine::Model::DirScanner {
    has IO $.root is required;
    submethod BUILD(IO() :$!root!{}
 
    class EndOfScan {}
 
    method scan(--> Supply{
        my $ret = Supplier::Preserving.new;
 
        my sub inner-scan(IO() $path) {
            my @todo = $path;
            while @todo {
                my $next = @todo.pop;
                $ret.emit($next);
                next unless $next ~~ :d & :r & :x;
                $next.watch().tap({ inner-scan($^event.path});
                for $next.dir(:CWD($next.CWD)) -> $child {
                    @todo.push($child);
                }
                CATCH {
                    when X::IO::Dir { }
                }
            }
        }
 
        (start {
            inner-scan(IO::Path.new('.',:CWD($.root)));
            $ret.emit(EndOfScan);
        }).then(-> $p { $ret.quit($p.causeif $p.status ~~ Broken });
 
        CATCH { $ret.quit($_};
        return $ret.Supply;
    }
}