| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package ExtUtils::Builder::Planner; |
|
2
|
|
|
|
|
|
|
$ExtUtils::Builder::Planner::VERSION = '0.020'; |
|
3
|
5
|
|
|
5
|
|
645003
|
use strict; |
|
|
5
|
|
|
|
|
14
|
|
|
|
5
|
|
|
|
|
192
|
|
|
4
|
5
|
|
|
5
|
|
28
|
use warnings; |
|
|
5
|
|
|
|
|
10
|
|
|
|
5
|
|
|
|
|
307
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
5
|
|
|
5
|
|
32
|
use Carp (); |
|
|
5
|
|
|
|
|
9
|
|
|
|
5
|
|
|
|
|
125
|
|
|
7
|
5
|
|
|
5
|
|
28
|
use File::Basename; |
|
|
5
|
|
|
|
|
22
|
|
|
|
5
|
|
|
|
|
603
|
|
|
8
|
5
|
|
|
5
|
|
35
|
use File::Spec; |
|
|
5
|
|
|
|
|
13
|
|
|
|
5
|
|
|
|
|
160
|
|
|
9
|
5
|
|
|
5
|
|
27
|
use List::Util 1.45 (); |
|
|
5
|
|
|
|
|
176
|
|
|
|
5
|
|
|
|
|
120
|
|
|
10
|
5
|
|
|
5
|
|
25
|
use Scalar::Util (); |
|
|
5
|
|
|
|
|
10
|
|
|
|
5
|
|
|
|
|
133
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
5
|
|
|
5
|
|
2777
|
use ExtUtils::Builder::Plan; |
|
|
5
|
|
|
|
|
17
|
|
|
|
5
|
|
|
|
|
200
|
|
|
13
|
5
|
|
|
5
|
|
2740
|
use ExtUtils::Builder::Node; |
|
|
5
|
|
|
|
|
37
|
|
|
|
5
|
|
|
|
|
243
|
|
|
14
|
5
|
|
|
5
|
|
2858
|
use ExtUtils::Builder::Util; |
|
|
5
|
|
|
|
|
24
|
|
|
|
5
|
|
|
|
|
366
|
|
|
15
|
|
|
|
|
|
|
|
|
16
|
5
|
|
|
5
|
|
2983
|
use ExtUtils::Builder::FileSet::Free; |
|
|
5
|
|
|
|
|
18
|
|
|
|
5
|
|
|
|
|
229
|
|
|
17
|
5
|
|
|
5
|
|
2729
|
use ExtUtils::Builder::FileSet::Filter; |
|
|
5
|
|
|
|
|
18
|
|
|
|
5
|
|
|
|
|
186
|
|
|
18
|
5
|
|
|
5
|
|
2794
|
use ExtUtils::Builder::FileSet::Subst; |
|
|
5
|
|
|
|
|
54
|
|
|
|
5
|
|
|
|
|
902
|
|
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
my $class_counter = 0; |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub new { |
|
23
|
3
|
|
|
3
|
1
|
786738
|
my $base_class = shift; |
|
24
|
3
|
|
|
|
|
43
|
my $all_files = ExtUtils::Builder::FileSet::Free->new; |
|
25
|
3
|
|
|
|
|
21
|
return $base_class->_new_scope($base_class, undef, {}, { 'all-files' => $all_files }); |
|
26
|
|
|
|
|
|
|
} |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub _new_scope { |
|
29
|
3
|
|
|
3
|
|
11
|
my ($self, $base_class, $outer, $nodes, $filesets) = @_; |
|
30
|
|
|
|
|
|
|
|
|
31
|
3
|
|
|
|
|
10
|
my $class = __PACKAGE__ . '::Anon_' . ++$class_counter; |
|
32
|
5
|
|
|
5
|
|
42
|
no strict 'refs'; |
|
|
5
|
|
|
|
|
10
|
|
|
|
5
|
|
|
|
|
10619
|
|
|
33
|
3
|
|
|
|
|
7
|
push @{ "$class\::ISA" }, $base_class; |
|
|
3
|
|
|
|
|
47
|
|
|
34
|
|
|
|
|
|
|
|
|
35
|
3
|
|
|
|
|
18
|
my $new = bless { |
|
36
|
|
|
|
|
|
|
nodes => $nodes, |
|
37
|
|
|
|
|
|
|
filesets => $filesets |
|
38
|
|
|
|
|
|
|
}, $class; |
|
39
|
|
|
|
|
|
|
|
|
40
|
3
|
|
|
0
|
|
33
|
$new->add_delegate('self', sub { $new }); |
|
|
0
|
|
|
5
|
|
0
|
|
|
41
|
3
|
|
|
0
|
|
15
|
$new->add_delegate('outer', sub { $outer }); |
|
|
0
|
|
|
5
|
|
0
|
|
|
42
|
|
|
|
|
|
|
|
|
43
|
3
|
|
|
|
|
10
|
return $new; |
|
44
|
|
|
|
|
|
|
} |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub new_scope { |
|
47
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
|
48
|
0
|
|
|
|
|
0
|
return $self->_new_scope(ref($self), $self, $self->{nodes}, $self->{filesets}); |
|
49
|
|
|
|
|
|
|
} |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
sub add_node { |
|
52
|
11
|
|
|
11
|
1
|
22
|
my ($self, $node) = @_; |
|
53
|
11
|
|
|
|
|
30
|
my $target = $node->target; |
|
54
|
11
|
50
|
|
|
|
37
|
if (exists $self->{nodes}{$target}) { |
|
55
|
0
|
0
|
0
|
|
|
0
|
Carp::croak("Duplicate for target $target") if !$node->mergeable or !$self->{nodes}{$target}->mergeable; |
|
56
|
0
|
|
|
|
|
0
|
my @dependencies = List::Util::uniq($self->{nodes}{$target}->dependencies, $node->dependencies); |
|
57
|
0
|
|
|
|
|
0
|
my $new = ExtUtils::Builder::Node->new(target => $target, dependencies => \@dependencies, phony => 1); |
|
58
|
0
|
|
|
|
|
0
|
$self->{nodes}{$target} = $new; |
|
59
|
|
|
|
|
|
|
} else { |
|
60
|
11
|
|
|
|
|
28
|
$self->{nodes}{$target} = $node; |
|
61
|
11
|
100
|
|
|
|
30
|
$self->{filesets}{'all-files'}->add_input($target) if not $node->phony; |
|
62
|
|
|
|
|
|
|
} |
|
63
|
11
|
|
|
|
|
35
|
return $node->target; |
|
64
|
|
|
|
|
|
|
} |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
sub create_node { |
|
67
|
11
|
|
|
11
|
1
|
101
|
my ($self, %args) = @_; |
|
68
|
11
|
|
|
|
|
54
|
my $node = ExtUtils::Builder::Node->new(%args); |
|
69
|
11
|
|
|
|
|
46
|
return $self->add_node($node); |
|
70
|
|
|
|
|
|
|
} |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub create_phony { |
|
73
|
0
|
|
|
0
|
1
|
0
|
my ($self, $target, @dependencies) = @_; |
|
74
|
0
|
|
|
|
|
0
|
return $self->create_node( |
|
75
|
|
|
|
|
|
|
target => $target, |
|
76
|
|
|
|
|
|
|
dependencies => \@dependencies, |
|
77
|
|
|
|
|
|
|
type => 'phony', |
|
78
|
|
|
|
|
|
|
); |
|
79
|
|
|
|
|
|
|
} |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
my $counter = 0; |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub _create_callback { |
|
84
|
2
|
|
|
2
|
|
8
|
my ($self, $add_to) = @_; |
|
85
|
2
|
50
|
|
|
|
23
|
return undef unless $add_to; |
|
86
|
0
|
|
|
|
|
0
|
my $this = $self; |
|
87
|
0
|
|
|
|
|
0
|
Scalar::Util::weaken($this); |
|
88
|
|
|
|
|
|
|
return sub { |
|
89
|
0
|
|
|
0
|
|
0
|
my ($entry) = @_; |
|
90
|
0
|
|
|
|
|
0
|
$this->create_phony($add_to, $entry); |
|
91
|
0
|
|
|
|
|
0
|
}; |
|
92
|
|
|
|
|
|
|
} |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub create_filter { |
|
95
|
1
|
|
|
1
|
1
|
6
|
my ($self, %args) = @_; |
|
96
|
|
|
|
|
|
|
my $set = ExtUtils::Builder::FileSet::Filter->new( |
|
97
|
|
|
|
|
|
|
condition => $args{condition}, |
|
98
|
1
|
|
|
|
|
8
|
callback => $self->_create_callback($args{add_to}), |
|
99
|
|
|
|
|
|
|
); |
|
100
|
1
|
|
50
|
|
|
8
|
my $on = $args{on} // 'all-files'; |
|
101
|
1
|
50
|
|
|
|
5
|
my @sources = ref($on) eq 'ARRAY' ? @{$on} : $on; |
|
|
0
|
|
|
|
|
0
|
|
|
102
|
1
|
|
|
|
|
3
|
for my $source (@sources) { |
|
103
|
1
|
50
|
|
|
|
9
|
my $object = $self->{filesets}{$source} or die "No such source $source"; |
|
104
|
1
|
|
|
|
|
9
|
$object->add_dependent($set); |
|
105
|
|
|
|
|
|
|
} |
|
106
|
1
|
|
33
|
|
|
9
|
my $name = $args{name} // 'filter-' . $counter++; |
|
107
|
1
|
|
|
|
|
3
|
$self->{filesets}{$name} = $set; |
|
108
|
1
|
|
|
|
|
6
|
return $name; |
|
109
|
|
|
|
|
|
|
} |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub _make_pattern { |
|
112
|
1
|
|
|
1
|
|
34
|
my ($self, %options) = @_; |
|
113
|
1
|
50
|
|
|
|
6
|
if ($options{file}) { |
|
|
|
0
|
|
|
|
|
|
|
114
|
1
|
|
|
|
|
6
|
my $file = ExtUtils::Builder::Util::glob_to_regex($options{file}); |
|
115
|
1
|
50
|
|
|
|
5
|
if ($options{dir}) { |
|
116
|
0
|
|
|
|
|
0
|
my $dir = ExtUtils::Builder::Util::native_to_unix_path($options{dir}); |
|
117
|
0
|
|
|
|
|
0
|
$dir =~ s{(?
|
|
118
|
|
|
|
|
|
|
return sub { |
|
119
|
0
|
|
|
0
|
|
0
|
my ($input) = @_; |
|
120
|
0
|
|
|
|
|
0
|
my $filename = ExtUtils::Builder::Util::native_to_unix_path($input); |
|
121
|
0
|
0
|
|
|
|
0
|
return if substr($filename, 0, length $dir) ne $dir; |
|
122
|
0
|
|
|
|
|
0
|
return File::Basename::basename($filename) =~ $file; |
|
123
|
0
|
|
|
|
|
0
|
}; |
|
124
|
|
|
|
|
|
|
} else { |
|
125
|
|
|
|
|
|
|
return sub { |
|
126
|
5
|
|
|
5
|
|
12
|
my ($filename) = @_; |
|
127
|
5
|
|
|
|
|
233
|
return File::Basename::basename($filename) =~ $file; |
|
128
|
1
|
|
|
|
|
8
|
}; |
|
129
|
|
|
|
|
|
|
} |
|
130
|
|
|
|
|
|
|
} elsif ($options{dir}) { |
|
131
|
0
|
|
|
|
|
0
|
my $dir = ExtUtils::Builder::Util::native_to_unix_path($options{dir}); |
|
132
|
0
|
|
|
|
|
0
|
$dir =~ s{(?
|
|
133
|
|
|
|
|
|
|
return sub { |
|
134
|
0
|
|
|
0
|
|
0
|
my ($input) = @_; |
|
135
|
0
|
|
|
|
|
0
|
my $filename = ExtUtils::Builder::Util::native_to_unix_path($input); |
|
136
|
0
|
|
|
|
|
0
|
return substr($filename, 0, length $dir) eq $dir; |
|
137
|
0
|
|
|
|
|
0
|
}; |
|
138
|
|
|
|
|
|
|
} else { |
|
139
|
0
|
|
|
|
|
0
|
Carp::croak("Unknown pattern type"); |
|
140
|
|
|
|
|
|
|
} |
|
141
|
|
|
|
|
|
|
} |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
sub create_pattern { |
|
144
|
1
|
|
|
1
|
1
|
15
|
my ($self, %args) = @_; |
|
145
|
1
|
|
|
|
|
7
|
my $positive = $self->_make_pattern(%args); |
|
146
|
1
|
50
|
|
0
|
|
4
|
my $callback = $args{negate} ? sub { !$positive->($_[0]) } : $positive; |
|
|
0
|
|
|
|
|
0
|
|
|
147
|
1
|
|
|
|
|
9
|
return $self->create_filter(%args, condition => $callback); |
|
148
|
|
|
|
|
|
|
} |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub create_subst { |
|
151
|
1
|
|
|
1
|
1
|
33
|
my ($self, %args) = @_; |
|
152
|
|
|
|
|
|
|
my $set = ExtUtils::Builder::FileSet::Subst->new( |
|
153
|
|
|
|
|
|
|
subst => $args{subst}, |
|
154
|
1
|
|
|
|
|
5
|
callback => $self->_create_callback($args{add_to}), |
|
155
|
|
|
|
|
|
|
); |
|
156
|
1
|
|
50
|
|
|
5
|
my $on = $args{on} // 'all-files'; |
|
157
|
1
|
50
|
|
|
|
16
|
my @sources = ref($on) eq 'ARRAY' ? @{$on} : $on; |
|
|
0
|
|
|
|
|
0
|
|
|
158
|
1
|
|
|
|
|
4
|
for my $source (@sources) { |
|
159
|
1
|
50
|
|
|
|
6
|
my $object = $self->{filesets}{$source} or die "No such source $source"; |
|
160
|
1
|
|
|
|
|
7
|
$object->add_dependent($set); |
|
161
|
|
|
|
|
|
|
} |
|
162
|
1
|
|
33
|
|
|
8
|
my $name = $args{name} // 'subst-' . $counter++; |
|
163
|
1
|
|
|
|
|
11
|
$self->{filesets}{$name} = $set; |
|
164
|
1
|
|
|
|
|
5
|
return $name; |
|
165
|
|
|
|
|
|
|
} |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
sub add_seen { |
|
168
|
2
|
|
|
2
|
1
|
14
|
my ($self, $entry) = @_; |
|
169
|
2
|
|
|
|
|
10
|
$self->{filesets}{'all-files'}->add_input($entry); |
|
170
|
2
|
|
|
|
|
6
|
return; |
|
171
|
|
|
|
|
|
|
} |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub merge_plan { |
|
174
|
0
|
|
|
0
|
1
|
0
|
my ($self, $plan) = @_; |
|
175
|
0
|
|
|
|
|
0
|
$self->add_node($_) for $plan->nodes; |
|
176
|
0
|
|
|
|
|
0
|
return; |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
my $set_subname = eval { require Sub::Util; Sub::Util->VERSION('1.40'); \&Sub::Util::set_subname } // sub { $_[1] }; |
|
180
|
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
sub add_delegate { |
|
182
|
9
|
|
|
9
|
1
|
39
|
my ($self, $name, $sub) = @_; |
|
183
|
9
|
|
|
|
|
25
|
my $full_name = ref($self) . '::' . $name; |
|
184
|
5
|
|
|
5
|
|
75
|
no strict 'refs'; |
|
|
5
|
|
|
|
|
12
|
|
|
|
5
|
|
|
|
|
327
|
|
|
185
|
5
|
|
|
5
|
|
36
|
no warnings 'redefine'; |
|
|
5
|
|
|
|
|
10
|
|
|
|
5
|
|
|
|
|
1937
|
|
|
186
|
9
|
|
|
|
|
69
|
*{$full_name} = $set_subname->($full_name, $sub); |
|
|
9
|
|
|
|
|
46
|
|
|
187
|
9
|
|
|
|
|
26
|
return; |
|
188
|
|
|
|
|
|
|
} |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub load_extension { |
|
191
|
3
|
|
|
3
|
1
|
22
|
my ($self, $plannable, $version, %options) = @_; |
|
192
|
3
|
|
|
|
|
20
|
ExtUtils::Builder::Util::require_module($plannable); |
|
193
|
3
|
50
|
|
|
|
16
|
$plannable->VERSION($version) if $version; |
|
194
|
3
|
|
|
|
|
24
|
return $plannable->add_methods($self, %options); |
|
195
|
|
|
|
|
|
|
} |
|
196
|
|
|
|
|
|
|
*load_module = \&load_extension; |
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
sub materialize { |
|
199
|
2
|
|
|
2
|
1
|
17
|
my $self = shift; |
|
200
|
2
|
|
|
|
|
4
|
my %nodes = %{ $self->{nodes} }; |
|
|
2
|
|
|
|
|
10
|
|
|
201
|
2
|
|
|
|
|
21
|
return ExtUtils::Builder::Plan->new(nodes => \%nodes); |
|
202
|
|
|
|
|
|
|
} |
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
my %dsl_commands = ( |
|
205
|
|
|
|
|
|
|
command => \&ExtUtils::Builder::Util::command, |
|
206
|
|
|
|
|
|
|
code => \&ExtUtils::Builder::Util::code, |
|
207
|
|
|
|
|
|
|
function => \&ExtUtils::Builder::Util::function, |
|
208
|
|
|
|
|
|
|
); |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
sub run_dsl { |
|
211
|
1
|
|
|
1
|
1
|
11
|
my ($self, $filename) = @_; |
|
212
|
|
|
|
|
|
|
|
|
213
|
1
|
|
|
|
|
3
|
my $dsl_module = ref($self) . '::DSL'; |
|
214
|
|
|
|
|
|
|
|
|
215
|
1
|
50
|
|
|
|
3
|
if (not defined &{ "$dsl_module\::AUTOLOAD" }) { |
|
|
1
|
|
|
|
|
7
|
|
|
216
|
5
|
|
|
5
|
|
42
|
no strict 'refs'; |
|
|
5
|
|
|
|
|
11
|
|
|
|
5
|
|
|
|
|
2436
|
|
|
217
|
1
|
|
|
|
|
9
|
*{ "$dsl_module\::AUTOLOAD" } = sub { |
|
218
|
3
|
|
|
3
|
|
305
|
my $name = our $AUTOLOAD; |
|
219
|
3
|
|
|
|
|
21
|
$name =~ s/.*:://; |
|
220
|
3
|
50
|
|
|
|
29
|
if (my $method = $self->can($name)) { |
|
221
|
|
|
|
|
|
|
my $delegate = $set_subname->($name, sub { |
|
222
|
5
|
|
|
5
|
1
|
19
|
$self->$method(@_); |
|
|
|
|
|
5
|
1
|
|
|
|
223
|
3
|
|
|
|
|
75
|
}); |
|
224
|
3
|
|
|
|
|
7
|
*{ "$dsl_module\::$name" } = $delegate; |
|
|
3
|
|
|
|
|
20
|
|
|
225
|
3
|
|
|
|
|
14
|
goto &$delegate; |
|
226
|
|
|
|
|
|
|
} |
|
227
|
|
|
|
|
|
|
else { |
|
228
|
0
|
|
|
|
|
0
|
Carp::croak("No such subroutine $name"); |
|
229
|
|
|
|
|
|
|
} |
|
230
|
1
|
|
|
|
|
7
|
}; |
|
231
|
|
|
|
|
|
|
|
|
232
|
1
|
|
|
|
|
5
|
for my $name (keys %dsl_commands) { |
|
233
|
3
|
50
|
|
|
|
25
|
*{ "$dsl_module\::$name" } = $dsl_commands{$name} if not $dsl_module->can($name); |
|
|
3
|
|
|
|
|
12
|
|
|
234
|
|
|
|
|
|
|
} |
|
235
|
|
|
|
|
|
|
} |
|
236
|
|
|
|
|
|
|
|
|
237
|
1
|
|
|
|
|
58
|
my $path = File::Spec->rel2abs($filename); |
|
238
|
1
|
50
|
0
|
|
|
173
|
eval "package $dsl_module; my \$ret = do \$path; die \$@ if \$@; defined \$ret || !\$!" or die $@ // Carp::shortmess("Can't run $path: $!"); |
|
239
|
1
|
|
|
|
|
9
|
return; |
|
240
|
|
|
|
|
|
|
} |
|
241
|
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
1; |
|
243
|
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
# ABSTRACT: An ExtUtils::Builder Plan builder |
|
245
|
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
__END__ |