File Coverage

blib/lib/App/Sys/Info.pm
Criterion Covered Total %
statement 203 251 80.8
branch 34 88 38.6
condition 12 38 31.5
subroutine 36 38 94.7
pod 3 3 100.0
total 288 418 68.9


line stmt bran cond sub pod time code
1             package App::Sys::Info;
2             $App::Sys::Info::VERSION = '0.25';
3 1     1   65257 use strict;
  1         10  
  1         29  
4 1     1   5 use warnings;
  1         2  
  1         38  
5              
6 1     1   7 use constant CP_UTF8 => 65_001;
  1         1  
  1         98  
7 1     1   6 use constant LAST_ELEMENT => -1;
  1         2  
  1         57  
8              
9 1     1   13 use Carp qw( croak );
  1         2  
  1         48  
10 1     1   439 use Format::Human::Bytes;
  1         483  
  1         32  
11 1     1   476 use POSIX qw( locale_h );
  1         5996  
  1         5  
12 1     1   2037 use Text::Table qw();
  1         18321  
  1         30  
13 1     1   430 use Time::Elapsed qw( elapsed );
  1         3580  
  1         5  
14 1     1   536 use Sys::Info qw();
  1         13604  
  1         25  
15 1     1   7 use Sys::Info::Constants qw( NEW_PERL OSID );
  1         2  
  1         61  
16              
17             my($NEED_CHCP, $OLDCP);
18              
19             BEGIN {
20 1     1   6 no strict qw( refs );
  1         2  
  1         60  
21 1     1   4 foreach my $id ( qw( info os cpu fhb meta NA ) ) {
22 6     25   15 *{ $id } = sub () { return shift->{$id} };
  6         2267  
  25         95  
23             }
24             }
25              
26             END {
27 1 50 33 1   665 _chcp( $OLDCP ) if $NEED_CHCP && $OLDCP;
28             }
29              
30             sub _chcp {
31 0   0 0   0 my $enc = shift || croak 'No encoding specified';
32 0         0 system chcp => $enc, '2>nul', '1>nul';
33 0         0 return;
34             }
35              
36             sub new {
37 1     1 1 2 my $class = shift;
38 1         7 my $i = Sys::Info->new;
39 1         9 my $loc = do {
40 1         1 my $rv;
41             eval {
42 1         7 $rv = setlocale( LC_CTYPE );
43 1         4 1;
44 1 50       2 } or do {
45 0   0     0 my $error = $@ || 'Unknown error';
46 0         0 warn "Unable to collect the locale information: $error";
47 0         0 $rv = '';
48             };
49 1         2 $rv;
50             };
51 1         5 my $self = {
52             LOCALE => $loc,
53             NA => 'N/A',
54             info => $i,
55             os => $i->os,
56             cpu => $i->device('CPU'),
57             fhb => Format::Human::Bytes->new,
58             };
59 1         13780 $self->{meta} = { $self->{os}->meta };
60 1         47035 bless $self, $class;
61 1         4 return $self;
62             }
63              
64             sub run {
65 1     1 1 85 my $self = __PACKAGE__->new;
66 1   33     4 $NEED_CHCP = $self->os->is_winnt && $ENV{PROMPT};
67 1         8 my @probe = $self->probe;
68              
69 1         4 $self->_init_encoding;
70              
71 1         9 my $tb = Text::Table->new( q{}, q{} );
72 1         524 $tb->load( @probe );
73              
74 1 50       1744 print "\n", $tb or croak "Unable to orint to STDOUT: $!";
75 1         29038 return;
76             }
77              
78             sub probe {
79 1     1 1 2 my $self = shift;
80 1         2 my @rv = eval { $self->_probe(); };
  1         3  
81 1 50       4 croak "Error fetching information: $@" if $@;
82 1         3 return @rv;
83             }
84              
85             sub _init_encoding {
86 1     1   2 my $self = shift;
87 1 50       3 if ( $NEED_CHCP ) {
88             ## no critic (InputOutput::ProhibitBacktickOperators)
89 0         0 chomp($OLDCP = (split /:\s?/xms, qx(chcp))[LAST_ELEMENT]);
90             # try to change the command line encoding to unicode
91 0 0       0 _chcp( CP_UTF8 ) if $OLDCP;
92 0         0 if ( NEW_PERL ) {
93 0         0 my $eok = eval q{ binmode STDOUT, ':utf8'; 1; };
94             }
95             }
96 1         2 return;
97             }
98              
99             sub _probe {
100 1     1   2 my $self = shift;
101 1         4 my $meta = $self->meta;
102 1         4 my $NA = $self->NA;
103 1         4 my $i = $self->info;
104 1         2 my $os = $self->os;
105 1         3 my $pt = $os->product_type;
106 1         5 my $proc = $self->_processors;
107 1         13 my $tz = $os->tz;
108 1         176 my $driver = 'Sys::Info::Driver::' . OSID;
109 1         7 my @rv;
110              
111 1         19 push @rv,
112             [ 'Sys::Info Version' => Sys::Info->VERSION ],
113             [ sprintf( '%s Driver Version', OSID ) => $driver->VERSION ],
114             [ 'Perl Version' => $i->perl_long ],
115             [ 'Host Name' => $os->host_name ],
116             [ 'OS Name' => $self->_os_name ],
117             [ 'OS Version' => $self->_os_version ],
118             ;
119              
120 1         24 my $manu = $meta->{manufacturer};
121 1         3 my $bt = $meta->{build_type};
122              
123 1 50       5 push @rv, [ 'OS Manufacturer' => $manu ] if $manu;
124 1 50       3 push @rv, [ 'OS Configuration' => $pt ] if $pt;
125 1 50       3 push @rv, [ 'OS Build Type' => $bt ] if $bt;
126              
127 1         4 $self->_bitness( \@rv );
128 1         4 $self->_current_user( \@rv );
129 1         867 $self->_registered( \@rv, $meta );
130              
131 1         11 my $pid = $meta->{product_id};
132 1         8 my $tick = $os->tick_count;
133 1         204 my $st = $meta->{system_type};
134              
135 1 50       4 push @rv, [ 'Product ID' => $pid ] if $pid;
136              
137 1         4 $self->_install_date( \@rv );
138              
139 1 50       7 push @rv, [ 'System Up Time' => elapsed($tick) ] if $tick;
140              
141 1         982 $self->_manufacturer( \@rv, $meta );
142              
143 1 50       11 push @rv, [ 'System Type' => $st ] if $st;
144 1 50       3 push @rv, [ 'Processor(s)' => $proc ] if $proc;
145              
146 1         4 $self->_proc_meta( \@rv );
147 1         5 $self->_bios_version( \@rv );
148 1         5 $self->_directories( \@rv, $meta );
149              
150 1         2 my $loc = $self->{LOCALE};
151              
152 1 50       4 push @rv, [ 'System Locale' => $loc ] if $loc;
153 1 50       26 push @rv, [ 'Input Locale' => $loc ] if $loc;
154 1 50       17 push @rv, [ 'Time Zone' => $tz ] if $tz;
155              
156 1         7 $self->_memory( \@rv, $meta );
157 1         3 $self->_vm( \@rv );
158              
159 1         14 my $domain = $os->domain_name;
160 1         167 my $logon = $os->logon_server;
161 1         6 my $ip = $os->ip;
162 1         5609 my $page = $meta->{page_file_path};
163              
164 1 50       6 push @rv, [ 'Page File Location(s)' => $page ] if $page;
165 1 50       4 push @rv, [ 'Domain' => $domain ] if $domain;
166 1 50       3 push @rv, [ 'Logon Server' => $logon ] if $logon;
167 1 50       5 push @rv, [ 'IP Address' => $ip ] if $ip;
168              
169 1         6 $self->_cdkey( \@rv );
170              
171 1         13 return @rv;
172             }
173              
174             sub _registered {
175 1     1   4 my($self, $rv, $meta) = @_;
176 1 50       4 return if ! $self->os->is_windows;
177 0         0 my $owner = $meta->{owner};
178 0         0 my $org = $meta->{organization};
179 0 0       0 push @{ $rv }, [ 'Registered Owner' => $owner ] if $owner;
  0         0  
180 0 0       0 push @{ $rv }, [ 'Registered Organization' => $org ] if $org;
  0         0  
181 0         0 return;
182             }
183              
184             sub _directories {
185 1     1   4 my($self, $rv, $meta) = @_;
186 1         2 my $win = $meta->{windows_dir};
187 1         2 my $sys = $meta->{system_dir};
188 1         2 my $boot = $meta->{boot_device};
189 1 50       3 push @{ $rv }, [ 'Windows Directory' => $win ] if $win;
  0         0  
190 1 50       3 push @{ $rv }, [ 'System Directory' => $sys ] if $sys;
  0         0  
191 1 50       3 push @{ $rv }, [ 'Boot Device' => $boot ] if $boot;
  0         0  
192 1         2 return;
193             }
194              
195             sub _manufacturer {
196 1     1   3 my($self, $rv, $meta) = @_;
197 1 50       3 return if ! $self->os->is_windows;
198 0         0 my $manu = $meta->{system_manufacturer};
199 0         0 my $model = $meta->{system_model};
200 0 0       0 push @{ $rv }, [ 'System Manufacturer' => $manu ] if $manu;
  0         0  
201 0 0       0 push @{ $rv }, [ 'System Model' => $model ] if $model;
  0         0  
202 0         0 return;
203             }
204              
205             sub _cdkey {
206 1     1   3 my($self, $rv) = @_;
207 1         3 my $os = $self->os;
208 1 50       4 return if ! $os->is_windows;
209              
210 0         0 my $cdkey = $os->cdkey;
211 0         0 my $okey = $self->_office_cdkey;
212 0 0       0 push @{ $rv }, [ 'Windows CD Key' => $cdkey ] if $cdkey;
  0         0  
213 0 0       0 push @{ $rv }, [ 'Microsoft Office CD Key' => $okey ] if $okey;
  0         0  
214 0         0 return;
215             }
216              
217             sub _current_user {
218 1     1   3 my($self, $rv_ref) = @_;
219 1         3 my $os = $self->os;
220 1   50     5 my $user = $os->login_name || return;
221 0         0 my $real = $os->login_name( real => 1 );
222              
223 0 0 0     0 return if ! $user || ! $real;
224              
225 0 0 0     0 my $display = $real && ($real ne $user) ? qq{$real ($user)} : $user;
226 0 0       0 $display .= $os->is_root ? q{ is an administrator} : q{};
227 0         0 push @{ $rv_ref }, [ 'Current User', $display ];
  0         0  
228              
229 0         0 return;
230             }
231              
232             sub _proc_meta {
233 1     1   3 my $self = shift;
234 1         1 my $data = shift;
235 1         3 my @cpu = $self->cpu->identify;
236 1   50     19 my $prop = $cpu[0] || {};
237 1         3 my $load = $self->cpu->load;
238 1         176 my $L1 = $prop->{L1_cache}{max_cache_size};
239 1         2 my $L2 = $prop->{L2_cache}{max_cache_size};
240 1         3 my $sock = $prop->{socket_designation};
241 1         1 my $id = $prop->{processor_id};
242 1         2 my @rv;
243              
244             my $check_lc = sub {
245 2   50 2   5 my $ref = shift || return;
246 2 100       4 return if ! ${ $ref };
  2         6  
247 1 50       1 ${ $ref } .= q{ KB} if ${ $ref } !~ m{\sKB\z}xms;
  0         0  
  1         6  
248 1         2 return;
249 1         5 };
250              
251 1         4 $check_lc->( \$L1 );
252 1         3 $check_lc->( \$L2 );
253              
254 1 50       5 push @rv, qq{Load : $load} if $load;
255 1 50       3 push @rv, qq{L1 Cache: $L1} if $L1;
256 1 50       4 push @rv, qq{L2 Cache: $L2} if $L2;
257 1 50       5 push @rv, qq{Package : $sock} if $sock;
258 1 50       3 push @rv, qq{ID : $id} if $id;
259              
260 1         2 my $buf = q{ } x 2**2;
261 1         3 push @{$data}, [ q{ }, $buf . $_ ] for @rv;
  2         17  
262 1         7 return;
263             }
264              
265             sub _processors {
266 1     1   2 my $self = shift;
267 1         3 my $cpu = $self->cpu;
268 1         3 my $name = scalar $cpu->identify;
269 1         4256 my $rv = sprintf '%s ~%sMHz', $name, $cpu->speed;
270 1         33 $rv =~ s{\s+}{ }xmsg;
271 1         3 return $rv;
272             }
273              
274             sub _memory {
275 1     1   3 my($self, $rv, $meta) = @_;
276 1         5 push @{ $rv },
277             map {
278 4         72 [ $_->[0], $self->_mb( $_->[1] ) ]
279             }
280             [ 'Total Physical Memory' => $meta->{physical_memory_total} ],
281             [ 'Available Physical Memory' => $meta->{physical_memory_available} ],
282             [ 'Virtual Memory: Max Size' => $meta->{page_file_total} ],
283 1         2 [ 'Virtual Memory: Available' => $meta->{page_file_available} ],
284             ;
285 1         19 return;
286             }
287              
288             sub _vm {
289 1     1   3 my($self, $rv_ref) = @_;
290 1   50     3 my $tot = $self->meta->{page_file_total} || return;
291 1   50     3 my $av = $self->meta->{page_file_available} || return;
292 1         2 push @{ $rv_ref },
  1         3  
293             [ 'Virtual Memory: In Use' => $self->_mb( $tot - $av ) ]
294             ;
295 1         20 return;
296             }
297              
298             sub _mb {
299 5     5   9 my $self = shift;
300 5   50     10 my $kb = shift || return $self->NA;
301 5         10 return $self->fhb->base2( $kb, 2 );
302             }
303              
304             sub _os_name {
305 1     1   57 my $self = shift;
306 1         3 return $self->os->name( long => 1, edition => 1 );
307             }
308              
309             sub _os_version {
310 1     1   57 my $self = shift;
311 1         3 my $os = $self->os;
312 1         8 return $os->version . q{.} . $os->build;
313             }
314              
315             sub _office_cdkey {
316 0     0   0 my $self = shift;
317 0         0 my @office = $self->os->cdkey( office => 1 );
318 0 0       0 return @office ? $office[0] : undef;
319             }
320              
321             sub _bitness {
322 1     1   4 my($self, $rv_ref) = @_;
323 1   50     3 my $cpu = $self->cpu->bitness || q{??};
324 1   50     77 my $os = $self->os->bitness || q{??};
325 1         19 push @{ $rv_ref }, [ 'Running on' => qq{${cpu}bit CPU & ${os}bit OS} ];
  1         4  
326 1         3 return;
327             }
328              
329             sub _install_date {
330 1     1   3 my($self, $rv_ref) = @_;
331 1   50     3 my $date = $self->meta->{install_date} || return;
332 1         2 push @{ $rv_ref }, [ 'Original Install Date' => scalar localtime $date ];
  1         26  
333 1         4 return;
334             }
335              
336             sub _bios_version {
337 1     1   3 my($self, $rv_ref) = @_;
338 1         2 local $@;
339 1         1 my $bv = eval { $self->info->device('bios')->version; };
  1         3  
340 1 50 33     470 return if $@ || ! $bv;
341 0           push @{ $rv_ref }, [ 'BIOS Version' => $bv ];
  0            
342 0           return;
343             }
344              
345             1;
346              
347             __END__