summaryrefslogtreecommitdiffstats
path: root/lib/Lintian/Changelog
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lintian/Changelog')
-rw-r--r--lib/Lintian/Changelog/Entry.pm184
-rw-r--r--lib/Lintian/Changelog/Version.pm250
2 files changed, 434 insertions, 0 deletions
diff --git a/lib/Lintian/Changelog/Entry.pm b/lib/Lintian/Changelog/Entry.pm
new file mode 100644
index 0000000..f36cb92
--- /dev/null
+++ b/lib/Lintian/Changelog/Entry.pm
@@ -0,0 +1,184 @@
+#
+# Lintian::Changelog::Entry
+#
+# Copyright (C) 2005 Frank Lichtenheld <frank@lichtenheld.de>
+# Copyright (C) 2019 Felix Lechner <felix.lechner@lease-up.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+package Lintian::Changelog::Entry;
+
+use v5.20;
+use warnings;
+use utf8;
+
+use Const::Fast;
+
+use Moo;
+use namespace::clean;
+
+const my $EMPTY => q{};
+const my $UNKNOWN => q{unknown};
+
+has Changes => (is => 'rw', default => $EMPTY);
+has Closes => (is => 'rw');
+has Date => (is => 'rw');
+has Distribution => (is => 'rw');
+has Header => (is => 'rw');
+#has Items => (is => 'rw', default => sub { [] });
+has Maintainer => (is => 'rw');
+has Source => (is => 'rw');
+has Timestamp => (is => 'rw');
+has Trailer => (is => 'rw');
+has Urgency => (is => 'rw', default => $UNKNOWN);
+has Urgency_LC => (is => 'rw', default => $UNKNOWN);
+has Urgency_Comment => (is => 'rw', default => $EMPTY);
+has Version => (is => 'rw');
+has ERROR => (is => 'rw');
+has position => (is => 'rw');
+
+=head1 NAME
+
+Lintian::Changelog::Entry - represents one entry in a Debian changelog
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+=head2 Methods
+
+=head3 init
+
+Creates a new object, no options.
+
+=head3 new
+
+Alias for init.
+
+=head3 is_empty
+
+Checks if the object is actually initialized with data. Due to limitations
+in Parse::DebianChangelog this currently simply checks if one of the
+fields Source, Version, Maintainer, Date, or Changes is initialized.
+
+=head2 Accessors
+
+The following fields are available via accessor functions (all
+fields are string values unless otherwise noted):
+
+=over 4
+
+=item Source
+
+=item Version
+
+=item Distribution
+
+=item Urgency
+
+=item Urgency_Comment
+
+=item C<Urgency_LC>
+
+=item C<ExtraFields>
+
+Extra_Fields (all fields except for urgency as hash; POD spelling forces the underscore)
+
+=item Header
+
+Header (the whole header in verbatim form)
+
+=item Changes
+
+Changes (the actual content of the bug report, in verbatim form)
+
+=item Trailer
+
+Trailer (the whole trailer in verbatim form)
+
+=item Closes
+
+Closes (Array of bug numbers)
+
+=item Maintainer
+
+=item C<MaintainerEmail>
+
+=item Date
+
+=item Timestamp
+
+Timestamp (Date expressed in seconds since the epoch)
+
+=item ERROR
+
+Last parse error related to this entry in the format described
+at Parse::DebianChangelog::get_parse_errors.
+
+=item position
+
+=back
+
+=begin Pod::Coverage
+
+Changes
+Closes
+Date
+Distribution
+Header
+Maintainer
+C<MaintainerEmail>
+Source
+Timestamp
+Trailer
+
+=end Pod::Coverage
+
+=cut
+
+sub is_empty {
+ my ($self) = @_;
+
+ return !(length $self->Changes
+ || length $self->Source
+ || length $self->Version
+ || length $self->Maintainer
+ || length $self->Date);
+}
+
+1;
+__END__
+
+=head1 SEE ALSO
+
+Originally based on Parse::DebianChangelog by Frank Lichtenheld, E<lt>frank@lichtenheld.deE<gt>
+
+=head1 AUTHOR
+
+Written by Felix Lechner <felix.lechner@lease-up.com> for Lintian in response to #933134.
+
+=head1 COPYRIGHT AND LICENSE
+
+Please see in the code; FSF's standard short text triggered a POD spelling error
+here.
+
+=cut
+
+# Local Variables:
+# indent-tabs-mode: nil
+# cperl-indent-level: 4
+# End:
+# vim: syntax=perl sw=4 sts=4 sr et
diff --git a/lib/Lintian/Changelog/Version.pm b/lib/Lintian/Changelog/Version.pm
new file mode 100644
index 0000000..d0e29f4
--- /dev/null
+++ b/lib/Lintian/Changelog/Version.pm
@@ -0,0 +1,250 @@
+# Copyright (C) 2019 Felix Lechner <felix.lechner@lease-up.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, you can find it on the World Wide
+# Web at https://www.gnu.org/copyleft/gpl.html, or write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+package Lintian::Changelog::Version;
+
+use v5.20;
+use warnings;
+use utf8;
+
+use Carp;
+use Const::Fast;
+use Unicode::UTF8 qw(encode_utf8);
+
+use Moo;
+use namespace::clean;
+
+const my $EMPTY => q{};
+
+=head1 NAME
+
+Lintian::Changelog::Version -- Parse a literal version string into its constituents
+
+=head1 SYNOPSIS
+
+ use Lintian::Changelog::Version;
+
+ my $version = Lintian::Changelog::Version->new;
+ $version->assign('1.2.3-4', undef);
+
+=head1 DESCRIPTION
+
+A class for parsing literal version strings
+
+=head1 CLASS METHODS
+
+=over 4
+
+=item new ()
+
+Creates a new Lintian::Changelog::Version object.
+
+=cut
+
+=back
+
+=head1 INSTANCE METHODS
+
+=over 4
+
+=item assign (LITERAL, NATIVE)
+
+Assign the various members in the Lintian::Changelog::Version object
+using the LITERAL version string and the NATIVE boolean selector.
+
+=cut
+
+sub assign {
+
+ my ($self, $literal, $native) = @_;
+
+ croak encode_utf8('Literal version string required for version parsing')
+ unless defined $literal;
+
+ croak encode_utf8('Native flag required for version parsing')
+ unless defined $native;
+
+ my $epoch_pattern = qr/([0-9]+)/;
+ my $upstream_pattern = qr/([A-Za-z0-9.+\-~]+?)/;
+ my $maintainer_revision_pattern = qr/([A-Za-z0-9.+~]+?)/;
+ my $source_nmu_pattern = qr/([A-Za-z0-9.+~]+)/;
+ my $bin_nmu_pattern = qr/([0-9]+)/;
+
+ my $source_pattern;
+
+ # these capture three matches each
+ $source_pattern
+ = qr/$upstream_pattern/
+ . qr/(?:-$maintainer_revision_pattern(?:\.$source_nmu_pattern)?)?/
+ if !$native;
+ $source_pattern
+ = qr/()/
+ . qr/$maintainer_revision_pattern/
+ . qr/(?:\+nmu$source_nmu_pattern)?/
+ if $native;
+
+ my $pattern
+ = qr/^/
+ . qr/(?:$epoch_pattern:)?/
+ . qr/$source_pattern/
+ . qr/(?:\+b$bin_nmu_pattern)?/. qr/$/;
+
+ my ($epoch, $upstream, $maintainer_revision, $source_nmu, $binary_nmu)
+ = ($literal =~ $pattern);
+
+ $epoch //= $EMPTY;
+ $upstream //= $EMPTY;
+ $maintainer_revision //= $EMPTY;
+ $source_nmu //= $EMPTY;
+ $binary_nmu //= $EMPTY;
+
+ my $source_nmu_string = $EMPTY;
+
+ $source_nmu_string = ($native ? "+nmu$source_nmu" : ".$source_nmu")
+ if length $source_nmu;
+
+ my $debian_source = $maintainer_revision . $source_nmu_string;
+
+ my $debian_no_epoch
+ = $debian_source . (length $binary_nmu ? "+b$binary_nmu" : $EMPTY);
+
+ my $upstream_string = (length $upstream ? "$upstream-" : $EMPTY);
+
+ my $no_epoch= $upstream_string . $debian_no_epoch;
+
+ my $epoch_string = (length $epoch ? "$epoch:" : $EMPTY);
+
+ my $reconstructed= $epoch_string . $no_epoch;
+
+ croak encode_utf8(
+ "Failed to parse package version: $reconstructed ne $literal")
+ unless $reconstructed eq $literal;
+
+ $self->literal($literal);
+ $self->epoch($epoch);
+ $self->no_epoch($no_epoch);
+ $self->upstream($upstream);
+ $self->maintainer_revision($maintainer_revision);
+ $self->debian_source($debian_source);
+ $self->debian_no_epoch($debian_no_epoch);
+ $self->source_nmu($source_nmu);
+ $self->binary_nmu($binary_nmu);
+
+ my $without_source_nmu
+ = $epoch_string . $upstream_string . $maintainer_revision;
+
+ $self->without_source_nmu($without_source_nmu);
+
+ my $backport_pattern = qr/^(.*)[+~]deb(\d+)u(\d+)$/;
+
+ my ($debian_without_backport, $backport_release, $backport_revision)
+ = ($self->maintainer_revision =~ $backport_pattern);
+
+ $debian_without_backport //= $maintainer_revision;
+ $backport_release //= $EMPTY;
+ $backport_revision //= $EMPTY;
+
+ $self->debian_without_backport($debian_without_backport);
+ $self->backport_release($backport_release);
+ $self->backport_revision($backport_revision);
+
+ my $without_backport
+ = $epoch_string . $upstream_string . $debian_without_backport;
+
+ $self->without_backport($without_backport);
+
+ return;
+}
+
+=item literal
+
+=item epoch
+
+=item no_epoch
+
+=item upstream
+
+=item maintainer_revision
+
+=item debian_source
+
+=item debian_no_epoch
+
+=item source_nmu
+
+=item binary_nmu
+
+=item without_source_nmu
+
+=item debian_without_backport
+
+=item backport_release
+
+=item backport_revision
+
+=item without_backport
+
+=cut
+
+has literal => (is => 'rw', default => $EMPTY);
+
+has epoch => (is => 'rw', default => $EMPTY);
+
+has no_epoch => (is => 'rw', default => $EMPTY);
+
+has upstream => (is => 'rw', default => $EMPTY);
+
+has maintainer_revision => (is => 'rw', default => $EMPTY);
+
+has debian_source => (is => 'rw', default => $EMPTY);
+
+has debian_no_epoch => (is => 'rw', default => $EMPTY);
+
+has source_nmu => (is => 'rw', default => $EMPTY);
+
+has binary_nmu => (is => 'rw', default => $EMPTY);
+
+has without_source_nmu => (is => 'rw', default => $EMPTY);
+
+has debian_without_backport => (is => 'rw', default => $EMPTY);
+
+has backport_release => (is => 'rw', default => $EMPTY);
+
+has backport_revision => (is => 'rw', default => $EMPTY);
+
+has without_backport => (is => 'rw', default => $EMPTY);
+
+=back
+
+=head1 AUTHOR
+
+Originally written by Felix Lechner <felix.lechner@lease-up.com> for Lintian.
+
+=head1 SEE ALSO
+
+lintian(1)
+
+=cut
+
+1;
+
+# Local Variables:
+# indent-tabs-mode: nil
+# cperl-indent-level: 4
+# End:
+# vim: syntax=perl sw=4 sts=4 sr et