/
Common.pm
116 lines (100 loc) · 2.67 KB
/
Common.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
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
module Panda::Common {
use Shell::Command;
sub dirname ($mod as Str) is export {
$mod.subst(':', '_', :g);
}
sub indir ($where, Callable $what) is export {
mkpath $where;
temp $*CWD = chdir($where);
$what()
}
sub withp6lib(&what) is export {
my $oldp6lib = %*ENV<PERL6LIB>;
LEAVE {
if $oldp6lib.defined {
%*ENV<PERL6LIB> = $oldp6lib;
}
else {
%*ENV<PERL6LIB>:delete;
}
}
my $sep = $*DISTRO.?cur-sep // $*DISTRO.path-sep;
%*ENV<PERL6LIB> = join $sep,
$*CWD ~ '/blib/lib',
$*CWD ~ '/lib',
%*ENV<PERL6LIB> // ();
what();
}
sub compsuffix is export { state $ = $*VM.precomp-ext }
sub comptarget is export { state $ = $*VM.precomp-target }
sub topo-sort(@modules, %dependencies) is export {
my @order;
my %color_of = @modules X=> 'not yet visited';
sub dfs-visit($module) {
%color_of{$module} = 'visited';
for %dependencies{$module}.list -> $used {
if (%color_of{$used} // '') eq 'not yet visited' {
dfs-visit($used);
}
}
push @order, $module;
}
for @modules -> $module {
if %color_of{$module} eq 'not yet visited' {
dfs-visit($module);
}
}
@order;
}
class X::Panda is Exception {
has $.module is rw;
has $.stage;
has $.description;
has $.bone;
method new($module, $stage, $description is copy, :$bone) {
if $description ~~ Failure {
$description = $description.exception.message
}
self.bless(:$module, :$stage, :$description, :$bone)
}
method message {
sprintf "%s stage failed for %s: %s",
$.stage, $.module, $.description
}
}
my $has-proc-async = Proc::<Async>:exists;
sub run-and-gather-output(*@command) is export {
my $output = '';
my $stdout = '';
my $stderr = '';
my $passed;
if $has-proc-async {
my $proc = Proc::Async.new(|@command);
$proc.stdout.tap(-> $chunk {
print $chunk;
$output ~= $chunk;
$stdout ~= $chunk;
});
$proc.stderr.tap(-> $chunk {
print $chunk;
$output ~= $chunk;
$stderr ~= $chunk;
});
my $p = $proc.start;
$passed = $p.result.exitcode == 0;
}
else {
my $cmd = @command.map({ qq{"$_"} }).join(' ');
$output ~= "$cmd\n";
my $p = shell("$cmd 2>&1", :out);
for $p.out.lines {
.chars && .say;
$output ~= "$_\n";
}
$p.out.close;
$passed = $p.exitcode == 0;
}
:$output, :$stdout, :$stderr, :$passed
}
}
# vim: ft=perl6