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   461496 use 5.006;
  4         8  
2 4     4   13 use strict;
  4         4  
  4         78  
3 4     4   13 use warnings;
  4         12  
  4         209  
4              
5             package Dist::Zilla::App::Command::dumpwith;
6              
7             our $VERSION = '0.003000';
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   381 use Dist::Zilla::App '-command';
  4         29362  
  4         33  
26 4     4   6070 use Try::Tiny qw( try catch );
  4         7  
  4         3009  
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   196423 return ( [ 'color-theme=s', 'color theme to use, ( eg: basic::blue )' ] );
34             }
35              
36             sub _has_module {
37 1     1   3 my ( undef, $module ) = @_;
38 1         7 require Module::Runtime;
39 1         3 require Try::Tiny;
40 1     1   34 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         8 };
47 1         31 return;
48             }
49              
50             sub _has_dz_role {
51 3     3   10 my ( undef, $role ) = @_;
52 3         20 require Module::Runtime;
53 3         16 my $module = Module::Runtime::compose_module_name( 'Dist::Zilla::Role', $role );
54 3         206 require Try::Tiny;
55             Try::Tiny::try {
56 3     3   184 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         33 };
64 3         340425 return;
65             }
66              
67             sub validate_args {
68 6     6   2343 my ( $self, $opt, $args ) = @_;
69 6         12 for my $arg ( @{$args} ) {
  6         16  
70 7 100       21 next if q[--] eq $arg;
71 4 100       20 if ( $arg =~ /\A-(.*)\z/msx ) {
72 3         10 $self->_has_dz_role($1);
73             }
74             else {
75 1         3 $self->_has_module($arg);
76             }
77             }
78 6   100     25 my $theme = $opt->color_theme || 'basic::blue';
79             try {
80 6     6   168 $self->_load_color_theme($theme);
81             }
82             catch {
83 1     1   192 my $error = shift;
84 1         18 require Carp;
85 1         3 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         179 Carp::croak($message);
89 6         101 };
90 5         110 return 1;
91             }
92              
93             sub _available_themes {
94 1     1   2 my (undef) = @_;
95 1         384 require Path::ScanINC;
96 1         3115 my (@theme_dirs) = Path::ScanINC->new()->all_dirs( 'Dist', 'Zilla', 'dumpphases', 'Theme' );
97 1 50       544 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         34 while ( my $item = $it->() ) {
112 5 100       392 next unless $item =~ /[.]pm\z/msx;
113 4 50       23 next if -d $item;
114 4         68 my $theme_name = $item->relative($dir);
115 4         424 $theme_name =~ s{[.]pm\z}{}msx;
116 4         27 $theme_name =~ s{/}{::}msxg;
117 4         13 $themes{$theme_name} = 1;
118             }
119             }
120             ## no critic (Variables::ProhibitUnusedVarsStricter)
121 1         35 return ( my (@list) = sort keys %themes );
122             }
123              
124             sub _load_color_theme {
125 11     11   69 my ( undef, $color_theme ) = @_;
126 11         54 require Module::Runtime;
127 11         35 my $theme_module = Module::Runtime::compose_module_name( 'Dist::Zilla::dumpphases::Theme', $color_theme );
128 11         397 Module::Runtime::require_module($theme_module);
129 10         86897 return $theme_module;
130             }
131              
132             sub execute {
133 5     5   25 my ( $self, $opt, $args ) = @_;
134 5   100     24 my $theme_module = $self->_load_color_theme( $opt->color_theme || 'basic::blue' );
135 5         42 my $theme = $theme_module->new();
136              
137 5         79 require Scalar::Util;
138 5         8 my $zilla;
139 5         6 for my $arg ( @{$args} ) {
  5         16  
140 7 100       18 next if q[--] eq $arg;
141 4         15 $theme->print_section_prelude( 'role: ', $arg );
142 4   33     11587 $zilla ||= $self->zilla;
143 4         2319716 my $seen = 0;
144 4         8 for my $plugin ( @{ $zilla->plugins_with($arg) } ) {
  4         20  
145 3         1055 $theme->print_star_assoc( $plugin->plugin_name, Scalar::Util::blessed($plugin) );
146 3         403 $seen++;
147             }
148 4 100       515 if ( not $seen ) {
149 1         7 require Carp;
150 1         216 Carp::carp("No plugins matching $arg found");
151             }
152             }
153              
154 5         316 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.003000
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/example_01.png> )
184              
185             =begin MetaPOD::JSON v1.1.0
186              
187             {
188             "namespace":"Dist::Zilla::App::Command::dumpwith",
189             "inherits":"Dist::Zilla::App::Command",
190             "interface":"class"
191             }
192              
193              
194             =end MetaPOD::JSON
195              
196             =for html <center>
197             <img src="http://kentnl.github.io/screenshots/Dist-Zilla-App-Command-dumpwith/example_01.png"
198             alt="Screenshot"
199             width="806"
200             height="438"/>
201             </center>
202              
203             =head1 KNOWN ISSUES
204              
205             Prior to C<Dist::Zilla 6.0>, the format
206              
207             dzil dumpwith -VersionProvider
208              
209             Was fine.
210              
211             However, since L<< C<Dist::Zilla 6.0>|https://metacpan.org/changes/release/RJBS/Dist-Zilla-6.000-TRIAL#L9-11 >>,
212             C<Dist::Zilla> maps L<< C<-V> to C<verbose>|https://github.com/rjbs/Dist-Zilla/commit/98f9fb8b60cc645ffd401d08f3014675166ad32c#diff-99ae7353049f6c64733828dfcfe4ffdfR16 >>.
213              
214             To work around this problem on C<Dist::Zilla 6.0> or later, you need to either not use short-hands for roles,
215              
216             # dzil dumpwith -VersionProvider
217             dzil dumpwith Dist::Zilla::Role::VersionProvider
218              
219             Or place all the role names (and only role names) after a C<-->
220              
221             dzil dumpwith --color=... -- -VersionProvider -OtherRole --color-ThisIsAlsoARoleBTWSoDontDoThis
222              
223             Any suggestions welcome for how I can detect this problem case happening and report it,
224             but the data appears now outside of a scope I can probe.
225              
226             =head1 DESCRIPTION
227              
228             This command, like its sibling L<< C<dumpphases>|Dist::Zilla::App::Command::dumpphases >>, exists to help make understanding
229             what is going on in C<Dist::Zilla> a little easier.
230              
231             At least, having this command means debugging certain kinds of problems is more obvious.
232              
233             If you want to see all plugins that are adding files to your dist?
234              
235             dzil dumpwith -- -FileGatherer
236              
237             Though, of course, this requires some knowledge of what roles are applicable.
238              
239             If you want to turn colors off, use L<< C<Term::ANSIcolor>'s environment variable|Term::ANSIColor >>
240             C<ANSI_COLORS_DISABLED>. E.g.,
241              
242             ANSI_COLORS_DISABLED=1 dzil dumpphases
243              
244             Alternatively, specify a color-free theme:
245              
246             dzil dumpwith --color-theme=basic::plain -- -VersionProvider
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