File Coverage

blib/lib/App/HWD.pm
Criterion Covered Total %
statement 58 74 78.3
branch 30 38 78.9
condition 4 6 66.6
subroutine 5 5 100.0
pod 1 1 100.0
total 98 124 79.0


line stmt bran cond sub pod time code
1             package App::HWD;
2              
3 6     6   160322 use warnings;
  6         16  
  6         193  
4 6     6   34 use strict;
  6         13  
  6         215  
5              
6 6     6   3736 use App::HWD::Task;
  6         21  
  6         228  
7 6     6   4371 use App::HWD::Work;
  6         16  
  6         4769  
8              
9             =head1 NAME
10              
11             App::HWD - Support functions for How We Doin'?, the project estimation and tracking tool
12              
13             =head1 VERSION
14              
15             Version 0.21_01
16              
17             =cut
18              
19             our $VERSION = '0.21_01';
20              
21             =head1 SYNOPSIS
22              
23             This module is nothing more than a place-holder for the version info and the TODO list.
24              
25             =head1 FUNCTIONS
26              
27             These functions are used by F, but are kept here so I can easily
28             test them.
29              
30             =head2 get_tasks_and_work( @tasks )
31              
32             Reads tasks and work, and applies the work to the tasks.
33              
34             Returns references to C<@tasks>, C<@work>, C<%tasks_by_id> and C<@errors>.
35              
36             =cut
37              
38             sub get_tasks_and_work {
39 5     5 1 54 my $handle = shift;
40              
41 5         16 my @tasks;
42             my @work;
43 0         0 my %tasks_by_id;
44 0         0 my @errors;
45              
46 0         0 my @parents;
47 0         0 my $curr_task;
48 0         0 my $lineno;
49 0         0 my $currfile;
50 5         110 for my $line ( <$handle> ) {
51 66 100       232 if ( !defined($currfile) ) {
    50          
    0          
52 5 50       23 $currfile = defined $ARGV ? $ARGV : "DATA";
53 5         11 $lineno = 1;
54             }
55             elsif ( !defined( $ARGV ) ) {
56 61         84 ++$lineno;
57             }
58             elsif ( $currfile eq $ARGV ) {
59 0         0 ++$lineno;
60             }
61             else {
62 0         0 $currfile = $ARGV;
63 0         0 $lineno = 1;
64             }
65              
66 66         177 my $where = "line $lineno of $currfile";
67 66         103 chomp $line;
68 66 100       257 next if $line =~ /^\s*#/;
69 62 100       226 next if $line !~ /./;
70              
71 56 100       251 if ( $line =~ /^(-+)/ ) {
    100          
72 37         88 my $level = length $1;
73 37         52 my $parent;
74 37 100       103 if ( $level > 1 ) {
75 32         58 $parent = $parents[ $level - 1 ];
76 32 100       90 if ( !$parent ) {
77 2         7 push( @errors, ucfirst( "$where has no parent: $line" ) );
78 2         5 next;
79             }
80             }
81 35         172 my $task = App::HWD::Task->parse( $line, $parent, $where );
82 35 50       188 if ( !$task ) {
83 0         0 push( @errors, "Can't parse at $where: $line" );
84 0         0 next;
85             }
86 35 100       212 if ( $task->id ) {
87 21 50       64 if ( $tasks_by_id{ $task->id } ) {
88 0         0 push( @errors, "Dupe task ID at $where: Task " . $task->id );
89 0         0 next;
90             }
91 21         68 $tasks_by_id{ $task->id } = $task;
92             }
93 35         74 push( @tasks, $task );
94 35         50 $curr_task = $task;
95 35 100       159 $parent->add_child( $task ) if $parent;
96              
97 35         132 @parents = @parents[0..$level-1]; # Clear any sub-parents
98 35         197 $parents[ $level ] = $task; # Set the new one
99             }
100             elsif ( $line =~ s/^\s+// ) {
101 7         49 $curr_task->add_notes( $line );
102             }
103             else {
104 12         63 my $work = App::HWD::Work->parse( $line );
105 12         31 push( @work, $work );
106 12 100       43 if ( $work->task eq "^" ) {
107 7 50       17 if ( $curr_task ) {
108 7         27 $curr_task->add_work( $work );
109             }
110             else {
111 0         0 push( @errors, "Can't apply work to current task, because there is no current task" );
112             }
113             }
114             }
115             } # while
116              
117             # Validate the structure
118 5         27 for my $task ( @tasks ) {
119 35 100 100     115 if ( $task->estimate && $task->children ) {
120 1   33     4 my $where = $task->id || ("at " . $task->where);
121 1         6 push( @errors, "Task $where cannot have estimates, because it has children" );
122             }
123             }
124              
125 5         17 for my $work ( @work ) {
126 12 100       42 next if $work->task eq "^"; # Already handled inline
127 5         16 my $task = $tasks_by_id{ $work->task };
128 5 50       16 if ( !$task ) {
129 0         0 push( @errors, "No task ID " . $work->task );
130 0         0 next;
131             }
132 5         16 $task->add_work( $work );
133             }
134              
135             # Get the work done in date order for each of the tasks
136 5         36 $_->sort_work() for @tasks;
137              
138 5         50 return( \@tasks, \@work, \%tasks_by_id, \@errors );
139             }
140              
141             =head1 AUTHOR
142              
143             Andy Lester, C<< >>
144              
145             =head1 BUGS
146              
147             Please report any bugs or feature requests to
148             C, or through the web interface at
149             L.
150             I will be notified, and then you'll automatically be notified of progress on
151             your bug as I make changes.
152              
153             =head1 ACKNOWLEDGEMENTS
154              
155             Thanks to
156             Neil Watkiss
157             and Luke Closs for features and patches.
158              
159             =head1 COPYRIGHT & LICENSE
160              
161             Copyright 2006 Andy Lester, all rights reserved.
162              
163             This program is free software; you can redistribute it and/or modify it
164             under the same terms as Perl itself.
165              
166             =cut
167              
168             1; # End of App::HWD