| @@ -1,15 +1,15 @@ | | | @@ -1,15 +1,15 @@ |
1 | #! @PERL@ | | 1 | #! @PERL@ |
2 | # $NetBSD: pkglint.pl,v 1.856 2013/05/26 18:09:24 wiz Exp $ | | 2 | # $NetBSD: pkglint.pl,v 1.857 2013/08/15 20:30:43 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 | # |
| @@ -4243,27 +4243,27 @@ sub checkline_mk_vartype_basic($$$$$$$$) | | | @@ -4243,27 +4243,27 @@ sub checkline_mk_vartype_basic($$$$$$$$) |
4243 | $line->log_error("PKGBASE must not be used in PKG_OPTIONS_VAR."); | | 4243 | $line->log_error("PKGBASE must not be used in PKG_OPTIONS_VAR."); |
4244 | $line->explain_error( | | 4244 | $line->explain_error( |
4245 | "PKGBASE is defined in bsd.pkg.mk, which is included as the", | | 4245 | "PKGBASE is defined in bsd.pkg.mk, which is included as the", |
4246 | "very last file, but PKG_OPTIONS_VAR is evaluated earlier.", | | 4246 | "very last file, but PKG_OPTIONS_VAR is evaluated earlier.", |
4247 | "Use \${PKGNAME:C/-[0-9].*//} instead."); | | 4247 | "Use \${PKGNAME:C/-[0-9].*//} instead."); |
4248 | } | | 4248 | } |
4249 | }, | | 4249 | }, |
4250 | | | 4250 | |
4251 | PkgRevision => sub { | | 4251 | PkgRevision => sub { |
4252 | if ($value !~ m"^[1-9]\d*$") { | | 4252 | if ($value !~ m"^[1-9]\d*$") { |
4253 | $line->log_warning("${varname} must be a positive integer number."); | | 4253 | $line->log_warning("${varname} must be a positive integer number."); |
4254 | } | | 4254 | } |
4255 | if ($line->fname !~ m"(?:^|/)Makefile$") { | | 4255 | if ($line->fname !~ m"(?:^|/)Makefile$") { |
4256 | $line->log_error("${varname} must not be set outside the package Makefile."); | | 4256 | $line->log_error("${varname} only makes sense directly in the package Makefile."); |
4257 | $line->explain_error( | | 4257 | $line->explain_error( |
4258 | "Usually, different packages using the same Makefile.common have", | | 4258 | "Usually, different packages using the same Makefile.common have", |
4259 | "different dependencies and will be bumped at different times (e.g. for", | | 4259 | "different dependencies and will be bumped at different times (e.g. for", |
4260 | "shlib major bumps) and thus the PKGREVISIONs must be in the separate", | | 4260 | "shlib major bumps) and thus the PKGREVISIONs must be in the separate", |
4261 | "Makefiles. There is no practical way of having this information in a", | | 4261 | "Makefiles. There is no practical way of having this information in a", |
4262 | "commonly used Makefile."); | | 4262 | "commonly used Makefile."); |
4263 | } | | 4263 | } |
4264 | }, | | 4264 | }, |
4265 | | | 4265 | |
4266 | PlatformTriple => sub { | | 4266 | PlatformTriple => sub { |
4267 | my $part = qr"(?:\[[^\]]+\]|[^-\[])+"; | | 4267 | my $part = qr"(?:\[[^\]]+\]|[^-\[])+"; |
4268 | if ($value =~ m"^(${part})-(${part})-(${part})$") { | | 4268 | if ($value =~ m"^(${part})-(${part})-(${part})$") { |
4269 | my ($opsys, $os_version, $arch) = ($1, $2, $3); | | 4269 | my ($opsys, $os_version, $arch) = ($1, $2, $3); |
| @@ -6132,27 +6132,27 @@ sub checkfile_package_Makefile($$) { | | | @@ -6132,27 +6132,27 @@ sub checkfile_package_Makefile($$) { |
6132 | } | | 6132 | } |
6133 | } else { | | 6133 | } else { |
6134 | if (!-f "${current_dir}/${distinfo_file}") { | | 6134 | if (!-f "${current_dir}/${distinfo_file}") { |
6135 | log_warning("${current_dir}/${distinfo_file}", NO_LINE_NUMBER, "File not found. Please run '".conf_make." makesum'."); | | 6135 | log_warning("${current_dir}/${distinfo_file}", NO_LINE_NUMBER, "File not found. Please run '".conf_make." makesum'."); |
6136 | } | | 6136 | } |
6137 | } | | 6137 | } |
6138 | | | 6138 | |
6139 | if (exists($pkgctx_vardef->{"REPLACE_PERL"}) && exists($pkgctx_vardef->{"NO_CONFIGURE"})) { | | 6139 | if (exists($pkgctx_vardef->{"REPLACE_PERL"}) && exists($pkgctx_vardef->{"NO_CONFIGURE"})) { |
6140 | $pkgctx_vardef->{"REPLACE_PERL"}->log_warning("REPLACE_PERL is ignored when ..."); | | 6140 | $pkgctx_vardef->{"REPLACE_PERL"}->log_warning("REPLACE_PERL is ignored when ..."); |
6141 | $pkgctx_vardef->{"NO_CONFIGURE"}->log_warning("... NO_CONFIGURE is set."); | | 6141 | $pkgctx_vardef->{"NO_CONFIGURE"}->log_warning("... NO_CONFIGURE is set."); |
6142 | } | | 6142 | } |
6143 | | | 6143 | |
6144 | if (!exists($pkgctx_vardef->{"LICENSE"})) { | | 6144 | if (!exists($pkgctx_vardef->{"LICENSE"})) { |
6145 | log_error($fname, NO_LINE_NUMBER, "All packages must define their LICENSE."); | | 6145 | log_error($fname, NO_LINE_NUMBER, "Each package must define its LICENSE."); |
6146 | } | | 6146 | } |
6147 | | | 6147 | |
6148 | if (exists($pkgctx_vardef->{"GNU_CONFIGURE"}) && exists($pkgctx_vardef->{"USE_LANGUAGES"})) { | | 6148 | if (exists($pkgctx_vardef->{"GNU_CONFIGURE"}) && exists($pkgctx_vardef->{"USE_LANGUAGES"})) { |
6149 | my $languages_line = $pkgctx_vardef->{"USE_LANGUAGES"}; | | 6149 | my $languages_line = $pkgctx_vardef->{"USE_LANGUAGES"}; |
6150 | my $value = $languages_line->get("value"); | | 6150 | my $value = $languages_line->get("value"); |
6151 | | | 6151 | |
6152 | if ($languages_line->has("comment") && $languages_line->get("comment") =~ m"\b(?:c|empty|none)\b"i) { | | 6152 | if ($languages_line->has("comment") && $languages_line->get("comment") =~ m"\b(?:c|empty|none)\b"i) { |
6153 | # Don't emit a warning, since the comment | | 6153 | # Don't emit a warning, since the comment |
6154 | # probably contains a statement that C is | | 6154 | # probably contains a statement that C is |
6155 | # really not needed. | | 6155 | # really not needed. |
6156 | | | 6156 | |
6157 | } elsif ($value !~ m"(?:^|\s+)(?:c|c99|objc)(?:\s+|$)") { | | 6157 | } elsif ($value !~ m"(?:^|\s+)(?:c|c99|objc)(?:\s+|$)") { |
6158 | $pkgctx_vardef->{"GNU_CONFIGURE"}->log_warning("GNU_CONFIGURE almost always needs a C compiler, ..."); | | 6158 | $pkgctx_vardef->{"GNU_CONFIGURE"}->log_warning("GNU_CONFIGURE almost always needs a C compiler, ..."); |
| @@ -6220,26 +6220,29 @@ sub checkfile_package_Makefile($$) { | | | @@ -6220,26 +6220,29 @@ sub checkfile_package_Makefile($$) { |
6220 | $pkgctx_vardef->{"USE_X11"}->log_note("... USE_X11 superfluous."); | | 6220 | $pkgctx_vardef->{"USE_X11"}->log_note("... USE_X11 superfluous."); |
6221 | } | | 6221 | } |
6222 | | | 6222 | |
6223 | if (defined($effective_pkgbase)) { | | 6223 | if (defined($effective_pkgbase)) { |
6224 | | | 6224 | |
6225 | foreach my $suggested_update (@{get_suggested_package_updates()}) { | | 6225 | foreach my $suggested_update (@{get_suggested_package_updates()}) { |
6226 | my ($line, $suggbase, $suggver, $suggcomm) = @{$suggested_update}; | | 6226 | my ($line, $suggbase, $suggver, $suggcomm) = @{$suggested_update}; |
6227 | my $comment = (defined($suggcomm) ? " (${suggcomm})" : ""); | | 6227 | my $comment = (defined($suggcomm) ? " (${suggcomm})" : ""); |
6228 | | | 6228 | |
6229 | next unless $effective_pkgbase eq $suggbase; | | 6229 | next unless $effective_pkgbase eq $suggbase; |
6230 | | | 6230 | |
6231 | if (dewey_cmp($effective_pkgversion, "<", $suggver)) { | | 6231 | if (dewey_cmp($effective_pkgversion, "<", $suggver)) { |
6232 | $effective_pkgname_line->log_warning("This package should be updated to ${suggver}${comment}."); | | 6232 | $effective_pkgname_line->log_warning("This package should be updated to ${suggver}${comment}."); |
| | | 6233 | $effective_pkgname_line->explain_warning( |
| | | 6234 | "The wishlist for package updates in doc/TODO mentions that a newer", |
| | | 6235 | "version of this package is available."); |
6233 | } | | 6236 | } |
6234 | if (dewey_cmp($effective_pkgversion, "==", $suggver)) { | | 6237 | if (dewey_cmp($effective_pkgversion, "==", $suggver)) { |
6235 | $effective_pkgname_line->log_note("The update request to ${suggver} from doc/TODO${comment} has been done."); | | 6238 | $effective_pkgname_line->log_note("The update request to ${suggver} from doc/TODO${comment} has been done."); |
6236 | } | | 6239 | } |
6237 | if (dewey_cmp($effective_pkgversion, ">", $suggver)) { | | 6240 | if (dewey_cmp($effective_pkgversion, ">", $suggver)) { |
6238 | $effective_pkgname_line->log_note("This package is newer than the update request to ${suggver}${comment}."); | | 6241 | $effective_pkgname_line->log_note("This package is newer than the update request to ${suggver}${comment}."); |
6239 | } | | 6242 | } |
6240 | } | | 6243 | } |
6241 | } | | 6244 | } |
6242 | | | 6245 | |
6243 | checklines_mk($lines); | | 6246 | checklines_mk($lines); |
6244 | checklines_package_Makefile_varorder($lines); | | 6247 | checklines_package_Makefile_varorder($lines); |
6245 | autofix($lines); | | 6248 | autofix($lines); |
| @@ -6272,26 +6275,36 @@ sub checkfile_patch($) { | | | @@ -6272,26 +6275,36 @@ sub checkfile_patch($) { |
6272 | use constant re_patch_ufa => qr"^\+{3}\s(\S+)(?:\s+(.*))?$"; | | 6275 | use constant re_patch_ufa => qr"^\+{3}\s(\S+)(?:\s+(.*))?$"; |
6273 | use constant re_patch_uh => qr"^\@\@\s-(?:(\d+),)?(\d+)\s\+(?:(\d+),)?(\d+)\s\@\@(.*)$"; | | 6276 | use constant re_patch_uh => qr"^\@\@\s-(?:(\d+),)?(\d+)\s\+(?:(\d+),)?(\d+)\s\@\@(.*)$"; |
6274 | use constant re_patch_uld => qr"^-(.*)$"; | | 6277 | use constant re_patch_uld => qr"^-(.*)$"; |
6275 | use constant re_patch_ula => qr"^\+(.*)$"; | | 6278 | use constant re_patch_ula => qr"^\+(.*)$"; |
6276 | use constant re_patch_ulc => qr"^\s(.*)$"; | | 6279 | use constant re_patch_ulc => qr"^\s(.*)$"; |
6277 | use constant re_patch_ulnonl => qr"^\\ No newline at end of file$"; | | 6280 | use constant re_patch_ulnonl => qr"^\\ No newline at end of file$"; |
6278 | | | 6281 | |
6279 | use enum qw(:PST_ | | 6282 | use enum qw(:PST_ |
6280 | START CENTER TEXT | | 6283 | START CENTER TEXT |
6281 | CFA CH CHD CLD0 CLD CLA0 CLA | | 6284 | CFA CH CHD CLD0 CLD CLA0 CLA |
6282 | UFA UH UL | | 6285 | UFA UH UL |
6283 | ); | | 6286 | ); |
6284 | | | 6287 | |
| | | 6288 | my @comment_explanation = ( |
| | | 6289 | "Each patch must document why it is necessary. If it has been applied", |
| | | 6290 | "because of a security issue, a reference to the CVE should be mentioned", |
| | | 6291 | "as well.", |
| | | 6292 | "", |
| | | 6293 | "Since it is our goal to have as few patches as possible, all patches", |
| | | 6294 | "should be sent to the upstream maintainers of the package. After you", |
| | | 6295 | "have done so, you should add a reference to the bug report containing", |
| | | 6296 | "the patch."); |
| | | 6297 | |
6285 | my ($line, $m); | | 6298 | my ($line, $m); |
6286 | | | 6299 | |
6287 | my $check_text = sub($) { | | 6300 | my $check_text = sub($) { |
6288 | my ($text) = @_; | | 6301 | my ($text) = @_; |
6289 | | | 6302 | |
6290 | if ($text =~ m"(\$(Author|Date|Header|Id|Locker|Log|Name|RCSfile|Revision|Source|State|$opt_rcsidstring)(?::[^\$]*)?\$)") { | | 6303 | if ($text =~ m"(\$(Author|Date|Header|Id|Locker|Log|Name|RCSfile|Revision|Source|State|$opt_rcsidstring)(?::[^\$]*)?\$)") { |
6291 | my ($tag) = ($2); | | 6304 | my ($tag) = ($2); |
6292 | | | 6305 | |
6293 | if ($text =~ re_patch_uh) { | | 6306 | if ($text =~ re_patch_uh) { |
6294 | $line->log_warning("Found RCS tag \"\$${tag}\$\". Please remove it."); | | 6307 | $line->log_warning("Found RCS tag \"\$${tag}\$\". Please remove it."); |
6295 | $line->set_text($1); | | 6308 | $line->set_text($1); |
6296 | } else { | | 6309 | } else { |
6297 | $line->log_warning("Found RCS tag \"\$${tag}\$\". Please remove it by reducing the number of context lines using pkgdiff or \"diff -U[210]\"."); | | 6310 | $line->log_warning("Found RCS tag \"\$${tag}\$\". Please remove it by reducing the number of context lines using pkgdiff or \"diff -U[210]\"."); |
| @@ -6423,50 +6436,54 @@ sub checkfile_patch($) { | | | @@ -6423,50 +6436,54 @@ sub checkfile_patch($) { |
6423 | }; | | 6436 | }; |
6424 | | | 6437 | |
6425 | my $transitions = | | 6438 | my $transitions = |
6426 | # [ from state, regex, to state, action ] | | 6439 | # [ from state, regex, to state, action ] |
6427 | [ [PST_START, re_patch_rcsid, PST_CENTER, sub() { | | 6440 | [ [PST_START, re_patch_rcsid, PST_CENTER, sub() { |
6428 | checkline_rcsid($line, ""); | | 6441 | checkline_rcsid($line, ""); |
6429 | }], [PST_START, undef, PST_CENTER, sub() { | | 6442 | }], [PST_START, undef, PST_CENTER, sub() { |
6430 | checkline_rcsid($line, ""); | | 6443 | checkline_rcsid($line, ""); |
6431 | }], [PST_CENTER, re_patch_empty, PST_TEXT, sub() { | | 6444 | }], [PST_CENTER, re_patch_empty, PST_TEXT, sub() { |
6432 | # | | 6445 | # |
6433 | }], [PST_TEXT, re_patch_cfd, PST_CFA, sub() { | | 6446 | }], [PST_TEXT, re_patch_cfd, PST_CFA, sub() { |
6434 | if (!$seen_comment) { | | 6447 | if (!$seen_comment) { |
6435 | $line->log_error("Comment expected."); | | 6448 | $line->log_error("Comment expected."); |
| | | 6449 | $line->explain_error(@comment_explanation); |
6436 | } | | 6450 | } |
6437 | $line->log_warning("Please use unified diffs (diff -u) for patches."); | | 6451 | $line->log_warning("Please use unified diffs (diff -u) for patches."); |
6438 | }], [PST_TEXT, re_patch_ufd, PST_UFA, sub() { | | 6452 | }], [PST_TEXT, re_patch_ufd, PST_UFA, sub() { |
6439 | if (!$seen_comment) { | | 6453 | if (!$seen_comment) { |
6440 | $line->log_error("Comment expected."); | | 6454 | $line->log_error("Comment expected."); |
| | | 6455 | $line->explain_error(@comment_explanation); |
6441 | } | | 6456 | } |
6442 | }], [PST_TEXT, re_patch_text, PST_TEXT, sub() { | | 6457 | }], [PST_TEXT, re_patch_text, PST_TEXT, sub() { |
6443 | $seen_comment = true; | | 6458 | $seen_comment = true; |
6444 | }], [PST_TEXT, re_patch_empty, PST_TEXT, sub() { | | 6459 | }], [PST_TEXT, re_patch_empty, PST_TEXT, sub() { |
6445 | # | | 6460 | # |
6446 | }], [PST_TEXT, undef, PST_TEXT, sub() { | | 6461 | }], [PST_TEXT, undef, PST_TEXT, sub() { |
6447 | # | | 6462 | # |
6448 | }], [PST_CENTER, re_patch_cfd, PST_CFA, sub() { | | 6463 | }], [PST_CENTER, re_patch_cfd, PST_CFA, sub() { |
6449 | if ($seen_comment) { | | 6464 | if ($seen_comment) { |
6450 | $opt_warn_space and $line->log_note("Empty line expected."); | | 6465 | $opt_warn_space and $line->log_note("Empty line expected."); |
6451 | } else { | | 6466 | } else { |
6452 | $line->log_error("Comment expected."); | | 6467 | $line->log_error("Comment expected."); |
| | | 6468 | $line->explain_error(@comment_explanation); |
6453 | } | | 6469 | } |
6454 | $line->log_warning("Please use unified diffs (diff -u) for patches."); | | 6470 | $line->log_warning("Please use unified diffs (diff -u) for patches."); |
6455 | }], [PST_CENTER, re_patch_ufd, PST_UFA, sub() { | | 6471 | }], [PST_CENTER, re_patch_ufd, PST_UFA, sub() { |
6456 | if ($seen_comment) { | | 6472 | if ($seen_comment) { |
6457 | $opt_warn_space and $line->log_note("Empty line expected."); | | 6473 | $opt_warn_space and $line->log_note("Empty line expected."); |
6458 | } else { | | 6474 | } else { |
6459 | $line->log_error("Comment expected."); | | 6475 | $line->log_error("Comment expected."); |
| | | 6476 | $line->explain_error(@comment_explanation); |
6460 | } | | 6477 | } |
6461 | }], [PST_CENTER, undef, PST_TEXT, sub() { | | 6478 | }], [PST_CENTER, undef, PST_TEXT, sub() { |
6462 | $opt_warn_space and $line->log_note("Empty line expected."); | | 6479 | $opt_warn_space and $line->log_note("Empty line expected."); |
6463 | }], [PST_CFA, re_patch_cfa, PST_CH, sub() { | | 6480 | }], [PST_CFA, re_patch_cfa, PST_CH, sub() { |
6464 | $current_fname = $m->text(1); | | 6481 | $current_fname = $m->text(1); |
6465 | $current_ftype = get_filetype($line, $current_fname); | | 6482 | $current_ftype = get_filetype($line, $current_fname); |
6466 | $opt_debug_patches and $line->log_debug("fname=$current_fname ftype=$current_ftype"); | | 6483 | $opt_debug_patches and $line->log_debug("fname=$current_fname ftype=$current_ftype"); |
6467 | $patched_files++; | | 6484 | $patched_files++; |
6468 | $hunks = 0; | | 6485 | $hunks = 0; |
6469 | }], [PST_CH, re_patch_ch, PST_CHD, sub() { | | 6486 | }], [PST_CH, re_patch_ch, PST_CHD, sub() { |
6470 | $hunks++; | | 6487 | $hunks++; |
6471 | }], [PST_CHD, re_patch_chd, PST_CLD0, sub() { | | 6488 | }], [PST_CHD, re_patch_chd, PST_CLD0, sub() { |
6472 | $dellines = ($m->has(2)) | | 6489 | $dellines = ($m->has(2)) |