File Coverage

blib/lib/Dotenv.pm
Criterion Covered Total %
statement 37 37 100.0
branch 18 18 100.0
condition n/a
subroutine 6 6 100.0
pod 2 2 100.0
total 63 63 100.0


line stmt bran cond sub pod time code
1             package Dotenv;
2             $Dotenv::VERSION = '0.001';
3 4     4   296115 use strict;
  4         43  
  4         173  
4 4     4   24 use warnings;
  4         7  
  4         101  
5              
6 4     4   22 use Carp ();
  4         7  
  4         71  
7 4     4   1554 use Path::Tiny ();
  4         26043  
  4         2901  
8              
9             my $parse = sub {
10             my ( $string, $env ) = @_;
11             $string =~ s/\A\x{feff}//; # drop BOM
12              
13             my %kv;
14             for my $line ( split /$/m, $string ) {
15             chomp($line);
16             next if $line =~ /\A\s*(?:[#:]|\z)/; # skip blanks and comments
17             if (
18             my ( $k, $v ) =
19             $line =~ m{
20             \A # beginning of line
21             \s* # leading whitespace
22             (?:export\s+)? # optional export
23             ([a-zA-Z_][a-zA-Z0-9_]+) # key
24             (?:\s*=\s*) # separator
25             ( # optional value begin
26             '[^']*(?:\\'|[^']*)*' # single quoted value
27             | # or
28             "[^"]*(?:\\"|[^"]*)*" # double quoted value
29             | # or
30             [^\#\r\n]+ # unquoted value
31             )? # value end
32             \s* # trailing whitespace
33             (?:\#.*)? # optional comment
34             \z # end of line
35             }x
36             )
37             {
38             $v //= '';
39             $v =~ s/\s*\z//;
40              
41             # single and double quotes semantics
42             if ( $v =~ s/\A(['"])(.*)\1\z/$2/ && $1 eq '"' ) {
43             $v =~ s/\\n/\n/g;
44             $v =~ s/\\//g;
45             }
46             $kv{$k} = $v;
47             }
48             else {
49             Carp::croak "Can't parse env line: $line";
50             }
51             }
52             return %kv;
53             };
54              
55             sub parse {
56 23     23 1 40054 my ( $package, @sources ) = @_;
57 23 100       69 @sources = ('.env') if !@sources;
58              
59 23         41 my %env;
60 23         42 for my $source (@sources) {
61 29 100       256 Carp::croak "Can't handle an unitialized value"
62             if !defined $source;
63              
64 28         37 my %kv;
65 28         51 my $ref = ref $source;
66 28 100       99 if ( $ref eq '' ) {
    100          
    100          
    100          
    100          
    100          
67 12         57 %kv = $parse->( Path::Tiny->new($source)->slurp_utf8, \%env );
68             }
69             elsif ( $ref eq 'HASH' ) { # bare hash ref
70 7         96 %kv = %$source;
71             }
72             elsif ( $ref eq 'ARRAY' ) {
73 1         7 %kv = $parse->( join( "\n", @$source ), \%env );
74             }
75             elsif ( $ref eq 'SCALAR' ) {
76 1         5 %kv = $parse->( $$source, \%env );
77             }
78             elsif ( $ref eq 'GLOB' ) {
79 1         4 local $/;
80 1         62 %kv = $parse->( scalar <$source>, \%env );
81 1         30 close $source;
82             }
83 6         56 elsif ( eval { $source->can('getline') } ) {
84 1         5 local $/;
85 1         46 %kv = $parse->( scalar $source->getline, \%env );
86 1         9 $source->close;
87             }
88             else {
89 5         495 Carp::croak "Don't know how to handle '$source'";
90             }
91              
92             # don't overwrite anything that already exists
93 23         348 %env = ( %kv, %env );
94             }
95              
96 17         485 return %env;
97             }
98              
99             sub load {
100 6     6 1 4382 my ( $package, @sources ) = @_;
101 6 100       23 @sources = ('.env') if !@sources;
102 6         28 %ENV = $package->parse( \%ENV, @sources );
103             }
104              
105             '.env';
106              
107             __END__