File Coverage

lib/RPM/NEVRA.pm
Criterion Covered Total %
statement 36 36 100.0
branch 6 6 100.0
condition n/a
subroutine 6 6 100.0
pod 4 4 100.0
total 52 52 100.0


line stmt bran cond sub pod time code
1             package RPM::NEVRA;
2              
3 1     1   23528 use strict;
  1         2  
  1         22  
4 1     1   5 use warnings;
  1         1  
  1         456  
5              
6             =head1 NAME
7              
8             RPM::NEVRA - Parses, validates NEVRA format
9              
10             =head1 VERSION
11              
12             Version 0.0.5
13              
14             =cut
15              
16             our $VERSION = 'v0.0.5';
17              
18             =head1 SYNOPSIS
19              
20             NEVRA is the best format to describe an RPM with full details. The problem is, rpm's handling of epoch is different
21             from how repoquery handles epoch. rpm omits the epoch when undefined, whereas repoquery thinks epoch was insignificant.
22             This subtle difference leads to incomplete queries such as this:
23              
24             $ repoquery bind-9.10.2-2.P1.fc22.x86_64
25             bind-32:9.10.2-2.P1.fc22.x86_64
26              
27             In the above example, I had the bind package from rpm -qa, which omitted epoch because it was undefined. However, when
28             I feed it to repoquery, it gave me back with a package with epoch of 32. This was an ambiguous query and the solution
29             is to ALWAYS specify the epoch in repoquery queries.
30              
31             use RPM::NEVRA;
32              
33             my $obj = RPM::NEVRA->new();
34             my %info = $obj->parse_nevra('bind-32:9.10.2-2.P1.fc22.x86_64');
35             print $info{epoch}; # prints 32
36              
37             my ( $is_nevra, $missing ) = $obj->is_nevra('bind-9.10.2-2.P1.fc22.x86_64'); # returns ( 0, 'epoch' )
38             my $str = $obj->convert_to_nevra('bind-9.10.2-2.P1.fc22.x86_64'); # returns 'bind-0:9.10.2-2.P1.fc22.x86_64'
39              
40             =head1 SUBROUTINES/METHODS
41              
42             =head2 new
43              
44             Constructor, takes no argument.
45              
46             =cut
47              
48             sub new {
49 4     4 1 4287 my $class = shift;
50 4         12 return bless {}, $class;
51             }
52              
53             =head2 parse_nevra($str)
54              
55             Takes a string and returns a hash of name, epoch, ver, rel and arch.
56              
57             =cut
58              
59             sub parse_nevra {
60 6     6 1 551 my ( $self, $str ) = @_;
61              
62 6         19 my $arch = ( split( /\./, $str ) )[-1];
63 6         38 $str =~ s/\.$arch$//;
64              
65 6         13 my $rel = ( split( /-/, $str ) )[-1];
66 6         29 $str =~ s/-$rel$//;
67              
68 6         14 my $ver_str = ( split( /-/, $str ) )[-1];
69 6         10 my ( $epoch, $ver ) = split( /:/, $ver_str );
70 6         8 my $trimmer;
71              
72 6 100       12 if ( !defined($ver) ) { # no epoch
73 3         5 $ver = $epoch;
74 3         4 $epoch = undef;
75 3         4 $trimmer = $ver;
76             }
77             else {
78 3         6 $trimmer = "$epoch:$ver";
79             }
80 6         56 $str =~ s/-\Q$trimmer\E//;
81              
82 6         7 my %info;
83 6         19 @info{qw(name arch rel ver epoch)} = ( $str, $arch, $rel, $ver, $epoch );
84 6         38 return %info;
85             }
86              
87             =head2 is_nevra($str)
88              
89             Takes a string and returns (1, undef) if NEVRA, (0, $missing_field) otherwise
90              
91             =cut
92              
93             sub is_nevra {
94 2     2 1 410 my ( $self, $str ) = @_;
95 2         6 my %info = $self->parse_nevra($str);
96 2         7 for my $key ( keys %info ) {
97 6         9 my $val = $info{$key};
98 6 100       15 return ( 0, $key ) unless ( defined $val );
99             }
100 1         5 return ( 1, undef );
101             }
102              
103             =head2 convert_to_nevra($str)
104              
105             Takes a string, parses it and convert to nevra format.
106              
107             =cut
108              
109             sub convert_to_nevra {
110 2     2 1 6 my ( $self, $str ) = @_;
111 2         6 my %pieces = $self->parse_nevra($str);
112 2         6 my ( $name, $epoch, $ver, $rel, $arch ) = @pieces{qw(name epoch ver rel arch)};
113 2 100       6 $epoch = 0 if ( !$epoch );
114 2         14 return "$name-$epoch:$ver-$rel.$arch";
115             }
116              
117             =head1 AUTHOR
118              
119             Satoshi Yagi, C<< >>
120              
121             =head1 BUGS
122              
123             Please report any bugs or feature requests to C, or through
124             the web interface at L. I will be notified, and then you'll
125             automatically be notified of progress on your bug as I make changes.
126              
127              
128              
129              
130             =head1 SUPPORT
131              
132             You can find documentation for this module with the perldoc command.
133              
134             perldoc RPM::NEVRA
135              
136              
137             You can also look for information at:
138              
139             =over 4
140              
141             =item * RT: CPAN's request tracker (report bugs here)
142              
143             L
144              
145             =item * AnnoCPAN: Annotated CPAN documentation
146              
147             L
148              
149             =item * CPAN Ratings
150              
151             L
152              
153             =item * Search CPAN
154              
155             L
156              
157             =back
158              
159              
160             =head1 ACKNOWLEDGEMENTS
161              
162              
163             =head1 LICENSE AND COPYRIGHT
164              
165             Copyright 2015 Satoshi Yagi.
166              
167             This program is free software; you can redistribute it and/or modify it
168             under the terms of the the Artistic License (2.0). You may obtain a
169             copy of the full license at:
170              
171             L
172              
173             Any use, modification, and distribution of the Standard or Modified
174             Versions is governed by this Artistic License. By using, modifying or
175             distributing the Package, you accept this license. Do not use, modify,
176             or distribute the Package, if you do not accept this license.
177              
178             If your Modified Version has been derived from a Modified Version made
179             by someone other than you, you are nevertheless required to ensure that
180             your Modified Version complies with the requirements of this license.
181              
182             This license does not grant you the right to use any trademark, service
183             mark, tradename, or logo of the Copyright Holder.
184              
185             This license includes the non-exclusive, worldwide, free-of-charge
186             patent license to make, have made, use, offer to sell, sell, import and
187             otherwise transfer the Package with respect to any patent claims
188             licensable by the Copyright Holder that are necessarily infringed by the
189             Package. If you institute patent litigation (including a cross-claim or
190             counterclaim) against any party alleging that the Package constitutes
191             direct or contributory patent infringement, then this Artistic License
192             to you shall terminate on the date that such litigation is filed.
193              
194             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
195             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
196             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
197             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
198             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
199             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
200             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
201             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
202              
203              
204             =cut
205              
206             1; # End of RPM::NEVRA