File Coverage

blib/lib/Dist/Joseki/Command/depends.pm
Criterion Covered Total %
statement 25 27 92.5
branch n/a
condition n/a
subroutine 9 9 100.0
pod n/a
total 34 36 94.4


line stmt bran cond sub pod time code
1             package Dist::Joseki::Command::depends;
2 1     1   24 use 5.008;
  1         4  
  1         36  
3 1     1   5 use strict;
  1         3  
  1         45  
4 1     1   5 use warnings;
  1         2  
  1         41  
5 1     1   5 use Cwd;
  1         1  
  1         85  
6 1     1   7 use File::Find;
  1         2  
  1         79  
7 1     1   3412 use File::Slurp;
  1         19114  
  1         95  
8 1     1   3616 use Module::CoreList;
  1         62869  
  1         14  
9 1     1   2043 use Module::ExtractUse;
  1         226682  
  1         38  
10 1     1   600 use Parse::CPAN::Packages;
  0            
  0            
11             use Perl::Version;
12             our $VERSION = '0.01';
13             use base 'Dist::Joseki::Cmd::Multiplexable';
14              
15             sub options {
16             my ($self, $app, $cmd_config) = @_;
17             return (
18             $self->SUPER::options($app, $cmd_config),
19             [ 'cpan|c=s',
20             'only print one requirement per CPAN distribution; value is location of 02packages.details.txt.gz file',
21             { default => '' },
22             ],
23             [ 'version|v=s',
24             'assuming the given perl version, only print non-core requirements',
25             { default => '' },
26             ],
27             );
28             }
29              
30             sub get_primary_package_from_dist {
31             my ($self, $parser, $dist_prefix) = @_;
32             return $1 if $dist_prefix =~ /\/(perl-[\d\.]+)\.tar\.gz$/;
33             my $distribution = $parser->distribution($dist_prefix);
34             my @dist_packages =
35             sort { length($a) <=> length($b) }
36             map { $_->package } @{ $distribution->packages || [] };
37             $dist_packages[0];
38             }
39              
40             sub restrict_to_CPAN_distributions {
41             my ($self, @packages) = @_;
42             return @packages unless $self->opt_has_value('cpan');
43             my @result;
44             my %dist_seen;
45             my $parser = Parse::CPAN::Packages->new($self->opt('cpan'));
46             for my $package (@packages) {
47             my $pkg_obj = $parser->package($package);
48              
49             # if there is no such package in any CPAN distribution, just add it as
50             # a requirement
51             unless (defined $pkg_obj) {
52             push @result => $package;
53             next;
54             }
55              
56             # use the distribution object's prefix() as a hash key because we can
57             # get back to the distribution from that
58             $dist_seen{ $pkg_obj->distribution->prefix }++;
59             }
60             push @result => map { $self->get_primary_package_from_dist($parser, $_) }
61             sort keys %dist_seen;
62             @result;
63             }
64              
65             sub get_core_list_version_string {
66             my ($self, $version) = @_;
67              
68             # Module::CoreList expects 5.6.0 as 5.006, but Perl::Version would return
69             # 5.006000, so chop off any subversion 0.
70             $version =~ s/^(\d.\d+)\.0$/$1/;
71             Perl::Version->new($version)->numify;
72             }
73              
74             sub restrict_to_non_core_modules {
75             my ($self, @packages) = @_;
76             return @packages unless $self->opt_has_value('version');
77             my $core_list =
78             $Module::CoreList::version{ $self->get_core_list_version_string(
79             $self->opt('version')) };
80             unless (defined $core_list) {
81             warn sprintf "no core module list for perl version %s, skipping\n",
82             $self->opt('version');
83             return @packages;
84             }
85             grep { !exists $core_list->{$_} } @packages;
86             }
87              
88             sub run_single {
89             my $self = shift;
90             $self->SUPER::run_single(@_);
91             $self->assert_is_dist_base_dir;
92             my %modules;
93             my %packages;
94             find(
95             sub {
96             return unless -f && /\.pm$/;
97             my $source = read_file($_);
98             my $p = Module::ExtractUse->new;
99             $p->extract_use(\$source);
100             @modules{ $p->array } = ();
101             my @packages = ($source =~ /^package\s*(\w+(?:::\w+)*)\s*;/gsm);
102             @packages{@packages} = ();
103             },
104             getcwd()
105             );
106              
107             # packages found in this distribution aren't external requirements
108             delete @modules{ keys %packages };
109             print "$_\n"
110             for $self->restrict_to_CPAN_distributions(
111             $self->restrict_to_non_core_modules(sort keys %modules,));
112             }
113             1;
114             __END__
115              
116             =head1 NAME
117              
118             Dist::Joseki::Command::depends - show your distribution's dependencies
119              
120             =head1 SYNOPSIS
121              
122             # dist depends
123              
124             =head1 DESCRIPTION
125              
126             This command plugin for L<Dist::Joseki> gives you a new command: C<dist
127             depends> lists the distribution's module dependencies.
128              
129             =head1 METHODS
130              
131             =over 4
132              
133             =back
134              
135             =head1 BUGS AND LIMITATIONS
136              
137             No bugs have been reported.
138              
139             Please report any bugs or feature requests through the web interface at
140             L<http://rt.cpan.org>.
141              
142             =head1 INSTALLATION
143              
144             See perlmodinstall for information and options on installing Perl modules.
145              
146             =head1 AVAILABILITY
147              
148             The latest version of this module is available from the Comprehensive Perl
149             Archive Network (CPAN). Visit L<http://www.perl.com/CPAN/> to find a CPAN
150             site near you. Or see
151             L<http://search.cpan.org/dist/Dist-Joseki-Command-depends/>.
152              
153             The development version lives at
154             L<http://github.com/hanekomu/dist-joseki-command-depends/>. Instead of
155             sending patches, please fork this project using the standard git and github
156             infrastructure.
157              
158             =head1 AUTHORS
159              
160             Marcel GrE<uuml>nauer, C<< <marcel@cpan.org> >>
161              
162             =head1 COPYRIGHT AND LICENSE
163              
164             Copyright 2010 by Marcel GrE<uuml>nauer
165              
166             This library is free software; you can redistribute it and/or modify
167             it under the same terms as Perl itself.
168              
169             =cut