File Coverage

blib/lib/Dist/Zilla/App/Command/dumpwith.pm
Criterion Covered Total %
statement 85 94 90.4
branch 12 14 85.7
condition 5 7 71.4
subroutine 16 19 84.2
pod n/a
total 118 134 88.0


line stmt bran cond sub pod time code
1 4     4   413520 use 5.006;
  4         9  
2 4     4   12 use strict;
  4         3  
  4         63  
3 4     4   11 use warnings;
  4         10  
  4         193  
4              
5             package Dist::Zilla::App::Command::dumpwith;
6              
7             our $VERSION = '0.003001';
8              
9             # ABSTRACT: Dump all plugins that 'do' a certain role
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13              
14              
15              
16              
17              
18              
19              
20              
21              
22              
23              
24              
25 4     4   389 use Dist::Zilla::App '-command';
  4         29218  
  4         26  
26 4     4   6056 use Try::Tiny qw( try catch );
  4         5  
  4         3312  
27              
28             ## no critic ( ProhibitAmbiguousNames)
29 0     0   0 sub abstract { return 'Dump all plugins that "do" a specific role' }
30             ## use critic
31              
32             sub opt_spec {
33 6     6   185433 return ( [ 'color-theme=s', 'color theme to use, ( eg: basic::blue )' ] );
34             }
35              
36             sub _has_module {
37 1     1   2 my ( undef, $module ) = @_;
38 1         4 require Module::Runtime;
39 1         3 require Try::Tiny;
40 1     1   26 Try::Tiny::try { Module::Runtime::require_module($module) }
41             Try::Tiny::catch {
42 0     0   0 require Carp;
43 0         0 Carp::cluck("The module $module seems invalid, did you type it right? Is it installed?");
44             ## no critic (RequireCarping)
45 0         0 die $_;
46 1         7 };
47 1         26 return;
48             }
49              
50             sub _has_dz_role {
51 3     3   7 my ( undef, $role ) = @_;
52 3         17 require Module::Runtime;
53 3         9 my $module = Module::Runtime::compose_module_name( 'Dist::Zilla::Role', $role );
54 3         193 require Try::Tiny;
55             Try::Tiny::try {
56 3     3   87 Module::Runtime::require_module($module);
57             }
58             Try::Tiny::catch {
59 0     0   0 require Carp;
60 0         0 Carp::cluck("The role -$role seems invalid, did you type it right? Is it installed?");
61             ## no critic (RequireCarping)
62 0         0 die $_;
63 3         36 };
64 3         287549 return;
65             }
66              
67             sub validate_args {
68 6     6   2207 my ( $self, $opt, $args ) = @_;
69 6         9 for my $arg ( @{$args} ) {
  6         14  
70 7 100       18 next if q[--] eq $arg;
71 4 100       16 if ( $arg =~ /\A-(.*)\z/msx ) {
72 3         9 $self->_has_dz_role($1);
73             }
74             else {
75 1         3 $self->_has_module($arg);
76             }
77             }
78 6   100     21 my $theme = $opt->color_theme || 'basic::blue';
79             try {
80 6     6   146 $self->_load_color_theme($theme);
81             }
82             catch {
83 1     1   209 my $error = shift;
84 1         19 require Carp;
85 1         2 my $message = $error . qq[\n\n];
86 1         3 $message .= sprintf "^ Was seen attempting to load theme <%s>\n", $theme;
87 1         4 $message .= sprintf 'available themes are: %s', ( join q{, }, $self->_available_themes );
88 1         172 Carp::croak($message);
89 6         84 };
90 5         82 return 1;
91             }
92              
93             sub _available_themes {
94 1     1   1 my (undef) = @_;
95 1         393 require Path::ScanINC;
96 1         3125 my (@theme_dirs) = Path::ScanINC->new()->all_dirs( 'Dist', 'Zilla', 'dumpphases', 'Theme' );
97 1 50       615 if ( not @theme_dirs ) {
98 0         0 require Carp;
99             ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
100 0         0 Carp::cluck('Found no theme dirs in @INC matching Dist/Zilla/dumpphases/Theme/');
101             }
102 1         10 my (%themes);
103 1         5 require Path::Tiny;
104 1         2 for my $dir (@theme_dirs) {
105 1         4 my $it = Path::Tiny->new($dir)->iterator(
106             {
107             recurse => 1,
108             follow_symlinks => 0,
109             },
110             );
111 1         36 while ( my $item = $it->() ) {
112 5 100       394 next unless $item =~ /[.]pm\z/msx;
113 4 50       23 next if -d $item;
114 4         70 my $theme_name = $item->relative($dir);
115 4         419 $theme_name =~ s{[.]pm\z}{}msx;
116 4         28 $theme_name =~ s{/}{::}msxg;
117 4         13 $themes{$theme_name} = 1;
118             }
119             }
120             ## no critic (Variables::ProhibitUnusedVarsStricter)
121 1         34 return ( my (@list) = sort keys %themes );
122             }
123              
124             sub _load_color_theme {
125 11     11   57 my ( undef, $color_theme ) = @_;
126 11         47 require Module::Runtime;
127 11         26 my $theme_module = Module::Runtime::compose_module_name( 'Dist::Zilla::dumpphases::Theme', $color_theme );
128 11         403 Module::Runtime::require_module($theme_module);
129 10         84485 return $theme_module;
130             }
131              
132             sub execute {
133 5     5   20 my ( $self, $opt, $args ) = @_;
134 5   100     16 my $theme_module = $self->_load_color_theme( $opt->color_theme || 'basic::blue' );
135 5         35 my $theme = $theme_module->new();
136              
137 5         69 require Scalar::Util;
138 5         8 my $zilla;
139 5         7 for my $arg ( @{$args} ) {
  5         10  
140 7 100       16 next if q[--] eq $arg;
141 4         14 $theme->print_section_prelude( 'role: ', $arg );
142 4   33     10796 $zilla ||= $self->zilla;
143 4         2206829 my $seen = 0;
144 4         6 for my $plugin ( @{ $zilla->plugins_with($arg) } ) {
  4         19  
145 3         1047 $theme->print_star_assoc( $plugin->plugin_name, Scalar::Util::blessed($plugin) );
146 3         294 $seen++;
147             }
148 4 100       464 if ( not $seen ) {
149 1         6 require Carp;
150 1         198 Carp::carp("No plugins matching $arg found");
151             }
152             }
153              
154 5         252 return 0;
155             }
156              
157             1;
158              
159             __END__
160              
161             =pod
162              
163             =encoding UTF-8
164              
165             =head1 NAME
166              
167             Dist::Zilla::App::Command::dumpwith - Dump all plugins that 'do' a certain role
168              
169             =head1 VERSION
170              
171             version 0.003001
172              
173             =head1 SYNOPSIS
174              
175             cd $PROJECT;
176             dzil dumpwith -- -VersionProvider
177              
178             dzil dumpwith --color-theme=basic::plain -- -FileGatherer # plain text
179             dzil dumpwith --color-theme=basic::green -- -BeforeRelease # green text
180              
181             If you are using an HTML-enabled POD viewer, you should see a screenshot of this in action:
182              
183             ( Everyone else can visit L<http://kentnl.github.io/screenshots/Dist-Zilla-App-Command-dumpwith/0.003000/example_01.png> )
184              
185             =for html <center>
186             <img src="http://kentnl.github.io/screenshots/Dist-Zilla-App-Command-dumpwith/0.003000/example_01.png"
187             alt="Screenshot"
188             width="740"
189             height="586"/>
190             </center>
191              
192             =head1 DESCRIPTION
193              
194             This command, like its sibling L<< C<dumpphases>|Dist::Zilla::App::Command::dumpphases >>, exists to help make understanding
195             what is going on in C<Dist::Zilla> a little easier.
196              
197             At least, having this command means debugging certain kinds of problems is more obvious.
198              
199             If you want to see all plugins that are adding files to your dist?
200              
201             dzil dumpwith -- -FileGatherer
202              
203             Though, of course, this requires some knowledge of what roles are applicable.
204              
205             If you want to turn colors off, use L<< C<Term::ANSIcolor>'s environment variable|Term::ANSIColor >>
206             C<ANSI_COLORS_DISABLED>. E.g.,
207              
208             ANSI_COLORS_DISABLED=1 dzil dumpphases
209              
210             Alternatively, specify a color-free theme:
211              
212             dzil dumpwith --color-theme=basic::plain -- -VersionProvider
213              
214             =begin MetaPOD::JSON v1.1.0
215              
216             {
217             "namespace":"Dist::Zilla::App::Command::dumpwith",
218             "inherits":"Dist::Zilla::App::Command",
219             "interface":"class"
220             }
221              
222              
223             =end MetaPOD::JSON
224              
225             =head1 KNOWN ISSUES
226              
227             Prior to C<Dist::Zilla 6.0>, the format
228              
229             dzil dumpwith -VersionProvider
230              
231             Was fine.
232              
233             However, since L<< C<Dist::Zilla 6.0>|https://metacpan.org/changes/release/RJBS/Dist-Zilla-6.000-TRIAL#L9-11 >>,
234             C<Dist::Zilla> maps L<< C<-V> to C<verbose>|https://github.com/rjbs/Dist-Zilla/commit/98f9fb8b60cc645ffd401d08f3014675166ad32c#diff-99ae7353049f6c64733828dfcfe4ffdfR16 >>.
235              
236             To work around this problem on C<Dist::Zilla 6.0> or later, you need to either not use short-hands for roles,
237              
238             # dzil dumpwith -VersionProvider
239             dzil dumpwith Dist::Zilla::Role::VersionProvider
240              
241             Or place all the role names (and only role names) after a C<-->
242              
243             dzil dumpwith --color=... -- -VersionProvider -OtherRole --color-ThisIsAlsoARoleBTWSoDontDoThis
244              
245             Any suggestions welcome for how I can detect this problem case happening and report it,
246             but the data appears now outside of a scope I can probe.
247              
248             =head1 AUTHOR
249              
250             Kent Fredric <kentnl@cpan.org>
251              
252             =head1 COPYRIGHT AND LICENSE
253              
254             This software is copyright (c) 2016 by Kent Fredric <kentfredric@gmail.com>.
255              
256             This is free software; you can redistribute it and/or modify it under
257             the same terms as the Perl 5 programming language system itself.
258              
259             =cut