File Coverage

blib/lib/NVMPL/Config.pm
Criterion Covered Total %
statement 27 51 52.9
branch 3 16 18.7
condition 0 6 0.0
subroutine 7 9 77.7
pod 0 2 0.0
total 37 84 44.0


line stmt bran cond sub pod time code
1             package NVMPL::Config;
2 6     6   1237793 use strict;
  6         16  
  6         303  
3 6     6   32 use warnings;
  6         11  
  6         473  
4 6     6   1880 use JSON::PP qw(decode_json);
  6         50482  
  6         636  
5 6     6   53 use File::Spec;
  6         34  
  6         238  
6 6     6   4181 use File::HomeDir;
  6         48253  
  6         515  
7 6     6   47 use File::Path qw(make_path);
  6         11  
  6         4947  
8              
9             # Default config locations
10             my $SYSTEM_CONF = '/etc/nvm-pl.conf';
11             my $USER_CONF = File::Spec->catfile(File::HomeDir->my_home, '.nvmplrc');
12              
13             # Default values (used if no config files exist)
14             my %DEFAULTS = (
15             install_dir => File::Spec->catdir(File::HomeDir->my_home, '.nvm-pl', 'install'),
16             mirror_url => 'https://nodejs.org/dist',
17             cache_ttl => 86400,
18             auto_use => 1,
19             color_output => 1,
20             log_level => 'info',
21             );
22              
23             my %CONFIG;
24              
25             # --------------------------------------------------------------------
26             # Initialize configuration (called once at startup)
27             # --------------------------------------------------------------------
28              
29             sub load {
30 1     1 0 4 my $class = shift;
31              
32 1         13 %CONFIG = %DEFAULTS;
33              
34 1 50       176 if (-f $SYSTEM_CONF) {
35 0         0 _merge_config($SYSTEM_CONF);
36             }
37              
38 1 50       125 if (-f $USER_CONF) {
39 0         0 _merge_config($USER_CONF);
40             }
41              
42 1         44 my $install_dir = $CONFIG{install_dir};
43 1         6 for my $subdir (qw(downloads versions)) {
44 2         43 my $path = File::Spec->catdir($install_dir, $subdir);
45 2 50       1132 make_path($path) unless -d $path;
46             }
47              
48 1         11 return \%CONFIG;
49             }
50              
51             # --------------------------------------------------------------------
52             # Return a single config value
53             # --------------------------------------------------------------------
54              
55             sub get {
56 0     0 0   my ($key) = @_;
57 0   0       return $CONFIG{$key} // $DEFAULTS{$key};
58             }
59              
60             # --------------------------------------------------------------------
61             # Internal helper: read and merge JSON or simple key=value config files
62             # --------------------------------------------------------------------
63              
64             sub _merge_config {
65 0     0     my ($file) = @_;
66              
67 0 0         open my $fh, '<', $file or do {
68 0           warn "Warning: could not open $file: $!\n";
69 0           return;
70             };
71              
72 0           local $/;
73 0           my $content = <$fh>;
74 0           close $fh;
75              
76 0           my $data;
77 0           eval { $data = decode_json($content) };
  0            
78 0 0         if ($@) {
79 0           for my $line (split /\n/, $content) {
80 0 0         next if $line =~ /^\s*#/;
81 0 0         next unless $line =~ /=/;
82 0           my ($key, $val) = split /=/, $line, 2;
83 0           $key =~ s/^\s+|\s+$//g;
84 0           $val =~ s/^\s+|\s+$//g;
85 0 0 0       $data->{$key} = $val if defined $key && defined $val;
86             }
87             }
88              
89 0           for my $k (keys %$data) {
90 0           $CONFIG{$k} = $data->{$k};
91             }
92             }
93              
94             1;