File Coverage

blib/lib/Dist/Iller.pm
Criterion Covered Total %
statement 67 69 97.1
branch 16 18 88.8
condition 5 9 55.5
subroutine 16 17 94.1
pod 0 2 0.0
total 104 115 90.4


line stmt bran cond sub pod time code
1 2     2   268750 use 5.10.0;
  2         27  
2 2     2   10 use strict;
  2         4  
  2         44  
3 2     2   8 use warnings;
  2         3  
  2         182  
4              
5             package Dist::Iller;
6              
7             # ABSTRACT: A Dist::Zilla & Pod::Weaver preprocessor
8             our $AUTHORITY = 'cpan:CSSON'; # AUTHORITY
9             our $VERSION = '0.1409';
10              
11 2     2   834 use Dist::Iller::Elk;
  2         8  
  2         8  
12 2     2   6732 use Types::Standard qw/Map Str ConsumerOf/;
  2         158080  
  2         24  
13 2     2   3380 use Types::Path::Tiny qw/Path/;
  2         61500  
  2         17  
14 2     2   1948 use String::CamelCase qw/camelize/;
  2         1265  
  2         135  
15 2     2   24 use Try::Tiny;
  2         7  
  2         140  
16 2     2   52 use Carp qw/croak/;
  2         4  
  2         97  
17 2     2   1187 use Module::Load qw/load/;
  2         2869  
  2         21  
18 2     2   1224 use Safe::Isa qw/$_does/;
  2         1036  
  2         275  
19 2     2   1260 use YAML::Tiny;
  2         12698  
  2         197  
20 2     2   910 use Dist::Iller::Prereq;
  2         8  
  2         1408  
21              
22             has docs => (
23             is => 'ro',
24             isa => Map[Str, ConsumerOf['Dist::Iller::DocType'] ],
25             default => sub { +{ } },
26             traits => ['Hash'],
27             handles => {
28             set_doc => 'set',
29             get_doc => 'get',
30             doc_keys => 'keys',
31             doc_kv => 'kv',
32             },
33             );
34             has filepath => (
35             is => 'ro',
36             isa => Path,
37             default => 'iller.yaml',
38             coerce => 1,
39             );
40              
41             sub parse {
42 5     5 0 151 my $self = shift;
43 5         16 my $phase = shift;
44              
45 5         163 my $yaml = YAML::Tiny->read($self->filepath->stringify);
46              
47             DOCTYPE:
48 5         45491 for my $document (sort { $a->{'doctype'} cmp $b->{'doctype'} } @{ $yaml }) {
  26         64  
  5         53  
49 19         124 my $doctype_class = sprintf 'Dist::Iller::DocType::%s', camelize($document->{'doctype'});
50             try {
51 19     19   1050 load $doctype_class;
52             }
53             catch {
54 0     0   0 croak "Can't load $doctype_class: $_";
55 19         558 };
56 19 100       1576 next DOCTYPE if $doctype_class->phase ne $phase;
57 7         329 $self->set_doc($document->{'doctype'}, $doctype_class->new(global => $self->get_doc('global'))->parse($document));
58             }
59 5 100       191 if($self->get_doc('dist')) {
60 4         140 $self->get_doc('dist')->add_prereq(Dist::Iller::Prereq->new(
61             module => __PACKAGE__,
62             version => __PACKAGE__->VERSION,
63             phase => 'develop',
64             relation => 'suggests',
65             ));
66              
67             DOC:
68 4         136 for my $doc ($self->doc_kv) {
69 12 100       326 if($doc->[1]->$_does('Dist::Iller::Role::HasPlugins')) {
70 8         878 $self->get_doc('dist')->add_plugins_as_prereqs($doc->[1]->packages_for_plugin, $doc->[1]->all_plugins);
71             }
72              
73 12         752 for my $included_config ($doc->[1]->all_included_configs) {
74 5         170 $self->get_doc('dist')->add_prereq(Dist::Iller::Prereq->new(
75             module => $included_config->[0],
76             version => $included_config->[1],
77             phase => 'develop',
78             relation => 'suggests',
79             ));
80             }
81              
82 12 100       57 next DOC if $doc->[0] eq 'dist';
83 8 100       26 next DOC if $doc->[0] eq 'cpanfile';
84 7 50       33 if($doc->[1]->$_does('Dist::Iller::Role::HasPrereqs')) {
85 0         0 $self->get_doc('dist')->merge_prereqs($doc->[1]->all_prereqs);
86             }
87             }
88             }
89 5 100 66     457 if($self->get_doc('cpanfile') && $self->get_doc('dist')) {
90 1         36 $self->get_doc('cpanfile')->merge_prereqs($self->get_doc('dist')->all_prereqs);
91             }
92             }
93              
94             sub generate_files {
95 4     4 0 40988 my $self = shift;
96 4         16 my $phase = shift;
97              
98 4 50 66     48 croak q{'phase' must be either 'before' or 'after'} if !defined $phase || $phase ne 'before' && $phase ne 'after';
      33        
99              
100 4         173 for my $doc ($self->doc_kv) {
101 12 100       87 next if $doc->[1]->phase ne $phase;
102 6         38 $doc->[1]->generate_file;
103             }
104             }
105              
106             __PACKAGE__->meta->make_immutable;
107              
108             1;
109              
110             __END__
111              
112             =pod
113              
114             =encoding UTF-8
115              
116             =head1 NAME
117              
118             Dist::Iller - A Dist::Zilla & Pod::Weaver preprocessor
119              
120              
121              
122             =begin html
123              
124             <p>
125             <img src="https://img.shields.io/badge/perl-5.10+-blue.svg" alt="Requires Perl 5.10+" />
126             <a href="http://cpants.cpanauthors.org/release/CSSON/Dist-Iller-0.1409"><img src="http://badgedepot.code301.com/badge/kwalitee/CSSON/Dist-Iller/0.1409" alt="Distribution kwalitee" /></a>
127             <a href="http://matrix.cpantesters.org/?dist=Dist-Iller%200.1409"><img src="http://badgedepot.code301.com/badge/cpantesters/Dist-Iller/0.1409" alt="CPAN Testers result" /></a>
128             <img src="https://img.shields.io/badge/coverage-84.3%25-orange.svg" alt="coverage 84.3%" />
129             </p>
130              
131             =end html
132              
133             =head1 VERSION
134              
135             Version 0.1409, released 2020-12-27.
136              
137             =head1 SYNOPSIS
138              
139             # dzil new, but...
140             $ dzil new -P DistIller::AMintingProvider My::Module
141              
142             $ cd My/Module
143              
144             # ...all other commands can be used via iller
145             $ iller build
146              
147             =head1 STATUS
148              
149             This is alpha software. Anything can change at any time.
150              
151             It is mostly here to document how I build my distributions. It is perfectly fine to use C<dzil> with a distribution built with C<Dist::Iller> (after a fork, for example).
152              
153             =head1 DESCRIPTION
154              
155             Dist::Iller is a L<Dist::Zilla> and L<Pod::Weaver> preprocessor. It comes with a command line tool (C<iller>) which is a C<dzil> wrapper: When run, it first generates
156             files specified in C<iller.yaml> in the current directory and then executes C<dzil> automatically. (Since C<iller> requires that an C<iller.yaml> is present, C<iller new ...> does not work.)
157              
158             The C<doctype> key in a document in C<iller.yaml> matches a camelized class in the C<Dist::Iller::DocType> namespace; so C<doctype: dist> is parsed by L<Dist::Iller::DocType::Dist>.
159              
160             =head2 iller.yaml
161              
162             This is the general syntax of an C<iller.yaml> file:
163              
164             ---
165             # This specifies that this yaml document will generate dist.ini.
166             doctype: dist
167              
168             # This generates the top part of C<dist.ini>. C<author> can be a list or string.
169             header:
170             name: My-Module
171             author: Ex Ample <ample@example.org>
172             license: Perl_5
173             copyright_holder: Ex Ample
174             copyright_year: 2015
175              
176             # It is possible to list all prereqs. The groups are specified in CPAN::Meta::Spec.
177             # Minimum version numbers are optional.
178             prereqs:
179             runtime:
180             requires:
181             - perl: 5.010001
182             - Moose
183              
184             # List all plugins under the 'plugins' key.
185             # Each +plugin item is a Dist::Zilla> plugin.
186             # All commands for Dist::Iller is prepended with a +.
187             plugins:
188             # Includes all plugins specified in Dist::Iller::Config::My::Config
189             - +config: My::Config
190              
191             - +plugin: DistIller::MetaGeneratedBy
192             - +plugin: AutoVersion
193             - +plugin: GatherDir
194              
195             # 'dir' is a parameter for ShareDir
196             - +plugin: ShareDir
197             dir: myshare
198              
199             [...]
200              
201             ---
202             # Here starts the weaver.ini configuration.
203             doctype: weaver
204              
205             plugins:
206             # Same Dist::Iller::Config as in the 'dist' document
207             - +config: My::Config
208              
209             # Use PluginBundles
210             - +plugin: '@CorePrep'
211              
212             - +plugin: -SingleEncoding
213              
214             - +plugin: Name
215              
216             - +plugin: Version
217             format: Version %v, released %{YYYY-MM-dd}d.
218              
219             - +plugin: prelude
220             +base: Region
221              
222             - +plugin: List
223             +base: -Transformer
224             +in: Elemental
225             transformer: List
226              
227             [...]
228              
229             ---
230             # Here starts the .gitignore configuration
231             doctype: gitignore
232              
233             always:
234             - /.build
235             - /_build*
236             - /Build
237             - MYMETA.*
238             - '!META.json'
239             - /.prove
240             ---
241             # No configuration for .cpanfile, but by having a YAML document for it, it gets generated from
242             # the prereqs listed in the 'dist' document
243             doctype: cpanfile
244              
245             =head2 Rationale
246              
247             PluginBundles for both L<Dist::Zilla> and L<Pod::Weaver> have a few downsides:
248              
249             =over 4
250              
251             =item *
252              
253             Mixes code and configuration.
254              
255             =item *
256              
257             Not straightforward to remove or replace specific plugins for a certain distribution
258              
259             =item *
260              
261             Difficult to insert a plugin before another plugin for a certain distribution.
262              
263             =item *
264              
265             PluginBundles can change after a distribution has been released.
266              
267             =item *
268              
269             Difficult for others to understand/know which plugins actually were in effect when the distribution was built.
270              
271             =back
272              
273             C<Dist::Iller> tries to solve this:
274              
275             =over 4
276              
277             =item *
278              
279             Dist::Iller configs (similar to PluginBundles) has their own C<iller.yaml> (normally in C<share/>) where plugins are specified. See tests and L<Dist::Iller::Config::Author::CSSON>.
280              
281             =item *
282              
283             Since C<dist.ini> and C<weaver.ini> are generated each time C<iller> is run, the plugins listed in them are those that were used to build the distribution.
284              
285             =item *
286              
287             Remove a plugin:
288              
289             =back
290              
291             - +remove_plugin: GatherDir
292              
293             =over 4
294              
295             =item *
296              
297             Insert a plugin:
298              
299             =back
300              
301             - +add_plugin: Git::GatherDir
302             +before: AutoVersion
303              
304             =over 4
305              
306             =item *
307              
308             Replace a plugin:
309              
310             =back
311              
312             - +replace_plugin: ShareDir
313             +with: ShareDir::Tarball
314              
315             =over 4
316              
317             =item *
318              
319             Set more attributes for an already included plugin:
320              
321             =back
322              
323             - +extend_plugin: Git::GatherDir
324             exclude_match:
325             - examples/.*\.html
326              
327             =head1 SEE ALSO
328              
329             =over 4
330              
331             =item *
332              
333             L<Dist::Zilla>
334              
335             =item *
336              
337             L<Pod::Weaver>
338              
339             =item *
340              
341             L<Dist::Iller::Config::Author::CSSON>
342              
343             =back
344              
345             =head1 SOURCE
346              
347             L<https://github.com/Csson/p5-Dist-Iller>
348              
349             =head1 HOMEPAGE
350              
351             L<https://metacpan.org/release/Dist-Iller>
352              
353             =head1 AUTHOR
354              
355             Erik Carlsson <info@code301.com>
356              
357             =head1 COPYRIGHT AND LICENSE
358              
359             This software is copyright (c) 2016 by Erik Carlsson.
360              
361             This is free software; you can redistribute it and/or modify it under
362             the same terms as the Perl 5 programming language system itself.
363              
364             =cut