File Coverage

perllib/Arch/Registry.pm
Criterion Covered Total %
statement 22 126 17.4
branch 0 42 0.0
condition 0 59 0.0
subroutine 7 18 38.8
pod 10 10 100.0
total 39 255 15.2


line stmt bran cond sub pod time code
1             # Arch Perl library, Copyright (C) 2004-2005 Mikhael Goikhman
2             #
3             # This program is free software; you can redistribute it and/or modify
4             # it under the terms of the GNU General Public License as published by
5             # the Free Software Foundation; either version 2 of the License, or
6             # (at your option) any later version.
7             #
8             # This program is distributed in the hope that it will be useful,
9             # but WITHOUT ANY WARRANTY; without even the implied warranty of
10             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11             # GNU General Public License for more details.
12             #
13             # You should have received a copy of the GNU General Public License
14             # along with this program; if not, write to the Free Software
15             # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16              
17 2     2   275 use 5.005;
  2         8  
  2         90  
18 2     2   11 use strict;
  2         4  
  2         162  
19              
20             package Arch::Registry;
21              
22 2     2   835 use Arch::Util qw(run_tla run_cmd save_file load_file);
  2         4  
  2         200  
23 2     2   44 use Arch::Backend qw(has_register_archive_name_arg);
  2         3  
  2         80  
24 2     2   1029 use Arch::LiteWeb;
  2         5  
  2         276  
25 2     2   737 use Arch::TempFiles;
  2         4  
  2         3275  
26              
27             my $SUPERMIRROR_REGISTRY_URL = $ENV{ARCH_SUPERMIRROR_REGISTRY_URL}
28             || "http://arch.debian.org/registry";
29             my $SUPERMIRROR_ARCHIVES_URL = "$SUPERMIRROR_REGISTRY_URL/archives.gz";
30             my $SUPERMIRROR_VERSIONS_URL = "$SUPERMIRROR_REGISTRY_URL/versions.gz";
31              
32             sub new ($%) {
33 1     1 1 7 my $class = shift;
34 1         5 my %args = @_;
35 1         3 my $self = { };
36 1         10 return bless $self, $class;
37             }
38              
39             sub register_archive ($$;$) {
40 0     0 1   my $self = shift;
41 0           my $location = shift;
42 0           my $archive = shift;
43              
44 0 0 0       my @name_arg = $archive && has_register_archive_name_arg()?
45             $archive: ();
46 0           my @args = ('register-archive --force', @name_arg, $location);
47 0           run_tla(@args);
48 0           return $? == 0;
49             }
50              
51             sub unregister_archive ($$) {
52 0     0 1   my $self = shift;
53 0           my $archive = shift;
54              
55 0           my @args = ('register-archive --force --delete', $archive);
56 0           run_tla(@args);
57 0           return $? == 0;
58             }
59              
60             sub _convert_lines_to_hash ($;$) {
61 0   0 0     my $lines = shift || die;
62 0   0       my $multiple = shift || 0;
63 0           my %hash = ();
64 0           my $key = undef;
65 0           my $values = [];
66 0   0       while (@$lines || @$values) {
67 0           my $line = shift @$lines;
68 0 0 0       if ($line && $line =~ s/^(\s+)//) {
69 0 0         die "Unexpected initial line with spaces '$1$line'" unless $key;
70 0           push @$values, $line;
71             } else {
72 0 0 0       $hash{$key} = $multiple? $values: ($values->[0] || die "No expected value line for '$key'") if $key;
    0          
73 0           $key = $line;
74 0           $values = [];
75             }
76             }
77 0           return \%hash;
78             }
79              
80             sub registered_archives ($) {
81 0     0 1   my $self = shift;
82 0           my @lines = run_tla('archives');
83 0           my $locations = _convert_lines_to_hash(\@lines);
84 0 0         return wantarray? %$locations: $locations;
85             }
86              
87             sub set_web_cache ($%) {
88 0     0 1   my $self = shift;
89 0           my %args = @_;
90 0           my $dir = $args{dir};
91 0 0 0       if ($dir && -d $dir) {
92 0   0       $self->{web_cache} = {
93             dir => $dir,
94             ttl => $args{ttl} || 3 * 60 * 60,
95             };
96 0           $self->{web_cache_flag} = "enabled";
97             } else {
98 0           $self->{web_cache} = undef;
99             }
100 0           $self->{archive_locations} = undef;
101 0           $self->{archive_versions} = undef;
102 0           return $self;
103             }
104              
105             sub flag_web_cache ($;$) {
106 0     0 1   my $self = shift;
107 0   0       my $val = shift || "disabled";
108 0 0         $val = "enabled" unless $val =~ /^disabled|noread|nowrite$/;
109 0           $self->{web_cache_flag} = $val;
110 0           return $self;
111             }
112              
113             sub _get_and_parse_gzipped_url ($$;$) {
114 0     0     my $self = shift;
115 0           my $url = shift;
116 0           my $multiple = shift;
117              
118 0   0       my $web = $self->{web} ||= Arch::LiteWeb->new;
119 0   0       my $tmp = $self->{tmp} ||= Arch::TempFiles->new;
120 0   0       my $read_cache =
121             $self->{web_cache} && $self->{web_cache_flag} =~ /^enabled|nowrite$/;
122 0   0       my $write_cache =
123             $self->{web_cache} && $self->{web_cache_flag} =~ /^enabled|noread$/;
124              
125 0           my $cached_file_name;
126             my $content;
127 0           my $content_from_cache = 0;
128 0 0 0       if ($read_cache || $write_cache) {
129 0 0         $url =~ m!/([^/]+)$! || die "Invalid url [$url]\n";
130 0           $cached_file_name = "$self->{web_cache}->{dir}/$1";
131             }
132 0 0 0       if (
      0        
133             $read_cache && -f $cached_file_name && (60 * 60 * 24 *
134             -M $cached_file_name < $self->{web_cache}->{ttl})
135             ) {
136 0           $content = load_file($cached_file_name);
137 0           $content_from_cache = 1;
138             }
139 0           $self->{content_from_cache} = $content_from_cache;
140              
141 0   0       $content ||= $web->get($url);
142 0 0         return unless $content;
143              
144 0 0 0       save_file($cached_file_name, \$content)
145             if $write_cache && !$content_from_cache;
146 0           my $file_name = $tmp->name;
147 0           save_file("$file_name.gz", \$content);
148 0           run_cmd("gzip -d", "$file_name.gz");
149 0 0         return if $?;
150 0           my $lines = [];
151 0           load_file($file_name, $lines);
152 0           unlink($file_name);
153 0           return _convert_lines_to_hash($lines, $multiple);
154             }
155              
156             sub supermirror_archives ($) {
157 0     0 1   my $self = shift;
158              
159 0           $self->{content_from_cache} = 1;
160 0   0       return $self->{supermirror_archive_locations}
161             ||= $self->_get_and_parse_gzipped_url($SUPERMIRROR_ARCHIVES_URL);
162             }
163              
164             sub supermirror_archive_versions ($) {
165 0     0 1   my $self = shift;
166              
167 0           $self->{content_from_cache} = 1;
168 0   0       return $self->{supermirror_archive_versions}
169             ||= $self->_get_and_parse_gzipped_url($SUPERMIRROR_VERSIONS_URL, 1);
170             }
171              
172             sub search_supermirror ($;$$$) {
173 0     0 1   my $self = shift;
174 0   0       my $archive_regexp = shift || '.*';
175 0   0       my $version_regexp = shift || '.*';
176 0           my $return_versions = shift;
177 0           my $archive_versions = $self->supermirror_archive_versions;
178 0 0         return undef unless $archive_versions;
179              
180             my @matching_archives =
181 0           eval { grep /$archive_regexp/, sort keys %$archive_versions };
  0            
182 0 0         return \@matching_archives unless $return_versions;
183              
184 0           my $want_hashref = $return_versions eq 'hashref';
185 0           my @matching_archive_versions = ();
186 0           my $matching_archive_versions = {};
187 0           foreach my $archive (@matching_archives) {
188 0           my $versions = $archive_versions->{$archive};
189 0           my @versions = eval { grep /$version_regexp/, @$versions };
  0            
190 0 0         if ($want_hashref) {
191 0 0         $matching_archive_versions->{$archive} = \@versions if @versions;
192             } else {
193 0           push @matching_archive_versions, map { "$archive/$_" } @versions;
  0            
194             }
195             }
196              
197 0 0         return $matching_archive_versions if $want_hashref;
198 0           return \@matching_archive_versions;
199             }
200              
201             sub web_error ($) {
202 0     0 1   my $self = shift;
203 0 0         return undef unless $self->{web};
204 0 0         return undef if $self->{content_from_cache};
205 0           return $self->{web}->error_with_url;
206             }
207              
208             1;
209              
210             __END__