File Coverage

blib/lib/Path/FindDev/Object.pm
Criterion Covered Total %
statement 46 77 59.7
branch 12 26 46.1
condition 1 3 33.3
subroutine 10 12 83.3
pod 4 4 100.0
total 73 122 59.8


line stmt bran cond sub pod time code
1 2     2   439 use 5.006; # our
  2         4  
2 2     2   7 use strict;
  2         2  
  2         40  
3 2     2   15 use warnings;
  2         2  
  2         340  
4              
5             package Path::FindDev::Object;
6              
7             our $VERSION = 'v0.5.3';
8              
9             # ABSTRACT: Object oriented guts to FindDev
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13             our $ENV_KEY_DEBUG = 'PATH_FINDDEV_DEBUG';
14             our $DEBUG = ( exists $ENV{$ENV_KEY_DEBUG} ? $ENV{$ENV_KEY_DEBUG} : undef );
15              
16              
17              
18              
19              
20              
21              
22              
23              
24              
25              
26              
27              
28             use Class::Tiny 0.010 'set', 'uplevel_max', {
29             nest_retry => sub {
30 1         13 return 0;
31             },
32             isdev => sub {
33 1         449 require Path::IsDev::Object;
34 1 50       1773 return Path::IsDev::Object->new( ( $_[0]->has_set ? ( set => $_[0]->set ) : () ) );
35             },
36 2     2   921 };
  2         4703  
  2         15  
37              
38              
39              
40              
41              
42              
43              
44              
45              
46             ## no critic (RequireArgUnpacking)
47              
48              
49              
50              
51              
52              
53              
54 1     1 1 11 sub has_set { return exists $_[0]->{set} }
55              
56              
57              
58              
59              
60              
61              
62              
63              
64              
65              
66              
67              
68              
69              
70 1     1 1 4 sub has_uplevel_max { return exists $_[0]->{uplevel_max} }
71              
72              
73              
74              
75              
76              
77              
78              
79              
80              
81              
82              
83              
84              
85              
86              
87              
88              
89             my $instances = {};
90             my $instance_id = 0;
91              
92              
93              
94              
95              
96              
97              
98              
99              
100              
101              
102              
103              
104              
105             sub _instance_id {
106 0     0   0 my ($self) = @_;
107 0         0 require Scalar::Util;
108 0         0 my $addr = Scalar::Util::refaddr($self);
109 0 0       0 return $instances->{$addr} if exists $instances->{$addr};
110 0         0 $instances->{$addr} = sprintf '%x', $instance_id++;
111 0         0 return $instances->{$addr};
112             }
113              
114              
115              
116              
117              
118              
119              
120              
121              
122              
123             sub BUILD {
124 1     1 1 65 my ($self) = @_;
125 1 50       5 return $self unless $DEBUG;
126 0         0 $self->_debug('{');
127 0 0       0 $self->_debug( ' set => ' . $self->set ) if $self->has_set;
128 0 0       0 $self->_debug( ' uplevel_max => ' . $self->uplevel_max ) if $self->uplevel_max;
129 0         0 $self->_debug( ' nest_retry => ' . $self->nest_retry );
130 0         0 $self->_debug( ' isdev => ' . $self->isdev );
131 0         0 $self->_debug('}');
132 0         0 return $self;
133             }
134              
135              
136              
137              
138              
139              
140              
141              
142              
143              
144              
145              
146              
147             sub _debug {
148 3     3   40 my ( $self, $message ) = @_;
149 3 50       11 return unless $DEBUG;
150 0         0 my $id = $self->_instance_id;
151 0         0 return *STDERR->printf( qq{[Path::FindDev=%s] %s\n}, $id, $message );
152             }
153              
154              
155              
156              
157              
158              
159              
160              
161              
162             sub _error {
163 0     0   0 my ( $self, $message ) = @_;
164 0         0 my $id = $self->_instance_id;
165 0         0 my $f_message = sprintf qq{[Path::FindDev=%s] %s\n}, $id, $message;
166 0         0 require Carp;
167 0         0 Carp::croak($f_message);
168             }
169              
170              
171              
172              
173              
174              
175              
176              
177              
178              
179              
180              
181              
182              
183              
184              
185             sub _step {
186 2     2   3 my ( $self, $search_root, $dev_levels, $uplevels ) = @_;
187              
188 2 100       38 if ( $self->isdev->matches($search_root) ) {
189 1         2510 $self->_debug( 'Found dev dir' . $search_root );
190 1         2 ${$dev_levels}++;
  1         2  
191 1 50       2 return { type => 'found', path => $search_root } if ${$dev_levels} >= $self->nest_retry;
  1         19  
192 0         0 $self->_debug( sprintf 'Ignoring found dev dir due to dev_levels(%s) < nest_retry(%s)', ${$dev_levels}, $self->nest_retry );
  0         0  
193             }
194 1 50       40927 if ( $search_root->is_rootdir ) {
195 0         0 $self->_debug('OS Root hit ( ->is_rootdir )');
196 0         0 return { type => 'stop' };
197             }
198 1 50 33     11 if ( $self->has_uplevel_max and ${$uplevels} > $self->uplevel_max ) {
  0         0  
199 0         0 $self->_debug( 'Stopping search due to uplevels(%s) >= uplevel_max(%s)', ${$uplevels}, $self->uplevel_max );
  0         0  
200 0         0 return { type => 'stop' };
201             }
202              
203 1         4 return { type => 'next' };
204             }
205              
206              
207              
208              
209              
210              
211              
212              
213              
214             sub find_dev {
215 1     1 1 1 my ( $self, $path ) = @_;
216 1         4 require Path::Tiny;
217 1         4 my $search_root = Path::Tiny::path($path)->absolute->realpath;
218 1         184 $self->_debug( 'Finding dev for ' . $path );
219 1         1 my $dev_levels = 0;
220 1         1 my $uplevels = 0 - 1;
221             FLOW: {
222 1         3 $uplevels++;
  2         2  
223 2         6 my $result = $self->_step( $search_root, \$dev_levels, \$uplevels );
224 2 100       6 if ( 'next' eq $result->{type} ) {
225 1         6 $self->_debug( 'Trying ../ : ' . $search_root->parent );
226 1         3 $search_root = $search_root->parent;
227 1         21 redo FLOW;
228             }
229 1 50       4 if ( 'stop' eq $result->{type} ) {
230 0         0 return;
231             }
232 1 50       3 if ( 'found' eq $result->{type} ) {
233 1         4 return $result->{path};
234             }
235 0           $self->_error( 'Unexpected end of flow control with _step response type' . $result->{type} );
236             }
237 0           return;
238             }
239             1;
240              
241             __END__