2 # Maemian::Collect::Source -- interface to source package data collection
4 # Copyright (C) 2008 Russ Allbery
5 # Copyright (C) 2009 Raphael Geissert
7 # This program is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by the Free
9 # Software Foundation; either version 2 of the License, or (at your option)
12 # This program is distributed in the hope that it will be useful, but WITHOUT
13 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 # You should have received a copy of the GNU General Public License along with
18 # this program. If not, see <http://www.gnu.org/licenses/>.
20 package Maemian::Collect::Source;
24 use base 'Maemian::Collect';
26 use Maemian::Relation;
27 use Parse::DebianChangelog;
31 our @ISA = qw(Maemian::Collect);
33 # Initialize a new source package collect object. Takes the package name,
34 # which is currently unused.
36 my ($class, $pkg) = @_;
42 # Get the changelog file of a source package as a Parse::DebianChangelog
43 # object. Returns undef if the changelog file couldn't be found.
44 # sub changelog Needs-Info <>
47 return $self->{changelog} if exists $self->{changelog};
48 if (-l 'debfiles/changelog' || ! -f 'debfiles/changelog') {
49 $self->{changelog} = undef;
51 my %opts = (infile => 'debfiles/changelog', quiet => 1);
52 $self->{changelog} = Parse::DebianChangelog->init(\%opts);
54 return $self->{changelog};
57 # Returns whether the package is a native package. For everything except
58 # format 3.0 (quilt) packages, we base this on whether we have a Debian
59 # *.diff.gz file. 3.0 (quilt) packages are always non-native. Returns true
60 # if the package is native and false otherwise.
61 # sub native Needs-Info <>
64 return $self->{native} if exists $self->{native};
65 my $format = $self->field('format');
66 if ($format =~ /^\s*2\.0\s*$/ or $format =~ /^\s*3\.0\s+\(quilt\)\s*$/) {
69 my $version = $self->field('version');
70 $version =~ s/^\d+://;
71 my $name = $self->{name};
72 $self->{native} = (-f "${name}_${version}.diff.gz" ? 0 : 1);
74 return $self->{native};
77 # Returns a hash of binaries to the package type, assuming a type of deb
78 # unless the package type field is present.
81 return $self->{binaries} if exists $self->{binaries};
83 # sub binaries Needs-Info source-control-file
84 opendir(BINPKGS, 'control') or fail("can't open control directory: $!");
85 for my $package (readdir BINPKGS) {
86 next if $package =~ /^\.\.?$/;
87 my $type = $self->binary_field($package, 'xc-package-type') || 'deb';
88 $binaries{$package} = lc $type;
91 $self->{binaries} = \%binaries;
92 return $self->{binaries};
95 # Returns the value of a control field for a binary package or the empty
96 # string if that control field isn't present. This does not implement
97 # inheritance from the settings in the source stanza.
99 my ($self, $package, $field) = @_;
100 return $self->{binary_field}{$package}{$field}
101 if exists $self->{binary_field}{$package}{$field};
103 # sub binary_field Needs-Info source-control-file
104 if (-f "control/$package/$field") {
105 $value = slurp_entire_file("control/$package/$field");
108 $self->{binary_field}{$package}{$field} = $value;
109 return $self->{binary_field}{$package}{$field};
112 # Return a Maemian::Relation object for the given relationship field in a
113 # binary package. In addition to all the normal relationship fields, the
114 # following special field names are supported: all (pre-depends, depends,
115 # recommends, and suggests), strong (pre-depends and depends), and weak
116 # (recommends and suggests).
117 sub binary_relation {
118 my ($self, $package, $field) = @_;
120 return $self->{binary_relation}->{$package}->{$field}
121 if exists $self->{binary_relation}->{$package}->{$field};
123 my %special = (all => [ qw(pre-depends depends recommends suggests) ],
124 strong => [ qw(pre-depends depends) ],
125 weak => [ qw(recommends suggests) ]);
127 if ($special{$field}) {
129 for my $f (@{ $special{$field} }) {
130 # sub binary_relation Needs-Info :binary_field
131 my $value = $self->binary_field($f);
132 $merged .= ', ' if (defined($merged) and defined($value));
133 $merged .= $value if defined($value);
137 my %known = map { $_ => 1 }
138 qw(pre-depends depends recommends suggests enhances breaks
139 conflicts provides replaces);
140 croak("unknown relation field $field") unless $known{$field};
141 my $value = $self->binary_field($field);
142 $result = $value if defined($value);
144 $result = Maemian::Relation->new($result);
145 $self->{binary_relation}->{$package}->{$field} = $result;
146 return $self->{binary_relation}->{$field};
149 # Returns the information from collect/file-info.
152 return $self->{file_info} if exists $self->{file_info};
155 # sub file_info Needs-Info file-info
156 open(my $idx, '<', "file-info") or fail("cannot open file-info: $!");
159 m/^(.+?):\s+(.*)$/o or fail("cannot parse file output: $_");
160 my ($file, $info) = ($1,$2);
163 $file_info{$file} = $info;
166 $self->{file_info} = \%file_info;
167 return $self->{file_info};
170 # Return a Maemian::Relation object for the given build relationship
171 # field. In addition to all the normal build relationship fields, the
172 # following special field names are supported: build-depends-all
173 # (build-depends and build-depends-indep) and build-conflicts-all
174 # (build-conflicts and build-conflicts-indep).
175 # sub relation Needs-Info <>
177 my ($self, $field) = @_;
179 return $self->{relation}->{$field} if exists $self->{relation}->{$field};
182 if ($field =~ /^build-(depends|conflicts)-all$/) {
185 for my $f ("build-$type", "build-$type-indep") {
186 my $value = $self->field($f);
187 $merged .= ', ' if (defined($merged) and defined($value));
188 $merged .= $value if defined($value);
191 } elsif ($field =~ /^build-(depends|conflicts)(-indep)?$/) {
192 my $value = $self->field($field);
193 $result = $value if defined($value);
195 croak("unknown relation field $field");
197 $self->{relation}->{$field} = Maemian::Relation->new($result);
198 return $self->{relation}->{$field};
201 # Similar to relation(), return a Maemian::Relation object for the given build
202 # relationship field, but ignore architecture restrictions. It supports the
203 # same special field names.
204 # sub relation_noarch Needs-Info <>
205 sub relation_noarch {
206 my ($self, $field) = @_;
208 return $self->{relation_noarch}->{$field}
209 if exists $self->{relation_noarch}->{$field};
212 if ($field =~ /^build-(depends|conflicts)-all$/) {
215 for my $f ("build-$type", "build-$type-indep") {
216 my $value = $self->field($f);
217 $merged .= ', ' if (defined($merged) and defined($value));
218 $merged .= $value if defined($value);
221 } elsif ($field =~ /^build-(depends|conflicts)(-indep)?$/) {
222 my $value = $self->field($field);
223 $result = $value if defined($value);
225 croak("unknown relation field $field");
227 $self->{relation_noarch}->{$field}
228 = Maemian::Relation->new_noarch($result);
229 return $self->{relation_noarch}->{$field};
234 Maemian::Collect::Source - Maemian interface to source package data collection
238 my ($name, $type) = ('foobar', 'source');
239 my $collect = Maemian::Collect->new($name, $type);
240 if ($collect->native) {
241 print "Package is native\n";
246 Maemian::Collect::Source provides an interface to package data for source
247 packages. It implements data collection methods specific to source
250 This module is in its infancy. Most of Maemian still reads all data from
251 files in the laboratory whenever that data is needed and generates that
252 data via collect scripts. The goal is to eventually access all data about
253 source packages via this module so that the module can cache data where
254 appropriate and possibly retire collect scripts in favor of caching that
263 Creates a new Maemian::Collect::Source object. Currently, PACKAGE is
264 ignored. Normally, this method should not be called directly, only via
265 the Maemian::Collect constructor.
269 =head1 INSTANCE METHODS
271 In addition to the instance methods listed below, all instance methods
272 documented in the Maemian::Collect module are also available.
278 Returns a hash reference with the binary package names as keys and the
279 Package-Type as value (which should be either C<deb> or C<udeb>
280 currently). The source-control-file collection script must have been run
281 to parse the F<debian/control> file and put the fields in the F<control>
282 directory in the lab.
284 =item binary_field(PACKAGE, FIELD)
286 Returns the content of the field FIELD for the binary package PACKAGE in
287 the F<debian/control> file, or an empty string if that field isn't set.
288 Inheritance of field values from the source section of the control file is
289 not implemented. Only the literal value of the field is returned.
291 The source-control-file collection script must have been run to parse the
292 F<debian/control> file and put the fields in the F<control> directory in
295 =item binary_relation(PACKAGE, FIELD)
297 Returns a Maemian::Relation object for the specified FIELD in the binary
298 package PACKAGE in the F<debian/control> file. FIELD should be one of the
299 possible relationship fields of a Debian package or one of the following
306 The concatenation of Pre-Depends, Depends, Recommends, and Suggests.
310 The concatenation of Pre-Depends and Depends.
314 The concatenation of Recommends and Suggests.
318 If FIELD isn't present in the package, the returned Maemian::Relation
319 object will be empty (always satisfied and implies nothing).
321 Any substvars in F<debian/control> will be represented in the returned
322 relation as packages named after the substvar.
326 Returns the changelog of the source package as a Parse::DebianChangelog
327 object, or undef if the changelog is a symlink or doesn't exist. The
328 debfiles collection script must have been run to create the changelog
329 file, which this method expects to find in F<debfiles/changelog>.
333 Returns true if the source package is native and false otherwise.
335 =item relation(FIELD)
337 Returns a Maemian::Relation object for the given build relationship field
338 FIELD. In addition to the normal build relationship fields, the
339 following special field names are supported:
343 =item build-depends-all
345 The concatenation of Build-Depends and Build-Depends-Indep.
347 =item build-conflicts-all
349 The concatenation of Build-Conflicts and Build-Conflicts-Indep.
353 If FIELD isn't present in the package, the returned Maemian::Relation
354 object will be empty (always satisfied and implies nothing).
356 =item relation_noarch(FIELD)
358 The same as relation(), but ignores architecture restrictions in the
365 Originally written by Russ Allbery <rra@debian.org> for Maemian.
369 lintian(1), Maemian::Collect(3), Maemian::Relation(3)
376 # indent-tabs-mode: nil
377 # cperl-indent-level: 4
379 # vim: syntax=perl sw=4 sts=4 ts=4 et shiftround