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