File Coverage

blib/lib/App/Task.pm
Criterion Covered Total %
statement 88 104 84.6
branch 26 40 65.0
condition 3 3 100.0
subroutine 10 14 71.4
pod 1 2 50.0
total 128 163 78.5


line stmt bran cond sub pod time code
1             package App::Task;
2              
3 4     4   407310 use strict;
  4         33  
  4         98  
4 4     4   23 use warnings;
  4         8  
  4         2305  
5              
6             our $lastprintchar;
7             our $VERSION = '0.01';
8             our $depth = 0;
9             our $level = 0;
10              
11             package App::Task::Tie {
12             require Tie::Handle;
13             our @ISA = ('Tie::Handle');
14              
15             sub FILENO {
16 21     21   233 my ($tie) = @_;
17 21         43 return fileno( $tie->{orig} );
18             }
19              
20             sub WRITE {
21 0     0   0 my ( $tie, $buf, $len, $offset ) = @_;
22 0         0 print substr $buf, $offset, $len;
23              
24 0         0 return 1;
25             }
26              
27             sub PRINT {
28 98     98   376 my ( $tie, @args ) = @_;
29              
30 98         138 ($lastprintchar) = substr( $args[-1], -1, 1 );
31 98         142 chomp( $args[-1] );
32 98         128 my $i = App::Task::indent();
33              
34             # print { $tie->{orig} } "DEBUG: -$App::Task::depth-\n";
35             # use Data::Dumper;print { $tie->{orig} } Dumper({ $App::Task::depth => \@args});
36 98         106 print { $tie->{orig} } map { my $p = $_; $p =~ s/\n/\n$i/msg; "$i$p" } @args;
  98         189  
  98         109  
  98         231  
  98         958  
37 98 100       335 print { $tie->{orig} } "\n" if $lastprintchar eq "\n";
  62         538  
38              
39 98         380 return 1;
40             }
41              
42             sub PRINTF {
43 24     24   121 my ( $tie, $pattern, @args ) = @_;
44              
45 24         40 ($lastprintchar) = substr( $pattern, -1, 1 );
46 24         27 chomp($pattern);
47 24         32 my $i = App::Task::indent();
48              
49 24         68 my $new = sprintf( "$i$pattern", @args );
50 24 100       47 if ( substr( $new, -1, 1 ) eq "\n" ) {
51 12         28 chomp($new);
52 12         13 $lastprintchar = "\n";
53             }
54 24         81 $new =~ s/\n/\n$i/msg;
55 24         30 print { $tie->{orig} } $new;
  24         218  
56 24 100       98 print { $tie->{orig} } "\n" if $lastprintchar eq "\n";
  12         90  
57              
58 24         90 return 1;
59             }
60              
61 22     22   37 sub TIEHANDLE { my ( $self, $orig ) = @_; bless { orig => $orig }, $self }
  22         55  
62             };
63              
64             sub import {
65 4     4   25 no strict 'refs'; ## no critic
  4         5  
  4         2967  
66 4     4   33 *{ caller() . '::task' } = \&task;
  4         5483  
67             }
68              
69             sub indent {
70 122 50   122 0 195 warn "indent() called outside of run()\n" if $depth < 0;
71 122 100       174 return "" if $depth <= 0;
72 103         182 return " " x $depth;
73             }
74              
75             our $steps = {};
76             our $prev_depth = 1;
77              
78             sub _sys {
79 0     0   0 my @cmd = @_;
80              
81 0 0       0 my $rv = system(@cmd) ? 0 : 1; # TODO: indent **line at a time** i.e. not run it all and dump it all at once
82 0         0 print "\n";
83              
84 0         0 return $rv;
85             }
86              
87             sub task($$) {
88 11     11 1 122181 my ( $msg, $code, $cmdhr ) = @_;
89 11         18 chomp($msg);
90              
91 11         14 local *STDOUT = *STDOUT;
92 11         13 local *STDERR = *STDERR;
93 11         215 open( local *ORIGOUT, ">&", \*STDOUT );
94 11         185 open( local *ORIGERR, ">&", \*STDERR );
95              
96             # close STDOUT;
97             # close STDERR;
98              
99 11         56 ORIGOUT->autoflush();
100 11         356 ORIGERR->autoflush();
101 11         268 my $o = tie( *STDOUT, __PACKAGE__ . "::Tie", \*ORIGOUT );
102 11         34 my $e = tie( *STDERR, __PACKAGE__ . "::Tie", \*ORIGERR );
103              
104 11         16 my $task = $code;
105 11         16 my $type = ref($code);
106 11 50       31 if ( $type eq 'ARRAY' ) {
    50          
107 0 0   0   0 $task = $cmdhr->{fatal} ? sub { _sys( @{$code} ) or die "`@{$code}` did not exit cleanly: $?\n" } : sub { _sys( @{$code} ) };
  0 0       0  
  0         0  
  0         0  
  0         0  
  0         0  
108             }
109             elsif ( !$type ) {
110 0 0   0   0 $task = $cmdhr->{fatal} ? sub { _sys($code) or die "`$code` did not exit cleanly: $?\n" } : sub { _sys($code) };
  0 0       0  
  0         0  
111             }
112              
113 11         26 my $cur_depth = $depth;
114 11         27 local $depth = $depth + 1;
115 11         14 local $level = $level + 1;
116              
117 11 100       35 $steps->{$depth} = defined $steps->{$depth} ? $steps->{$depth} + 1 : 1;
118              
119 11 100       21 if ( $prev_depth > $cur_depth ) {
120 6         7 for my $k ( keys %{$steps} ) {
  6         16  
121 13 100       30 delete $steps->{$k} if $k > $depth;
122             }
123             }
124              
125 11         12 $prev_depth = $depth;
126              
127 11 50       33 my $pre = $steps->{$depth} ? "[$level.$steps->{$depth}]" : "[$level]";
128              
129             {
130              
131 11         12 local $depth = $depth - 1;
  11         14  
132 11 100 100     39 if ( !defined $lastprintchar || $lastprintchar ne "\n" ) {
133 5         5 local $depth = 0;
134 5         13 print "\n";
135             }
136 11         37 print "➜➜➜➜ $pre $msg …\n";
137             }
138              
139 11         33 my $ok = $task->();
140              
141             {
142 11         34 local $depth = $depth - 1;
  11         14  
143 11 100       22 if ( $lastprintchar ne "\n" ) {
144 8         8 local $depth = 0;
145 8         16 print "\n";
146             }
147              
148 11 100       21 if ($ok) {
149 2         7 print " … $pre done ($msg).\n\n";
150             }
151             else {
152 9         66 warn " … $pre failed ($msg).\n\n";
153             }
154             }
155              
156 11 100       25 if ( $depth < 2 ) {
157 3         8 undef $o;
158 3         14 untie *STDOUT;
159 3         6 undef $e;
160 3         5 untie *STDERR;
161             }
162              
163 11         153 return $ok;
164             }
165              
166             1;
167              
168             __END__