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 9     9   47 use strict;
  9         13  
  9         328  
3 9     9   38 use warnings;
  6         9  
  6         151  
4 6     6   2335 use Module::CPANfile::Prereqs;
  6         15  
  6         173  
5 6     6   31 use Carp ();
  6         9  
  6         679  
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 12     12 0 23 my($class, $file) = @_;
19 12         95 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 12     12 0 28 my $self = shift;
31 12         23 my $pkg = caller;
32              
33 12         31 for my $binding (@bindings) {
34 6     6   31 no strict 'refs';
  6         11  
  6         5541  
35 144     40   340 *{"$pkg\::$binding"} = sub { $self->$binding(@_) };
  144         3520  
  40         241  
36             }
37             }
38              
39             sub parse {
40 12     12 0 17 my($self, $code) = @_;
41              
42 12         12 my $err;
43             {
44 12         16 local $@;
  12         18  
45 12         19 $file_id++;
46 12         107 $self->_evaluate(<<EVAL);
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 12         65 $err = $@;
55             }
56              
57 12 100       37 if ($err) { die "Parsing $self->{file} failed: $err" };
  1         10  
58              
59 11         44 return 1;
60             }
61              
62             sub _evaluate {
63 12     12   20 my $_environment = $_[0];
64 6     6   39 eval $_[1];
  6     6   11  
  6     3   348  
  6     3   29  
  3         25  
  3         6  
  3         158  
  3         14  
  12         979  
65             }
66              
67 40     40 0 132 sub prereqs { $_[0]->{prereqs} }
68              
69 11     11 0 50 sub mirrors { $_[0]->{mirrors} }
70              
71             # DSL goes from here
72              
73             sub on {
74 13     13 0 19 my($self, $phase, $code) = @_;
75 13         31 local $self->{phase} = $phase;
76 13         31 $code->();
77             }
78              
79             sub feature {
80 2     2 0 4 my($self, $identifier, $description, $code) = @_;
81              
82             # shortcut: feature identifier => sub { ... }
83 2 100 66     14 if (@_ == 3 && ref($description) eq 'CODE') {
84 1         2 $code = $description;
85 1         1 $description = $identifier;
86             }
87              
88 2 50 33     15 unless (ref $description eq '' && ref $code eq 'CODE') {
89 0         0 Carp::croak("Usage: feature 'identifier', 'Description' => sub { ... }");
90             }
91              
92 2         6 local $self->{feature} = $identifier;
93 2         7 $self->prereqs->add_feature($identifier, $description);
94              
95 2         7 $code->();
96             }
97              
98 0     0 0 0 sub osname { die "TODO" }
99              
100             sub mirror {
101 2     2 0 4 my($self, $url) = @_;
102 2         2 push @{$self->{mirrors}}, $url;
  2         7  
103             }
104              
105             sub requirement_for {
106 27     27 0 45 my($self, $module, @args) = @_;
107              
108 27         29 my $requirement = 0;
109 27 100       83 $requirement = shift @args if @args % 2;
110              
111 27         129 return Module::CPANfile::Requirement->new(
112             name => $module,
113             version => $requirement,
114             @args,
115             );
116             }
117              
118             sub requires {
119 25     25 0 32 my $self = shift;
120 25         61 $self->add_prereq(requires => @_);
121             }
122              
123             sub recommends {
124 1     1 0 2 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 2 my $self = shift;
135 1         4 $self->add_prereq(conflicts => @_);
136             }
137              
138             sub add_prereq {
139 27     27 0 53 my($self, $type, $module, @args) = @_;
140              
141             $self->prereqs->add_prereq(
142             feature => $self->{feature},
143             phase => $self->{phase},
144 27         56 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 3 my($self, @args) = @_;
154 1     1   8 $self->on(configure => sub { $self->requires(@args) });
  1         3  
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 5 my($self, @args) = @_;
164 2     2   10 $self->on(test => sub { $self->requires(@args) });
  2         7  
165             }
166              
167             sub author_requires {
168 1     1 0 2 my($self, @args) = @_;
169 1     1   5 $self->on(develop => sub { $self->requires(@args) });
  1         2  
170             }
171              
172             1;
173