Mercurial > pub > Yours
view lib/Yours/Model/Repository.pm @ 5:45a84be3ebb1 default tip
added deltainfo (.drpm) packages support
author | sergey |
---|---|
date | Wed, 23 Oct 2013 16:24:52 +0400 |
parents | ae61af01bfa5 |
children |
line wrap: on
line source
package Yours::Model::Repository; use strict; use File::Spec(); use IMPL::Exception(); use IMPL::Const qw(:prop); use URI; use IMPL::declare { require => { MDParser => 'Yours::Parsers::MDParser', PMDParser => 'Yours::Parsers::PMDParser', DIMDParser => 'Yours::Parsers::DIMDParser', Uncompress => 'IO::Uncompress::AnyUncompress', IOException => '-IMPL::IOException', ArgException => '-IMPL::InvalidArgumentException', FileValidator => 'Yours::FileValidator' }, base => [ 'IMPL::Object' => undef, ], props => [ name => PROP_RW, localPath => PROP_RW, repoUrl => PROP_RW ] }; sub CTOR { my ( $this, $name, $localPath, $repoUrl ) = @_; die ArgException->new( name => "A name is required" ) unless $name; die ArgException->new( localPath => "A localPath is required" ) unless $localPath; die ArgException->new( repoUrl => "A repoUrl is required" ) unless $repoUrl; $this->repoUrl( URI->new($repoUrl) ); $this->localPath($localPath); $this->name($name); } sub GetMetadataFiles { my ($this) = @_; return { map { $this->GetLocalFile($_), { location => $this->GetRemoteLocation($_) } } ( 'repodata/repomd.xml', 'repodata/repomd.xml.asc', 'repodata/repomd.xml.key' ) }; } sub GetDescriptionFiles { my ($this) = @_; return { map { $this->GetLocalFile($_->{location}), { location => $this->GetRemoteLocation($_->{location}), checksum => $_->{checksum} } } @{$this->ReadMetadata()->{data} || []} }; } sub GetLocalFile { my ( $this, $url ) = @_; my @parts = split /\//, $url; return File::Spec->catfile( $this->localPath, @parts ); } sub GetRemoteLocation { my ( $this, $url ) = @_; return URI->new_abs( $url, $this->repoUrl ); } sub ReadMetadata { my ($this) = @_; my $mdFile = $this->GetLocalFile('repodata/repomd.xml'); die IOException->new( "File not found", $mdFile ) unless -f $mdFile; my $parser = MDParser->new(); $parser->Parse( { location => $mdFile, no_blanks => 1 } ); return $parser->data; } sub ProcessContent { my ( $this, $handler ) = @_; die ArgException->new(handler => 'A handler is required') unless $handler; my %index = map { $_->{type}, $_ } @{ $this->ReadMetadata()->{data} || [] }; my %parsers = ( primary => PMDParser, deltainfo => DIMDParser ); foreach my $db (qw(primary deltainfo)) { my $file = $index{$db}{location} or next; $file = $this->GetLocalFile( $file ); die IOException->new( "File not found", $file ) unless -f $file; my $hdata = Uncompress->new($file) or die IOException->new( "Failed to uncompress file", $file ); $parsers{$db}->new(sub { my ($meta) = shift; my $file = $this->GetLocalFile($meta->{location}); $meta->{location} = $this->GetRemoteLocation($meta->{location}); &$handler($file,$meta); })->Parse( { IO => $hdata, no_blanks => 1 } ); } } sub ValidateMetadata { my ($this) = @_; my $files = $this->GetMetadataFiles(); my $validator = FileValidator->new(); my @errors = $validator->Validate($files); return @errors if @errors; $files = $this->GetDescriptionFiles; return $validator->Validate($files); } sub ValidateContent { my ($this,$opts) = @_; $opts ||= {}; my %files; $this->ProcessContent(sub { my ($file,$md) = @_; return if $opts->{skipSrc} and $md->{arch} eq 'src'; return if $opts->{skipDebug} and $md->{name} =~ /debuginfo|debugsource/; $files{$file} = $md; }); return FileValidator->new()->Validate(\%files); } 1;