File Coverage

blib/lib/Module/Data.pm
Criterion Covered Total %
statement 57 61 93.4
branch 10 12 83.3
condition n/a
subroutine 16 17 94.1
pod 3 3 100.0
total 86 93 92.4


line stmt bran cond sub pod time code
1 4     4   28779 use 5.006; # our
  4         10  
2 4     4   16 use strict;
  4         5  
  4         93  
3 4     4   24 use warnings;
  4         7  
  4         267  
4              
5             package Module::Data;
6              
7             our $VERSION = '0.013';
8              
9             # ABSTRACT: Introspect context information about modules in @INC
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13 4     4   2034 use Moo qw( around has );
  4         48322  
  4         30  
14 4     4   7894 use Sub::Quote qw( quote_sub );
  4         19541  
  4         3387  
15              
16             around BUILDARGS => sub {
17             my ( $orig, $class, @args ) = @_;
18              
19             unshift @args, 'package' if @args % 2 == 1;
20              
21             return $class->$orig(@args);
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             has package => (
62             required => 1,
63             is => 'ro',
64             ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars, ValuesAndExpressions::RestrictLongStrings)
65             isa => quote_sub q{}
66             . q{die "given undef for 'package' , expects a Str/module name" if not defined $_[0];}
67             . q{die " ( 'package' => $_[0] ) is not a Str/module name, got a ref : " . ref $_[0] if ref $_[0];}
68             . q{require Module::Runtime;}
69             . q{Module::Runtime::check_module_name( $_[0] );},
70             );
71              
72             has _notional_name => (
73             is => 'ro',
74             lazy => 1,
75             ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
76             default => quote_sub q{} . q{require Module::Runtime;} . q{return Module::Runtime::module_notional_filename( $_[0]->package );},
77             );
78              
79              
80              
81              
82              
83              
84              
85              
86              
87              
88              
89             sub loaded {
90 15     15 1 16 my ($self) = @_;
91 15         279 return exists $INC{ $self->_notional_name };
92             }
93              
94              
95              
96              
97              
98              
99              
100              
101              
102              
103              
104              
105              
106              
107              
108             ## no critic ( ProhibitBuiltinHomonyms )
109             sub require {
110 4     4 1 4 my ($self) = @_;
111 4 50       6 return $self->package if $self->loaded;
112              
113 4         91 require Module::Runtime;
114 4         12 Module::Runtime::require_module( $self->package );
115 4         1732 return $self->package;
116             }
117              
118             sub _find_module_perl {
119 0     0   0 my ($self) = @_;
120 0         0 $self->require;
121 0         0 return $INC{ $self->_notional_name };
122             }
123              
124             sub _find_module_emulate {
125 4     4   3 my ($self) = @_;
126 4         18 require Path::ScanINC;
127 4         48 Path::ScanINC->VERSION('0.011');
128 4         20 return Path::ScanINC->new()->first_file( $self->_notional_name );
129             }
130              
131             sub _find_module_optimistic {
132 5     5   5 my ($self) = @_;
133 5 100       11 return $INC{ $self->_notional_name } if $self->loaded;
134 4         115 return $self->_find_module_emulate;
135             }
136              
137             ## use critic
138              
139              
140              
141              
142              
143              
144              
145              
146              
147              
148              
149              
150              
151              
152              
153             has path => (
154             is => 'ro',
155             lazy => 1,
156             init_arg => undef,
157             builder => '_build_path',
158             );
159              
160             sub _build_path {
161 5     5   2678 my ( $self, ) = @_;
162 5         11 my $value = $self->_find_module_optimistic;
163 5 50       1182 return if not defined $value;
164 5         794 require Path::Tiny;
165 5         8607 return Path::Tiny::path($value)->absolute;
166             }
167              
168              
169              
170              
171              
172              
173              
174              
175              
176              
177              
178              
179              
180              
181              
182              
183              
184             has root => (
185             is => 'ro',
186             lazy => 1,
187             init_arg => undef,
188             builder => '_build_root',
189             );
190              
191             sub _build_root {
192 5     5   3488 my ($path) = $_[0]->path;
193              
194             # Parent ne Self is the only cross-platform way
195             # I can think of that will stop at the top of a tree
196             # as / is not applicable on windows.
197 5         110 while ( $path->parent->absolute ne $path->absolute ) {
198 15 100       843 if ( not $path->is_dir ) {
199 5         118 $path = $path->parent;
200 5         117 next;
201             }
202 10 100       326 if ( $path->child( $_[0]->_notional_name )->absolute eq $_[0]->path->absolute ) {
203 5         353 return $path->absolute;
204             }
205 5         384 $path = $path->parent;
206             }
207 0         0 return;
208              
209             }
210              
211              
212              
213              
214              
215              
216              
217              
218              
219              
220              
221              
222              
223              
224              
225              
226              
227              
228              
229              
230              
231             sub _version_perl {
232 4     4   2480 my ($self) = @_;
233 4         10 $self->require;
234              
235             # has to load the code into memory to work
236 4         61 return $self->package->VERSION;
237             }
238              
239             sub _version_emulate {
240 4     4   5 my ($self) = @_;
241 4         52 my $path = $self->path;
242 4         47 require Module::Metadata;
243 4         20 my $i = Module::Metadata->new_from_file( $path, collect_pod => 0 );
244 4         2355 return $i->version( $self->package );
245             }
246              
247             sub _version_optimistic {
248 6     6   9 my ($self) = @_;
249 6 100       12 return $self->package->VERSION if $self->loaded;
250 4         82 return $self->_version_emulate;
251             }
252              
253             sub version {
254 6     6 1 2585 my ( $self, ) = @_;
255 6         14 return $self->_version_optimistic;
256             }
257              
258              
259              
260              
261              
262              
263              
264              
265              
266 4     4   50 no Moo;
  4         7  
  4         35  
267              
268             1;
269              
270             __END__