App-Deps-Verify
view release on metacpan or search on metacpan
lib/App/Deps/Verify.pm view on Meta::CPAN
package App::Deps::Verify;
$App::Deps::Verify::VERSION = '0.12.2';
use strict;
use warnings;
use autodie;
use 5.014;
use Moo;
use File::Which qw/ which /;
use YAML::XS qw/ LoadFile /;
use Path::Tiny qw/ path /;
sub _load_yamls
{
my ( $self, $args ) = @_;
return [ map { LoadFile($_) } @{ $args->{filenames} } ];
}
sub verify_deps_in_yamls
{
my ( $self, $args ) = @_;
return $self->find_deps(
{
inputs => $self->_load_yamls($args),
}
);
}
sub list_perl5_modules_in_yamls
{
my ( $self, $args ) = @_;
return $self->list_perl5_modules(
{
inputs => $self->_load_yamls($args),
}
);
}
sub list_python3_modules_in_yamls
{
my ( $self, $args ) = @_;
return $self->list_missing_python3_modules(
{
inputs => [
map { $_->{required}->{py3_modules} }
@{ $self->_load_yamls($args) }
],
}
);
}
sub _find_exes
{
my ( $self, $args ) = @_;
my @not_found;
foreach my $line ( map { @$_ } @{ $args->{inputs} } )
{
my $cmd = $line->{exe};
if (
not(
( $cmd =~ m{\A/} )
? ( -e $cmd )
: ( defined( scalar( which($cmd) ) ) )
)
)
{
push @not_found, $line;
}
}
if (@not_found)
{
print "The following commands could not be found:\n\n";
foreach my $cmd ( sort { $a->{exe} cmp $b->{exe} } @not_found )
{
print "$cmd->{exe}\t$cmd->{url}\n";
}
exit(-1);
}
return;
}
sub list_perl5_modules
{
my ( $self, $args ) = @_;
my $inputs = $args->{inputs};
my $map = sub {
my ($key) = @_;
return [ map { $_->{required}->{$key} } @$inputs ];
};
my $args_m = sub {
my ($key) = @_;
return +{ inputs => $map->($key), };
};
my $reqs = +{};
foreach my $required_modules ( @{ $args_m->('perl5_modules')->{inputs} } )
{
foreach my $m ( keys(%$required_modules) )
{
$reqs->{$m} = 1;
}
}
return +{ perl5_modules => [ sort { $a cmp $b } keys %$reqs ] };
}
sub _find_perl5_modules
{
my ( $self, $args ) = @_;
my @not_found;
foreach my $required_modules ( @{ $args->{inputs} } )
{
foreach my $m ( sort { $a cmp $b } keys(%$required_modules) )
{
my $v = $required_modules->{$m};
local $SIG{__WARN__} = sub { };
my $verdict = eval( "use $m " . ( $v || '' ) . ' ();' );
my $Err = $@;
if ($Err)
{
push @not_found, $m;
}
}
}
if (@not_found)
{
print "The following modules could not be found:\n\n";
foreach my $module (@not_found)
{
print "$module\n";
}
exit(-1);
}
return;
}
sub list_missing_python3_modules
{
my ( $self, $args ) = @_;
my %not_found;
foreach my $mods ( @{ $args->{inputs} } )
{
use Data::Dumper;
# die Dumper($mods);
my @required_modules = keys %{$mods};
REQUIRED:
foreach my $module (@required_modules)
{
if ( $module !~ m#\A[a-zA-Z0-9_\.]+\z# )
{
die "invalid python3 module id - $module !";
}
if ( exists $not_found{$module} )
{
next REQUIRED;
}
if ( system( 'python3', '-c', "import $module" ) != 0 )
{
$not_found{$module} = 0;
}
}
}
return { missing_python3_modules =>
[ map { +{ module => $_, }, } sort keys(%not_found) ] };
}
sub _find_python3_modules
{
my ( $self, $args ) = @_;
my @not_found =
map { $_->{module} }
@{ $self->list_missing_python3_modules($args)->{missing_python3_modules}
};
if (@not_found)
{
print "The following python3 modules could not be found:\n\n";
foreach my $module (@not_found)
{
print "$module\n";
}
exit(-1);
}
return;
}
sub _find_required_files
{
my ( $self, $args ) = @_;
my @not_found;
foreach my $required_files ( @{ $args->{inputs} } )
{
foreach my $path (@$required_files)
{
my $p = $path->{path};
if ( $p =~ m#[\\\$]# )
{
die "Invalid path $p!";
}
if ( !-e ( $p =~ s#\A~/#$ENV{HOME}/#r ) )
{
push @not_found, $path;
}
}
}
if (@not_found)
{
print "The following required files could not be found.\n";
print "Please set them up:\n";
print "\n";
foreach my $path (@not_found)
{
print "$path->{path}\n$path->{desc}\n";
}
exit(-1);
}
return;
}
sub find_deps
{
my ( $self, $args ) = @_;
my $inputs = $args->{inputs};
my $map = sub {
my ($key) = @_;
return [ map { $_->{required}->{$key} } @$inputs ];
};
my $args_m = sub {
my ($key) = @_;
return +{ inputs => $map->($key), };
};
$self->_find_exes( $args_m->('executables') );
$self->_find_perl5_modules( $args_m->('perl5_modules') );
$self->_find_python3_modules( $args_m->('py3_modules') );
$self->_find_required_files( $args_m->('files') );
return;
}
sub write_rpm_spec_from_yaml_file
{
my ( $self, $args ) = @_;
$self->write_rpm_spec_text_from_yaml_file_to_fh(
+{
deps_fn => $args->{deps_fn},
out_fh => scalar( path( $args->{out_fn} )->openw_utf8 ),
}
);
return;
}
sub write_rpm_spec_text_from_yaml_file_to_fh
{
my ( $self, $args, ) = @_;
my ($yaml_data) = LoadFile( $args->{deps_fn} );
return $self->write_rpm_spec_text_to_fh(
{
data => $yaml_data,
out_fh => $args->{out_fh},
}
);
}
my %EXES_TRANSLATIONS = (
( run in 2.272 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )