File Coverage

blib/lib/Dist/Zilla/Util/AuthorDeps.pm
Criterion Covered Total %
statement 75 91 82.4
branch 19 32 59.3
condition 3 11 27.2
subroutine 7 9 77.7
pod 2 2 100.0
total 106 145 73.1


line stmt bran cond sub pod time code
1             package Dist::Zilla::Util::AuthorDeps 6.037;
2             # ABSTRACT: Utils for listing your distribution's author dependencies
3              
4 2     2   146543 use Dist::Zilla::Pragmas;
  2         7  
  2         20  
5              
6 2     2   709 use Dist::Zilla::Util;
  2         8  
  2         74  
7 2     2   1367 use Path::Tiny;
  2         14226  
  2         246  
8 2     2   20 use List::Util 1.45 ();
  2         130  
  2         62  
9              
10 2     2   12 use namespace::autoclean;
  2         3  
  2         26  
11              
12             #pod =func extract_author_deps
13             #pod
14             #pod my $prereqs = extract_author_deps($dist_root, $missing_only);
15             #pod
16             #pod This returns a reference to an array in the form:
17             #pod
18             #pod [
19             #pod { $module1 => $ver1 },
20             #pod { $module2 => $ver2 },
21             #pod ...
22             #pod ]
23             #pod
24             #pod Each entry is one of the likely author dependencies for the distribution at the
25             #pod root path C<$dist_root>. If C<$missing_only> is true, then prereqs that appear
26             #pod to be available under the running perl will not be included.
27             #pod
28             #pod I<This function is not really meant to be reliable.> It was undocumented and
29             #pod subject to change at any time, but some downstream libraries chose to use it
30             #pod anyway. I may provide a replacement, at some point, at which point this method
31             #pod will be deprecated and begin issuing a warning. I have documented this method
32             #pod only to provide this warning!
33             #pod
34             #pod =cut
35              
36             sub extract_author_deps {
37 2     2 1 351015 my ($root, $missing) = @_;
38              
39 2         14 my $ini = path($root, 'dist.ini');
40              
41 2 50       179 die "dzil authordeps only works on dist.ini files, and you don't have one\n"
42             unless -e $ini;
43              
44 2         88 my $fh = $ini->openr_utf8;
45              
46 2         2237 require Config::INI::Reader;
47 2         14947 my $config = Config::INI::Reader->read_handle($fh);
48              
49 2         2473 require CPAN::Meta::Requirements;
50 2         36 my $reqs = CPAN::Meta::Requirements->new;
51              
52 2 50       49 if (defined (my $license = $config->{_}->{license})) {
53 2         7 $license = 'Software::License::'.$license;
54 2         11 $reqs->add_minimum($license => 0);
55             }
56              
57 2         195 for my $section ( sort keys %$config ) {
58 14 100       784 if (q[_] eq $section) {
59 2         50 my $version = $config->{_}{':version'};
60 2 50       12 $reqs->add_minimum('Dist::Zilla' => $version) if $version;
61 2         153 next;
62             }
63              
64 12         22 my $pack = $section;
65 12         50 $pack =~ s{\s*/.*$}{}; # trim optional space and slash-delimited suffix
66              
67 12         18 my $version = 0;
68 12 100       43 $version = $config->{$section}->{':version'} if exists $config->{$section}->{':version'};
69              
70 12         69 my $realname = Dist::Zilla::Util->expand_config_package_name($pack);
71 12         332 $reqs->add_minimum($realname => $version);
72             }
73              
74 2         19 seek $fh, 0, 0;
75              
76 2         6 my $in_filter = 0;
77 2         36 while (<$fh>) {
78 58 50 33     239 next unless $in_filter or /^\[\s*\@Filter/;
79 0 0 0     0 $in_filter = 0, next if /^\[/ and ! /^\[\s*\@Filter/;
80 0         0 $in_filter = 1;
81              
82 0 0       0 next unless /\A-bundle\s*=\s*([^;\s]+)/;
83 0         0 my $pname = $1;
84 0         0 chomp($pname);
85 0         0 $reqs->add_minimum(Dist::Zilla::Util->expand_config_package_name($1) => 0)
86             }
87              
88 2         13 seek $fh, 0, 0;
89              
90 2         3 my @packages;
91 2         18 while (<$fh>) {
92 58         810 chomp;
93 58 100       219 next unless /\A\s*;\s*authordep\s*(\S+)\s*(?:=\s*([^;]+))?\s*/;
94 6         16 my $module = $1;
95 6   50     17 my $ver = $2 // "0";
96 6         22 $ver =~ s/\s+$//;
97             # Any "; authordep " is inserted at the beginning of the list
98             # in the file order so the user can control the order of at least a part of
99             # the plugin list
100 6         16 push @packages, $module;
101             # And added to the requirements so we can use it later
102 6         20 $reqs->add_string_requirement($module => $ver);
103             }
104              
105 2         10 my $vermap = $reqs->as_string_hash;
106             # Add the other requirements
107 2         771 push @packages, sort keys %$vermap;
108              
109             # Move inc:: first in list as they may impact the loading of other
110             # plugins (in particular local ones).
111             # Also order inc:: so that those that want to hack @INC with inc:: plugins
112             # can have a consistent playground.
113             # We don't sort the others packages to preserve the same (random) ordering
114             # for the common case (no inc::, no '; authordep') as in previous dzil
115             # releases.
116 2         49 @packages = ((sort grep /^inc::/, @packages), (grep !/^inc::/, @packages));
117 2         26 @packages = List::Util::uniq(@packages);
118              
119 2 100       11 if ($missing) {
120 1         7 require Module::Runtime;
121              
122 1         2 my @new_packages;
123 1         3 PACKAGE: for my $package (@packages) {
124 11 100       37 if ($package eq 'perl') {
125             # This is weird, perl can never really be a prereq to fulfill but...
126             # it was like this. -- rjbs, 2024-06-02
127 1 50 33 1   15 if ($vermap->{perl} && ! eval "use $vermap->{perl}; 1") {
  1         2  
  1         113  
128 0         0 push @new_packages, 'perl';
129             }
130              
131 1         5 next PACKAGE;
132             }
133              
134 10         16 my $ok = eval {
135 10         169 local @INC = (@INC, "$root");
136              
137             # This will die if module is missing
138 10         35 Module::Runtime::require_module($package);
139 9         3724 my $v = $vermap->{$package};
140              
141             # This will die if VERSION is too low
142 9 100       124 !$v || $package->VERSION($v);
143              
144             # Success!
145 9         44 1;
146             };
147              
148 10 100       268 unless ($ok) {
149 1         3 push @new_packages, $package;
150             }
151             }
152              
153 1         9 @packages = @new_packages;
154             }
155              
156             # Now that we have a sorted list of packages, use that to build an array of
157             # hashrefs for display.
158 2         7 [ map { { $_ => $vermap->{$_} } } @packages ]
  12         227  
159             }
160              
161             #pod =func format_author_deps
162             #pod
163             #pod my $string = format_author_deps($prereqs, $include_versions);
164             #pod
165             #pod Given a reference to an array in the format returned by C<extract_author_deps>,
166             #pod this returns a string in the form:
167             #pod
168             #pod Module::One
169             #pod Module::Two
170             #pod Module::Three
171             #pod
172             #pod or, if C<$include_versions> is true:
173             #pod
174             #pod Module::One = 1.00
175             #pod Module::Two = 1.23
176             #pod Module::Three = 8.910213
177             #pod
178             #pod I<This function is not really meant to be reliable.> It was undocumented and
179             #pod subject to change at any time, but some downstream libraries chose to use it
180             #pod anyway. I may provide a replacement, at some point, at which point this method
181             #pod will be deprecated and begin issuing a warning. I have documented this method
182             #pod only to provide this warning!
183             #pod
184             #pod =cut
185              
186             sub format_author_deps {
187 0     0 1   my ($prereqs, $versions) = @_;
188 0           return _format_author_deps($prereqs, $versions);
189             }
190              
191             sub _format_author_deps {
192 0     0     my ($prereqs, $versions, $cpanm_versions) = @_;
193              
194 0           my $formatted = '';
195 0           for my $rec (@$prereqs) {
196 0           my ($mod, $ver) = %$rec;
197 0 0         $formatted .= $cpanm_versions ? "$mod~$ver\n"
    0          
198             : $versions ? "$mod = $ver\n"
199             : "$mod\n";
200             }
201              
202 0           chomp $formatted;
203              
204 0           return $formatted;
205             }
206              
207              
208             1;
209              
210             __END__
211              
212             =pod
213              
214             =encoding UTF-8
215              
216             =head1 NAME
217              
218             Dist::Zilla::Util::AuthorDeps - Utils for listing your distribution's author dependencies
219              
220             =head1 VERSION
221              
222             version 6.037
223              
224             =head1 PERL VERSION
225              
226             This module should work on any version of perl still receiving updates from
227             the Perl 5 Porters. This means it should work on any version of perl
228             released in the last two to three years. (That is, if the most recently
229             released version is v5.40, then this module should work on both v5.40 and
230             v5.38.)
231              
232             Although it may work on older versions of perl, no guarantee is made that the
233             minimum required version will not be increased. The version may be increased
234             for any reason, and there is no promise that patches will be accepted to
235             lower the minimum required perl.
236              
237             =head1 FUNCTIONS
238              
239             =head2 extract_author_deps
240              
241             my $prereqs = extract_author_deps($dist_root, $missing_only);
242              
243             This returns a reference to an array in the form:
244              
245             [
246             { $module1 => $ver1 },
247             { $module2 => $ver2 },
248             ...
249             ]
250              
251             Each entry is one of the likely author dependencies for the distribution at the
252             root path C<$dist_root>. If C<$missing_only> is true, then prereqs that appear
253             to be available under the running perl will not be included.
254              
255             I<This function is not really meant to be reliable.> It was undocumented and
256             subject to change at any time, but some downstream libraries chose to use it
257             anyway. I may provide a replacement, at some point, at which point this method
258             will be deprecated and begin issuing a warning. I have documented this method
259             only to provide this warning!
260              
261             =head2 format_author_deps
262              
263             my $string = format_author_deps($prereqs, $include_versions);
264              
265             Given a reference to an array in the format returned by C<extract_author_deps>,
266             this returns a string in the form:
267              
268             Module::One
269             Module::Two
270             Module::Three
271              
272             or, if C<$include_versions> is true:
273              
274             Module::One = 1.00
275             Module::Two = 1.23
276             Module::Three = 8.910213
277              
278             I<This function is not really meant to be reliable.> It was undocumented and
279             subject to change at any time, but some downstream libraries chose to use it
280             anyway. I may provide a replacement, at some point, at which point this method
281             will be deprecated and begin issuing a warning. I have documented this method
282             only to provide this warning!
283              
284             =head1 AUTHOR
285              
286             Ricardo SIGNES 😏 <cpan@semiotic.systems>
287              
288             =head1 COPYRIGHT AND LICENSE
289              
290             This software is copyright (c) 2026 by Ricardo SIGNES.
291              
292             This is free software; you can redistribute it and/or modify it under
293             the same terms as the Perl 5 programming language system itself.
294              
295             =cut