Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / t / test.t @ 17f78427

Historique | Voir | Annoter | Télécharger (6,44 ko)

1
# -*- perl -*-
2

    
3
use strict;
4
use warnings;
5

    
6
use Test::More;
7
use File::Find ();
8
use Capture::Tiny ':all';
9

    
10
use vars qw/*name *dir *prune/;
11
*name  = *File::Find::name;
12
*dir   = *File::Find::dir;
13
*prune = *File::Find::prune;
14
my $num_plugins = 0;
15

    
16
sub wanted {
17
    my ( $dev, $ino, $mode, $nlink, $uid, $gid, $interpreter, $arguments );
18

    
19
    ( ( $dev, $ino, $mode, $nlink, $uid, $gid ) = lstat($_) )
20
        && -f _
21
        && ( ( $interpreter, $arguments ) = hashbang("$_") )
22
        && ($interpreter)
23
        && ++$num_plugins
24
        && process_file( $_, $name, $interpreter, $arguments );
25
}
26

    
27
File::Find::find( { wanted => \&wanted }, 'plugins' );
28

    
29
sub hashbang {
30
    my ($filename) = @_;
31
    open my $file, '<', $filename;
32
    my $firstline = <$file>;
33
    close $file;
34

    
35
    $firstline =~ m{ ^\#!                    # hashbang
36
                     \s*                     # optional space
37
                     (?:/usr/bin/env\s+)?    # optional /usr/bin/env
38
                     (?<interpreter>\S+)     # interpreter
39
                     (?:\s+
40
                         (?<arguments>[^\n]*)   # optional interpreter arguments
41
                     )?
42
               }xms;
43

    
44
    return ( $+{interpreter}, $+{arguments} );
45
}
46

    
47
sub process_file {
48
    my ( $file, $filename, $interpreter, $arguments ) = @_;
49
    use v5.10.1;
50

    
51
    if ( ! -x $file ) {
52
        # missing executable flag
53
        diag(
54
            sprintf("\nFile '%s' lacks executable permission bits. Maybe try 'chmod +x $file'?\n",
55
                    $file)
56
        );
57
    }
58
    elsif ( $interpreter =~ m{/bin/sh} ) {
59
        subtest $filename => sub {
60
            plan tests => 2;
61
            run_check(
62
                {   command     => [ 'sh', '-n', $file ],
63
                    description => 'sh syntax check'
64
                }
65
            );
66
            my $checkbashisms_location = `command -v checkbashisms 2>/dev/null`;
67
            chomp($checkbashisms_location);
68
            my $command;
69
            if ($checkbashisms_location ne "") {
70
                # monkey-patch "checkbashisms" in order to allow "command -v"
71
                # see https://unix.stackexchange.com/a/85250: "command -v" vs. which/hash/...
72
                # see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=733511
73
                my $run_modified_checkbashisms = q/sed 's#command\\\s+-\[\^p\]#command\s+-[^pvV]#'/
74
                    . " '$checkbashisms_location' | perl - '$file'";
75
                $command = [ 'sh', '-c', $run_modified_checkbashisms ];
76
            } else {
77
                # make sure that the non-confusing "checkbashisms not found" message is displayed
78
                $command = [ 'checkbashisms', $file ];
79
            }
80
            run_check(
81
                {   command     => $command,
82
                    description => 'checkbashisms'
83
                }
84
            );
85
        };
86
    }
87
    elsif ( $interpreter =~ m{/bin/ksh} ) {
88
        subtest $filename => sub {
89
            plan tests => 2;
90
            run_check(
91
                {   command     => [ 'ksh', '-n', $file ],
92
                    description => 'ksh syntax check',
93
                    filename    => $filename
94
                }
95
            );
96
            run_check(
97
                {   command     => [ 'shellcheck', $file ],
98
                    description => 'shellcheck'
99
                }
100
            );
101
        }
102
    }
103
    elsif ( $interpreter =~ m{bash} ) {
104
        run_check(
105
            {   command     => [ 'bash', '-n', $file ],
106
                description => 'bash syntax check',
107
                filename    => $filename
108
            }
109
        );
110
    }
111
    elsif ( $interpreter =~ m{/bin/zsh} ) {
112
        run_check(
113
            {   command     => [ 'zsh', '-n', $file ],
114
                description => 'zsh syntax check',
115
                filename    => $filename
116
            }
117
        );
118
    }
119
    elsif ( $interpreter =~ m{perl} ) {
120
        my $command;
121
        if ( $arguments =~ m{-.*T}mx ) {
122
            $command = [ 'perl', '-cwT', $file ];
123
        }
124
        else {
125
            $command = [ 'perl', '-cw', $file ];
126
        }
127
        run_check(
128
            {   command     => $command,
129
                description => 'perl syntax check',
130
                filename    => $filename
131
            }
132
        );
133
    }
134
    elsif ( $interpreter =~ m{python3} ) {
135
        run_check(
136
            {   command     => [ 'python3', '-m', 'py_compile', $file ],
137
                description => 'python3 compile',
138
                filename    => $filename
139
            }
140
        );
141
    }
142
    elsif ( $interpreter =~ m{python} ) {
143
        run_check(
144
            {   command     => [ 'python', '-m', 'py_compile', $file ],
145
                description => 'python compile',
146
                filename    => $filename
147
            }
148
        );
149
    }
150
    elsif ( $interpreter =~ m{php} ) {
151
        run_check(
152
            {   command     => [ 'php', '-l', $file ],
153
                description => 'php syntax check',
154
                filename    => $filename
155
            }
156
        );
157
    }
158
    elsif ( $interpreter =~ m{j?ruby} ) {
159
        run_check(
160
            {   command     => [ 'ruby', '-cw', $file ],
161
                description => 'ruby syntax check',
162
                filename    => $filename
163
            }
164
        );
165
    }
166
    elsif ( $interpreter =~ m{gawk} ) {
167
        run_check(
168
            {   command => [
169
                    'gawk', '--source', 'BEGIN { exit(0) } END { exit(0) }',
170
                    '--file', $file
171
                ],
172
                description => 'gawk syntax check',
173
                filename    => $filename
174
            }
175
        );
176
    }
177
    elsif ( $interpreter =~ m{expect} ) {
178
    SKIP: {
179
            skip 'no idea how to check expect scripts', 1;
180
            pass("No pretending everything is ok");
181
        }
182
    }
183
    else {
184
        fail( $filename . " unknown interpreter " . $interpreter );
185
    }
186
}
187

    
188
sub run_check {
189
    my ($args)        = @_;
190
    my $check_command = $args->{command};
191
    my $description   = $args->{description};
192
    my $filename      = $args->{filename};
193

    
194
    my $message;
195

    
196
    if ($filename) {
197
        $message = sprintf( '%s: %s', $filename, $description );
198
    }
199
    else {
200
        $message = $description;
201
    }
202

    
203
    my ( $stdout, $stderr, $exit ) = capture {
204
        system( @{$check_command} );
205
    };
206

    
207
    ok( ( $exit == 0 ), $message );
208

    
209
    if ($exit) {
210
        diag(
211
            sprintf(
212
                "\nCommand: %s\n\nSTDOUT:\n\n%s\n\nSTDERR:\n\n%s\n\n",
213
                join( " ", @{$check_command} ),
214
                $stdout, $stderr
215
            )
216
        );
217
    }
218
}
219

    
220
done_testing($num_plugins);