pkgsrc-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: pkgsrc/pkgtools/pkglint



Module Name:    pkgsrc
Committed By:   rillig
Date:           Thu Apr 30 21:15:04 UTC 2020

Modified Files:
        pkgsrc/pkgtools/pkglint: Makefile
        pkgsrc/pkgtools/pkglint/files: homepage_test.go mkassignchecker_test.go
            mklinechecker.go mklinechecker_test.go mktypes.go mktypes_test.go
            mkvarusechecker_test.go package.go package_test.go patches.go
            patches_test.go pkglint.go plist.go util.go vardefs.go
            vartypecheck.go
        pkgsrc/pkgtools/pkglint/files/pkgver: vercmp.go
        pkgsrc/pkgtools/pkglint/files/regex: regex.go

Log Message:
pkgtools/pkglint: update to 20.1.3

Changes since 20.1.2:

Stricter check for Python version numbers. Before, 25 and 26 had not
been marked as wrong.

In assignments like PKGNAME=${DISTNAME:S,from,to,}, modifiers that don't
have any effect generate a note. Most of these modifiers are redundant
or outdated.

Patches must not add well-known absolute paths like /usr/pkg, /var and
/etc since these must be overridable by the pkgsrc user. Other absolute
paths continue to be allowed.


To generate a diff of this commit:
cvs rdiff -u -r1.641 -r1.642 pkgsrc/pkgtools/pkglint/Makefile
cvs rdiff -u -r1.4 -r1.5 pkgsrc/pkgtools/pkglint/files/homepage_test.go
cvs rdiff -u -r1.5 -r1.6 \
    pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go
cvs rdiff -u -r1.65 -r1.66 pkgsrc/pkgtools/pkglint/files/mklinechecker.go
cvs rdiff -u -r1.59 -r1.60 \
    pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go
cvs rdiff -u -r1.24 -r1.25 pkgsrc/pkgtools/pkglint/files/mktypes.go
cvs rdiff -u -r1.22 -r1.23 pkgsrc/pkgtools/pkglint/files/mktypes_test.go
cvs rdiff -u -r1.9 -r1.10 \
    pkgsrc/pkgtools/pkglint/files/mkvarusechecker_test.go
cvs rdiff -u -r1.87 -r1.88 pkgsrc/pkgtools/pkglint/files/package.go
cvs rdiff -u -r1.74 -r1.75 pkgsrc/pkgtools/pkglint/files/package_test.go
cvs rdiff -u -r1.38 -r1.39 pkgsrc/pkgtools/pkglint/files/patches.go
cvs rdiff -u -r1.37 -r1.38 pkgsrc/pkgtools/pkglint/files/patches_test.go
cvs rdiff -u -r1.79 -r1.80 pkgsrc/pkgtools/pkglint/files/pkglint.go
cvs rdiff -u -r1.56 -r1.57 pkgsrc/pkgtools/pkglint/files/plist.go
cvs rdiff -u -r1.76 -r1.77 pkgsrc/pkgtools/pkglint/files/util.go
cvs rdiff -u -r1.93 -r1.94 pkgsrc/pkgtools/pkglint/files/vardefs.go
cvs rdiff -u -r1.84 -r1.85 pkgsrc/pkgtools/pkglint/files/vartypecheck.go
cvs rdiff -u -r1.5 -r1.6 pkgsrc/pkgtools/pkglint/files/pkgver/vercmp.go
cvs rdiff -u -r1.6 -r1.7 pkgsrc/pkgtools/pkglint/files/regex/regex.go

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/pkgtools/pkglint/Makefile
diff -u pkgsrc/pkgtools/pkglint/Makefile:1.641 pkgsrc/pkgtools/pkglint/Makefile:1.642
--- pkgsrc/pkgtools/pkglint/Makefile:1.641      Mon Apr 13 19:46:44 2020
+++ pkgsrc/pkgtools/pkglint/Makefile    Thu Apr 30 21:15:03 2020
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.641 2020/04/13 19:46:44 rillig Exp $
+# $NetBSD: Makefile,v 1.642 2020/04/30 21:15:03 rillig Exp $
 
-PKGNAME=       pkglint-20.1.2
+PKGNAME=       pkglint-20.1.3
 CATEGORIES=    pkgtools
 DISTNAME=      tools
 MASTER_SITES=  ${MASTER_SITE_GITHUB:=golang/}

Index: pkgsrc/pkgtools/pkglint/files/homepage_test.go
diff -u pkgsrc/pkgtools/pkglint/files/homepage_test.go:1.4 pkgsrc/pkgtools/pkglint/files/homepage_test.go:1.5
--- pkgsrc/pkgtools/pkglint/files/homepage_test.go:1.4  Sat Mar  7 23:35:35 2020
+++ pkgsrc/pkgtools/pkglint/files/homepage_test.go      Thu Apr 30 21:15:03 2020
@@ -393,7 +393,8 @@ func (s *Suite) Test_HomepageChecker_che
                "https://no-such-name.example.org/";,
                // The "unknown network error" is for compatibility with Go < 1.13.
                `^WARN: filename\.mk:1: Homepage "https://no-such-name.example.org/"; `+
-                       `cannot be checked: (name not found|timeout|unknown network error:.*)$`)
+                       `cannot be checked: `+
+                       `(name not found|timeout|connection refused|unknown network error:.*)$`)
 
        // Syntactically invalid URLs are silently skipped since VartypeCheck.URL
        // already warns about them.

Index: pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go:1.5 pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go:1.6
--- pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go:1.5   Wed Mar 18 08:24:49 2020
+++ pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go       Thu Apr 30 21:15:03 2020
@@ -995,23 +995,25 @@ func (s *Suite) Test_MkAssignChecker_che
 
        mklines.Check()
 
-       // Half of these warnings are from VartypeCheck.Version, the
-       // other half are from checkVarassignDecreasingVersions.
-       // Strictly speaking some of them are redundant, but that would
-       // mean to reject only variable references in checkVarassignDecreasingVersions.
-       // This is probably ok.
-       // TODO: Fix this.
+       // Half of these warnings are from VartypeCheck.Enum,
+       // the other half are from checkVarassignDecreasingVersions.
+       // Strictly speaking some of them are redundant, but that's ok.
+       // They all need to be fixed in the end.
        t.CheckOutputLines(
-               "WARN: Makefile:2: Invalid version number \"__future__\".",
+               "WARN: Makefile:2: \"__future__\" is not valid for PYTHON_VERSIONS_ACCEPTED. "+
+                       "Use one of { 27 36 37 38 } instead.",
                "ERROR: Makefile:2: Value \"__future__\" for "+
                        "PYTHON_VERSIONS_ACCEPTED must be a positive integer.",
-               "WARN: Makefile:3: Invalid version number \"-13\".",
+               "WARN: Makefile:3: \"-13\" is not valid for PYTHON_VERSIONS_ACCEPTED. "+
+                       "Use one of { 27 36 37 38 } instead.",
                "ERROR: Makefile:3: Value \"-13\" for "+
                        "PYTHON_VERSIONS_ACCEPTED must be a positive integer.",
                "ERROR: Makefile:4: Value \"${PKGVERSION_NOREV}\" for "+
                        "PYTHON_VERSIONS_ACCEPTED must be a positive integer.",
                "WARN: Makefile:5: The values for PYTHON_VERSIONS_ACCEPTED "+
-                       "should be in decreasing order (37 before 36).")
+                       "should be in decreasing order (37 before 36).",
+               "WARN: Makefile:6: \"25\" is not valid for PYTHON_VERSIONS_ACCEPTED. "+
+                       "Use one of { 27 36 37 38 } instead.")
 }
 
 func (s *Suite) Test_MkAssignChecker_checkVarassignMiscRedundantInstallationDirs__AUTO_MKDIRS_yes(c *check.C) {

Index: pkgsrc/pkgtools/pkglint/files/mklinechecker.go
diff -u pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.65 pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.66
--- pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.65 Mon Apr 13 19:46:44 2020
+++ pkgsrc/pkgtools/pkglint/files/mklinechecker.go      Thu Apr 30 21:15:03 2020
@@ -98,7 +98,7 @@ func (ck MkLineChecker) checkTextWrksrcD
                        "",
                        "Example:",
                        "",
-                       "\tWRKSRC=\t${WRKDIR}",
+                       "\tWRKSRC=\t\t${WRKDIR}",
                        "\tCONFIGURE_DIRS=\t${WRKSRC}/lib ${WRKSRC}/src",
                        "\tBUILD_DIRS=\t${WRKSRC}/lib ${WRKSRC}/src ${WRKSRC}/cmd",
                        "",

Index: pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.59 pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.60
--- pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.59    Sun Jan 26 17:12:36 2020
+++ pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go Thu Apr 30 21:15:03 2020
@@ -161,7 +161,7 @@ func (s *Suite) Test_MkLineChecker_check
                "",
                "\tExample:",
                "",
-               "\t\tWRKSRC=\t${WRKDIR}",
+               "\t\tWRKSRC=\t\t${WRKDIR}",
                "\t\tCONFIGURE_DIRS=\t${WRKSRC}/lib ${WRKSRC}/src",
                "\t\tBUILD_DIRS=\t${WRKSRC}/lib ${WRKSRC}/src ${WRKSRC}/cmd",
                "",

Index: pkgsrc/pkgtools/pkglint/files/mktypes.go
diff -u pkgsrc/pkgtools/pkglint/files/mktypes.go:1.24 pkgsrc/pkgtools/pkglint/files/mktypes.go:1.25
--- pkgsrc/pkgtools/pkglint/files/mktypes.go:1.24       Mon Dec 16 17:06:05 2019
+++ pkgsrc/pkgtools/pkglint/files/mktypes.go    Thu Apr 30 21:15:03 2020
@@ -40,7 +40,7 @@ func NewMkVarUse(varname string, modifie
 func (vu *MkVarUse) String() string { return sprintf("${%s%s}", vu.varname, vu.Mod()) }
 
 type MkVarUseModifier struct {
-       Text string
+       Text string // The text of the modifier, without the initial colon.
 }
 
 func (m MkVarUseModifier) IsQ() bool { return m.Text == "Q" }
@@ -59,13 +59,13 @@ func (m MkVarUseModifier) MatchSubst() (
 //
 // Example:
 //  MkVarUseModifier{"S,name,file,g"}.Subst("distname-1.0") => "distfile-1.0"
-func (m MkVarUseModifier) Subst(str string) (string, bool) {
+func (m MkVarUseModifier) Subst(str string) (bool, string) {
        // XXX: The call to MatchSubst is usually redundant because MatchSubst
        //  is typically called directly before calling Subst.
        //  This comes from a time when there was no boolean return value.
        ok, isRegex, from, to, options := m.MatchSubst()
        if !ok {
-               return "", false
+               return false, ""
        }
 
        leftAnchor := hasPrefix(from, "^")
@@ -86,14 +86,14 @@ func (m MkVarUseModifier) Subst(str stri
 
        if isRegex {
                // XXX: Maybe implement regular expression substitutions later.
-               return "", false
+               return false, ""
        }
 
        ok, result := m.EvalSubst(str, leftAnchor, from, rightAnchor, to, options)
        if trace.Tracing && ok && result != str {
                trace.Stepf("Subst: %q %q => %q", str, m.Text, result)
        }
-       return result, ok
+       return ok, result
 }
 
 // mkopSubst evaluates make(1)'s :S substitution operator.

Index: pkgsrc/pkgtools/pkglint/files/mktypes_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mktypes_test.go:1.22 pkgsrc/pkgtools/pkglint/files/mktypes_test.go:1.23
--- pkgsrc/pkgtools/pkglint/files/mktypes_test.go:1.22  Mon Dec 16 17:06:05 2019
+++ pkgsrc/pkgtools/pkglint/files/mktypes_test.go       Thu Apr 30 21:15:03 2020
@@ -90,60 +90,60 @@ func (s *Suite) Test_MkVarUseModifier_Ma
 func (s *Suite) Test_MkVarUseModifier_Subst(c *check.C) {
        t := s.Init(c)
 
-       test := func(mod, str, result string, ok bool) {
+       test := func(mod, str string, ok bool, result string) {
                m := MkVarUseModifier{mod}
 
-               actualResult, actualOk := m.Subst(str)
+               actualOk, actualResult := m.Subst(str)
 
                t.CheckDeepEquals(
-                       []interface{}{actualResult, actualOk},
-                       []interface{}{result, ok})
+                       []interface{}{actualOk, actualResult},
+                       []interface{}{ok, result})
        }
 
-       test("???", "anything", "", false)
+       test("???", "anything", false, "")
 
-       test("S,from,to,", "from", "to", true)
+       test("S,from,to,", "from", true, "to")
 
-       test("C,from,to,", "from", "to", true)
+       test("C,from,to,", "from", true, "to")
 
-       test("C,syntax error", "anything", "", false)
+       test("C,syntax error", "anything", false, "")
 
        // The substitution modifier does not match, therefore
        // the value is returned unmodified, but successful.
-       test("C,no_match,replacement,", "value", "value", true)
+       test("C,no_match,replacement,", "value", true, "value")
 
        // As of December 2019, pkglint doesn't know how to handle
        // complicated :C modifiers.
-       test("C,.*,,", "anything", "", false)
+       test("C,.*,,", "anything", false, "")
 
        // When given a modifier that is not actually a :S or :C, Subst
        // doesn't do anything.
-       test("Mpattern", "anything", "", false)
+       test("Mpattern", "anything", false, "")
 
-       test("S,from,to,", "from a to b", "to a to b", true)
+       test("S,from,to,", "from a to b", true, "to a to b")
 
        // Since the replacement text is not a simple string, the :C modifier
        // cannot be treated like the :S modifier. The variable could contain
        // one of the special characters that would need to be escaped in the
        // replacement text.
-       test("C,from,${VAR},", "from a to b", "", false)
+       test("C,from,${VAR},", "from a to b", false, "")
 
        // As of December 2019, nothing is substituted. If pkglint should ever
        // handle variables in the modifier, this test would need to provide a
        // context in which to resolve the variables. If that happens, the
        // .TARGET variable needs to be set to "target".
-       test("S/$@/replaced/", "The target", "The target", true)
-       test("S,${PREFIX},/prefix,", "${PREFIX}/dir", "", false)
+       test("S/$@/replaced/", "The target", true, "The target")
+       test("S,${PREFIX},/prefix,", "${PREFIX}/dir", false, "")
 
        // Just for code coverage.
        t.DisableTracing()
-       test("S,long,long long,g", "A long story", "A long long story", true)
+       test("S,long,long long,g", "A long story", true, "A long long story")
        t.EnableTracing()
 
        // And now again with full tracing, to investigate cases where
        // pkglint produces results that are not easily understandable.
        t.EnableTracingToLog()
-       test("S,long,long long,g", "A long story", "A long long story", true)
+       test("S,long,long long,g", "A long story", true, "A long long story")
        t.EnableTracing()
        t.CheckOutputLines(
                "TRACE:   Subst: \"A long story\" " +

Index: pkgsrc/pkgtools/pkglint/files/mkvarusechecker_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mkvarusechecker_test.go:1.9 pkgsrc/pkgtools/pkglint/files/mkvarusechecker_test.go:1.10
--- pkgsrc/pkgtools/pkglint/files/mkvarusechecker_test.go:1.9   Wed Mar 18 08:24:49 2020
+++ pkgsrc/pkgtools/pkglint/files/mkvarusechecker_test.go       Thu Apr 30 21:15:03 2020
@@ -592,13 +592,13 @@ func (s *Suite) Test_MkVarUseChecker_che
        t.SetUpVartypes()
        mklines := t.NewMkLines("file.mk",
                MkCvsID,
-               "IGNORE_PKG.package=\t${ONLY_FOR_UNPRIVILEGED}")
+               "IGNORE_PKG.package=\t${NOT_FOR_UNPRIVILEGED}")
 
        mklines.Check()
 
        t.CheckOutputLines(
                "WARN: file.mk:2: IGNORE_PKG.package should be set to YES or yes.",
-               "WARN: file.mk:2: ONLY_FOR_UNPRIVILEGED should not be used indirectly at load time (via IGNORE_PKG.package).")
+               "WARN: file.mk:2: NOT_FOR_UNPRIVILEGED should not be used indirectly at load time (via IGNORE_PKG.package).")
 }
 
 // This test is only here for branch coverage.

Index: pkgsrc/pkgtools/pkglint/files/package.go
diff -u pkgsrc/pkgtools/pkglint/files/package.go:1.87 pkgsrc/pkgtools/pkglint/files/package.go:1.88
--- pkgsrc/pkgtools/pkglint/files/package.go:1.87       Mon Apr 13 19:46:44 2020
+++ pkgsrc/pkgtools/pkglint/files/package.go    Thu Apr 30 21:15:03 2020
@@ -275,7 +275,6 @@ func (pkg *Package) loadPackageMakefile(
        return mainLines, allLines
 }
 
-// TODO: What is allLines used for, is it still necessary? Would it be better as a field in Package?
 func (pkg *Package) parse(mklines *MkLines, allLines *MkLines, includingFileForUsedCheck CurrPath, main bool) bool {
        if trace.Tracing {
                defer trace.Call(mklines.lines.Filename)()
@@ -891,7 +890,6 @@ func (pkg *Package) CheckVarorder(mkline
                {"NOT_FOR_COMPILER", many},
                {"ONLY_FOR_COMPILER", many},
                {"NOT_FOR_UNPRIVILEGED", optional},
-               {"ONLY_FOR_UNPRIVILEGED", optional},
                emptyLine,
                {"BUILD_DEPENDS", many},
                {"TOOL_DEPENDS", many},
@@ -1147,7 +1145,7 @@ func (pkg *Package) determineEffectivePk
 
        effname := pkgname
        if distname != "" && effname != "" {
-               merged, ok := pkg.pkgnameFromDistname(effname, distname)
+               merged, ok := pkg.pkgnameFromDistname(effname, distname, pkgnameLine)
                if ok {
                        effname = merged
                }
@@ -1209,7 +1207,7 @@ func (pkg *Package) nbPart() string {
        return ""
 }
 
-func (pkg *Package) pkgnameFromDistname(pkgname, distname string) (string, bool) {
+func (pkg *Package) pkgnameFromDistname(pkgname, distname string, diag Diagnoser) (string, bool) {
        tokens, rest := NewMkLexer(pkgname, nil).MkTokens()
        if rest != "" {
                return "", false
@@ -1228,7 +1226,10 @@ func (pkg *Package) pkgnameFromDistname(
                        for _, mod := range token.Varuse.modifiers {
                                if mod.IsToLower() {
                                        newDistname = strings.ToLower(newDistname)
-                               } else if subst, ok := mod.Subst(newDistname); ok {
+                               } else if ok, subst := mod.Subst(newDistname); ok {
+                                       if subst == newDistname && !containsVarUse(subst) {
+                                               diag.Notef("The modifier :%s does not have an effect.", mod.Text)
+                                       }
                                        newDistname = subst
                                } else {
                                        return "", false

Index: pkgsrc/pkgtools/pkglint/files/package_test.go
diff -u pkgsrc/pkgtools/pkglint/files/package_test.go:1.74 pkgsrc/pkgtools/pkglint/files/package_test.go:1.75
--- pkgsrc/pkgtools/pkglint/files/package_test.go:1.74  Mon Apr 13 19:46:44 2020
+++ pkgsrc/pkgtools/pkglint/files/package_test.go       Thu Apr 30 21:15:03 2020
@@ -2609,6 +2609,43 @@ func (s *Suite) Test_Package_determineEf
        pkg.check(files, mklines, allLines)
 
        t.CheckEquals(pkg.EffectivePkgname, "distname-1.0")
+       t.CheckOutputLines(
+               "NOTE: ~/category/package/Makefile:4: " +
+                       "The modifier :C:does_not_match:replacement: does not have an effect.")
+}
+
+func (s *Suite) Test_Package_determineEffectivePkgVars__ineffective_S_modifier_with_variable(c *check.C) {
+       t := s.Init(c)
+
+       t.SetUpPackage("category/package",
+               "VERSION=\t1.008",
+               "DISTNAME=\tdistname-v${VERSION}",
+               "PKGNAME=\t${DISTNAME:S/v1/1/}")
+       t.FinishSetUp()
+       pkg := NewPackage(t.File("category/package"))
+       files, mklines, allLines := pkg.load()
+
+       pkg.check(files, mklines, allLines)
+
+       // TODO: Expand ${VERSION}, that's pretty simple.
+       t.CheckEquals(pkg.EffectivePkgname, "") // Because of the unexpanded VERSION.
+       t.CheckOutputEmpty()
+}
+
+func (s *Suite) Test_Package_determineEffectivePkgVars__effective_S_modifier_with_variable(c *check.C) {
+       t := s.Init(c)
+
+       t.SetUpPackage("category/package",
+               "MINOR_VERSION=\t1.008",
+               "DISTNAME=\tdistname-v1.${MINOR_VERSION}",
+               "PKGNAME=\t${DISTNAME:S/v1/1/}")
+       t.FinishSetUp()
+       pkg := NewPackage(t.File("category/package"))
+       files, mklines, allLines := pkg.load()
+
+       pkg.check(files, mklines, allLines)
+
+       t.CheckEquals(pkg.EffectivePkgname, "") // because of MINOR_VERSION
        t.CheckOutputEmpty()
 }
 
@@ -2724,9 +2761,11 @@ func (s *Suite) Test_Package_pkgnameFrom
        // the package version. Therefore it is discarded completely.
        test("${DISTNAME:S|^lib||}", "libncurses", "")
 
-       // The substitution succeeds, but the substituted value is missing
-       // the package version. Therefore it is discarded completely.
-       test("${DISTNAME:S|^lib||}", "mylib", "")
+       // The substitution does not have an effect.
+       // The substituted value is missing the package version.
+       // Therefore it is discarded completely.
+       test("${DISTNAME:S|^lib||}", "mylib", "",
+               "NOTE: ~/category/package/Makefile:4: The modifier :S|^lib|| does not have an effect.")
 
        test("${DISTNAME:tl:S/-/./g:S/he/-/1}", "SaxonHE9-5-0-1J", "saxon-9.5.0.1j")
 

Index: pkgsrc/pkgtools/pkglint/files/patches.go
diff -u pkgsrc/pkgtools/pkglint/files/patches.go:1.38 pkgsrc/pkgtools/pkglint/files/patches.go:1.39
--- pkgsrc/pkgtools/pkglint/files/patches.go:1.38       Sun Mar 22 17:43:15 2020
+++ pkgsrc/pkgtools/pkglint/files/patches.go    Thu Apr 30 21:15:03 2020
@@ -224,15 +224,90 @@ func (ck *PatchChecker) checkConfigure(a
 }
 
 func (ck *PatchChecker) checkAddedLine(addedText string) {
-       if !matches(addedText, `/usr/pkg\b`) {
-               return
+       dirs := regcomp(`(?:^|[^.@)}])(/usr/pkg|/var|/etc)([^\w-]|$)`)
+       for _, m := range dirs.FindAllStringSubmatchIndex(addedText, -1) {
+               before := addedText[:m[2]]
+               dir := NewPath(addedText[m[2]:m[3]])
+               ck.checkAddedAbsPath(before, dir, addedText[m[4]:])
        }
+}
 
+func (ck *PatchChecker) checkAddedAbsPath(before string, dir Path, after string) {
        line := ck.llex.PreviousLine()
-       line.Errorf("Patches must not hard-code the pkgsrc PREFIX.")
-       line.Explain(
-               "Instead of hard-coding /usr/pkg, packages should use the PREFIX variable.",
-               "The usual way of doing this is to use the SUBST framework in mk/subst.mk.")
+
+       // Remove the #define from C and C++ macros.
+       before = replaceAll(before, `^[ \t]*#[ \t]*define[ \t]*\w+[ \t]*(.+)[ \t]*$`, "$1")
+
+       // Remove the "set(VAR" from CMakeLists.txt.
+       before = replaceAll(before, `^[ \t]*set\(\w+[ \t]*`, "")
+
+       // Ignore comments in shell programs.
+       if m, first := match1(before, `^[ \t]*#[ \t]*(\w*)`); m && first != "define" {
+               return
+       }
+
+       // Ignore paths inside C-style comments.
+       if contains(before, "/*") && contains(after, "*/") {
+               return
+       }
+
+       // Ignore composed C string literals such as PREFIX "/etc".
+       if matches(before, `\w+[ \t]*"$`) {
+               return
+       }
+
+       // Ignore shell literals such as $PREFIX/etc.
+       // But keep compiler options like -I/usr/pkg even though they look
+       // like a relative pathname.
+       if matches(before, `\w$`) && !matches(before, `(^|[ \t])-(I|L|R|rpath|Wl,-R)$`) {
+               return
+       }
+
+       switch dir {
+       case "/usr/pkg":
+
+               line.Errorf("Patches must not hard-code the pkgsrc PREFIX.")
+               line.Explain(
+                       "Not every pkgsrc installation uses /usr/pkg as its PREFIX.",
+                       "To keep the PREFIX configurable, the patch files should contain",
+                       "the placeholder @PREFIX@ instead.",
+                       "",
+                       "In the pre-configure stage, this placeholder should then be",
+                       "replaced with the actual configuration directory",
+                       "using a SUBST block containing SUBST_VARS.dirs=PREFIX.",
+                       "See mk/subst.mk for details.")
+
+       case "/var":
+               afterPath := NewPath(after)
+               if afterPath.HasPrefixPath("/tmp") || afterPath.HasPrefixPath("/shm") {
+                       break
+               }
+
+               line.Errorf("Patches must not hard-code the pkgsrc VARBASE.")
+               line.Explain(
+                       "Not every pkgsrc installation uses /var as its directory",
+                       "for writable files.",
+                       "To keep the VARBASE configurable, the patch files should",
+                       "contain the placeholder @VARBASE@ instead.",
+                       "",
+                       "In the pre-configure stage, this placeholder should then be",
+                       "replaced with the actual configuration directory",
+                       "using a SUBST block containing SUBST_VARS.dirs=VARBASE.",
+                       "See mk/subst.mk for details.")
+
+       default:
+               line.Errorf("Patches must not hard-code the pkgsrc PKG_SYSCONFDIR.")
+               line.Explain(
+                       "Not every pkgsrc installation uses /etc as its directory",
+                       "for configuration files.",
+                       "To keep the PKG_SYSCONFDIR configurable, the patch files should",
+                       "contain the placeholder @PKG_SYSCONFDIR@ instead.",
+                       "",
+                       "In the pre-configure stage, this placeholder should then be",
+                       "replaced with the actual configuration directory",
+                       "using a SUBST block containing SUBST_VARS.dirs=PKG_SYSCONFDIR.",
+                       "See mk/subst.mk for details.")
+       }
 }
 
 func (ck *PatchChecker) checktextUniHunkCr() {

Index: pkgsrc/pkgtools/pkglint/files/patches_test.go
diff -u pkgsrc/pkgtools/pkglint/files/patches_test.go:1.37 pkgsrc/pkgtools/pkglint/files/patches_test.go:1.38
--- pkgsrc/pkgtools/pkglint/files/patches_test.go:1.37  Sun Mar 22 17:43:15 2020
+++ pkgsrc/pkgtools/pkglint/files/patches_test.go       Thu Apr 30 21:15:03 2020
@@ -754,6 +754,168 @@ func (s *Suite) Test_PatchChecker_checkC
                "ERROR: ~/patch-aa:9: This code must not be included in patches.")
 }
 
+func (s *Suite) Test_PatchChecker_checkAddedAbsPath(c *check.C) {
+       t := s.Init(c)
+
+       test := func(addedLine string, diagnostics ...string) {
+               lines := t.NewLines("patch-file",
+                       CvsID,
+                       "",
+                       "Demonstrates absolute paths.",
+                       "",
+                       "--- before",
+                       "+++ after",
+                       "@@ -1,0 +1,1 @@",
+                       "+"+addedLine)
+
+               CheckLinesPatch(lines, nil)
+
+               t.CheckOutput(diagnostics)
+       }
+
+       test(
+               "/usr/pkg",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PREFIX.")
+
+       test(
+               "/usr/pkgsrc",
+               nil...)
+
+       test(
+               "/usr/pkg/bin",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PREFIX.")
+
+       test(
+               "/usr/local:/usr/pkg:/opt",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PREFIX.")
+
+       test(
+               "/var",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc VARBASE.")
+
+       test(
+               "/var/db",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc VARBASE.")
+
+       test(
+               "/var/run",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc VARBASE.")
+
+       // A well-known path that is not specific to pkgsrc.
+       test(
+               "/var/shm",
+               nil...)
+
+       // A well-known path that is not specific to pkgsrc.
+       test(
+               "/var/tmp",
+               nil...)
+
+       test(
+               "/etc",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PKG_SYSCONFDIR.")
+
+       // BSD-style Makefile
+       test(
+               "${PREFIX}/etc",
+               nil...)
+
+       // GNU automake-style Makefile
+       test(
+               "$(prefix)/etc",
+               nil...)
+
+       // C source code.
+       // Instead of PREFIX/etc, this should rather be PKG_SYSCONFDIR.
+       // This is a relative path because of the PREFIX.
+       test(
+               "const char *conf_dir = PREFIX \"/etc\"",
+               nil...)
+
+       // CMakeLists.txt
+       test(
+               "set(ETC_DIR \"/etc\")",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PKG_SYSCONFDIR.")
+
+       test(
+               "/etc/mk.conf",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PKG_SYSCONFDIR.")
+
+       test(
+               "/etc/rc.d/daemon",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PKG_SYSCONFDIR.")
+
+       test(
+               "/usr/pkg and /var and /etc",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PREFIX.",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc VARBASE.",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PKG_SYSCONFDIR.")
+
+       // From the --help text of a GNU configure script.
+       test(
+               "[PREFIX/etc]",
+               nil...)
+
+       // Shell program, default value for a variable.
+       test(
+               "DIR=${DIR-/var/bytebench}",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc VARBASE.")
+
+       // Shell program or Makefile.
+       // The placeholder will make this a relative path.
+       test(
+               "dir=@prefix@/etc",
+               nil...)
+
+       // Makefile with flags for the C compiler.
+       test(
+               "CFLAGS+= -I/usr/pkg/include",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PREFIX.")
+
+       // Makefile with flags for the linker.
+       test(
+               "LDFLAGS+= -L/usr/pkg/lib",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PREFIX.")
+
+       // Makefile with flags for the linker.
+       // There should be an additional warning for using COMPILER_RPATH_FLAG.
+       test(
+               "LDFLAGS+= -rpath/usr/pkg/lib",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PREFIX.")
+
+       // Makefile with flags for the linker.
+       // There should be an additional warning for using COMPILER_RPATH_FLAG.
+       test(
+               "LDFLAGS+= -Wl,-R/usr/pkg/lib",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc PREFIX.")
+
+       // The dot before the "/etc" makes it a relative pathname.
+       test(
+               "cp ./etc/hostname /tmp")
+
+       // +>   +#      from /etc/inittab (SYSV systems)
+       // +ERROR: devel/tet3/patches/patch-ac:51: Patches must not hard-code the pkgsrc PKG_SYSCONFDIR.
+
+       test(
+               "# SysV /etc/install, /usr/sbin/install")
+
+       // C or C++ program, macro definition.
+       // This is an absolute path since the PID_FILE is the macro name,
+       // and not part of the macro body containing the path.
+       test(
+               "#define PID_FILE \"/var/run/daemon.pid\"",
+               "ERROR: patch-file:8: Patches must not hard-code the pkgsrc VARBASE.")
+
+       // This is a relative path because of the PREFIX before it.
+       test(
+               "#define PID_FILE PREFIX \"/etc/conf\"",
+               nil...)
+
+       test(
+               "#define L 150 /* Length of a line in /etc/passwd */",
+               nil...)
+}
+
 func (s *Suite) Test_PatchChecker_checktextCvsID(c *check.C) {
        t := s.Init(c)
 

Index: pkgsrc/pkgtools/pkglint/files/pkglint.go
diff -u pkgsrc/pkgtools/pkglint/files/pkglint.go:1.79 pkgsrc/pkgtools/pkglint/files/pkglint.go:1.80
--- pkgsrc/pkgtools/pkglint/files/pkglint.go:1.79       Thu Mar 26 07:02:44 2020
+++ pkgsrc/pkgtools/pkglint/files/pkglint.go    Thu Apr 30 21:15:03 2020
@@ -823,6 +823,12 @@ func (ip *InterPackage) Enable() {
                make(map[string]*Hash),
                make(map[string]struct{}),
                make(map[string]Location)}
+
+       // This is the only license that is added by an infrastructure file,
+       // mk/djbware.mk. The correct way to handle this situation would be
+       // to scan Package.check.allLines for LICENSE lines, but that would
+       // be too much just to cover this special case.
+       ip.UseLicense("djb-unlicense")
 }
 
 func (ip *InterPackage) Enabled() bool { return ip.hashes != nil }

Index: pkgsrc/pkgtools/pkglint/files/plist.go
diff -u pkgsrc/pkgtools/pkglint/files/plist.go:1.56 pkgsrc/pkgtools/pkglint/files/plist.go:1.57
--- pkgsrc/pkgtools/pkglint/files/plist.go:1.56 Sun Mar 22 17:43:15 2020
+++ pkgsrc/pkgtools/pkglint/files/plist.go      Thu Apr 30 21:15:03 2020
@@ -370,7 +370,12 @@ func (ck *PlistChecker) checkPathLib(pli
 }
 
 func (ck *PlistChecker) checkPathMan(pline *PlistLine) {
-       m, catOrMan, section, manpage, ext, gz := match5(pline.text, `^man/(cat|man)(\w+)/(.*?)\.(\w+)(\.gz)?$`)
+       m, catOrMan, section, base := match3(pline.text, `^man/(cat|man)(\w+)/(.*)$`)
+       if !m {
+               // maybe: line.Warnf("Invalid filename %q for manual page.", text)
+               return
+       }
+       m, manpage, ext, gz := match3(base, `^(.*?)\.(\w+)(\.gz)?$`)
        if !m {
                // maybe: line.Warnf("Invalid filename %q for manual page.", text)
                return

Index: pkgsrc/pkgtools/pkglint/files/util.go
diff -u pkgsrc/pkgtools/pkglint/files/util.go:1.76 pkgsrc/pkgtools/pkglint/files/util.go:1.77
--- pkgsrc/pkgtools/pkglint/files/util.go:1.76  Thu Mar 26 07:02:44 2020
+++ pkgsrc/pkgtools/pkglint/files/util.go       Thu Apr 30 21:15:03 2020
@@ -58,12 +58,6 @@ func match2(s string, re regex.Pattern) 
 func match3(s string, re regex.Pattern) (matched bool, m1, m2, m3 string) {
        return G.res.Match3(s, re)
 }
-func match4(s string, re regex.Pattern) (matched bool, m1, m2, m3, m4 string) {
-       return G.res.Match4(s, re)
-}
-func match5(s string, re regex.Pattern) (matched bool, m1, m2, m3, m4, m5 string) {
-       return G.res.Match5(s, re)
-}
 func replaceAll(s string, re regex.Pattern, repl string) string {
        return G.res.Compile(re).ReplaceAllString(s, repl)
 }
@@ -558,7 +552,7 @@ func (o *Once) FirstTime(what string) bo
        key := o.keyString(what)
        firstTime := o.check(key)
        if firstTime && o.Trace {
-               G.Logger.out.WriteLine(sprintf("FirstTime: %s", what))
+               G.Logger.out.WriteLine("FirstTime: " + what)
        }
        return firstTime
 }
@@ -567,7 +561,7 @@ func (o *Once) FirstTimeSlice(whats ...s
        key := o.keyStrings(whats)
        firstTime := o.check(key)
        if firstTime && o.Trace {
-               G.Logger.out.WriteLine(sprintf("FirstTime: %s", strings.Join(whats, ", ")))
+               G.Logger.out.WriteLine("FirstTime: " + strings.Join(whats, ", "))
        }
        return firstTime
 }

Index: pkgsrc/pkgtools/pkglint/files/vardefs.go
diff -u pkgsrc/pkgtools/pkglint/files/vardefs.go:1.93 pkgsrc/pkgtools/pkglint/files/vardefs.go:1.94
--- pkgsrc/pkgtools/pkglint/files/vardefs.go:1.93       Mon Apr 13 19:46:44 2020
+++ pkgsrc/pkgtools/pkglint/files/vardefs.go    Thu Apr 30 21:15:03 2020
@@ -1102,7 +1102,7 @@ func (reg *VarTypeRegistry) Init(src *Pk
        reg.pkg("DJB_RESTRICTED", BtYesNo)
        reg.pkg("DJB_SLASHPACKAGE", BtYesNo)
        reg.pkg("DLOPEN_REQUIRE_PTHREADS", BtYesNo)
-       reg.pkg("DL_AUTO_VARS", BtYes)
+       reg.pkg("DL_AUTO_VARS", BtYesNo)
        reg.acllist("DL_LIBS", BtLdFlag,
                PackageSettable,
                "*: append, use")
@@ -1357,7 +1357,6 @@ func (reg *VarTypeRegistry) Init(src *Pk
        reg.sysload("OBJECT_FMT", enum("COFF ECOFF ELF SOM XCOFF Mach-O PE a.out"))
        reg.pkglistrat("ONLY_FOR_COMPILER", compilers)
        reg.pkglistrat("ONLY_FOR_PLATFORM", BtMachinePlatformPattern)
-       reg.pkgrat("ONLY_FOR_UNPRIVILEGED", BtYesNo)
        reg.sysload("OPSYS", operatingSystems, DefinedIfInScope|NonemptyIfDefined)
        reg.pkglistbl3("OPSYSVARS", BtVariableName)
        reg.pkg("OSVERSION_SPECIFIC", BtYes)
@@ -1569,11 +1568,12 @@ func (reg *VarTypeRegistry) Init(src *Pk
                "special:pyversion.mk: set",
                "*: use, use-loadtime")
        // See lang/python/pyversion.mk
+       py := reg.enumFromDirs(src, "lang", `^python(\d+)$`, "$1", "27 36 37 38")
        reg.pkg("PYTHON_FOR_BUILD_ONLY", enum("yes no test tool YES"))
-       reg.pkglistrat("PYTHON_VERSIONS_ACCEPTED", BtVersion)
-       reg.pkglistrat("PYTHON_VERSIONS_INCOMPATIBLE", BtVersion)
-       reg.usr("PYTHON_VERSION_DEFAULT", BtVersion)
-       reg.usr("PYTHON_VERSION_REQD", BtVersion)
+       reg.pkglistrat("PYTHON_VERSIONS_ACCEPTED", py)
+       reg.pkglistrat("PYTHON_VERSIONS_INCOMPATIBLE", py)
+       reg.usr("PYTHON_VERSION_DEFAULT", py)
+       reg.sys("PYTHON_VERSION_REQD", py)
        reg.pkglist("PYTHON_VERSIONED_DEPENDENCIES", BtPythonDependency)
        reg.sys("RANLIB", BtShellCommand)
        reg.pkglist("RCD_SCRIPTS", BtFilename)

Index: pkgsrc/pkgtools/pkglint/files/vartypecheck.go
diff -u pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.84 pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.85
--- pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.84  Mon Apr 13 19:46:44 2020
+++ pkgsrc/pkgtools/pkglint/files/vartypecheck.go       Thu Apr 30 21:15:03 2020
@@ -1387,7 +1387,7 @@ func (cv *VartypeCheck) URL() {
        } else if containsVarUse(value) {
                // No further checks
 
-       } else if m, _, host, _, _ := match4(value, `^(https?|ftp|gopher)://([-0-9A-Za-z.]+)(?::(\d+))?/([-%&+,./0-9:;=?@A-Z_a-z~]|#)*$`); m {
+       } else if m, host := match1(value, `^(?:https?|ftp|gopher)://([-0-9A-Za-z.]+)(?::\d+)?/[-#%&+,./0-9:;=?@A-Z_a-z~]*$`); m {
                if matches(host, `(?i)\.NetBSD\.org$`) && !matches(host, `\.NetBSD\.org$`) {
                        prefix := host[:len(host)-len(".NetBSD.org")]
                        fix := cv.Autofix()
@@ -1566,7 +1566,7 @@ func (cv *VartypeCheck) WrksrcSubdirecto
                        "",
                        "Example:",
                        "",
-                       "\tWRKSRC=\t${WRKDIR}",
+                       "\tWRKSRC=\t\t${WRKDIR}",
                        "\tCONFIGURE_DIRS=\t${WRKSRC}/lib ${WRKSRC}/src",
                        "\tBUILD_DIRS=\t${WRKSRC}/lib ${WRKSRC}/src ${WRKSRC}/cmd",
                        "",

Index: pkgsrc/pkgtools/pkglint/files/pkgver/vercmp.go
diff -u pkgsrc/pkgtools/pkglint/files/pkgver/vercmp.go:1.5 pkgsrc/pkgtools/pkglint/files/pkgver/vercmp.go:1.6
--- pkgsrc/pkgtools/pkglint/files/pkgver/vercmp.go:1.5  Sun Jan 13 19:55:53 2019
+++ pkgsrc/pkgtools/pkglint/files/pkgver/vercmp.go      Thu Apr 30 21:15:03 2020
@@ -31,7 +31,7 @@ func Compare(left, right string) int {
 
        m := imax(len(lv.v), len(rv.v))
        for i := 0; i < m; i++ {
-               if c := icmp(lv.Field(i), rv.Field(i)); c != 0 {
+               if c := icmp(lv.field(i), rv.field(i)); c != 0 {
                        return c
                }
        }
@@ -52,24 +52,24 @@ func newVersion(vstr string) *version {
                case lex.TestByteSet(textproc.Digit):
                        num := lex.NextBytesSet(textproc.Digit)
                        n, _ := strconv.Atoi(num)
-                       v.Add(n)
+                       v.add(n)
                case lex.SkipByte('_') || lex.SkipByte('.'):
-                       v.Add(0)
+                       v.add(0)
                case lex.SkipString("alpha"):
-                       v.Add(-3)
+                       v.add(-3)
                case lex.SkipString("beta"):
-                       v.Add(-2)
+                       v.add(-2)
                case lex.SkipString("pre"):
-                       v.Add(-1)
+                       v.add(-1)
                case lex.SkipString("rc"):
-                       v.Add(-1)
+                       v.add(-1)
                case lex.SkipString("pl"):
-                       v.Add(0)
+                       v.add(0)
                case lex.SkipString("nb"):
                        num := lex.NextBytesSet(textproc.Digit)
                        v.nb, _ = strconv.Atoi(num)
                case lex.TestByteSet(textproc.Lower):
-                       v.Add(int(lex.Rest()[0] - 'a' + 1))
+                       v.add(int(lex.Rest()[0] - 'a' + 1))
                        lex.Skip(1)
                default:
                        lex.Skip(1)
@@ -78,11 +78,12 @@ func newVersion(vstr string) *version {
        return v
 }
 
-func (v *version) Add(i int) {
+//go:noinline
+func (v *version) add(i int) {
        v.v = append(v.v, i)
 }
 
-func (v *version) Field(i int) int {
+func (v *version) field(i int) int {
        if i < len(v.v) {
                return v.v[i]
        }

Index: pkgsrc/pkgtools/pkglint/files/regex/regex.go
diff -u pkgsrc/pkgtools/pkglint/files/regex/regex.go:1.6 pkgsrc/pkgtools/pkglint/files/regex/regex.go:1.7
--- pkgsrc/pkgtools/pkglint/files/regex/regex.go:1.6    Sun Jan 13 19:55:53 2019
+++ pkgsrc/pkgtools/pkglint/files/regex/regex.go        Thu Apr 30 21:15:03 2020
@@ -103,20 +103,6 @@ func (r *Registry) Match3(s string, re P
        return
 }
 
-func (r *Registry) Match4(s string, re Pattern) (matched bool, m1, m2, m3, m4 string) {
-       if m := r.matchn(s, re, 4); m != nil {
-               return true, m[1], m[2], m[3], m[4]
-       }
-       return
-}
-
-func (r *Registry) Match5(s string, re Pattern) (matched bool, m1, m2, m3, m4, m5 string) {
-       if m := r.matchn(s, re, 5); m != nil {
-               return true, m[1], m[2], m[3], m[4], m[5]
-       }
-       return
-}
-
 func (r *Registry) ReplaceFirst(s string, re Pattern, replacement string) ([]string, string) {
        if m := r.Compile(re).FindStringSubmatchIndex(s); m != nil {
                replaced := s[:m[0]] + replacement + s[m[1]:]



Home | Main Index | Thread Index | Old Index