File Coverage

blib/lib/MooseX/Configuration/Trait/Object.pm
Criterion Covered Total %
statement 94 96 97.9
branch 23 32 71.8
condition 6 11 54.5
subroutine 16 17 94.1
pod 0 1 0.0
total 139 157 88.5


line stmt bran cond sub pod time code
1             package MooseX::Configuration::Trait::Object;
2             BEGIN {
3 1     1   7266 $MooseX::Configuration::Trait::Object::VERSION = '0.02';
4             }
5              
6 1     1   9 use Moose::Role;
  1         2  
  1         8  
7              
8 1     1   4567 use autodie;
  1         3  
  1         7  
9 1     1   4360 use namespace::autoclean;
  1         3  
  1         13  
10              
11 1     1   64 use B;
  1         3  
  1         55  
12 1     1   439 use Config::INI::Reader;
  1         19369  
  1         37  
13 1     1   329 use List::AllUtils qw( uniq );
  1         7437  
  1         93  
14 1     1   373 use MooseX::Types -declare => ['MaybeFile'];
  1         31382  
  1         6  
15 1     1   5035 use MooseX::Types::Moose qw( HashRef Maybe Str );
  1         15216  
  1         11  
16 1     1   4981 use MooseX::Types::Path::Class qw( File );
  1         38128  
  1         54  
17 1     1   1139 use Path::Class::File;
  1         2  
  1         34  
18 1     1   5 use Scalar::Util qw( looks_like_number );
  1         2  
  1         77  
19 1     1   525 use Text::Autoformat qw( autoformat );
  1         15565  
  1         772  
20              
21             subtype MaybeFile,
22             as Maybe[File];
23              
24             coerce MaybeFile,
25             from Str,
26             via { Path::Class::File->new($_) };
27              
28             has config_file => (
29             is => 'ro',
30             isa => MaybeFile,
31             coerce => 1,
32             lazy => 1,
33             builder => '_build_config_file',
34             clearer => '_clear_config_file',
35             );
36              
37             has _raw_config => (
38             is => 'ro',
39             isa => HashRef [ HashRef [Str] ],
40             lazy => 1,
41             builder => '_build_raw_config',
42             );
43              
44       0     sub _build_config_file { }
45              
46             sub _build_raw_config {
47 1     1   2 my $self = shift;
48              
49 1 50       30 my $file = $self->config_file()
50             or return {};
51              
52 1   50     22 return Config::INI::Reader->read_file($file) || {};
53             }
54              
55             sub _from_config {
56 7     7   15 my $self = shift;
57 7         14 my $section = shift;
58 7         10 my $key = shift;
59              
60 7         197 my $hash = $self->_raw_config();
61              
62 7         19 for my $key ( $section, $key ) {
63 14         28 $hash = $hash->{$key};
64              
65 14 100 66     58 return unless defined $hash && length $hash;
66             }
67              
68 6 50       13 if ( ref $hash ) {
69 0         0 die
70             "Config for $section - $key did not resolve to a non-reference value";
71             }
72              
73 6         37 return $hash;
74             }
75              
76             sub write_config_file {
77 1     1 0 1337 my $self = shift;
78 1         5 my %p = @_;
79              
80 1 50       5 my $file = exists $p{file} ? $p{file} : $self->config_file();
81              
82 1 50       4 die 'Cannot write a configuration file without a config file'
83             unless defined $file;
84              
85 1         2 my @sections;
86             my %attrs_by_section;
87              
88 1         6 for my $attr (
89 5         21 sort { $a->insertion_order() <=> $b->insertion_order() }
90 7         128 grep { $_->can('config_section') } $self->meta()->get_all_attributes()
91             ) {
92              
93 4         115 push @sections, $attr->config_section();
94 4         7 push @{ $attrs_by_section{ $attr->config_section() } }, $attr;
  4         103  
95             }
96              
97 1         5 my $content = q{};
98              
99 1 50       6 if ( $p{generated_by} ) {
100 1         6 $content .= '; ' . $p{generated_by} . "\n\n";
101             }
102              
103 1         9 for my $section ( uniq @sections ) {
104 2 100       15 unless ( $section eq q{_} ) {
105 1         6 $content .= '[' . $section . ']';
106 1         3 $content .= "\n";
107             }
108              
109 2         6 for my $attr ( @{ $attrs_by_section{$section} } ) {
  2         8  
110              
111 4         11 my $doc;
112 4 100       186 if ( $attr->has_documentation() ) {
113 3         109 $doc = autoformat( $attr->documentation() );
114 3         2911 $doc =~ s/\n\n+$/\n/;
115 3         10 $doc =~ s/^/; /gm;
116             }
117              
118 4 100       144 if ( $attr->is_required() ) {
119 1         11 $doc .= "; This configuration key is required.\n";
120             }
121              
122 4 100       149 if ( $attr->has_original_default() ) {
123 2         91 my $def = $attr->original_default();
124 2 50       8 if ( length $def ) {
125 2 100       17 $def
126             = looks_like_number($def)
127             ? $def
128             : B::perlstring($def);
129 2         8 $doc .= "; Defaults to $def\n";
130             }
131             }
132              
133 4 50       14 $content .= $doc if defined $doc;
134              
135             my $value
136             = exists $p{values}{ $attr->name() }
137 4 50       149 ? $p{values}{ $attr->name() }
138             : $self->_from_config(
139             $attr->config_section(),
140             $attr->config_key(),
141             );
142              
143 4         120 my $key = $attr->config_key();
144              
145 4 100 66     22 if ( defined $value && length $value ) {
146 3         15 $content .= "$key = $value\n";
147             }
148             else {
149 1         4 $content .= "; $key =\n";
150             }
151              
152 4         14 $content .= "\n";
153             }
154             }
155              
156 1         26 my $fh;
157              
158 1 50 33     7 if ( ref $file eq 'GLOB' || ref(\$file) eq 'GLOB' ) {
159 1         2 $fh = $file;
160             }
161             else {
162 0         0 open $fh, '>', $file;
163             }
164              
165 1         2 print {$fh} $content;
  1         8  
166 1         6 close $fh;
167             }
168              
169             1;