File Coverage

blib/lib/Module/Setup/Flavor.pm
Criterion Covered Total %
statement 78 78 100.0
branch 29 30 96.6
condition 6 6 100.0
subroutine 12 12 100.0
pod 3 6 50.0
total 128 132 96.9


line stmt bran cond sub pod time code
1             package Module::Setup::Flavor;
2 34     34   8541 use strict;
  34         74  
  34         1196  
3 34     34   188 use warnings;
  34         120  
  34         846  
4              
5 34     34   195 use Carp ();
  34         67  
  34         495  
6 34     34   55298 use Storable ();
  34         160498  
  34         1039  
7 34     34   347 use YAML ();
  34         75  
  34         53940  
8              
9 57     57 0 24001 sub new { bless {}, shift }
10              
11             my %data_cache;
12             sub loader {
13 75     75 0 212 my $self = shift;
14 75         199 my $class = ref($self);
15 75 100       276 $class = $self unless $class;
16              
17 75 100       326 unless ($data_cache{$class}) {
18 49         238 local $/;
19 49         4437 my $data = eval "package $class; "; ## no critic
20 49 100       537 Carp::croak "flavor template class is invalid: $class" unless $data;
21              
22 48         636 my @template = YAML::Load(join '', $data);
23 48 100 100     1513615 if (scalar(@template) == 1 && !defined $template[0]) {
24 1         6 $data_cache{$class} = [];
25             } else {
26 47         490 $data_cache{$class} = \@template;
27             }
28             };
29 74         186 @{ Storable::dclone($data_cache{$class}) };
  74         9473  
30             }
31              
32             sub _import_template {
33 9     9   27 my($self, $base_class, $args) = @_;
34              
35 9         730 eval "require $base_class"; ## no critic
36 9 100       900 Carp::croak $@ if $@;
37              
38 8         91 my @base_template = $base_class->loader;
39 8         32 my @template;
40             LOOP:
41 8         30 for my $tmpl (@base_template) {
42 68 100       178 if (exists $tmpl->{config}) {
43 7 100       37 $args->{template_config} = $tmpl unless $args->{template_config};
44 7         18 next;
45             }
46 61         106 for my $type (qw/ file plugin dir /) {
47 77 100       180 next unless exists $tmpl->{$type};
48 59         138 my $key = "$type - $tmpl->{$type}";
49 59 100       237 next LOOP if $args->{template_loaded}->{$key}++;
50 58         120 my $template = delete $args->{template_index}->{$key};
51              
52 58 100 100     194 if (ref($template) eq 'HASH' && $template->{patch}) {
53             # apply patch
54 3         224 eval "require Text::Patch;";
55 3 50       7436 die $@ if $@;
56 3         21 $template->{template} = Text::Patch::patch( $tmpl->{template}, $template->{patch}, STYLE => 'Unified' );
57             }
58              
59 58 100       1197 $template = $tmpl unless $template;
60 58         84 push @template, $template;
61 58         131 next LOOP;
62             }
63 2         7 push @template, $tmpl;
64             }
65              
66 8         72 @template;
67             }
68              
69             sub import_template {
70 8     8 0 26 my($self, @base_classes) = @_;
71 8         28 my $class = ref($self);
72              
73 8         92 my @local_template = loader($self);
74              
75 8         23 my %template_index;
76             my $template_config;
77 8         20 my $anthor_key_count = 0;
78             LOOP:
79 8         30 for my $tmpl (@local_template) {
80 15 100       55 if (exists $tmpl->{config}) {
81 2         3 $template_config = $tmpl;
82 2         4 next;
83             }
84 13         34 for my $type (qw/ file plugin dir /) {
85 23 100       66 next unless exists $tmpl->{$type};
86 11         49 $template_index{"$type - $tmpl->{$type}"} = $tmpl;
87 11         39 next LOOP;
88             }
89 2         12 $template_index{'anthor - ' . $anthor_key_count++} = $tmpl;
90             }
91              
92 8         46 my $args = {
93             template_config => $template_config,
94             template_index => \%template_index,
95             };
96 8         24 my @template;
97 8         26 for my $base_class (reverse @base_classes) {
98 9         98 push @template, $self->_import_template($base_class, $args);
99             }
100              
101 7         19 for my $tmpl (values %{ $args->{template_index} }) {
  7         42  
102 2         4 push @template, $tmpl;
103             }
104 7 100       35 push @template, $args->{template_config} if $args->{template_config};
105              
106 7         193 @template;
107             }
108              
109 52     52 1 236 sub setup_flavor { 1 }
110              
111             sub setup_config {
112 15     15 1 69 my($self, $context, $config) = @_;
113             }
114              
115             sub setup_additional {
116 5     5 1 22 my($self, $context, $config) = @_;
117             }
118              
119              
120             1;
121              
122             =head1 NAME
123              
124             Module::Setup::Flavor - Module::Setup Flavor
125              
126             =head1 Flavor Hook Point
127              
128             =head2 setup_flavor
129              
130             flavor setup, if return value is false is exit create flavor
131              
132             =head2 setup_config
133              
134             before flavors plugin load
135              
136             =head2 setup_additional
137              
138             end of additional flavor install
139              
140             =cut
141              
142             __DATA__