Moose -> Moo
[Packaging-Tools.git] / lib / Packaging / Tools / Plugin / pkgsrc.pm
blob3db1771eb3c7ebdced423269ba9db4b4c27f5ce8
1 package Packaging::Tools::Plugin::pkgsrc;
3 use 5.008;
4 use strict;
5 use warnings;
7 use Carp qw(carp croak);
8 use Carp::Assert qw(affirm);
9 use Cwd qw();
10 use File::Basename qw();
11 use File::Spec qw();
12 use File::Find::Rule qw(find);
13 use File::pushd;
14 use IO::CaptureOutput qw(capture_exec);
16 # make it optional - with cache only ...
17 use DateTime;
18 use File::Find::Rule::Age;
20 use Moo;
21 use namespace::clean;
23 extends qw(Packaging::Tools::Plugin);
25 =head1 NAME
27 Packaging::Tools::Plugin::pkgsrc - Support tools packagers packaging Perl 5 modules
29 =cut
31 our $VERSION = '0.001';
33 =head1 SYNOPSIS
35 =head1 SUBROUTINES/METHODS
37 =cut
39 has 'make' => (
40 is => 'ro',
41 isa => 'Str',
42 required => 1
44 has 'pkg_info_cmd' => (
45 is => 'ro',
46 isa => 'Str',
47 required => 1
49 has 'pkgsrcdir' => (
50 is => 'ro',
51 isa => 'Str',
52 builder => '_find_pkgsrc_dir'
55 sub _find_pkgsrc_dir
57 defined( $ENV{PKGSRCDIR} ) and return $ENV{PKGSRCDIR};
59 my $self = $_[0];
60 foreach my $dir (qw(. .. ../.. /usr/pkgsrc))
62 -d $dir
63 and -f File::Spec->catfile( $dir, "mk", "bsd.pkg.mk" )
64 and return $self->{pkgsrcdir} = Cwd::abs_path($dir);
67 return;
70 sub _get_pkg_vars
72 my ( $self, $pkg_loc, @varnames ) = @_;
73 my $varnames = join( " ", @varnames );
74 my $last_dir = pushd($pkg_loc);
75 my ( $stdout, $stderr, $success, $exit_code ) =
76 capture_exec( $self->{MAKE}, "show-vars", "VARNAMES=$varnames" );
77 if ( $success and 0 == $exit_code )
79 chomp $stdout;
80 my @vals = split( "\n", $stdout );
81 return @vals;
84 die $stderr;
87 =head2 find_installed_packages
89 =cut
91 sub find_installed_packages
93 my $self = $_[0];
95 -x $self->pkg_info_cmd or croak( "Can't exec " . $self->pkg_info_cmd . ": $!" );
96 my ( $stdout, $stderr, $success, $exit_code ) = capture_exec( $self->pkg_info_cmd );
97 $success or croak( "Error running " . $self->pkg_info_cmd . ": $stderr" );
98 chomp $stdout;
99 my %havepkgs =
100 map { $_ =~ m/^(.*)-(v?[0-9].*?)$/ ? ( $1 => $2 ) : ( $_ => 0E0 ) }
101 map { ( split( m/\s+/, $_ ) )[0] } grep { 0 == index( $_, 'p5-' ) } split( "\n", $stdout );
103 return \%havepkgs;
106 =head2 _find_packaged_modules
108 =cut
110 sub _find_packaged_modules
112 my ( $self, $last_state ) = @_;
113 my $pkgsrc_base = $self->pkgsrcdir();
114 -d $pkgsrc_base or return; # XXX die?
115 my %age_args;
117 if ($last_state)
119 my $now = time();
120 my $duration = $now - $last_state;
121 %age_args = ( age => [ newer => "${duration}s" ] );
124 my @p5_pkg_dirs = find(
125 directory => name => "p5-*",
126 %age_args,
127 in => $pkgsrc_base
130 return map { $_ => $self->_fetch_full_pkg_details($_) } @p5_pkg_dirs;
133 =head2 _get_pkg_details
135 =cut
137 sub _get_pkg_details
139 my ( $self, $pkg_loc, @var_names ) = @_;
141 $self->_pkg_details->{$pkg_loc} //= $self->_fetch_full_pkg_details($pkg_loc);
143 return @{ $self->_pkg_details->{$pkg_loc} }{@var_names};
146 has '_pkg_var_names' => (
147 is => 'ro',
148 isa => 'ArrayRef[Str]',
149 default => sub {
150 return [
151 qw(DISTNAME DISTFILES EXTRACT_SUFX),
152 qw(PKGNAME PKGVERSION MAINTAINER),
153 qw(HOMEPAGE LICENSE MASTER_SITES)
156 auto_deref => 1,
157 init_arg => undef
160 sub _fetch_full_pkg_details
162 my ( $self, $pkg_loc ) = @_;
164 my (
165 $distname, $distfiles, $suffix, $pkgname, $pkgver,
166 $maintainer, $homepage, $license, $master_sites
167 ) = $self->_get_pkg_vars( $pkg_loc, $self->_pkg_var_names() );
169 my $distver;
170 if ( $distname =~ m/^(.*)-(v?[0-9].*?)$/ )
172 $distname = $1;
173 $distver = $2;
176 my $pkgsrcdir = $self->_find_pkgsrc_dir();
178 my %pkg_details;
179 $pkg_details{DIST_NAME} = $distname;
180 $pkg_details{DIST_VERSION} = $distver;
181 $pkg_details{DIST_FILE} = $distfiles;
182 $pkg_details{PKG_NAME} = $pkgname;
183 defined($pkgname) and defined($pkgver) and $pkg_details{PKG_NAME} =~ s/-$pkgver//;
184 $pkg_details{PKG_VERSION} = $pkgver;
185 $pkg_details{PKG_MAINTAINER} = $maintainer;
186 $pkg_details{PKG_INSTALLED} =
187 defined( $self->{installed_packages}->{ $pkg_details{PKG_NAME} } );
188 ( $pkg_details{PKG_LOCATION} = $pkg_loc ) =~ s|$pkgsrcdir/||;
189 $pkg_details{PKG_HOMEPAGE} = $homepage;
190 $pkg_details{PKG_LICENSE} = $license;
191 $pkg_details{PKG_MASTER_SITES} = $master_sites;
193 return \%pkg_details;
196 =head1 AUTHOR
198 Jens Rehsack, C<< <rehsack at cpan.org> >>
200 =cut
202 no Moo;
204 1; # End of Packaging::Tools::Plugin::pkgsrc