pkgsrc-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[pkgsrc/trunk]: pkgsrc/pkgtools/pkglint Updated pkglint to 5.4.7.
details: https://anonhg.NetBSD.org/pkgsrc/rev/19201637f9e7
branches: trunk
changeset: 349581:19201637f9e7
user: rillig <rillig%pkgsrc.org@localhost>
date: Sun Jul 10 21:24:47 2016 +0000
description:
Updated pkglint to 5.4.7.
Changes since 5.4.6:
* Allow conditionals of the form "${var1}" == "${var2}"
* Check for indentation of .include directives
* Check arbitrarily complex license conditions
* General code cleanup
diffstat:
pkgtools/pkglint/Makefile | 4 +-
pkgtools/pkglint/files/globaldata.go | 2 +-
pkgtools/pkglint/files/globaldata_test.go | 4 +-
pkgtools/pkglint/files/license.y | 35 +
pkgtools/pkglint/files/licenses.go | 162 ++-
pkgtools/pkglint/files/licenses_test.go | 27 +-
pkgtools/pkglint/files/main.go | 2 +-
pkgtools/pkglint/files/mkline.go | 236 ++--
pkgtools/pkglint/files/mkline_test.go | 17 +-
pkgtools/pkglint/files/mklines.go | 2 +-
pkgtools/pkglint/files/mkparser.go | 10 +
pkgtools/pkglint/files/mkparser_test.go | 4 +
pkgtools/pkglint/files/mkshparser_test.go | 110 +-
pkgtools/pkglint/files/mkshtypes.go | 14 +-
pkgtools/pkglint/files/mkshtypes_test.go | 5 +
pkgtools/pkglint/files/mktypes.go | 4 -
pkgtools/pkglint/files/mktypes_test.go | 4 +
pkgtools/pkglint/files/package.go | 4 +-
pkgtools/pkglint/files/pkglint.go | 2 +-
pkgtools/pkglint/files/shell.go | 394 +++----
pkgtools/pkglint/files/shell.y | 26 +-
pkgtools/pkglint/files/shell_test.go | 20 -
pkgtools/pkglint/files/shtokenizer.go | 4 +-
pkgtools/pkglint/files/shtypes.go | 10 -
pkgtools/pkglint/files/shtypes_test.go | 10 +-
pkgtools/pkglint/files/vardefs.go | 1316 +++++++++++++-------------
pkgtools/pkglint/files/vartype.go | 224 ++--
pkgtools/pkglint/files/vartype_test.go | 4 +-
pkgtools/pkglint/files/vartypecheck.go | 27 +-
pkgtools/pkglint/files/vartypecheck_test.go | 18 +
30 files changed, 1398 insertions(+), 1303 deletions(-)
diffs (truncated from 3922 to 300 lines):
diff -r e38ef21c14fe -r 19201637f9e7 pkgtools/pkglint/Makefile
--- a/pkgtools/pkglint/Makefile Sun Jul 10 21:12:19 2016 +0000
+++ b/pkgtools/pkglint/Makefile Sun Jul 10 21:24:47 2016 +0000
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.491 2016/07/10 11:37:27 rillig Exp $
+# $NetBSD: Makefile,v 1.492 2016/07/10 21:24:47 rillig Exp $
-PKGNAME= pkglint-5.4.6
+PKGNAME= pkglint-5.4.7
DISTFILES= # none
CATEGORIES= pkgtools
diff -r e38ef21c14fe -r 19201637f9e7 pkgtools/pkglint/files/globaldata.go
--- a/pkgtools/pkglint/files/globaldata.go Sun Jul 10 21:12:19 2016 +0000
+++ b/pkgtools/pkglint/files/globaldata.go Sun Jul 10 21:24:47 2016 +0000
@@ -114,7 +114,7 @@
fname := G.globalData.Pkgsrcdir + "/mk/tools/bsd.tools.mk"
lines := LoadExistingLines(fname, true)
for _, line := range lines {
- if m, _, includefile := match2(line.Text, reMkInclude); m {
+ if m, _, _, includefile := match3(line.Text, reMkInclude); m {
if !contains(includefile, "/") {
toolFiles = append(toolFiles, includefile)
}
diff -r e38ef21c14fe -r 19201637f9e7 pkgtools/pkglint/files/globaldata_test.go
--- a/pkgtools/pkglint/files/globaldata_test.go Sun Jul 10 21:12:19 2016 +0000
+++ b/pkgtools/pkglint/files/globaldata_test.go Sun Jul 10 21:24:47 2016 +0000
@@ -7,8 +7,8 @@
func (s *Suite) Test_GlobalData_InitVartypes(c *check.C) {
G.globalData.InitVartypes()
- c.Check(G.globalData.vartypes["BSD_MAKE_ENV"].checker.name, equals, "ShellWord")
- c.Check(G.globalData.vartypes["USE_BUILTIN.*"].checker.name, equals, "YesNoIndirectly")
+ c.Check(G.globalData.vartypes["BSD_MAKE_ENV"].basicType.name, equals, "ShellWord")
+ c.Check(G.globalData.vartypes["USE_BUILTIN.*"].basicType.name, equals, "YesNoIndirectly")
}
func (s *Suite) Test_parselinesSuggestedUpdates(c *check.C) {
diff -r e38ef21c14fe -r 19201637f9e7 pkgtools/pkglint/files/license.y
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pkgtools/pkglint/files/license.y Sun Jul 10 21:24:47 2016 +0000
@@ -0,0 +1,35 @@
+%{
+package main
+%}
+
+%token <Node> ltNAME
+%token ltAND ltOR ltOPEN ltCLOSE
+
+%union {
+ Node *LicenseCondition
+}
+
+%type <Node> start list condition
+
+%%
+
+start : list {
+ liyylex.(*licenseLexer).result = $$
+}
+
+list : condition {
+ $$ = $1
+}
+list : list ltAND condition {
+ $$.And = append($$.And, $3)
+}
+list : list ltOR condition {
+ $$.Or = append($$.Or, $3)
+}
+
+condition : ltNAME {
+ $$ = $1
+}
+condition : ltOPEN list ltCLOSE {
+ $$ = &LicenseCondition{Main: $2}
+}
diff -r e38ef21c14fe -r 19201637f9e7 pkgtools/pkglint/files/licenses.go
--- a/pkgtools/pkglint/files/licenses.go Sun Jul 10 21:12:19 2016 +0000
+++ b/pkgtools/pkglint/files/licenses.go Sun Jul 10 21:24:47 2016 +0000
@@ -2,16 +2,78 @@
import (
"io/ioutil"
- "strings"
)
-func parseLicenses(licenses string) []string {
- noPerl := strings.Replace(licenses, "${PERL5_LICENSE}", "gnu-gpl-v2 OR artistic", -1)
- noOps := regcomp(`[()]|AND|OR`).ReplaceAllString(noPerl, "") // cheated
- return splitOnSpace(strings.TrimSpace(noOps))
+//go:generate go tool yacc -p liyy -o licenseyacc.go -v licenseyacc.log license.y
+
+// LicenseCondition describes a complex license condition.
+// It has either `Name` or `Main` set.
+type LicenseCondition struct {
+ Name string
+ Main *LicenseCondition
+ And []*LicenseCondition
+ Or []*LicenseCondition
+}
+
+func (lc *LicenseCondition) Walk(callback func(*LicenseCondition)) {
+ callback(lc)
+ if lc.Main != nil {
+ lc.Main.Walk(callback)
+ }
+ for _, and := range lc.And {
+ and.Walk(callback)
+ }
+ for _, or := range lc.Or {
+ or.Walk(callback)
+ }
+}
+
+type licenseLexer struct {
+ repl *PrefixReplacer
+ result *LicenseCondition
+ error string
}
-func checktoplevelUnusedLicenses() {
+func (lexer *licenseLexer) Lex(llval *liyySymType) int {
+ repl := lexer.repl
+ repl.AdvanceHspace()
+ switch {
+ case repl.rest == "":
+ return 0
+ case repl.AdvanceStr("("):
+ return ltOPEN
+ case repl.AdvanceStr(")"):
+ return ltCLOSE
+ case repl.AdvanceRegexp(`^[\w-.]+`):
+ word := repl.m[0]
+ switch word {
+ case "AND":
+ return ltAND
+ case "OR":
+ return ltOR
+ default:
+ llval.Node = &LicenseCondition{Name: word}
+ return ltNAME
+ }
+ }
+ return -1
+}
+
+func (lexer *licenseLexer) Error(s string) {
+ lexer.error = s
+}
+
+func parseLicenses(licenses string) *LicenseCondition {
+ expanded := resolveVariableRefs(licenses) // For ${PERL5_LICENSE}
+ lexer := &licenseLexer{repl: NewPrefixReplacer(expanded)}
+ result := liyyNewParser().Parse(lexer)
+ if result == 0 {
+ return lexer.result
+ }
+ return nil
+}
+
+func checkToplevelUnusedLicenses() {
if G.UsedLicenses == nil {
return
}
@@ -29,38 +91,68 @@
}
}
-func checklineLicense(line *MkLine, value string) {
- licenses := parseLicenses(value)
- for _, license := range licenses {
- var licenseFile string
- if G.Pkg != nil {
- if licenseFileValue, ok := G.Pkg.varValue("LICENSE_FILE"); ok {
- licenseFile = G.CurrentDir + "/" + resolveVarsInRelativePath(licenseFileValue, false)
- }
- }
- if licenseFile == "" {
- licenseFile = G.globalData.Pkgsrcdir + "/licenses/" + license
- if G.UsedLicenses != nil {
- G.UsedLicenses[license] = true
- }
- }
+type LicenseChecker struct {
+ MkLine *MkLine
+}
+
+func (lc *LicenseChecker) Check(value string, op MkOperator) {
+ licenses := parseLicenses(ifelseStr(op == opAssignAppend, "append-placeholder ", "") + value)
- if !fileExists(licenseFile) {
- line.Warn1("License file %s does not exist.", cleanpath(licenseFile))
+ if licenses == nil {
+ if op == opAssign {
+ lc.MkLine.Line.Error1("Parse error for license condition %q.", value)
+ } else {
+ lc.MkLine.Line.Error1("Parse error for appended license condition %q.", value)
}
+ return
+ }
- switch license {
- case "fee-based-commercial-use",
- "no-commercial-use",
- "no-profit",
- "no-redistribution",
- "shareware":
- line.Warn1("License %q is deprecated.", license)
- Explain(
- "Instead of using these deprecated licenses, extract the actual",
- "license from the package into the pkgsrc/licenses/ directory",
- "and define LICENSE to that file name. See the pkgsrc guide,",
- "keyword LICENSE, for more information.")
+ licenses.Walk(lc.checkNode)
+}
+
+func (lc *LicenseChecker) checkNode(cond *LicenseCondition) {
+ license := cond.Name
+ if license == "" || license == "append-placeholder" {
+ return
+ }
+
+ var licenseFile string
+ if G.Pkg != nil {
+ if licenseFileValue, ok := G.Pkg.varValue("LICENSE_FILE"); ok {
+ licenseFile = G.CurrentDir + "/" + resolveVarsInRelativePath(licenseFileValue, false)
}
}
+ if licenseFile == "" {
+ licenseFile = G.globalData.Pkgsrcdir + "/licenses/" + license
+ if G.UsedLicenses != nil {
+ G.UsedLicenses[license] = true
+ }
+ }
+
+ if !fileExists(licenseFile) {
+ lc.MkLine.Warn1("License file %s does not exist.", cleanpath(licenseFile))
+ }
+
+ switch license {
+ case "fee-based-commercial-use",
+ "no-commercial-use",
+ "no-profit",
+ "no-redistribution",
+ "shareware":
+ lc.MkLine.Error1("License %q must not be used.", license)
+ Explain(
+ "Instead of using these deprecated licenses, extract the actual",
+ "license from the package into the pkgsrc/licenses/ directory",
+ "and define LICENSE to that file name. See the pkgsrc guide,",
+ "keyword LICENSE, for more information.")
+ }
+
+ if len(cond.And) > 0 && len(cond.Or) > 0 {
+ lc.MkLine.Line.Error0("AND and OR operators in license conditions can only be combined using parentheses.")
+ Explain(
+ "Examples for valid license conditions are:",
+ "",
+ "\tlicense1 AND license2 AND (license3 OR license4)",
+ "\t(((license1 OR license2) AND (license3 OR license4)))")
+ }
}
diff -r e38ef21c14fe -r 19201637f9e7 pkgtools/pkglint/files/licenses_test.go
--- a/pkgtools/pkglint/files/licenses_test.go Sun Jul 10 21:12:19 2016 +0000
+++ b/pkgtools/pkglint/files/licenses_test.go Sun Jul 10 21:24:47 2016 +0000
@@ -5,8 +5,8 @@
)
func (s *Suite) Test_parseLicenses(c *check.C) {
- c.Check(parseLicenses("gnu-gpl-v2"), check.DeepEquals, []string{"gnu-gpl-v2"})
- c.Check(parseLicenses("AND artistic"), check.DeepEquals, []string{"artistic"})
+ c.Check(parseLicenses("gnu-gpl-v2"), check.DeepEquals, &LicenseCondition{Name: "gnu-gpl-v2"})
+ c.Check(parseLicenses("AND artistic"), check.IsNil)
}
func (s *Suite) Test_checklineLicense(c *check.C) {
@@ -15,19 +15,32 @@
G.globalData.Pkgsrcdir = s.tmpdir
G.CurrentDir = s.tmpdir
- checklineLicense(mkline, "gpl-v2")
+ licenseChecker := &LicenseChecker{mkline}
+ licenseChecker.Check("gpl-v2", opAssign)
c.Check(s.Output(), equals, "WARN: Makefile:7: License file ~/licenses/gpl-v2 does not exist.\n")
- checklineLicense(mkline, "no-profit shareware")
+ licenseChecker.Check("no-profit shareware", opAssign)
+
+ c.Check(s.Output(), equals, "ERROR: Makefile:7: Parse error for license condition \"no-profit shareware\".\n")
+
+ licenseChecker.Check("no-profit AND shareware", opAssign)
c.Check(s.Output(), equals, ""+
"WARN: Makefile:7: License file ~/licenses/no-profit does not exist.\n"+
- "WARN: Makefile:7: License \"no-profit\" is deprecated.\n"+
+ "ERROR: Makefile:7: License \"no-profit\" must not be used.\n"+
"WARN: Makefile:7: License file ~/licenses/shareware does not exist.\n"+
- "WARN: Makefile:7: License \"shareware\" is deprecated.\n")
Home |
Main Index |
Thread Index |
Old Index