File Coverage

blib/lib/App/bif/show/project.pm
Criterion Covered Total %
statement 12 42 28.5
branch 0 14 0.0
condition n/a
subroutine 4 4 100.0
pod 1 1 100.0
total 17 61 27.8


line stmt bran cond sub pod time code
1             package App::bif::show::project;
2 1     1   4955 use strict;
  1         3  
  1         31  
3 1     1   5 use warnings;
  1         2  
  1         29  
4 1     1   5 use Bif::Mo;
  1         1  
  1         8  
5              
6             our $VERSION = '0.1.5_6';
7             extends 'App::bif::show';
8              
9             sub run {
10 1     1 1 2 my $self = shift;
11 1         4 my $opts = $self->opts;
12 1         7 my $db = $self->db;
13 0 0         my $info = $self->get_project( $opts->{id} ? $opts->{id} : $opts->{path} );
14 0           my $now = $self->now;
15              
16 0           my @data;
17              
18 0           DBIx::ThinSQL->import(qw/sum case coalesce concat qv/);
19              
20             my $ref = $db->xhashref(
21             select => [
22             'nodes.id',
23             'substr(nodes.uuid,1,8) as uuid',
24             'nodes.path',
25             'projects.title',
26             'nodes.ctime AS ctime',
27             'nodes.ctimetz AS ctimetz',
28             'nodes.ctimetzhm AS ctimetzhm',
29             "$now - nodes.ctime AS ctime_age",
30             'nodes.mtime AS mtime',
31             'nodes.mtimetz AS mtimetz',
32             'nodes.mtimetzhm AS mtimetzhm',
33             "$now - nodes.mtime AS mtime_age",
34             'changes.author',
35             'changes.author_contact AS contact',
36             'changes.message',
37             'project_status.status',
38             'project_status.status',
39             'projects.local',
40             'hn.name AS hub',
41             'hn.uuid AS hub_uuid',
42             'h.location',
43             ],
44             from => 'projects',
45             inner_join => 'nodes',
46             on => 'nodes.id = projects.id',
47             inner_join => 'changes',
48             on => 'changes.id = nodes.first_change_id',
49             inner_join => 'project_status',
50             on => 'project_status.id = projects.project_status_id',
51             left_join => 'nodes hn',
52             on => 'hn.id = projects.default_hub_id',
53             left_join => 'hubs h',
54             on => 'h.id = projects.default_hub_id',
55             where => { 'projects.id' => $info->{id} },
56 0           );
57              
58 0           push( @data, $self->header( ' Path', $ref->{path}, $ref->{uuid} ), );
59             push( @data, $self->header( ' Hub', $ref->{hub}, $ref->{location} ), )
60 0 0         if $ref->{hub};
61              
62 0 0         if ( $opts->{full} ) {
63             push( @data,
64 0           $self->header( ' Creator', $ref->{author}, $ref->{contact} ),
65             $self->header( ' Created', $self->ctime_ago($ref) ),
66             );
67             }
68              
69             my @phases = $db->xarrayrefs(
70             select => [
71             case (
72             when => { status => $ref->{status} },
73             then => 'UPPER(status)',
74             else => 'status',
75             )->as('status'),
76             ],
77             from => 'project_status',
78             where => { project_id => $info->{id} },
79 0           order_by => 'rank',
80             );
81              
82             push( @data,
83 0           $self->header( ' Phases', join( ', ', map { $_->[0] } @phases ) ),
  0            
84             );
85              
86 0 0         if ( $ref->{local} ) {
87              
88             # TODO: need to use actual status names here
89             my $sth = $db->xprepare(
90             select => [
91             'ts.tkind AS tkind',
92             coalesce( sum( { 'ts.status' => 'open' } ), 0 )->as('open'),
93             coalesce( sum( { 'ts.status' => 'stalled' } ), 0 )
94             ->as('stalled'),
95             coalesce( sum( { 'ts.status' => 'closed' } ), 0 )->as('closed'),
96             coalesce( sum( { 'ts.status' => 'ignored' } ), 0 )
97             ->as('ignored'),
98             ],
99             from => 'topic_status ts',
100             inner_join => 'topics t',
101             on => 't.topic_status_id = ts.id',
102             where => { 'ts.project_id' => $info->{id} },
103 0           group_by => 'ts.tkind',
104             );
105              
106 0           $sth->execute;
107              
108 0           my $closed;
109             my $total;
110              
111 0           while ( my $row = $sth->hashref ) {
112             push(
113             @data,
114             $self->header(
115 0           ' ' . ucfirst( $row->{tkind} ),
116             "$row->{open} open, "
117             . "$row->{stalled} stalled, "
118             . "$row->{closed} closed, "
119             . "$row->{ignored} ignored"
120             ),
121             );
122 0           $closed += $row->{closed};
123 0           $total += $row->{open} + $row->{stalled} + $row->{closed};
124             }
125              
126 0 0         my $progress = $total ? int( ( $closed / $total ) * 100 ) : 0;
127              
128 0           push( @data,
129             $self->header( ' Progress', $progress . '%' ),
130             $self->header( ' Updated', $self->mtime_ago($ref) ) );
131             }
132              
133 0 0         if ( $opts->{full} ) {
134 0           require Text::Autoformat;
135             push(
136             @data,
137             $self->header(
138             'Description',
139             Text::Autoformat::autoformat(
140             $ref->{message},
141             {
142 0           right => 60,
143             all => 1
144             }
145             )
146             ),
147             );
148             }
149 0           $self->start_pager;
150 0           print $self->render_table( 'l l', [ 'Project', $ref->{title} ], \@data,
151             1 );
152              
153 0           print "\n";
154             $self->dispatch( 'App::bif::log::project',
155             opts => { path => $info->{path} } )
156 0 0         if $opts->{log};
157              
158 0           return $self->ok( 'ShowProject', \@data );
159             }
160              
161             1;
162             __END__