File Coverage

blib/lib/Alien/Packages.pm
Criterion Covered Total %
statement 40 55 72.7
branch 5 12 41.6
condition 3 6 50.0
subroutine 5 5 100.0
pod 3 3 100.0
total 56 81 69.1


line stmt bran cond sub pod time code
1             package Alien::Packages;
2              
3 2     2   15777 use warnings;
  2         3  
  2         67  
4 2     2   7 use strict;
  2         2  
  2         1036  
5              
6             require 5.008;
7             require Module::Pluggable::Object;
8              
9             =head1 NAME
10              
11             Alien::Packages - Find information of installed packages
12              
13             =cut
14              
15             our $VERSION = '0.001';
16              
17             =head1 SYNOPSIS
18              
19             my $ap = Alien::Packages->new();
20              
21             my @packages = $ap->list_packages();
22             foreach my $pkg (@packages)
23             {
24             print "$pkg->[0] version $pkg->[1]: $pkg->[2]\n";
25             }
26              
27             my %perl_owners = $ap->list_fileowners( File::Spec->rel2abs( $^X ) );
28             while( my ($fn, $pkg) = each( %perl_owners ) )
29             {
30             print "$fn is provided by ", join( ", ", @$pkg ), "\n";
31             }
32              
33             =head1 SUBROUTINES/METHODS
34              
35             =head2 new
36              
37             Instantiates new Alien::Packages object. Attributes can be specified
38             for used finder (of type L). Additionally,
39              
40             =over 4
41              
42             =item C
43              
44             Use only plugins which are still loaded.
45              
46             =back
47              
48             can be specified with a true value. This forces to grep C<%INC> instead
49             of using Module::Pluggable.
50              
51             =cut
52              
53             sub new
54             {
55 1     1 1 16 my ( $class, %attrs ) = @_;
56 1         4 my $self = bless( { plugins => [], }, $class );
57              
58 1         2 my $only_loaded = delete $attrs{only_loaded};
59              
60 1 50       4 if ($only_loaded)
61             {
62 0 0       0 my @search_path = __PACKAGE__ eq $class ? (__PACKAGE__) : ( __PACKAGE__, $class );
63 0         0 foreach my $path (@search_path)
64             {
65 0         0 $path =~ s|::|/|g;
66 0         0 $path .= "/";
67 0         0 my @loadedModules = grep { 0 == index( $_, $path ) } keys %INC;
  0         0  
68 0         0 foreach my $module (@loadedModules)
69             {
70 0         0 $module =~ s|/|::|;
71 0         0 $module =~ s/\.pm$//;
72 0 0 0     0 next unless ( $module->can('usable') && $module->usable() );
73 0         0 push( @{ $self->{plugins} }, $module->new() );
  0         0  
74             }
75             }
76             }
77             else
78             {
79 1 50       6 %attrs = (
80             require => 1,
81             search_path => [ __PACKAGE__ eq $class ? __PACKAGE__ : ( __PACKAGE__, $class ) ],
82             inner => 0,
83             %attrs,
84             );
85 1         8 my $finder = Module::Pluggable::Object->new(%attrs);
86 1         7 my @pkgClasses = $finder->plugins();
87 1         5641 foreach my $pkgClass (@pkgClasses)
88             {
89 9 100 100     131 next unless ( $pkgClass->can('usable') && $pkgClass->usable() );
90 1         2 push( @{ $self->{plugins} }, $pkgClass->new() );
  1         21  
91             }
92             }
93              
94 1         5 return $self;
95             }
96              
97             =head2 list_packages
98              
99             Lists the installed packages on the system (if the caller has the
100             permission to do).
101              
102             Results in a list of array references, whereby each item contains:
103              
104             {
105             PkgType => $pkg_type, # e.g. 'dpkg', 'pkgsrc', ...
106             Package => $pkg_name,
107             Version => $version,
108             Summary => $summary,
109             }
110              
111             C is the packager type, e.g. I, I or I.
112              
113             =cut
114              
115             sub list_packages
116             {
117 1     1 1 342 my $self = $_[0];
118 1         2 my @packages;
119              
120 1         1 foreach my $plugin ( @{ $self->{plugins} } )
  1         3  
121             {
122 1         4 my @ppkgs = $plugin->list_packages();
123 1         27 my $pkgtype = $plugin->pkgtype();
124 1         4 foreach my $pkg (@ppkgs)
125             {
126 209         155 $pkg->{PkgType} = $pkgtype;
127 209         147 push( @packages, $pkg );
128             }
129             }
130              
131 1         45 return @packages;
132             }
133              
134             =head2 list_fileowners
135              
136             Provides an association between files on the system and the package which
137             reference it (has presumably installed it).
138              
139             Returns a hash with the files names as key and a list of referencing
140             package names as value:
141              
142             '/absolute/path/to/file' =>
143             [
144             {
145             PkgType => $pkg_type,
146             Package => $pkg_name,
147             }
148             ],
149             ...
150              
151             =cut
152              
153             sub list_fileowners
154             {
155 1     1 1 1005 my ( $self, @files ) = @_;
156 1         1 my %file_owners;
157              
158 1         1 foreach my $plugin ( @{ $self->{plugins} } )
  1         5  
159             {
160 1         4 my $pkgtype = $plugin->pkgtype();
161 1         17 my %pfos = $plugin->list_fileowners(@files);
162 1         8 while ( my ( $fn, $pkgs ) = each %pfos )
163             {
164 1         4 foreach my $pkg (@$pkgs)
165             {
166 1         5 $pkg->{PkgType} = $pkgtype;
167             }
168              
169 1 50       8 if ( defined( $file_owners{$fn} ) )
170             {
171 0         0 push( @{ $file_owners{$fn} }, @{$pkgs} );
  0         0  
  0         0  
172             }
173             else
174             {
175 1         9 $file_owners{$fn} = $pkgs;
176             }
177             }
178             }
179              
180 1         18 return %file_owners;
181             }
182              
183             =head1 AUTHOR
184              
185             Jens Rehsack, C<< >>
186              
187             =head1 GETTING HELP
188              
189             To get novice help, it's usually recommended to ask on typical platforms
190             like PerlMonks. To help you make the best use of the PerlMonks platform,
191             and any other lists or forums you may use, I strongly recommend that you
192             read "How To Ask Questions The Smart Way" by Eric Raymond:
193             L.
194              
195             If you really asks a question what noone can answer, please drop me a
196             note with the question URL to either my CPAN address or on C
197             in the channels C<#toolchain> or C<#devops>. I'll try to answer as best
198             as I can (and as soon, as possible, of course).
199              
200             =head2 Where can I go for help with a concrete version?
201              
202             Bugs and feature requests are accepted against the latest version only.
203             To get patches for earlier versions, you need to get an agreement with a
204             developer of your choice - who may or not report the issue and a suggested
205             fix upstream (depends on the license you have chosen).
206              
207             =head2 Business support and maintenance
208              
209             For business support you can contact Jens via his CPAN email address
210             rehsackATcpan.org. Please keep in mind that business support is neither
211             available for free nor are you eligible to receive any support based on
212             the license distributed with this package.
213              
214             =head1 BUGS
215              
216             This module is alpha software, the API may change in future releases.
217             See L for more details.
218              
219             Please report any bugs or feature requests to
220             C, or through the web interface at
221             L. I will
222             be notified, and then you'll automatically be notified of progress on
223             your bug as I make changes.
224              
225             =head1 SUPPORT
226              
227             You can find documentation for this module with the perldoc command.
228              
229             perldoc Alien::Packages
230              
231             You can also look for information at:
232              
233             =over 4
234              
235             =item * RT: CPAN's request tracker
236              
237             L
238              
239             =item * AnnoCPAN: Annotated CPAN documentation
240              
241             L
242              
243             =item * CPAN Ratings
244              
245             L
246              
247             =item * Search CPAN
248              
249             L
250              
251             =back
252              
253             If you think you've found a bug then please also read "How to Report Bugs
254             Effectively" by Simon Tatham:
255             L.
256              
257             =head1 RESOURCES AND CONTRIBUTIONS
258              
259             There're several ways how you can help to support future development: You can
260             hire the author to implement the features you require at most (this also
261             defines priorities), you can negotiate a support and maintenance contract
262             with the company of the author and you can provide tests and patches. Further,
263             you can submit documentation and links to resources to improve or add
264             packaging systems or grant remote access to machines with insufficient
265             supported packaging tools.
266              
267             =head1 ACKNOWLEDGEMENTS
268              
269              
270             =head1 LICENSE AND COPYRIGHT
271              
272             Copyright 2010 Jens Rehsack.
273              
274             This program is free software; you can redistribute it and/or modify it
275             under the terms of either: the GNU General Public License as published
276             by the Free Software Foundation; or the Artistic License.
277              
278             See http://dev.perl.org/licenses/ for more information.
279              
280             =cut
281              
282             1; # End of Alien::Packages