File Coverage

blib/lib/Dir/Which.pm
Criterion Covered Total %
statement 21 58 36.2
branch 0 30 0.0
condition n/a
subroutine 7 10 70.0
pod 1 1 100.0
total 29 99 29.2


line stmt bran cond sub pod time code
1             package Dir::Which ;
2              
3             =begin comment
4              
5             ======================
6              
7             Jacquelin Charbonnel - CNRS/LAREMA
8            
9             $Id: Which.pm 133 2007-04-04 07:35:27Z jaclin $
10            
11             ----
12            
13             Search for entries in a list of directories
14              
15             ----
16             $LastChangedDate: 2007-04-04 09:35:27 +0200 (Wed, 04 Apr 2007) $
17             $LastChangedRevision: 133 $
18             $LastChangedBy: jaclin $
19             $URL: https://svn.math.cnrs.fr/jaclin/src/lib/Dir-Which/Which.pm $
20            
21             ======================
22              
23             =end comment
24              
25             =head1 NAME
26              
27             Dir::Which - Search for directory entries in a list of directories.
28              
29             =head1 SYNOPSIS
30              
31             use Dir::Which qw/ which /;
32              
33             @entries = which(
34             -entry => "myprog.conf",
35             -env => "myprog_path",
36             -defaultpath => ".:".$FindBin::Bin.":/etc:/usr/local/etc") ;
37              
38             =head1 DESCRIPTION
39              
40             This module searches directory entries (files, dirs, links, named pipes...) in a list of directories specified as a path-like string.
41              
42             The path string can be specified in an environment variable or as an argument.
43              
44             =cut
45              
46 1     1   23237 use 5.006;
  1         5  
  1         42  
47 1     1   7 use Carp;
  1         3  
  1         81  
48 1     1   5 use warnings;
  1         7  
  1         33  
49 1     1   6 use strict;
  1         1  
  1         53  
50              
51 1     1   6 use base qw/ Exporter /;
  1         2  
  1         114  
52 1     1   6 use vars qw/ $VERSION @EXPORT_OK /;
  1         2  
  1         637  
53              
54 1     1   8 use File::Spec ;
  1         2  
  1         629  
55              
56             $VERSION = "0.3" ;
57              
58             @EXPORT_OK = qw( which );
59              
60             =head1 EXPORT
61              
62             =head2 which
63              
64             =head1 FUNCTION
65              
66             =head2 which
67              
68             This fonction takes named arguments :
69              
70             =over 8
71              
72             =item -entry (mandatory)
73              
74             The name of the searched entry.
75              
76             =item -env (optional)
77              
78             The name of a environment variable supposed to be a path-like string, and which be used to search the specified entry.
79             If one or more entries are found in this path, the search ends and returns these values.
80              
81             =item -defaultpath (optional)
82              
83             The path used to search the specified entry, if C<-env> argument is missing,
84             or if this environment variable doesn't exist, or if no entry have been found in it.
85              
86             =back
87              
88             =head1 RETURN VALUE
89              
90             In scalar context, the first match is returned according to the order of the directories
91             listed in the path string, or undef if no match can be found.
92              
93             In list context, all matches are returned in the order corresponding to the directories
94             listed in the path string (and so an empty list if no match is found).
95              
96             =head1 EXAMPLES
97              
98             use Dir::Which qw/ which /;
99              
100             $file = which(
101             -entry => "myprog.conf",
102             -defaultpath => "/etc:/usr/local/etc"
103             ) ;
104              
105             Searches the absolute name of C successivement in the directories
106             C and C. Returns the first entry found.
107              
108             use Dir::Which qw/ which /;
109             use FindBin qw($Bin) ;
110              
111             @entries = which(
112             -entry => "myprog.d",
113             -defaultpath => ".:".$FindBin::Bin.":/etc:/usr/local/etc"
114             ) ;
115              
116             Returns the absolute names of C searched in the current directory, the directory which contains the program binary,
117             C and C.
118              
119             use Dir::Which qw/ which /;
120              
121             $file = which(
122             -entry => "myprog.conf",
123             -env => "myprog_path"
124             ) ;
125              
126             Searches the absolute name of C in the path stored in the environment variable C.
127             Returns the name of the first file found, or C if no entry found.
128              
129             use Dir::Which qw/ which /;
130             use FindBin qw($Bin) ;
131              
132             $file = which(
133             -entry => "myprog.conf",
134             -env => "myprog_path",
135             -defaultpath => ".:".$FindBin::Bin.":/etc:/usr/local/etc"
136             ) ;
137              
138             Searches the absolute name of C in the path stored in the environment variable C.
139             If no file has been found, searches successivement in the current directory, the directory which contains the program binary,
140             C and C. Returns the name of the first entry found, or C if no entry found.
141              
142              
143             =cut
144              
145             sub which {
146 0     0 1   my(%h) = @_ ;
147              
148 0 0         %h = map { /^-/ ? lc : $_ ;} %h ;
  0            
149            
150 0 0         my $file = $h{"-entry"} or croak "error in Dir::Which::which : argument '-entry' is missing" ;
151              
152 0           my @matches = () ;
153 0 0         if (exists($h{"-env"}))
154             {
155 0           my $env = $h{"-env"} ;
156 0 0         if (exists($ENV{$env}))
157             {
158 0           my @path = _split($env) ;
159 0           @matches = _search($file,@path) ;
160             }
161             }
162            
163 0 0         if (scalar(@matches)>0)
164             {
165 0 0         return wantarray ? @matches : $matches[0] ;
166             }
167              
168 0 0         if (exists($h{"-defaultpath"}))
169             {
170 0           $ENV{"defaultpath_$$"} = $h{"-defaultpath"} ;
171 0           my @path = _split("defaultpath_$$") ;
172 0           @matches = _search($file,@path) ;
173             }
174              
175 0 0         if (scalar(@matches)>0)
176             {
177 0 0         return wantarray ? @matches : $matches[0] ;
178             }
179 0 0         return wantarray ? () : undef ;
180             }
181              
182             sub _split
183             {
184 0     0     my ($path) = @_ ;
185            
186 0           eval { require Env::Path };
  0            
187 0 0         if ($@)
188             {
189             # no Env::Path so we just split on :
190 0           return split(/:/, $ENV{$path});
191             }
192             else
193             {
194 0           my $lpath = Env::Path->$path;
195 0           return $lpath->List;
196             }
197             }
198            
199             sub _search
200             {
201 0     0     my($file,@path) = @_ ;
202 0           my @matches ;
203            
204 0           for my $d (@path) {
205             # blank means current directory
206 0 0         $d = File::Spec->curdir unless $d;
207              
208             # Create the filename
209 0           my $testfile = File::Spec->catfile( $d, $file);
210              
211             # does the file exist?
212 0 0         next unless -e $testfile ;
213              
214             # File looks to be found store it
215 0           push(@matches, $testfile);
216              
217             # if we are in a scalar context we do not need to keep on looking
218 0 0         last unless wantarray();
219              
220             }
221              
222             # return the result
223 0 0         if (wantarray) {
224 0           return @matches;
225             } else {
226 0           return $matches[0];
227             }
228             }
229              
230             =head1 NOTES
231              
232             If C module is installed it will be used. This allows for
233             more portability than simply assuming colon-separated paths.
234              
235             =head1 SEE ALSO
236              
237             L, L, L, L.
238              
239             =head1 AUTHOR
240              
241             Jacquelin Charbonnel, C<< >>
242              
243             =head1 BUGS
244              
245             Please report any bugs or feature requests to
246             C, or through the web interface at
247             L.
248             I will be notified, and then you'll automatically be notified of progress on
249             your bug as I make changes.
250              
251             =head1 SUPPORT
252              
253             You can find documentation for this module with the perldoc command.
254              
255             perldoc Dir::Which
256              
257             You can also look for information at:
258              
259             =over 4
260              
261             =item * AnnoCPAN: Annotated CPAN documentation
262              
263             L
264              
265             =item * CPAN Ratings
266              
267             L
268              
269             =item * RT: CPAN's request tracker
270              
271             L
272              
273             =item * Search CPAN
274              
275             L
276              
277             =back
278              
279             =head1 ACKNOWLEDGEMENTS
280              
281             C is inspired by C written by Tim Jenness.
282             Thanks to Tim for allowing me to reuse his idea.
283              
284             =head1 COPYRIGHT & LICENSE
285              
286             Copyright Jacquelin Charbonnel Ejacquelin.charbonnel at math.cnrs.frE
287              
288             This software is governed by the CeCILL-C license under French law and
289             abiding by the rules of distribution of free software. You can use,
290             modify and/ or redistribute the software under the terms of the CeCILL-C
291             license as circulated by CEA, CNRS and INRIA at the following URL
292             "http://www.cecill.info".
293              
294             As a counterpart to the access to the source code and rights to copy,
295             modify and redistribute granted by the license, users are provided only
296             with a limited warranty and the software's author, the holder of the
297             economic rights, and the successive licensors have only limited
298             liability.
299              
300             In this respect, the user's attention is drawn to the risks associated
301             with loading, using, modifying and/or developing or reproducing the
302             software by the user in light of its specific status of free software,
303             that may mean that it is complicated to manipulate, and that also
304             therefore means that it is reserved for developers and experienced
305             professionals having in-depth computer knowledge. Users are therefore
306             encouraged to load and test the software's suitability as regards their
307             requirements in conditions enabling the security of their systems and/or
308             data to be ensured and, more generally, to use and operate it in the
309             same conditions as regards security.
310              
311             The fact that you are presently reading this means that you have had
312             knowledge of the CeCILL-C license and that you accept its terms.
313              
314             =cut
315