1
# Copyright © 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
2
# Copyright © 2005-2008 Ryan Murray <rmurray@debian.org>
3
# Copyright © 2008 Roger Leigh <rleigh@debian.org
5
# This program is free software: you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation, either version 2 of the License, or
8
# (at your option) any later version.
10
# This program is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
# General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program. If not, see
17
# <http://www.gnu.org/licenses/>.
19
#######################################################################
21
package Wannabuild::Database;
28
use Sbuild qw(isin usage_error version_less version_lesseq version_eq version_compare);
29
use WannaBuild::Conf qw();
30
use Sbuild::Sysconfig;
32
use Sbuild::DB::MLDBM;
33
use Sbuild::DB::Postgres;
34
use WannaBuild::Options;
40
@ISA = qw(Exporter Sbuild::Base);
49
my $self = $class->SUPER::new($conf);
52
$self->set('Current Database', undef);
53
$self->set('Databases', {});
55
$self->set('Mail Logs', '');
57
my @curr_time = gmtime();
60
$self->set('Current Date', strftime("%Y %b %d %H:%M:%S", @curr_time));
61
$self->set('Short Date', strftime("%m/%d/%y", @curr_time));
62
$self->set('Current Time', $ctime);
64
# Note: specific contents are only incremented, never initially set.
65
# This might be a bug.
66
$self->set('New Version', {});
68
$self->set('Merge Src Version', {});
69
$self->set('Merge Bin Src', {});
71
$self->set('Priority Values', {
81
'debian-installer' => -199,
102
localizations => -178,
103
interpreters => -177,
134
foreach my $i (keys %{$sectval}) {
135
$sectval->{"contrib/$i"} = $sectval->{$i}+40;
136
$sectval->{"non-free/$i"} = $sectval->{$i}+80;
138
$sectval->{'unknown'} = -165;
139
$self->set('Section Values', $sectval);
141
$self->set('Category Values', {
143
"uploaded-fixed-pkg" => -19,
144
"fix-expected" => -18,
145
"reminder-sent" => -17,
146
"nmu-offered" => -16,
150
"compiler-error" => -12});
158
$self->set_conf('DB_OPERATION', $self->get_conf('DB_CATEGORY') ? "set-failed" : "set-building")
159
if !$self->get_conf('DB_OPERATION'); # default operation
160
$self->set_conf('DB_LIST_ORDER', $self->get_conf('DB_LIST_STATE') eq "failed" ? 'fPcpasn' : 'PScpasn')
161
if (!$self->get_conf('DB_LIST_ORDER') &&
162
(defined($self->get_conf('DB_LIST_STATE')) && $self->get_conf('DB_LIST_STATE')));
163
$self->set_conf('DISTRIBUTION', 'unstable')
164
if !defined($self->get_conf('DISTRIBUTION'));
166
die "Bad distribution '" . $self->get_conf('DISTRIBUTION') . "'\n"
167
if !isin($self->get_conf('DISTRIBUTION'), keys %{$self->get_conf('DB_DISTRIBUTIONS')});
169
if ($self->get_conf('VERBOSE')) {
170
print "wanna-build (Debian sbuild) $Sbuild::Sysconfig::version ($Sbuild::Sysconfig::release_date) on " . $self->get_conf('HOSTNAME') . "\n";
171
print "Using database " . $self->get_conf('DB_BASE_NAME') . '/' . $self->get_conf('DISTRIBUTION') . "\n"
174
if (!@ARGV && !isin($self->get_conf('DB_OPERATION'),
175
qw(list merge-quinn merge-partial-quinn import
176
export merge-packages manual-edit
177
maintlock-create merge-sources
178
maintlock-remove clean-db))) {
179
usage_error("wanna-build", "No packages given.");
182
if (!$self->get_conf('DB_FAIL_REASON')) {
183
if ($self->get_conf('DB_OPERATION') eq "set-failed" && !$self->get_conf('DB_CATEGORY')) {
184
print "Enter reason for failing (end with '.' alone on ".
190
last if $line eq ".\n";
194
$self->set_conf('DB_FAIL_REASON', $log);
195
} elsif ($self->get_conf('DB_OPERATION') eq "set-dep-wait") {
196
print "Enter dependencies (one line):\n";
198
while( !$line && !eof(STDIN) ) {
199
chomp( $line = <STDIN> );
201
die "No dependencies given\n" if !$line;
202
$self->set_conf('DB_FAIL_REASON'. $line);
203
} elsif ($self->get_conf('DB_OPERATION') eq "set-binary-nmu" and $self->get_conf('DB_BIN_NMU_VERSION') > 0) {
204
print "Enter changelog entry (one line):\n";
206
while( !$line && !eof(STDIN) ) {
207
chomp( $line = <STDIN> );
209
die "No changelog entry given\n" if !$line;
210
$self->set_conf('DB_FAIL_REASON', $line);
213
if ($self->get_conf('DB_OPERATION') eq "maintlock-create") {
214
$self->create_maintlock();
217
if ($self->get_conf('DB_OPERATION') eq "maintlock-remove") {
218
$self->remove_maintlock();
221
$self->waitfor_maintlock() if $self->get_conf('DB_OPERATION') !~ /^(?:merge-|clean-db$)/;
223
if (!-f $self->db_filename( $self->get_conf('DISTRIBUTION') ) && !$self->get_conf('DB_CREATE')) {
224
die "Database for " . $self->get_conf('DISTRIBUTION') . " doesn't exist\n";
227
# TODO: Use 'Databases' only.
228
$self->set('Current Database',
229
$self->open_db($self->get_conf('DISTRIBUTION')));
233
if ($self->get('Mail Logs') &&
234
defined($self->get_conf('DB_LOG_MAIL')) && $self->get_conf('DB_LOG_MAIL')) {
235
$self->send_mail($self->get_conf('DB_LOG_MAIL'),
236
"wanna-build " . $self->get_conf('DISTRIBUTION') .
237
" state changes " . $self->get('Current Date'),
238
"State changes at " . $self->get('Current Date') .
239
" for distribution ".
240
$self->get_conf('DISTRIBUTION') . ":\n\n".
241
$self->get('Mail Logs') . "\n");
250
SWITCH: foreach ($self->get_conf('DB_OPERATION')) {
252
$self->add_packages( $1, @ARGV );
256
$self->list_packages($self->get_conf('DB_LIST_STATE'));
260
$self->info_packages( @ARGV );
263
/^forget-user/ && do {
264
die "This operation is restricted to admin users\n"
265
if (defined @{$self->get_conf('DB_ADMIN_USERS')} and
266
!isin( $self->get_conf('USERNAME'), @{$self->get_conf('DB_ADMIN_USERS')}));
267
$self->forget_users( @ARGV );
271
$self->forget_packages( @ARGV );
274
/^merge-partial-quinn/ && do {
275
die "This operation is restricted to admin users\n"
276
if (defined @{$self->get_conf('DB_ADMIN_USERS')} and
277
!isin( $self->get_conf('USERNAME'), @{$self->get_conf('DB_ADMIN_USERS')}));
278
$self->parse_quinn_diff(1);
281
/^merge-quinn/ && do {
282
die "This operation is restricted to admin users\n"
283
if (defined @{$self->get_conf('DB_ADMIN_USERS')} and
284
!isin( $self->get_conf('USERNAME'), @{$self->get_conf('DB_ADMIN_USERS')}));
285
$self->parse_quinn_diff(0);
288
/^merge-packages/ && do {
289
die "This operation is restricted to admin users\n"
290
if (defined @{$self->get_conf('DB_ADMIN_USERS')} and
291
!isin( $self->get_conf('USERNAME'), @{$self->get_conf('DB_ADMIN_USERS')}));
292
$self->parse_packages();
295
/^merge-sources/ && do {
296
die "This operation is restricted to admin users\n"
297
if (defined @{$self->get_conf('DB_ADMIN_USERS')} and
298
!isin( $self->get_conf('USERNAME'), @{$self->get_conf('DB_ADMIN_USERS')}));
299
$self->parse_sources(0);
302
/^pretend-avail/ && do {
303
$self->pretend_avail( @ARGV );
307
die "This operation is restricted to admin users\n"
308
if (defined @{$self->get_conf('DB_ADMIN_USERS')} and
309
!isin( $self->get_conf('USERNAME'), @{$self->get_conf('DB_ADMIN_USERS')}));
311
@ARGV = ( $ARGS[0] );
312
my $pkgs = $self->parse_packages();
313
@ARGV = ( $ARGS[1] );
314
$self->parse_quinn_diff(0);
315
@ARGV = ( $ARGS[2] );
316
my $build_deps = $self->parse_sources(1);
317
$self->auto_dep_wait( $build_deps, $pkgs );
318
$self->get('Current Database')->clean();
322
die "This operation is restricted to admin users\n"
323
if (defined @{$self->get_conf('DB_ADMIN_USERS')} and
324
!isin( $self->get_conf('USERNAME'), @{$self->get_conf('DB_ADMIN_USERS')}));
325
$self->get('Current Database')->clear(); # clear all current contents
326
$self->get('Current Database')->restore($self->get_conf('DB_IMPORT_FILE'));
330
$self->get('Current Database')->dump($self->get_conf('DB_EXPORT_FILE'));
333
/^manual-edit/ && do {
334
die "This operation is restricted to admin users\n"
335
if (defined @{$self->get_conf('DB_ADMIN_USERS')} and
336
!isin( $self->get_conf('USERNAME'), @{$self->get_conf('DB_ADMIN_USERS')}));
337
my $tmpfile_pattern = "/tmp/wanna-build-" . $self->get_conf('DISTRIBUTION') . ".$$-";
339
for( $i = 0;; ++$i ) {
340
$tmpfile = $tmpfile_pattern . $i;
341
last if ! -e $tmpfile;
343
$self->get('Current Database')->dump($tmpfile);
344
my $editor = $ENV{'VISUAL'} ||
345
"/usr/bin/sensible-editor";
346
system "$editor $tmpfile";
347
$self->get('Current Database')->clear(); # clear all current contents
348
$self->get('Current Database')->restore($tmpfile);
353
die "This operation is restricted to admin users\n"
354
if (defined @{$self->get_conf('DB_ADMIN_USERS')} and
355
!isin( $self->get_conf('USERNAME'), @{$self->get_conf('DB_ADMIN_USERS')}));
356
$self->get('Current Database')->clean();
360
die "Unexpected operation mode " . $self->get_conf('DB_OPERATION') . "\n";
362
if (not -t and $self->get_conf('DB_USER') =~ /-/) {
363
my $ui = $self->get('Current Database')->get_user($self->get_conf('DB_USER'));
364
$ui = {} if (!defined($ui));
366
$ui->{'Last-Seen'} = $self->get('Current Date');
367
$ui->{'User'} = $self->get_conf('DB_USER');
369
$self->get('Current Database')->set_user($ui);
376
my $newstate = shift;
378
my( $package, $name, $version, $ok, $reason );
380
foreach $package (@_) {
381
$package =~ s,^.*/,,; # strip path
382
$package =~ s/\.(dsc|diff\.gz|tar\.gz|deb)$//; # strip extension
383
$package =~ s/_[a-zA-Z\d-]+\.changes$//; # strip extension
384
if ($package =~ /^([\w\d.+-]+)_([\w\d:.+~-]+)/) {
385
($name,$version) = ($1,$2);
388
warn "$package: can't extract package name and version ".
393
if ($self->get_conf('DB_OPERATION') eq "set-building") {
394
$self->add_one_building( $name, $version );
396
elsif ($self->get_conf('DB_OPERATION') eq "set-built") {
397
$self->add_one_built( $name, $version );
399
elsif ($self->get_conf('DB_OPERATION') eq "set-attempted") {
400
$self->add_one_attempted( $name, $version );
402
elsif ($self->get_conf('DB_OPERATION') eq "set-uploaded") {
403
$self->add_one_uploaded( $name, $version );
405
elsif ($self->get_conf('DB_OPERATION') eq "set-failed") {
406
$self->add_one_failed( $name, $version );
408
elsif ($self->get_conf('DB_OPERATION') eq "set-not-for-us") {
409
$self->add_one_notforus( $name, $version );
411
elsif ($self->get_conf('DB_OPERATION') eq "set-needs-build") {
412
$self->add_one_needsbuild( $name, $version );
414
elsif ($self->get_conf('DB_OPERATION') eq "set-dep-wait") {
415
$self->add_one_depwait( $name, $version );
417
elsif ($self->get_conf('DB_OPERATION') eq "set-build-priority") {
418
$self->set_one_buildpri( $name, $version, 'BuildPri' );
420
elsif ($self->get_conf('DB_OPERATION') eq "set-permanent-build-priority") {
421
$self->set_one_buildpri( $name, $version, 'PermBuildPri' );
423
elsif ($self->get_conf('DB_OPERATION') eq "set-binary-nmu") {
424
$self->set_one_binnmu( $name, $version );
429
sub add_one_building {
437
my $pkg = $self->get('Current Database')->get_package($name);
439
if ($pkg->{'State'} eq "Not-For-Us") {
441
$reason = "not suitable for this architecture";
443
elsif ($pkg->{'State'} =~ /^Dep-Wait/) {
445
$reason = "not all source dependencies available yet";
447
elsif ($pkg->{'State'} eq "Uploaded" &&
448
(version_lesseq($version, $pkg->{'Version'}))) {
450
$reason = "already uploaded by $pkg->{'Builder'}";
451
$reason .= " (in newer version $pkg->{'Version'})"
452
if !version_eq($pkg, $version);
454
elsif ($pkg->{'State'} eq "Installed" &&
455
version_less($version,$pkg->{'Version'})) {
456
if ($self->get_conf('DB_OVERRIDE')) {
457
print "$name: Warning: newer version $pkg->{'Version'} ".
458
"already installed, but overridden.\n";
462
$reason = "newer version $pkg->{'Version'} already in ".
463
"archive; doesn't need rebuilding";
464
print "$name: Note: If the following is due to an epoch ",
465
" change, use --override\n";
468
elsif ($pkg->{'State'} eq "Installed" &&
469
$self->pkg_version_eq($pkg,$version)) {
471
$reason = "is up-to-date in the archive; doesn't need rebuilding";
473
elsif ($pkg->{'State'} eq "Needs-Build" &&
474
version_less($version,$pkg->{'Version'})) {
475
if ($self->get_conf('DB_OVERRIDE')) {
476
print "$name: Warning: newer version $pkg->{'Version'} ".
477
"needs building, but overridden.";
481
$reason = "newer version $pkg->{'Version'} needs building, ".
485
elsif (isin($pkg->{'State'},qw(Building Built Build-Attempted))) {
486
if (version_less($pkg->{'Version'},$version)) {
487
print "$name: Warning: Older version $pkg->{'Version'} ",
488
"is being built by $pkg->{'Builder'}\n";
489
if ($pkg->{'Builder'} ne $self->get_conf('DB_USER')) {
492
"package takeover in newer version",
493
"You are building package '$name' in ".
494
"version $version\n".
495
"(as far as I'm informed).\n".
496
$self->get_conf('DB_USER') . " now has taken the newer ".
497
"version $version for building.".
498
"You can abort the build if you like.\n");
502
if ($self->get_conf('DB_OVERRIDE')) {
503
print "User $pkg->{'Builder'} had already ",
504
"taken the following package,\n",
505
"but overriding this as you request:\n";
507
$pkg->{'Builder'}, "package takeover",
508
"The package '$name' (version $version) that ".
509
"was locked by you\n".
510
"has been taken over by " . $self->get_conf('DB_USER') . "\n");
512
elsif ($pkg->{'Builder'} eq $self->get_conf('DB_USER')) {
513
print "$name: Note: already taken by you.\n";
514
print "$name: ok\n" if $self->get_conf('VERBOSE');
519
$reason = "already taken by $pkg->{'Builder'}";
520
$reason .= " (in newer version $pkg->{'Version'})"
521
if !version_eq($pkg->{'Version'}, $version);
525
elsif ($pkg->{'State'} =~ /^Failed/ &&
526
$self->pkg_version_eq($pkg, $version)) {
527
if ($self->get_conf('DB_OVERRIDE')) {
528
print "The following package previously failed ",
529
"(by $pkg->{'Builder'})\n",
530
"but overriding this as you request:\n";
532
$pkg->{'Builder'}, "failed package takeover",
533
"The package '$name' (version $version) that ".
534
"is locked by you\n".
535
"and has failed previously has been taken over ".
536
"by " . $self->get_conf('DB_USER') . "\n")
537
if $pkg->{'Builder'} ne $self->get_conf('DB_USER');
541
$reason = "build of $version failed previously:\n ";
542
$reason .= join( "\n ", split( "\n", $pkg->{'Failed'} ));
543
$reason .= "\nalso the package doesn't need builing"
544
if $pkg->{'State'} eq 'Failed-Removed';
550
if ($pkg->{'Binary-NMU-Version'}) {
551
print "$name: Warning: needs binary NMU $pkg->{'Binary-NMU-Version'}\n" .
552
"$pkg->{'Binary-NMU-Changelog'}\n";
555
print "$name: Warning: Previous version failed!\n"
556
if $pkg->{'Previous-State'} =~ /^Failed/ ||
557
$pkg->{'State'} =~ /^Failed/;
559
$self->change_state( $pkg, 'Building' );
560
$pkg->{'Package'} = $name;
561
$pkg->{'Version'} = $version;
562
$pkg->{'Builder'} = $self->get_conf('DB_USER');
563
$self->log_ta( $pkg, "--take" );
564
$self->get('Current Database')->set_package($pkg);
565
print "$name: $ok\n" if $self->get_conf('VERBOSE');
568
print "$name: NOT OK!\n $reason\n";
572
sub add_one_attempted {
577
my $pkg = $self->get('Current Database')->get_package($name);
579
if (!defined($pkg)) {
580
print "$name: not registered yet.\n";
584
if ($pkg->{'State'} ne "Building" ) {
585
print "$name: not taken for building (state is $pkg->{'State'}). ",
589
if ($pkg->{'Builder'} ne $self->get_conf('USERNAME')) {
590
print "$name: not taken by you, but by $pkg->{'Builder'}. Skipping.\n";
593
elsif ( !$self->pkg_version_eq($pkg, $version) ) {
594
print "$name: version mismatch ".
595
"$(pkg->{'Version'} ".
596
"by $pkg->{'Builder'})\n";
600
$self->change_state( $pkg, 'Build-Attempted' );
601
$self->log_ta( $pkg, "--attempted" );
602
$self->get('Current Database')->set_package($pkg);
603
print "$name: registered as uploaded\n" if $self->get_conf('VERBOSE');
611
my $pkg = $self->get('Current Database')->get_package($name);
613
if (!defined($pkg)) {
614
print "$name: not registered yet.\n";
618
if ($pkg->{'State'} ne "Building" ) {
619
print "$name: not taken for building (state is $pkg->{'State'}). ",
623
if ($pkg->{'Builder'} ne $self->get_conf('USERNAME')) {
624
print "$name: not taken by you, but by $pkg->{'Builder'}. Skipping.\n";
627
elsif ( !$self->pkg_version_eq($pkg, $version) ) {
628
print "$name: version mismatch ".
629
"$(pkg->{'Version'} ".
630
"by $pkg->{'Builder'})\n";
633
$self->change_state( $pkg, 'Built' );
634
$self->log_ta( $pkg, "--built" );
635
$self->get('Current Database')->set_package($pkg);
636
print "$name: registered as built\n" if $self->get_conf('VERBOSE');
639
sub add_one_uploaded {
644
my $pkg = $self->get('Current Database')->get_package($name);
646
if (!defined($pkg)) {
647
print "$name: not registered yet.\n";
651
if ($pkg->{'State'} eq "Uploaded" &&
652
$self->pkg_version_eq($pkg,$version)) {
653
print "$name: already uploaded\n";
656
if (!isin( $pkg->{'State'}, qw(Building Built Build-Attempted))) {
657
print "$name: not taken for building (state is $pkg->{'State'}). ",
661
if ($pkg->{'Builder'} ne $self->get_conf('DB_USER')) {
662
print "$name: not taken by you, but by $pkg->{'Builder'}. Skipping.\n";
665
# strip epoch -- buildd-uploader used to go based on the filename.
666
# (to remove at some point)
668
($pkgver = $pkg->{'Version'}) =~ s/^\d+://;
669
$version =~ s/^\d+://; # for command line use
670
if ($pkg->{'Binary-NMU-Version'} ) {
671
my $nmuver = binNMU_version($pkgver, $pkg->{'Binary-NMU-Version'});
672
if (!version_eq( $nmuver, $version )) {
673
print "$name: version mismatch ($nmuver registered). ",
677
} elsif (!version_eq($pkgver, $version)) {
678
print "$name: version mismatch ($pkg->{'Version'} registered). ",
683
$self->change_state( $pkg, 'Uploaded' );
684
$self->log_ta( $pkg, "--uploaded" );
685
$self->get('Current Database')->set_package($pkg);
686
print "$name: registered as uploaded\n" if $self->get_conf('VERBOSE');
695
my $pkg = $self->get('Current Database')->get_package($name);
697
if (!defined($pkg)) {
698
print "$name: not registered yet.\n";
701
$state = $pkg->{'State'};
703
if ($state eq "Not-For-Us") {
704
print "$name: not suitable for this architecture anyway. Skipping.\n";
707
elsif ($state eq "Failed-Removed") {
708
print "$name: failed previously and doesn't need building. Skipping.\n";
711
elsif ($state eq "Installed") {
712
print "$name: Is already installed in archive. Skipping.\n";
715
elsif ($pkg->{'Builder'} &&
716
(($self->get_conf('DB_USER') ne $pkg->{'Builder'}) &&
717
!($pkg->{'Builder'} =~ /^(\w+)-\w+/ && $1 eq $self->get_conf('DB_USER')))) {
718
print "$name: not taken by you, but by ".
719
"$pkg->{'Builder'}. Skipping.\n";
722
elsif ( !$self->pkg_version_eq($pkg, $version) ) {
723
print "$name: version mismatch ".
724
"$(pkg->{'Version'} ".
725
"by $pkg->{'Builder'})\n";
729
$cat = $self->get_conf('DB_CATEGORY');
730
if (!$cat && $self->get_conf('DB_FAIL_REASON') =~ /^\[([^\]]+)\]/) {
732
$cat = category($cat);
733
$cat = "" if !defined($cat);
734
my $fail_reason = $self->get_conf('DB_FAIL_REASON');
735
$fail_reason =~ s/^\[[^\]]+\][ \t]*\n*//;
736
$self->set_conf('DB_FAIL_REASON', $fail_reason);
739
if ($state eq "Needs-Build") {
740
print "$name: Warning: not registered for building previously, ".
741
"but processing anyway.\n";
743
elsif ($state eq "Uploaded") {
744
print "$name: Warning: marked as uploaded previously, ".
745
"but processing anyway.\n";
747
elsif ($state eq "Dep-Wait") {
748
print "$name: Warning: marked as waiting for dependencies, ".
749
"but processing anyway.\n";
751
elsif ($state eq "Failed") {
752
print "$name: already registered as failed; will append new message\n"
753
if $self->get_conf('DB_FAIL_REASON');
754
print "$name: already registered as failed; changing category\n"
758
if (($cat eq "reminder-sent" || $cat eq "nmu-offered") &&
759
exists $pkg->{'Failed-Category'} &&
760
$pkg->{'Failed-Category'} ne $cat) {
761
(my $action = $cat) =~ s/-/ /;
762
$self->set_conf('DB_FAIL_REASON',
763
$self->get_conf('DB_FAIL_REASON') . "\n" .
764
$self->get('Short Date') . ": $action");
767
$self->change_state( $pkg, 'Failed' );
768
$pkg->{'Builder'} = $self->get_conf('DB_USER');
769
$pkg->{'Failed'} .= "\n" if $pkg->{'Failed'};
770
$pkg->{'Failed'} .= $self->get_conf('DB_FAIL_REASON');
771
$pkg->{'Failed-Category'} = $cat if $cat;
772
if (defined $pkg->{'PermBuildPri'}) {
773
$pkg->{'BuildPri'} = $pkg->{'PermBuildPri'};
775
delete $pkg->{'BuildPri'};
777
$self->log_ta( $pkg, "--failed" );
778
$self->get('Current Database')->set_package($pkg);
779
print "$name: registered as failed\n" if $self->get_conf('VERBOSE');
782
sub add_one_notforus {
787
my $pkg = $self->get('Current Database')->get_package($name);
789
if ($pkg->{'State'} eq 'Not-For-Us') {
790
# reset Not-For-Us state in case it's called twice; this is
791
# the only way to get a package out of this state...
792
# There is no really good state in which such packages should
793
# be put :-( So use Failed for now.
794
$self->change_state( $pkg, 'Failed' );
795
$pkg->{'Package'} = $name;
796
$pkg->{'Failed'} = "Was Not-For-Us previously";
797
delete $pkg->{'Builder'};
798
delete $pkg->{'Depends'};
799
$self->log_ta( $pkg, "--no-build(rev)" );
800
print "$name: now not unsuitable anymore\n";
803
$self->get_conf('DB_NOTFORUS_MAINTAINER_EMAIL'),
804
"$name moved out of Not-For-Us state",
805
"The package '$name' has been moved out of the Not-For-Us ".
806
"state by " . $self->get_conf('DB_USER') . ".\n".
807
"It should probably also be removed from ".
808
"Packages-arch-specific or\n".
809
"the action was wrong.\n")
810
if $self->get_conf('DB_NOTFORUS_MAINTAINER_EMAIL');
813
$self->change_state( $pkg, 'Not-For-Us' );
814
$pkg->{'Package'} = $name;
815
delete $pkg->{'Builder'};
816
delete $pkg->{'Depends'};
817
delete $pkg->{'BuildPri'};
818
delete $pkg->{'Binary-NMU-Version'};
819
delete $pkg->{'Binary-NMU-Changelog'};
820
$self->log_ta( $pkg, "--no-build" );
821
print "$name: registered as unsuitable\n" if $self->get_conf('VERBOSE');
824
$self->get_conf('DB_NOTFORUS_MAINTAINER_EMAIL'),
825
"$name set to Not-For-Us",
826
"The package '$name' has been set to state Not-For-Us ".
827
"by " . $self->get_conf('DB_USER') . ".\n".
828
"It should probably also be added to ".
829
"Packages-arch-specific or\n".
830
"the Not-For-Us state is wrong.\n")
831
if $self->get_conf('DB_NOTFORUS_MAINTAINER_EMAIL');
833
$self->get('Current Database')->set_package($pkg);
836
sub add_one_needsbuild {
842
my $pkg = $self->get('Current Database')->get_package($name);
844
if (!defined($pkg)) {
845
print "$name: not registered; can't give back.\n";
848
$state = $pkg->{'State'};
850
if ($state eq "Dep-Wait") {
851
if ($self->get_conf('DB_OVERRIDE')) {
852
print "$name: Forcing source dependency list to be cleared\n";
855
print "$name: waiting for source dependencies. Skipping\n",
856
" (use --override to clear dependency list and ",
857
"give back anyway)\n";
861
elsif (!isin( $state, qw(Building Built Build-Attempted))) {
862
print "$name: not taken for building (state is $state).";
863
if ($self->get_conf('DB_OVERRIDE')) {
864
print "\n$name: Forcing give-back\n";
867
print " Skipping.\n";
871
if (defined ($pkg->{'Builder'}) && $self->get_conf('DB_USER') ne $pkg->{'Builder'} &&
872
!($pkg->{'Builder'} =~ /^(\w+)-\w+/ && $1 eq $self->get_conf('DB_USER'))) {
873
print "$name: not taken by you, but by ".
874
"$pkg->{'Builder'}. Skipping.\n";
877
if (!$self->pkg_version_eq($pkg, $version)) {
878
print "$name: version mismatch ($pkg->{'Version'} registered). ",
882
$self->change_state( $pkg, 'Needs-Build' );
883
delete $pkg->{'Builder'};
884
delete $pkg->{'Depends'};
885
$self->log_ta( $pkg, "--give-back" );
886
$self->get('Current Database')->set_package($pkg);
887
print "$name: given back\n" if $self->get_conf('VERBOSE');
895
my $pkg = $self->get('Current Database')->get_package($name);
898
if (!defined($pkg)) {
899
print "$name: not registered; can't register for binNMU.\n";
902
my $db_ver = $pkg->{'Version'};
904
if (!version_eq($db_ver, $version)) {
905
print "$name: version mismatch ($db_ver registered). ",
909
$state = $pkg->{'State'};
911
if (defined $pkg->{'Binary-NMU-Version'}) {
912
if ($self->get_conf('DB_BIN_NMU_VERSION') == 0) {
913
$self->change_state( $pkg, 'Installed' );
914
delete $pkg->{'Builder'};
915
delete $pkg->{'Depends'};
916
delete $pkg->{'Binary-NMU-Version'};
917
delete $pkg->{'Binary-NMU-Changelog'};
918
} elsif ($self->get_conf('DB_BIN_NMU_VERSION') <= $pkg->{'Binary-NMU-Version'}) {
919
print "$name: already building binNMU $pkg->{'Binary-NMU-Version'}\n";
922
$pkg->{'Binary-NMU-Version'} = $self->get_conf('DB_BIN_NMU_VERSION');
923
$pkg->{'Binary-NMU-Changelog'} = $self->get_conf('DB_FAIL_REASON');
924
$pkg->{'Notes'} = 'out-of-date';
925
$pkg->{'BuildPri'} = $pkg->{'PermBuildPri'}
926
if (defined $pkg->{'PermBuildPri'});
928
$self->log_ta( $pkg, "--binNMU" );
929
$self->get('Current Database')->set_package($pkg);
931
} elsif ($self->get_conf('DB_BIN_NMU_VERSION')) {
932
print "${name}_$version: no scheduled binNMU to cancel.\n";
936
if ($state ne 'Installed') {
937
print "${name}_$version: not installed; can't register for binNMU.\n";
941
my $fullver = binNMU_version($version,$self->get_conf('DB_BIN_NMU_VERSION'));
942
if (version_lesseq($fullver, $pkg->{'Installed-Version'})) {
943
print "$name: binNMU $fullver is not newer than current version $pkg->{'Installed-Version'}\n";
947
$self->change_state( $pkg, 'Needs-Build' );
948
delete $pkg->{'Builder'};
949
delete $pkg->{'Depends'};
950
$pkg->{'Binary-NMU-Version'} = $self->get_conf('DB_BIN_NMU_VERSION');
951
$pkg->{'Binary-NMU-Changelog'} = $self->get_conf('DB_FAIL_REASON');
952
$pkg->{'Notes'} = 'out-of-date';
953
$self->log_ta( $pkg, "--binNMU" );
954
$self->get('Current Database')->set_package($pkg);
955
print "${name}: registered for binNMU $fullver\n" if $self->get_conf('VERBOSE');
958
sub set_one_buildpri {
963
my $pkg = $self->get('Current Database')->get_package($name);
966
if (!defined($pkg)) {
967
print "$name: not registered; can't set priority.\n";
970
$state = $pkg->{'State'};
972
if ($state eq "Not-For-Us") {
973
print "$name: not suitable for this architecture. Skipping.\n";
975
} elsif ($state eq "Failed-Removed") {
976
print "$name: failed previously and doesn't need building. Skipping.\n";
979
if (!$self->pkg_version_eq($pkg, $version)) {
980
print "$name: version mismatch ($pkg->{'Version'} registered). ",
984
if ( $self->get_conf('DB_BUILD_PRIORITY') == 0 ) {
985
delete $pkg->{'BuildPri'}
986
if $key eq 'PermBuildPri' and defined $pkg->{'BuildPri'}
987
and $pkg->{'BuildPri'} == $pkg->{$key};
990
$pkg->{'BuildPri'} = $self->get_conf('DB_BUILD_PRIORITY')
991
if $key eq 'PermBuildPri';
992
$pkg->{$key} = $self->get_conf('DB_BUILD_PRIORITY');
994
$self->get('Current Database')->set_package($pkg);
995
print "$name: set to build priority " .
996
$self->get_conf('DB_BUILD_PRIORITY') . "\n" if $self->get_conf('VERBOSE');
999
sub add_one_depwait {
1002
my $version = shift;
1004
my $pkg = $self->get('Current Database')->get_package($name);
1006
if (!defined($pkg)) {
1007
print "$name: not registered yet.\n";
1010
$state = $pkg->{'State'};
1012
if ($state eq "Dep-Wait") {
1013
print "$name: merging with previously registered dependencies\n";
1016
if (isin( $state, qw(Needs-Build Failed))) {
1017
print "$name: Warning: not registered for building previously, ".
1018
"but processing anyway.\n";
1020
elsif ($state eq "Not-For-Us") {
1021
print "$name: not suitable for this architecture anyway. Skipping.\n";
1024
elsif ($state eq "Failed-Removed") {
1025
print "$name: failed previously and doesn't need building. Skipping.\n";
1028
elsif ($state eq "Installed") {
1029
print "$name: Is already installed in archive. Skipping.\n";
1032
elsif ($state eq "Uploaded") {
1033
print "$name: Is already uploaded. Skipping.\n";
1036
elsif ($pkg->{'Builder'} &&
1037
$self->get_conf('DB_USER') ne $pkg->{'Builder'}) {
1038
print "$name: not taken by you, but by ".
1039
"$pkg->{'Builder'}. Skipping.\n";
1042
elsif ( !$self->pkg_version_eq($pkg,$version)) {
1043
print "$name: version mismatch ".
1044
"($pkg->{'Version'} ".
1045
"by $pkg->{'Builder'})\n";
1048
elsif ($self->get_conf('DB_FAIL_REASON') =~ /^\s*$/ ||
1049
!$self->parse_deplist( $self->get_conf('DB_FAIL_REASON'), 1 )) {
1050
print "$name: Bad dependency list\n";
1053
$self->change_state( $pkg, 'Dep-Wait' );
1054
$pkg->{'Builder'} = $self->get_conf('DB_USER');
1055
if (defined $pkg->{'PermBuildPri'}) {
1056
$pkg->{'BuildPri'} = $pkg->{'PermBuildPri'};
1058
delete $pkg->{'BuildPri'};
1060
my $deplist = $self->parse_deplist( $pkg->{'Depends'}, 0 );
1061
my $new_deplist = $self->parse_deplist( $self->get_conf('DB_FAIL_REASON'), 0 );
1062
# add new dependencies, maybe overwriting old entries
1063
foreach (keys %$new_deplist) {
1064
$deplist->{$_} = $new_deplist->{$_};
1066
$pkg->{'Depends'} = $self->build_deplist($deplist);
1067
$self->log_ta( $pkg, "--dep-wait" );
1068
$self->get('Current Database')->set_package($pkg);
1069
print "$name: registered as waiting for dependencies\n" if $self->get_conf('VERBOSE');
1081
local($/) = ""; # read in paragraph mode
1083
my( $version, $arch, $section, $priority, $builddep, $buildconf, $binaries );
1085
/^Package:\s*(\S+)$/mi and $name = $1;
1086
/^Version:\s*(\S+)$/mi and $version = $1;
1087
/^Architecture:\s*(.+)$/mi and $arch = $1;
1088
/^Section:\s*(\S+)$/mi and $section = $1;
1089
/^Priority:\s*(\S+)$/mi and $priority = $1;
1090
/^Build-Depends:\s*(.*)$/mi and $builddep = $1;
1091
/^Build-Conflicts:\s*(.*)$/mi and $buildconf = $1;
1092
/^Binary:\s*(.*)$/mi and $binaries = $1;
1094
next if (defined $srcver{$name} and version_less( $version, $srcver{$name} ));
1095
$srcver{$name} = $version;
1097
$buildconf = join( ", ", map { "!$_" } split( /\s*,\s*/, $buildconf ));
1099
$builddep .= "," . $buildconf;
1101
$builddep = $buildconf;
1105
$pkgs{$name}{'dep'} = defined $builddep ? $builddep : "";
1106
$pkgs{$name}{'ver'} = $version;
1107
$pkgs{$name}{'bin'} = $binaries;
1108
my $pkg = $self->get('Current Database')->get_package($name);
1113
if ($arch eq "all" && !version_less( $version, $pkg->{'Version'} )) {
1114
# package is now Arch: all, delete it from db
1115
$self->change_state( $pkg, 'deleted' );
1116
$self->log_ta( $pkg, "--merge-sources" );
1117
print "$name ($pkg->{'Version'}): deleted ".
1118
"from database, because now Arch: all\n"
1119
if $self->get_conf('VERBOSE');
1120
$self->get('Current Database')->del_package($pkg);
1124
# The "Version" should always be the source version --
1125
# not a possible binNMU version number.
1126
$pkg->{'Version'} = $version, $change++
1127
if ($pkg->{'State'} eq 'Installed' and
1128
!version_eq( $pkg->{'Version'}, $version));
1129
# Always update priority and section, if available
1130
$pkg->{'Priority'} = $priority, $change++
1131
if defined $priority && (!defined($pkg->{'Priority'}) ||
1132
$pkg->{'Priority'} ne $priority);
1133
$pkg->{'Section'} = $section, $change++
1134
if defined $section && (!defined($pkg->{'Section'}) ||
1135
$pkg->{'Section'} ne $section);
1136
$self->get('Current Database')->set_package($pkg) if $change;
1139
# Now that we only have the latest source version, build the list
1140
# of binary packages from the Sources point of view
1141
foreach $name (keys %pkgs) {
1142
foreach my $bin (split( /\s*,\s*/, $pkgs{$name}{'bin'} ) ) {
1143
$self->get('Merge Bin Src')->{$bin} = $name;
1146
# remove installed packages that no longer have source available
1147
# or binaries installed
1148
foreach $name ($self->get('Current Database')->list_packages()) {
1149
my $pkg = $self->get('Current Database')->get_package($name);
1150
if (not defined($pkgs{$name})) {
1151
$self->change_state( $pkg, 'deleted' );
1152
$self->log_ta( $pkg, "--merge-sources" );
1153
print "$name ($pkg->{'Version'}): ".
1154
"deleted from database, because ".
1155
"not in Sources anymore\n"
1156
if $self->get_conf('VERBOSE');
1157
$self->get('Current Database')->del_package($name);
1159
next if !isin( $pkg->{'State'}, qw(Installed) );
1160
if ($full && not defined $self->get('Merge Src Version')->{$name}) {
1161
$self->change_state( $pkg, 'deleted' );
1162
$self->log_ta( $pkg, "--merge-sources" );
1163
print "$name ($pkg->{'Version'}): ".
1164
"deleted from database, because ".
1165
"binaries don't exist anymore\n"
1166
if $self->get_conf('VERBOSE');
1167
$self->get('Current Database')->del_package($name);
1168
} elsif ($full && version_less( $self->get('Merge Src Version')->{$name}, $pkg->{'Version'})) {
1169
print "$name ($pkg->{'Version'}): ".
1170
"package is Installed but binaries are from ".
1171
$self->get('Merge Src Version')->{$name}. "\n"
1172
if $self->get_conf('VERBOSE');
1179
# This function looks through a Packages file and sets the state of
1180
# packages to 'Installed'
1181
sub parse_packages {
1186
local($/) = ""; # read in paragraph mode
1188
my( $name, $version, $depends, $source, $sourcev, $architecture, $provides, $binaryv, $binnmu );
1190
/^Package:\s*(\S+)$/mi and $name = $1;
1191
/^Version:\s*(\S+)$/mi and $version = $1;
1192
/^Depends:\s*(.*)$/mi and $depends = $1;
1193
/^Source:\s*(\S+)(\s*\((\S+)\))?$/mi and ($source,$sourcev) = ($1, $3);
1194
/^Architecture:\s*(\S+)$/mi and $architecture = $1;
1195
/^Provides:\s*(.*)$/mi and $provides = $1;
1197
next if !$name || !$version;
1198
next if ($self->get_conf('ARCH') ne $architecture and $architecture ne "all");
1199
next if (defined ($installed->{$name}) and $installed->{$name}{'Version'} ne "" and
1200
version_lesseq( $version, $installed->{$name}{'Version'} ));
1201
$installed->{$name}{'Version'} = $version;
1202
$installed->{$name}{'Depends'} = $depends;
1203
$installed->{$name}{'all'} = 1 if $architecture eq "all";
1204
undef $installed->{$name}{'Provider'};
1205
$installed->{$name}{'Source'} = $source ? $source : $name;
1208
foreach (split( /\s*,\s*/, $provides )) {
1209
if (not defined ($installed->{$_})) {
1210
$installed->{$_}{'Version'} = "";
1211
$installed->{$_}{'Provider'} = $name;
1215
if ( $version =~ /\+b(\d+)$/ ) {
1218
$version = $sourcev if $sourcev;
1219
$binaryv = $version;
1220
$binaryv =~ s/\+b\d+$//;
1221
$installed->{$name}{'Sourcev'} = $sourcev ? $sourcev : $binaryv;
1222
$binaryv .= "+b$binnmu" if defined($binnmu);
1224
next if $architecture ne $self->get_conf('ARCH');
1225
$name = $source if $source;
1226
next if defined($self->get('Merge Src Version')->{$name}) and $self->get('Merge Src Version')->{$name} eq $version;
1228
$self->get('Merge Src Version')->{$name} = $version;
1230
my $pkg = $self->get('Current Database')->get_package($name);
1233
if (isin( $pkg->{'State'}, qw(Not-For-Us)) ||
1234
(isin($pkg->{'State'}, qw(Installed)) &&
1235
version_lesseq($binaryv, $pkg->{'Installed-Version'}))) {
1236
print "Skipping $name because State == $pkg->{'State'}\n"
1237
if $self->get_conf('VERBOSE') >= 2;
1240
if ($pkg->{'Binary-NMU-Version'} ) {
1241
my $nmuver = binNMU_version($pkg->{'Version'}, $pkg->{'Binary-NMU-Version'});
1242
if (version_less( $binaryv, $nmuver )) {
1243
print "Skipping $name ($version) because have newer ".
1244
"version ($nmuver) in db.\n"
1245
if $self->get_conf('VERBOSE') >= 2;
1248
} elsif (version_less($version, $pkg->{'Version'})) {
1249
print "Skipping $name ($version) because have newer ".
1250
"version ($pkg->{'Version'}) in db.\n"
1251
if $self->get_conf('VERBOSE') >= 2;
1255
if (!$self->pkg_version_eq($pkg, $version) &&
1256
$pkg->{'State'} ne "Installed") {
1257
warn "Warning: $name: newer version than expected appeared ".
1258
"in archive ($version vs. $pkg->{'Version'})\n";
1259
delete $pkg->{'Builder'};
1262
if (!isin( $pkg->{'State'}, qw(Uploaded) )) {
1263
warn "Warning: Package $name was not in uploaded state ".
1264
"before (but in '$pkg->{'State'}').\n";
1265
delete $pkg->{'Builder'};
1266
delete $pkg->{'Depends'};
1270
$pkg->{'Version'} = $version;
1273
$self->change_state( $pkg, 'Installed' );
1274
$pkg->{'Package'} = $name;
1275
$pkg->{'Installed-Version'} = $binaryv;
1276
if (defined $pkg->{'PermBuildPri'}) {
1277
$pkg->{'BuildPri'} = $pkg->{'PermBuildPri'};
1279
delete $pkg->{'BuildPri'};
1281
$pkg->{'Version'} = $version
1282
if version_less( $pkg->{'Version'}, $version);
1283
delete $pkg->{'Binary-NMU-Version'};
1284
delete $pkg->{'Binary-NMU-Changelog'};
1285
$self->log_ta( $pkg, "--merge-packages" );
1286
$self->get('Current Database')->set_package($pkg);
1287
print "$name ($version) is up-to-date now.\n" if $self->get_conf('VERBOSE');
1290
$self->check_dep_wait( "--merge-packages", $installed );
1297
my ($package, $name, $version, $installed);
1299
foreach $package (@_) {
1300
$package =~ s,^.*/,,; # strip path
1301
$package =~ s/\.(dsc|diff\.gz|tar\.gz|deb)$//; # strip extension
1302
$package =~ s/_[\w\d]+\.changes$//; # strip extension
1303
if ($package =~ /^([\w\d.+-]+)_([\w\d:.+~-]+)/) {
1304
($name,$version) = ($1,$2);
1307
warn "$package: can't extract package name and version ".
1311
$installed->{$name}{'Version'} = $version;
1314
$self->check_dep_wait( "--pretend-avail", $installed );
1317
sub check_dep_wait {
1320
my $installed = shift;
1322
# check all packages in state Dep-Wait if dependencies are all
1325
foreach $name ($self->get('Current Database')->list_packages()) {
1326
my $pkg = $self->get('Current Database')->get_package($name);
1327
next if $pkg->{'State'} ne "Dep-Wait";
1328
my $deps = $pkg->{'Depends'};
1330
print "$name: was in state Dep-Wait, but with empty ",
1332
goto make_needs_build;
1334
my $deplist = $self->parse_deplist($deps, 0);
1338
foreach (keys %$deplist) {
1339
if (!exists $installed->{$_} ||
1340
($deplist->{$_}->{'Rel'} && $deplist->{$_}->{'Version'} &&
1341
!version_compare( $installed->{$_}{'Version'},
1342
$deplist->{$_}->{'Rel'},
1343
$deplist->{$_}->{'Version'}))) {
1345
$new_deplist->{$_} = $deplist->{$_};
1348
push( @removed_deps, $_ );
1353
$self->change_state( $pkg, 'Needs-Build' );
1354
$self->log_ta( $pkg, $action );
1355
delete $pkg->{'Builder'};
1356
delete $pkg->{'Depends'};
1357
print "$name ($pkg->{'Version'}) has all ",
1358
"dependencies available now\n" if $self->get_conf('VERBOSE');
1359
$self->get('New Version')->{$name}++;
1360
$self->get('Current Database')->set_package($pkg);
1362
elsif (@removed_deps) {
1363
$pkg->{'Depends'} = $self->build_deplist( $new_deplist );
1364
print "$name ($pkg->{'Version'}): some dependencies ",
1365
"(@removed_deps) available now, but not all yet\n"
1366
if $self->get_conf('VERBOSE');
1367
$self->get('Current Database')->set_package($pkg);
1372
# This function accepts quinn-diff output (either from a file named on
1373
# the command line, or on stdin) and sets the packages named there to
1374
# state 'Needs-Build'.
1375
sub parse_quinn_diff {
1377
my $partial = shift;
1384
next if !m,^([-\w\d/]*)/ # section
1385
([-\w\d.+]+)_ # package name
1386
([\w\d:.~+-]+)\.dsc\s* # version
1387
\[([^:]*): # priority
1388
([^]]+)\]\s*$,x; # rest of notes
1389
my($section,$name,$version,$priority,$notes) = ($1, $2, $3, $4, $5);
1390
$quinn_pkgs{$name}++;
1391
$section ||= "unknown";
1392
$priority ||= "unknown";
1393
$priority = "unknown" if $priority eq "-";
1394
$priority = "standard" if ($name eq "debian-installer");
1396
my $pkg = $self->get('Current Database')->get_package($name);
1398
# Always update section and priority.
1399
if (defined($pkg)) {
1401
$pkg->{'Section'} = $section, $change++ if not defined
1402
$pkg->{'Section'} or $section ne "unknown";
1403
$pkg->{'Priority'} = $priority, $change++ if not defined
1404
$pkg->{'Priority'} or $priority ne "unknown";
1407
if (defined($pkg) &&
1408
$pkg->{'State'} =~ /^Dep-Wait/ &&
1409
version_less( $pkg->{'Version'}, $version )) {
1410
$self->change_state( $pkg, 'Dep-Wait' );
1411
$pkg->{'Version'} = $version;
1412
delete $pkg->{'Binary-NMU-Version'};
1413
delete $pkg->{'Binary-NMU-Changelog'};
1414
$self->log_ta( $pkg, "--merge-quinn" );
1416
print "$name ($version) still waiting for dependencies.\n"
1417
if $self->get_conf('VERBOSE');
1419
elsif (defined($pkg) &&
1420
$pkg->{'State'} =~ /-Removed$/ &&
1421
version_eq($pkg->{'Version'}, $version)) {
1422
# reinstantiate a package that has been removed earlier
1423
# (probably due to a quinn-diff malfunction...)
1424
my $newstate = $pkg->{'State'};
1425
$newstate =~ s/-Removed$//;
1426
$self->change_state( $pkg, $newstate );
1427
$pkg->{'Version'} = $version;
1428
$pkg->{'Notes'} = $notes;
1429
$self->log_ta( $pkg, "--merge-quinn" );
1431
print "$name ($version) reinstantiated to $newstate.\n"
1432
if $self->get_conf('VERBOSE');
1434
elsif (defined($pkg) &&
1435
$pkg->{'State'} eq "Not-For-Us" &&
1436
version_less( $pkg->{'Version'}, $version )) {
1437
# for Not-For-Us packages just update the version etc., but
1439
$self->change_state( $pkg, "Not-For-Us" );
1440
$pkg->{'Package'} = $name;
1441
$pkg->{'Version'} = $version;
1442
$pkg->{'Notes'} = $notes;
1443
delete $pkg->{'Builder'};
1444
$self->log_ta( $pkg, "--merge-quinn" );
1446
print "$name ($version) still Not-For-Us.\n" if $self->get_conf('VERBOSE');
1448
elsif (!defined($pkg) ||
1449
$pkg->{'State'} ne "Not-For-Us" &&
1450
(version_less( $pkg->{'Version'}, $version ) ||
1451
($pkg->{'State'} eq "Installed" && version_less($pkg->{'Installed-Version'}, $version)))) {
1452
if (defined( $pkg->{'State'} ) &&
1453
isin($pkg->{'State'}, qw(Building Built Build-Attempted))) {
1456
"new version of $name (dist=" . $self->get_conf('DISTRIBUTION') . ")",
1457
"As far as I'm informed, you're currently ".
1458
"building the package $name\n".
1459
"in version $pkg->{'Version'}.\n\n".
1460
"Now there's a new source version $version. ".
1461
"If you haven't finished\n".
1462
"compiling $name yet, you can stop it to ".
1463
"save some work.\n".
1464
"Just to inform you...\n".
1465
"(This is an automated message)\n");
1466
print "$name: new version ($version) while building ".
1467
"$pkg->{'Version'} -- sending mail ".
1468
"to builder ($pkg->{'Builder'})\n"
1469
if $self->get_conf('VERBOSE');
1471
$self->change_state( $pkg, 'Needs-Build' );
1472
$pkg->{'Package'} = $name;
1473
$pkg->{'Version'} = $version;
1474
$pkg->{'Section'} = $section;
1475
$pkg->{'Priority'} = $priority;
1476
$pkg->{'Notes'} = $notes;
1477
delete $pkg->{'Builder'};
1478
delete $pkg->{'Binary-NMU-Version'};
1479
delete $pkg->{'Binary-NMU-Changelog'};
1480
$self->log_ta( $pkg, "--merge-quinn" );
1481
$self->get('New Version')->{$name}++;
1483
print "$name ($version) needs rebuilding now.\n" if $self->get_conf('VERBOSE');
1485
elsif (defined($pkg) &&
1486
!version_eq( $pkg->{'Version'}, $version ) &&
1487
isin( $pkg->{'State'}, qw(Installed Not-For-Us) )) {
1488
print "$name: skipping because version in db ".
1489
"($pkg->{'Version'}) is >> than ".
1490
"what quinn-diff says ($version) ".
1491
"(state is $pkg->{'State'})\n"
1492
if $self->get_conf('VERBOSE');
1493
$dubious .= "$pkg->{'State'}: ".
1494
"db ${name}_$pkg->{'Version'} >> ".
1495
"quinn $version\n" if !$partial;
1497
elsif ($self->get_conf('VERBOSE') >= 2) {
1498
if ($pkg->{'State'} eq "Not-For-Us") {
1499
print "Skipping $name because State == ".
1500
"$pkg->{'State'}\n";
1502
elsif (!version_less($pkg->{'Version'}, $version)) {
1503
print "Skipping $name because version in db ".
1504
"($pkg->{'Version'}) is >= than ".
1505
"what quinn-diff says ($version)\n";
1508
$self->get('Current Database')->set_package($pkg) if $change;
1513
$self->get_conf('DB_MAINTAINER_EMAIL'),
1514
"Dubious versions in " . $self->get_conf('DISTRIBUTION') . " " .
1515
$self->get_conf('DB_BASE_NAME') . " database",
1516
"The following packages have a newer version in the ".
1517
"wanna-build database\n".
1518
"than what quinn-diff says, and this is strange for ".
1520
"It could be caused by a lame mirror, or the version ".
1521
"in the database\n".
1526
# Now re-check the DB for packages in states Needs-Build, Failed,
1527
# or Dep-Wait and remove them if they're not listed anymore by quinn-diff.
1530
foreach $name ($self->get('Current Database')->list_packages()) {
1531
my $pkg = $self->get('Current Database')->get_package($name);
1532
next if defined $pkg->{'Binary-NMU-Version'};
1533
next if !isin($pkg->{'State'},
1534
qw(Needs-Build Building Built
1535
Build-Attempted Uploaded Failed
1537
my $virtual_delete = $pkg->{'State'} eq 'Failed';
1539
if (!$quinn_pkgs{$name}) {
1540
$self->change_state( $pkg, $virtual_delete ?
1541
$pkg->{'State'}."-Removed" :
1543
$self->log_ta( $pkg, "--merge-quinn" );
1544
print "$name ($pkg->{'Version'}): ".
1545
($virtual_delete ? "(virtually) " : "") . "deleted ".
1546
"from database, because not in quinn-diff anymore\n"
1547
if $self->get_conf('VERBOSE');
1548
if ($virtual_delete) {
1549
$self->get('Current Database')->set_package($pkg);
1551
$self->get('Current Database')->set_package($name);
1559
sub send_reupload_mail {
1563
my $version = shift;
1565
my $other_dist = shift;
1569
"Please reupload ${pkg}_${'Version'} for $dist",
1570
"You have recently built (or are currently building)\n".
1571
"${pkg}_${'Version'} for $other_dist.\n".
1572
"This version is now also needed in the $dist distribution.\n".
1573
"Please reupload the files now present in the Debian archive\n".
1574
"(best with buildd-reupload).\n");
1577
sub sort_list_func {
1580
my $sortfunc = sub {
1583
foreach $letter (split( "", $self->get_conf('DB_LIST_ORDER') )) {
1584
SWITCH: foreach ($letter) {
1586
my $ap = $a->{'BuildPri'};
1587
my $bp = $b->{'BuildPri'};
1588
$ap = 0 if !defined($ap);
1589
$bp = 0 if !defined($bp);
1591
return $x if $x != 0;
1595
$x = $self->get('Priority Values')->{$a->{'Priority'}} <=> $self->get('Priority Values')->{$b->{'Priority'}};
1596
return $x if $x != 0;
1600
$self->get('Section Values')->{$a->{'Section'}} = -125 if(!$self->get('Section Values')->{$a->{'Section'}});
1601
$self->get('Section Values')->{$b->{'Section'}} = -125 if(!$self->get('Section Values')->{$b->{'Section'}});
1602
$x = $self->get('Section Values')->{$a->{'Section'}} <=> $self->get('Section Values')->{$b->{'Section'}};
1603
return $x if $x != 0;
1607
$x = $a->{'Package'} cmp $b->{'Package'};
1608
return $x if $x != 0;
1612
my $ab = $a->{'Builder'};
1613
my $bb = $b->{'Builder'};
1614
$ab = "" if !defined($ab);
1615
$bb = "" if !defined($bb);
1617
return $x if $x != 0;
1623
if (defined($a->{'Notes'})) {
1624
$ax = ($a->{'Notes'} =~ /^(out-of-date|partial)/) ? 0 :
1625
($a->{'Notes'} =~ /^uncompiled/) ? 2 : 1;
1627
if (defined($b->{'Notes'})) {
1628
$bx = ($b->{'Notes'} =~ /^(out-of-date|partial)/) ? 0 :
1629
($b->{'Notes'} =~ /^uncompiled/) ? 2 : 1;
1632
return $x if $x != 0;
1636
my $ca = exists $a->{'Failed-Category'} ?
1637
$a->{'Failed-Category'} : "none";
1638
my $cb = exists $b->{'Failed-Category'} ?
1639
$b->{'Failed-Category'} : "none";
1640
$x = $self->get('Category Values')->{$ca} <=> $self->get('Category Values')->{$cb};
1641
return $x if $x != 0;
1645
my $pa = $self->get('Priority Values')->{$a->{'Priority'}} >
1646
$self->get('Priority Values')->{'standard'};
1647
my $pb = $self->get('Priority Values')->{$b->{'Priority'}} >
1648
$self->get('Priority Values')->{'standard'};
1650
return $x if $x != 0;
1654
my $x = $self->get('Current Time') - $self->parse_date($a->{'State-Change'}) <=>
1655
$self->get('Current Time') - $self->parse_date($b->{'State-Change'});
1656
return $x if $x != 0;
1671
my( $name, $pkg, @list );
1674
my $user = $self->get_conf('DB_USER');
1676
foreach $name ($self->get('Current Database')->list_packages()) {
1677
$pkg = $self->get('Current Database')->get_package($name);
1678
next if $state ne "all" && $pkg->{'State'} !~ /^\Q$state\E$/i;
1679
next if $user && (lc($state) ne 'needs-build' &&
1680
defined($pkg->{'Builder'}) &&
1681
$pkg->{'Builder'} ne $self->get_conf('DB_USER'));
1682
next if $self->get_conf('DB_CATEGORY') && $pkg->{'State'} eq "Failed" &&
1683
$pkg->{'Failed-Category'} ne $self->get_conf('DB_CATEGORY');
1684
next if ($self->get_conf('DB_LIST_MIN_AGE') > 0 &&
1685
($self->get('Current Time') - $self->parse_date($pkg->{'State-Change'})) < $self->get_conf('DB_LIST_MIN_AGE'))||
1686
($self->get_conf('DB_LIST_MIN_AGE') < 0 &&
1687
($self->get('Current Time') - $self->parse_date($pkg->{'State-Change'})) > -$self->get_conf('DB_LIST_MIN_AGE'));
1688
push( @list, $pkg );
1691
my $sortfunc = $self->sort_list_func();
1692
foreach $pkg (sort $sortfunc @list) {
1693
print "$pkg->{'Section'}/$pkg->{'Package'}_$pkg->{'Version'}";
1694
print ": $pkg->{'State'}"
1696
print " by $pkg->{'Builder'}"
1697
if $pkg->{'State'} ne "Needs-Build" && $pkg->{'Builder'};
1698
print " [$pkg->{'Priority'}:";
1699
print "$pkg->{'Notes'}"
1700
if defined($pkg->{'Notes'});
1701
print ":PREV-FAILED"
1702
if defined($pkg->{'Previous-State'}) &&
1703
$pkg->{'Previous-State'} =~ /^Failed/;
1704
print ":bp{" . $pkg->{'BuildPri'} . "}"
1705
if exists $pkg->{'BuildPri'};
1706
print ":binNMU{" . $pkg->{'Binary-NMU-Version'} . "}"
1707
if exists $pkg->{'Binary-NMU-Version'};
1709
print " Reasons for failing:\n",
1711
exists $pkg->{'Failed-Category'} ? $pkg->{'Failed-Category'} : "none",
1713
join("\n ",split("\n",$pkg->{'Failed'})), "\n"
1714
if $pkg->{'State'} =~ /^Failed/;
1715
print " Dependencies: $pkg->{'Depends'}\n"
1716
if $pkg->{'State'} eq "Dep-Wait" &&
1717
defined $pkg->{'Depends'};
1718
print " Previous state was $pkg->{'Previous-State'} until ",
1719
"$pkg->{'State-Change'}\n"
1720
if $self->get_conf('VERBOSE') && $pkg->{'Previous-State'};
1721
print " Previous failing reasons:\n ",
1722
join("\n ",split("\n",$pkg->{'Old-Failed'})), "\n"
1723
if $self->get_conf('VERBOSE') && $pkg->{'Old-Failed'};
1725
$scnt{$pkg->{'State'}}++ if $state eq "all";
1727
if ($state eq "all") {
1728
foreach (sort keys %scnt) {
1729
print "Total $scnt{$_} package(s) in state $_.\n";
1732
print "Total $cnt package(s)\n";
1738
my( $name, $pkg, $key, $dist );
1739
my @firstkeys = qw(Package Version Builder State Section Priority
1740
Installed-Version Previous-State State-Change);
1741
my @dists = $self->get_conf('DB_INFO_ALL_DISTS') ? keys %{$self->get_conf('DB_DISTRIBUTIONS')} : ($self->get_conf('DISTRIBUTION'));
1743
foreach $dist (@dists) {
1744
if ($dist ne $self->get_conf('DISTRIBUTION')) {
1745
if (!$self->open_db($dist)) {
1746
warn "Cannot open database for $dist!\n";
1747
@dists = grep { $_ ne $dist } @dists;
1752
foreach $name (@_) {
1753
$name =~ s/_.*$//; # strip version
1754
foreach $dist (@dists) {
1755
$self->set('Current Database', $self->get('Databases')->{$dist});
1756
my $pname = "$name" . ($self->get_conf('DB_INFO_ALL_DISTS') ? "($dist)" : "");
1758
$pkg = $self->get('Current Database')->get_package($name);
1759
if (!defined( $pkg )) {
1760
print "$pname: not registered\n";
1765
foreach $key (@firstkeys) {
1766
next if !exists $pkg->{$key};
1767
my $val = $pkg->{$key};
1769
$val = "\n$val" if isin( $key, qw(Failed Old-Failed));
1771
printf " %-20s: %s\n", $key, $val;
1773
foreach $key (sort keys %$pkg) {
1774
next if isin( $key, @firstkeys );
1775
my $val = $pkg->{$key};
1777
$val = "\n$val" if isin( $key, qw(Failed Old-Failed));
1779
printf " %-20s: %s\n", $key, $val;
1785
sub forget_packages {
1788
my( $name, $pkg, $key, $data );
1790
foreach $name (@_) {
1791
$name =~ s/_.*$//; # strip version
1792
$pkg = $self->get('Current Database')->get_package($name);
1793
if (!defined( $pkg )) {
1794
print "$name: not registered\n";
1799
foreach $key (sort keys %$pkg) {
1800
my $val = $pkg->{$key};
1803
$data .= sprintf " %-20s: %s\n", $key, $val;
1806
$self->get_conf('DB_MAINTAINER_EMAIL'),
1807
"$name deleted from DB " . $self->get_conf('DB_BASE_NAME'),
1808
"The package '$name' has been deleted from the database ".
1809
"by " . $self->get_conf('DB_USER') . ".\n\n".
1810
"Data registered about the deleted package:\n".
1812
if $self->get_conf('DB_MAINTAINER_EMAIL');
1813
$self->change_state( $pkg, 'deleted' );
1814
$self->log_ta( $pkg, "--forget" );
1815
$self->get('Current Database')->set_package($name);
1816
print "$name: deleted from database\n" if $self->get_conf('VERBOSE');
1825
foreach $name (@_) {
1826
if (!$self->get('Current Database')->del_user($name)) {
1827
print "$name: not registered\n";
1831
print "$name: deleted from database\n" if $self->get_conf('VERBOSE');
1835
sub create_maintlock {
1838
my $lockfile = $self->db_filename("maintenance") . ".lock";
1842
print "Creating maintenance lock\n" if $self->get_conf('VERBOSE') >= 2;
1844
if (!sysopen( F, $lockfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644 )){
1846
# lock file exists, wait
1847
goto repeat if !open( F, "<$lockfile" );
1850
if ($line !~ /^(\d+)\s+([\w\d.-]+)$/) {
1851
warn "Bad maintenance lock file contents -- still trying\n";
1854
my($pid, $usr) = ($1, $2);
1855
if (kill( 0, $pid ) == 0 && $! == ESRCH) {
1856
# process doesn't exist anymore, remove stale lock
1857
print "Removing stale lock file (pid $pid, user $usr)\n";
1858
unlink( $lockfile );
1861
warn "Maintenance lock already exists by $usr -- ".
1862
"please wait\n" if $try == 0;
1865
die "Lock still present after 120 * 60 seconds.\n";
1870
die "Can't create maintenance lock $lockfile: $!\n";
1872
F->print(getppid(), " " . $self->get_conf('USERNAME') . "\n");
1876
sub remove_maintlock {
1879
my $lockfile = $self->db_filename("maintenance") . ".lock";
1881
print "Removing maintenance lock\n" if $self->get_conf('VERBOSE') >= 2;
1885
sub waitfor_maintlock {
1888
my $lockfile = $self->db_filename("maintenance") . ".lock";
1892
print "Checking for maintenance lock\n" if $self->get_conf('VERBOSE') >= 2;
1894
if (open( F, "<$lockfile" )) {
1897
if ($line !~ /^(\d+)\s+([\w\d.-]+)$/) {
1898
warn "Bad maintenance lock file contents -- still trying\n";
1901
my($pid, $usr) = ($1, $2);
1902
if (kill( 0, $pid ) == 0 && $! == ESRCH) {
1903
# process doesn't exist anymore, remove stale lock
1904
print "Removing stale maintenance lock (pid $pid, user $usr)\n";
1905
unlink( $lockfile );
1908
warn "Databases locked for general maintenance by $usr -- ".
1909
"please wait\n" if $try == 0;
1912
die "Lock still present after 120 * 60 seconds.\n";
1922
my $newstate = shift;
1924
my $state = $pkg->{'State'};
1926
return if defined($state) and $state eq $newstate;
1927
$pkg->{'Previous-State'} = $state if defined($state);
1929
$pkg->{'State-Change'} = $self->get('Current Date');
1931
if (defined($state) and $state eq 'Failed') {
1932
$pkg->{'Old-Failed'} =
1933
"-"x20 . " $pkg->{'Version'} " . "-"x20 . "\n" .
1934
$pkg->{'Failed'} . "\n" .
1935
$pkg->{'Old-Failed'};
1936
delete $pkg->{'Failed'};
1937
delete $pkg->{'Failed-Category'};
1940
$pkg->{'State'} = $newstate;
1947
my $newdb = $self->get('Databases')->{$dist};
1949
if (!defined($newdb)) {
1950
if ($self->get_conf('DB_TYPE') eq 'mldbm') {
1951
$newdb = Sbuild::DB::MLDBM->new($self->get('Config'));
1952
} elsif ($self->get_conf('DB_TYPE') eq 'postgres') {
1953
$newdb = Sbuild::DB::Postgres->new($self->get('Config'));
1955
die "Unsupported database type '" . $self->get_conf('DB_TYPE') . "'\n";
1958
$newdb->open($self->db_filename($dist));
1961
$self->get('Databases')->{$dist} = $newdb;
1972
my $dist = $self->get_conf('DISTRIBUTION');
1974
my $prevstate = 'Unknown';
1976
$prevstate = $pkg->{'Previous-State'} if defined($pkg->{'Previous-State'});
1978
$str = "$action($dist): $pkg->{'Package'}_$pkg->{'Version'} ".
1979
"changed from $prevstate to $pkg->{'State'} ".
1980
"by " . $self->get_conf('USERNAME'). " as " . $self->get_conf('DB_USER') . ".";
1982
my $transactlog = $self->get_conf('DB_BASE_DIR') . "/$dist-" .
1983
$self->get_conf('DB_TRANSACTION_LOG');
1984
if (!open( LOG, ">>$transactlog" )) {
1985
warn "Can't open log file $transactlog: $!\n";
1988
print LOG $self->get('Current Date') . ": $str\n";
1991
if (!($prevstate eq 'Failed' && $pkg->{'State'} eq 'Failed')) {
1992
$str .= " (with --override)"
1993
if $self->get_conf('DB_OVERRIDE');
1994
$self->set('Mail Logs',
1995
$self->get('Mail Logs') . "$str\n");
2005
my $dist_order = $self->get_conf('DB_DISTRIBUTIONS');
2007
return $dist_order->{$d1}->{'priority'} <=> $dist_order->{$d2}->{'priority'};
2013
my $subject = shift;
2016
my $from = $self->get_conf('DB_MAINTAINER_EMAIL');
2017
my $domain = $self->get_conf('DB_MAIL_DOMAIN');
2019
if (defined($domain)) {
2020
$from .= "\@$domain" if $from !~ /\@/;
2021
$to .= '@$domain' if $to !~ /\@/;
2023
$from .= "\@" . $self->get_conf('HOSTNAME') if $from !~ /\@/;
2024
$to .= '@' . $self->get_conf('HOSTNAME') if $to !~ /\@/;
2027
$text =~ s/^\.$/../mg;
2028
local $SIG{'PIPE'} = 'IGNORE';
2029
open( PIPE, "| " . $self->get_conf('MAILPROG') . " -oem $to" )
2030
or die "Can't open pipe to " . $self->get_conf('MAILPROG') . ": $!\n";
2032
print PIPE "From: $from\n";
2033
print PIPE "Subject: $subject\n\n";
2034
print PIPE "$text\n";
2042
return $self->get_conf('DB_BASE_DIR') . '/' . $self->get_conf('DB_BASE_NAME') . "-$dist";
2045
# for parsing input to dep-wait
2052
foreach (split( /\s*,\s*/, $deps )) {
2054
# verification requires > starting prompts, no | crap
2055
if (!/^(\S+)\s*(\(\s*(>(?:[>=])?)\s*(\S+)\s*\))?\s*$/) {
2060
my @alts = split( /\s*\|\s*/, $_ );
2061
# Anything with an | is ignored, as it can be configured on a
2062
# per-buildd basis what will be installed
2063
next if $#alts != 0;
2066
if (!/^(\S+)\s*(\(\s*(>=|=|==|>|>>|<<|<=)\s*(\S+)\s*\))?\s*$/) {
2067
warn( "parse_deplist: bad dependency $_\n" );
2070
my($dep, $rel, $relv) = ($1, $3, $4);
2071
$rel = ">>" if defined($rel) and $rel eq ">";
2072
$result{$dep}->{'Package'} = $dep;
2073
if ($rel && $relv) {
2074
$result{$dep}->{'Rel'} = $rel;
2075
$result{$dep}->{'Version'} = $relv;
2078
return 1 if $verify;
2082
# for parsing Build-Depends from Sources
2083
sub parse_srcdeplist {
2092
foreach $dep (split( /\s*,\s*/, $deps )) {
2093
my @alts = split( /\s*\|\s*/, $dep );
2094
# Anything with an | is ignored, as it can be configured on a
2095
# per-buildd basis what will be installed
2096
next if $#alts != 0;
2098
if (!/^([^\s([]+)\s*(\(\s*([<=>]+)\s*(\S+)\s*\))?(\s*\[([^]]+)\])?/) {
2099
warn( "parse_srcdeplist: bad dependency $_\n" );
2102
my($dep, $rel, $relv, $archlist) = ($1, $3, $4, $6);
2104
$archlist =~ s/^\s*(.*)\s*$/$1/;
2105
my @archs = split( /\s+/, $archlist );
2106
my ($use_it, $ignore_it, $include) = (0, 0, 0);
2108
# Use 'dpkg-architecture' to support architecture
2111
$ignore_it = 1 if Dpkg::Arch::debarch_is($arch, substr($_, 1));
2113
$use_it = 1 if Dpkg::Arch::debarch_is($arch, $_);
2117
warn "Warning: inconsistent arch restriction on ",
2118
"$pkg: $dep depedency\n"
2119
if $ignore_it && $use_it;
2120
next if $ignore_it || ($include && !$use_it);
2128
$result->{'Package'} = $dep;
2129
$result->{'Neg'} = $neg;
2130
if ($rel && $relv) {
2131
$result->{'Rel'} = $rel;
2132
$result->{'Version'} = $relv;
2134
push @results, $result;
2146
foreach $key (keys %$list) {
2147
$result .= ", " if $result;
2149
$result .= " ($list->{$key}->{'Rel'} $list->{$key}->{'Version'})"
2150
if $list->{$key}->{'Rel'} && $list->{$key}->{'Version'};
2155
sub get_unsatisfied_dep {
2160
my $savedep = shift;
2162
my $pkgname = $dep->{'Package'};
2164
if (defined $pkgs->{$pkgname}{'Provider'}) {
2165
# provides. leave them for buildd/sbuild.
2170
return $pkgs->{$pkgname}{'Unsatisfied'} if $savedep and defined($pkgs->{$pkgname}{'Unsatisfied'});
2172
# Return unsatisfied deps to a higher caller to process
2173
if ((!defined($pkgs->{$pkgname})) or
2174
(defined($dep->{'Rel'}) and !version_compare( $pkgs->{$pkgname}{'Version'}, $dep->{'Rel'}, $dep->{'Version'} ) ) ) {
2176
$deplist{$pkgname} = $dep;
2177
my $deps = $self->build_deplist(\%deplist);
2178
$pkgs->{$pkgname}{'Unsatisfied'} = $deps if $savedep;
2182
# set cache to "" to avoid infinite recursion
2183
$pkgs->{$pkgname}{'Unsatisfied'} = "" if $savedep;
2185
if (defined $pkgs->{$dep->{'Package'}}{'Depends'}) {
2186
my $deps = $self->parse_deplist( $pkgs->{$dep->{'Package'}}{'Depends'} );
2187
foreach (keys %$deps) {
2190
my $ret = $self->get_unsatisfied_dep($bd,$pkgs,$dep,1);
2192
my $retdep = $self->parse_deplist( $ret );
2193
foreach (keys %$retdep) {
2194
$dep = $$retdep{$_};
2196
$dep->{'Rel'} = '>=' if defined($dep->{'Rel'}) and $dep->{'Rel'} =~ '^=';
2198
if (defined($dep->{'Rel'}) and $dep->{'Rel'} =~ '^>' and defined ($pkgs->{$dep->{'Package'}}) and
2199
version_compare($bd->{$pkgs->{$dep->{'Package'}}{'Source'}}{'ver'},'>>',$pkgs->{$dep->{'Package'}}{'Sourcev'})) {
2200
if (not defined($self->get('Merge Bin Src')->{$dep->{'Package'}})) {
2201
# the uninstallable package doesn't exist in the new source; look for something else that does.
2202
delete $$retdep{$dep->{'Package'}};
2203
foreach (sort (split( /\s*,\s*/, $bd->{$pkgs->{$dep->{'Package'}}{'Source'}}{'bin'}))) {
2204
next if ($pkgs->{$_}{'all'} or not defined $pkgs->{$_}{'Version'});
2205
$dep->{'Package'} = $_;
2206
$dep->{'Rel'} = '>>';
2207
$dep->{'Version'} = $pkgs->{$_}{'Version'};
2208
$$retdep{$_} = $dep;
2213
# sanity check to make sure the depending binary still exists, and the depended binary exists and dep-wait on a new version of it
2214
if ( defined($self->get('Merge Bin Src')->{$pkgname}) and defined($pkgs->{$dep->{'Package'}}{'Version'}) ) {
2215
delete $$retdep{$dep->{'Package'}};
2216
$dep->{'Package'} = $pkgname;
2217
$dep->{'Rel'} = '>>';
2218
$dep->{'Version'} = $pkgs->{$pkgname}{'Version'};
2219
$$retdep{$pkgname} = $dep;
2221
delete $$retdep{$dep->{'Package'}} if (defined ($dep->{'Rel'}) and $dep->{'Rel'} =~ '^>');
2224
$ret = $self->build_deplist($retdep);
2225
$pkgs->{$pkgname}{'Unsatisfied'} = $ret if $savedep;
2239
my $distribution = $self->get_conf('DISTRIBUTION');
2241
return if (defined ($self->get_conf('DB_DISTRIBUTIONS')->{'$distribution'}) &&
2242
defined ($self->get_conf('DB_DISTRIBUTIONS')->{'$distribution'}->{'noadw'}));
2244
# We need to walk all of needs-build, as any new upload could make
2245
# something in needs-build have uninstallable deps
2246
foreach $key ($self->get('Current Database')->list_packages()) {
2247
my $pkg = $self->get('Current Database')->get_package($key);
2249
if not defined $pkg or $pkg->{'State'} ne "Needs-Build";
2250
my $srcdeps = $self->parse_srcdeplist($key,$bd->{$key}{'dep'},
2251
$self->get_conf('ARCH'));
2252
foreach my $srcdep (@$srcdeps) {
2253
next if $srcdep->{'Neg'} != 0; # we ignore conflicts atm
2254
my $rc = $self->get_unsatisfied_dep($bd,$pkgs,$srcdep,0);
2257
my $deplist = $self->parse_deplist( $pkg->{'Depends'} );
2258
my $newdeps = $self->parse_deplist( $rc );
2260
foreach (%$newdeps) {
2261
my $dep = $$newdeps{$_};
2262
# ensure we're not waiting on ourselves, or a package that has been removed
2263
next if (not defined($self->get('Merge Bin Src')->{$dep->{'Package'}})) or ($self->get('Merge Bin Src')->{$dep->{'Package'}} eq $key);
2264
if ($dep->{'Rel'} =~ '^>') {
2265
$deplist->{$dep->{'Package'}} = $dep;
2270
$pkg->{'Depends'} = $self->build_deplist($deplist);
2271
$self->change_state( $pkg, 'Dep-Wait' );
2272
$self->log_ta( $pkg, "--merge-all" );
2273
$self->get('Current Database')->set_package($pkg);
2274
print "Auto-Dep-Waiting ${key}_$pkg->{'Version'} to $pkg->{'Depends'}\n" if $self->get_conf('VERBOSE');
2282
sub pkg_version_eq {
2285
my $version = shift;
2288
if (defined $pkg->{'Binary-NMU-Version'}) and
2289
version_compare(binNMU_version($pkg->{'Version'},
2290
$pkg->{'Binary-NMU-Version'}),'=', $version);
2291
return version_compare( $pkg->{'Version'}, "=", $version );