File Coverage

blib/lib/App/mymeta_requires.pm
Criterion Covered Total %
statement 71 76 93.4
branch 17 24 70.8
condition n/a
subroutine 15 15 100.0
pod 0 5 0.0
total 103 120 85.8


line stmt bran cond sub pod time code
1 2     2   209008 use 5.010;
  2         7  
  2         92  
2 2     2   13 use strict;
  2         5  
  2         89  
3 2     2   12 use warnings;
  2         3  
  2         157  
4              
5             package App::mymeta_requires;
6             # ABSTRACT: Extract module requirements from MYMETA files
7             our $VERSION = '0.005'; # VERSION
8              
9             # Dependencies
10 2     2   3323 use autodie 2.00;
  2         46010  
  2         13  
11 2     2   13657 use Class::Load qw/try_load_class/;
  2         81906  
  2         158  
12 2     2   2027 use CPAN::Meta;
  2         70873  
  2         76  
13 2     2   2319 use Log::Dispatchouli;
  2         62585  
  2         83  
14 2     2   3206 use Getopt::Lucid ':all';
  2         68083  
  2         474  
15 2     2   2820 use Object::Tiny qw/opt logger/;
  2         708  
  2         14  
16 2     2   659 use CPAN::Meta::Requirements;
  2         5  
  2         2478  
17              
18             my $opt_spec = [
19             Param("file|f"),
20             Switch("verbose|v"),
21             Switch("help|h"),
22             Switch("runtime|r")->default(1),
23             Switch("configure|c")->default(1),
24             Switch("build|b")->default(1),
25             Switch("test|t")->default(1),
26             Switch("develop|d")->default(0),
27             Switch("recommends")->default(1),
28             Switch("suggests")->default(1),
29             ];
30              
31             sub new {
32 11     11 0 62649 my $class = shift;
33 11         42 my $self = bless {}, $class;
34 11         128 $self->{opt} = Getopt::Lucid->getopt($opt_spec);
35 11         16070 $self->{logger} = Log::Dispatchouli->new({
36             ident => 'mymeta-requires',
37             to_stderr => 1,
38             debug => $self->opt->get_verbose,
39             log_pid => 0,
40             });
41 11         13197 return $self;
42             }
43              
44             sub run {
45 11     11 0 15295 my $self = shift;
46 11 50       58 $self = $self->new unless ref $self;
47              
48 11 50       349 if ( $self->opt->get_help ) {
49 0         0 require File::Basename;
50 0         0 require Pod::Usage;
51 0         0 my $file = File::Basename::basename($0);
52 0         0 Pod::Usage::pod2usage();
53             }
54              
55 11 50       628 my $mymeta = $self->load_mymeta
56             or $self->logger->log_fatal("Could not load a MYMETA file");
57 11         82 my $prereqs = $self->merge_prereqs( $mymeta->effective_prereqs );
58 11         303 my @missing = $self->find_missing( $prereqs );
59 11         6767 say for sort @missing;
60 11         537 return 0;
61             }
62              
63             sub load_mymeta {
64 11     11 0 26 my $self = shift;
65 11 100       259 my @candidates = $self->opt->get_file
66             ? ($self->opt->get_file)
67             : qw/MYMETA.json MYMETA.yml META.json META.yml/;
68 11         819 for my $f ( @candidates ) {
69 23 100       360 next unless -r $f;
70 11 50       31 my $mymeta = eval { CPAN::Meta->load_file($f) }
  11         122  
71             or $self->logger->log_debug("Error loading '$f': $@");
72 11 50       253306 if ( $mymeta ) {
73 11         516 $self->logger->log_debug("Got MYMETA from '$f'");
74 11         786 return $mymeta;
75             }
76             }
77 0         0 return;
78             }
79              
80             sub merge_prereqs {
81 11     11 0 50182 my ($self, $prereqs) = @_;
82 11         52 my $merged = CPAN::Meta::Requirements->new;
83 11         157 for my $phase (qw(configure runtime build test develop)) {
84 55         2554 my $get_p = "get_$phase";
85 55 100       1557 next unless $self->opt->$get_p;
86             # Always get 'requires'
87 46         2162 $merged->add_requirements( $prereqs->requirements_for( $phase, 'requires' ) );
88             # Maybe get other types
89 46         5141 for my $extra( qw/recommends suggests/ ) {
90 92         2643 my $get_x = "get_$extra";
91 92 100       2333 next unless $self->opt->$get_x;
92 76         3583 $merged->add_requirements( $prereqs->requirements_for( $phase, $extra ) );
93             }
94             }
95 11         524 return $merged;
96             }
97              
98             sub find_missing {
99 11     11 0 25 my ($self, $prereqs) = @_;
100 11         18 my @missing;
101 11         41 for my $mod ( $prereqs->required_modules ) {
102 75 50       1024 next if $mod eq 'perl';
103 75 100       225 if ( try_load_class($mod) ) {
104 16 50       102469 push @missing, $mod unless $prereqs->accepts_module($mod, $mod->VERSION);
105             }
106             else {
107 59         34768 push @missing, $mod;
108             }
109             }
110 11         71 return @missing;
111             }
112              
113             1;
114              
115              
116             # vim: ts=2 sts=2 sw=2 et:
117              
118             __END__