File Coverage

blib/lib/Circle/Command.pm
Criterion Covered Total %
statement 48 61 78.6
branch 5 8 62.5
condition 20 23 86.9
subroutine 12 16 75.0
pod 0 12 0.0
total 85 120 70.8


line stmt bran cond sub pod time code
1             # You may distribute under the terms of the GNU General Public License
2             #
3             # (C) Paul Evans, 2008-2014 -- leonerd@leonerd.org.uk
4              
5             package Circle::Command;
6              
7 4     4   22 use strict;
  4         8  
  4         94  
8 4     4   18 use warnings;
  4         6  
  4         137  
9              
10             our $VERSION = '0.173320';
11              
12 4     4   17 use Attribute::Storage qw( get_subattrs get_subattr find_subs_with_attr );
  4         8  
  4         64  
13             require mro;
14              
15             sub _find_commands
16             {
17 12     12   26 my ( $obj, $cinv, $containedby ) = @_;
18              
19 12         17 my @ret;
20             my %commands;
21              
22 12         26 while( $obj ) {
23 22         221 my %subs = find_subs_with_attr( mro::get_linear_isa( ref $obj ), "Command_description",
24             matching => qr/^command_/,
25             );
26              
27 22         46458 foreach my $name ( keys %subs ) {
28 444         1068 ( my $commandname = $name ) =~ s/^command_//;
29 444         567 my $cv = $subs{$name};
30              
31 444 100       667 next if $commands{$commandname};
32              
33 432         617 my $subof = get_subattr( $cv, "Command_subof" );
34 432 100 100     5150 next if $containedby and !$subof or
      100        
      100        
      66        
      100        
      100        
35             !$containedby and $subof or
36             $containedby and $subof and $containedby ne $subof;
37              
38 90         143 my $attrs = get_subattrs( $cv );
39              
40 90         1004 $commands{$commandname} = 1;
41 90         231 push @ret, __PACKAGE__->new( %$attrs,
42             name => $commandname,
43             obj => $obj,
44             cv => $cv,
45             );
46             }
47              
48             # Collect in parent too
49 22   100     130 $obj = $obj->can( "commandable_parent" ) && $obj->commandable_parent( $cinv );
50             }
51              
52 12         146 return @ret;
53             }
54              
55             sub root_commands
56             {
57 5     5 0 10 my $class = shift;
58 5         8 my ( $cinv ) = @_;
59              
60 5         19 return map { $_->name => $_ } _find_commands( $cinv->invocant, $cinv, undef );
  82         102  
61             }
62              
63             # Object stuff
64              
65             sub new
66             {
67 90     90 0 118 my $class = shift;
68 90         271 my %attrs = @_;
69              
70 90         158 $attrs{name} =~ s/_/ /g;
71              
72 90         260 return bless \%attrs, $class;
73             }
74              
75             sub sub_commands
76             {
77 7     7 0 10 my $self = shift;
78 7         22 my ( $cinv ) = @_;
79              
80 7         28 return map { $_->shortname => $_ } _find_commands( $cinv->invocant, $cinv, $self->name );
  8         15  
81             }
82              
83             sub name
84             {
85 102     102 0 112 my $self = shift; return $self->{name};
  102         219  
86             }
87              
88             sub shortname
89             {
90 8     8 0 9 my $self = shift;
91 8         14 ( split m/ /, $self->name )[-1];
92             }
93              
94             sub is_default
95             {
96 0     0 0 0 my $self = shift; return $self->{Command_default};
  0         0  
97             }
98              
99             sub desc
100             {
101 0   0 0 0 0 my $self = shift; return $self->{Command_description}[0] || "[no description]";
  0         0  
102             }
103              
104             sub detail
105             {
106 0     0 0 0 my $self = shift; return $self->{Command_description}[1];
  0         0  
107             }
108              
109             sub args
110             {
111 5     5 0 8 my $self = shift;
112 5 50       34 return unless $self->{Command_arg};
113 5         9 return @{ $self->{Command_arg} };
  5         18  
114             }
115              
116             sub opts
117             {
118 5     5 0 8 my $self = shift;
119 5         13 return $self->{Command_opt};
120             }
121              
122             sub default_sub
123             {
124 0     0 0 0 my $self = shift;
125 0         0 my ( $cinv ) = @_;
126              
127 0         0 my %subs = $self->sub_commands( $cinv );
128 0         0 my @defaults = grep { $_->is_default } values %subs;
  0         0  
129              
130 0 0       0 return $defaults[0] if @defaults == 1; # Only if it's unique
131 0         0 return;
132             }
133              
134             sub invoke
135             {
136 5     5 0 10 my $self = shift; $self->{cv}->( $self->{obj}, @_ );
  5         24  
137             }
138              
139             0x55AA;