File Coverage

inc/Devel/CheckOS.pm
Criterion Covered Total %
statement 74 207 35.7
branch 3 24 12.5
condition 0 5 0.0
subroutine 56 61 91.8
pod 7 7 100.0
total 140 304 46.0


line stmt bran cond sub pod time code
1             package #
2             Devel::CheckOS;
3              
4 1     1   19516 use strict;
  1         2  
  1         28  
5 1     1   4 use Exporter;
  1         1  
  1         39  
6              
7 1     1   4 use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
  1         2  
  1         220  
8              
9             $VERSION = '1.72';
10              
11             # localising prevents the warningness leaking out of this module
12             local $^W = 1; # use warnings is a 5.6-ism
13              
14             @ISA = qw(Exporter);
15             @EXPORT_OK = qw(os_is os_isnt die_if_os_is die_if_os_isnt die_unsupported list_platforms list_family_members);
16             %EXPORT_TAGS = (
17             all => \@EXPORT_OK,
18             booleans => [qw(os_is os_isnt die_unsupported)],
19             fatal => [qw(die_if_os_is die_if_os_isnt)]
20             );
21              
22             =head1 NAME
23              
24             Devel::CheckOS - check what OS we're running on
25              
26             =head1 DESCRIPTION
27              
28             A learned sage once wrote on IRC:
29              
30             $^O is stupid and ugly, it wears its pants as a hat
31              
32             Devel::CheckOS provides a more friendly interface to $^O, and also lets
33             you check for various OS "families" such as "Unix", which includes things
34             like Linux, Solaris, AIX etc.
35              
36             It spares perl the embarrassment of wearing its pants on its head by
37             covering them with a splendid Fedora.
38              
39             =head1 SYNOPSIS
40              
41             use Devel::CheckOS qw(os_is);
42             print "Hey, I know this, it's a Unix system\n" if(os_is('Unix'));
43              
44             print "You've got Linux 2.6\n" if(os_is('Linux::v2_6'));
45              
46             =head1 USING IT IN Makefile.PL or Build.PL
47              
48             If you want to use this from Makefile.PL or Build.PL, do
49             not simply copy the module into your distribution as this may cause
50             problems when PAUSE and search.cpan.org index the distro. Instead, use
51             the use-devel-assertos script.
52              
53             =head1 FUNCTIONS
54              
55             Devel::CheckOS implements the following functions, which load subsidiary
56             OS-specific modules on demand to do the real work. They can be exported
57             by listing their names after C<use Devel::CheckOS>. You can also export
58             groups of functions thus:
59              
60             use Devel::CheckOS qw(:booleans); # export the boolean functions
61             # and 'die_unsupported'
62            
63             use Devel::CheckOS qw(:fatal); # export those that die on no match
64              
65             use Devel::CheckOS qw(:all); # export everything
66              
67             =head2 Boolean functions
68              
69             =head3 os_is
70              
71             Takes a list of OS names. If the current platform matches any of them,
72             it returns true, otherwise it returns false. The names can be a mixture
73             of OSes and OS families, eg ...
74              
75             os_is(qw(Unix VMS)); # Unix is a family, VMS is an OS
76              
77             =cut
78              
79             sub os_is {
80 50     50 1 58 my @targets = @_;
81 50         50 my $rval = 0;
82 50         54 foreach my $target (@targets) {
83 50 50       290 die("Devel::CheckOS: $target isn't a legal OS name\n")
84             unless($target =~ /^\w+(::\w+)*$/);
85 1     1   337 eval "use Devel::AssertOS::$target";
  0     1   0  
  0     1   0  
  1     1   198  
  0     1   0  
  0     1   0  
  1     1   195  
  0     1   0  
  0     1   0  
  1     1   205  
  0     1   0  
  0     1   0  
  1     1   181  
  0     1   0  
  0     1   0  
  1     1   303  
  0     1   0  
  0     1   0  
  1     1   190  
  0     1   0  
  0     1   0  
  1     1   191  
  0     1   0  
  0     1   0  
  1     1   189  
  0     1   0  
  0     1   0  
  1     1   188  
  0     1   0  
  0     1   0  
  1     1   187  
  0     1   0  
  0     1   0  
  1     1   190  
  0     1   0  
  0     1   0  
  1     1   189  
  0     1   0  
  0     1   0  
  1     1   207  
  0     1   0  
  0     1   0  
  1     1   186  
  0     1   0  
  0     1   0  
  1     1   183  
  0     1   0  
  0     1   0  
  1     1   190  
  0     1   0  
  0         0  
  1         178  
  0         0  
  0         0  
  1         187  
  0         0  
  0         0  
  1         181  
  0         0  
  0         0  
  1         196  
  0         0  
  0         0  
  1         184  
  0         0  
  0         0  
  1         183  
  0         0  
  0         0  
  1         194  
  0         0  
  0         0  
  1         190  
  0         0  
  0         0  
  1         186  
  0         0  
  0         0  
  1         195  
  0         0  
  0         0  
  1         215  
  0         0  
  0         0  
  1         224  
  0         0  
  0         0  
  1         187  
  0         0  
  0         0  
  1         193  
  0         0  
  0         0  
  1         197  
  0         0  
  0         0  
  1         190  
  0         0  
  0         0  
  1         185  
  0         0  
  0         0  
  1         183  
  0         0  
  0         0  
  1         191  
  0         0  
  0         0  
  1         194  
  0         0  
  0         0  
  1         181  
  0         0  
  0         0  
  1         194  
  0         0  
  0         0  
  1         189  
  0         0  
  0         0  
  1         185  
  0         0  
  0         0  
  1         188  
  0         0  
  0         0  
  1         193  
  0         0  
  0         0  
  1         241  
  0         0  
  0         0  
  1         189  
  0         0  
  0         0  
  1         189  
  0         0  
  0         0  
  1         203  
  0         0  
  0         0  
  1         192  
  0         0  
  0         0  
  1         190  
  0         0  
  0         0  
  1         183  
  0         0  
  0         0  
  50         3116  
86 50 50       250 if(!$@) {
87 1     1   4 no strict 'refs';
  1         1  
  1         495  
88 0 0       0 $rval = 1 if(&{"Devel::AssertOS::${target}::os_is"}());
  0         0  
89             }
90             }
91 50         197 return $rval;
92             }
93              
94             =head3 os_isnt
95              
96             If the current platform matches any of the parameters it returns false,
97             otherwise it returns true.
98              
99             =cut
100              
101             sub os_isnt {
102 50     50 1 9294 my @targets = @_;
103 50         51 my $rval = 1;
104 50         63 foreach my $target (@targets) {
105 50 50       74 $rval = 0 if(os_is($target));
106             }
107 50         102 return $rval;
108             }
109              
110             =head2 Fatal functions
111              
112             =head3 die_if_os_isnt
113              
114             As C<os_is()>, except that it dies instead of returning false. The die()
115             message matches what the CPAN-testers look for to determine if a module
116             doesn't support a particular platform.
117              
118             =cut
119              
120             sub die_if_os_isnt {
121 0 0   0 1   os_is(@_) ? 1 : die_unsupported();
122             }
123              
124             =head3 die_if_os_is
125              
126             As C<os_isnt()>, except that it dies instead of returning false.
127              
128             =cut
129              
130             sub die_if_os_is {
131 0 0   0 1   os_isnt(@_) ? 1 : die_unsupported();
132             }
133              
134             =head2 And some utility functions ...
135              
136             =head3 die_unsupported
137              
138             This function simply dies with the message "OS unsupported", which is what
139             the CPAN testers look for to figure out whether a platform is supported or
140             not.
141              
142             =cut
143              
144 0     0 1   sub die_unsupported { die("OS unsupported\n"); }
145              
146             =head3 list_platforms
147              
148             When called in list context,
149             return a list of all the platforms for which the corresponding
150             Devel::AssertOS::* module is available. This includes both OSes and OS
151             families, and both those bundled with this module and any third-party
152             add-ons you have installed.
153              
154             In scalar context, returns a hashref keyed by platform with the filename
155             of the most recent version of the supporting module that is available to you.
156             This is to make sure that the use-devel-assertos script Does The Right Thing
157             in the case where you have installed the module in one version of perl, then
158             upgraded perl, and installed it again in the new version. Sometimes the old
159             version of perl and all its modules will still be hanging around and perl
160             "helpfully" includes the old perl's search path in its own.
161              
162             Unfortunately, on some platforms this list may have file case
163             broken. eg, some platforms might return 'freebsd' instead of 'FreeBSD'.
164             This is because they have case-insensitive filesystems so things
165             should Just Work anyway.
166              
167             =cut
168              
169             my ($re_Devel, $re_AssertOS);
170              
171             sub list_platforms {
172 0     0 1   eval " # only load these if needed
173             use File::Find::Rule;
174             use File::Spec;
175             ";
176            
177 0 0         die($@) if($@);
178 0 0         if (!$re_Devel) {
179 0 0         my $case_flag = File::Spec->case_tolerant ? '(?i)' : '';
180 0           $re_Devel = qr/$case_flag ^Devel$/x;
181 0           $re_AssertOS = qr/$case_flag ^AssertOS$/x;
182             }
183              
184             # sort by mtime, so oldest last
185 0           my @modules = sort {
186 0           (stat($a->{file}))[9] <=> (stat($b->{file}))[9]
187             } map {
188 0           my (undef, $dir_part, $file_part) = File::Spec->splitpath($_);
189 0           $file_part =~ s/\.pm$//;
190 0           my (@dirs) = grep {+length} File::Spec->splitdir($dir_part);
  0            
191 0           foreach my $i (reverse 1..$#dirs) {
192 0 0 0       next unless $dirs[$i] =~ $re_AssertOS
193             && $dirs[$i - 1] =~ $re_Devel;
194 0           splice @dirs, 0, $i + 1;
195 0           last;
196             }
197             {
198 0           module => join('::', @dirs, $file_part),
199             file => File::Spec->canonpath($_)
200             }
201             } File::Find::Rule->file()->name('*.pm')->in(
202 0           grep { -d }
203 0           map { File::Spec->catdir($_, qw(Devel AssertOS)) }
204             @INC
205             );
206              
207 0           my %modules = map {
208 0           $_->{module} => $_->{file}
209             } @modules;
210              
211 0 0         if(wantarray()) {
212 0           return sort keys %modules;
213             } else {
214 0           return \%modules;
215             }
216             }
217              
218             =head3 list_family_members
219              
220             Takes the name of an OS 'family' and returns a list of all its members.
221             In list context, you get a list, in scalar context you get an arrayref.
222              
223             If called on something that isn't a family, you get an empty list (or
224             a ref to an empty array).
225              
226             =cut
227              
228             sub list_family_members {
229 0   0 0 1   my $family = shift() ||
230             die(__PACKAGE__."::list_family_members needs a parameter\n");
231              
232             # this will die if it's the wrong OS, but the module is loaded ...
233 0           eval qq{use Devel::AssertOS::$family};
234             # ... so we can now query it
235 0           my @members = eval qq{
236             no strict 'refs';
237             &{"Devel::AssertOS::${family}::matches"}()
238             };
239 0 0         return wantarray() ? @members : \@members;
240             }
241              
242             =head1 PLATFORMS SUPPORTED
243              
244             To see the list of platforms for which information is available, run this:
245              
246             perl -MDevel::CheckOS -e 'print join(", ", Devel::CheckOS::list_platforms())'
247              
248             Note that capitalisation is important. These are the names of the
249             underlying Devel::AssertOS::* modules
250             which do the actual platform detection, so they have to
251             be 'legal' filenames and module names, which unfortunately precludes
252             funny characters, so platforms like OS/2 are mis-spelt deliberately.
253             Sorry.
254              
255             Also be aware that not all of them have been properly tested. I don't
256             have access to most of them and have had to work from information
257             gleaned from L<perlport> and a few other places. For a complete list of
258             OS families, see L<Devel::CheckOS::Families>.
259              
260             If you want to add your own OSes or families, see L<Devel::AssertOS::Extending>
261             and please feel free to upload the results to the CPAN.
262              
263             =head1 BUGS and FEEDBACK
264              
265             I welcome feedback about my code, including constructive criticism.
266             Bug reports should be made using L<http://rt.cpan.org/> or by email.
267              
268             You will need to include in your bug report the exact value of $^O, what
269             the OS is called (eg Windows Vista 64 bit Ultimate Home Edition), and,
270             if relevant, what "OS family" it should be in and who wrote it.
271              
272             If you are feeling particularly generous you can encourage me in my
273             open source endeavours by buying me something from my wishlist:
274             L<http://www.cantrell.org.uk/david/wishlist/>
275              
276             =head1 SEE ALSO
277              
278             $^O in L<perlvar>
279              
280             L<perlport>
281              
282             L<Devel::AssertOS>
283              
284             L<Devel::AssertOS::Extending>
285              
286             L<Probe::Perl>
287              
288             The use-devel-assertos script
289              
290             L<Module::Install::AssertOS>
291              
292             =head1 AUTHOR
293              
294             David Cantrell E<lt>F<david@cantrell.org.uk>E<gt>
295              
296             Thanks to David Golden for the name and ideas about the interface, and
297             to the cpan-testers-discuss mailing list for prompting me to write it
298             in the first place.
299              
300             Thanks to Ken Williams, from whose L<Module::Build> I lifted some of the
301             information about what should be in the Unix family.
302              
303             Thanks to Billy Abbott for finding some bugs for me on VMS.
304              
305             Thanks to Matt Kraai for information about QNX.
306              
307             Thanks to Kenichi Ishigaki and Gabor Szabo for reporting a bug on Windows,
308             and to the former for providing a patch.
309              
310             Thanks to Paul Green for some information about VOS.
311              
312             Thanks to Yanick Champoux for a patch to let Devel::AssertOS support
313             negative assertions.
314              
315             =head1 SOURCE CODE REPOSITORY
316              
317             L<git://github.com/DrHyde/perl-modules-Devel-CheckOS.git>
318              
319             =head1 COPYRIGHT and LICENCE
320              
321             Copyright 2007-2012 David Cantrell
322              
323             This software is free-as-in-speech software, and may be used, distributed, and modified under the terms of either the GNU General Public Licence version 2 or the Artistic Licence. It's up to you which one you use. The full text of the licences can be found in the files GPL2.txt and ARTISTIC.txt, respectively.
324              
325             =head1 HATS
326              
327             I recommend buying a Fedora from L<http://hatsdirect.com/>.
328              
329             =head1 CONSPIRACY
330              
331             This module is also free-as-in-mason software.
332              
333             =cut
334              
335             1;