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