diff --git a/devel/portlint/Makefile b/devel/portlint/Makefile index 898e714af9ce..4aa4bc3b6f60 100644 --- a/devel/portlint/Makefile +++ b/devel/portlint/Makefile @@ -8,7 +8,7 @@ # PORTNAME= portlint -PORTVERSION= 2.2.1 +PORTVERSION= 2.2.2 CATEGORIES= devel MASTER_SITES= # none DISTFILES= # none diff --git a/devel/portlint/pkg-descr b/devel/portlint/pkg-descr index 8fee79b44be3..39bf003d355e 100644 --- a/devel/portlint/pkg-descr +++ b/devel/portlint/pkg-descr @@ -1,8 +1,10 @@ portlint makes a small set of sanity checks for port directory. -usage: portlint [-avN] [port_directory] - -a additional check for scripts/* and pkg/* - -b warn $(VARIABLE) - -c committer mode - -v verbose mode - -N writing a new port +usage: portlint [-abctvN] [-B#] [port_directory] + -a additional check for scripts/* and pkg/* + -b warn $(VARIABLE) + -c committer mode + -v verbose mode + -t nit pick about use of spaces + -N writing a new port + -B# allow # contiguous blank lines (default: 1 line) diff --git a/devel/portlint/src/portlint.1 b/devel/portlint/src/portlint.1 index 748cfb28bce2..d5c3f4e1615c 100644 --- a/devel/portlint/src/portlint.1 +++ b/devel/portlint/src/portlint.1 @@ -119,6 +119,7 @@ port collection on NetBSD/OpenBSD .Pc .Sh AUTHORS +.An Michael Haro Aq mharo@FreeBSD.org .An Jun-ichiro Hagino Aq itojun@itojun.org and .An Yoshishige Arai Aq ryo2@on.rim.or.jp . diff --git a/devel/portlint/src/portlint.pl b/devel/portlint/src/portlint.pl index a0d6e79eb4dc..792a89031f99 100644 --- a/devel/portlint/src/portlint.pl +++ b/devel/portlint/src/portlint.pl @@ -17,20 +17,21 @@ # OpenBSD and NetBSD will be accepted. # # $FreeBSD$ -# $Id: portlint.pl,v 1.16 2000/04/16 22:39:57 mharo Exp $ +# $Id: portlint.pl,v 1.28.2.1 2000/04/24 02:12:36 mharo Exp $ # -use vars qw/ $opt_a $opt_b $opt_c $opt_h $opt_v $opt_N $opt_B $opt_V /; +use vars qw/ $opt_a $opt_b $opt_c $opt_h $opt_t $opt_v $opt_M $opt_N $opt_B $opt_V /; use Getopt::Std; #use strict; my ($err, $warn); -my ($extrafile, $parenwarn, $committer, $verbose, $newport); +my ($extrafile, $parenwarn, $committer, $verbose, $usetabs, $newport); my $contblank; my $portdir; +my $makeenv; $err = $warn = 0; -$extrafile = $parenwarn = $committer = $verbose = $newport = 0; +$extrafile = $parenwarn = $committer = $verbose = $usetabs = $newport = 0; $contblank = 1; $portdir = '.'; @@ -46,7 +47,6 @@ my $l = &l; my $r = &r; my $s = &s; - # default setting - for FreeBSD my $portsdir = '/usr/ports'; my $rcsidstr = 'FreeBSD'; @@ -71,11 +71,13 @@ my $re_lang_pref = '(' . join('|', @lang_pref) . ')'; my ($prog) = ($0 =~ /([^\/]+)$/); sub usage { print STDERR <, <$portdir/pkg/*>)) { + foreach my $i ((, )) { next if (! -T $i); - $i =~ s/^$portdir\///; next if (defined $checker{$i}); if ($i =~ /pkg\/PLIST$/ || ($multiplist && $i =~ /pkg\/PLIST/)) { @@ -250,16 +275,15 @@ if ($extrafile) { } } } -foreach my $i (<$portdir/patches/patch-??>) { +foreach my $i () { next if (! -T $i); - $i =~ s/^$portdir\///; next if (defined $checker{$i}); push(@checker, $i); $checker{$i} = 'checkpatch'; } foreach my $i (@checker) { print "OK: checking $i.\n"; - if (! -f "$portdir/$i") { + if (! -f "$i") { &perror("FATAL: no $i in \"$portdir\"."); } else { my $proc = $checker{$i}; @@ -271,16 +295,16 @@ foreach my $i (@checker) { } } if ($committer) { - if (scalar(@_ = <$portdir/work/*>) || -d "$portdir/work") { + if (scalar(@_ = ) || -d "work") { &perror("FATAL: be sure to cleanup $portdir/work ". "before committing the port."); } - if (scalar(@_ = <$portdir/*/*~>) || scalar(@_ = <$portdir/*~>)) { + if (scalar(@_ = <*/*~>) || scalar(@_ = <*~>)) { &perror("FATAL: for safety, be sure to cleanup ". "editor backup files before committing the port."); } - if (scalar(@_ = <$portdir/*/*.orig>) || scalar(@_ = <$portdir/*.orig>) - || scalar(@_ = <$portdir/*/*.rej>) || scalar(@_ = <$portdir/*.rej>)) { + if (scalar(@_ = <*/*.orig>) || scalar(@_ = ) + || scalar(@_ = <*/*.rej>) || scalar(@_ = <*.rej>)) { &perror("FATAL: for safety, be sure to cleanup ". "patch backup files before committing the port."); } @@ -297,14 +321,14 @@ exit $err; # sub checkdescr { my($file) = @_; - my(%maxchars) = ('pkg/COMMENT', 70, 'pkg/DESCR', 80); - my(%maxlines) = ('pkg/COMMENT', 1, 'pkg/DESCR', 24); - my(%errmsg) = ('pkg/COMMENT', "must be one-liner.", - 'pkg/DESCR', "exceeds $maxlines{'pkg/DESCR'} ". + my(%maxchars) = ($makevar{COMMENT}, 70, $makevar{DESCR}, 80); + my(%maxlines) = ($makevar{COMMENT}, 1, $makevar{DESCR}, 24); + my(%errmsg) = ($makevar{COMMENT}, "must be one-liner.", + $makevar{DESCR}, "exceeds $maxlines{$makevar{DESCR}} ". "lines, make it shorter if possible."); my($longlines, $linecnt, $tmp) = (0, 0, ""); - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; while () { $linecnt++; $longlines++ if ($maxchars{$file} < length(chomp($_))); @@ -325,8 +349,22 @@ sub checkdescr { "other local characters. $file should be ". "plain ascii file."); } + if ($file =~ m/DESCR/ && $tmp =~ m,http://,) { + my $has_url = 0; + my $has_www = 0; + foreach my $line (grep($_ =~ "http://", split(/\n+/, $tmp))) { + $has_url = 1; + if ($line =~ m,WWW:[ \t]+http://,) { + $has_www = 1; + } + } + + if ($has_url && ! $has_www) { + &perror("FATAL: $file: contains a URL but no WWW:"); + } + } if ($file =~ m/COMMENT/) { - if (($tmp !~ /^[0-9A-Z].*$/) || ($tmp =~ m/\.$/)) { + if (($tmp !~ /^["0-9A-Z]/) || ($tmp =~ m/\.$/)) { &perror("WARN: pkg/COMMENT should begin with a capital, and end without a period"); } } @@ -348,7 +386,7 @@ sub checkplist { my(@unexec_info) = (); my(@infofile) = (); - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; while () { if ($_ =~ /[ \t]+\n?$/) { &perror("WARN: $file $.: whitespace before end ". @@ -515,7 +553,7 @@ sub checkpathname { my($file) = @_; my($whole); - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; $whole = ''; while () { $whole .= $_; @@ -528,7 +566,7 @@ sub checklastline { my($file) = @_; my($whole); - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; $whole = ''; while () { $whole .= $_; @@ -549,13 +587,13 @@ sub checkpatch { my($file) = @_; my($whole); - if (-z "$portdir/$file") { + if (-z "$file") { &perror("FATAL: $file has no content. should be removed ". "from repository."); return; } - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; $whole = ''; while () { $whole .= $_; @@ -581,10 +619,12 @@ sub checkmakefile { my $bogusdistfiles = 0; my @varnames = (); my($portname, $portversion, $distfiles, $distname, $extractsufx) = ('', '', '', '', ''); + my $masterport = 0; + my $slaveport = 0; my($realwrksrc, $wrksrc, $nowrksubdir) = ('', '', ''); my(@mman, @pman); - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; $rawwhole = ''; $tmp = 0; while () { @@ -596,6 +636,17 @@ sub checkmakefile { &perror("WARN: $file $.: use tab (not space) to make ". "indentation"); } + if ($usetabs) { + if (m/^[A-Za-z0-9_-]+.?= /) { + if (m/[?+]=/) { + &perror("WARN: $file $.: use a tab (not space) after a ". + "variable name"); + } else { + &perror("FATAL: $file $.: use a tab (not space) after a ". + "variable name"); + } + } + } # # I'm still not very convinced, for using this kind of magical word. # 1. This kind of items are not important for Makefile; @@ -673,7 +724,6 @@ sub checkmakefile { "PORTVERSION, PKGNAMEPREFIX and PKGNAMESUFFIX."); } - # # whole file: IS_INTERACTIVE/NOPORTDOCS # @@ -752,6 +802,18 @@ EOF # &abspathname($whole, $file); + # + # slave port check + # + my $masterdir = $makevar{MASTERDIR}; + if ($masterdir ne '' && $masterdir ne $makevar{'.CURDIR'}) { + $slaveport = 1; + print "OK: checking master port in $masterdir.\n" if ($verbose); + if (! -e "$masterdir/Makefile") { + &perror("WARN: unable to locate master port in $masterdir"); + } + } + # # break the makefile into sections. # @@ -795,14 +857,12 @@ EOF print "OK: \"$j\" seen in $file.\n" if ($verbose); } } - foreach my $i (@linestocheck) { - if ($i =~ m/Version [rR]equired/) { - &perror("FATAL: Version required is no longer needed in the comment section of $file."); - } + if ($tmp =~ m/Version [rR]equired/) { + &perror("WARN: Version required is no longer needed in the comment section of $file."); } my $tmp2 = ""; for (split(/\n/, $tmp)) { - $tmp2 = $_ if (m/$rcsidstr/); + $tmp2 .= $_ if (m/\$$rcsidstr/); } if ($tmp2 !~ /#(\s+)\$$rcsidstr([^\$]*)\$$/) { @@ -847,38 +907,38 @@ EOF # check the order of items. &checkorder('PORTNAME', $tmp, split(/\s+/, <, <$portdir/pkg/*>)) { + foreach my $i ((, )) { next if (! -T $i); - $i =~ s/^$portdir\///; next if (defined $checker{$i}); if ($i =~ /pkg\/PLIST$/ || ($multiplist && $i =~ /pkg\/PLIST/)) { @@ -250,16 +275,15 @@ if ($extrafile) { } } } -foreach my $i (<$portdir/patches/patch-??>) { +foreach my $i () { next if (! -T $i); - $i =~ s/^$portdir\///; next if (defined $checker{$i}); push(@checker, $i); $checker{$i} = 'checkpatch'; } foreach my $i (@checker) { print "OK: checking $i.\n"; - if (! -f "$portdir/$i") { + if (! -f "$i") { &perror("FATAL: no $i in \"$portdir\"."); } else { my $proc = $checker{$i}; @@ -271,16 +295,16 @@ foreach my $i (@checker) { } } if ($committer) { - if (scalar(@_ = <$portdir/work/*>) || -d "$portdir/work") { + if (scalar(@_ = ) || -d "work") { &perror("FATAL: be sure to cleanup $portdir/work ". "before committing the port."); } - if (scalar(@_ = <$portdir/*/*~>) || scalar(@_ = <$portdir/*~>)) { + if (scalar(@_ = <*/*~>) || scalar(@_ = <*~>)) { &perror("FATAL: for safety, be sure to cleanup ". "editor backup files before committing the port."); } - if (scalar(@_ = <$portdir/*/*.orig>) || scalar(@_ = <$portdir/*.orig>) - || scalar(@_ = <$portdir/*/*.rej>) || scalar(@_ = <$portdir/*.rej>)) { + if (scalar(@_ = <*/*.orig>) || scalar(@_ = ) + || scalar(@_ = <*/*.rej>) || scalar(@_ = <*.rej>)) { &perror("FATAL: for safety, be sure to cleanup ". "patch backup files before committing the port."); } @@ -297,14 +321,14 @@ exit $err; # sub checkdescr { my($file) = @_; - my(%maxchars) = ('pkg/COMMENT', 70, 'pkg/DESCR', 80); - my(%maxlines) = ('pkg/COMMENT', 1, 'pkg/DESCR', 24); - my(%errmsg) = ('pkg/COMMENT', "must be one-liner.", - 'pkg/DESCR', "exceeds $maxlines{'pkg/DESCR'} ". + my(%maxchars) = ($makevar{COMMENT}, 70, $makevar{DESCR}, 80); + my(%maxlines) = ($makevar{COMMENT}, 1, $makevar{DESCR}, 24); + my(%errmsg) = ($makevar{COMMENT}, "must be one-liner.", + $makevar{DESCR}, "exceeds $maxlines{$makevar{DESCR}} ". "lines, make it shorter if possible."); my($longlines, $linecnt, $tmp) = (0, 0, ""); - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; while () { $linecnt++; $longlines++ if ($maxchars{$file} < length(chomp($_))); @@ -325,8 +349,22 @@ sub checkdescr { "other local characters. $file should be ". "plain ascii file."); } + if ($file =~ m/DESCR/ && $tmp =~ m,http://,) { + my $has_url = 0; + my $has_www = 0; + foreach my $line (grep($_ =~ "http://", split(/\n+/, $tmp))) { + $has_url = 1; + if ($line =~ m,WWW:[ \t]+http://,) { + $has_www = 1; + } + } + + if ($has_url && ! $has_www) { + &perror("FATAL: $file: contains a URL but no WWW:"); + } + } if ($file =~ m/COMMENT/) { - if (($tmp !~ /^[0-9A-Z].*$/) || ($tmp =~ m/\.$/)) { + if (($tmp !~ /^["0-9A-Z]/) || ($tmp =~ m/\.$/)) { &perror("WARN: pkg/COMMENT should begin with a capital, and end without a period"); } } @@ -348,7 +386,7 @@ sub checkplist { my(@unexec_info) = (); my(@infofile) = (); - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; while () { if ($_ =~ /[ \t]+\n?$/) { &perror("WARN: $file $.: whitespace before end ". @@ -515,7 +553,7 @@ sub checkpathname { my($file) = @_; my($whole); - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; $whole = ''; while () { $whole .= $_; @@ -528,7 +566,7 @@ sub checklastline { my($file) = @_; my($whole); - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; $whole = ''; while () { $whole .= $_; @@ -549,13 +587,13 @@ sub checkpatch { my($file) = @_; my($whole); - if (-z "$portdir/$file") { + if (-z "$file") { &perror("FATAL: $file has no content. should be removed ". "from repository."); return; } - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; $whole = ''; while () { $whole .= $_; @@ -581,10 +619,12 @@ sub checkmakefile { my $bogusdistfiles = 0; my @varnames = (); my($portname, $portversion, $distfiles, $distname, $extractsufx) = ('', '', '', '', ''); + my $masterport = 0; + my $slaveport = 0; my($realwrksrc, $wrksrc, $nowrksubdir) = ('', '', ''); my(@mman, @pman); - open(IN, "< $portdir/$file") || return 0; + open(IN, "< $file") || return 0; $rawwhole = ''; $tmp = 0; while () { @@ -596,6 +636,17 @@ sub checkmakefile { &perror("WARN: $file $.: use tab (not space) to make ". "indentation"); } + if ($usetabs) { + if (m/^[A-Za-z0-9_-]+.?= /) { + if (m/[?+]=/) { + &perror("WARN: $file $.: use a tab (not space) after a ". + "variable name"); + } else { + &perror("FATAL: $file $.: use a tab (not space) after a ". + "variable name"); + } + } + } # # I'm still not very convinced, for using this kind of magical word. # 1. This kind of items are not important for Makefile; @@ -673,7 +724,6 @@ sub checkmakefile { "PORTVERSION, PKGNAMEPREFIX and PKGNAMESUFFIX."); } - # # whole file: IS_INTERACTIVE/NOPORTDOCS # @@ -752,6 +802,18 @@ EOF # &abspathname($whole, $file); + # + # slave port check + # + my $masterdir = $makevar{MASTERDIR}; + if ($masterdir ne '' && $masterdir ne $makevar{'.CURDIR'}) { + $slaveport = 1; + print "OK: checking master port in $masterdir.\n" if ($verbose); + if (! -e "$masterdir/Makefile") { + &perror("WARN: unable to locate master port in $masterdir"); + } + } + # # break the makefile into sections. # @@ -795,14 +857,12 @@ EOF print "OK: \"$j\" seen in $file.\n" if ($verbose); } } - foreach my $i (@linestocheck) { - if ($i =~ m/Version [rR]equired/) { - &perror("FATAL: Version required is no longer needed in the comment section of $file."); - } + if ($tmp =~ m/Version [rR]equired/) { + &perror("WARN: Version required is no longer needed in the comment section of $file."); } my $tmp2 = ""; for (split(/\n/, $tmp)) { - $tmp2 = $_ if (m/$rcsidstr/); + $tmp2 .= $_ if (m/\$$rcsidstr/); } if ($tmp2 !~ /#(\s+)\$$rcsidstr([^\$]*)\$$/) { @@ -847,38 +907,38 @@ EOF # check the order of items. &checkorder('PORTNAME', $tmp, split(/\s+/, <