| File: | lib/CheckSpelling/CleanupFiles.pm |
| Coverage: | 100.0% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 1 | #! -*-perl-*- | |||||
| 2 | ||||||
| 3 | package CheckSpelling::CleanupFiles; | |||||
| 4 | ||||||
| 5 | 1 1 1 | 109304 1 25 | use Cwd 'realpath'; | |||
| 6 | 1 1 1 | 1 1 15 | use File::Spec; | |||
| 7 | 1 1 1 | 152 1 17 | use CheckSpelling::Util; | |||
| 8 | 1 1 1 | 216 1 15 | use CheckSpelling::CheckDictionary; | |||
| 9 | 1 1 1 | 190 1 14 | use CheckSpelling::CheckPattern; | |||
| 10 | 1 1 1 | 229 1 15 | use CheckSpelling::EnglishList; | |||
| 11 | 1 1 1 | 4 1 471 | use Cwd qw(abs_path); | |||
| 12 | ||||||
| 13 | sub identity { | |||||
| 14 | 13 | 6 | my ($line) = @_; | |||
| 15 | 13 | 11 | return ($line, ''); | |||
| 16 | } | |||||
| 17 | ||||||
| 18 | sub call_check_line { | |||||
| 19 | 23 | 8 | my ($line) = @_; | |||
| 20 | 23 | 11 | my $warning; | |||
| 21 | 23 | 8 | our ($check_line, $output_fh, $warnings_fh); | |||
| 22 | 23 | 13 | ($line, $warning) = $check_line->($line); | |||
| 23 | 23 | 16 | if ($warning ne '') { | |||
| 24 | 2 | 4 | print $warnings_fh "$ARGV:$.:$warning"; | |||
| 25 | } | |||||
| 26 | 23 | 14 | if ($line ne '') { | |||
| 27 | 21 | 45 | print $output_fh $line."\n"; | |||
| 28 | } | |||||
| 29 | } | |||||
| 30 | ||||||
| 31 | sub clean_files { | |||||
| 32 | 8 | 11854 | my @files = @_; | |||
| 33 | 8 | 10 | CheckSpelling::CheckPattern::reset_seen(); | |||
| 34 | 8 | 6 | my $type=CheckSpelling::Util::get_file_from_env('type'); | |||
| 35 | 8 | 8 | my $output=CheckSpelling::Util::get_file_from_env('output', '/dev/null'); | |||
| 36 | 8 | 3 | my $workspace_path=abs_path(CheckSpelling::Util::get_file_from_env('GITHUB_WORKSPACE', '.')); | |||
| 37 | 8 | 6 | my $used_config_files=CheckSpelling::Util::get_file_from_env('used_config_files', '/dev/null'); | |||
| 38 | 8 | 24 | $ENV{comment_char}='\s*#'; | |||
| 39 | 1 1 1 8 | 1 1 3 6 | open our $warnings_fh, '>>:encoding(UTF-8)', CheckSpelling::Util::get_file_from_env('early_warnings', '/dev/null'); | |||
| 40 | 8 | 850 | open our $output_fh, '>>:encoding(UTF-8)', $output; | |||
| 41 | 8 | 240 | open my $used_config_files_fh, '>>:encoding(UTF-8)', $used_config_files; | |||
| 42 | 8 | 129 | my $old_file; | |||
| 43 | 8 | 6 | our $check_line; | |||
| 44 | ||||||
| 45 | 8 | 16 | if ($type =~ /^(?:line_forbidden|patterns|excludes|only|reject)$/) { | |||
| 46 | 1 | 1 | $check_line = \&CheckSpelling::CheckPattern::process_line; | |||
| 47 | } elsif ($type =~ /^(?:dictionary|expect|allow)$/) { | |||||
| 48 | 1 | 1 | $check_line = \&CheckSpelling::CheckDictionary::process_line; | |||
| 49 | } else { | |||||
| 50 | 6 | 3 | $check_line = \&identity; | |||
| 51 | } | |||||
| 52 | ||||||
| 53 | 8 | 8 | for my $file (@files) { | |||
| 54 | 12 | 173 | my $maybe_bad=abs_path($file); | |||
| 55 | 12 | 37 | if ($maybe_bad !~ /^\Q$workspace_path\E/) { | |||
| 56 | 1 | 16 | print "::error ::Configuration files must live within $workspace_path...\n"; | |||
| 57 | 1 | 3 | print "::error ::Unfortunately, file '$file' appears to reside elsewhere.\n"; | |||
| 58 | 1 | 9 | return 3; | |||
| 59 | } | |||||
| 60 | 11 | 12 | if ($maybe_bad =~ m{/\.git/}i) { | |||
| 61 | 1 | 11 | print "::error ::Configuration files must not live within `.git/`...\n"; | |||
| 62 | 1 | 3 | print "::error ::Unfortunately, file '$file' appears to.\n"; | |||
| 63 | 1 | 6 | return 4; | |||
| 64 | } | |||||
| 65 | 10 | 4 | my $fh; | |||
| 66 | 10 | 75 | if (open($fh, '<:encoding(UTF-8)', $file)) { | |||
| 67 | 9 | 147 | $ARGV = $file; | |||
| 68 | 9 | 17 | print $used_config_files_fh "$file\0"; | |||
| 69 | 9 | 11 | seek($fh, -1, 2); | |||
| 70 | 9 | 71 | read($fh, $buffer, 1); | |||
| 71 | 9 | 21 | my $length = tell($fh); | |||
| 72 | 9 | 11 | seek($fh, 0, 0); | |||
| 73 | 9 | 4 | my $add_nl_at_eof = 0; | |||
| 74 | 9 | 7 | if ($length == 0) { | |||
| 75 | 3 | 32 | print STDERR "$file:1:1 ... 1, Notice - File is empty (empty-file)\n"; | |||
| 76 | } else { | |||||
| 77 | 6 | 9 | if ($buffer !~ /\R/) { | |||
| 78 | 1 | 0 | $add_nl_at_eof = 1; | |||
| 79 | } | |||||
| 80 | # local $/ = undef; | |||||
| 81 | 6 | 5 | my ($nl, $first_end, $end, $line); | |||
| 82 | 6 | 0 | my %eol_counts; | |||
| 83 | 6 | 3 | my $content = ''; | |||
| 84 | 6 | 13 | while (!eof($fh)) { | |||
| 85 | 6 | 25 | read $fh, $buffer, 4096; | |||
| 86 | 6 | 6 | $content .= $buffer; | |||
| 87 | 6 | 14 | while ($content =~ s/([^\r\n\x0b\f\x85\x{2028}\x{2029}]*)(\r\n|\n|\r|\x0b|\f|\x85|\x{2028}|\x{2029})//m) { | |||
| 88 | 22 | 14 | ++$.; | |||
| 89 | 22 | 19 | my ($line, $end) = ($1, $2); | |||
| 90 | 22 | 14 | unless (defined $nl) { | |||
| 91 | 6 | 2 | $nl = $end; | |||
| 92 | } elsif ($end ne $nl) { | |||||
| 93 | print $warnings_fh "$file:$.:$-[0] ... $+[0], Warning - Entry has inconsistent line endings (unexpected-line-ending)\n"; | |||||
| 94 | } | |||||
| 95 | 22 | 17 | ++$eol_counts{$end}; | |||
| 96 | 22 | 5 | my $warning; | |||
| 97 | 22 | 16 | call_check_line($line); | |||
| 98 | } | |||||
| 99 | } | |||||
| 100 | 6 | 4 | if ($content ne '') { | |||
| 101 | 1 | 0 | call_check_line($content); | |||
| 102 | } | |||||
| 103 | 6 | 29 | if ($add_nl_at_eof) { | |||
| 104 | 1 | 1 | my $line_length = length $_; | |||
| 105 | 1 | 8 | print STDERR "$file:$.:1 ... $length, Warning - Missing newline at end of file (no-newline-at-eof)\n"; | |||
| 106 | 1 | 1 | print $output_fh "\n"; | |||
| 107 | } | |||||
| 108 | 6 | 11 | my $eol_a = $eol_counts{"\n"} || 0; | |||
| 109 | 6 | 7 | my $eol_d = $eol_counts{"\r"} || 0; | |||
| 110 | 6 | 6 | my $eol_d_a = $eol_counts{"\r\n"} || 0; | |||
| 111 | 6 | 3 | my @line_endings; | |||
| 112 | 6 | 3 | push @line_endings, "DOS [$eol_d_a]" if $eol_d_a; | |||
| 113 | 6 | 13 | push @line_endings, "UNIX [$eol_a]" if $eol_a; | |||
| 114 | 6 | 5 | push @line_endings, "Mac classic [$eol_d]" if $eol_d; | |||
| 115 | 6 | 6 | if (scalar @line_endings > 1) { | |||
| 116 | 1 | 1 | my $line_length = length $_; | |||
| 117 | 1 | 1 | my $mixed_endings = CheckSpelling::EnglishList::build(@line_endings); | |||
| 118 | 1 | 14 | printf STDERR "$file:$.:1 ... $length, Warning - Mixed $mixed_endings line endings (mixed-line-endings)\n"; | |||
| 119 | } | |||||
| 120 | } | |||||
| 121 | 9 | 41 | close($fh); | |||
| 122 | } | |||||
| 123 | } | |||||
| 124 | 6 | 26 | close $used_config_files_fh; | |||
| 125 | 6 | 21 | close $warnings_fh; | |||
| 126 | 6 | 11 | return 0; | |||
| 127 | } | |||||
| 128 | ||||||
| 129 | 1; | |||||