File Coverage

lib/Amon2/Setup/Flavor.pm
Criterion Covered Total %
statement 101 131 77.1
branch 14 36 38.8
condition 4 9 44.4
subroutine 23 30 76.6
pod 3 14 21.4
total 145 220 65.9


line stmt bran cond sub pod time code
1 3     3   1245 use strict;
  3         7  
  3         89  
2 3     3   15 use warnings;
  3         6  
  3         71  
3 3     3   17 use utf8;
  3         14  
  3         15  
4              
5             use Text::Xslate;
6 3     3   1732 use File::Spec;
  3         36344  
  3         158  
7 3     3   23 use File::Basename;
  3         8  
  3         58  
8 3     3   14 use File::Path ();
  3         6  
  3         255  
9 3     3   22 use Amon2;
  3         19  
  3         64  
10 3     3   1316 use Plack::Util ();
  3         8  
  3         91  
11 3     3   18 use Carp ();
  3         7  
  3         37  
12 3     3   14 use Amon2::Trigger;
  3         4  
  3         58  
13 3     3   1164 use mro;
  3         9  
  3         175  
14 3     3   19 use File::ShareDir ();
  3         6  
  3         12  
15 3     3   1560 use Module::CPANfile 0.9020;
  3         77325  
  3         106  
16 3     3   1355  
  3         42458  
  3         4590  
17             my $self = shift;
18              
19 1     1 0 3 my @assets = qw(
20             jQuery Bootstrap MicroTemplateJS StrftimeJS SprintfJS
21 1         7 MicroLocationJS MicroDispatcherJS XSRFTokenJS
22             );
23             @assets;
24             }
25 1         4  
26             my $caller = do {
27             my $x;
28             for (1..10) {
29 57     57 0 121 $x = caller($_);
30 57         75 last if $x ne __PACKAGE__;
31 57         158 }
32 120         238 $x;
33 120 100       269 };
34             $caller =~ s/^Amon2::Setup:://;
35 57         107 print "[$caller] ";
36             @_==1 ? print(@_) : printf(@_);
37 57         100 print "\n";
38 57         1884 }
39 57 50       493  
40 57         366 my $class = shift;
41             my %args = @_ ==1 ? %{$_[0]} : @_;
42              
43             $args{amon2_version} = $Amon2::VERSION;
44 1     1 0 1485  
45 1 50       8 for (qw/module/) {
  0         0  
46             die "Missing mandatory parameter $_" unless exists $args{$_};
47 1         3 }
48             $args{module} =~ s!-!::!g;
49 1         22  
50 1 50       14 # $module = "Foo::Bar"
51             # $dist = "Foo-Bar"
52 1         4 # $path = "Foo/Bar"
53             my @pkg = split /::/, $args{module};
54             $args{dist} = join "-", @pkg;
55             $args{path} = join "/", @pkg;
56             my $self = bless { %args }, $class;
57 1         5 $self->{xslate} = $self->_build_xslate();
58 1         5 $self->load_assets();
59 1         3 $self;
60 1         5 }
61 1         5  
62 1         5 my $self = shift;
63 1         9  
64             my $xslate = Text::Xslate->new(
65             syntax => 'Kolon',
66             type => 'text',
67 1     1   1 tag_start => '<%',
68             tag_end => '%>',
69 1         7 line_start => '%%',
70             path => [ File::Spec->catdir(File::ShareDir::dist_dir('Amon2'), 'flavor') ],
71             module => [
72             'Amon2::Util' => ['random_string'],
73             ],
74             );
75             $xslate;
76             }
77              
78              
79             my ($self, $path) = @_;
80 1         8330 Carp::croak("path should not be ref") if ref $path;
81             infof("mkpath: $path");
82             File::Path::mkpath($path);
83 0     0 0 0 }
84              
85             my $self = shift;
86 0     0 1 0 my $template = shift;
87 0 0       0 my %args = @_==1 ? %{$_[0]} : @_;
88 0         0 return $self->{xslate}->render_string($template, {%$self, %args});
89 0         0 }
90              
91             my ($self, $dstname, $filename, $params) = @_;
92             Carp::croak("filename should not be reference") if ref $filename;
93 0     0 0 0 $dstname =~ s/<<([^>]+)>>/$self->{lc($1)} or die "$1 is not defined. But you want to use $1 in filename."/ge;
94 0         0  
95 0 0       0 my $content = $self->{xslate}->render($filename, {%$self, $params ? %$params : () });
  0         0  
96 0         0 $self->write_file_raw($dstname, $content);
97             }
98              
99             my ($self, $filename, $template) = (shift, shift, shift);
100 0     0 0 0 Carp::croak("filename should not be reference") if ref $filename;
101 0 0       0  
102 0 0       0 $filename =~ s/<<([^>]+)>>/$self->{lc($1)} or die "$1 is not defined. But you want to use $1 in filename."/ge;
  0         0  
103              
104 0 0       0 my $content = $self->render_string($template, @_);
105 0         0 $self->write_file_raw($filename, $content);
106             }
107              
108             my ($self, $filename, $content, $input_mode) = @_;
109 0     0 1 0 Carp::croak("filename should not be reference") if ref $filename;
110 0 0       0 $input_mode ||= '>:encoding(utf-8)';
111              
112 0 0       0 infof("writing $filename");
  0         0  
113              
114 0         0 my $dirname = dirname($filename);
115 0         0 File::Path::mkpath($dirname) if $dirname;
116              
117             open my $ofh, $input_mode, $filename or die "Cannot open file: $filename: $!";
118             print {$ofh} $content;
119 47     47 1 101 close $ofh;
120 47 50       91 }
121 47   50     81  
122             my ($self) = @_;
123 47         136 for my $asset ($self->assets) {
124             $self->load_asset($asset);
125 47         1477 }
126 47 50       1837 }
127              
128 1 50   1   9 my ($self, $asset) = @_;
  1         3  
  1         9  
  47         3306  
129 47         17758 infof("Loading asset: $asset");
  47         17667  
130 47         1553 my $klass = Plack::Util::load_class($asset, 'Amon2::Setup::Asset');
131              
132             my $require_newline = $self->{tags} ? 1 : 0;
133             $self->{tags} .= $klass->tags;
134 1     1 0 3 $self->{tags} .= "\n" if $require_newline && $self->{tags} !~ /\n\z/;
135 1         8  
136 8         26 # $klass->run($self);
137             }
138              
139             my ($self, $asset, $base) = @_;
140             $asset || die "Missing asset name";
141 10     10 0 36 $base ||= 'static/';
142 10         37  
143 10         43 my $klass = Plack::Util::load_class($asset, 'Amon2::Setup::Asset');
144             my $files = $klass->files;
145 10 100       145 while (my ($fname, $content) = each %$files) {
146 10         161 my $layer = $fname =~ /\.js\z/ ? '>:encoding(utf-8)' : '>:raw';
147 10 50 66     102 $self->write_file_raw("$base/$fname", $content, $layer);
148             }
149             }
150              
151             my ($self, $dst) = @_;
152              
153 2     2 0 15 for my $asset ($self->assets) {
154 2 50       8 $self->write_asset($asset, $dst);
155 2   50     14 }
156             }
157 2         8  
158 2         47 my ($self, $runtime_deps) = @_;
159 2         12 $runtime_deps ||= +{};
160 47 100       235  
161 47         248 my $cpanfile = Module::CPANfile->from_prereqs(
162             {
163             runtime => {
164             requires => {
165             'perl' => '5.010_001',
166 0     0 0   'Amon2' => $Amon2::VERSION,
167             'Text::Xslate' => '2.0009',
168 0           'Starlet' => '0.20',
169 0           'Module::Functions' => 2,
170             %$runtime_deps,
171             },
172             },
173             configure => {
174 0     0 0   requires => {
175 0   0       'Module::Build' => '0.38',
176             'Module::CPANfile' => '0.9010',
177 0           },
178             },
179             test => {
180             requires => {
181             'Test::More' => '0.98',
182             },
183             },
184             }
185             );
186             $self->write_file('cpanfile', $cpanfile->to_string());
187             }
188              
189             1;
190              
191             =head1 NAME
192              
193             Amon2::Setup::Flavor - Abstract base class for flavors.
194              
195             =head1 DESCRIPTION
196              
197             This is an abstract base class for flavors. But you don't need to inherit this class. Amon2 uses duck typing. You should implement only C<< Class->run >> method.
198              
199             In Amon2, flavor means setup script.
200              
201             =head1 METHODS
202 0            
203             This class provides some useful methods to write setup script.
204              
205             =over 4
206              
207             =item C<< $flavor->init() >>
208              
209             Hook point to initialize module directory.
210              
211             =item C<< $flavor->mkpath($dir) >>
212              
213             same as C<< `mkdir -p $dir` >>.
214              
215             =item C<< $flavor->write_file($fnametmpl, $template) >>
216              
217             C<< $fnametmpl >> will be replace with the parameters.
218              
219             Generate file using L<Text::Xslate>.
220              
221             For more details, read the source Luke! Or please write docs...
222              
223             =item C<< $flavor->write_file_raw($fname, $content) >>
224              
225             Write C<< $content >> to the C<< $fname >>.
226              
227             =back
228