| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Web::AssetLib::InputEngine::LocalFile; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 6 |  |  | 6 |  | 7659208 | use Method::Signatures; | 
|  | 6 |  |  |  |  | 49069 |  | 
|  | 6 |  |  |  |  | 40 |  | 
| 4 | 6 |  |  | 6 |  | 2459 | use Moose; | 
|  | 6 |  |  |  |  | 283016 |  | 
|  | 6 |  |  |  |  | 31 |  | 
| 5 | 6 |  |  | 6 |  | 23989 | use Carp; | 
|  | 6 |  |  |  |  | 10 |  | 
|  | 6 |  |  |  |  | 321 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 6 |  |  | 6 |  | 4245 | use Path::Tiny; | 
|  | 6 |  |  |  |  | 48653 |  | 
|  | 6 |  |  |  |  | 315 |  | 
| 8 |  |  |  |  |  |  |  | 
| 9 | 6 |  |  | 6 |  | 72 | use v5.14; | 
|  | 6 |  |  |  |  | 16 |  | 
| 10 | 6 |  |  | 6 |  | 21 | no if $] >= 5.018, warnings => "experimental"; | 
|  | 6 |  |  |  |  | 8 |  | 
|  | 6 |  |  |  |  | 38 |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | extends 'Web::AssetLib::InputEngine'; | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | has 'search_paths' => ( | 
| 15 |  |  |  |  |  |  | is      => 'rw', | 
| 16 |  |  |  |  |  |  | isa     => 'ArrayRef', | 
| 17 |  |  |  |  |  |  | default => sub { [] }, | 
| 18 |  |  |  |  |  |  | traits  => [qw/Array/], | 
| 19 |  |  |  |  |  |  | handles => { 'allSearchPaths' => 'elements' } | 
| 20 |  |  |  |  |  |  | ); | 
| 21 |  |  |  |  |  |  |  | 
| 22 | 6 | 50 |  | 6 |  | 192574 | method load ($asset!) { | 
|  | 4 | 50 |  | 4 |  | 7 |  | 
|  | 4 |  |  |  |  | 10 |  | 
|  | 4 |  |  |  |  | 6 |  | 
|  | 4 |  |  |  |  | 10 |  | 
| 23 |  |  |  |  |  |  | croak sprintf( "%s requires 'path' asset input_arg", ref($self) ) | 
| 24 | 4 | 50 |  |  |  | 115 | unless $asset->input_args->{path}; | 
| 25 |  |  |  |  |  |  |  | 
| 26 | 4 |  |  |  |  | 14 | my $path = $self->_findAssetPath($asset); | 
| 27 |  |  |  |  |  |  |  | 
| 28 | 4 |  |  |  |  | 25 | my $digest = $path->digest; | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | # will return undef if asset not in cache, | 
| 31 |  |  |  |  |  |  | # otherwise will return contents from previous read | 
| 32 | 4 |  |  |  |  | 6017 | my $contents = $self->getAssetFromCache($digest); | 
| 33 |  |  |  |  |  |  |  | 
| 34 | 4 | 100 |  |  |  | 12 | unless ($contents) { | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 2 |  |  |  |  | 10 | $contents = $path->slurp_utf8; | 
| 37 | 2 |  |  |  |  | 1641 | $contents =~ s/\xef\xbb\xbf//; # remove BOM if exists | 
| 38 |  |  |  |  |  |  |  | 
| 39 | 2 |  |  |  |  | 134 | $self->addAssetToCache( $digest => $contents ); | 
| 40 |  |  |  |  |  |  | } | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | $self->storeAssetContents( | 
| 43 | 4 |  |  |  |  | 21 | asset    => $asset, | 
| 44 |  |  |  |  |  |  | digest   => $digest, | 
| 45 |  |  |  |  |  |  | contents => $contents | 
| 46 |  |  |  |  |  |  | ); | 
| 47 |  |  |  |  |  |  | } | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | # search all the included search paths for the asset | 
| 50 | 6 | 50 |  | 6 |  | 10096 | method _findAssetPath ($asset!) { | 
|  | 4 | 50 |  | 4 |  | 7 |  | 
|  | 4 |  |  |  |  | 10 |  | 
|  | 4 |  |  |  |  | 6 |  | 
|  | 4 |  |  |  |  | 12 |  | 
| 51 | 4 |  |  |  |  | 167 | foreach my $path ( $self->allSearchPaths ) { | 
| 52 | 4 | 50 |  |  |  | 11 | next unless $path; | 
| 53 | 4 |  |  |  |  | 19 | $path = path($path); | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | # does the root path exist? | 
| 56 | 4 | 50 |  |  |  | 163 | unless ( $path->exists ) { | 
| 57 | 0 |  |  |  |  | 0 | $self->log->warn("skipping path '$path' - does not exist"); | 
| 58 | 0 |  |  |  |  | 0 | next; | 
| 59 |  |  |  |  |  |  | } | 
| 60 |  |  |  |  |  |  |  | 
| 61 | 4 |  |  |  |  | 322 | my $target_path = $path->child( $asset->input_args->{path} ); | 
| 62 | 4 | 50 |  |  |  | 109 | if ( $target_path->exists ) { | 
| 63 | 4 |  |  |  |  | 85 | return $target_path; | 
| 64 |  |  |  |  |  |  | } | 
| 65 |  |  |  |  |  |  | } | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | croak sprintf( | 
| 68 |  |  |  |  |  |  | "could not find asset %s in search paths (%s)", | 
| 69 |  |  |  |  |  |  | $asset->input_args->{path}, | 
| 70 | 0 |  |  |  |  |  | join( ', ', $self->allSearchPaths ) | 
| 71 |  |  |  |  |  |  | ); | 
| 72 |  |  |  |  |  |  | } | 
| 73 |  |  |  |  |  |  |  | 
| 74 | 6 |  |  | 6 |  | 1295 | no Moose; | 
|  | 6 |  |  |  |  | 8 |  | 
|  | 6 |  |  |  |  | 46 |  | 
| 75 |  |  |  |  |  |  | 1; | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  | =pod | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | =encoding UTF-8 | 
| 80 |  |  |  |  |  |  |  | 
| 81 |  |  |  |  |  |  | =head1 NAME | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | Web::AssetLib::InputEngine::LocalFile - allows importing an asset from your local filesystem | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | my $library = My::AssetLib::Library->new( | 
| 88 |  |  |  |  |  |  | input_engines => [ | 
| 89 |  |  |  |  |  |  | Web::AssetLib::InputEngine::LocalFile->new( | 
| 90 |  |  |  |  |  |  | search_paths => [ '/my/local/asset/dir' ] | 
| 91 |  |  |  |  |  |  | ) | 
| 92 |  |  |  |  |  |  | ] | 
| 93 |  |  |  |  |  |  | ); | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | # asset existing at "/my/local/asset/dir/myfile.js": | 
| 96 |  |  |  |  |  |  | my $asset = Web::AssetLib::Asset->new( | 
| 97 |  |  |  |  |  |  | type         => 'javascript', | 
| 98 |  |  |  |  |  |  | input_engine => 'LocalFile', | 
| 99 |  |  |  |  |  |  | input_args   => { path => "myfile.js", } | 
| 100 |  |  |  |  |  |  | ); | 
| 101 |  |  |  |  |  |  |  | 
| 102 |  |  |  |  |  |  | $library->compile( asset => $asset ); | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | =head1 USAGE | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | Instantiate with C<< search_paths >> parameter, and include in your library's | 
| 107 |  |  |  |  |  |  | input engine list. | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | Assets using the LocalFile input engine must provide C<< path >> input arg. | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | =head1 ATTRIBUTES | 
| 112 |  |  |  |  |  |  |  | 
| 113 |  |  |  |  |  |  | =head2 search_paths | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | Arrayref of local filesystem root paths to search when looking for an | 
| 116 |  |  |  |  |  |  | asset. | 
| 117 |  |  |  |  |  |  |  | 
| 118 |  |  |  |  |  |  | =head1 METHODS | 
| 119 |  |  |  |  |  |  |  | 
| 120 |  |  |  |  |  |  | =head2 allSearchPaths | 
| 121 |  |  |  |  |  |  |  | 
| 122 |  |  |  |  |  |  | my @paths = $engine->allSearchPaths(); | 
| 123 |  |  |  |  |  |  |  | 
| 124 |  |  |  |  |  |  | Returns a list of search paths. | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  | L<Web::AssetLib::InputEngine> | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | L<Web::AssetLib::InputEngine::RemoteFile> | 
| 131 |  |  |  |  |  |  |  | 
| 132 |  |  |  |  |  |  | L<Web::AssetLib::InputEngine::Content> | 
| 133 |  |  |  |  |  |  |  | 
| 134 |  |  |  |  |  |  | =head1 AUTHOR | 
| 135 |  |  |  |  |  |  |  | 
| 136 |  |  |  |  |  |  | Ryan Lang <rlang@cpan.org> | 
| 137 |  |  |  |  |  |  |  | 
| 138 |  |  |  |  |  |  | =cut |