aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Youri/Check/Input/Conflicts.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Youri/Check/Input/Conflicts.pm')
-rw-r--r--lib/Youri/Check/Input/Conflicts.pm231
1 files changed, 231 insertions, 0 deletions
diff --git a/lib/Youri/Check/Input/Conflicts.pm b/lib/Youri/Check/Input/Conflicts.pm
new file mode 100644
index 0000000..88cb2f6
--- /dev/null
+++ b/lib/Youri/Check/Input/Conflicts.pm
@@ -0,0 +1,231 @@
+# $Id: Conflicts.pm 1179 2006-08-05 08:30:57Z warly $
+package Youri::Check::Input::Conflicts;
+
+=head1 NAME
+
+Youri::Check::Input::Conflicts - Check file conflicts
+
+=head1 DESCRIPTION
+
+This plugin checks packages files, and report conflict and duplications.
+
+=cut
+
+use warnings;
+use strict;
+use Carp;
+use constant;
+use Youri::Package;
+use base 'Youri::Check::Input';
+
+use constant TYPE_MASK => 0170000;
+use constant TYPE_DIR => 0040000;
+
+use constant PACKAGE => 0;
+use constant MODE => 1;
+use constant MD5SUM => 2;
+
+my $compatibility = {
+ x86_64 => 'i586',
+ i586 => 'x86_64',
+ sparc64 => 'sparc',
+ sparc => 'sparc64',
+ ppc64 => 'ppc',
+ ppc => 'ppc64'
+};
+
+sub columns {
+ return qw/
+ arch
+ file
+ error
+ level
+ /;
+}
+
+sub links {
+ return qw//;
+}
+
+=head2 new(%args)
+
+Creates and returns a new Youri::Check::Input::Conflicts object.
+
+No specific parameters.
+
+=cut
+
+sub prepare {
+ my ($self, @medias) = @_;
+ croak "Not a class method" unless ref $self;
+
+ my $index = sub {
+ my ($package) = @_;
+
+ # index files
+ foreach my $file ($package->get_files()) {
+ push(
+ @{$self->{_files}->{$file->[Youri::Package::FILE_NAME]}},
+ [ $package, $file->[Youri::Package::FILE_MODE], $file->[Youri::Package::FILE_MD5SUM] ]
+ );
+ }
+ };
+
+ foreach my $media (@medias) {
+ # don't index source media files
+ next unless $media->get_type() eq 'binary';
+
+ my $media_id = $media->get_id();
+ $self->{_medias}->{$media_id} = 1;
+ print STDERR "Indexing media $media_id files\n"
+ if $self->{_verbose};
+
+ $media->traverse_headers($index);
+ }
+}
+
+sub run {
+ my ($self, $media, $result) = @_;
+ croak "Not a class method" unless ref $self;
+
+ # this is a binary media check only
+ return unless $media->get_type() eq 'binary';
+
+ my $check = sub {
+ my ($package) = @_;
+
+ return if $package->get_arch() eq 'src';
+
+ my $arch = $package->get_arch();
+ my $name = $package->get_name();
+
+ foreach my $file ($package->get_files()) {
+
+ my $found =
+ $self->{_files}->{$file->[Youri::Package::FILE_NAME]};
+
+ my @found = $found ? @$found : ();
+
+ foreach my $found (@found) {
+ next if $found->[PACKAGE] == $package;
+ next unless compatible($found->[PACKAGE], $package);
+ next if conflict($found->[PACKAGE], $package);
+ next if replace($found->[PACKAGE], $package);
+ if (
+ ($file->[Youri::Package::FILE_MODE] & TYPE_MASK) == TYPE_DIR &&
+ ($found->[MODE] & TYPE_MASK) == TYPE_DIR
+ ) {
+ $result->add_result($self->{_id}, $media, $package, {
+ arch => $arch,
+ file => $name,
+ error => "directory $file->[Youri::Package::FILE_NAME] duplicated with package " . $found->[PACKAGE]->get_name(),
+ level => Youri::Check::Input::WARNING
+ }) unless $self->_directory_duplicate_exception(
+ $package,
+ $found->[PACKAGE],
+ $file
+ );
+ } else {
+ if ($found->[MD5SUM] eq $file->[Youri::Package::FILE_MD5SUM]) {
+ $result->add_result($self->{_id}, $media, $package, {
+ arch => $arch,
+ file => $name,
+ error => "file $file->[Youri::Package::FILE_NAME] duplicated with package " . $found->[PACKAGE]->get_name(),
+ level => Youri::Check::Input::WARNING
+ }) unless $self->_file_duplicate_exception(
+ $package,
+ $found->[PACKAGE],
+ $file
+ );
+ } else {
+ $result->add_result($self->{_id}, $media, $package, {
+ arch => $arch,
+ file => $name,
+ error => "non-explicit conflict on file $file->[Youri::Package::FILE_NAME] with package " . $found->[PACKAGE]->get_name(),
+ level => Youri::Check::Input::ERROR
+ }) unless $self->_file_conflict_exception(
+ $package,
+ $found->[PACKAGE],
+ $file
+ );
+ }
+ }
+ }
+ }
+ };
+
+ $media->traverse_headers($check);
+}
+
+# return true if $package1 is arch-compatible with $package2
+sub compatible {
+ my ($package1, $package2) = @_;
+
+ my $arch1 = $package1->get_arch();
+ my $arch2 = $package2->get_arch();
+
+ return 1 if $arch1 eq $arch2;
+
+ return 1 if $compatibility->{$arch1} && $compatibility->{$arch1} eq $arch2;
+
+ return 0;
+}
+
+# return true if $package1 conflict with $package2
+# or the other way around
+sub conflict {
+ my ($package1, $package2) = @_;
+
+ my $name2 = $package2->get_name();
+
+ foreach my $conflict ($package1->get_conflicts()) {
+ return 1 if $conflict eq $name2;
+ }
+
+ my $name1 = $package1->get_name();
+
+ foreach my $conflict ($package2->get_conflicts()) {
+ return 1 if $conflict eq $name1;
+ }
+
+ return 0;
+}
+
+# return true if $package1 replace $package2
+sub replace {
+ my ($package1, $package2) = @_;
+
+
+ my $name1 = $package1->get_name();
+ my $name2 = $package2->get_name();
+
+ return 1 if $name1 eq $name2;
+
+ foreach my $obsolete ($package1->get_obsoletes()) {
+ return 1 if $obsolete->[Youri::Package::DEPENDENCY_NAME] eq $name2;
+ }
+
+ return 0;
+}
+
+sub _directory_duplicate_exception {
+ return 0;
+}
+
+sub _file_duplicate_exception {
+ return 0;
+}
+
+sub _file_conflict_exception {
+ return 0;
+}
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2002-2006, YOURI project
+
+This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
+
+=cut
+
+1;