App-cpan2arch
view release on metacpan or search on metacpan
lib/App/cpan2arch/WritePkgbuild.pm view on Meta::CPAN
use v5.42.0;
use strict;
use warnings;
no source::encoding; # Avoid dying on v5.42.0 (non-ASCII char in POD).
use Object::Pad 0.825;
package App::cpan2arch::WritePkgbuild; # For toolchain compatibility.
role App::cpan2arch::WritePkgbuild;
use open qw< :std :encoding(UTF-8) >;
use File::Basename qw< basename >;
use Scalar::Util qw< looks_like_number >;
use List::Util qw<
any
first
reduce
uniq
>;
$|++; # Disable STDOUT buffering.
our $VERSION = 'v1.1.2';
field $_install_license;
field %_generated_meta;
field %_pkgbuild :reader :writer;
# Generate the PKGBUILD bash script.
#
# References:
# https://wiki.archlinux.org/title/Perl_package_guidelines
method generate_pkgbuild ()
{
$self->_psub;
$self->_get_pkgbuild_vars;
my %opts = $self->opts;
my %meta = $self->meta;
my $mb = false;
# build()
my $build;
{
my %arch_prereqs = $self->arch_prereqs;
my @has_mb;
# Set the builder to use in PKGBUILD
# (Prefer M::B or M::B::T and use EU::MM as fallback)
if ( !$meta{has_module_install} ) {
@has_mb = grep { /\Aperl-module-build(?> -tiny)? (?> [<>=] | \z )/x } $arch_prereqs{makedepends}->@*;
$mb = true if scalar @has_mb;
}
$build = $mb
? <<~'END'
unset PERL_MB_OPT PERL5LIB PERL_LOCAL_LIB_ROOT
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null
/usr/bin/perl Build.PL --create_packlist=0
./Build
END
: <<~'END';
unset PERL_MM_OPT PERL5LIB PERL_LOCAL_LIB_ROOT
export PERL_MM_USE_DEFAULT=1
/usr/bin/perl Makefile.PL NO_PACKLIST=1 NO_PERLLOCAL=1
make
END
# Do not auto-install prereqs with Module::Install.
lib/App/cpan2arch/WritePkgbuild.pm view on Meta::CPAN
pkgdesc
url
install
changelog
>
);
my @NEEDED_VARS = (
qw<
pkgbase
pkgver
pkgrel
>
);
# References:
# https://wiki.archlinux.org/title/.SRCINFO
# https://man.archlinux.org/man/SRCINFO.5
# https://man.archlinux.org/man/alpm-pkgver.7
# https://man.archlinux.org/man/alpm-pkgrel.7
foreach my $line (@srcinfo) {
next if $line eq '';
my ( $key, $val ) = split / = /, $line;
next unless defined $val;
$key =~ s{\A\t}{};
if ( any { $key eq $_ } @VARS ) {
$srcinfo_meta{$key} = $val;
next;
}
push $srcinfo_meta{$key}->@*, $val;
}
$self->_pdump( '%srcinfo_meta', \%srcinfo_meta, "\n" );
foreach my ($var) (@NEEDED_VARS) {
if ( !exists $srcinfo_meta{$var} ) {
warn "$prog: $var is not declared in $FILES{metadata}\n";
return 1;
}
}
if ( $pkgname ne $srcinfo_meta{pkgbase} ) {
warn "$prog: $FILES{metadata} package ($srcinfo_meta{pkgbase}) is different than $pkgname\n";
return 1;
}
}
# .SRCINFO pkgver must not be newer than generated PKGBUILD pkgver.
{
my $ret = $self->_comp_vers( $_pkgbuild{pkgver}, $srcinfo_meta{pkgver}, '<' );
return 1 if defined $ret && $ret == 1;
if ( defined $ret && $ret == 0 ) {
warn "$prog: $FILES{metadata} version ($srcinfo_meta{pkgver}) is newer than $_pkgbuild{pkgver}\n";
return 1;
}
}
if ( !looks_like_number( $srcinfo_meta{pkgrel} ) ) {
warn "$prog: pkgrel $srcinfo_meta{pkgrel} is not a number\n";
return 1;
}
# Add epoch if newer version breaks pacman's version comparison logic.
#
# References:
# https://wiki.archlinux.org/title/PKGBUILD#epoch
# https://man.archlinux.org/man/core/pacman/PKGBUILD.5.en#:~:text=epoch
# https://man.archlinux.org/man/alpm-epoch.7
# https://man.archlinux.org/man/vercmp.8
# https://gitlab.archlinux.org/pacman/pacman/-/blob/master/lib/libalpm/version.c
my $has_epoch = false;
{
my $ret = $self->_comp_vers( $_pkgbuild{pkgver}, $srcinfo_meta{pkgver}, '>' );
return 1 if defined $ret && $ret == 1;
if ( defined $ret && $ret == 0 ) {
require Devel::CheckBin;
Devel::CheckBin->VERSION('0.04');
my $cmd_path = Devel::CheckBin::can_run('vercmp');
$self->_pdump( '$cmd_path', \$cmd_path, '' );
if ( defined $cmd_path ) {
require Capture::Tiny;
Capture::Tiny->VERSION('0.50');
my ( $stdout, $stderr, $exit ) = Capture::Tiny::capture(
sub { system( $cmd_path, $_pkgbuild{pkgver}, $srcinfo_meta{pkgver} ) }
);
$self->_pdump( '$stdout', \$stdout, '' );
$self->_pdump( '$stderr', \$stderr, '' );
$self->_pdump( '$exit', \$exit, '' );
if ( $exit != 0 ) {
warn $stderr;
warn "$prog: failed to run vercmp\n";
return 1;
}
# New version breaks vercmp logic.
if ( $stdout < 0 ) {
my $epoch = $srcinfo_meta{epoch} // 1;
if ( exists $srcinfo_meta{epoch} ) {
++$epoch;
$self->_pdbg("bump epoch to $epoch\n");
}
if ( $gen_output =~ s{^pkgrel=[^\n]+\n\K}{epoch=$epoch\n}m ) {
$has_epoch = true;
$self->_pdbg("add epoch\n");
}
}
$self->_pdbg("\n");
}
( run in 0.833 second using v1.01-cache-2.11-cpan-6aa56a78535 )