File Coverage

blib/lib/AlignDB/Stopwatch.pm
Criterion Covered Total %
statement 117 117 100.0
branch 22 22 100.0
condition n/a
subroutine 21 21 100.0
pod 5 10 50.0
total 165 170 97.0


line stmt bran cond sub pod time code
1             package AlignDB::Stopwatch;
2 6     6   193101 use Moose;
  6         2133907  
  6         39  
3              
4 6     6   36923 use Time::Duration;
  6         10234  
  6         549  
5 6     6   2771 use Data::UUID;
  6         3539  
  6         355  
6 6     6   86 use File::Spec;
  6         8  
  6         126  
7 6     6   3035 use YAML::Syck;
  6         9778  
  6         5787  
8              
9             our $VERSION = '1.1.0';
10              
11             has program_name => ( is => 'ro', isa => 'Str' );
12             has program_argv => ( is => 'ro', isa => 'ArrayRef', default => sub { [] } );
13             has program_conf => ( is => 'ro', isa => 'Object' );
14             has 'start_time' => ( is => 'rw', isa => 'Value' );
15             has 'div_char' => ( is => 'rw', isa => 'Str', default => sub {"="}, );
16             has 'div_length' => ( is => 'rw', isa => 'Int', default => sub {30}, );
17             has 'min_div_length' => ( is => 'rw', isa => 'Int', default => sub {5} );
18             has uuid => ( is => 'ro', isa => 'Str' );
19              
20             sub BUILD {
21 5     5 0 5440 my $self = shift;
22              
23 5         47 $self->{start_time} = time;
24 5         2076 $self->{uuid} = Data::UUID->new->create_str;
25              
26 5         10597 return;
27             }
28              
29             #@returns AlignDB::Stopwatch
30             sub record {
31 1     1 1 13 my $self = shift;
32              
33 1         4 $self->{program_name} = $main::0;
34              
35 1         3 $self->{program_argv} = [@main::ARGV];
36              
37 1         3 return $self;
38             }
39              
40             #@returns AlignDB::Stopwatch
41             sub record_conf {
42 1     1 1 2 my $self = shift;
43 1         2 my $conf = shift;
44              
45 1         3 $self->{program_conf} = $conf;
46              
47 1         2 return $self;
48             }
49              
50             sub _divider {
51 6     6   12 my $self = shift;
52 6         8 my $title = shift;
53              
54 6 100       16 my $title_length = $title ? length $title : 0;
55              
56 6         320 my $div_char = $self->div_char;
57 6         348 my $div_length = $self->div_length;
58 6         360 my $min_div_length = $self->min_div_length;
59              
60 6         13 my $divider_str;
61              
62 6 100       32 if ( !$title_length ) {
    100          
63 4         19 $divider_str .= $div_char x $div_length;
64 4         8 $divider_str .= "\n";
65             }
66             elsif ( $title_length > $div_length - 2 * $min_div_length ) {
67 1         5 $divider_str .= $div_char x $min_div_length;
68 1         5 $divider_str .= $title;
69 1         5 $divider_str .= $div_char x $min_div_length;
70 1         3 $divider_str .= "\n";
71             }
72             else {
73 1         7 my $left_length = int( ( $div_length - $title_length ) / 2 );
74 1         17 my $right_length = $div_length - $title_length - $left_length;
75 1         3 $divider_str .= $div_char x $left_length;
76 1         2 $divider_str .= $title;
77 1         1 $divider_str .= $div_char x $right_length;
78 1         2 $divider_str .= "\n";
79             }
80              
81 6         21 return $divider_str;
82             }
83              
84             sub _prompt {
85 6     6   5 my $self = shift;
86 6         12 return "==> ";
87             }
88              
89             sub _empty_line {
90 16     16   21 my $self = shift;
91 16         36 return "\n";
92             }
93              
94             sub _time {
95 8     8   15 my $self = shift;
96 8         14 my $title = shift;
97              
98 8         11 my $time_str;
99              
100 8 100       61 if ( !defined $title ) {
    100          
    100          
101 1         3 $time_str .= "Current time: ";
102             }
103             elsif ( $title =~ /start/i ) {
104 4         11 $time_str .= "Start at: ";
105             }
106             elsif ( $title =~ /end/i ) {
107 2         9 $time_str .= "End at: ";
108             }
109             else {
110 1         3 $time_str .= "$title: ";
111             }
112 8         403 $time_str .= scalar localtime;
113 8         14 $time_str .= "\n";
114              
115 8         36 return $time_str;
116             }
117              
118             sub _duration {
119 3     3   7 my $self = shift;
120 3         11 return "Runtime " . $self->duration_now . ".\n";
121             }
122              
123             sub _message {
124 8     8   22 my $self = shift;
125 8         10 my $message = shift;
126              
127 8 100       25 $message = '' unless defined $message;
128              
129 8         36 return $message . "\n";
130             }
131              
132             sub duration_now {
133 7     7 0 2001821 my $self = shift;
134 7         579 return Time::Duration::duration( time - $self->start_time );
135             }
136              
137             sub block_message {
138 4     4 1 2285 my $self = shift;
139 4         6 my $message = shift;
140 4         4 my $with_duration = shift;
141              
142 4         3 my $text;
143 4         10 $text .= $self->_empty_line;
144 4         9 $text .= $self->_prompt;
145 4         6 $text .= $self->_message($message);
146 4 100       10 if ($with_duration) {
147 1         2 $text .= $self->_prompt;
148 1         3 $text .= $self->_duration;
149             }
150 4         13 $text .= $self->_empty_line;
151              
152 4         97 print $text;
153              
154 4         17 return;
155             }
156              
157             sub start_message {
158 4     4 1 5676 my $self = shift;
159 4         14 my $message = shift;
160 4         9 my $embed_in_divider = shift;
161              
162 4         33 my $text;
163 4 100       19 if ( defined $message ) {
164 3 100       13 if ( defined $embed_in_divider ) {
165 2         24 $text .= $self->_divider($message);
166             }
167             else {
168 1         19 $text .= $self->_divider;
169 1         6 $text .= $self->_message($message);
170             }
171             }
172             else {
173 1         5 $text .= $self->_divider;
174             }
175 4         16 $text .= $self->_time("start");
176 4         27 $text .= $self->_empty_line;
177              
178 4         300 print $text;
179              
180 4         24 return;
181             }
182              
183             sub end_message {
184 2     2 1 2079 my $self = shift;
185 2         8 my $message = shift;
186              
187 2         4 my $text;
188 2         12 $text .= $self->_empty_line;
189 2 100       15 if ( defined $message ) {
190 1         7 $text .= $self->_message($message);
191              
192             }
193 2         9 $text .= $self->_time("end");
194 2         13 $text .= $self->_duration;
195 2         43 $text .= $self->_divider;
196              
197 2         114 print $text;
198              
199 2         19 return;
200             }
201              
202             sub cmd_line {
203 1     1 0 2 my $self = shift;
204 1         38 return join( ' ', $self->program_name, @{ $self->program_argv } );
  1         29  
205             }
206              
207             sub init_config {
208 1     1 0 1 my $self = shift;
209 1         36 return YAML::Syck::Dump $self->program_conf;
210             }
211              
212             sub operation {
213 1     1 0 6 my $self = shift;
214 1         39 my ( undef, undef, $filename ) = File::Spec->splitpath( $self->program_name );
215 1         6 return $filename;
216             }
217              
218             1;
219              
220             __END__
221              
222             =head1 NAME
223              
224             AlignDB::Stopwatch - Record running time and print standard messages
225              
226             =head1 SYNOPSIS
227              
228             use AlignDB::Stopwatch;
229              
230             # record command line
231             my $stopwatch = AlignDB::Stopwatch->new->record;
232              
233             # record config
234             $stopwatch->record_conf($opt);
235              
236             $stopwatch->start_message("Doing really bad things...");
237              
238             $stopwatch->end_message;
239              
240             =head1 ATTRIBUTES
241              
242             =head2 program_name
243              
244             program name
245              
246             =head2 program_argv
247              
248             program command line options
249              
250             =head2 program_conf
251              
252             program configurations
253              
254             =head2 start_time
255              
256             start time
257              
258             =head2 div_char
259              
260             Divider char used in output messages, default is [=]
261              
262             =head2 div_length
263              
264             Length of divider char, default is [30]
265              
266             =head2 min_div_length
267              
268             minimal single-side divider length, default is [5]
269              
270             =head2 uuid
271              
272             Use Data::UUID to generate a UUID that prevent inserting meta info more than
273             one time on multithreads mode
274              
275             =head1 METHODS
276              
277             =head2 record
278              
279             Record $main::0 to program_name and [@main::ARGV] to program_argv.
280              
281             Getopt::Long would manipulate @ARGV.
282              
283             my $stopwatch = AlignDB::Stopwatch->new->record;
284              
285             =head2 record_conf
286              
287             Record a hashref or object to program_conf.
288              
289             $stopwatch->record_conf( $opt );
290              
291             =head2 block_message
292              
293             Print a blocked message
294              
295             $stopwatch->block_message( $message, $with_duration );
296              
297             =head2 start_message
298              
299             Print a starting message
300              
301             $stopwatch->start_message( $message, $embed_in_divider );
302              
303             =head2 end_message
304              
305             Print a ending message
306              
307             $stopwatch->end_message( $message );
308              
309             =head1 AUTHOR
310              
311             Qiang Wang <wang-q@outlook.com>
312              
313             =head1 COPYRIGHT AND LICENSE
314              
315             This software is copyright (c) 2008- by Qiang Wang.
316              
317             This is free software; you can redistribute it and/or modify it under
318             the same terms as the Perl 5 programming language system itself.
319              
320             =cut