File Coverage

blib/lib/Text/Markup/Cmd.pm
Criterion Covered Total %
statement 39 56 69.6
branch 2 12 16.6
condition 1 3 33.3
subroutine 10 12 83.3
pod 3 3 100.0
total 55 86 63.9


line stmt bran cond sub pod time code
1             package Text::Markup::Cmd;
2              
3 1     1   72674 use strict;
  1         11  
  1         29  
4 1     1   5 use warnings;
  1         11  
  1         47  
5 1     1   469 use Symbol;
  1         864  
  1         61  
6 1     1   479 use IPC::Open3;
  1         2882  
  1         55  
7 1     1   7 use File::Spec;
  1         2  
  1         32  
8 1     1   5 use Carp;use constant WIN32 => $^O eq 'MSWin32';
  1     1   2  
  1         68  
  1         7  
  1         2  
  1         65  
9 1     1   6 use Exporter 'import';
  1         9  
  1         303  
10             our @EXPORT = qw(find_cmd exec_or_die open_pipe WIN32);
11              
12             sub find_cmd {
13 3     3 1 10 my ($names, @opts) = @_;
14 3         7 my $cli;
15             EXE: {
16 3         4 for my $exe (@{ $names }) {
  3         6  
  3         8  
17 5         70 for my $p (File::Spec->path) {
18 45         356 my $path = File::Spec->catfile($p, $exe);
19 45 50 33     909 next unless -f $path && -x $path;
20 0         0 $cli = $path;
21 0         0 last EXE;
22             }
23             }
24             }
25              
26 3 50       14 unless ($cli) {
27 3         10 my $list = join(', ', @{ $names }[0..$#$names-1]) . ", or $names->[-1]";
  3         15  
28 3         372 Carp::croak( "Cannot find $list in path $ENV{PATH}" );
29             }
30              
31             # Make sure it looks like it will work.
32 0           exec_or_die("$cli will not execute", $cli, @opts);
33 0           return $cli;
34             }
35              
36             sub exec_or_die {
37 0     0 1   my $err = shift;
38 0           my $output = gensym;
39 0           my $pid = open3(undef, $output, $output, @_);
40 0           waitpid $pid, 0;
41 0 0         return 1 unless $?;
42 1     1   8 use Carp;
  1         2  
  1         252  
43 0           local $/;
44 0           Carp::croak( qq{$err\n}, <$output> );
45             }
46              
47             # Stolen from SVN::Notify.
48             sub open_pipe {
49             # Ignored; looks like docutils always emits UTF-8.
50 0     0 1   if (WIN32) {
51             my $cmd = q{"} . join(q{" "}, @_) . q{"|};
52             open my $fh, $cmd or die "Cannot fork: $!\n";
53             return $fh;
54             }
55              
56 0           my $pid = open my $fh, '-|';
57 0 0         die "Cannot fork: $!\n" unless defined $pid;
58              
59 0 0         if ($pid) {
60             # Parent process, return the file handle.
61 0           return $fh;
62             } else {
63             # Child process. Execute the commands.
64 0 0         exec @_ or die "Cannot exec $_[0]: $!\n";
65             # Not reached.
66             }
67             }
68              
69             1;
70             __END__