/
watch.pm
87 lines (74 loc) · 2.41 KB
/
watch.pm
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
use v6.c;
use File::Find;
use Bailador::CLI;
use Bailador::Command;
class Bailador::Command::watch does Bailador::Command {
has $!process;
method run(:$app) {
my $config = $app.config;
my $watch-command = $config.watch-command;
unless $watch-command {
if $.config.command-detection() {
my $watch-command = $.commands.detect-command();
}
}
unless $watch-command {
die 'cannot detect watch-command'
}
my $param = %*ENV<BAILADOR>;
$param ~= ',default-command:' ~ $watch-command;
%*ENV<BAILADOR> = $param;
my @watchlist = $config.watch-list;
die 'nothing to watch, empty watch-list' unless @watchlist;
$!process = bootup-app();
signal(SIGINT).tap: { self.kill-process(); exit }
react {
whenever watch-recursive(@watchlist.grep: *.IO.e) -> $e {
if $e.path() !~~ /\.sw.$/ and $e.path() !~~ /\~$/ {
say "Change detected [$e.path(), $e.event()]. Restarting app";
self.kill-process();
$!process = bootup-app();
}
}
}
}
method kill-process() {
$!process.kill(SIGINT);
}
my sub bootup-app() {
my @includes = repo-to-includes();
my Proc::Async $p .= new($*EXECUTABLE.Str, |@includes, $*PROGRAM.Str);
$p.stdout.tap: -> $v { $*OUT.print: "# $v" };
$p.stderr.tap: -> $v { $*ERR.print: "! $v" };
$p.start;
return $p;
}
my sub watch-recursive(@elements) is export {
supply {
for @elements -> $path {
if $path.IO.d {
watch-it($_) for find-dirs $path;
} else {
watch-it($path);
}
}
}
}
my sub watch-it($p) {
if ( $p ~~ rx{ '/'? '.precomp' [ '/' | $ ] } ) {
#say "Skipping .precomp dir [$p]";
return;
}
say "Starting watch on `$p`";
whenever IO::Notification.watch-path($p) -> $e {
if $e.event ~~ FileRenamed && $e.path.IO ~~ :d {
watch-it($_) for find-dirs $e.path;
}
emit($e);
}
}
my sub find-dirs (Str:D $p) {
state $seen = {};
return slip ($p.IO, slip find :dir($p), :type<dir>).grep: { !$seen{$_}++ };
}
}