File Coverage

blib/lib/Gentoo/Probe.pm
Criterion Covered Total %
statement 37 155 23.8
branch 11 72 15.2
condition 1 15 6.6
subroutine 9 22 40.9
pod 0 15 0.0
total 58 279 20.7


line stmt bran cond sub pod time code
1             package Gentoo::Probe;
2             our ($VERSION) = q(1.0.6);
3 8     8   71910 use strict; $|=1;
  8         19  
  8         491  
4              
5 23     23   31420 sub import { goto \&Exporter::import };
6 8     8   961 use Gentoo::Util;
  8         16  
  8         51  
7 8     8   43 use Cwd;
  8         14  
  8         16339  
8             our(@mods);
9             my (%defs) = (
10             'uninstalled' => 0,
11             'installed' => 0,
12             'case' => 1,
13             'versions' => 0,
14             'builds' => 0,
15             'verbose' => 0,
16             'latest' => 0,
17             'pats' => [],
18             'cfgdir' => undef,
19             'portdir' => undef,
20             'vdb_dir' => undef,
21             );
22             my $cfg;
23             sub cfg {
24 8   33 8 0 47 $cfg ||= do {
25 8     8   3244 local $_ = eval q{
  0         0  
  0         0  
  8         549  
26             use Gentoo::Config;
27             new Gentoo::Config;
28             };
29 8 50       1987 die "$@" if "$@";
30 0 0       0 die "no cfg!" unless defined $_;
31 0         0 $_;
32             };
33 0         0 $cfg;
34             };
35             sub output {
36 0     0 0 0 my $self = shift;
37 0         0 print @_, "\n";
38             };
39             sub portdir {
40 0     0 0 0 $_[0]->{portdir};
41             };
42             sub overdir {
43 0     0 0 0 $_[0]->{overdir};
44             };
45             sub vdb_dir {
46 0     0 0 0 $_[0]->{vdb_dir};
47             };
48             sub new {
49 8     8 0 2203 local $_;
50 8         16 my $class = shift;
51 8 100       37 my $passed = @_ ? shift : {};
52 8 50       42 confess "usage: new Gentoo::Probe(\%parms) [got: ", $passed, "]"
53             unless ref $passed;
54 8         40 my %data = ( %defs, %{$passed} );
  8         76  
55 8         26 my $self=\%data;
56 8         25 bless($self,$class);
57 8         76 $self->gen_methods();
58 8         31 for($self->{portdir}) {
59 8 100       39 $_= cfg()->get(qw(PORTDIR)) unless defined;
60             };
61 7         22 for($self->{vdb_dir}) {
62 7 50       29 $_= cfg()->get(qw(VDB_DIR),"/var/db/pkg") unless defined;
63             }
64 7         23 for($self->{overdir}) {
65 7 50       44 $_= cfg()->get(qw(PORTDIR_OVERLAY),"") unless defined;
66             };
67 0         0 for ( @{$self}{qw(portdir vdb_dir overdir)} ) {
  0         0  
68 0 0       0 next unless defined;
69 0 0       0 $_ = getcwd()."/".$_ unless m{^/};
70 0         0 $_.="/";
71 0         0 s{/[./]*/}{/}g;
72             };
73 0         0 my $pats = $data{pats};
74 0 0       0 if ( !defined($pats) ) {
    0          
    0          
75 0         0 $pats = $data{pats} = [ ];
76             } elsif ( ref $pats eq 'ARRAY' ) {
77             # all is well
78             } elsif ( ref $pats ) {
79 0         0 die "got a ", ref $pats, " as pats\n";
80             } else {
81 0         0 $pats = $data{pats} = [ $pats ];
82             }
83 0         0 for ( @$pats ) {
84 0         0 $_ = qr($_);
85             }
86 0 0       0 confess "\$pats should be an array ref!" unless ref $pats eq 'ARRAY';
87              
88 0 0 0     0 $self->{versions}=1 if $self->builds() || $self->latest();
89 0 0 0     0 unless ( $self->{installed} || $self->{uninstalled} ) {
90 0         0 $self->{installed} = $self->{uninstalled} = 1
91             };
92 0         0 return $self;
93             };
94             sub ls_uver($$) {
95 0     0 0 0 my $self = shift;
96 0         0 my $cat = shift;
97 0         0 my $pkg = shift;
98 0         0 my $pre = $self->{portdir}."/".$cat."/".$pkg."/$pkg-";
99 0         0 my $len = length($pre);
100 0         0 @_ = glob("${pre}*.ebuild");
101 0         0 @_ = map { substr($_,$len) } @_;
  0         0  
102 0         0 @_ = map { substr($_,0,-7) } @_;
  0         0  
103 0         0 @_;
104             };
105             sub ls_iver($$) {
106 0     0 0 0 my $self = shift;
107 0         0 my $cat = shift;
108 0         0 my $pkg = shift;
109 0         0 my $pre = $self->{vdb_dir}."/".$cat."/".$pkg."-";
110 0         0 my $len = length($pre);
111 0         0 @_ = glob("${pre}[0-9]*");
112 0         0 @_ = map { substr($_,$len) } @_;
  0         0  
113 0         0 @_;
114             };
115             sub ls_pkgs($$){
116             return map {
117 0 0   0 0 0 if ( /^canna-2ch/ ) {
  0 0       0  
118 0         0 s/-2ch-[0-9].*/-2ch/;
119             } elsif ( /^font-adobe-\d+dpi/ ) {
120 0         0 s/dpi-[0-9].*/dpi/;
121             } else {
122 0         0 s/-[0-9].*//;
123             };
124 0         0 $_;
125             } ls_dirs( $_[0],$_[1] );
126             };
127             sub ls_dirs($$){
128 0     0 0 0 my ( $dir, $allowfail ) = (shift,shift);
129 0 0       0 if ( opendir(my $DIR, $dir) ) {
130 0         0 my @x= readdir($DIR);
131 0 0 0     0 @x=grep {
      0        
132 0         0 $_ ne '.' && $_ ne 'CVS' && $_ ne '..' && -d $dir."/".$_
133             } @x;
134 0         0 return @x;
135             };
136 0 0       0 return () if $allowfail;
137 0         0 confess "opendir:$dir:$!\n";
138             };
139             sub accept($$$@) {
140 0     0 0 0 my ( $self, $cat, $pkg, @vers ) = @_;
141              
142 0 0       0 splice(@vers,0,-1) if ( $self->latest() );
143 0 0       0 if ( $self->builds() ) {
    0          
144 0         0 $cat = join("/", $self->portdir(),$cat);
145 0         0 for ( @vers ) {
146 0         0 $self->output(join("/",$cat,$pkg,$pkg."-".$_ .".ebuild"));
147             };
148             } elsif ( $self->versions() ) {
149 0         0 for (@vers ) {
150 0         0 $self->output($cat."/".$pkg."-".$_);
151             };
152             } else {
153 0         0 $self->output($cat."/".$pkg);
154             };
155             };
156             sub not_installed($$$){
157 0     0 0 0 my ( $self, $cat, $pkg ) = @_;
158 0         0 my $globspec = $self->vdb_dir()."/$cat/$pkg-[0-9]*/.";
159 0         0 return !glob($globspec);
160             };
161             sub check_pats($@){
162 0     0 0 0 my $self = shift;
163 0         0 local $_ = shift;
164 0 0       0 return 1 unless @_;
165 0         0 for my $re ( @_ ) {
166             # confess "internal error" if ref $re ne 'Regexp';
167 0 0       0 return 1 if /$re/;
168             };
169 0         0 return 0;
170             };
171             sub run($) {
172 0     0 0 0 my $self=shift;
173 0         0 my $idir = $self->vdb_dir();
174 0         0 my $udir = $self->portdir();
175 0         0 my @pats = @{$self->{pats}};
  0         0  
176              
177 0         0 my %cat;
178 0         0 $cat{$_} = undef for(grep { /-/ } ls_dirs($udir,0));
  0         0  
179 0         0 $cat{$_} = undef for(grep { /-/ } ls_dirs($idir,0));
  0         0  
180 0         0 my $x=0;
181 0         0 for my $cat ( sort keys %cat ) {
182 0         0 my %pkg;
183 0         0 $pkg{$_} |= 1 for(ls_pkgs("$udir/$cat",1));
184 0         0 $pkg{$_} |= 2 for(ls_pkgs("$idir/$cat",1));
185              
186 0 0       0 if(!$self->installed()){
187 0         0 for(keys %pkg) {
188 0 0       0 delete $pkg{$_} if $pkg{$_} & 2;
189             };
190             };
191 0 0       0 if(!$self->uninstalled()){
192 0         0 for(keys %pkg) {
193 0 0       0 delete $pkg{$_} unless $pkg{$_} & 2;
194             };
195             };
196              
197 0         0 for my $pkg ( sort keys %pkg ) {
198 0         0 my $qua = $cat."/".$pkg;
199 0 0       0 next unless $self->check_pats( $qua , @pats );
200 0 0       0 if ( $self->versions() ) {
201 0         0 my %ver;
202 0         0 $ver{$_} |= 1 for $self->ls_uver($cat,$pkg);
203 0         0 $ver{$_} |= 2 for $self->ls_iver($cat,$pkg);
204             # if(!$self->installed()){
205             # for(keys %ver) {
206             # delete $ver{$_} if $ver{$_} & 2;
207             # };
208             # };
209 0 0       0 if(!$self->uninstalled()){
210 0         0 for(keys %ver) {
211 0 0       0 delete $ver{$_} unless $ver{$_} & 2;
212             };
213             };
214 0         0 $self->accept($cat,$pkg,sort keys %ver);
215             } else {
216 0         0 $self->accept($cat,$pkg);
217             }
218             };
219             }
220             };
221             sub gen_methods($) {
222 8     8 0 33 my ($self) = @_;
223 8 50       89 die 'ref \$self="',ref $self,'"' unless $self->isa("Gentoo::Probe");
224 8     8   54 no strict 'refs';
  8         67  
  8         1054  
225 8         15 for my $key (keys %{$self}){
  8         109  
226             *$key = sub{
227 0     0     my $self = shift;
228 0           my $slot = \$self->{$key};
229 0           my $res = $$slot;
230 0 0         $$slot = shift if @_;
231 0           $res;
232 100 100       981 } unless defined &$key;
233             };
234             };
235             1;