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:           Sat Apr 27 19:33:57 UTC 2019

Modified Files:
        pkgsrc/pkgtools/pkglint: Makefile
        pkgsrc/pkgtools/pkglint/files: autofix.go autofix_test.go
            category_test.go check_test.go logging.go logging_test.go mkline.go
            mkline_test.go mklinechecker.go mklinechecker_test.go mklines.go
            mklines_test.go mkparser_test.go package.go package_test.go
            pkglint.go pkglint_test.go pkgsrc.go pkgsrc_test.go shell_test.go
            util.go util_test.go vardefs.go vartypecheck.go
            vartypecheck_test.go

Log Message:
pkgtools/pkglint: update to 5.7.7

Changes since 5.7.6:

Warn about packages that override user-settable variables. Packages that
define variables with the same value as the default value only get a
note instead of the warning since these definitions do not cause any
confusion.

Do not suppress technical error messages in autofix mode.

Do not warn about the package version being greater than the latest from
doc/CHANGES if the file defining the package version has been modified
locally and is about to be committed.


To generate a diff of this commit:
cvs rdiff -u -r1.576 -r1.577 pkgsrc/pkgtools/pkglint/Makefile
cvs rdiff -u -r1.20 -r1.21 pkgsrc/pkgtools/pkglint/files/autofix.go \
    pkgsrc/pkgtools/pkglint/files/logging.go
cvs rdiff -u -r1.21 -r1.22 pkgsrc/pkgtools/pkglint/files/autofix_test.go \
    pkgsrc/pkgtools/pkglint/files/category_test.go \
    pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go
cvs rdiff -u -r1.39 -r1.40 pkgsrc/pkgtools/pkglint/files/check_test.go \
    pkgsrc/pkgtools/pkglint/files/pkglint_test.go
cvs rdiff -u -r1.14 -r1.15 pkgsrc/pkgtools/pkglint/files/logging_test.go
cvs rdiff -u -r1.51 -r1.52 pkgsrc/pkgtools/pkglint/files/mkline.go \
    pkgsrc/pkgtools/pkglint/files/package.go
cvs rdiff -u -r1.56 -r1.57 pkgsrc/pkgtools/pkglint/files/mkline_test.go
cvs rdiff -u -r1.35 -r1.36 pkgsrc/pkgtools/pkglint/files/mklinechecker.go
cvs rdiff -u -r1.31 -r1.32 \
    pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go
cvs rdiff -u -r1.47 -r1.48 pkgsrc/pkgtools/pkglint/files/mklines.go
cvs rdiff -u -r1.41 -r1.42 pkgsrc/pkgtools/pkglint/files/mklines_test.go
cvs rdiff -u -r1.28 -r1.29 pkgsrc/pkgtools/pkglint/files/mkparser_test.go
cvs rdiff -u -r1.44 -r1.45 pkgsrc/pkgtools/pkglint/files/package_test.go \
    pkgsrc/pkgtools/pkglint/files/shell_test.go
cvs rdiff -u -r1.52 -r1.53 pkgsrc/pkgtools/pkglint/files/pkglint.go
cvs rdiff -u -r1.24 -r1.25 pkgsrc/pkgtools/pkglint/files/pkgsrc.go
cvs rdiff -u -r1.42 -r1.43 pkgsrc/pkgtools/pkglint/files/util.go
cvs rdiff -u -r1.27 -r1.28 pkgsrc/pkgtools/pkglint/files/util_test.go
cvs rdiff -u -r1.60 -r1.61 pkgsrc/pkgtools/pkglint/files/vardefs.go
cvs rdiff -u -r1.54 -r1.55 pkgsrc/pkgtools/pkglint/files/vartypecheck.go
cvs rdiff -u -r1.46 -r1.47 pkgsrc/pkgtools/pkglint/files/vartypecheck_test.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.576 pkgsrc/pkgtools/pkglint/Makefile:1.577
--- pkgsrc/pkgtools/pkglint/Makefile:1.576      Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/Makefile    Sat Apr 27 19:33:56 2019
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.576 2019/04/23 21:20:49 rillig Exp $
+# $NetBSD: Makefile,v 1.577 2019/04/27 19:33:56 rillig Exp $
 
-PKGNAME=       pkglint-5.7.6
+PKGNAME=       pkglint-5.7.7
 CATEGORIES=    pkgtools
 DISTNAME=      tools
 MASTER_SITES=  ${MASTER_SITE_GITHUB:=golang/}

Index: pkgsrc/pkgtools/pkglint/files/autofix.go
diff -u pkgsrc/pkgtools/pkglint/files/autofix.go:1.20 pkgsrc/pkgtools/pkglint/files/autofix.go:1.21
--- pkgsrc/pkgtools/pkglint/files/autofix.go:1.20       Sat Apr 20 17:43:24 2019
+++ pkgsrc/pkgtools/pkglint/files/autofix.go    Sat Apr 27 19:33:57 2019
@@ -455,14 +455,12 @@ func SaveAutofixChanges(lines Lines) (au
                }
                err := ioutil.WriteFile(tmpName, []byte(text.String()), 0666)
                if err != nil {
-                       G.Logf(Error, tmpName, "", "Cannot write: %s", "Cannot write: "+err.Error())
+                       G.Logger.Errorf(tmpName, "Cannot write: %s", err)
                        continue
                }
                err = os.Rename(tmpName, filename)
                if err != nil {
-                       G.Logf(Error, tmpName, "",
-                               "Cannot overwrite with autofixed content: %s",
-                               "Cannot overwrite with autofixed content: "+err.Error())
+                       G.Logger.Errorf(tmpName, "Cannot overwrite with autofixed content: %s", err)
                        continue
                }
                autofixed = true
Index: pkgsrc/pkgtools/pkglint/files/logging.go
diff -u pkgsrc/pkgtools/pkglint/files/logging.go:1.20 pkgsrc/pkgtools/pkglint/files/logging.go:1.21
--- pkgsrc/pkgtools/pkglint/files/logging.go:1.20       Thu Feb 21 22:49:03 2019
+++ pkgsrc/pkgtools/pkglint/files/logging.go    Sat Apr 27 19:33:57 2019
@@ -234,6 +234,24 @@ func (l *Logger) Logf(level *LogLevel, f
        }
 }
 
+// Errorf logs a technical error on the error output.
+//
+// location must be either an empty string or a slash-separated filename,
+// such as the one in Location.Filename. It may be followed by the usual
+// ":123" for line numbers.
+//
+// For diagnostics, use Logf instead.
+func (l *Logger) Errorf(location string, format string, args ...interface{}) {
+       msg := sprintf(format, args...)
+       var diag string
+       if l.Opts.GccOutput {
+               diag = sprintf("%s: %s: %s\n", location, Error.GccName, msg)
+       } else {
+               diag = sprintf("%s: %s: %s\n", Error.TraditionalName, location, msg)
+       }
+       l.err.Write(escapePrintable(diag))
+}
+
 // SeparatorWriter writes output, occasionally separated by an
 // empty line. This is used for separating the diagnostics when
 // --source is combined with --show-autofix, where each

Index: pkgsrc/pkgtools/pkglint/files/autofix_test.go
diff -u pkgsrc/pkgtools/pkglint/files/autofix_test.go:1.21 pkgsrc/pkgtools/pkglint/files/autofix_test.go:1.22
--- pkgsrc/pkgtools/pkglint/files/autofix_test.go:1.21  Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/autofix_test.go       Sat Apr 27 19:33:57 2019
@@ -1098,9 +1098,9 @@ func (s *Suite) Test_SaveAutofixChanges_
 
        SaveAutofixChanges(lines)
 
-       c.Check(t.Output(), check.Matches, ""+
-               "AUTOFIX: ~/subdir/file.txt:1: Replacing \"line\" with \"Line\".\n"+
-               "ERROR: ~/subdir/file.txt.pkglint.tmp: Cannot write: .*\n")
+       t.CheckOutputMatches(
+               "AUTOFIX: ~/subdir/file.txt:1: Replacing \"line\" with \"Line\".",
+               `ERROR: ~/subdir/file.txt.pkglint.tmp: Cannot write: .*`)
 }
 
 func (s *Suite) Test_SaveAutofixChanges__file_busy_Windows(c *check.C) {
@@ -1126,9 +1126,9 @@ func (s *Suite) Test_SaveAutofixChanges_
 
        SaveAutofixChanges(lines)
 
-       c.Check(t.Output(), check.Matches, ""+
-               "AUTOFIX: ~/subdir/file.txt:1: Replacing \"line\" with \"Line\".\n"+
-               "ERROR: ~/subdir/file.txt.pkglint.tmp: Cannot overwrite with autofixed content: .*\n")
+       t.CheckOutputMatches(
+               "AUTOFIX: ~/subdir/file.txt:1: Replacing \"line\" with \"Line\".",
+               `ERROR: ~/subdir/file.txt.pkglint.tmp: Cannot overwrite with autofixed content: .*`)
 }
 
 // This test covers the highly unlikely situation in which a file is loaded
@@ -1153,9 +1153,9 @@ func (s *Suite) Test_SaveAutofixChanges_
 
        SaveAutofixChanges(lines)
 
-       c.Check(t.Output(), check.Matches, ""+
-               "AUTOFIX: ~/file.txt:1: Replacing \"line\" with \"Line\".\n"+
-               "ERROR: ~/file.txt.pkglint.tmp: Cannot overwrite with autofixed content: .*\n")
+       t.CheckOutputMatches(
+               "AUTOFIX: ~/file.txt:1: Replacing \"line\" with \"Line\".",
+               `ERROR: ~/file.txt.pkglint.tmp: Cannot overwrite with autofixed content: .*`)
 }
 
 // Up to 2018-11-25, pkglint in some cases logged only the source without
Index: pkgsrc/pkgtools/pkglint/files/category_test.go
diff -u pkgsrc/pkgtools/pkglint/files/category_test.go:1.21 pkgsrc/pkgtools/pkglint/files/category_test.go:1.22
--- pkgsrc/pkgtools/pkglint/files/category_test.go:1.21 Sat Apr 20 17:43:24 2019
+++ pkgsrc/pkgtools/pkglint/files/category_test.go      Sat Apr 27 19:33:57 2019
@@ -69,7 +69,6 @@ func (s *Suite) Test_CheckdirCategory__w
        t := s.Init(c)
 
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.CreateFileLines("mk/misc/category.mk")
        t.CreateFileLines("wip/package/Makefile")
        t.CreateFileLines("wip/Makefile",
@@ -95,7 +94,6 @@ func (s *Suite) Test_CheckdirCategory__s
        t := s.Init(c)
 
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.CreateFileLines("mk/misc/category.mk")
        t.CreateFileLines("category/in-wrong-order/Makefile")
        t.CreateFileLines("category/duplicate/Makefile")
@@ -136,7 +134,6 @@ func (s *Suite) Test_CheckdirCategory__o
        t := s.Init(c)
 
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.CreateFileLines("mk/misc/category.mk")
        t.CreateFileLines("category/both/Makefile")
        t.CreateFileLines("category/Makefile",
@@ -164,7 +161,6 @@ func (s *Suite) Test_CheckdirCategory__o
        t := s.Init(c)
 
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.CreateFileLines("mk/misc/category.mk")
        t.CreateFileLines("category/above-only-in-fs/Makefile")
        t.CreateFileLines("category/both/Makefile")
@@ -193,7 +189,6 @@ func (s *Suite) Test_CheckdirCategory__r
 
        t.SetUpCommandLine("-r")
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.CreateFileLines("mk/misc/category.mk")
        t.CreateFileLines("category/commented/Makefile")
        t.CreateFileLines("category/package/Makefile")
@@ -231,7 +226,6 @@ func (s *Suite) Test_CheckdirCategory__s
 
        t.SetUpCommandLine("-Wall", "--show-autofix")
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.CreateFileLines("mk/misc/category.mk")
        t.CreateFileLines("category/mk-and-fs/Makefile")
        t.CreateFileLines("category/zzz-fs-only/Makefile")
@@ -256,7 +250,6 @@ func (s *Suite) Test_CheckdirCategory__i
        t := s.Init(c)
 
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.CreateFileLines("mk/misc/category.mk")
        t.CreateFileLines("category/package1/Makefile")
        t.CreateFileLines("category/package2/Makefile")
@@ -281,7 +274,6 @@ func (s *Suite) Test_CheckdirCategory__c
        t := s.Init(c)
 
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.CreateFileLines("mk/misc/category.mk")
        t.CreateFileLines("category/package/Makefile")
        t.CreateFileLines("category/Makefile",
@@ -317,7 +309,6 @@ func (s *Suite) Test_CheckdirCategory__u
        t := s.Init(c)
 
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.CreateFileLines("mk/misc/category.mk")
        t.CreateFileLines("category/package/Makefile")
        t.CreateFileLines("category/Makefile",
Index: pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go
diff -u pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go:1.21 pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go:1.22
--- pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go:1.21   Sat Apr 20 17:43:24 2019
+++ pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go        Sat Apr 27 19:33:57 2019
@@ -79,6 +79,52 @@ func (s *Suite) Test_Pkgsrc_checkTopleve
                "0 errors and 2 warnings found.")
 }
 
+func (s *Suite) Test_Pkgsrc_loadUntypedVars(c *check.C) {
+       t := s.Init(c)
+
+       t.SetUpPkgsrc()
+       t.SetUpTool("echo", "ECHO", AtRunTime)
+       t.CreateFileLines("mk/infra.mk",
+               MkRcsID,
+               "#",
+               "# System-provided variables:",
+               "#",
+               "# DOCUMENTED",
+               "#\tThis variable is not actually defined but still documented.",
+               "#\tThis may be because its definition is evaluated dynamically.",
+               "",
+               ".if !defined(INFRA_MK)",
+               "INFRA_MK:=",
+               "",
+               "UNTYPED.one=\tone",
+               "UNTYPED.two=\ttwo",
+               "ECHO=\t\techo",
+               "_UNTYPED=\tinfrastructure only",
+               ".for p in param",
+               "PARAMETERIZED.${p}=\tparameterized",
+               "INDIRECT_${p}=\tindirect",
+               ".endfor",
+               "#COMMENTED=\tcommented",
+               ".endif")
+       t.FinishSetUp()
+
+       mklines := t.NewMkLines("filename.mk",
+               MkRcsID,
+               "",
+               "do-build:",
+               "\t: ${INFRA_MK} ${UNTYPED.three} ${ECHO}",
+               "\t: ${_UNTYPED} ${PARAMETERIZED.param}",
+               "\t: ${INDIRECT_param}",
+               "\t: ${DOCUMENTED} ${COMMENTED}")
+
+       mklines.Check()
+
+       t.CheckOutputLines(
+               "WARN: filename.mk:4: INFRA_MK is used but not defined.",
+               "WARN: filename.mk:5: _UNTYPED is used but not defined.",
+               "WARN: filename.mk:6: INDIRECT_param is used but not defined.")
+}
+
 func (s *Suite) Test_Pkgsrc_loadTools(c *check.C) {
        t := s.Init(c)
 

Index: pkgsrc/pkgtools/pkglint/files/check_test.go
diff -u pkgsrc/pkgtools/pkglint/files/check_test.go:1.39 pkgsrc/pkgtools/pkglint/files/check_test.go:1.40
--- pkgsrc/pkgtools/pkglint/files/check_test.go:1.39    Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/check_test.go Sat Apr 27 19:33:57 2019
@@ -9,6 +9,7 @@ import (
        "os"
        "path"
        "path/filepath"
+       "regexp"
        "strings"
        "testing"
 
@@ -339,7 +340,6 @@ func (t *Tester) SetUpPackage(pkgpath st
        }
 
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.SetUpCategory(category)
 
        t.CreateFileLines(pkgpath+"/DESCR",
@@ -723,7 +723,8 @@ func (t *Tester) ExpectFatalMatches(acti
                if r == nil {
                        panic("Expected a pkglint fatal error but didn't get one.")
                } else if _, ok := r.(pkglintFatal); ok {
-                       t.Check(t.Output(), check.Matches, string(expected))
+                       pattern := `^(?:` + string(expected) + `)$`
+                       t.Check(t.Output(), check.Matches, pattern)
                } else {
                        panic(r)
                }
@@ -780,7 +781,10 @@ func (t *Tester) NewLine(filename string
 func (t *Tester) NewMkLine(filename string, lineno int, text string) MkLine {
        basename := path.Base(filename)
        G.Assertf(
-               hasSuffix(basename, ".mk") || basename == "Makefile" || hasPrefix(basename, "Makefile."),
+               hasSuffix(basename, ".mk") ||
+                       basename == "Makefile" ||
+                       hasPrefix(basename, "Makefile.") ||
+                       basename == "mk.conf",
                "filename %q must be realistic, otherwise the variable permissions are wrong", filename)
 
        return MkLineParser{}.Parse(t.NewLine(filename, lineno, text))
@@ -869,6 +873,47 @@ func (t *Tester) CheckOutputLines(expect
        t.CheckOutput(expectedLines)
 }
 
+// CheckOutputMatches checks that the output up to now matches the given lines.
+// Each line may either be an exact string or a regular expression.
+// By convention, regular expressions are written in backticks.
+//
+// After the comparison, the output buffers are cleared so that later
+// calls only check against the newly added output.
+//
+// See CheckOutputEmpty.
+func (t *Tester) CheckOutputMatches(expectedLines ...regex.Pattern) {
+       output := t.Output()
+       actualLines := strings.Split(output, "\n")
+       actualLines = actualLines[:len(actualLines)-1]
+
+       ok := func(actualLine string, expectedLine regex.Pattern) bool {
+               if actualLine == string(expectedLine) {
+                       return true
+               }
+
+               pattern := `^(?:` + string(expectedLine) + `)$`
+               re, err := regexp.Compile(pattern)
+               if err != nil {
+                       return false
+               }
+
+               return re.MatchString(actualLine)
+       }
+
+       // If a line matches the corresponding pattern, make them equal in the
+       // comparison output, in order to concentrate on the lines that don't match.
+       var patterns []string
+       for i, expectedLine := range expectedLines {
+               if i < len(actualLines) && ok(actualLines[i], expectedLine) {
+                       patterns = append(patterns, actualLines[i])
+               } else {
+                       patterns = append(patterns, string(expectedLine))
+               }
+       }
+
+       t.Check(emptyToNil(actualLines), deepEquals, emptyToNil(patterns))
+}
+
 // CheckOutput checks that the output up to now equals the given lines.
 // After the comparison, the output buffers are cleared so that later
 // calls only check against the newly added output.
Index: pkgsrc/pkgtools/pkglint/files/pkglint_test.go
diff -u pkgsrc/pkgtools/pkglint/files/pkglint_test.go:1.39 pkgsrc/pkgtools/pkglint/files/pkglint_test.go:1.40
--- pkgsrc/pkgtools/pkglint/files/pkglint_test.go:1.39  Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/pkglint_test.go       Sat Apr 27 19:33:57 2019
@@ -626,8 +626,8 @@ func (s *Suite) Test_Pkglint__profiling_
        exitcode := t.Main("--profiling")
 
        c.Check(exitcode, equals, 1)
-       c.Check(t.Output(), check.Matches,
-               `^FATAL: Cannot create profiling file: open pkglint\.pprof: .*\n$`)
+       t.CheckOutputMatches(
+               `FATAL: Cannot create profiling file: open pkglint\.pprof: .*`)
 }
 
 func (s *Suite) Test_Pkglint_checkReg__in_current_working_directory(c *check.C) {
@@ -974,7 +974,6 @@ func (s *Suite) Test_Pkglint_checkdirPac
 func (s *Suite) Test_Pkglint_checkdirPackage__PKGDIR(c *check.C) {
        t := s.Init(c)
 
-       t.SetUpVartypes()
        t.SetUpPkgsrc()
        t.CreateFileLines("category/Makefile")
        t.CreateFileLines("other/package/Makefile",
@@ -1120,9 +1119,9 @@ func (s *Suite) Test_Pkglint_checkExecut
 
        G.checkExecutable(filename, 0555)
 
-       // FIXME: The error message "Cannot clear executable bits" is swallowed.
-       t.CheckOutputLines(
-               "AUTOFIX: ~/file.mk: Clearing executable bits")
+       t.CheckOutputMatches(
+               "AUTOFIX: ~/file.mk: Clearing executable bits",
+               `ERROR: ~/file.mk: Cannot clear executable bits: chmod ~/file.mk: .*`)
 }
 
 func (s *Suite) Test_Pkglint_checkExecutable__already_committed(c *check.C) {

Index: pkgsrc/pkgtools/pkglint/files/logging_test.go
diff -u pkgsrc/pkgtools/pkglint/files/logging_test.go:1.14 pkgsrc/pkgtools/pkglint/files/logging_test.go:1.15
--- pkgsrc/pkgtools/pkglint/files/logging_test.go:1.14  Sat Apr 20 17:43:24 2019
+++ pkgsrc/pkgtools/pkglint/files/logging_test.go       Sat Apr 27 19:33:57 2019
@@ -676,6 +676,17 @@ func (s *Suite) Test_Logger_Logf__tradit
                "NOTE: Neither filename nor line number.")
 }
 
+func (s *Suite) Test_Logger_Errorf__gcc_format(c *check.C) {
+       t := s.Init(c)
+
+       t.SetUpCommandLine("--gcc-output-format")
+
+       G.Errorf("filename", "Cannot be opened for %s.", "reading")
+
+       t.CheckOutputLines(
+               "filename: error: Cannot be opened for reading.")
+}
+
 // Ensures that pkglint never destroys the terminal emulator by sending unintended escape sequences.
 func (s *Suite) Test_Logger_Logf__strange_characters(c *check.C) {
        t := s.Init(c)

Index: pkgsrc/pkgtools/pkglint/files/mkline.go
diff -u pkgsrc/pkgtools/pkglint/files/mkline.go:1.51 pkgsrc/pkgtools/pkglint/files/mkline.go:1.52
--- pkgsrc/pkgtools/pkglint/files/mkline.go:1.51        Sat Apr 20 17:43:24 2019
+++ pkgsrc/pkgtools/pkglint/files/mkline.go     Sat Apr 27 19:33:57 2019
@@ -548,7 +548,7 @@ func (mkline *MkLineImpl) ValueTokens() 
 // For variable assignments, it returns the right-hand side, properly split into words.
 // For .for loops, it returns all arguments (including variable names), properly split into words.
 func (mkline *MkLineImpl) Fields() []string {
-       if mkline.IsVarassign() {
+       if mkline.IsVarassign() || mkline.IsCommentedVarassign() {
                value := mkline.Value()
                if value == "" {
                        return nil
Index: pkgsrc/pkgtools/pkglint/files/package.go
diff -u pkgsrc/pkgtools/pkglint/files/package.go:1.51 pkgsrc/pkgtools/pkglint/files/package.go:1.52
--- pkgsrc/pkgtools/pkglint/files/package.go:1.51       Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/package.go    Sat Apr 27 19:33:57 2019
@@ -135,7 +135,7 @@ func (pkg *Package) checkPossibleDowngra
                                "This is unusual, since packages are typically upgraded instead of",
                                "downgraded.")
 
-               case cmp > 0:
+               case cmp > 0 && !isLocallyModified(mkline.Filename):
                        mkline.Notef("Package version %q is greater than the latest %q from %s.",
                                pkgversion, change.Version, mkline.Line.RefToLocation(change.Location))
                        mkline.Explain(

Index: pkgsrc/pkgtools/pkglint/files/mkline_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.56 pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.57
--- pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.56   Sat Apr 20 17:43:24 2019
+++ pkgsrc/pkgtools/pkglint/files/mkline_test.go        Sat Apr 27 19:33:57 2019
@@ -1551,7 +1551,6 @@ func (s *Suite) Test_Indentation_TrackAf
 func (s *Suite) Test_Indentation_Varnames__repetition(c *check.C) {
        t := s.Init(c)
 
-       t.SetUpVartypes()
        t.SetUpPackage("category/other")
        t.CreateFileDummyBuildlink3("category/other/buildlink3.mk")
        t.SetUpPackage("category/package",

Index: pkgsrc/pkgtools/pkglint/files/mklinechecker.go
diff -u pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.35 pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.36
--- pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.35 Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/mklinechecker.go      Sat Apr 27 19:33:57 2019
@@ -471,7 +471,13 @@ func (ck MkLineChecker) checkVaruseUndef
                // Well-known variables are probably defined by the infrastructure.
                return
 
-       case ck.MkLines != nil && (ck.MkLines.vars.DefinedSimilar(varname) || ck.MkLines.forVars[varname]):
+       case ck.MkLines != nil && ck.MkLines.vars.DefinedSimilar(varname):
+               return
+
+       case ck.MkLines != nil && ck.MkLines.forVars[varname]:
+               return
+
+       case ck.MkLines != nil && ck.MkLines.vars.Mentioned(varname) != nil:
                return
 
        case G.Pkg != nil && G.Pkg.vars.DefinedSimilar(varname):
@@ -922,8 +928,10 @@ func (ck MkLineChecker) checkVarassignLe
 
        ck.checkVarassignLeftNotUsed()
        ck.checkVarassignLeftDeprecated()
-       ck.checkVarassignLeftPermissions()
        ck.checkVarassignLeftBsdPrefs()
+       if !ck.checkVarassignLeftUserSettable() {
+               ck.checkVarassignLeftPermissions()
+       }
 
        ck.checkTextVarUse(
                ck.MkLine.Varname(),
@@ -1226,6 +1234,57 @@ func (ck MkLineChecker) checkVarassignLe
                "bsd.prefs.mk file, which will take care of everything.")
 }
 
+// checkVarassignLeftUserSettable checks whether a package defines a
+// variable that is marked as user-settable since it is defined in
+// mk/defaults/mk.conf.
+func (ck MkLineChecker) checkVarassignLeftUserSettable() bool {
+       mkline := ck.MkLine
+       varname := mkline.Varname()
+
+       defaultMkline := G.Pkgsrc.UserDefinedVars.Mentioned(varname)
+       if defaultMkline == nil {
+               return false
+       }
+       defaultValue := defaultMkline.Value()
+
+       // A few of the user-settable variables can also be set by packages.
+       // That's an unfortunate situation since there is no definite source
+       // of truth, but luckily only a few variables make use of it.
+       vartype := G.Pkgsrc.VariableType(nil, varname)
+       if vartype != nil && vartype.PackageSettable() {
+               return true
+       }
+
+       switch {
+       case mkline.VarassignComment() != "":
+               // Assume that the comment contains a rationale for disabling
+               // this particular check.
+
+       case mkline.Op() == opAssignAppend:
+               mkline.Warnf("Packages should not append to user-settable %s.", varname)
+
+       case defaultValue != mkline.Value():
+               mkline.Warnf(
+                       "Package sets user-defined %q to %q, which differs "+
+                               "from the default value %q from mk/defaults/mk.conf.",
+                       varname, mkline.Value(), defaultValue)
+
+       case defaultMkline.IsCommentedVarassign():
+               // Since the variable assignment is commented out in
+               // mk/defaults/mk.conf, the package has to define it.
+
+       default:
+               mkline.Notef("Redundant definition for %s from mk/defaults/mk.conf.", varname)
+               if !ck.MkLines.Tools.SeenPrefs {
+                       mkline.Explain(
+                               "Instead of defining the variable redundantly, it suffices to include",
+                               "../../mk/bsd.prefs.mk, which provides all user-settable variables.")
+               }
+       }
+
+       return true
+}
+
 func (ck MkLineChecker) checkVartype(varname string, op MkOperator, value, comment string) {
        if trace.Tracing {
                defer trace.Call(varname, op, value, comment)()

Index: pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.31 pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.32
--- pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.31    Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go Sat Apr 27 19:33:57 2019
@@ -92,6 +92,51 @@ func (s *Suite) Test_MkLineChecker_check
                "WARN: ~/mk/infra.mk:2: _VARNAME is defined but not used.")
 }
 
+func (s *Suite) Test_MkLineChecker_checkVarassignLeftUserSettable(c *check.C) {
+       t := s.Init(c)
+
+       // TODO: Allow CreateFileLines before SetUpPackage, since it matches
+       //  the expected reading order of human readers.
+
+       t.SetUpPackage("category/package",
+               "ASSIGN_DIFF=\tpkg",          // assignment, differs from default value
+               "ASSIGN_DIFF2=\treally # ok", // ok because of the rationale in the comment
+               "ASSIGN_SAME=\tdefault",      // assignment, same value as default
+               "DEFAULT_DIFF?=\tpkg",        // default, differs from default value
+               "DEFAULT_SAME?=\tdefault",    // same value as default
+               "FETCH_USING=\tcurl",         // both user-settable and package-settable
+               "APPEND_DIRS+=\tdir3",        // appending requires a separate diagnostic
+               "COMMENTED_SAME?=\tdefault",  // commented default, same value as default
+               "COMMENTED_DIFF?=\tpkg")      // commented default, differs from default value
+       t.CreateFileLines("mk/defaults/mk.conf",
+               MkRcsID,
+               "ASSIGN_DIFF?=default",
+               "ASSIGN_DIFF2?=default",
+               "ASSIGN_SAME?=default",
+               "DEFAULT_DIFF?=\tdefault",
+               "DEFAULT_SAME?=\tdefault",
+               "FETCH_USING=\tauto",
+               "APPEND_DIRS=\tdefault",
+               "#COMMENTED_SAME?=\tdefault",
+               "#COMMENTED_DIFF?=\tdefault")
+       t.Chdir("category/package")
+       t.FinishSetUp()
+
+       G.Check(".")
+
+       t.CheckOutputLines(
+               "WARN: Makefile:20: Package sets user-defined \"ASSIGN_DIFF\" to \"pkg\", "+
+                       "which differs from the default value \"default\" from mk/defaults/mk.conf.",
+               "NOTE: Makefile:22: Redundant definition for ASSIGN_SAME from mk/defaults/mk.conf.",
+               "WARN: Makefile:23: Please include \"../../mk/bsd.prefs.mk\" before using \"?=\".",
+               "WARN: Makefile:23: Package sets user-defined \"DEFAULT_DIFF\" to \"pkg\", "+
+                       "which differs from the default value \"default\" from mk/defaults/mk.conf.",
+               "NOTE: Makefile:24: Redundant definition for DEFAULT_SAME from mk/defaults/mk.conf.",
+               "WARN: Makefile:26: Packages should not append to user-settable APPEND_DIRS.",
+               "WARN: Makefile:28: Package sets user-defined \"COMMENTED_DIFF\" to \"pkg\", "+
+                       "which differs from the default value \"default\" from mk/defaults/mk.conf.")
+}
+
 func (s *Suite) Test_MkLineChecker_Check__url2pkg(c *check.C) {
        t := s.Init(c)
 
@@ -625,8 +670,8 @@ func (s *Suite) Test_MkLineChecker_check
        mklines.Check()
 
        t.CheckOutputLines(
-               "WARN: options.mk:2: The variable PKG_DEVELOPER should not be given a default value by any package.",
                "WARN: options.mk:2: Please include \"../../mk/bsd.prefs.mk\" before using \"?=\".",
+               "WARN: options.mk:2: The variable PKG_DEVELOPER should not be given a default value by any package.",
                "WARN: options.mk:3: The variable BUILD_DEFS should not be given a default value (only appended to) in this file.",
                "WARN: options.mk:4: USE_TOOLS should not be used at load time in this file; "+
                        "it would be ok in Makefile.common or builtin.mk, but not buildlink3.mk or *.",
@@ -660,7 +705,6 @@ func (s *Suite) Test_MkLineChecker_check
 func (s *Suite) Test_MkLineChecker_checkVarassignLeftPermissions__license_default(c *check.C) {
        t := s.Init(c)
 
-       t.SetUpVartypes()
        t.SetUpPkgsrc()
        mklines := t.NewMkLines("filename.mk",
                MkRcsID,
@@ -1814,7 +1858,6 @@ func (s *Suite) Test_MkLineChecker_Check
 func (s *Suite) Test_MkLineChecker_CheckVaruse__varcanon(c *check.C) {
        t := s.Init(c)
 
-       t.SetUpVartypes()
        t.SetUpPkgsrc()
        t.CreateFileLines("mk/sys-vars.mk",
                MkRcsID,
@@ -1845,7 +1888,6 @@ func (s *Suite) Test_MkLineChecker_Check
        t := s.Init(c)
 
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.CreateFileLines("mk/deeply/nested/infra.mk",
                MkRcsID,
                "INFRA_VAR?=\tvalue")
@@ -1997,6 +2039,33 @@ func (s *Suite) Test_MkLineChecker_Check
                "WARN: module.mk:123: Use of _PKG_SILENT and _PKG_DEBUG is deprecated. Use ${RUN} instead.")
 }
 
+func (s *Suite) Test_MkLineChecker_checkVaruseUndefined(c *check.C) {
+       t := s.Init(c)
+
+       t.SetUpPkgsrc()
+       t.CreateFileLines("mk/infra.mk",
+               MkRcsID,
+               "#",
+               "# User-settable variables:",
+               "#",
+               "# DOCUMENTED",
+               "",
+               "ASSIGNED=\tassigned",
+               "#COMMENTED=\tcommented")
+       t.FinishSetUp()
+
+       mklines := t.NewMkLines("filename.mk",
+               MkRcsID,
+               "",
+               "do-build:",
+               "\t: ${ASSIGNED} ${COMMENTED} ${DOCUMENTED} ${UNKNOWN}")
+
+       mklines.Check()
+
+       t.CheckOutputLines(
+               "WARN: filename.mk:4: UNKNOWN is used but not defined.")
+}
+
 // PR 46570, item "15. net/uucp/Makefile has a make loop"
 func (s *Suite) Test_MkLineChecker_checkVaruseUndefined__indirect_variables(c *check.C) {
        t := s.Init(c)
@@ -2019,6 +2088,32 @@ func (s *Suite) Test_MkLineChecker_check
                "WARN: net/uucp/Makefile:2: var is used but not defined.")
 }
 
+// Documented variables are declared as both defined and used since, as
+// of April 2019, pkglint doesn't yet interpret the "Package-settable
+// variables" comment.
+func (s *Suite) Test_MkLineChecker_checkVaruseUndefined__documented(c *check.C) {
+       t := s.Init(c)
+
+       t.SetUpVartypes()
+
+       mklines := t.NewMkLines("interpreter.mk",
+               MkRcsID,
+               "#",
+               "# Package-settable variables:",
+               "#",
+               "# REPLACE_INTERP",
+               "#\tThe list of files whose interpreter will be corrected.",
+               "",
+               "REPLACE_INTERPRETER+=\tinterp",
+               "REPLACE.interp.old=\t.*/interp",
+               "REPLACE.interp.new=\t${PREFIX}/bin/interp",
+               "REPLACE_FILES.interp=\t${REPLACE_INTERP}")
+
+       mklines.Check()
+
+       t.CheckOutputEmpty()
+}
+
 func (s *Suite) Test_MkLineChecker_checkVarassignMisc(c *check.C) {
        t := s.Init(c)
 
@@ -2051,7 +2146,6 @@ func (s *Suite) Test_MkLineChecker_check
        t := s.Init(c)
 
        t.SetUpPkgsrc()
-       t.SetUpVartypes()
        t.CreateFileLines("filename.mk",
                MkRcsID,
                ".if !defined(FILENAME_MK)",

Index: pkgsrc/pkgtools/pkglint/files/mklines.go
diff -u pkgsrc/pkgtools/pkglint/files/mklines.go:1.47 pkgsrc/pkgtools/pkglint/files/mklines.go:1.48
--- pkgsrc/pkgtools/pkglint/files/mklines.go:1.47       Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/mklines.go    Sat Apr 27 19:33:57 2019
@@ -265,7 +265,7 @@ func (mklines *MkLinesImpl) collectDefin
        mklines.ForEach(func(mkline MkLine) {
                mklines.Tools.ParseToolLine(mklines, mkline, false, true)
 
-               if !mkline.IsVarassign() {
+               if !mkline.IsVarassign() && !mkline.IsCommentedVarassign() {
                        return
                }
 

Index: pkgsrc/pkgtools/pkglint/files/mklines_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.41 pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.42
--- pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.41  Sat Apr 20 17:43:24 2019
+++ pkgsrc/pkgtools/pkglint/files/mklines_test.go       Sat Apr 27 19:33:57 2019
@@ -325,6 +325,8 @@ func (s *Suite) Test_MkLines_collectDefi
                "SUBST_VARS.subst=       SUV",
                "SUV=                    value for substitution",
                "",
+               "#BUILD_DEFS+=           VARBASE",
+               "",
                "pre-configure:",
                "\t${RUN} autoreconf; autoheader-2.13",
                "\t${ECHO} ${OSV:Q}")

Index: pkgsrc/pkgtools/pkglint/files/mkparser_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mkparser_test.go:1.28 pkgsrc/pkgtools/pkglint/files/mkparser_test.go:1.29
--- pkgsrc/pkgtools/pkglint/files/mkparser_test.go:1.28 Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/mkparser_test.go      Sat Apr 27 19:33:57 2019
@@ -528,6 +528,14 @@ func (s *Suite) Test_MkParser_MkCond(c *
        test("${\"${PKG_OPTIONS:Moption}\":?--enable-option:--disable-option}",
                &mkCond{Var: varuse("\"${PKG_OPTIONS:Moption}\"", "?--enable-option:--disable-option")})
 
+       // Contrary to most other programming languages, the == operator binds
+       // more tightly that the ! operator.
+       //
+       // TODO: Since this operator precedence is surprising there should be a warning,
+       //  suggesting to replace "!${VAR} == value" with "${VAR} != value".
+       test("!${VAR} == value",
+               &mkCond{Not: &mkCond{CompareVarStr: &MkCondCompareVarStr{varuse("VAR"), "==", "value"}}})
+
        // Errors
 
        testRest("!empty(PKG_OPTIONS:Msndfile) || defined(PKG_OPTIONS:Msamplerate)",

Index: pkgsrc/pkgtools/pkglint/files/package_test.go
diff -u pkgsrc/pkgtools/pkglint/files/package_test.go:1.44 pkgsrc/pkgtools/pkglint/files/package_test.go:1.45
--- pkgsrc/pkgtools/pkglint/files/package_test.go:1.44  Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/package_test.go       Sat Apr 27 19:33:57 2019
@@ -477,7 +477,6 @@ func (s *Suite) Test_Package_loadPackage
        t := s.Init(c)
 
        t.SetUpCommandLine("--dumpmakefile")
-       t.SetUpVartypes()
        t.SetUpPkgsrc()
        t.CreateFileLines("category/Makefile")
        t.CreateFileLines("category/package/PLIST",
@@ -682,7 +681,6 @@ func (s *Suite) Test_Package_loadPackage
 func (s *Suite) Test_Package_checkIncludeConditionally__conditional_and_unconditional_include(c *check.C) {
        t := s.Init(c)
 
-       t.SetUpVartypes()
        t.SetUpOption("zlib", "")
        t.SetUpPackage("category/package",
                ".include \"../../devel/zlib/buildlink3.mk\"",
@@ -718,7 +716,6 @@ func (s *Suite) Test_Package_checkInclud
 func (s *Suite) Test_Package__include_without_exists(c *check.C) {
        t := s.Init(c)
 
-       t.SetUpVartypes()
        t.SetUpPackage("category/package",
                ".include \"options.mk\"")
        t.FinishSetUp()
@@ -733,7 +730,6 @@ func (s *Suite) Test_Package__include_wi
 func (s *Suite) Test_Package__include_after_exists(c *check.C) {
        t := s.Init(c)
 
-       t.SetUpVartypes()
        t.SetUpPackage("category/package",
                ".if exists(options.mk)",
                ".  include \"options.mk\"",
@@ -750,7 +746,6 @@ func (s *Suite) Test_Package__include_af
 func (s *Suite) Test_Package_readMakefile__include_other_after_exists(c *check.C) {
        t := s.Init(c)
 
-       t.SetUpVartypes()
        t.SetUpPackage("category/package",
                ".if exists(options.mk)",
                ".  include \"another.mk\"",
Index: pkgsrc/pkgtools/pkglint/files/shell_test.go
diff -u pkgsrc/pkgtools/pkglint/files/shell_test.go:1.44 pkgsrc/pkgtools/pkglint/files/shell_test.go:1.45
--- pkgsrc/pkgtools/pkglint/files/shell_test.go:1.44    Sat Apr 20 17:43:24 2019
+++ pkgsrc/pkgtools/pkglint/files/shell_test.go Sat Apr 27 19:33:57 2019
@@ -159,9 +159,6 @@ func (s *Suite) Test_ShellLineChecker_Ch
                "WARN: filename.mk:1: Please switch to \"set -e\" mode "+
                        "before using a semicolon (after \"uname=`uname`\") to separate commands.")
 
-       t.SetUpTool("echo", "", AtRunTime)
-       t.SetUpVartypes()
-
        test("echo ${PKGNAME:Q}", // VucQuotPlain
                "NOTE: filename.mk:1: The :Q operator isn't necessary for ${PKGNAME} here.")
 

Index: pkgsrc/pkgtools/pkglint/files/pkglint.go
diff -u pkgsrc/pkgtools/pkglint/files/pkglint.go:1.52 pkgsrc/pkgtools/pkglint/files/pkglint.go:1.53
--- pkgsrc/pkgtools/pkglint/files/pkglint.go:1.52       Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/pkglint.go    Sat Apr 27 19:33:57 2019
@@ -714,7 +714,7 @@ func (pkglint *Pkglint) checkExecutable(
                fix.Describef(0, "Clearing executable bits")
                if autofix {
                        if err := os.Chmod(filename, mode&^0111); err != nil {
-                               line.Errorf("Cannot clear executable bits: %s", err)
+                               G.Logger.Errorf(cleanpath(filename), "Cannot clear executable bits: %s", err)
                        }
                }
        })

Index: pkgsrc/pkgtools/pkglint/files/pkgsrc.go
diff -u pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.24 pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.25
--- pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.24        Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/pkgsrc.go     Sat Apr 27 19:33:57 2019
@@ -348,12 +348,21 @@ func (src *Pkgsrc) loadUntypedVars() {
 
        define := func(varcanon string, mkline MkLine) {
                switch {
-               case
-                       src.vartypes.DefinedCanon(varcanon),  // Already defined
-                       src.Tools.ByVarname(varcanon) != nil, // Already known as a tool
-                       hasPrefix(varcanon, "_"),             // Skip internal variables
-                       contains(varcanon, "$"),              // Indirect or parameterized
-                       hasSuffix(varcanon, "_MK"):           // Multiple-inclusion guard
+               case src.vartypes.DefinedCanon(varcanon):
+                       // Already defined, can also be a tool.
+
+               case hasPrefix(varcanon, "_"):
+                       // Variables starting with an underscore are reserved for the
+                       // infrastructure and are not available for use by packages.
+
+               case contains(varcanon, "$"):
+                       // Indirect, but not the usual parameterized form. Variables of
+                       // this form should not be unintentionally visible from outside
+                       // the infrastructure since they don't follow the pkgsrc naming
+                       // conventions.
+
+               case hasSuffix(varcanon, "_MK"):
+                       // Multiple-inclusion guards are internal to the infrastructure.
 
                default:
                        if trace.Tracing {
@@ -598,7 +607,7 @@ func (src *Pkgsrc) loadUserDefinedVars()
        mklines := src.LoadMk("mk/defaults/mk.conf", MustSucceed|NotEmpty)
 
        for _, mkline := range mklines.mklines {
-               if mkline.IsVarassign() { // TODO: What about mkline.IsCommentedVarassign?
+               if mkline.IsVarassign() || mkline.IsCommentedVarassign() {
                        src.UserDefinedVars.Define(mkline.Varname(), mkline)
                }
        }

Index: pkgsrc/pkgtools/pkglint/files/util.go
diff -u pkgsrc/pkgtools/pkglint/files/util.go:1.42 pkgsrc/pkgtools/pkglint/files/util.go:1.43
--- pkgsrc/pkgtools/pkglint/files/util.go:1.42  Sat Apr 20 17:43:25 2019
+++ pkgsrc/pkgtools/pkglint/files/util.go       Sat Apr 27 19:33:57 2019
@@ -516,10 +516,10 @@ func (s *Scope) Define(varname string, m
                s.lastDef[name] = mkline
 
                // In most cases the defining lines are indeed variable assignments.
-               // Exceptions are comments that only document the variable but still mark
-               // it as defined so that it doesn't produce the "used but not defined" warning.
-               if mkline.IsVarassign() || mkline.IsCommentedVarassign() {
-
+               // Exceptions are comments from documentation sections, which still mark
+               // it as defined so that it doesn't produce the "used but not defined" warning;
+               // see MkLines.collectDocumentedVariables.
+               if mkline.IsVarassign() {
                        switch mkline.Op() {
                        case opAssign, opAssignEval, opAssignShell:
                                s.value[name] = mkline.Value()
@@ -560,18 +560,27 @@ func (s *Scope) Use(varname string, line
        use(varnameCanon(varname))
 }
 
+// Mentioned returns the first line in which the variable is either:
+//  - defined,
+//  - mentioned in a commented variable assignment,
+//  - mentioned in a documentation comment.
+func (s *Scope) Mentioned(varname string) MkLine {
+       return s.firstDef[varname]
+}
+
 // Defined tests whether the variable is defined.
 // It does NOT test the canonicalized variable name.
 //
 // Even if Defined returns true, FirstDefinition doesn't necessarily return true
 // since the latter ignores the default definitions from vardefs.go, keyword dummyVardefMkline.
 func (s *Scope) Defined(varname string) bool {
-       return s.firstDef[varname] != nil
+       mkline := s.firstDef[varname]
+       return mkline != nil && mkline.IsVarassign()
 }
 
 // DefinedSimilar tests whether the variable or its canonicalized form is defined.
 func (s *Scope) DefinedSimilar(varname string) bool {
-       if s.firstDef[varname] != nil {
+       if s.Defined(varname) {
                if trace.Tracing {
                        trace.Step1("Variable %q is defined", varname)
                }
@@ -579,7 +588,7 @@ func (s *Scope) DefinedSimilar(varname s
        }
 
        varcanon := varnameCanon(varname)
-       if s.firstDef[varcanon] != nil {
+       if s.Defined(varcanon) {
                if trace.Tracing {
                        trace.Step2("Variable %q (similar to %q) is defined", varcanon, varname)
                }
@@ -611,6 +620,11 @@ func (s *Scope) UsedAtLoadTime(varname s
 // FirstDefinition returns the line in which the variable has been defined first.
 //
 // Having multiple definitions is typical in the branches of "if" statements.
+//
+// Another typical case involves two files: the included file defines a default
+// value, and the including file later overrides that value. Or the other way
+// round: the including file sets a value first, and the included file then
+// assigns a default value using ?=.
 func (s *Scope) FirstDefinition(varname string) MkLine {
        mkline := s.firstDef[varname]
        if mkline != nil && mkline.IsVarassign() {
@@ -629,7 +643,9 @@ func (s *Scope) FirstDefinition(varname 
 // Having multiple definitions is typical in the branches of "if" statements.
 //
 // Another typical case involves two files: the included file defines a default
-// value, and the including file later overrides that value.
+// value, and the including file later overrides that value. Or the other way
+// round: the including file sets a value first, and the included file then
+// assigns a default value using ?=.
 func (s *Scope) LastDefinition(varname string) MkLine {
        mkline := s.lastDef[varname]
        if mkline != nil && mkline.IsVarassign() {
@@ -638,6 +654,33 @@ func (s *Scope) LastDefinition(varname s
        return nil // See NewPackage and G.Pkgsrc.UserDefinedVars
 }
 
+// Commented returns whether the variable has only been defined in commented
+// variable assignments. These are ignored by bmake but used heavily in
+// mk/defaults/mk.conf for documentation.
+func (s *Scope) Commented(varname string) MkLine {
+       var mklines []MkLine
+       if first := s.firstDef[varname]; first != nil {
+               mklines = append(mklines, first)
+       }
+       if last := s.lastDef[varname]; last != nil {
+               mklines = append(mklines, last)
+       }
+
+       for _, mkline := range mklines {
+               if mkline != nil && mkline.IsVarassign() {
+                       return nil
+               }
+       }
+
+       for _, mkline := range mklines {
+               if mkline != nil && mkline.IsCommentedVarassign() {
+                       return mkline
+               }
+       }
+
+       return nil
+}
+
 func (s *Scope) FirstUse(varname string) MkLine {
        return s.used[varname]
 }

Index: pkgsrc/pkgtools/pkglint/files/util_test.go
diff -u pkgsrc/pkgtools/pkglint/files/util_test.go:1.27 pkgsrc/pkgtools/pkglint/files/util_test.go:1.28
--- pkgsrc/pkgtools/pkglint/files/util_test.go:1.27     Sat Apr 20 17:43:25 2019
+++ pkgsrc/pkgtools/pkglint/files/util_test.go  Sat Apr 27 19:33:57 2019
@@ -462,6 +462,61 @@ func (s *Suite) Test_Scope__no_tracing(c
        t.Check(scope.DefinedSimilar("OTHER"), equals, false)
 }
 
+func (s *Suite) Test_Scope__commented_varassign(c *check.C) {
+       t := s.Init(c)
+
+       mkline := t.NewMkLine("mk/defaults/mk.conf", 3, "#VAR=default")
+       scope := NewScope()
+       scope.Define("VAR", mkline)
+
+       t.Check(scope.Defined("VAR"), equals, false)
+       t.Check(scope.FirstDefinition("VAR"), check.IsNil)
+       t.Check(scope.LastDefinition("VAR"), check.IsNil)
+
+       t.Check(scope.Mentioned("VAR"), equals, mkline)
+       t.Check(scope.Commented("VAR"), equals, mkline)
+
+       value, found := scope.LastValueFound("VAR")
+       t.Check(value, equals, "")
+       t.Check(found, equals, false)
+}
+
+func (s *Suite) Test_Scope_Commented(c *check.C) {
+       t := s.Init(c)
+
+       assigned := t.NewMkLine("filename.mk", 3, "VAR=\tvalue")
+       commented := t.NewMkLine("filename.mk", 4, "#COMMENTED=\tvalue")
+       documented := t.NewMkLine("filename.mk", 5, "# DOCUMENTED is a variable.")
+
+       scope := NewScope()
+       scope.Define("VAR", assigned)
+       scope.Define("COMMENTED", commented)
+       scope.Define("DOCUMENTED", documented)
+
+       t.Check(scope.Commented("VAR"), check.IsNil)
+       t.Check(scope.Commented("COMMENTED"), equals, commented)
+       t.Check(scope.Commented("DOCUMENTED"), check.IsNil)
+       t.Check(scope.Commented("UNKNOWN"), check.IsNil)
+}
+
+func (s *Suite) Test_Scope_Mentioned(c *check.C) {
+       t := s.Init(c)
+
+       assigned := t.NewMkLine("filename.mk", 3, "VAR=\tvalue")
+       commented := t.NewMkLine("filename.mk", 4, "#COMMENTED=\tvalue")
+       documented := t.NewMkLine("filename.mk", 5, "# DOCUMENTED is a variable.")
+
+       scope := NewScope()
+       scope.Define("VAR", assigned)
+       scope.Define("COMMENTED", commented)
+       scope.Define("DOCUMENTED", documented)
+
+       t.Check(scope.Mentioned("VAR"), equals, assigned)
+       t.Check(scope.Mentioned("COMMENTED"), equals, commented)
+       t.Check(scope.Mentioned("DOCUMENTED"), equals, documented)
+       t.Check(scope.Mentioned("UNKNOWN"), check.IsNil)
+}
+
 func (s *Suite) Test_naturalLess(c *check.C) {
        c.Check(naturalLess("", "a"), equals, true)
        c.Check(naturalLess("a", ""), equals, false)

Index: pkgsrc/pkgtools/pkglint/files/vardefs.go
diff -u pkgsrc/pkgtools/pkglint/files/vardefs.go:1.60 pkgsrc/pkgtools/pkglint/files/vardefs.go:1.61
--- pkgsrc/pkgtools/pkglint/files/vardefs.go:1.60       Tue Apr 23 21:20:49 2019
+++ pkgsrc/pkgtools/pkglint/files/vardefs.go    Sat Apr 27 19:33:57 2019
@@ -99,7 +99,10 @@ func (reg *VarTypeRegistry) Init(src *Pk
        //  - how this individual permission set differs
        //  - why the predefined permission set is not good enough
        //  - which packages need this custom permission set.
-       acl := reg.DefineParse
+       acl := func(varname string, basicType *BasicType, options vartypeOptions, aclEntries ...string) {
+               G.Assertf(!reg.DefinedExact(varname), "Variable %q must only be defined once.", varname)
+               reg.DefineParse(varname, basicType, options, aclEntries...)
+       }
 
        // acllist defines the permissions of a list variable by listing
        // the permissions individually.
@@ -110,7 +113,7 @@ func (reg *VarTypeRegistry) Init(src *Pk
        //  - why the predefined permission set is not good enough
        //  - which packages need this custom permission set.
        acllist := func(varname string, basicType *BasicType, options vartypeOptions, aclEntries ...string) {
-               reg.DefineParse(varname, basicType, options|List, aclEntries...)
+               acl(varname, basicType, options|List, aclEntries...)
        }
 
        // A package-settable variable may be set in all Makefiles except buildlink3.mk and builtin.mk.
@@ -123,7 +126,7 @@ func (reg *VarTypeRegistry) Init(src *Pk
 
        // pkgload is the same as pkg, except that the variable may be accessed at load time.
        pkgload := func(varname string, basicType *BasicType) {
-               reg.DefineParse(varname, basicType,
+               acl(varname, basicType,
                        PackageSettable,
                        "buildlink3.mk: none",
                        "builtin.mk: use, use-loadtime",
@@ -169,14 +172,14 @@ func (reg *VarTypeRegistry) Init(src *Pk
        // These variables are typically related to compiling and linking files
        // from C and related languages.
        pkgbl3 := func(varname string, basicType *BasicType) {
-               reg.DefineParse(varname, basicType,
+               acl(varname, basicType,
                        PackageSettable,
                        "Makefile, Makefile.*, *.mk: default, set, use")
        }
        // Some package-defined lists may also be modified in buildlink3.mk files,
        // for example platform-specific CFLAGS and LDFLAGS.
        pkglistbl3 := func(varname string, basicType *BasicType) {
-               reg.DefineParse(varname, basicType,
+               acl(varname, basicType,
                        List|PackageSettable,
                        "Makefile, Makefile.*, *.mk: default, set, append, use")
        }
@@ -228,15 +231,34 @@ func (reg *VarTypeRegistry) Init(src *Pk
                        "*: use, use-loadtime")
        }
 
+       // A few variables from mk/defaults/mk.conf may be overridden by packages.
+       // Therefore they need a separate definition of "user-settable".
+       //
+       // It is debatable whether packages should be allowed to override these
+       // variables at all since then there are two competing sources for the
+       // default values. Current practice is to have exactly this ambiguity,
+       // combined with some package Makefiles including bsd.prefs.mk and others
+       // omitting this necessary inclusion.
+       //
+       // TODO: parse all the below information directly from mk/defaults/mk.conf.
+       usrpkg := func(varname string, basicType *BasicType) {
+               acl(varname, basicType,
+                       PackageSettable|UserSettable,
+                       "Makefile: default, set, use, use-loadtime",
+                       "buildlink3.mk, builtin.mk: none",
+                       "Makefile.*, *.mk: default, set, use, use-loadtime",
+                       "*: use, use-loadtime")
+       }
+
        // sysload declares a system-provided variable that may already be used at load time.
        sysload := func(varname string, basicType *BasicType) {
-               reg.DefineParse(varname, basicType,
+               acl(varname, basicType,
                        SystemProvided,
                        "*: use, use-loadtime")
        }
 
        sysloadlist := func(varname string, basicType *BasicType) {
-               reg.DefineParse(varname, basicType,
+               acl(varname, basicType,
                        List|SystemProvided,
                        "*: use, use-loadtime")
        }
@@ -244,7 +266,7 @@ func (reg *VarTypeRegistry) Init(src *Pk
        // bl3list declares a list variable that is defined by buildlink3.mk and
        // builtin.mk and can later be used by the package.
        bl3list := func(varname string, basicType *BasicType) {
-               reg.DefineParse(varname, basicType,
+               acl(varname, basicType,
                        List, // not PackageSettable since the package uses it more than setting it.
                        "buildlink3.mk, builtin.mk: append",
                        "*: use")
@@ -253,7 +275,7 @@ func (reg *VarTypeRegistry) Init(src *Pk
        // cmdline declares a variable that is defined on the command line. There
        // are only few variables of this type, such as PKG_DEBUG_LEVEL.
        cmdline := func(varname string, basicType *BasicType) {
-               reg.DefineParse(varname, basicType,
+               acl(varname, basicType,
                        CommandLineProvided,
                        "buildlink3.mk, builtin.mk: none",
                        "*: use, use-loadtime")
@@ -466,11 +488,6 @@ func (reg *VarTypeRegistry) Init(src *Pk
        usr("DIST_PATH", BtPathlist)
        usr("DEFAULT_VIEW", BtUnknown) // XXX: deprecate? pkgviews has been removed
        usr("FETCH_CMD", BtShellCommand)
-       usr("FETCH_USING", enum("auto curl custom fetch ftp manual wget"))
-       usrlist("FETCH_BEFORE_ARGS", BtShellWord)
-       usrlist("FETCH_AFTER_ARGS", BtShellWord)
-       usrlist("FETCH_RESUME_ARGS", BtShellWord)
-       usrlist("FETCH_OUTPUT_ARGS", BtShellWord)
        usr("FIX_SYSTEM_HEADERS", BtYes)
        usr("LIBTOOLIZE_PLIST", BtYesNo)
        usr("PKG_RESUME_TRANSFERS", BtYesNo)
@@ -486,12 +503,10 @@ func (reg *VarTypeRegistry) Init(src *Pk
        usrlist("HOST_SPECIFIC_PKGS", BtPkgPath)
        usrlist("GROUP_SPECIFIC_PKGS", BtPkgPath)
        usrlist("USER_SPECIFIC_PKGS", BtPkgPath)
-       usr("EXTRACT_USING", enum("bsdtar gtar nbtar pax"))
        usr("FAILOVER_FETCH", BtYes)
        usrlist("MASTER_SORT", BtUnknown)
        usrlist("MASTER_SORT_REGEX", BtUnknown)
        usr("MASTER_SORT_RANDOM", BtYes)
-       usr("PATCH_DEBUG", BtYes)
        usr("PKG_FC", BtShellCommand)
        usrlist("IMAKEOPTS", BtShellWord)
        usr("PRE_ROOT_CMD", BtShellCommand)
@@ -504,248 +519,227 @@ func (reg *VarTypeRegistry) Init(src *Pk
        usrlist("BIN_INSTALL_FLAGS", BtShellWord)
        usr("LOCALPATCHES", BtPathname)
 
-       // The remaining variables from mk/defaults/mk.conf may be overridden by packages.
-       // Therefore they need a separate definition of "user-settable".
-       //
-       // It is debatable whether packages should be allowed to override these
-       // variables at all since then there are two competing sources for the
-       // default values. Current practice is to have exactly this ambiguity,
-       // combined with some package Makefiles including bsd.prefs.mk and others
-       // omitting this necessary inclusion.
-       //
-       // TODO: parse all the below information directly from mk/defaults/mk.conf.
-       usrpkg := func(varname string, basicType *BasicType) {
-               acl(varname, basicType,
-                       PackageSettable|UserSettable,
-                       "Makefile: default, set, use, use-loadtime",
-                       "buildlink3.mk, builtin.mk: none",
-                       "Makefile.*, *.mk: default, set, use, use-loadtime",
-                       "*: use, use-loadtime")
-       }
-       usrpkglist := func(varname string, basicType *BasicType) {
-               acllist(varname, basicType,
-                       List|PackageSettable|UserSettable,
-                       "Makefile: default, set, use, use-loadtime",
-                       "buildlink3.mk, builtin.mk: none",
-                       "Makefile.*, *.mk: default, set, use, use-loadtime",
-                       "*: use, use-loadtime")
-       }
-
-       usrpkg("ACROREAD_FONTPATH", BtPathlist)
-       usrpkg("AMANDA_USER", BtUserGroupName)
-       usrpkg("AMANDA_TMP", BtPathname)
-       usrpkg("AMANDA_VAR", BtPathname)
-       usrpkg("APACHE_USER", BtUserGroupName)
-       usrpkg("APACHE_GROUP", BtUserGroupName)
-       usrpkglist("APACHE_SUEXEC_CONFIGURE_ARGS", BtShellWord)
-       usrpkglist("APACHE_SUEXEC_DOCROOT", BtPathname)
-       usrpkg("ARLA_CACHE", BtPathname)
-       usrpkg("BIND_DIR", BtPathname)
-       usrpkg("BIND_GROUP", BtUserGroupName)
-       usrpkg("BIND_USER", BtUserGroupName)
-       usrpkg("CACTI_GROUP", BtUserGroupName)
-       usrpkg("CACTI_USER", BtUserGroupName)
-       usrpkg("CANNA_GROUP", BtUserGroupName)
-       usrpkg("CANNA_USER", BtUserGroupName)
-       usrpkg("CDRECORD_CONF", BtPathname)
-       usrpkg("CLAMAV_GROUP", BtUserGroupName)
-       usrpkg("CLAMAV_USER", BtUserGroupName)
-       usrpkg("CLAMAV_DBDIR", BtPathname)
-       usrpkg("CONSERVER_DEFAULTHOST", BtIdentifier)
-       usrpkg("CONSERVER_DEFAULTPORT", BtInteger)
-       usrpkg("CUPS_GROUP", BtUserGroupName)
-       usrpkg("CUPS_USER", BtUserGroupName)
-       usrpkglist("CUPS_SYSTEM_GROUPS", BtUserGroupName)
-       usrpkg("CYRUS_IDLE", enum("poll idled no"))
-       usrpkg("CYRUS_GROUP", BtUserGroupName)
-       usrpkg("CYRUS_USER", BtUserGroupName)
-       usrpkg("DAEMONTOOLS_LOG_USER", BtUserGroupName)
-       usrpkg("DAEMONTOOLS_GROUP", BtUserGroupName)
-       usrpkg("DBUS_GROUP", BtUserGroupName)
-       usrpkg("DBUS_USER", BtUserGroupName)
-       usrpkg("DEFANG_GROUP", BtUserGroupName)
-       usrpkg("DEFANG_USER", BtUserGroupName)
-       usrpkg("DEFANG_SPOOLDIR", BtPathname)
-       usrpkg("DEFAULT_IRC_SERVER", BtIdentifier)
-       usrpkg("DEFAULT_SERIAL_DEVICE", BtPathname)
-       usrpkg("DIALER_GROUP", BtUserGroupName)
-       usrpkg("DJBDNS_AXFR_USER", BtUserGroupName)
-       usrpkg("DJBDNS_CACHE_USER", BtUserGroupName)
-       usrpkg("DJBDNS_LOG_USER", BtUserGroupName)
-       usrpkg("DJBDNS_RBL_USER", BtUserGroupName)
-       usrpkg("DJBDNS_TINY_USER", BtUserGroupName)
-       usrpkg("DJBDNS_DJBDNS_GROUP", BtUserGroupName)
-       usrpkg("DT_LAYOUT", enum("US FI FR GER DV"))
-       usrpkglist("ELK_GUI", enum("none xaw motif"))
-       usrpkg("EMACS_TYPE", emacsVersions)
-       usrpkg("EXIM_GROUP", BtUserGroupName)
-       usrpkg("EXIM_USER", BtUserGroupName)
-       usrpkg("FLUXBOX_USE_XINERAMA", enum("YES NO"))
-       usrpkg("FLUXBOX_USE_KDE", enum("YES NO"))
-       usrpkg("FLUXBOX_USE_GNOME", enum("YES NO"))
-       usrpkg("FLUXBOX_USE_XFT", enum("YES NO"))
-       usrpkg("FOX_USE_XUNICODE", enum("YES NO"))
-       usrpkg("FREEWNN_USER", BtUserGroupName)
-       usrpkg("FREEWNN_GROUP", BtUserGroupName)
-       usrpkg("GAMES_USER", BtUserGroupName)
-       usrpkg("GAMES_GROUP", BtUserGroupName)
-       usrpkg("GAMEMODE", BtFileMode)
-       usrpkg("GAMEDIRMODE", BtFileMode)
-       usrpkg("GAMEDATAMODE", BtFileMode)
-       usrpkg("GAMEGRP", BtUserGroupName)
-       usrpkg("GAMEOWN", BtUserGroupName)
-       usrpkg("GRUB_NETWORK_CARDS", BtIdentifier)
-       usrpkg("GRUB_PRESET_COMMAND", enum("bootp dhcp rarp"))
-       usrpkglist("GRUB_SCAN_ARGS", BtShellWord)
-       usrpkg("HASKELL_COMPILER", enum("ghc"))
-       usrpkg("HOWL_GROUP", BtUserGroupName)
-       usrpkg("HOWL_USER", BtUserGroupName)
-       usrpkg("ICECAST_CHROOTDIR", BtPathname)
-       usrpkg("ICECAST_CHUNKLEN", BtInteger)
-       usrpkg("ICECAST_SOURCE_BUFFSIZE", BtInteger)
-       usrpkg("IMAP_UW_CCLIENT_MBOX_FMT",
+       usr("ACROREAD_FONTPATH", BtPathlist)
+       usr("AMANDA_USER", BtUserGroupName)
+       usr("AMANDA_TMP", BtPathname)
+       usr("AMANDA_VAR", BtPathname)
+       usr("APACHE_USER", BtUserGroupName)
+       usr("APACHE_GROUP", BtUserGroupName)
+       usrlist("APACHE_SUEXEC_CONFIGURE_ARGS", BtShellWord)
+       usrlist("APACHE_SUEXEC_DOCROOT", BtPathname)
+       usr("ARLA_CACHE", BtPathname)
+       usr("BIND_DIR", BtPathname)
+       usr("BIND_GROUP", BtUserGroupName)
+       usr("BIND_USER", BtUserGroupName)
+       usr("CACTI_GROUP", BtUserGroupName)
+       usr("CACTI_USER", BtUserGroupName)
+       usr("CANNA_GROUP", BtUserGroupName)
+       usr("CANNA_USER", BtUserGroupName)
+       usr("CDRECORD_CONF", BtPathname)
+       usr("CLAMAV_GROUP", BtUserGroupName)
+       usr("CLAMAV_USER", BtUserGroupName)
+       usr("CLAMAV_DBDIR", BtPathname)
+       usr("CONSERVER_DEFAULTHOST", BtIdentifier)
+       usr("CONSERVER_DEFAULTPORT", BtInteger)
+       usr("CUPS_GROUP", BtUserGroupName)
+       usr("CUPS_USER", BtUserGroupName)
+       usrlist("CUPS_SYSTEM_GROUPS", BtUserGroupName)
+       usr("CYRUS_IDLE", enum("poll idled no"))
+       usr("CYRUS_GROUP", BtUserGroupName)
+       usr("CYRUS_USER", BtUserGroupName)
+       usr("DAEMONTOOLS_LOG_USER", BtUserGroupName)
+       usr("DAEMONTOOLS_GROUP", BtUserGroupName)
+       usr("DBUS_GROUP", BtUserGroupName)
+       usr("DBUS_USER", BtUserGroupName)
+       usr("DEFANG_GROUP", BtUserGroupName)
+       usr("DEFANG_USER", BtUserGroupName)
+       usr("DEFANG_SPOOLDIR", BtPathname)
+       usr("DEFAULT_IRC_SERVER", BtIdentifier)
+       usr("DEFAULT_SERIAL_DEVICE", BtPathname)
+       usr("DIALER_GROUP", BtUserGroupName)
+       usr("DJBDNS_AXFR_USER", BtUserGroupName)
+       usr("DJBDNS_CACHE_USER", BtUserGroupName)
+       usr("DJBDNS_LOG_USER", BtUserGroupName)
+       usr("DJBDNS_RBL_USER", BtUserGroupName)
+       usr("DJBDNS_TINY_USER", BtUserGroupName)
+       usr("DJBDNS_DJBDNS_GROUP", BtUserGroupName)
+       usr("DT_LAYOUT", enum("US FI FR GER DV"))
+       usrlist("ELK_GUI", enum("none xaw motif"))
+       usr("EMACS_TYPE", emacsVersions)
+       usr("EXIM_GROUP", BtUserGroupName)
+       usr("EXIM_USER", BtUserGroupName)
+       usrpkg("EXTRACT_USING", enum("bsdtar gtar nbtar pax"))
+       usrlist("FETCH_BEFORE_ARGS", BtShellWord)
+       usrlist("FETCH_AFTER_ARGS", BtShellWord)
+       usrlist("FETCH_RESUME_ARGS", BtShellWord)
+       usrlist("FETCH_OUTPUT_ARGS", BtShellWord)
+       usrpkg("FETCH_USING", enum("auto curl custom fetch ftp manual wget"))
+       usr("FLUXBOX_USE_XINERAMA", enum("YES NO"))
+       usr("FLUXBOX_USE_KDE", enum("YES NO"))
+       usr("FLUXBOX_USE_GNOME", enum("YES NO"))
+       usr("FLUXBOX_USE_XFT", enum("YES NO"))
+       usr("FOX_USE_XUNICODE", enum("YES NO"))
+       usr("FREEWNN_USER", BtUserGroupName)
+       usr("FREEWNN_GROUP", BtUserGroupName)
+       usr("GAMES_USER", BtUserGroupName)
+       usr("GAMES_GROUP", BtUserGroupName)
+       usr("GAMEMODE", BtFileMode)
+       usr("GAMEDIRMODE", BtFileMode)
+       usr("GAMEDATAMODE", BtFileMode)
+       usr("GAMEGRP", BtUserGroupName)
+       usr("GAMEOWN", BtUserGroupName)
+       usr("GRUB_NETWORK_CARDS", BtIdentifier)
+       usr("GRUB_PRESET_COMMAND", enum("bootp dhcp rarp"))
+       usrlist("GRUB_SCAN_ARGS", BtShellWord)
+       usr("HASKELL_COMPILER", enum("ghc"))
+       usr("HOWL_GROUP", BtUserGroupName)
+       usr("HOWL_USER", BtUserGroupName)
+       usr("ICECAST_CHROOTDIR", BtPathname)
+       usr("ICECAST_CHUNKLEN", BtInteger)
+       usr("ICECAST_SOURCE_BUFFSIZE", BtInteger)
+       usr("IMAP_UW_CCLIENT_MBOX_FMT",
                enum("mbox mbx mh mmdf mtx mx news phile tenex unix"))
-       usrpkg("IMAP_UW_MAILSPOOLHOME", BtFileName)
-       usrpkg("IMDICTDIR", BtPathname)
-       usrpkg("INN_DATA_DIR", BtPathname)
-       usrpkg("INN_USER", BtUserGroupName)
-       usrpkg("INN_GROUP", BtUserGroupName)
-       usrpkg("IRCD_HYBRID_NICLEN", BtInteger)
-       usrpkg("IRCD_HYBRID_TOPICLEN", BtInteger)
-       usrpkg("IRCD_HYBRID_SYSLOG_EVENTS", BtUnknown)
-       usrpkg("IRCD_HYBRID_SYSLOG_FACILITY", BtIdentifier)
-       usrpkg("IRCD_HYBRID_MAXCONN", BtInteger)
-       usrpkg("IRCD_HYBRID_IRC_USER", BtUserGroupName)
-       usrpkg("IRCD_HYBRID_IRC_GROUP", BtUserGroupName)
-       usrpkg("IRRD_USE_PGP", enum("5 2"))
-       usrpkg("JABBERD_USER", BtUserGroupName)
-       usrpkg("JABBERD_GROUP", BtUserGroupName)
-       usrpkg("JABBERD_LOGDIR", BtPathname)
-       usrpkg("JABBERD_SPOOLDIR", BtPathname)
-       usrpkg("JABBERD_PIDDIR", BtPathname)
-       usrpkg("JAKARTA_HOME", BtPathname)
-       usrpkg("KERBEROS", BtYes)
-       usrpkg("KERMIT_SUID_UUCP", BtYes)
-       usrpkg("KJS_USE_PCRE", BtYes)
-       usrpkg("KNEWS_DOMAIN_FILE", BtPathname)
-       usrpkg("KNEWS_DOMAIN_NAME", BtIdentifier)
-       usrpkg("LIBDVDCSS_HOMEPAGE", BtHomepage)
-       usrpkglist("LIBDVDCSS_MASTER_SITES", BtFetchURL)
-       usrpkg("LIBUSB_TYPE", enum("compat native"))
-       usrpkg("LATEX2HTML_ICONPATH", BtURL)
-       usrpkg("LEAFNODE_DATA_DIR", BtPathname)
-       usrpkg("LEAFNODE_USER", BtUserGroupName)
-       usrpkg("LEAFNODE_GROUP", BtUserGroupName)
-       usrpkglist("LINUX_LOCALES", BtIdentifier)
-       usrpkg("MAILAGENT_DOMAIN", BtIdentifier)
-       usrpkg("MAILAGENT_EMAIL", BtMailAddress)
-       usrpkg("MAILAGENT_FQDN", BtIdentifier)
-       usrpkg("MAILAGENT_ORGANIZATION", BtUnknown)
-       usrpkg("MAJORDOMO_HOMEDIR", BtPathname)
-       usrpkglist("MAKEINFO_ARGS", BtShellWord)
-       usrpkg("MECAB_CHARSET", BtIdentifier)
-       usrpkg("MEDIATOMB_GROUP", BtUserGroupName)
-       usrpkg("MEDIATOMB_USER", BtUserGroupName)
-       usrpkg("MIREDO_USER", BtUserGroupName)
-       usrpkg("MIREDO_GROUP", BtUserGroupName)
-       usrpkg("MLDONKEY_GROUP", BtUserGroupName)
-       usrpkg("MLDONKEY_HOME", BtPathname)
-       usrpkg("MLDONKEY_USER", BtUserGroupName)
-       usrpkg("MONOTONE_GROUP", BtUserGroupName)
-       usrpkg("MONOTONE_USER", BtUserGroupName)
-       usrpkg("MOTIF_TYPE", enum("motif openmotif lesstif dt"))
-       usrpkg("MOTIF_TYPE_DEFAULT", enum("motif openmotif lesstif dt"))
-       usrpkg("MTOOLS_ENABLE_FLOPPYD", BtYesNo)
-       usrpkg("MYSQL_USER", BtUserGroupName)
-       usrpkg("MYSQL_GROUP", BtUserGroupName)
-       usrpkg("MYSQL_DATADIR", BtPathname)
-       usrpkg("MYSQL_CHARSET", BtIdentifier)
-       usrpkglist("MYSQL_EXTRA_CHARSET", BtIdentifier)
-       usrpkg("NAGIOS_GROUP", BtUserGroupName)
-       usrpkg("NAGIOS_USER", BtUserGroupName)
-       usrpkg("NAGIOSCMD_GROUP", BtUserGroupName)
-       usrpkg("NAGIOSDIR", BtPathname)
-       usrpkg("NBPAX_PROGRAM_PREFIX", BtUnknown)
-       usrpkg("NMH_EDITOR", BtIdentifier)
-       usrpkg("NMH_MTA", enum("smtp sendmail"))
-       usrpkg("NMH_PAGER", BtIdentifier)
-       usrpkg("NS_PREFERRED", enum("communicator navigator mozilla"))
-       usrpkg("NULLMAILER_USER", BtUserGroupName)
-       usrpkg("NULLMAILER_GROUP", BtUserGroupName)
-       usrpkg("OPENSSH_CHROOT", BtPathname)
-       usrpkg("OPENSSH_USER", BtUserGroupName)
-       usrpkg("OPENSSH_GROUP", BtUserGroupName)
-       usrpkg("P4USER", BtUserGroupName)
-       usrpkg("P4GROUP", BtUserGroupName)
-       usrpkg("P4ROOT", BtPathname)
-       usrpkg("P4PORT", BtInteger)
-       usrpkg("PALMOS_DEFAULT_SDK", enum("1 2 3.1 3.5"))
-       usrpkg("PAPERSIZE", enum("A4 Letter"))
-       usrpkg("PGGROUP", BtUserGroupName)
-       usrpkg("PGUSER", BtUserGroupName)
-       usrpkg("PGHOME", BtPathname)
-       usrpkg("PILRC_USE_GTK", BtYesNo)
-       usrpkg("PKG_JVM_DEFAULT", jvms)
-       usrpkg("POPTOP_USE_MPPE", BtYes)
-       usrpkg("PROCMAIL_MAILSPOOLHOME", BtFileName)
+       usr("IMAP_UW_MAILSPOOLHOME", BtFileName)
+       usr("IMDICTDIR", BtPathname)
+       usr("INN_DATA_DIR", BtPathname)
+       usr("INN_USER", BtUserGroupName)
+       usr("INN_GROUP", BtUserGroupName)
+       usr("IRCD_HYBRID_NICLEN", BtInteger)
+       usr("IRCD_HYBRID_TOPICLEN", BtInteger)
+       usr("IRCD_HYBRID_SYSLOG_EVENTS", BtUnknown)
+       usr("IRCD_HYBRID_SYSLOG_FACILITY", BtIdentifier)
+       usr("IRCD_HYBRID_MAXCONN", BtInteger)
+       usr("IRCD_HYBRID_IRC_USER", BtUserGroupName)
+       usr("IRCD_HYBRID_IRC_GROUP", BtUserGroupName)
+       usr("IRRD_USE_PGP", enum("5 2"))
+       usr("JABBERD_USER", BtUserGroupName)
+       usr("JABBERD_GROUP", BtUserGroupName)
+       usr("JABBERD_LOGDIR", BtPathname)
+       usr("JABBERD_SPOOLDIR", BtPathname)
+       usr("JABBERD_PIDDIR", BtPathname)
+       usr("JAKARTA_HOME", BtPathname)
+       usr("KERBEROS", BtYes)
+       usr("KERMIT_SUID_UUCP", BtYes)
+       usr("KJS_USE_PCRE", BtYes)
+       usr("KNEWS_DOMAIN_FILE", BtPathname)
+       usr("KNEWS_DOMAIN_NAME", BtIdentifier)
+       usr("LIBDVDCSS_HOMEPAGE", BtHomepage)
+       usrlist("LIBDVDCSS_MASTER_SITES", BtFetchURL)
+       usr("LIBUSB_TYPE", enum("compat native"))
+       usr("LATEX2HTML_ICONPATH", BtURL)
+       usr("LEAFNODE_DATA_DIR", BtPathname)
+       usr("LEAFNODE_USER", BtUserGroupName)
+       usr("LEAFNODE_GROUP", BtUserGroupName)
+       usrlist("LINUX_LOCALES", BtIdentifier)
+       usr("MAILAGENT_DOMAIN", BtIdentifier)
+       usr("MAILAGENT_EMAIL", BtMailAddress)
+       usr("MAILAGENT_FQDN", BtIdentifier)
+       usr("MAILAGENT_ORGANIZATION", BtUnknown)
+       usr("MAJORDOMO_HOMEDIR", BtPathname)
+       usrlist("MAKEINFO_ARGS", BtShellWord)
+       usr("MECAB_CHARSET", BtIdentifier)
+       usr("MEDIATOMB_GROUP", BtUserGroupName)
+       usr("MEDIATOMB_USER", BtUserGroupName)
+       usr("MIREDO_USER", BtUserGroupName)
+       usr("MIREDO_GROUP", BtUserGroupName)
+       usr("MLDONKEY_GROUP", BtUserGroupName)
+       usr("MLDONKEY_HOME", BtPathname)
+       usr("MLDONKEY_USER", BtUserGroupName)
+       usr("MONOTONE_GROUP", BtUserGroupName)
+       usr("MONOTONE_USER", BtUserGroupName)
+       usr("MOTIF_TYPE", enum("motif openmotif lesstif dt"))
+       usr("MOTIF_TYPE_DEFAULT", enum("motif openmotif lesstif dt"))
+       usr("MTOOLS_ENABLE_FLOPPYD", BtYesNo)
+       usr("MYSQL_USER", BtUserGroupName)
+       usr("MYSQL_GROUP", BtUserGroupName)
+       usr("MYSQL_DATADIR", BtPathname)
+       usr("MYSQL_CHARSET", BtIdentifier)
+       usrlist("MYSQL_EXTRA_CHARSET", BtIdentifier)
+       usr("NAGIOS_GROUP", BtUserGroupName)
+       usr("NAGIOS_USER", BtUserGroupName)
+       usr("NAGIOSCMD_GROUP", BtUserGroupName)
+       usr("NAGIOSDIR", BtPathname)
+       usr("NBPAX_PROGRAM_PREFIX", BtUnknown)
+       usr("NMH_EDITOR", BtIdentifier)
+       usr("NMH_MTA", enum("smtp sendmail"))
+       usr("NMH_PAGER", BtIdentifier)
+       usr("NS_PREFERRED", enum("communicator navigator mozilla"))
+       usr("NULLMAILER_USER", BtUserGroupName)
+       usr("NULLMAILER_GROUP", BtUserGroupName)
+       usr("OPENSSH_CHROOT", BtPathname)
+       usr("OPENSSH_USER", BtUserGroupName)
+       usr("OPENSSH_GROUP", BtUserGroupName)
+       usr("P4USER", BtUserGroupName)
+       usr("P4GROUP", BtUserGroupName)
+       usr("P4ROOT", BtPathname)
+       usr("P4PORT", BtInteger)
+       usr("PALMOS_DEFAULT_SDK", enum("1 2 3.1 3.5"))
+       usr("PAPERSIZE", enum("A4 Letter"))
+       usr("PGGROUP", BtUserGroupName)
+       usr("PGUSER", BtUserGroupName)
+       usr("PGHOME", BtPathname)
+       usr("PILRC_USE_GTK", BtYesNo)
+       usr("PKG_JVM_DEFAULT", jvms)
+       usr("POPTOP_USE_MPPE", BtYes)
+       usr("PROCMAIL_MAILSPOOLHOME", BtFileName)
        // Comma-separated list of string or integer literals.
-       usrpkg("PROCMAIL_TRUSTED_IDS", BtUnknown)
-       usrpkg("PVM_SSH", BtPathname)
-       usrpkg("QMAILDIR", BtPathname)
-       usrpkg("QMAIL_ALIAS_USER", BtUserGroupName)
-       usrpkg("QMAIL_DAEMON_USER", BtUserGroupName)
-       usrpkg("QMAIL_LOG_USER", BtUserGroupName)
-       usrpkg("QMAIL_ROOT_USER", BtUserGroupName)
-       usrpkg("QMAIL_PASSWD_USER", BtUserGroupName)
-       usrpkg("QMAIL_QUEUE_USER", BtUserGroupName)
-       usrpkg("QMAIL_REMOTE_USER", BtUserGroupName)
-       usrpkg("QMAIL_SEND_USER", BtUserGroupName)
-       usrpkg("QMAIL_QMAIL_GROUP", BtUserGroupName)
-       usrpkg("QMAIL_NOFILES_GROUP", BtUserGroupName)
-       usrpkg("QMAIL_QFILTER_TMPDIR", BtPathname)
-       usrpkg("QMAIL_QUEUE_DIR", BtPathname)
-       usrpkg("QMAIL_QUEUE_EXTRA", BtMailAddress)
-       usrpkg("QPOPPER_FAC", BtIdentifier)
-       usrpkg("QPOPPER_USER", BtUserGroupName)
-       usrpkg("QPOPPER_SPOOL_DIR", BtPathname)
-       usrpkg("RASMOL_DEPTH", enum("8 16 32"))
-       usrpkg("RELAY_CTRL_DIR", BtPathname)
-       usrpkg("RPM_DB_PREFIX", BtPathname)
-       usrpkg("RSSH_SCP_PATH", BtPathname)
-       usrpkg("RSSH_SFTP_SERVER_PATH", BtPathname)
-       usrpkg("RSSH_CVS_PATH", BtPathname)
-       usrpkg("RSSH_RDIST_PATH", BtPathname)
-       usrpkg("RSSH_RSYNC_PATH", BtPathname)
-       usrpkglist("SAWFISH_THEMES", BtFileName)
-       usrpkg("SCREWS_GROUP", BtUserGroupName)
-       usrpkg("SCREWS_USER", BtUserGroupName)
-       usrpkg("SDIST_PAWD", enum("pawd pwd"))
-       usrpkglist("SERIAL_DEVICES", BtPathname)
-       usrpkg("SILC_CLIENT_WITH_PERL", BtYesNo)
-       usrpkg("SNIPROXY_USER", BtUserGroupName)
-       usrpkg("SNIPROXY_GROUP", BtUserGroupName)
-       usrpkg("SSH_SUID", BtYesNo)
-       usrpkg("SSYNC_PAWD", enum("pawd pwd"))
-       usrpkg("SUSE_PREFER", enum("13.1 12.1 10.0")) // TODO: extract
-       usrpkg("TEXMFSITE", BtPathname)
-       usrpkg("THTTPD_LOG_FACILITY", BtIdentifier)
-       usrpkg("UCSPI_SSL_USER", BtUserGroupName)
-       usrpkg("UCSPI_SSL_GROUP", BtUserGroupName)
-       usrpkg("UNPRIVILEGED", BtYesNo)
-       usrpkg("USE_CROSS_COMPILE", BtYesNo)
-       usrpkg("USERPPP_GROUP", BtUserGroupName)
-       usrpkg("UUCP_GROUP", BtUserGroupName)
-       usrpkg("UUCP_USER", BtUserGroupName)
-       usrpkglist("VIM_EXTRA_OPTS", BtShellWord)
-       usrpkg("WCALC_HTMLDIR", BtPathname)
-       usrpkg("WCALC_HTMLPATH", BtPathname) // URL path
-       usrpkg("WCALC_CGIDIR", BtPrefixPathname)
-       usrpkg("WCALC_CGIPATH", BtPathname) // URL path
-       usrpkglist("WDM_MANAGERS", BtIdentifier)
-       usrpkg("X10_PORT", BtPathname)
+       usr("PROCMAIL_TRUSTED_IDS", BtUnknown)
+       usr("PVM_SSH", BtPathname)
+       usr("QMAILDIR", BtPathname)
+       usr("QMAIL_ALIAS_USER", BtUserGroupName)
+       usr("QMAIL_DAEMON_USER", BtUserGroupName)
+       usr("QMAIL_LOG_USER", BtUserGroupName)
+       usr("QMAIL_ROOT_USER", BtUserGroupName)
+       usr("QMAIL_PASSWD_USER", BtUserGroupName)
+       usr("QMAIL_QUEUE_USER", BtUserGroupName)
+       usr("QMAIL_REMOTE_USER", BtUserGroupName)
+       usr("QMAIL_SEND_USER", BtUserGroupName)
+       usr("QMAIL_QMAIL_GROUP", BtUserGroupName)
+       usr("QMAIL_NOFILES_GROUP", BtUserGroupName)
+       usr("QMAIL_QFILTER_TMPDIR", BtPathname)
+       usr("QMAIL_QUEUE_DIR", BtPathname)
+       usr("QMAIL_QUEUE_EXTRA", BtMailAddress)
+       usr("QPOPPER_FAC", BtIdentifier)
+       usr("QPOPPER_USER", BtUserGroupName)
+       usr("QPOPPER_SPOOL_DIR", BtPathname)
+       usr("RASMOL_DEPTH", enum("8 16 32"))
+       usr("RELAY_CTRL_DIR", BtPathname)
+       usr("RPM_DB_PREFIX", BtPathname)
+       usr("RSSH_SCP_PATH", BtPathname)
+       usr("RSSH_SFTP_SERVER_PATH", BtPathname)
+       usr("RSSH_CVS_PATH", BtPathname)
+       usr("RSSH_RDIST_PATH", BtPathname)
+       usr("RSSH_RSYNC_PATH", BtPathname)
+       usrlist("SAWFISH_THEMES", BtFileName)
+       usr("SCREWS_GROUP", BtUserGroupName)
+       usr("SCREWS_USER", BtUserGroupName)
+       usr("SDIST_PAWD", enum("pawd pwd"))
+       usrlist("SERIAL_DEVICES", BtPathname)
+       usr("SILC_CLIENT_WITH_PERL", BtYesNo)
+       usr("SNIPROXY_USER", BtUserGroupName)
+       usr("SNIPROXY_GROUP", BtUserGroupName)
+       usr("SSH_SUID", BtYesNo)
+       usr("SSYNC_PAWD", enum("pawd pwd"))
+       usr("SUSE_PREFER", enum("13.1 12.1 10.0")) // TODO: extract
+       usr("TEXMFSITE", BtPathname)
+       usr("THTTPD_LOG_FACILITY", BtIdentifier)
+       usr("UCSPI_SSL_USER", BtUserGroupName)
+       usr("UCSPI_SSL_GROUP", BtUserGroupName)
+       usr("UNPRIVILEGED", BtYesNo)
+       usr("USE_CROSS_COMPILE", BtYesNo)
+       usr("USERPPP_GROUP", BtUserGroupName)
+       usr("UUCP_GROUP", BtUserGroupName)
+       usr("UUCP_USER", BtUserGroupName)
+       usrlist("VIM_EXTRA_OPTS", BtShellWord)
+       usr("WCALC_HTMLDIR", BtPathname)
+       usr("WCALC_HTMLPATH", BtPathname) // URL path
+       usr("WCALC_CGIDIR", BtPrefixPathname)
+       usr("WCALC_CGIPATH", BtPathname) // URL path
+       usrlist("WDM_MANAGERS", BtIdentifier)
+       usr("X10_PORT", BtPathname)
        usrpkg("XAW_TYPE", enum("standard 3d xpm neXtaw"))
-       usrpkg("XLOCK_DEFAULT_MODE", BtIdentifier)
-       usrpkg("ZSH_STATIC", BtYes)
+       usr("XLOCK_DEFAULT_MODE", BtIdentifier)
+       usr("ZSH_STATIC", BtYes)
 
        // some other variables, sorted alphabetically
 
@@ -1029,7 +1023,6 @@ func (reg *VarTypeRegistry) Init(src *Pk
        sys("EMACS_LISPPREFIX", BtPathname)
        pkglistbl3("EMACS_MODULES", BtIdentifier)
        sys("EMACS_PKGNAME_PREFIX", BtIdentifier) // Or the empty string.
-       sys("EMACS_TYPE", enum("emacs xemacs"))
        pkglist("EMACS_VERSIONS_ACCEPTED", emacsVersions)
        sys("EMACS_VERSION_MAJOR", BtInteger)
        sys("EMACS_VERSION_MINOR", BtInteger)
@@ -1067,13 +1060,11 @@ func (reg *VarTypeRegistry) Init(src *Pk
        pkglist("EXTRACT_OPTS_ZIP", BtShellWord)
        pkglist("EXTRACT_OPTS_ZOO", BtShellWord)
        pkg("EXTRACT_SUFX", BtDistSuffix)
-       pkg("EXTRACT_USING", enum("bsdtar gtar nbtar pax"))
        sys("FAIL_MSG", BtShellCommand)
        sys("FAMBASE", BtPathname)
        pkglist("FAM_ACCEPTED", enum("fam gamin"))
        usr("FAM_DEFAULT", enum("fam gamin"))
        sys("FAM_TYPE", enum("fam gamin"))
-       pkglist("FETCH_BEFORE_ARGS", BtShellWord)
        pkglist("FETCH_MESSAGE", BtShellWord)
        pkgload("FILESDIR", BtRelativePkgPath)
        pkglist("FILES_SUBST", BtShellWord)
@@ -1081,12 +1072,8 @@ func (reg *VarTypeRegistry) Init(src *Pk
        pkglist("FIX_RPATH", BtVariableName)
        pkglist("FLEX_REQD", BtVersion)
        pkglist("FONTS_DIRS.*", BtPathname)
-       sys("GAMEDATAMODE", BtFileMode)
-       sys("GAMES_GROUP", BtUserGroupName)
        syslist("GAMEDATA_PERMS", BtPerms)
        syslist("GAMEDIR_PERMS", BtPerms)
-       sys("GAMEMODE", BtFileMode)
-       sys("GAMES_USER", BtUserGroupName)
        pkglistbl3("GCC_REQD", BtGccReqd)
        pkgappend("GENERATE_PLIST", BtShellCommands)
        pkg("GITHUB_PROJECT", BtIdentifier)
@@ -1202,7 +1189,6 @@ func (reg *VarTypeRegistry) Init(src *Pk
        pkg("MAKE_FILE", BtPathname)
        pkglist("MAKE_FLAGS", BtShellWord)
        pkglist("MAKE_FLAGS.*", BtShellWord)
-       usr("MAKE_JOBS", BtInteger)
        pkg("MAKE_JOBS_SAFE", BtYesNo)
        pkg("MAKE_PROGRAM", BtShellCommand)
        pkg("MANCOMPRESSED", BtYesNo)
@@ -1406,7 +1392,6 @@ func (reg *VarTypeRegistry) Init(src *Pk
        sys("PKG_JAVA_HOME", BtPathname)
        sys("PKG_JVM", jvms)
        pkglist("PKG_JVMS_ACCEPTED", jvms)
-       usr("PKG_JVM_DEFAULT", jvms)
        pkg("PKG_LIBTOOL", BtPathname)
 
        // begin PKG_OPTIONS section
@@ -1484,7 +1469,6 @@ func (reg *VarTypeRegistry) Init(src *Pk
                "*: use, use-loadtime")
        // See lang/python/pyversion.mk
        pkg("PYTHON_FOR_BUILD_ONLY", enum("yes no test tool YES"))
-       pkglist("REPLACE_PYTHON", BtPathmask)
        pkglist("PYTHON_VERSIONS_ACCEPTED", BtVersion)
        pkglist("PYTHON_VERSIONS_INCOMPATIBLE", BtVersion)
        usr("PYTHON_VERSION_DEFAULT", BtVersion)
@@ -1673,7 +1657,6 @@ func (reg *VarTypeRegistry) Init(src *Pk
        pkg("WRKSRC", BtWrkdirSubdirectory)
        pkglist("X11_LDFLAGS", BtLdFlag)
        sys("X11_PKGSRCDIR.*", BtPathname)
-       usr("XAW_TYPE", enum("3d neXtaw standard xpm"))
        pkglist("XMKMF_FLAGS", BtShellWord)
        pkglist("_WRAP_EXTRA_ARGS.*", BtShellWord)
 

Index: pkgsrc/pkgtools/pkglint/files/vartypecheck.go
diff -u pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.54 pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.55
--- pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.54  Sat Apr 20 17:43:25 2019
+++ pkgsrc/pkgtools/pkglint/files/vartypecheck.go       Sat Apr 27 19:33:57 2019
@@ -1153,7 +1153,7 @@ func (cv *VartypeCheck) URL() {
 }
 
 func (cv *VartypeCheck) UserGroupName() {
-       if cv.Value == cv.ValueNoVar && !matches(cv.Value, `^[0-9_a-z]+$`) {
+       if cv.Value == cv.ValueNoVar && !matches(cv.Value, `^[0-9_a-z][0-9_a-z-]*[0-9_a-z]$`) {
                cv.Warnf("Invalid user or group name %q.", cv.Value)
        }
 }

Index: pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go
diff -u pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.46 pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.47
--- pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.46     Sat Apr 20 17:43:25 2019
+++ pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go  Sat Apr 27 19:33:57 2019
@@ -1457,7 +1457,9 @@ func NewVartypeCheckTester(t *Tester, ch
 
        // This is necessary to know whether the variable name is a list type
        // since in such a case each value is split into the list elements.
-       t.SetUpVartypes()
+       if G.Pkgsrc.VariableType(nil, "USE_CWRAPPERS") == nil {
+               t.SetUpVartypes()
+       }
 
        return &VartypeCheckTester{
                t,



Home | Main Index | Thread Index | Old Index