File Coverage

blib/lib/App/Env/_app.pm
Criterion Covered Total %
statement 77 77 100.0
branch 35 44 79.5
condition 8 11 72.7
subroutine 14 14 100.0
pod 0 8 0.0
total 134 154 87.0


line stmt bran cond sub pod time code
1             package App::Env::_app;
2              
3 28     28   266859 use v5.10;
  28         106  
4 28     28   176 use strict;
  28         54  
  28         925  
5 28     28   165 use warnings;
  28         92  
  28         2285  
6              
7             our $VERSION = '1.05';
8              
9 28     28   720 use App::Env::_Util;
  28         51  
  28         1309  
10              
11 28     28   161 use Storable ();
  28         79  
  28         654  
12 28     28   15394 use Digest;
  28         22522  
  28         32282  
13              
14             # new( pid => $pid, app => $app, opt => \%opt )
15             # new( pid => $pid, env => \%env, module => $module, cacheid => $cacheid )
16             sub new {
17 92     92 0 573 my ( $class, %opt ) = @_;
18              
19             # make copy of options
20 92         11827 my $self = bless Storable::dclone( \%opt ), $class;
21              
22 92 100       552 if ( exists $self->{env} ) {
23 5 50       21 $self->{opt} = {} unless defined $self->{opt};
24 5         40 $self->{ENV} = delete $self->{env};
25             }
26             else {
27              
28 87         212 ( $self->{module}, my $app_opts ) = eval {
29             App::Env::_Util::require_module(
30             $self->{app},
31             (
32             exists $self->{opt}{Site}
33             ? ( site => $self->{opt}{Site} )
34 87 100       615 : () ) );
35             };
36              
37 87 0       493 App::Env::_Util::croak( ref $@
    50          
38             ? $@
39             : "error loading application environment module for $self->{app}:\n", $@, )
40             if $@ ne q{};
41              
42             App::Env::_Util::croak( "application environment module for $self->{app} does not exist\n" )
43 87 100       340 unless defined $self->{module};
44              
45             # merge possible alias AppOpts
46 86   50     298 $self->{opt}{AppOpts} //= {};
47 86         216 $self->{opt}{AppOpts} = { %$app_opts, %{ $self->{opt}{AppOpts} } };
  86         343  
48              
49 86         455 $self->mk_cacheid;
50             }
51              
52             # return cached entry if possible
53 91 100 100     261 if ( App::Env::_Util::existsCacheEntry( $self->cacheid ) && !$opt{opt}{Force} ) {
54 17         42 $self = App::Env::_Util::getCacheEntry( $self->cacheid );
55             }
56              
57             else {
58 74 100       237 $self->load unless $self->{NoLoad};
59 74         162 delete $self->{NoLoad};
60             }
61              
62 91         420 return $self;
63             }
64              
65             #-------------------------------------------------------
66              
67             sub mk_cacheid {
68 88     88 0 300 my ( $self, $cacheid ) = @_;
69              
70 88 100       397 $cacheid = $self->{opt}{CacheID} unless defined $cacheid;
71              
72 88         175 my @elements;
73              
74 88 100       303 if ( defined $cacheid ) {
75 6 100       29 push @elements, $cacheid eq 'AppID' ? $self->{module} : $cacheid;
76             }
77             else {
78             # create a hash of unique stuff which will be folded
79             # into the cacheid
80 82         195 my %uniq;
81             $uniq{AppOpts} = $self->{opt}{AppOpts}
82 82 100 66     446 if defined $self->{opt}{AppOpts} && keys %{ $self->{opt}{AppOpts} };
  82         434  
83              
84 82         182 my $digest;
85              
86 82 100       237 if ( keys %uniq ) {
87 7         16 local $Storable::canonical = 1; ## no critic( Variables::ProhibitPackageVars )
88 7         56 $digest = Storable::freeze( \%uniq );
89              
90             # use whatever digest aglorithm we can find. if none is
91             # found, default to the frozen representation of the
92             # options
93 7         496 for my $alg ( qw[ SHA-256 SHA-1 MD5 ] ) {
94 7         12 my $ctx = eval { Digest->new( $alg ) };
  7         59  
95              
96 7 50       19248 if ( defined $ctx ) {
97 7         91 $digest = $ctx->add( $digest )->digest;
98 7         41 last;
99             }
100             }
101             }
102 82         319 push @elements, $self->{module}, $digest;
103             }
104              
105 88         261 $self->cacheid( join( $;, grep { defined } @elements ) );
  170         745  
106             }
107              
108              
109             #-------------------------------------------------------
110              
111             sub load {
112 72     72 0 178 my ( $self ) = @_;
113              
114             # only load if we haven't before
115 72 100       261 return $self->{ENV} if exists $self->{ENV};
116              
117 67         202 my $module = $self->module;
118              
119 67         119 my $envs;
120 67         438 my $fenvs = $module->can( 'envs' );
121              
122 67 50       229 App::Env::_Util::croak( "$module does not have an 'envs' function\n" )
123             unless $fenvs;
124              
125 67         133 $envs = eval { $fenvs->( $self->{opt}{AppOpts} ) };
  67         297  
126              
127 67 0       2130 App::Env::_Util::croak( ref $@ ? $@ : "error in ${module}::envs: $@\n" )
    50          
128             if $@;
129              
130             # make copy of environment
131 67         128 $self->{ENV} = { %{$envs} };
  67         930  
132              
133             # cache it
134 67 100       396 $self->cache if $self->{opt}{Cache};
135              
136 67         3553 return $self->{ENV};
137             }
138              
139             #-------------------------------------------------------
140              
141             sub cache {
142 45     45 0 101 my ( $self ) = @_;
143 45         136 App::Env::_Util::setCacheEntry( $self->cacheid, $self );
144             }
145              
146             #-------------------------------------------------------
147              
148             sub uncache {
149 2     2 0 6 my ( $self ) = @_;
150 2         8 my $cacheid = $self->cacheid;
151              
152             App::Env::_Util::deleteCacheEntry( $cacheid )
153             if App::Env::_Util::existsCacheEntry( $cacheid )
154 2 100 66     12 && App::Env::_Util::getCacheEntry( $cacheid )->{pid} eq $self->{pid};
155             }
156              
157             #-------------------------------------------------------
158              
159 28 100   28 0 301 sub opt { @_ > 1 ? $_[0]->{opt} = $_[1] : $_[0]->{opt} }
160 337 100   337 0 1748 sub cacheid { @_ > 1 ? $_[0]->{cacheid} = $_[1] : $_[0]->{cacheid} }
161 77     77 0 275 sub module { $_[0]->{module} }
162              
163             #-------------------------------------------------------
164              
165             1;
166              
167             #
168             # This file is part of App-Env
169             #
170             # This software is Copyright (c) 2018 by Smithsonian Astrophysical Observatory.
171             #
172             # This is free software, licensed under:
173             #
174             # The GNU General Public License, Version 3, June 2007
175             #
176              
177             __END__