File Coverage

blib/lib/Module/CPANfile/Environment.pm
Criterion Covered Total %
statement 80 87 91.9
branch 7 8 87.5
condition 3 6 50.0
subroutine 30 34 88.2
pod 0 19 0.0
total 120 154 77.9


line stmt bran cond sub pod time code
1             package Module::CPANfile::Environment;
2 10     10   71 use strict;
  10         24  
  10         374  
3 10     10   51 use warnings;
  7         14  
  7         182  
4 7     7   2864 use Module::CPANfile::Prereqs;
  7         25  
  7         235  
5 7     7   54 use Carp ();
  7         18  
  7         826  
6              
7             my @bindings = qw(
8             on requires recommends suggests conflicts
9             feature
10             osname
11             mirror
12             configure_requires build_requires test_requires author_requires
13             );
14              
15             my $file_id = 1;
16              
17             sub new {
18 14     14 0 52 my($class, $file) = @_;
19 14         112 bless {
20             file => $file,
21             phase => 'runtime', # default phase
22             feature => undef,
23             features => {},
24             prereqs => Module::CPANfile::Prereqs->new,
25             mirrors => [],
26             }, $class;
27             }
28              
29             sub bind {
30 14     14 0 36 my $self = shift;
31 14         41 my $pkg = caller;
32              
33 14         47 for my $binding (@bindings) {
34 7     7   49 no strict 'refs';
  7         19  
  7         7184  
35 168     48   716 *{"$pkg\::$binding"} = sub { $self->$binding(@_) };
  168         5054  
  48         190  
36             }
37             }
38              
39             sub parse {
40 14     14 0 43 my($self, $code) = @_;
41              
42 14         28 my $err;
43             {
44 14         29 local $@;
  14         31  
45 14         27 $file_id++;
46 14         154 $self->_evaluate(<
47             package Module::CPANfile::Sandbox$file_id;
48             no warnings;
49             BEGIN { \$_environment->bind }
50              
51             # line 1 "$self->{file}"
52             $code;
53             EVAL
54 14         69 $err = $@;
55             }
56              
57 14 100       52 if ($err) { die "Parsing $self->{file} failed: $err" };
  1         13  
58              
59 13         66 return 1;
60             }
61              
62             sub _evaluate {
63 14     14   34 my $_environment = $_[0];
64 7     7   76 eval $_[1];
  7     7   32  
  7     4   494  
  7     4   46  
  4         33  
  4         14  
  4         218  
  4         30  
  14         1197  
65             }
66              
67 50     50 0 249 sub prereqs { $_[0]->{prereqs} }
68              
69 13     13 0 95 sub mirrors { $_[0]->{mirrors} }
70              
71             # DSL goes from here
72              
73             sub on {
74 13     13 0 35 my($self, $phase, $code) = @_;
75 13         46 local $self->{phase} = $phase;
76 13         37 $code->();
77             }
78              
79             sub feature {
80 2     2 0 8 my($self, $identifier, $description, $code) = @_;
81              
82             # shortcut: feature identifier => sub { ... }
83 2 100 66     15 if (@_ == 3 && ref($description) eq 'CODE') {
84 1         3 $code = $description;
85 1         3 $description = $identifier;
86             }
87              
88 2 50 33     16 unless (ref $description eq '' && ref $code eq 'CODE') {
89 0         0 Carp::croak("Usage: feature 'identifier', 'Description' => sub { ... }");
90             }
91              
92 2         7 local $self->{feature} = $identifier;
93 2         7 $self->prereqs->add_feature($identifier, $description);
94              
95 2         9 $code->();
96             }
97              
98 0     0 0 0 sub osname { die "TODO" }
99              
100             sub mirror {
101 2     2 0 5 my($self, $url) = @_;
102 2         3 push @{$self->{mirrors}}, $url;
  2         5  
103             }
104              
105             sub requirement_for {
106 35     35 0 107 my($self, $module, @args) = @_;
107              
108 35         64 my $requirement = 0;
109 35 100       121 $requirement = shift @args if @args % 2;
110              
111 35         224 return Module::CPANfile::Requirement->new(
112             name => $module,
113             version => $requirement,
114             @args,
115             );
116             }
117              
118             sub requires {
119 33     33 0 79 my $self = shift;
120 33         91 $self->add_prereq(requires => @_);
121             }
122              
123             sub recommends {
124 1     1 0 3 my $self = shift;
125 1         4 $self->add_prereq(recommends => @_);
126             }
127              
128             sub suggests {
129 0     0 0 0 my $self = shift;
130 0         0 $self->add_prereq(suggests => @_);
131             }
132              
133             sub conflicts {
134 1     1 0 3 my $self = shift;
135 1         6 $self->add_prereq(conflicts => @_);
136             }
137              
138             sub add_prereq {
139 35     35 0 104 my($self, $type, $module, @args) = @_;
140              
141             $self->prereqs->add(
142             feature => $self->{feature},
143             phase => $self->{phase},
144 35         95 type => $type,
145             module => $module,
146             requirement => $self->requirement_for($module, @args),
147             );
148             }
149              
150             # Module::Install compatible shortcuts
151              
152             sub configure_requires {
153 1     1 0 6 my($self, @args) = @_;
154 1     1   10 $self->on(configure => sub { $self->requires(@args) });
  1         6  
155             }
156              
157             sub build_requires {
158 0     0 0 0 my($self, @args) = @_;
159 0     0   0 $self->on(build => sub { $self->requires(@args) });
  0         0  
160             }
161              
162             sub test_requires {
163 2     2 0 10 my($self, @args) = @_;
164 2     2   19 $self->on(test => sub { $self->requires(@args) });
  2         14  
165             }
166              
167             sub author_requires {
168 1     1 0 5 my($self, @args) = @_;
169 1     1   22 $self->on(develop => sub { $self->requires(@args) });
  1         4  
170             }
171              
172             1;
173