File Coverage

blib/lib/Dist/Zilla/Plugin/Chrome/ExtraPrompt.pm
Criterion Covered Total %
statement 27 27 100.0
branch n/a
condition n/a
subroutine 9 9 100.0
pod n/a
total 36 36 100.0


line stmt bran cond sub pod time code
1 5     5   9681996 use strict;
  5         15  
  5         174  
2 5     5   29 use warnings;
  5         13  
  5         387  
3             package Dist::Zilla::Plugin::Chrome::ExtraPrompt; # git description: v0.014-17-gecdfd0f
4             # vim: set ts=8 sts=4 sw=4 tw=115 et :
5             # ABSTRACT: Perform arbitrary commands when Dist::Zilla prompts you
6             # KEYWORDS: prompt execute command external
7              
8             our $VERSION = '0.015';
9              
10 5     5   34 use Moose;
  5         14  
  5         52  
11             with 'Dist::Zilla::Role::Plugin';
12 5     5   33389 use namespace::autoclean;
  5         14  
  5         53  
13              
14             # since the plugin is never actually instantiated, these attributes
15             # are mostly useless, but it does serve as a bit of self-documentation...
16             # and who knows, config.ini-oriented plugins may actually become more
17             # supported some day.
18             has command => (
19             is => 'ro', isa => 'Str',
20             required => 1,
21             );
22             has repeat_prompt => (
23             is => 'ro', isa => 'Bool',
24             default => 0,
25             );
26              
27             # metaconfig is unimportant for this distribution since it does not alter the
28             # built distribution in any way
29             around dump_config => sub
30             {
31             my ($orig, $self) = @_;
32             my $config = $self->$orig;
33              
34             my $data = {
35             blessed($self) ne __PACKAGE__ ? ( version => $VERSION ) : (),
36             };
37             $config->{+__PACKAGE__} = $data if keys %$data;
38              
39             return $config;
40             };
41              
42             around register_component => sub
43             {
44             my $orig = shift;
45             my $self = shift;
46             my ($class, $payload, $section) = @_;
47              
48             my $chrome = $section->sequence->assembler->chrome;
49              
50             # if this plugin were in dist.ini, it would be applied for everyone, not just you
51             $chrome->logger->log_fatal('must be used in ~/.dzil/config.ini -- NOT dist.ini!')
52             if $section->sequence->assembler->can('zilla');
53              
54             Moose::Util::apply_all_roles($chrome, 'Dist::Zilla::Role::Chrome::ExtraPrompt');
55              
56             if ($chrome->does('Dist::Zilla::Role::Chrome::ExtraPrompt'))
57             {
58             $chrome->logger->log_debug('setting up chrome for extra prompt command');
59             $chrome->command($payload->{command});
60             $chrome->repeat_prompt($payload->{repeat_prompt});
61             }
62              
63             # WE DO NOT CALL $orig - we will blow up (no zilla, etc)
64             };
65             __PACKAGE__->meta->make_immutable;
66              
67              
68             package Dist::Zilla::Role::Chrome::ExtraPrompt; # git description: v0.014-17-gecdfd0f
69              
70             our $VERSION = '0.015';
71              
72 5     5   1691 use Moose::Role;
  5         12  
  5         43  
73 5     5   28166 use IPC::Open3;
  5         11200  
  5         248  
74 5     5   39 use File::Spec;
  5         12  
  5         109  
75 5     5   2183 use POSIX ':sys_wait_h';
  5         25326  
  5         40  
76 5     5   6911 use namespace::autoclean;
  5         15  
  5         47  
77              
78             has command => (
79             is => 'rw', isa => 'Str',
80             # no point in saying 'required => 1' - the object is already instantiated
81             # by the time we apply our role to it
82             );
83              
84             has repeat_prompt => (
85             is => 'rw', isa => 'Bool',
86             );
87              
88             around [qw(prompt_str prompt_yn)] => sub {
89             my $orig = shift;
90             my $self = shift;
91              
92             if (not $self->command)
93             {
94             warn "[Chrome::ExtraPrompt] no command to run!\n";
95             return $self->$orig(@_);
96             }
97              
98             open(my $in, '<', File::Spec->devnull);
99             open(my $out, '>', File::Spec->devnull);
100             my $err = IO::Handle->new;
101              
102             my $command = $self->command;
103             $command .= ' ' . '"' . $_[0] . '"' if $self->repeat_prompt;
104              
105             my $pid = open3($in, $out, $err, $command);
106             binmode $err, ':crlf' if $^O eq 'MSWin32';
107              
108             # wait for the user to respond
109             my $input = $self->$orig(@_);
110              
111             # check what happened to the command
112             my $done = waitpid($pid, WNOHANG);
113              
114             my $exit_status = $? >> 8;
115             warn "[Chrome::ExtraPrompt] process exited with status $exit_status\n" if $done == $pid and $exit_status;
116              
117             kill 'KILL', $pid if $done == 0;
118              
119             foreach my $warning (<$err>)
120             {
121             warn "[Chrome::ExtraPrompt] $warning";
122             }
123              
124             return $input;
125             };
126              
127             1;
128              
129             __END__
130              
131             =pod
132              
133             =encoding UTF-8
134              
135             =head1 NAME
136              
137             Dist::Zilla::Plugin::Chrome::ExtraPrompt - Perform arbitrary commands when Dist::Zilla prompts you
138              
139             =head1 VERSION
140              
141             version 0.015
142              
143             =head1 SYNOPSIS
144              
145             In your F<~/.dzil/config.ini> (B<NOT> F<dist.ini>):
146              
147             [Chrome::ExtraPrompt]
148             command = say Dist zilla would like your attention.
149             repeat_prompt = 1
150              
151             =head1 DESCRIPTION
152              
153             This is a L<Dist::Zilla> plugin that is loaded from your
154             F<~/.dzil/config.ini>, which affects the behaviour of prompts within
155             L<Dist::Zilla> commands. When you are prompted, the specified command is run;
156             it is killed when you provide prompt input.
157              
158             I have mine configured as in the synopsis, which uses the C<say> command on
159             OS X to provide an audio prompt to bring me back to this screen session.
160              
161             =head1 CONFIGURATION OPTIONS
162              
163             =head2 C<command>
164              
165             The string containing the command and arguments to call. required.
166              
167             =head2 C<repeat_prompt>
168              
169             A boolean flag (defaulting to false) that, when set,
170             appends the prompt string to the command and arguments that are called,
171             passing as a single (additional?) argument.
172              
173             =head1 CAVEATS
174              
175             Some architectures may be incapable of processing the kill signal sent to the
176             command when the prompt returns; if this is happening to you, let me know and I
177             can do some more things in code to avoid this (such as massaging the command to
178             avoid a shell intermediary).
179              
180             =head1 SUPPORT
181              
182             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Dist-Zilla-Plugin-Chrome-ExtraPrompt>
183             (or L<bug-Dist-Zilla-Plugin-Chrome-ExtraPrompt@rt.cpan.org|mailto:bug-Dist-Zilla-Plugin-Chrome-ExtraPrompt@rt.cpan.org>).
184              
185             There is also a mailing list available for users of this distribution, at
186             L<http://dzil.org/#mailing-list>.
187              
188             There is also an irc channel available for users of this distribution, at
189             L<C<#distzilla> on C<irc.perl.org>|irc://irc.perl.org/#distzilla>.
190              
191             I am also usually active on irc, as 'ether' at C<irc.perl.org>.
192              
193             =head1 AUTHOR
194              
195             Karen Etheridge <ether@cpan.org>
196              
197             =head1 COPYRIGHT AND LICENCE
198              
199             This software is copyright (c) 2013 by Karen Etheridge.
200              
201             This is free software; you can redistribute it and/or modify it under
202             the same terms as the Perl 5 programming language system itself.
203              
204             =cut