line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
12
|
|
|
12
|
|
89286
|
use 5.008; # utf8 |
|
12
|
|
|
|
|
39
|
|
|
12
|
|
|
|
|
508
|
|
2
|
12
|
|
|
12
|
|
65
|
use strict; |
|
12
|
|
|
|
|
20
|
|
|
12
|
|
|
|
|
409
|
|
3
|
12
|
|
|
12
|
|
59
|
use warnings; |
|
12
|
|
|
|
|
20
|
|
|
12
|
|
|
|
|
371
|
|
4
|
12
|
|
|
12
|
|
12388
|
use utf8; |
|
12
|
|
|
|
|
110
|
|
|
12
|
|
|
|
|
86
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
package Path::IsDev; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '1.001002'; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# ABSTRACT: Determine if a given Path resembles a development source tree |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
|
25
|
12
|
|
|
12
|
|
13994
|
use Sub::Exporter -setup => { exports => [ is_dev => \&_build_is_dev, ], }; |
|
12
|
|
|
|
|
159796
|
|
|
12
|
|
|
|
|
158
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
our $ENV_KEY_DEBUG = 'PATH_ISDEV_DEBUG'; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
our $DEBUG = ( exists $ENV{$ENV_KEY_DEBUG} ? $ENV{$ENV_KEY_DEBUG} : undef ); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
sub debug { |
42
|
0
|
0
|
|
0
|
1
|
0
|
return unless $DEBUG; |
43
|
0
|
|
|
|
|
0
|
return *STDERR->printf( qq{[Path::IsDev] %s\n}, shift ); |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub _build_is_dev { |
47
|
21
|
|
|
21
|
|
12128
|
my ( undef, undef, $arg ) = @_; |
48
|
|
|
|
|
|
|
|
49
|
21
|
|
|
|
|
33
|
my $isdev_object; |
50
|
|
|
|
|
|
|
return sub { |
51
|
10
|
|
|
10
|
|
5917
|
my ($path) = @_; |
52
|
10
|
|
66
|
|
|
66
|
$isdev_object ||= do { |
53
|
9
|
|
|
|
|
10087
|
require Path::IsDev::Object; |
54
|
9
|
50
|
|
|
|
35
|
Path::IsDev::Object->new( %{ $arg || {} } ); |
|
9
|
|
|
|
|
136
|
|
55
|
|
|
|
|
|
|
}; |
56
|
10
|
|
|
|
|
160
|
return $isdev_object->matches($path); |
57
|
21
|
|
|
|
|
115
|
}; |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
*is_dev = _build_is_dev( 'Path::IsDev', 'is_dev', {} ); |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
1; |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
__END__ |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=pod |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=encoding UTF-8 |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=head1 NAME |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
Path::IsDev - Determine if a given Path resembles a development source tree |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=head1 VERSION |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
version 1.001002 |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=head1 SYNOPSIS |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
use Path::IsDev qw(is_dev); |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
if( is_dev('/some/path') ) { |
106
|
|
|
|
|
|
|
... |
107
|
|
|
|
|
|
|
} else { |
108
|
|
|
|
|
|
|
... |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=head1 DESCRIPTION |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
This module is more or less a bunch of heuristics for determining if a given path |
114
|
|
|
|
|
|
|
is a development tree root of some kind. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
This has many useful applications, notably ones that require behaviours for "installed" |
117
|
|
|
|
|
|
|
modules to be different to those that are still "in development" |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=head1 FUNCTIONS |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=head2 debug |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
Debug callback. |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
To enable debugging: |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
export PATH_ISDEV_DEBUG=1 |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=head2 C<is_dev> |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
Using an C<import>'ed C<is_dev>: |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
if( is_dev( $path ) ) { |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
Though the actual heuristics used will be based on how C<import> was called. |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
Additionally, you can call |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
Path::IsDev::is_dev |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
without C<import>ing anything, and it will behave exactly the same as if you'd imported |
144
|
|
|
|
|
|
|
it using |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
use Path::IsDev qw( is_dev ); |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
That is, no C<set> specification is applicable, so you'll only get the "default". |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=begin MetaPOD::JSON v1.1.0 |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
{ |
153
|
|
|
|
|
|
|
"namespace":"Path::IsDev", |
154
|
|
|
|
|
|
|
"interface":"exporter" |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=end MetaPOD::JSON |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=head1 UNDERSTANDING AND DEBUGGING THIS MODULE |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
Understanding how this module works, is critical to understand where you can use it, and the consequences of using it. |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
This module operates on a very simplistic level, and its easy for false-positives to occur. |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
There are two types of Heuristics, Postive/Confirming Heuristics, and Negative/Disconfirming Heuristics. |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
Positive Heuristics and Negative Heuristics are based solely on the presence of specific marker files in a directory, or special |
169
|
|
|
|
|
|
|
marker directories. |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
For instance, the files C<META.yml>, C<Makefile.PL>, and C<Build.PL> are all B<Positive Heuristic> markers, because their |
172
|
|
|
|
|
|
|
presence often indicates a "root" of a development tree. |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
And for instance, the directories C<t/>, C<xt/> and C<.git/> are also B<Positive Heuristic> markers, because these structures |
175
|
|
|
|
|
|
|
are common in C<perl> development trees, and uncommon in install trees. |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
However, these markers sometimes go wrong, for instance, consider you have a C<local::lib> or C<perlbrew> install in C<$HOME> |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
$HOME/ |
180
|
|
|
|
|
|
|
$HOME/lib/ |
181
|
|
|
|
|
|
|
$HOME/perl5/perls/perl-5.19.3/lib/site_perl/ |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
Etc. |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
Under normal circumstances, neither C<$HOME> nor those 3 paths are considered C<dev>. |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
However, all it takes to cause a false positive, is for somebody to install a C<t> or C<xt> directory, or a marker file in one of |
188
|
|
|
|
|
|
|
the above directories for C<path_isdev($dir)> to return true. |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
This may not be a problem, at least, until you use C<Path::FindDev> which combines C<Path::IsDev> with recursive up-level |
191
|
|
|
|
|
|
|
traversal. |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
$HOME/ |
194
|
|
|
|
|
|
|
$HOME/lib/ |
195
|
|
|
|
|
|
|
$HOME/perl5/perls/perl-5.19.3/lib/site_perl/ |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
find_dev('$HOME/perl5/perls/perl-5.19.3/lib/site_perl/') # returns false, because it is not inside a dev directory |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
mkdir $HOME/t |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
find_dev('$HOME/perl5/perls/perl-5.19.3/lib/site_perl/') # returns $HOME, because $HOME/t exists. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
And it is this kind of problem that usually catches people off guard. |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
PATH_ISDEV_DEBUG=1 \ |
206
|
|
|
|
|
|
|
perl -Ilib -MPath::FindDev=find_dev \ |
207
|
|
|
|
|
|
|
-E "say find_dev(q{/home/kent/perl5/perlbrew/perls/perl-5.19.3/lib/site_perl})" |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
... |
210
|
|
|
|
|
|
|
[Path::IsDev=0] + ::Tool::Dzil => 0 : dist.ini does not exist |
211
|
|
|
|
|
|
|
[Path::IsDev=0] + ::Tool::MakeMaker => 0 : Makefile.PL does not exist |
212
|
|
|
|
|
|
|
[Path::IsDev=0] + ::Tool::ModuleBuild => 0 : Build.PL does not exist |
213
|
|
|
|
|
|
|
[Path::IsDev=0] + ::META => 0 : META.json does not exist |
214
|
|
|
|
|
|
|
[Path::IsDev=0] + ::META => 1 : META.yml exists |
215
|
|
|
|
|
|
|
[Path::IsDev=0] + ::META => 1 : /home/kent/perl5/META.yml is a file |
216
|
|
|
|
|
|
|
[Path::IsDev=0] + ::META matched path /home/kent/perl5 |
217
|
|
|
|
|
|
|
/home/kent/perl5 |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
Whoops!. |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
[Path::IsDev=0] + ::META => 1 : META.yml exists |
222
|
|
|
|
|
|
|
[Path::IsDev=0] + ::META => 1 : /home/kent/perl5/META.yml is a file |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
No wonder! |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
rm /home/kent/perl5/META.yml |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
PATH_ISDEV_DEBUG=1 \ |
229
|
|
|
|
|
|
|
perl -Ilib -MPath::FindDev=find_dev \ |
230
|
|
|
|
|
|
|
-E "say find_dev(q{/home/kent/perl5/perlbrew/perls/perl-5.19.3/lib/site_perl})" |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
... |
233
|
|
|
|
|
|
|
[Path::IsDev=0] Matching /home/kent/perl5 |
234
|
|
|
|
|
|
|
... |
235
|
|
|
|
|
|
|
[Path::IsDev=0] + ::TestDir => 0 : xt does not exist |
236
|
|
|
|
|
|
|
[Path::IsDev=0] + ::TestDir => 1 : t exists |
237
|
|
|
|
|
|
|
[Path::IsDev=0] + ::TestDir => 1 : /home/kent/perl5/t is a dir |
238
|
|
|
|
|
|
|
[Path::IsDev=0] + ::TestDir matched path /home/kent/perl5 |
239
|
|
|
|
|
|
|
/home/kent/perl5 |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
Double whoops! |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
[Path::IsDev=0] + ::TestDir => 1 : t exists |
244
|
|
|
|
|
|
|
[Path::IsDev=0] + ::TestDir => 1 : /home/kent/perl5/t is a dir |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
And you could keep doing that until you rule out all the bad heuristics in your tree. |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
Or, you could use a negative heuristic. |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
touch /home/kent/perl5/.path_isdev_ignore |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
PATH_ISDEV_DEBUG=1 \ |
253
|
|
|
|
|
|
|
perl -Ilib -MPath::FindDev=find_dev \ |
254
|
|
|
|
|
|
|
-E "say find_dev(q{/home/kent/perl5/perlbrew/perls/perl-5.19.3/lib/site_perl})" |
255
|
|
|
|
|
|
|
... |
256
|
|
|
|
|
|
|
[Path::IsDev=0] Matching /home/kent/perl5 |
257
|
|
|
|
|
|
|
[Path::IsDev=0] - ::IsDev::IgnoreFile => 1 : .path_isdev_ignore exists |
258
|
|
|
|
|
|
|
[Path::IsDev=0] - ::IsDev::IgnoreFile => 1 : /home/kent/perl5/.path_isdev_ignore is a file |
259
|
|
|
|
|
|
|
[Path::IsDev=0] - ::IsDev::IgnoreFile excludes path /home/kent/perl5 |
260
|
|
|
|
|
|
|
[Path::IsDev=0] no match found |
261
|
|
|
|
|
|
|
... |
262
|
|
|
|
|
|
|
[Path::IsDev=0] Matching / |
263
|
|
|
|
|
|
|
... |
264
|
|
|
|
|
|
|
[Path::IsDev=0] no match found |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
Success! |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
[Path::IsDev=0] - ::IsDev::IgnoreFile => 1 : .path_isdev_ignore exists |
269
|
|
|
|
|
|
|
[Path::IsDev=0] - ::IsDev::IgnoreFile => 1 : /home/kent/perl5/.path_isdev_ignore is a file |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
=head1 HEURISTICS |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
=head2 Negative Heuristics bundled with this distribution |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
Just remember, a B<Negative> Heuristic B<excludes the path it is associated with> |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
=over 4 |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
=item * L<< C<IsDev::IgnoreFile>|Path::IsDev::NegativeHeuristic::IsDev::IgnoreFile >> - C<.path_isdev_ignore> |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
=back |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
=head2 Positive Heuristics bundled with this distribution |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=over 4 |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=item * L<< C<Changelog>|Path::IsDev::Heuristic::Changelog >> - Files matching C<Changes>, C<Changelog>, and similar, case |
288
|
|
|
|
|
|
|
insensitive, extensions optional. |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
=item * L<< C<DevDirMarker>|Path::IsDev::Heuristic::DevDirMarker >> - explicit C<.devdir> file to indicate a project root. |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=item * L<< C<META>|Path::IsDev::Heuristic::META >> - C<META.yml>/C<META.json> |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=item * L<< C<MYMETA>|Path::IsDev::Heuristic::MYMETA >> - C<MYMETA.yml>/C<MYMETA.json> |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=item * L<< C<Makefile>|Path::IsDev::Heuristic::Makefile >> - Any C<Makefile> format documented supported by GNU Make |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
=item * L<< C<TestDir>|Path::IsDev::Heuristic::TestDir >> - A directory called either C<t/> or C<xt/> |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=item * L<< C<Tool::DZil>|Path::IsDev::Heuristic::Tool::DZil >> - A C<dist.ini> file |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=item * L<< C<Tool::MakeMaker>|Path::IsDev::Heuristic::Tool::MakeMaker >> - A C<Makefile.PL> file |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
=item * L<< C<Tool::ModuleBuild>|Path::IsDev::Heuristic::Tool::ModuleBuild >> - A C<Build.PL> file |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=item * L<< C<VCS::Git>|Path::IsDev::Heuristic::VCS::Git >> - A C<.git> directory |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
=back |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=head1 HEURISTIC SETS |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=head2 Heuristic Sets Bundled with this distribution |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=over 4 |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
=item * L<< C<Basic>|Path::IsDev::HeuristicSet::Basic >> - The basic heuristic set that contains most, if not all heuristics. |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=back |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=head1 ADVANCED USAGE |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=head2 Custom Sets |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
C<Path::IsDev> has a system of "sets" of Heuristics, in order to allow for pluggable |
325
|
|
|
|
|
|
|
and flexible heuristic types. |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
Though, for the vast majority of cases, this is not required. |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
use Path::IsDev is_dev => { set => 'Basic' }; |
330
|
|
|
|
|
|
|
use Path::IsDev is_dev => { set => 'SomeOtherSet' , -as => 'is_dev_other' }; |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=head2 Overriding the default set |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
If for whatever reason the C<Basic> set is insufficient, or if it false positives on your system for some reason, |
335
|
|
|
|
|
|
|
the "default" set can be overridden. |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
export PATH_ISDEV_DEFAULT_SET="SomeOtherSet" |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
... |
340
|
|
|
|
|
|
|
use Path::IsDev qw( is_dev ); |
341
|
|
|
|
|
|
|
is_dev('/some/path') # uses SomeOtherSet |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
Though this will only take priority in the event the set is not specified during C<import> |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
If this poses a security concern for the user, then this security hole can be eliminated by declaring the set you want in code: |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
export PATH_ISDEV_DEFAULT_SET="SomeOtherSet" |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
... |
350
|
|
|
|
|
|
|
use Path::IsDev is_dev => { set => 'Basic' }; |
351
|
|
|
|
|
|
|
is_dev('/some/path') # uses Basic, regardless of ENV |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
=head1 SECURITY |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
Its conceivable, than an evil user could construct an evil set, containing arbitrary and vulnerable code, and possibly stash that |
356
|
|
|
|
|
|
|
evil set in a poorly secured privileged users @INC |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
And if they managed to achieve that, if they could poison the privileged users %ENV, they could trick the privileged user into |
359
|
|
|
|
|
|
|
executing arbitrary code. |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
Though granted, if you can do either of those 2 things, you're probably security vulnerable anyway, and granted, if you could do |
362
|
|
|
|
|
|
|
either of those 2 things you could do much more evil things by the following: |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
export PERL5OPT="-MEvil::Module" |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
So with that in understanding, saying this modules default utility is "insecure" is mostly a bogus argument. |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
And to that effect, this module does nothing to "lock down" that mechanism, and this module encourages you |
369
|
|
|
|
|
|
|
to B<NOT> force a set, unless you B<NEED> to, and strongly suggests that forcing a set for the purpose of security will achieve |
370
|
|
|
|
|
|
|
no real improvement in security, while simultaneously reducing utility. |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=head1 AUTHOR |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
Kent Fredric <kentfredric@gmail.com> |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
This software is copyright (c) 2014 by Kent Fredric <kentfredric@gmail.com>. |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
381
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=cut |