File Coverage

blib/lib/lazy.pm
Criterion Covered Total %
statement 41 48 85.4
branch 7 10 70.0
condition 11 15 73.3
subroutine 8 9 88.8
pod n/a
total 67 82 81.7


line stmt bran cond sub pod time code
1             package lazy;
2              
3 12     12   1847748 use strict;
  12         78  
  12         270  
4 12     12   54 use warnings;
  12         18  
  12         432  
5              
6             our $VERSION = '0.000007';
7              
8 12     12   3846 use App::cpm 0.975; # CLI has no $VERSION
  12         1116  
  12         228  
9 12     12   4476 use App::cpm::CLI;
  12         2315538  
  12         432  
10              
11             # Cargo-culted from App::cpm::CLI
12             # Adding pass_through so that we don't have to keep up with all possible options
13 12         84 use Getopt::Long qw(
14             :config
15             no_auto_abbrev
16             no_ignore_case
17             bundling
18             pass_through
19 12     12   90 );
  12         18  
20              
21 12     12   7380 use Module::Loaded qw( is_loaded );
  12         5934  
  12         4368  
22              
23             sub import {
24 12     12   96 shift;
25 12         30 my @args = @_;
26              
27 12         12 my $is_global;
28             my $local_lib;
29              
30             {
31 12         24 local @ARGV = @args;
  12         24  
32              
33             # Stolen from App::cpm::CLI::parse_options()
34 12         42 GetOptions(
35             'L|local-lib-contained=s' => \$local_lib,
36             'g|global' => \$is_global,
37             );
38             }
39              
40             # Generally assume a global install, which makes the invocation as
41             # simple as:
42              
43             # perl -Mlazy foo.pl
44              
45             # However, if we're already using local::lib and --global has not been
46             # explicitly set and no local::lib has been explicitly set, let's try
47             # to DTRT and use the correct local::lib.
48              
49             # This allows us to do something like:
50             # perl -Mlocal::lib -Mlazy foo.pl
51              
52             # This may or may not be a good idea.
53              
54             # Allowing --local-lib-contained to be passed is mostly useful for
55             # testing. For real world cases, the user should specify the
56             # local::lib via local::lib itself.
57              
58             # perl -Mlocal::lib=my_local_lib -Mlazy foo.pl
59              
60 12 50 66     3828 if ( ( !$is_global && !$local_lib ) && is_loaded('local::lib') ) {
    100 66        
      66        
61 0         0 my @paths = local::lib->new->active_paths;
62 0         0 my $path = shift @paths;
63 0 0       0 if ($path) {
64 0         0 push @args, ( '-L', $path );
65 0         0 _print_msg_about_local_lib($path);
66             }
67             }
68              
69             # Assume a global install if local::lib is not in use or has not been
70             # explicitly invoked.
71              
72             elsif ( !$is_global && !$local_lib ) {
73 6         120 push @args, ('-g');
74             }
75              
76 12         60 my $cpm = App::cpm::CLI->new;
77              
78             # Push the hook onto @INC and then re-add all of @INC again. This way, if
79             # we got to the hook and tried to install, we can re-try @INC to see if the
80             # module can now be used.
81              
82             push @INC, sub {
83 13     13   21129 shift;
84              
85 13         36 my $name = shift;
86 13         36 $name =~ s{/}{::}g;
87 13         26 $name =~ s{\.pm\z}{};
88              
89             # Don't try to install if we're called inside an eval
90             # See https://stackoverflow.com/questions/51483287/how-to-detect-if-perl-code-is-being-run-inside-an-eval/
91 13         40 for my $level ( 0 .. 20 ) {
92 65         246 my @caller = caller($level);
93 65 100       116 last unless @caller;
94              
95 53 100 66     409 if (
      100        
96             (
97             ( $caller[1] && $caller[1] =~ m{eval} )
98             || ( $caller[3] && $caller[3] =~ m{eval} )
99             )
100             && ( $caller[0] ne 'Capture::Tiny' )
101             ) {
102 1         2 my @args = (
103             $caller[0], $name, $name, $caller[1], $caller[2],
104             $caller[0]
105             );
106 1         30 warn sprintf( <<'EOF', @args );
107             Code in package "%s" is attempting to load %s from inside an eval, so we are not installing %s.
108             See %s at line %s
109             Please open an issue if %s should be whitelisted.
110             EOF
111 1         7 return;
112             }
113             }
114              
115 12         96 $cpm->run( 'install', @args, $name );
116 2         2716622 return 1;
117 12         12990 }, @INC;
118             }
119              
120             sub _print_msg_about_local_lib {
121 0     0     my $path = shift;
122              
123 0           print <<"EOF";
124              
125             ********
126              
127             You haven't included any arguments for App::cpm via lazy, but you've
128             loaded local::lib, so we're going to install all modules into:
129              
130             $path
131              
132             If you do not want to do this, you can explicitly invoke a global install via:
133              
134             perl -Mlazy=-g path/to/script.pl
135              
136             or, from inside your code:
137              
138             use lazy qw( -g );
139              
140             If you would like to install to a different local lib:
141              
142             perl -Mlocal::lib=my_local_lib -Mlazy path/to/script.pl
143              
144             or, from inside your code:
145              
146             use local::lib qw( my_local_lib );
147             use lazy;
148              
149             ********
150              
151             EOF
152             }
153              
154             1;
155              
156             # ABSTRACT: Lazily install missing Perl modules
157              
158             __END__