summaryrefslogtreecommitdiffstats
path: root/lib/App/ArchLinux/PackagerTools/Pacman.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/App/ArchLinux/PackagerTools/Pacman.pm')
-rw-r--r--lib/App/ArchLinux/PackagerTools/Pacman.pm126
1 files changed, 126 insertions, 0 deletions
diff --git a/lib/App/ArchLinux/PackagerTools/Pacman.pm b/lib/App/ArchLinux/PackagerTools/Pacman.pm
new file mode 100644
index 0000000..765746e
--- /dev/null
+++ b/lib/App/ArchLinux/PackagerTools/Pacman.pm
@@ -0,0 +1,126 @@
+package App::ArchLinux::PackagerTools::Pacman;
+use strictures;
+
+use autodie;
+use Function::Parameters;
+use Log::Any qw($log);
+
+=head1 NAME
+
+App::ArchLinux::PackagerTools::Pacman - Methods to interact with pacman
+
+=head1 SYNOPSIS
+
+ use App::ArchLinux::PackagerTools::Pacman;
+
+ # synopsis...
+
+=head1 DESCRIPTION
+
+This module allows to query pacman for a list of packages in the repository and
+extract a list of perl distributions that are part of the repository.
+
+
+=head1 METHODS
+
+=head2 Constructors
+
+=head3 new
+
+ App::ArchLinux::PackagerTools::Pacman->new();
+
+Returns a new instance.
+
+=cut
+
+
+method new($class: $deps = {}) {
+ $deps->{cpan} //= App::ArchLinux::PackagerTools::CPAN->new();
+ $deps->{pkgname_cpan_name_map} //= {
+ # pkgname => cpan_name
+ 'perl-critic' => 'Perl::Critic',
+ 'perl-libintl-perl' => 'libintl-perl',
+ };
+ return $class->new_no_defaults($deps);
+}
+
+method new_no_defaults($class: $deps = {}) {
+ my $self = {};
+ bless $self, $class;
+ $self->{deps} = $deps;
+ return $self;
+}
+
+=head2 Public Methods
+
+=head3 get_packages
+
+Returns an arrayref of package hashes. Each package hash contains at least the
+pkgname and pkgver keys.
+
+=cut
+
+method get_packages() {
+ my @packages;
+ open my $fh, '-|', 'expac -S \'%n %v\'';
+ my %seen;
+ while (<$fh>) {
+ if (m/^(?<pkgname>[^\s]+) (?<pkgver>.*)$/) {
+ push @packages, {%+};
+ }
+ }
+ return \@packages;
+}
+
+method get_perl_packages() {
+ my @packages = grep {$_->{pkgname} =~ /^perl-/} $self->get_packages->@*;
+ $log->debugf("Found %d perl packages", scalar(@packages));
+ return \@packages;
+}
+
+method get_perl_distributions() {
+ my @distributions;
+
+ for my $package ($self->get_perl_packages()->@*) {
+ my $cleaned_name = $package->{pkgname} =~ s/^perl-//r;
+ my $dist;
+ if (defined $self->{deps}->{pkgname_cpan_name_map}->{$package->{pkgname}}) {
+ $dist = $self->{deps}->{cpan}->get_dist($self->{deps}->{pkgname_cpan_name_map}->{$package->{pkgname}});
+ } else {
+ $dist = $self->{deps}->{cpan}->search_dist($cleaned_name);
+ }
+ push @distributions, $dist if defined $dist;
+ $log->warningf("Failed to find distribution for package '%s'", $package) if !defined $dist;
+ }
+ return \@distributions;
+}
+
+method get_package_version($pkgname) {
+ # TODO do not fork expac for each package here! works for now, but it's sloooow
+ my $version = `expac -S -1 '%v' -- '$pkgname'`;
+ chomp $version;
+ return $version;
+}
+
+method get_perl_pkgname($dist_name) {
+ my $pkgname = lc($dist_name);
+ $pkgname =~ s/::/-/g;
+ $pkgname = "perl-$pkgname";
+ return $pkgname;
+}
+
+method get_perl_distribution_version($dist_name) {
+ my $pkgname = $self->get_perl_pkgname($dist_name);
+ my $version = $self->get_package_version($pkgname);
+ # remove pkgrel
+ $version =~ s/-\d+(\.\d+)?$//;
+ # remove epoch
+ $version =~ s/^\d+://;
+
+ $log->tracef("Found version '%s' for package '%s'", $version, $pkgname);
+ return $version;
+}
+
+1;
+
+__END__