Skip to content

Commit 3741df6

Browse files
committed
Use check_perl_syntax.pl for Perl checks
Replace make-based compilation with scripts/utils/check_perl_syntax.pl. Add check_perl_args and check_perl_fast targets and introduce CHECK_PERL_EXCLUDES to control excluded files.
1 parent 0f97d55 commit 3741df6

2 files changed

Lines changed: 114 additions & 100 deletions

File tree

Makefile

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ ifeq ($(shell test $(CPU_COUNT) -gt 8; echo $$?),0)
3434
export CPU_COUNT=8
3535
endif
3636

37+
CHECK_PERL_EXCLUDES ?= .check_perl_excludes
38+
3739
# tell gitbash not to complete path
3840
export MSYS_NO_PATHCONV=1
3941

@@ -407,24 +409,24 @@ bash_test:
407409
# We have to finally filter out "." as this will the output if we have no file
408410
TO_CHECK := $(shell [ -x "`which git 2>/dev/null`" ] && git diff origin/main --name-only | grep '.*\.\(pl\|pm\|t\)$$' | grep -v "scripts/obsolete" | xargs ls -d 2>/dev/null | grep -v "^.$$" )
409411

410-
check_perl_fast:
411-
@echo "🥫 Checking ${TO_CHECK}"
412-
test -z "${TO_CHECK}" || \
413-
${DOCKER_COMPOSE_BUILD} run --rm backend make -j ${CPU_COUNT} ${TO_CHECK} || \
414-
( echo "Perl syntax errors! Look at 'failed--compilation' in above logs" && false )
415-
416412
check_translations:
417413
@echo "🥫 Checking translations"
418414
${DOCKER_COMPOSE_BUILD} run --rm backend scripts/check-translations.sh
419415

420416
# check all perl files compile (takes time, but needed to check a function rename did not break another module !)
421417
# IMPORTANT: We exclude some files that are in .check_perl_excludes
422418
check_perl:
423-
@echo "🥫 Checking all perl files"
424-
ALL_PERL_FILES=$$(find . -regex ".*\.\(p[lm]\|t\)"|grep -v "/\."|grep -v "/obsolete/"| grep -vFf .check_perl_excludes) ; \
425-
${DOCKER_COMPOSE_BUILD} run --rm --no-deps backend make -j ${CPU_COUNT} $$ALL_PERL_FILES || \
426-
( echo "Perl syntax errors! Look at 'failed--compilation' in above logs" && false )
427-
@if grep -E '^\s*$$' .check_perl_excludes; then echo "No blank line accepted in .check_perl_excludes, fix it"; false; fi
419+
$(MAKE) check_perl_args args="--no-fast-fail"
420+
421+
check_perl_fast:
422+
@echo "🥫 Checking ${TO_CHECK}"
423+
test -z "${TO_CHECK}" || \
424+
${DOCKER_COMPOSE_BUILD} run --rm backend perl scripts/utils/check_perl_syntax.pl ${TO_CHECK}
425+
426+
# check only specified files/directories or with custom flags (e.g. make check_perl_args args="--no-fast-fail lib/")
427+
check_perl_args:
428+
${DOCKER_COMPOSE_BUILD} run --rm --no-deps backend \
429+
perl scripts/utils/check_perl_syntax.pl $(args)
428430

429431
# check with perltidy
430432
# we exclude files that are in .perltidy_excludes

scripts/utils/check_perl_syntax.pl

Lines changed: 101 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
use Term::ANSIColor;
3131
use Getopt::Long qw(:config pass_through);
3232

33-
# 0. Parse options
33+
# Parse options
3434
my $no_fast_fail = 0;
3535
GetOptions("no-fast-fail" => \$no_fast_fail);
3636

@@ -42,92 +42,102 @@
4242
}
4343
my $check_perl_excludes_file = $ENV{CHECK_PERL_EXCLUDES} || '.check_perl_excludes';
4444

45-
# Load excludes and check for stale entries and format
46-
my %excludes;
47-
my $stale_excludes = 0;
48-
if (-f $check_perl_excludes_file) {
49-
print colored("Checking entries in $check_perl_excludes_file\n", "bold white");
50-
open my $fh, '<', $check_perl_excludes_file or die "Cannot open $check_perl_excludes_file: $!";
51-
while (<$fh>) {
52-
chomp;
53-
# Skip blank lines and comments
54-
next if /^\s*$/ || /^\s*#/;
55-
56-
if (!-e $_) {
57-
print colored("error: ", "bold red") . "Stale exclude (file not found): $_\n";
58-
$stale_excludes = 1;
45+
sub load_excludes {
46+
my ($file) = @_;
47+
my %excludes;
48+
if (-f $file) {
49+
open my $fh, '<', $file or die "Cannot open $file: $!";
50+
while (<$fh>) {
51+
chomp;
52+
# Skip blank lines and comments
53+
next if /^\s*$/ || /^\s*#/;
54+
$excludes{$_} = 1;
5955
}
60-
$excludes{$_} = 1;
56+
close $fh;
6157
}
62-
close $fh;
58+
return %excludes;
6359
}
64-
if ($stale_excludes) {
65-
exit 1;
60+
61+
my %excludes = load_excludes($check_perl_excludes_file);
62+
63+
# Warn if any excludes don't exist
64+
for my $exclude (keys %excludes) {
65+
if (!-e $exclude) {
66+
print colored("warning: ", "bold yellow") . "Excluded file not found: $exclude\n";
67+
}
6668
}
6769

68-
# 2. Find files to check using native File::Find
70+
# Find files to check using native File::Find
6971
my @files;
7072
my @roots = @ARGV;
7173
if (!@roots) {
7274
@roots = ('.');
7375
}
7476

75-
# Identify explicitly passed files and warn if they are in the excludes list
77+
# Normalize "./path" to "path"
78+
sub normalize_path {
79+
my ($path) = @_;
80+
$path =~ s/^\.\///;
81+
return $path;
82+
}
83+
84+
# Warn if explicitly specified files are in the excludes list
7685
my %explicit_files;
7786
foreach my $arg (@roots) {
78-
if (-f $arg) {
79-
my $path = $arg;
80-
$path =~ s/^\.\///; # Normalize
81-
if ($excludes{$path}) {
82-
print colored("warning: ", "bold yellow")
83-
. "File '$path' is explicitly specified but is in the excludes list. Skipping.\n";
84-
}
85-
else {
86-
$explicit_files{$path} = 1;
87-
}
87+
if (!-f $arg) {
88+
next;
89+
}
90+
my $path = $arg;
91+
$path = normalize_path($path);
92+
if ($excludes{$path}) {
93+
print colored("warning: ", "bold yellow")
94+
. "File '$path' is explicitly specified but is in the excludes list. Skipping.\n";
95+
}
96+
else {
97+
$explicit_files{$path} = 1;
8898
}
99+
89100
}
90101

91-
find(
92-
{
93-
wanted => sub {
94-
my $path = $File::Find::name;
95-
$path =~ s/^\.\///; # Normalize "./path" to "path"
102+
# Collect files to check, applying excludes and pruning directories
103+
sub on_wanted {
104+
my $path = $File::Find::name;
105+
$path = normalize_path($path);
96106

97-
# If the file was explicitly passed on the command line and not excluded, we always check it
98-
if ($explicit_files{$path}) {
99-
push @files, $path if $path =~ /\.(pl|pm|t)$/;
100-
return;
101-
}
107+
# If the file was explicitly passed on the command line and not excluded, we always check it
108+
if ($explicit_files{$path}) {
109+
push @files, $path if $path =~ /\.(pl|pm|t)$/;
110+
return;
111+
}
102112

103-
# Prune hidden directories (except .) and obsolete directories
104-
if (-d $_) {
105-
if (($path ne '.' && $path =~ m{(^|/)\.}) || $path =~ m{(^|/)obsolete($|/)}) {
106-
$File::Find::prune = 1;
107-
return;
108-
}
109-
}
110-
# Filter for Perl files
111-
return unless -f $_;
112-
return unless $path =~ /\.(pl|pm|t)$/;
113+
# Prune hidden directories (except .) and obsolete directories
114+
if (-d $_) {
115+
if (($path ne '.' && $path =~ m{(^|/)\.}) || $path =~ m{(^|/)obsolete($|/)}) {
116+
$File::Find::prune = 1;
117+
return;
118+
}
119+
}
120+
# Filter for Perl files
121+
return unless -f $_;
122+
return unless $path =~ /\.(pl|pm|t)$/;
113123

114-
# Skip explicitly excluded files
115-
return if $excludes{$path};
124+
# Skip explicitly excluded files
125+
return if $excludes{$path};
116126

117-
push @files, $path;
118-
},
119-
no_chdir => 1,
120-
},
121-
@roots
122-
);
127+
push @files, $path;
128+
return;
129+
}
130+
131+
# Run the find with our custom wanted function
132+
find({wanted => \&on_wanted, no_chdir => 1,}, @roots);
123133

124134
if (!@files) {
125135
print colored("No Perl files to check.\n", "bold white");
126136
exit 0;
127137
}
128138

129139
my $total = scalar @files;
130-
print colored("Checking Perl syntax of $total files using $max_workers workers ...\n", "bold white");
140+
print colored("Checking $total files using $max_workers workers ...\n", "bold white");
131141

132142
my %running; # pid => { file => ..., pipe => ... }
133143
my @failed;
@@ -136,40 +146,42 @@
136146
my $fast_failing = 0;
137147

138148
sub wait_for_worker {
139-
# We use a blocking wait to get any finished child
140149
my $pid = wait();
141-
if ($pid > 0) {
142-
my $job = delete $running{$pid};
143-
my $file = $job->{file};
144-
my $fh = $job->{pipe};
150+
if ($pid <= 0) {
151+
return; # No children
152+
}
145153

146-
# Read any output from the pipe
147-
my $output = do {local $/; <$fh>};
148-
close $fh;
154+
my $job = delete $running{$pid};
155+
my $file = $job->{file};
156+
my $fh = $job->{pipe};
157+
158+
# Read any output from the pipe
159+
my $output = do {local $/; <$fh>};
160+
close $fh;
149161

150-
if ($? != 0 && !$fast_failing) {
151-
# Check if it was a real failure or if we killed it
152-
# (If we killed it, $? will indicate a signal)
153-
my $was_signaled = $? & 127;
154-
155-
if (!$was_signaled) {
156-
print "\n" . colored("error: ", "bold red") . "Syntax error in $file:\n";
157-
# Indent each line of the output with a tab and color it red
158-
my $indented_output = $output;
159-
$indented_output =~ s/^/\t/mg;
160-
print colored($indented_output, "red") . "\n";
161-
push @failed, $file;
162-
163-
if (!$no_fast_fail) {
164-
$fast_failing = 1;
165-
print colored("warning: ", "bold yellow")
166-
. "Fast-fail enabled, terminating remaining workers... (pass --no-fast-fail to disable)\n";
167-
kill 'KILL', keys %running;
168-
}
162+
if ($? != 0 && !$fast_failing) {
163+
# Check if it was a real failure or if we killed it
164+
# (If we killed it, $? will indicate a signal)
165+
my $was_signaled = $? & 127;
166+
167+
if (!$was_signaled) {
168+
print "\n" . colored("error: ", "bold red") . "Syntax error in $file:\n";
169+
# Indent each line of the output with a tab and color it red
170+
my $indented_output = $output;
171+
$indented_output =~ s/^/\t/mg;
172+
print colored($indented_output, "red") . "\n";
173+
push @failed, $file;
174+
175+
if (!$no_fast_fail) {
176+
$fast_failing = 1;
177+
print colored("warning: ", "bold yellow")
178+
. "Fast-fail enabled, terminating remaining workers... (pass --no-fast-fail to disable)\n";
179+
kill 'KILL', keys %running;
169180
}
170181
}
171-
$finished++;
172182
}
183+
$finished++;
184+
return;
173185
}
174186

175187
# Set up signal handling for graceful termination
@@ -237,7 +249,7 @@ sub wait_for_worker {
237249
wait_for_worker();
238250
}
239251

240-
print "\n";
252+
print "\r" . (" " x 80) . "\r";
241253

242254
if (@failed) {
243255
print colored("error: ", "bold red") . "Check failed. See above for details.\n";

0 commit comments

Comments
 (0)