File Coverage

blib/lib/Filename/Type/Executable.pm
Criterion Covered Total %
statement 11 16 68.7
branch 0 4 0.0
condition 0 2 0.0
subroutine 4 5 80.0
pod 1 1 100.0
total 16 28 57.1


line stmt bran cond sub pod time code
1             package Filename::Type::Executable;
2              
3 1     1   376018 use 5.010001;
  1         4  
4 1     1   6 use strict;
  1         2  
  1         29  
5 1     1   11 use warnings;
  1         2  
  1         130  
6              
7             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
8             our $DATE = '2024-12-20'; # DATE
9             our $DIST = 'Filename-Type-Executable'; # DIST
10             our $VERSION = '0.002'; # VERSION
11              
12 1     1   6 use Exporter qw(import);
  1         2  
  1         645  
13             our @EXPORT_OK = qw(check_executable_filename);
14              
15             our %TYPES = (
16             'perl script' => [qw/.pl/],
17             'php script' => [qw/.php/],
18             'python script' => [qw/.py/],
19             'ruby script' => [qw/.rb/],
20             'shell script' => [qw/.sh .bash/],
21             'shell archive' => [qw/.shar/],
22             'dos program' => [qw/.exe .com .bat/],
23             'appimage' => [qw/.appimage/],
24             );
25             our %EXTS = map { my $type = $_; map {($_=> $type)} @{ $TYPES{$type} } } keys %TYPES;
26             our $RE_STR = join("|", sort {length($b) <=> length($a) || $a cmp $b} keys %EXTS);
27             our $RE_NOCI = qr/\A(.+)($RE_STR)\z/;
28             our $RE_CI = qr/\A(.+)($RE_STR)\z/i;
29              
30             our %SPEC;
31              
32             $SPEC{check_executable_filename} = {
33             v => 1.1,
34             summary => 'Check whether filename indicates being an executable program/script',
35             description => <<'MARKDOWN',
36              
37              
38             MARKDOWN
39             args => {
40             filename => {
41             schema => 'str*',
42             req => 1,
43             pos => 0,
44             },
45             # XXX recurse?
46             ci => {
47             summary => 'Whether to match case-insensitively',
48             schema => 'bool',
49             default => 1,
50             },
51             },
52             result_naked => 1,
53             result => {
54             schema => ['any*', of=>['bool*', 'hash*']],
55             description => <<'MARKDOWN',
56              
57             Return false if no archive suffixes detected. Otherwise return a hash of
58             information, which contains these keys: `exec_type`, `exec_ext`,
59             `exec_name`.
60              
61             MARKDOWN
62             },
63             examples => [
64             {
65             args => {filename => 'foo.pm'},
66             naked_result => 0,
67             },
68             {
69             args => {filename => 'foo.appimage'},
70             naked_result => {exec_name=>'foo', exec_type=>'appimage', exec_ext=>'.appimage'},
71             },
72             {
73             summary => 'Case-insensitive by default',
74             args => {filename => 'foo.Appimage'},
75             naked_result => {exec_name=>'foo', exec_type=>'appimage', exec_ext=>'.Appimage'},
76             },
77             {
78             summary => 'Case-sensitive',
79             args => {filename => 'foo.Appimage', ci=>0},
80             naked_result => 0,
81             },
82             ],
83             };
84             sub check_executable_filename {
85 0     0 1   my %args = @_;
86              
87 0           my $filename = $args{filename};
88 0   0       my $ci = $args{ci} // 1;
89              
90             #use DD; dd \%EXTS;
91 0 0         my ($name, $ext) = $filename =~ ($ci ? $RE_CI : $RE_NOCI)
    0          
92             or return 0;
93             return {
94             exec_name => $name,
95             exec_ext => $ext,
96 0           exec_type => $EXTS{lc $ext},
97             };
98             }
99              
100             1;
101             # ABSTRACT: Check whether filename indicates being an executable program/script
102              
103             __END__