File Coverage

blib/lib/Circle/Command.pm
Criterion Covered Total %
statement 48 61 78.6
branch 5 8 62.5
condition 18 23 78.2
subroutine 12 16 75.0
pod 0 12 0.0
total 83 120 69.1


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   27 use strict;
  4         9  
  4         141  
8 4     4   20 use warnings;
  4         10  
  4         154  
9              
10 4     4   21 use Attribute::Storage qw( get_subattrs get_subattr find_subs_with_attr );
  4         9  
  4         28  
11             require mro;
12              
13             sub _find_commands
14             {
15 12     12   23 my ( $obj, $cinv, $containedby ) = @_;
16              
17 12         18 my @ret;
18             my %commands;
19              
20 12         44 while( $obj ) {
21 22         276 my %subs = find_subs_with_attr( mro::get_linear_isa( ref $obj ), "Command_description",
22             matching => qr/^command_/,
23             );
24              
25 22         47585 foreach my $name ( keys %subs ) {
26 430         1084 ( my $commandname = $name ) =~ s/^command_//;
27 430         538 my $cv = $subs{$name};
28              
29 430 100       747 next if $commands{$commandname};
30              
31 419         818 my $subof = get_subattr( $cv, "Command_subof" );
32 419 100 100     5444 next if $containedby and !$subof or
      100        
      66        
      66        
      100        
      66        
33             !$containedby and $subof or
34             $containedby and $subof and $containedby ne $subof;
35              
36 85         177 my $attrs = get_subattrs( $cv );
37              
38 85         875 $commands{$commandname} = 1;
39 85         273 push @ret, __PACKAGE__->new( %$attrs,
40             name => $commandname,
41             obj => $obj,
42             cv => $cv,
43             );
44             }
45              
46             # Collect in parent too
47 22   100     186 $obj = $obj->can( "commandable_parent" ) && $obj->commandable_parent( $cinv );
48             }
49              
50 12         146 return @ret;
51             }
52              
53             sub root_commands
54             {
55 5     5 0 12 my $class = shift;
56 5         9 my ( $cinv ) = @_;
57              
58 5         21 return map { $_->name => $_ } _find_commands( $cinv->invocant, $cinv, undef );
  77         108  
59             }
60              
61             # Object stuff
62              
63             sub new
64             {
65 85     85 0 104 my $class = shift;
66 85         311 my %attrs = @_;
67              
68 85         127 $attrs{name} =~ s/_/ /g;
69              
70 85         339 return bless \%attrs, $class;
71             }
72              
73             sub sub_commands
74             {
75 7     7 0 10 my $self = shift;
76 7         13 my ( $cinv ) = @_;
77              
78 7         32 return map { $_->shortname => $_ } _find_commands( $cinv->invocant, $cinv, $self->name );
  8         18  
79             }
80              
81             sub name
82             {
83 97     97 0 90 my $self = shift; return $self->{name};
  97         301  
84             }
85              
86             sub shortname
87             {
88 8     8 0 10 my $self = shift;
89 8         18 ( split m/ /, $self->name )[-1];
90             }
91              
92             sub is_default
93             {
94 0     0 0 0 my $self = shift; return $self->{Command_default};
  0         0  
95             }
96              
97             sub desc
98             {
99 0   0 0 0 0 my $self = shift; return $self->{Command_description}[0] || "[no description]";
  0         0  
100             }
101              
102             sub detail
103             {
104 0     0 0 0 my $self = shift; return $self->{Command_description}[1];
  0         0  
105             }
106              
107             sub args
108             {
109 5     5 0 11 my $self = shift;
110 5 50       18 return unless $self->{Command_arg};
111 5         19 return @{ $self->{Command_arg} };
  5         41  
112             }
113              
114             sub opts
115             {
116 5     5 0 13 my $self = shift;
117 5         14 return $self->{Command_opt};
118             }
119              
120             sub default_sub
121             {
122 0     0 0 0 my $self = shift;
123 0         0 my ( $cinv ) = @_;
124              
125 0         0 my %subs = $self->sub_commands( $cinv );
126 0         0 my @defaults = grep { $_->is_default } values %subs;
  0         0  
127              
128 0 0       0 return $defaults[0] if @defaults == 1; # Only if it's unique
129 0         0 return;
130             }
131              
132             sub invoke
133             {
134 5     5 0 18 my $self = shift; $self->{cv}->( $self->{obj}, @_ );
  5         31  
135             }
136              
137             0x55AA;