From owner-ports-jp@jp.freebsd.org  Fri Jun 13 20:49:39 1997
Received: by jaz.jp.freebsd.org (8.8.5+2.7Wbeta5/8.7.3) id UAA06946
	Fri, 13 Jun 1997 20:49:39 +0900 (JST)
Received: by jaz.jp.freebsd.org (8.8.5+2.7Wbeta5/8.7.3) with ESMTP id UAA06940
	for <ports-jp@jp.freebsd.org>; Fri, 13 Jun 1997 20:49:37 +0900 (JST)
From: itojun@itojun.org
Received: from localhost (itojun@localhost [127.0.0.1]) by itojun.csl.sony.co.jp (8.8.5/3.3W3) with ESMTP id UAA25912 for <ports-jp@jp.freebsd.org>; Fri, 13 Jun 1997 20:49:36 +0900 (JST)
To: ports-jp@jp.freebsd.org
X-Template-Reply-To: itojun@itojun.org
X-Template-Return-Receipt-To: itojun@itojun.org
X-PGP-Fingerprint: F8 24 B4 2C 8C 98 57 FD  90 5F B4 60 79 54 16 E2
References: <18838.866137410@itojun.csl.sony.co.jp>
In-reply-to: itojun@itojun.org's message of Fri, 13 Jun 1997 02:43:30 +0900.
	<18838.866137410@itojun.csl.sony.co.jp>
X-Mailer: comp (MHng project) version 1997/04/30 02:23:09, by Jun-ichiro Itoh
MIME-Version: 1.0
Content-type: text/plain; charset=iso-2022-jp
Content-transfer-encoding: 7bit
Content-ID: <top.866202574.25904@itojun.csl.sony.co.jp>
Date: Fri, 13 Jun 1997 20:49:35 +0900
Message-ID: <25909.866202575@itojun.csl.sony.co.jp>
Reply-To: ports-jp@jp.freebsd.org
Precedence: bulk
X-Distribute: distribute [version 2.1 (Alpha) patchlevel=19]
X-Sequence: ports-jp 1152
Subject: [ports-jp 1152] Re: portlint
Errors-To: owner-ports-jp@jp.freebsd.org
Sender: owner-ports-jp@jp.freebsd.org

	$BD:$$$?$N$r$$$/$D$+D>$7$F!"0J2<$KCV$-$^$7$?!#(B
	$B0J2<$N(BURL$B$K>o$K:G?7HG$rCV$$$F$*$/$D$b$j$G$9(B:
	ftp://ftp.foretune.co.jp/pub/tools/portlint/portlint.pl

	- *_DEPEND$B$O$J$/$F$b9=$o$J$$$N$G!"$J$$>l9g$b9MN8(B
	- MASTER_SITES+=$B$N@55,I=8=D>$7(B
	- EXTRACT_SUFX$B$,(B"."$B$G$O$8$^$k!"$C$F%k!<%k$,$"$C$?$1$I!"(B
	  $BI,$:$7$b$=$&$8$c$J$$$N$G=|5n(B
	  (hoge-2.2-tar.gz$B$C$F$N$,2a5n$K$"$C$?(B)

	$B$?$$$7$?Bg$-$5$G$O$J$$$N$G!"$$$A$*$&E:IU$7$F$*$-$^$9!#(B
	$B0J8e$OE:IUITMW$+$J!#(B

itojun


---
#! /usr/bin/perl
#
# portlint - lint for port directory
# implemented by:
#	Jun-ichiro itojun Itoh <itojun@itojun.org>
#	Yoshishige Arai <ryo2@on.rim.or.jp>
# visit ftp://ftp.foetune.co.jp/pub/tools/portlint/ for latest version.
#
# $Id: portlint.pl,v 1.3 1997/06/13 11:45:24 itojun Exp $
#

$err = $warn = 0;
$verbose = 0;
$portdir = ".";
while (@ARGV > 0) {
	$_ = shift;
	/^-v/ && do {$verbose = 1; next;};
	$portdir = $_;
}
select(STDERR);

#
# check for files.
#
@checker = ('pkg/PLIST', 'pkg/COMMENT', 'pkg/DESCR', 'Makefile');
%checker = ('pkg/PLIST', 'TRUE', 'pkg/COMMENT', 'checkdescr',
	    'pkg/DESCR', 'checkdescr', 'Makefile', 'checkmakefile');
foreach $i (@checker) {
	if (! -f "$portdir/$i") {
		&perror("FATAL: no $i in \"$portdir\".");
	} else {
		$proc = $checker{$i};
		&$proc($i) || &perror("Cannot open the file $i\n");
	}
}
print "$err fatal errors and $warn warnings found.\n"
	if ($err || $warn);
exit $err;

#
# pkg/COMMENT, pkg/DESCR
#
sub checkdescr {
	local($file) = @_;
	local(%maxcnt) = ('pkg/COMMENT', 1, 'pkg/DESCR', 20);
	local(%errmsg) = ('pkg/COMMENT', "must be one-liner.",
			  'pkg/DESCR', "exceeds $maxcnt{'pkg/DESCR'} lines, ".
			  "could you trim it if possible?");
	local($longlines, $linecnt, $tmp) = (0, 0, "");

	print "OK: looking into $file.\n" if ($verbose);
	open(IN, "< $portdir/$file") || return 0;
	while (<IN>) {
		$linecnt++;
		$longlines++ if (80 < length($_));
		$tmp .= $_;
	}
	if ($linecnt > $maxcnt{$file}) {
		&perror("WARN: $file $errmsg{$file}");
	}
	if ($longlines > 0) {
		&perror("WARN: $i includes lines that exceed 80 charactors.");
	}
	if ($tmp =~ /[\033\200-\377]/) {
		&perror("WARN: pkg/DESCR includes iso-8859-1, or ".
			"other local characters.  $file should be".
			"plain ascii file.");
	}
	close(IN);
}

#
# Makefile
#
sub checkmakefile {
	local($file) = @_;
	local($tmp, $tmp2);
	print "OK: looking into Makefile.\n" if ($verbose);

	open(IN, "< $portdir/$file") || return 0;

	# Makefile 1: comment lines.
	print "OK: looking into comment section of $file.\n" if ($verbose);
	@linestocheck = split("\n", <<EOF);
Whom
Version required
Date created
EOF
	$tmp = '';
	while (<IN>) {
		last if (!/^#/);

		$tmp .= $_;
	}
	if ($_ ne "\n") {
		&perror("WARN: no blank line after $file comment section.");
	}

	foreach $i (@linestocheck) {
		if ($tmp !~ /# $i:[ 	]+\S+/) {
			&perror("FATAL: no \"$i\" line in $file comment section.");
		}
	}
	if ($tmp !~ /# (New )?ports collection makefile for:[ 	]+\S+/) {
		&perror("FATAL: no \"ports collection makefile for\" ".
			"line in $file comment section.");
	}
	if ($tmp !~ /#\n# \$Id([^\$]+)\$\n/) {
		&perror("FATAL: no \$Id\$ line in $file comment section.");
	} else {
		if ($1 ne '') {
			&perror("WARN: is it a new port? ".
			"if so, make \$Id\$ tag in comment section empty ".
			"to make CVS happy.");
		}
	}

	# Makefile 2: DISTNAME/PKGNAME/...
	print "OK: looking into first section of $file. (DISTNAME/...)\n"
		if ($verbose);
	$tmp = &read_nextblock(*IN);
	if ($tmp !~ /^DISTNAME=/) {
		&perror("FATAL: DISTNAME must come first.");
	} else {
		print "OK: seen DISTNAME.\n" if ($verbose);
		$tmp =~ s/^[^\n]+\n//;
	}
	if ($tmp =~ /^PKGNAME=/) {
		print "OK: seen PKGNAME.\n" if ($verbose);
		$tmp =~ s/^[^\n]+\n//;
	}
	if ($tmp !~ /^CATEGORIES=/) {
		&perror("FATAL: CATEGORIES must be placed after DISTNAME.".
			"(or after PKGNAME, if there is PKGNAME)");
	} else {
		print "OK: seen CATEGORIES.\n" if ($verbose);
		$tmp =~ s/^[^\n]+\n//;
	}
	unless ($tmp =~ s/^MASTER_SITES\+?=\s*//) {
		&perror("WARN: no MASTER_SITES found. is it OK?");
	} else {
		print "OK: seen MASTER_SITES.\n" if ($verbose);
		$tmp =~ s/^([^\n]+)\n//; @sites = split(/[ \t]+/, $1);
		foreach $i (@sites) {
			&perror("FATAL: URL $i should end with \"/\".")
				if ($i =~ m#^\w+://# && $i !~ m#/$#);
		}
	}
	if ($tmp =~ /^MASTER_SITES_SUBDIR=/) {
		print "OK: seen MASTER_SITES_SUBDIR.\n" if ($verbose);
		$tmp =~ s/^[^\n]+\n//;
	}
	if ($tmp =~ /^EXTRACT_SUFX=/) {
		print "OK: seen EXTRACT_SUFX.\n" if ($verbose);
		$tmp =~ s/^[^\n]+\n//;
	}
	if ($tmp =~ /^DISTFILES=/) {
		print "OK: seen DISTFILES.\n" if ($verbose);
		$tmp =~ s/^[^\n]+\n//;
	}
	if ($tmp ne '') {
		&perror("WARN: extra item placed in the DISTNAME/... section.");
	}

	# Makefile 3: PATCH_SITES/PATCHFILES(optional)
	print "OK: looking into second section of $file, (PATCH*: optinal).\n"
		if ($verbose);
	$tmp = &read_nextblock(*IN);
	if ($tmp !~ /^MAINTAINER=/) {
		if ($tmp =~ /^PATCH_SITES=/) {
			print "OK: seen PATCH_SITES.\n" if ($verbose);
			$tmp =~ s/^[^\n]+\n//;
		}
		if ($tmp =~ /^PATCHFILES=/) {
			print "OK: seen PATCHFILES.\n" if ($verbose);
			$tmp =~ s/^[^\n]+\n//;
		}
		$tmp = &read_nextblock(*IN);
	}

	# Makefile 4: MAINTAINER
	print "OK: looking into third section of Makefile (MAINTAINER).\n"
		if ($verbose);
	if ($tmp !~ /^MAINTAINER=[^\n]+\n$/) {
		&perror("FATAL: extra item placed in MAINTAINER section.");
	}

	# Makefile 5: *_DEPENDS (may not be there)
	print "OK: looking into fourth section of $file(*_DEPENDS).\n"
		if ($verbose);
	@linestocheck = split("\n", <<EOF);
LIB_DEPENDS
BUILD_DEPENDS
RUN_DEPENDS
FETCH_DEPENDS
DEPENDS
EOF
	$tmp = $tmp2 = &read_nextblock(*IN);
	foreach $i (@linestocheck) {
		$tmp =~ s/$i=[^\n]+\n//g;
	}
	if ($tmp ne '' && $tmp ne $tmp2) {
		&perror("WARN: extra item placed in *_DEPENDS section.");
	}
	close(IN);
}

sub read_nextblock {
	local(*F) = @_;
	local($s) = "";
	while (<F>) {
		last if ($_ eq "\n");
		next if ($_ =~ /^#/);
		$s .= $_;
	}
	$s =~ s/\\\n//g;
	$s;
}

sub perror {
	local(@msg) = @_;
	if ($msg[0] =~ /^FATAL/) {
		$err++;
	} else {
		$warn++;
	}
	print join("\n", @msg) . "\n";
}

sub TRUE {1;}
