File Coverage

blib/lib/System/Introspector/Probe/Packages/Apt.pm
Criterion Covered Total %
statement 55 55 100.0
branch 6 8 75.0
condition n/a
subroutine 21 21 100.0
pod 0 1 0.0
total 82 85 96.4


line stmt bran cond sub pod time code
1             package System::Introspector::Probe::Packages::Apt;
2 1     1   26866 use Moo;
  1         15487  
  1         6  
3 1     1   1719 use File::Basename;
  1         2  
  1         145  
4              
5 1         1104 use System::Introspector::Util qw(
6             handle_from_command
7             transform_exceptions
8             output_from_file
9             files_from_dir
10 1     1   580 );
  1         5  
11              
12             has apt_lists_dir => (is => 'ro', builder => 1);
13             has apt_update_after => (is => 'ro', default => sub { 86400 });
14             has apt_update => (is => 'ro');
15              
16             has apt_sources => (is => 'ro', builder => 1);
17             has apt_sources_dir => (is => 'ro', builder => 1);
18              
19 2     2   3209 sub _build_apt_lists_dir { '/var/lib/apt/lists' }
20 1     1   29 sub _build_apt_sources { '/etc/apt/sources.list' }
21 1     1   25 sub _build_apt_sources_dir { '/etc/apt/sources.list.d' }
22              
23             sub gather {
24 2     2 0 34 my ($self) = @_;
25             return {
26             update => {
27             last => $self->_last_apt_update,
28             run => transform_exceptions {
29 2     2   8 return { result => $self->_check_apt_state };
30             },
31             },
32             installed => transform_exceptions {
33 2     2   14 return { packages => $self->_gather_installed };
34             },
35             upgradable => transform_exceptions {
36 2     2   10 return { actions => $self->_gather_upgradable };
37             },
38             sources => transform_exceptions {
39 2     2   16 return { config => $self->_gather_sources };
40             },
41 2         8 };
42             }
43              
44             sub _last_apt_update {
45 3     3   5 my ($self) = @_;
46 3         133 return scalar( (stat($self->apt_lists_dir))[9] );
47             }
48              
49             sub _check_apt_state {
50 2     2   27 my ($self) = @_;
51 2 100       19 return 'disabled' unless $self->apt_update;
52 1         5 my $threshold = $self->apt_update_after;
53 1         6 my $last_change = $self->_last_apt_update;
54 1 50       9 return 'no'if ($last_change + $threshold) > time;
55 1         27 handle_from_command 'apt-get update';
56 1         29 return 'yes';
57             }
58              
59             sub _open_dpkg_query_pipe {
60 2     2   5 my ($self) = @_;
61 2         12 return handle_from_command 'dpkg-query --show';
62             }
63              
64             sub _open_apt_get_upgrade_simulation_pipe {
65 2     2   5 my ($self) = @_;
66 2         18 return handle_from_command 'apt-get -s upgrade';
67             }
68              
69             sub _gather_sources {
70 2     2   9 my ($self) = @_;
71 2         21 my $sources_dir = $self->apt_sources_dir;
72             return {
73             'sources_list' => $self->_fetch_source_list($self->apt_sources),
74             'sources_list_dir' => (-e $sources_dir) ? transform_exceptions {
75 1         7 return +{ files => +{ map {
76 2     2   16 ($_, $self->_fetch_source_list("$sources_dir/$_"));
77             } files_from_dir $sources_dir } };
78             } : {},
79 2 50       18 };
80             }
81              
82             sub _fetch_source_list {
83 3     3   12 my ($self, $file) = @_;
84             return transform_exceptions {
85             return {
86 3     3   35 file_name => $file,
87             body => scalar(output_from_file $file),
88             };
89 3         45 };
90             }
91              
92             sub _gather_upgradable {
93 2     2   7 my ($self) = @_;
94 2         14 my $pipe = $self->_open_apt_get_upgrade_simulation_pipe;
95 2         15 my %action;
96 2         21 while (defined( my $line = <$pipe> )) {
97 13         22 chomp $line;
98 13 100       100 if ($line =~ m{^(inst|remv)\s+(\S+)\s+(.+)$}i) {
99 4         66 $action{ lc($1) }{ $2 } = $3;
100             }
101             }
102 2         45 return \%action;
103             }
104              
105             sub _gather_installed {
106 2     2   6 my ($self) = @_;
107 2         8 my $pipe = $self->_open_dpkg_query_pipe;
108 2         7 my %package;
109 2         16 while (defined( my $line = <$pipe> )) {
110 528         606 chomp $line;
111 528         1182 my ($package, $version) = split m{\s+}, $line;
112 528         2672 $package{ $package } = {
113             version => $version,
114             };
115             }
116 2         36 return \%package;
117             }
118              
119             1;
120              
121             __END__