File Coverage

blib/lib/Pcore/Core/Env/Share.pm
Criterion Covered Total %
statement 44 102 43.1
branch 12 58 20.6
condition 0 3 0.0
subroutine 5 8 62.5
pod 0 5 0.0
total 61 176 34.6


line stmt bran cond sub pod time code
1             package Pcore::Core::Env::Share;
2              
3 5     5   39 use Pcore -class, -const;
  5         12  
  5         45  
4 5     5   54 use Pcore::Util::Scalar qw[is_plain_arrayref is_plain_hashref];
  5         14  
  5         46  
5              
6             has _temp => ( is => 'lazy', isa => InstanceOf ['Pcore::Util::File::TempDir'], init_arg => undef );
7             has _lib => ( is => 'ro', isa => HashRef, default => sub { {} }, init_arg => undef ); # name => [$level, $path]
8             has _storage => ( is => 'lazy', isa => HashRef, default => sub { {} }, clearer => 1, init_arg => undef ); # storage cache, name => [$path, ...]
9             has _lib_storage => ( is => 'lazy', isa => HashRef, default => sub { {} }, init_arg => undef ); # lib storage cache, {lib}->{storage} = $path
10              
11             const our $RESERVED_LIB_NAME => {
12             dist => 1, # alias for main dist
13             temp => 1, # temporary resources lib
14             };
15              
16 0     0   0 sub _build__temp ($self) {
  0         0  
  0         0  
17 0         0 return P->file->tempdir;
18             }
19              
20 5     5 0 386 sub add_lib ( $self, $name, $path, $level ) {
  5         14  
  5         15  
  5         13  
  5         13  
  5         10  
21 5 50       33 die qq[resource lib name "$name" is reserved] if exists $RESERVED_LIB_NAME->{$name};
22              
23 5 50       29 die qq[resource lib "$name" already exists] if exists $self->_lib->{$name};
24              
25             # register lib
26 5         28 $self->_lib->{$name} = [ $level, $path ];
27              
28             # clear cache
29 5         116 $self->_clear_storage;
30              
31 5         38 return;
32             }
33              
34             # return lib path by name
35 0     0 0 0 sub get_lib ( $self, $lib_name ) {
  0         0  
  0         0  
  0         0  
36 0         0 \my $libs = \$self->_lib;
37              
38 0 0       0 if ( $ENV->is_par ) {
    0          
39              
40             # under the PAR all resources libs are merged under the "dist" alias
41 0         0 return $libs->{dist}->[1];
42             }
43             elsif ( $lib_name eq 'temp' ) {
44 0         0 return $self->_temp->path;
45             }
46             else {
47 0 0       0 if ( $lib_name eq 'dist' ) {
48 0 0       0 if ( my $dist = $ENV->dist ) {
49 0         0 $lib_name = lc $dist->name;
50             }
51             else {
52 0         0 return;
53             }
54             }
55              
56 0 0       0 return if !exists $libs->{$lib_name};
57              
58 0         0 return $libs->{$lib_name}->[1];
59             }
60             }
61              
62             # return undef if storage is not exists
63             # return $storage_path if lib is specified
64             # return ArrayRef[$storage_path] if lib is not specified
65 5     5 0 13 sub get_storage ( $self, $storage_name, $lib_name = undef ) {
  5         10  
  5         13  
  5         15  
  5         11  
66 5         33 \my $libs = \$self->_lib;
67              
68 5 50       19 if ($lib_name) {
69 0         0 my $lib_path = $self->get_lib($lib_name);
70              
71 0 0       0 die qq[resource lib is not exists "$lib_name"] if !$lib_path;
72              
73 0         0 \my $lib_storage = \$self->_lib_storage;
74              
75             # cache lib/storage path, if not cached yet
76 0 0       0 if ( !exists $lib_storage->{$lib_name}->{$storage_name} ) {
77 0 0       0 if ( -d "${lib_path}${storage_name}" ) {
78 0         0 $lib_storage->{$lib_name}->{$storage_name} = $lib_path . $storage_name;
79             }
80             else {
81 0         0 $lib_storage->{$lib_name}->{$storage_name} = undef;
82             }
83             }
84              
85             # return cached path
86 0         0 return $lib_storage->{$lib_name}->{$storage_name};
87             }
88             else {
89 5         124 \my $storage = \$self->_storage;
90              
91             # build and cache storage paths array
92 5 100       68 if ( !exists $storage->{$storage_name} ) {
93 4         35 for my $lib_name ( sort { $libs->{$b}->[0] <=> $libs->{$a}->[0] } keys $libs->%* ) {
  0         0  
94 4         27 my $storage_path = $libs->{$lib_name}->[1] . $storage_name;
95              
96 4 50       148 push $storage->{$storage_name}->@*, $storage_path if -d $storage_path;
97             }
98              
99 4 50       24 $storage->{$storage_name} = undef if !exists $storage->{$storage_name};
100             }
101              
102             # return cached value
103 5         37 return $storage->{$storage_name};
104             }
105             }
106              
107 5     5 0 110 sub get ( $self, $path, @ ) {
  5         14  
  5         12  
  5         10  
108 5         33 my %args = (
109             storage => undef,
110             lib => undef,
111             splice @_, 2,
112             );
113              
114             # get storage name from path
115 5 50       27 if ( !$args{storage} ) {
116 5 50       37 if ( $path =~ m[\A/?([^/]+)/(.+)]sm ) {
117 5         24 $args{storage} = $1;
118              
119 5         132 $path = P->path( q[/] . $2 );
120             }
121             else {
122 0         0 die qq[invalid resource path "$path"];
123             }
124             }
125             else {
126 0         0 $path = P->path( q[/] . $path );
127             }
128              
129 5 50       43 if ( $args{lib} ) {
    50          
130 0 0       0 if ( my $storage_path = $self->get_storage( $args{storage}, $args{lib} ) ) {
131 0         0 my $res = $storage_path . $path;
132              
133 0 0       0 return $res if -f $res;
134             }
135             }
136             elsif ( my $storage = $self->get_storage( $args{storage} ) ) {
137 5         17 for my $storage_path ( $storage->@* ) {
138 5         222 my $res = $storage_path . $path;
139              
140 5 50       292 return $res if -f $res;
141             }
142             }
143              
144 0           return;
145             }
146              
147 0     0 0   sub store ( $self, $path, $file, $lib_name, @ ) {
  0            
  0            
  0            
  0            
  0            
148 0           my %args = (
149             storage => undef,
150             splice @_, 4,
151             );
152              
153 0           my $lib_path = $self->get_lib($lib_name);
154              
155 0 0         die qq[resource lib is not exists "$lib_name"] if !$lib_path;
156              
157             # get storage name from path
158 0 0         if ( !$args{storage} ) {
159 0 0         if ( $path =~ m[\A/?([^/]+)/(.+)]sm ) {
160 0           $args{storage} = $1;
161              
162 0           $path = P->path( q[/] . $2 );
163             }
164             else {
165 0           die qq[invalid resource path "$path"];
166             }
167             }
168             else {
169 0           $path = P->path( q[/] . $path );
170             }
171              
172             # clear storage cache if new storage was created
173 0 0         if ( !-d "${lib_path}$args{storage}" ) {
174 0           delete $self->_storage->{ $args{storage} };
175              
176 0 0         delete $self->_lib_storage->{$lib_name}->{ $args{storage} } if exists $self->_lib_storage->{$lib_name};
177             }
178              
179             # create path
180 0 0         P->file->mkpath( $lib_path . $args{storage} . $path->dirname ) if !-d "${lib_path}$args{storage}@{[$path->dirname]}";
  0            
181              
182             # create file
183 0 0 0       if ( ref $file eq 'SCALAR' ) {
    0          
184 0           P->file->write_bin( $lib_path . $args{storage} . $path, $file );
185             }
186             elsif ( is_plain_arrayref $file || is_plain_hashref $file ) {
187 0           P->cfg->store( $lib_path . $args{storage} . $path, $file, readable => 1 );
188             }
189             else {
190 0           P->file->copy( $file, $lib_path . $args{storage} . $path );
191             }
192              
193 0           return $lib_path . $args{storage} . $path;
194             }
195              
196             1;
197             ## -----SOURCE FILTER LOG BEGIN-----
198             ##
199             ## PerlCritic profile "pcore-script" policy violations:
200             ## +------+----------------------+----------------------------------------------------------------------------------------------------------------+
201             ## | Sev. | Lines | Policy |
202             ## |======+======================+================================================================================================================|
203             ## | 3 | 147 | Subroutines::ProhibitManyArgs - Too many arguments |
204             ## |------+----------------------+----------------------------------------------------------------------------------------------------------------|
205             ## | 1 | 93 | BuiltinFunctions::ProhibitReverseSortBlock - Forbid $b before $a in sort blocks |
206             ## +------+----------------------+----------------------------------------------------------------------------------------------------------------+
207             ##
208             ## -----SOURCE FILTER LOG END-----
209             __END__
210             =pod
211              
212             =encoding utf8
213              
214             =head1 NAME
215              
216             Pcore::Core::Env::Share
217              
218             =head1 SYNOPSIS
219              
220             =head1 DESCRIPTION
221              
222             =head1 ATTRIBUTES
223              
224             =head1 METHODS
225              
226             =head1 SEE ALSO
227              
228             =cut