File Coverage

blib/lib/Web/AssetLib/Library.pm
Criterion Covered Total %
statement 83 112 74.1
branch 25 54 46.3
condition 3 12 25.0
subroutine 20 22 90.9
pod n/a
total 131 200 65.5


line stmt bran cond sub pod time code
1             package Web::AssetLib::Library;
2              
3 6     6   5252832 use Method::Signatures;
  6         48848  
  6         52  
4 6     6   2565 use Moose;
  6         278836  
  6         31  
5 6     6   25577 use Carp;
  6         10  
  6         359  
6 6     6   21 use Scalar::Util qw/blessed/;
  6         9  
  6         209  
7              
8 6     6   2389 use Web::AssetLib::Asset;
  6         125  
  6         418  
9              
10             with 'Web::AssetLib::Role::Logger';
11              
12             has 'input_engines' => (
13             is => 'rw',
14             isa => 'ArrayRef[Web::AssetLib::InputEngine]',
15             traits => [qw/Array/],
16             handles => { _findInputEngine => 'first', allInputEngines => 'elements' }
17             );
18              
19             has 'minifier_engines' => (
20             is => 'rw',
21             isa => 'ArrayRef[Web::AssetLib::MinifierEngine]',
22             traits => [qw/Array/],
23             handles =>
24             { _findMinifierEngine => 'first', allMinifierEngines => 'elements' }
25             );
26              
27             has 'output_engines' => (
28             is => 'rw',
29             isa => 'ArrayRef[Web::AssetLib::OutputEngine]',
30             traits => [qw/Array/],
31             handles =>
32             { _findOutputEngine => 'first', allOutputEngines => 'elements' }
33             );
34              
35 6 100   6   40239 method compile (:$bundle, :$asset, :$output_engine = 'LocalFile',
  6     6   720  
  6         42  
  6         18  
  6         12  
  6         12  
  6         18  
  6         22  
  6         13  
  6         8  
36 6 100       25 :$minifier_engine = 'Standard') {
  6 50       10  
  6 50       27  
  6         18  
37              
38             # possible to pass in a minifier object here
39 6 50 33     72 $minifier_engine = $self->findMinifierEngine($minifier_engine)
40             if $minifier_engine && !blessed($minifier_engine);
41              
42 6         36 $output_engine = $self->findOutputEngine($output_engine);
43              
44 6 50 33     58 if ( $asset && !$bundle ) {
    50 33        
    0 0        
45 0         0 return $self->_compileAsset(
46             asset => $asset,
47             output_engine => $output_engine,
48             minifier_engine => $minifier_engine
49             );
50             }
51             elsif ( $bundle && !$asset ) {
52 6         35 return $self->_compileBundle(
53             bundle => $bundle,
54             output_engine => $output_engine,
55             minifier_engine => $minifier_engine
56             );
57             }
58             elsif ( $bundle && $asset ) {
59 0         0 croak "cannot provide both bundle and asset - dont know what to do";
60             }
61             else {
62 0         0 croak "either asset or bundle must be provided";
63             }
64             }
65              
66 6 50   6   20459 method _compileBundle (:$bundle!, :$output_engine!, :$minifier_engine?) {
  6 50   6   12  
  6 50       36  
  6 50       21  
  6         11  
  6         10  
  6         33  
  6         13  
  6         12  
  6         12  
  6         8  
  6         19  
  6         16  
67              
68 6         43 $self->log->dump( 'attempting to compile assets=',
69             $bundle->assets, 'trace' );
70              
71 6         216 foreach my $asset ( $bundle->allAssets ) {
72 12         352 my $input_engine = $self->findInputEngine( $asset->input_engine );
73              
74             # populate contents and digest attributes
75 12         76 $input_engine->load($asset);
76              
77             # bundle should not contain assets with matching
78             # fingerprints, but it's possible that two assets
79             # can have different fingerprints, but the same digest
80             # (same file, different parameters)
81              
82 11 100       336 if ( $asset->digest ) {
83 10 50       251 if ( $bundle->getDigest( $asset->digest ) ) {
84             my $idx
85             = $bundle->findAssetIdx(
86 0     0   0 sub { $_->digest eq $asset->digest } );
  0         0  
87 0         0 $bundle->deleteAsset($idx);
88 0         0 $self->log->dump( 'duplicate digest found for asset=',
89             $bundle->getAsset($idx), 'trace' );
90             }
91             else {
92 10         288 $bundle->addDigest( $asset->digest => 1 );
93             }
94             }
95             }
96              
97 5         171 $bundle->_set_isCompiled(1);
98              
99             # output
100 5         101 return $output_engine->_export(
101             bundle => $bundle,
102             minifier => $minifier_engine
103             );
104             }
105              
106 6 0   6   19104 method _compileAsset (:$asset!,:$output_engine!, :$minifier_engine?) {
  0 0   0   0  
  0 0       0  
  0 0       0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
107 0         0 my $input_engine = $self->findInputEngine( $asset->input_engine );
108 0         0 $input_engine->load($asset);
109              
110 0         0 $asset->_set_isCompiled(1);
111              
112 0         0 return $output_engine->_export(
113             asset => $asset,
114             minifier => $minifier_engine
115             );
116             }
117              
118 6 50   6   9737 method findInputEngine ($name!) {
  12 50   12   29  
  12         45  
  12         20  
  12         34  
119 12     20   526 my $engine = $self->_findInputEngine( sub { ref($_) =~ /$name/ } );
  20         189  
120 12 50       63 return $engine if $engine;
121              
122             croak
123             sprintf( "could not find input engine $name - available engines: %s",
124 0         0 join( ', ', map { ref($_) } $self->allInputEngines ) );
  0         0  
125             }
126              
127 6 50   6   9383 method findMinifierEngine ($name!) {
  6 50   6   13  
  6         21  
  6         11  
  6         18  
128 6     6   276 my $engine = $self->_findMinifierEngine( sub { ref($_) =~ /$name/ } );
  6         128  
129 6 50       34 return $engine if $engine;
130              
131             croak
132             sprintf(
133             "could not find minifier engine $name - available engines: %s",
134 0         0 join( ', ', map { ref($_) } $self->allMinifierEngines ) );
  0         0  
135             }
136              
137 6 50   6   9294 method findOutputEngine ($name!) {
  6 50   6   15  
  6         20  
  6         10  
  6         18  
138 6     7   255 my $engine = $self->_findOutputEngine( sub { ref($_) =~ /$name/ } );
  7         55  
139 6 50       40 return $engine if $engine;
140              
141             croak
142             sprintf( "could not find output engine $name - available engines: %s",
143 0           join( ', ', map { ref($_) } $self->allOutputEngines ) );
  0            
144             }
145              
146 6     6   946 no Moose;
  6         10  
  6         44  
147             1;
148              
149             =pod
150            
151             =encoding UTF-8
152            
153             =head1 NAME
154              
155             Web::AssetLib::Library - a base class for writing your own asset library, and configuring the various pipeline plugins
156              
157             =head1 SYNOPSIS
158              
159             Create a library for your project:
160              
161             package My::Library;
162              
163             use Moose;
164              
165             extends 'Web::AssetLib::Library';
166              
167             sub jQuery{
168             return Web::AssetLib::Asset->new(
169             type => 'javascript',
170             input_engine => 'LocalFile',
171             rank => -100,
172             input_args => { path => "your/local/path/jquery.min.js", }
173             );
174             }
175              
176             1;
177              
178             Instantiate your library
179              
180             use My::Library;
181              
182             # configure at least one input and one output plugin
183             # (and optionally, a minifier plugin)
184             my $lib = My::Library->new(
185             input_engines => [
186             Web::AssetLib::InputEngine::LocalFile->new(
187             search_paths => ['/my/assets/root/']
188             )
189             ],
190             output_engines => [
191             Web::AssetLib::OutputEngine::LocalFile->new(
192             output_path => '/my/webserver/path/assets/'
193             )
194             ]
195             );
196              
197             # create an asset bundle to represent a group of assets
198             # that should be compiled together:
199              
200             my $homepage_javascript = Web::AssetLib::Bundle->new();
201             $hompage_javascript->addAsset($lib->jQuery);
202              
203              
204             # compile your bundle
205             my $html_tag = $lib->compile( bundle => $homepage_javascript )->as_html;
206              
207             =head1 DESCRIPTION
208              
209             Web::AssetLib::Library holds the instances of the plugins you wish to use. It is also suggested that
210             this class be subclassed and used as a place to manage availalbe assets.
211              
212             =head1 ATTRIBUTES
213            
214             =head2 input_engines
215            
216             Arrayref of L<Web::AssetLib::InputEngine> instance(s) that you wish to use with your library
217              
218             =head2 minifier_engines
219            
220             Arrayref of L<Web::AssetLib::MinifierEngine> instance(s) that you wish to use with your library
221            
222             =head2 output_engines
223            
224             Arrayref of L<Web::AssetLib::OutputEngine> instance(s) that you wish to use with your library
225              
226             =head1 METHODS
227            
228             =head2 compile( :$bundle, :$asset, :$output_engine = 'LocalFile', :$minifier_engine = 'Standard' )
229            
230             $library->compile( bundle => $bundle )
231             $library->compile( asset => $asset )
232              
233             # specify desired output and/or minifier engine:
234             $library->compile( ..., output_engine => 'String', minifier_engine => 'CustomMinifier' );
235              
236             # skip minification
237             $library->compile( bundle => $bundle, minifier_engine => undef )
238              
239             print $bundle->as_html();
240             print $library->compile( bundle => $bundle )->as_html()
241             # <script src="/your/output.js" type="text/javascript"></script>
242              
243             Combines and processes a bundle or asset, sending it through the provided minifer, and
244             provided output engine. Provide a type to selectively filter to only a single file type.
245              
246             =head3 parameters
247              
248             One of:
249              
250             =over 4
251            
252             =item *
253            
254             C<< bundle >> - L<Web::AssetLib::Bundle> object
255              
256             =item *
257              
258             C<< asset >> - L<Web::AssetLib::Asset> object
259            
260             =back
261              
262             Optionally:
263              
264             =over 4
265              
266             =item *
267            
268             C<< output_engine >> — string; partial class name that will match one of the provided
269             output_engines for your library (defaults to "LocalFile")
270            
271             =item *
272            
273             C<< minifier_engine >> — string; partial class name that will match one of the provided
274             minifer_engines for your library. Set to undef if no minification is desired. (defaults to "Standard")
275            
276             =item *
277            
278             C<< type >> — string; filter compilation by file type (will output only assets of this type). The following types are supported: js, javascript, css, stylesheet.
279              
280             =item *
281            
282             C<< html_attrs >> — hashref; attributes to be included in output html
283              
284             =back
285              
286             =head1 AUTHOR
287            
288             Ryan Lang <rlang@cpan.org>
289              
290             =cut