| @@ -1,15 +1,15 @@ | | | @@ -1,15 +1,15 @@ |
1 | #! @PERL@ | | 1 | #! @PERL@ |
2 | # $NetBSD: pkglint.pl,v 1.857 2013/08/15 20:30:43 rillig Exp $ | | 2 | # $NetBSD: pkglint.pl,v 1.858 2013/08/31 18:14:28 rillig Exp $ |
3 | # | | 3 | # |
4 | | | 4 | |
5 | # pkglint - static analyzer and checker for pkgsrc packages | | 5 | # pkglint - static analyzer and checker for pkgsrc packages |
6 | # | | 6 | # |
7 | # Written by: | | 7 | # Written by: |
8 | # Roland Illig <rillig@NetBSD.org> | | 8 | # Roland Illig <rillig@NetBSD.org> |
9 | # | | 9 | # |
10 | # Based on work by: | | 10 | # Based on work by: |
11 | # Hubert Feyrer <hubertf@NetBSD.org> | | 11 | # Hubert Feyrer <hubertf@NetBSD.org> |
12 | # Thorsten Frueauf <frueauf@NetBSD.org> | | 12 | # Thorsten Frueauf <frueauf@NetBSD.org> |
13 | # Thomas Klausner <wiz@NetBSD.org> | | 13 | # Thomas Klausner <wiz@NetBSD.org> |
14 | # and others. | | 14 | # and others. |
15 | # | | 15 | # |
| @@ -2517,26 +2517,33 @@ sub checkline_trailing_whitespace($) { | | | @@ -2517,26 +2517,33 @@ sub checkline_trailing_whitespace($) { |
2517 | "Note: This is mostly for aesthetic reasons."); | | 2517 | "Note: This is mostly for aesthetic reasons."); |
2518 | $line->replace_regex(qr"\s+\n$", "\n"); | | 2518 | $line->replace_regex(qr"\s+\n$", "\n"); |
2519 | } | | 2519 | } |
2520 | } | | 2520 | } |
2521 | | | 2521 | |
2522 | sub checkline_rcsid_regex($$$) { | | 2522 | sub checkline_rcsid_regex($$$) { |
2523 | my ($line, $prefix_regex, $prefix) = @_; | | 2523 | my ($line, $prefix_regex, $prefix) = @_; |
2524 | my ($id) = ($opt_rcsidstring . ($is_wip ? "|Id" : "")); | | 2524 | my ($id) = ($opt_rcsidstring . ($is_wip ? "|Id" : "")); |
2525 | | | 2525 | |
2526 | $opt_debug_trace and $line->log_debug("checkline_rcsid_regex(${prefix_regex}, ${prefix})"); | | 2526 | $opt_debug_trace and $line->log_debug("checkline_rcsid_regex(${prefix_regex}, ${prefix})"); |
2527 | | | 2527 | |
2528 | if ($line->text !~ m"^${prefix_regex}\$(${id})(?::[^\$]+|)\$$") { | | 2528 | if ($line->text !~ m"^${prefix_regex}\$(${id})(?::[^\$]+|)\$$") { |
2529 | $line->log_error("\"${prefix}\$${opt_rcsidstring}\$\" expected."); | | 2529 | $line->log_error("\"${prefix}\$${opt_rcsidstring}\$\" expected."); |
| | | 2530 | $line->explain_error( |
| | | 2531 | "Several files in pkgsrc must contain the CVS Id, so that their current", |
| | | 2532 | "version can be traced back later from a binary package. This is to", |
| | | 2533 | "ensure reproducible builds, for example for finding bugs.", |
| | | 2534 | "", |
| | | 2535 | "Please insert the text from the above error message (without the quotes)", |
| | | 2536 | "at this position in the file."); |
2530 | return false; | | 2537 | return false; |
2531 | } | | 2538 | } |
2532 | return true; | | 2539 | return true; |
2533 | } | | 2540 | } |
2534 | | | 2541 | |
2535 | sub checkline_rcsid($$) { | | 2542 | sub checkline_rcsid($$) { |
2536 | my ($line, $prefix) = @_; | | 2543 | my ($line, $prefix) = @_; |
2537 | | | 2544 | |
2538 | checkline_rcsid_regex($line, quotemeta($prefix), $prefix); | | 2545 | checkline_rcsid_regex($line, quotemeta($prefix), $prefix); |
2539 | } | | 2546 | } |
2540 | | | 2547 | |
2541 | # Checks whether the line contains text that looks like absolute | | 2548 | # Checks whether the line contains text that looks like absolute |
2542 | # pathnames, assuming that the file uses the common syntax with | | 2549 | # pathnames, assuming that the file uses the common syntax with |
| @@ -4389,27 +4396,30 @@ sub checkline_mk_vartype_basic($$$$$$$$) | | | @@ -4389,27 +4396,30 @@ sub checkline_mk_vartype_basic($$$$$$$$) |
4389 | }, | | 4396 | }, |
4390 | | | 4397 | |
4391 | Stage => sub { | | 4398 | Stage => sub { |
4392 | if ($value !~ m"^(?:pre|do|post)-(?:extract|patch|configure|build|install)$") { | | 4399 | if ($value !~ m"^(?:pre|do|post)-(?:extract|patch|configure|build|install)$") { |
4393 | $line->log_warning("Invalid stage name. Use one of {pre,do,post}-{extract,patch,configure,build,install}."); | | 4400 | $line->log_warning("Invalid stage name. Use one of {pre,do,post}-{extract,patch,configure,build,install}."); |
4394 | } | | 4401 | } |
4395 | }, | | 4402 | }, |
4396 | | | 4403 | |
4397 | String => sub { | | 4404 | String => sub { |
4398 | # No further checks possible. | | 4405 | # No further checks possible. |
4399 | }, | | 4406 | }, |
4400 | | | 4407 | |
4401 | Tool => sub { | | 4408 | Tool => sub { |
4402 | if ($value =~ m"^([-\w]+|\[)(?::(\w+))?$") { | | 4409 | if ($varname eq "TOOLS_NOOP" && $op eq "+=") { |
| | | 4410 | # no warning for package-defined tool definitions |
| | | 4411 | |
| | | 4412 | } elsif ($value =~ m"^([-\w]+|\[)(?::(\w+))?$") { |
4403 | my ($toolname, $tooldep) = ($1, $2); | | 4413 | my ($toolname, $tooldep) = ($1, $2); |
4404 | if (!exists(get_tool_names()->{$toolname})) { | | 4414 | if (!exists(get_tool_names()->{$toolname})) { |
4405 | $line->log_error("Unknown tool \"${toolname}\"."); | | 4415 | $line->log_error("Unknown tool \"${toolname}\"."); |
4406 | } | | 4416 | } |
4407 | if (defined($tooldep) && $tooldep !~ m"^(?:bootstrap|build|pkgsrc|run)$") { | | 4417 | if (defined($tooldep) && $tooldep !~ m"^(?:bootstrap|build|pkgsrc|run)$") { |
4408 | $line->log_error("Unknown tool dependency \"${tooldep}\". Use one of \"build\", \"pkgsrc\" or \"run\"."); | | 4418 | $line->log_error("Unknown tool dependency \"${tooldep}\". Use one of \"build\", \"pkgsrc\" or \"run\"."); |
4409 | } | | 4419 | } |
4410 | } else { | | 4420 | } else { |
4411 | $line->log_error("Invalid tool syntax: \"${value}\"."); | | 4421 | $line->log_error("Invalid tool syntax: \"${value}\"."); |
4412 | } | | 4422 | } |
4413 | }, | | 4423 | }, |
4414 | | | 4424 | |
4415 | Unchecked => sub { | | 4425 | Unchecked => sub { |
| @@ -6921,29 +6931,30 @@ sub checkfile_PLIST($) { | | | @@ -6921,29 +6931,30 @@ sub checkfile_PLIST($) { |
6921 | } elsif ($text =~ m"^share/applications/.*\.desktop$") { | | 6931 | } elsif ($text =~ m"^share/applications/.*\.desktop$") { |
6922 | my $f = "../../sysutils/desktop-file-utils/desktopdb.mk"; | | 6932 | my $f = "../../sysutils/desktop-file-utils/desktopdb.mk"; |
6923 | if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) { | | 6933 | if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) { |
6924 | $line->log_warning("Packages that install a .desktop entry may .include \"$f\"."); | | 6934 | $line->log_warning("Packages that install a .desktop entry may .include \"$f\"."); |
6925 | $line->explain_warning( | | 6935 | $line->explain_warning( |
6926 | "If *.desktop files contain MimeType keys, global MIME Type registory DB", | | 6936 | "If *.desktop files contain MimeType keys, global MIME Type registory DB", |
6927 | "must be updated by desktop-file-utils.", | | 6937 | "must be updated by desktop-file-utils.", |
6928 | "Otherwise, this warning is harmless."); | | 6938 | "Otherwise, this warning is harmless."); |
6929 | } | | 6939 | } |
6930 | | | 6940 | |
6931 | } elsif ($pkgpath ne "graphics/hicolor-icon-theme" && $text =~ m"^share/icons/hicolor(?:$|/)") { | | 6941 | } elsif ($pkgpath ne "graphics/hicolor-icon-theme" && $text =~ m"^share/icons/hicolor(?:$|/)") { |
6932 | my $f = "../../graphics/hicolor-icon-theme/buildlink3.mk"; | | 6942 | my $f = "../../graphics/hicolor-icon-theme/buildlink3.mk"; |
6933 | if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) { | | 6943 | if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) { |
6934 | $line->log_error("Please .include \"$f\""); | | 6944 | $line->log_error("Please .include \"$f\" in the Makefile"); |
6935 | $line->explain_error( | | 6945 | $line->explain_error( |
6936 | "If hicolor icon themes are installed, icon theme cache must be maintained."); | | 6946 | "If hicolor icon themes are installed, icon theme cache must be", |
| | | 6947 | "maintained. The hicolor-icon-theme package takes care of that."); |
6937 | } | | 6948 | } |
6938 | | | 6949 | |
6939 | } elsif ($pkgpath ne "graphics/gnome-icon-theme" && $text =~ m"^share/icons/gnome(?:$|/)") { | | 6950 | } elsif ($pkgpath ne "graphics/gnome-icon-theme" && $text =~ m"^share/icons/gnome(?:$|/)") { |
6940 | my $f = "../../graphics/gnome-icon-theme/buildlink3.mk"; | | 6951 | my $f = "../../graphics/gnome-icon-theme/buildlink3.mk"; |
6941 | if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) { | | 6952 | if (defined($pkgctx_included) && !exists($pkgctx_included->{$f})) { |
6942 | $line->log_error("Please .include \"$f\""); | | 6953 | $line->log_error("Please .include \"$f\""); |
6943 | $line->explain_error( | | 6954 | $line->explain_error( |
6944 | "If Gnome icon themes are installed, icon theme cache must be maintained."); | | 6955 | "If Gnome icon themes are installed, icon theme cache must be maintained."); |
6945 | } | | 6956 | } |
6946 | } elsif ($dirname eq "share/aclocal" && $basename =~ m"\.m4$") { | | 6957 | } elsif ($dirname eq "share/aclocal" && $basename =~ m"\.m4$") { |
6947 | # Fine. | | 6958 | # Fine. |
6948 | | | 6959 | |
6949 | } elsif ($text =~ m"^share/doc/html/") { | | 6960 | } elsif ($text =~ m"^share/doc/html/") { |
| @@ -7154,32 +7165,34 @@ sub checkdir_root() { | | | @@ -7154,32 +7165,34 @@ sub checkdir_root() { |
7154 | | | 7165 | |
7155 | if ($comment_flag eq "#" && (!defined($comment) || $comment eq "")) { | | 7166 | if ($comment_flag eq "#" && (!defined($comment) || $comment eq "")) { |
7156 | $line->log_warning("${subdir} commented out without giving a reason."); | | 7167 | $line->log_warning("${subdir} commented out without giving a reason."); |
7157 | } | | 7168 | } |
7158 | | | 7169 | |
7159 | if ($indentation ne "\t") { | | 7170 | if ($indentation ne "\t") { |
7160 | $line->log_warning("Indentation should be a single tab character."); | | 7171 | $line->log_warning("Indentation should be a single tab character."); |
7161 | } | | 7172 | } |
7162 | | | 7173 | |
7163 | if ($subdir =~ m"\$" || !-f "${current_dir}/${subdir}/Makefile") { | | 7174 | if ($subdir =~ m"\$" || !-f "${current_dir}/${subdir}/Makefile") { |
7164 | next; | | 7175 | next; |
7165 | } | | 7176 | } |
7166 | | | 7177 | |
7167 | if (defined($prev_subdir) && $subdir eq $prev_subdir) { | | 7178 | if (!defined($prev_subdir) || $subdir gt $prev_subdir) { |
| | | 7179 | # correctly ordered |
| | | 7180 | } elsif ($subdir eq $prev_subdir) { |
7168 | $line->log_error("${subdir} must only appear once."); | | 7181 | $line->log_error("${subdir} must only appear once."); |
7169 | } elsif (defined($prev_subdir) && $subdir lt $prev_subdir) { | | 7182 | } elsif ($prev_subdir eq "x11" && $subdir eq "archivers") { |
7170 | $line->log_warning("${subdir} should come before ${prev_subdir}."); | | 7183 | # ignore that one, since it is documented in the top-level Makefile |
7171 | } else { | | 7184 | } else { |
7172 | # correctly ordered | | 7185 | $line->log_warning("${subdir} should come before ${prev_subdir}."); |
7173 | } | | 7186 | } |
7174 | | | 7187 | |
7175 | $prev_subdir = $subdir; | | 7188 | $prev_subdir = $subdir; |
7176 | | | 7189 | |
7177 | if ($comment_flag eq "") { | | 7190 | if ($comment_flag eq "") { |
7178 | push(@subdirs, "${current_dir}/${subdir}"); | | 7191 | push(@subdirs, "${current_dir}/${subdir}"); |
7179 | } | | 7192 | } |
7180 | } | | 7193 | } |
7181 | } | | 7194 | } |
7182 | | | 7195 | |
7183 | checklines_mk($lines); | | 7196 | checklines_mk($lines); |
7184 | | | 7197 | |
7185 | if ($opt_recursive) { | | 7198 | if ($opt_recursive) { |