File Coverage

blib/lib/NVMPL/Utils.pm
Criterion Covered Total %
statement 26 42 61.9
branch 0 14 0.0
condition 1 2 50.0
subroutine 9 14 64.2
pod 0 6 0.0
total 36 78 46.1


line stmt bran cond sub pod time code
1             package NVMPL::Utils;
2 8     8   1150 use strict;
  8         20  
  8         310  
3 8     8   43 use warnings;
  8         13  
  8         521  
4 8     8   52 use feature 'say';
  8         19  
  8         1048  
5 8     8   51 use Exporter 'import';
  8         15  
  8         435  
6 8     8   51 use File::Spec;
  8         16  
  8         228  
7 8     8   6190 use Term::ANSIColor;
  8         88967  
  8         6649  
8              
9             our @EXPORT_OK = qw(
10             detect_platform
11             normalize_path
12             log_info
13             log_warn
14             log_error
15             path_join
16             );
17              
18              
19             # ---------------------------------------------------------
20             # Detect the current OS/platform
21             # ---------------------------------------------------------
22              
23             sub detect_platform {
24 0     0 0 0 my $os = $^O;
25 0 0       0 return 'windows' if $os =~ /MSWin/i;
26 0 0       0 return 'macos' if $os =~ /darwin/i;
27 0 0       0 return 'linux' if $os =~ /linux/i;
28 0 0       0 return 'unix' if $os =~ /bsd|solaris/i;
29 0         0 return 'unkown';
30             }
31              
32             # ---------------------------------------------------------
33             # Normalize file paths cross-platform
34             # ---------------------------------------------------------
35              
36             sub normalize_path {
37 0     0 0 0 my ($path) = @_;
38 0 0       0 return '' unless defined $path;
39              
40 0 0       0 $path =~ s#\\#/#g if detect_platform() eq 'windows';
41 0         0 $path =~ s#/{2,}#/#g;
42 0 0       0 $path =~ s#/$## unless $path eq '/';
43              
44 0         0 return $path;
45             }
46              
47             # ---------------------------------------------------------
48             # Join path segments safely
49             # ---------------------------------------------------------
50              
51             sub path_join {
52 0     0 0 0 my @parts = @_;
53 0         0 return normalize_path(File::Spec->catfile(@parts));
54             }
55              
56             # ---------------------------------------------------------
57             # Logging helpers
58             # ---------------------------------------------------------
59              
60 2     2 0 10 sub log_info { _log('INFO', @_) }
61 0     0 0 0 sub log_warn { _log('WARN', @_) }
62 0     0 0 0 sub log_error { _log('ERROR', @_) }
63              
64             sub _log {
65 2     2   6 my ($level, $msg) = @_;
66 2         21 my %colors = (
67             INFO => 'green',
68             WARN => 'yellow',
69             ERROR => 'red',
70             );
71              
72 2   50     12 my $color = $colors{$level} // 'white';
73 2         7 my $timestamp = _timestamp();
74 2         15 say colored("[$timestamp] [$level] $msg", $color);
75             }
76              
77             # ---------------------------------------------------------
78             # Timestamp for logs
79             # ---------------------------------------------------------
80              
81             sub _timestamp {
82 2     2   69 my @t = localtime();
83 2         24 return sprintf("%04d-%02d-%02d %02d:%02d:%02d",
84             $t[5]+1900, $t[4]+1, $t[3], $t[2], $t[1], $t[0]);
85             }
86              
87             1;