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:           Mon Jan  6 20:38:42 UTC 2020

Modified Files:
        pkgsrc/pkgtools/pkglint: Makefile
        pkgsrc/pkgtools/pkglint/files: check_test.go files.go mkline.go
            mklinechecker_test.go mklineparser.go mklineparser_test.go
            mklines.go mklines_test.go package.go plist.go plist_test.go
            util.go util_test.go vartypecheck_test.go

Log Message:
pkgtools/pkglint: update to 19.4.2

Changes since 19.4.1:

Fixed variable resolution. Before, variables that had not been defined
in an included file could still end up in the scope of the package,
which made many of the pkglint checks unreliable.

Each condition that is used in the PLIST should be defined somewhere in
the package Makefile or its included files.

When loading a package Makefile, hacks.mk is loaded implicitly at the
end, just as the pkgsrc infrastructure does in mk/bsd.hacks.mk.


To generate a diff of this commit:
cvs rdiff -u -r1.622 -r1.623 pkgsrc/pkgtools/pkglint/Makefile
cvs rdiff -u -r1.63 -r1.64 pkgsrc/pkgtools/pkglint/files/check_test.go
cvs rdiff -u -r1.30 -r1.31 pkgsrc/pkgtools/pkglint/files/files.go
cvs rdiff -u -r1.72 -r1.73 pkgsrc/pkgtools/pkglint/files/mkline.go
cvs rdiff -u -r1.56 -r1.57 \
    pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go
cvs rdiff -u -r1.11 -r1.12 pkgsrc/pkgtools/pkglint/files/mklineparser.go
cvs rdiff -u -r1.10 -r1.11 pkgsrc/pkgtools/pkglint/files/mklineparser_test.go
cvs rdiff -u -r1.66 -r1.67 pkgsrc/pkgtools/pkglint/files/mklines.go
cvs rdiff -u -r1.58 -r1.59 pkgsrc/pkgtools/pkglint/files/mklines_test.go
cvs rdiff -u -r1.76 -r1.77 pkgsrc/pkgtools/pkglint/files/package.go
cvs rdiff -u -r1.51 -r1.52 pkgsrc/pkgtools/pkglint/files/plist.go
cvs rdiff -u -r1.44 -r1.45 pkgsrc/pkgtools/pkglint/files/plist_test.go
cvs rdiff -u -r1.69 -r1.70 pkgsrc/pkgtools/pkglint/files/util.go
cvs rdiff -u -r1.46 -r1.47 pkgsrc/pkgtools/pkglint/files/util_test.go
cvs rdiff -u -r1.70 -r1.71 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.622 pkgsrc/pkgtools/pkglint/Makefile:1.623
--- pkgsrc/pkgtools/pkglint/Makefile:1.622      Sat Jan  4 19:53:13 2020
+++ pkgsrc/pkgtools/pkglint/Makefile    Mon Jan  6 20:38:42 2020
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.622 2020/01/04 19:53:13 rillig Exp $
+# $NetBSD: Makefile,v 1.623 2020/01/06 20:38:42 rillig Exp $
 
-PKGNAME=       pkglint-19.4.1
+PKGNAME=       pkglint-19.4.2
 CATEGORIES=    pkgtools
 DISTNAME=      tools
 MASTER_SITES=  ${MASTER_SITE_GITHUB:=golang/}

Index: pkgsrc/pkgtools/pkglint/files/check_test.go
diff -u pkgsrc/pkgtools/pkglint/files/check_test.go:1.63 pkgsrc/pkgtools/pkglint/files/check_test.go:1.64
--- pkgsrc/pkgtools/pkglint/files/check_test.go:1.63    Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/check_test.go Mon Jan  6 20:38:42 2020
@@ -319,7 +319,7 @@ func (t *Tester) LoadMkInclude(filename 
 
        var load func(filename CurrPath)
        load = func(filename CurrPath) {
-               mklines := NewMkLines(Load(filename, MustSucceed), nil)
+               mklines := NewMkLines(Load(filename, MustSucceed), nil, nil)
                for _, mkline := range mklines.mklines {
                        lines = append(lines, mkline.Line)
 
@@ -333,7 +333,7 @@ func (t *Tester) LoadMkInclude(filename 
 
        // This assumes that the test files do not contain parse errors.
        // Otherwise the diagnostics would appear twice.
-       return NewMkLines(NewLines(t.File(filename), lines), nil)
+       return NewMkLines(NewLines(t.File(filename), lines), nil, nil)
 }
 
 // SetUpPkgsrc sets up a minimal but complete pkgsrc installation in the
@@ -444,6 +444,9 @@ func (t *Tester) SetUpCategory(name RelP
 // After calling this method, individual files can be overwritten as necessary.
 // At the end of the setup phase, t.FinishSetUp() must be called to load all
 // the files.
+//
+// If the package path does not really matter for this test,
+// just use "category/package".
 func (t *Tester) SetUpPackage(pkgpath RelPath, makefileLines ...string) CurrPath {
        assertf(
                matches(pkgpath.String(), `^[^/]+/[^/]+$`),
@@ -750,7 +753,7 @@ func (t *Tester) SetUpHierarchy() (
                        }
                }
 
-               mklines := NewMkLines(NewLines(NewCurrPath(relFilename.AsPath()), lines), nil)
+               mklines := NewMkLines(NewLines(NewCurrPath(relFilename.AsPath()), lines), nil, nil)
                assertf(files[filename] == nil, "MkLines with name %q already exists.", filename)
                files[filename] = mklines
                return mklines
@@ -1054,7 +1057,7 @@ func (t *Tester) NewLinesAt(filename Cur
 // This can lead to strange error messages such as "Relative path %s does
 // not exist." because an intermediate directory in the path does not exist.
 //
-// If the filename is irrelevant for the particular test, take filename.mk.
+// If the filename is irrelevant for the particular test, just use filename.mk.
 func (t *Tester) NewMkLines(filename CurrPath, lines ...string) *MkLines {
        return t.NewMkLinesPkg(filename, nil, lines...)
 }
@@ -1070,7 +1073,7 @@ func (t *Tester) NewMkLinesPkg(filename 
                rawText.WriteString(line)
                rawText.WriteString("\n")
        }
-       return NewMkLines(convertToLogicalLines(filename, rawText.String(), true), pkg)
+       return NewMkLines(convertToLogicalLines(filename, rawText.String(), true), pkg, nil)
 }
 
 // Returns and consumes the output from both stdout and stderr.

Index: pkgsrc/pkgtools/pkglint/files/files.go
diff -u pkgsrc/pkgtools/pkglint/files/files.go:1.30 pkgsrc/pkgtools/pkglint/files/files.go:1.31
--- pkgsrc/pkgtools/pkglint/files/files.go:1.30 Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/files.go      Mon Jan  6 20:38:42 2020
@@ -19,7 +19,7 @@ func LoadMk(filename CurrPath, pkg *Pack
        if lines == nil {
                return nil
        }
-       return NewMkLines(lines, pkg)
+       return NewMkLines(lines, pkg, nil)
 }
 
 func Load(filename CurrPath, options LoadOptions) *Lines {

Index: pkgsrc/pkgtools/pkglint/files/mkline.go
diff -u pkgsrc/pkgtools/pkglint/files/mkline.go:1.72 pkgsrc/pkgtools/pkglint/files/mkline.go:1.73
--- pkgsrc/pkgtools/pkglint/files/mkline.go:1.72        Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/mkline.go     Mon Jan  6 20:38:42 2020
@@ -30,7 +30,6 @@ type mkLineAssign struct {
        varparam          string // e.g. "", "perl"
        spaceAfterVarname string
        op                MkOperator //
-       valueAlign        string     // The text up to and including the assignment operator, e.g. VARNAME+=\t
        value             string     // The trimmed value
        valueMk           []*MkToken // The value, sent through splitIntoMkWords
        valueMkRest       string     // nonempty in case of parse errors
@@ -211,7 +210,10 @@ func (mkline *MkLine) Op() MkOperator { 
 
 // ValueAlign applies to variable assignments and returns all the text
 // before the variable value, e.g. "VARNAME+=\t".
-func (mkline *MkLine) ValueAlign() string { return mkline.data.(*mkLineAssign).valueAlign }
+func (mkline *MkLine) ValueAlign() string {
+       parts := NewVaralignSplitter().split(mkline.Line.raw[0].Text(), true)
+       return parts.leadingComment + parts.varnameOp + parts.spaceBeforeValue
+}
 
 func (mkline *MkLine) Value() string { return mkline.data.(*mkLineAssign).value }
 

Index: pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.56 pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.57
--- pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.56    Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go Mon Jan  6 20:38:42 2020
@@ -425,7 +425,11 @@ func (s *Suite) Test_MkLineChecker_check
        // The purpose of this "nonexistent" diagnostic is only to show that
        // hacks.mk is indeed parsed and checked.
        t.CheckOutputLines(
-               "ERROR: ~/category/package/hacks.mk:2: " +
+               // XXX: The diagnostics should be the same since they
+               //  describe the same problem.
+               "ERROR: ~/category/package/hacks.mk:2: "+
+                       "Cannot read \"../../category/package/nonexistent.mk\".",
+               "ERROR: ~/category/package/hacks.mk:2: "+
                        "Relative path \"../../category/package/nonexistent.mk\" does not exist.")
 }
 
@@ -495,7 +499,7 @@ func (s *Suite) Test_MkLineChecker_check
                ".endif",
                ".endfor",
                ".endif")
-       mklines := NewMkLines(lines, nil)
+       mklines := NewMkLines(lines, nil, nil)
 
        mklines.Check()
 

Index: pkgsrc/pkgtools/pkglint/files/mklineparser.go
diff -u pkgsrc/pkgtools/pkglint/files/mklineparser.go:1.11 pkgsrc/pkgtools/pkglint/files/mklineparser.go:1.12
--- pkgsrc/pkgtools/pkglint/files/mklineparser.go:1.11  Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/mklineparser.go       Mon Jan  6 20:38:42 2020
@@ -5,6 +5,8 @@ import (
        "strings"
 )
 
+// MkLineParser parses a line of text into the syntactical parts of a
+// line in Makefiles.
 type MkLineParser struct{}
 
 func NewMkLineParser() MkLineParser { return MkLineParser{} }
@@ -147,7 +149,6 @@ func (p MkLineParser) MatchVarassign(lin
                varparam:          varnameParam(varname),
                spaceAfterVarname: spaceAfterVarname,
                op:                op,
-               valueAlign:        valueAlign,
                value:             value,
                valueMk:           nil, // filled in lazily
                valueMkRest:       "",  // filled in lazily
@@ -169,7 +170,8 @@ func (p MkLineParser) fixSpaceAfterVarna
                break
 
        default:
-               before := a.valueAlign
+               parts := NewVaralignSplitter().split(line.raw[0].Text(), true)
+               before := parts.leadingComment + parts.varnameOp + parts.spaceBeforeValue
                after := alignWith(varname+op.String(), before)
 
                fix := line.Autofix()

Index: pkgsrc/pkgtools/pkglint/files/mklineparser_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mklineparser_test.go:1.10 pkgsrc/pkgtools/pkglint/files/mklineparser_test.go:1.11
--- pkgsrc/pkgtools/pkglint/files/mklineparser_test.go:1.10     Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/mklineparser_test.go  Mon Jan  6 20:38:42 2020
@@ -213,6 +213,10 @@ func (s *Suite) Test_MkLineParser_MatchV
        testLine := func(line *Line, commented bool, varname, spaceAfterVarname, op, align, value, spaceAfterValue, comment string, diagnostics ...string) {
                text := line.Text
 
+               t.CheckOutputEmpty()
+               valueAlign := NewMkLineParser().Parse(line).ValueAlign()
+               _ = t.Output()
+
                parser := NewMkLineParser()
                splitResult := parser.split(nil, text, true)
                m, actual := parser.MatchVarassign(line, text, &splitResult)
@@ -225,13 +229,13 @@ func (s *Suite) Test_MkLineParser_MatchV
                        varparam:          varnameParam(varname),
                        spaceAfterVarname: spaceAfterVarname,
                        op:                NewMkOperator(op),
-                       valueAlign:        align,
                        value:             value,
                        valueMk:           nil,
                        valueMkRest:       "",
                        fields:            nil,
                }
                t.CheckDeepEquals(*actual, expected)
+               t.CheckEquals(valueAlign, align)
                t.CheckEquals(splitResult.spaceBeforeComment, spaceAfterValue)
                t.CheckEquals(splitResult.hasComment, comment != "")
                t.CheckEquals(condStr(splitResult.hasComment, "#", "")+splitResult.comment, comment)

Index: pkgsrc/pkgtools/pkglint/files/mklines.go
diff -u pkgsrc/pkgtools/pkglint/files/mklines.go:1.66 pkgsrc/pkgtools/pkglint/files/mklines.go:1.67
--- pkgsrc/pkgtools/pkglint/files/mklines.go:1.66       Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/mklines.go    Mon Jan  6 20:38:42 2020
@@ -6,7 +6,24 @@ import "strings"
 type MkLines struct {
        mklines []*MkLine
        lines   *Lines
-       pkg     *Package
+
+       // The package that provides further context for cross-checks,
+       // such as the conditionally included files.
+       //
+       // This package should be used mostly as a read-only storage of context
+       // information. To keep the code understandable, only few things should
+       // be changed, if at all. This is exactly the reason that the
+       // extraScope has been moved to a separate variable.
+       //
+       // XXX: Maybe split this field into two: pkg and pkgForModification.
+       pkg *Package
+
+       // The extra scope in which all variable assignments are recorded.
+       // In most cases this is nil.
+       //
+       // When loading the package Makefile with all its included files,
+       // it is set to pkg.vars.
+       extraScope *Scope
 
        allVars       Scope              // The variables after loading the complete file
        buildDefs     map[string]bool    // Variables that are registered in BUILD_DEFS, to ensure that all user-defined variables are added to it.
@@ -36,7 +53,7 @@ type mklinesCheckAll struct {
        postLine func(mkline *MkLine)
 }
 
-func NewMkLines(lines *Lines, pkg *Package) *MkLines {
+func NewMkLines(lines *Lines, pkg *Package, extraScope *Scope) *MkLines {
        mklines := make([]*MkLine, lines.Len())
        for i, line := range lines.Lines {
                mklines[i] = NewMkLineParser().Parse(line)
@@ -49,6 +66,7 @@ func NewMkLines(lines *Lines, pkg *Packa
                mklines,
                lines,
                pkg,
+               extraScope,
                NewScope(),
                make(map[string]bool),
                make(map[string]*MkLine),
@@ -154,8 +172,8 @@ func (mklines *MkLines) collectUsedVaria
 // This controls the "defined but not used" warning.
 func (mklines *MkLines) UseVar(mkline *MkLine, varname string, time VucTime) {
        mklines.allVars.Use(varname, mkline, time)
-       if mklines.pkg != nil {
-               mklines.pkg.vars.Use(varname, mkline, time)
+       if mklines.extraScope != nil {
+               mklines.extraScope.Use(varname, mkline, time)
        }
 }
 
@@ -344,8 +362,8 @@ func (mklines *MkLines) ForEachEnd(actio
 // defineVar marks a variable as defined in both the current package and the current file.
 func (mklines *MkLines) defineVar(mkline *MkLine, varname string) {
        mklines.allVars.Define(varname, mkline)
-       if mklines.pkg != nil {
-               mklines.pkg.vars.Define(varname, mkline)
+       if mklines.extraScope != nil {
+               mklines.extraScope.Define(varname, mkline)
        }
 }
 

Index: pkgsrc/pkgtools/pkglint/files/mklines_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.58 pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.59
--- pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.58  Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/mklines_test.go       Mon Jan  6 20:38:42 2020
@@ -15,6 +15,7 @@ func (s *Suite) Test_MkLines__quoting_LD
                MkCvsID,
                "GNU_CONFIGURE=\tyes",
                "CONFIGURE_ENV+=\tX_LIBS=${X11_LDFLAGS:Q}")
+       mklines.extraScope = &pkg.vars
 
        mklines.Check()
 

Index: pkgsrc/pkgtools/pkglint/files/package.go
diff -u pkgsrc/pkgtools/pkglint/files/package.go:1.76 pkgsrc/pkgtools/pkglint/files/package.go:1.77
--- pkgsrc/pkgtools/pkglint/files/package.go:1.76       Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/package.go    Mon Jan  6 20:38:42 2020
@@ -181,11 +181,17 @@ func (pkg *Package) loadPackageMakefile(
                return nil, nil
        }
 
-       allLines := NewMkLines(NewLines("", nil), pkg)
+       allLines := NewMkLines(NewLines("", nil), pkg, &pkg.vars)
        if !pkg.parse(mainLines, allLines, "", true) {
                return nil, nil
        }
 
+       // See mk/bsd.hacks.mk, which is included by mk/bsd.pkg.mk.
+       hacks := LoadMk(pkg.File("${PKGDIR}/hacks.mk"), pkg, NotEmpty)
+       if hacks != nil {
+               _ = pkg.parse(hacks, allLines, "", false)
+       }
+
        // TODO: Is this still necessary? This code is 20 years old and was introduced
        //  when pkglint loaded the package Makefile including all included files into
        //  a single string. Maybe it makes sense to print the file inclusion hierarchy

Index: pkgsrc/pkgtools/pkglint/files/plist.go
diff -u pkgsrc/pkgtools/pkglint/files/plist.go:1.51 pkgsrc/pkgtools/pkglint/files/plist.go:1.52
--- pkgsrc/pkgtools/pkglint/files/plist.go:1.51 Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/plist.go      Mon Jan  6 20:38:42 2020
@@ -206,6 +206,7 @@ func (ck *PlistChecker) checkPath(pline 
        }
 
        ck.checkPathMisc(rel, pline)
+       ck.checkPathCond(pline)
 }
 
 func (ck *PlistChecker) checkPathMisc(rel RelPath, pline *PlistLine) {
@@ -406,11 +407,10 @@ func (ck *PlistChecker) checkPathMan(pli
 }
 
 func (ck *PlistChecker) checkPathShare(pline *PlistLine) {
-       pkg := ck.pkg
        text := pline.text
 
        switch {
-       case pkg != nil && hasPrefix(text, "share/icons/"):
+       case ck.pkg != nil && hasPrefix(text, "share/icons/"):
                ck.checkPathShareIcons(pline)
 
        case hasPrefix(text, "share/doc/html/"):
@@ -460,6 +460,44 @@ func (ck *PlistChecker) checkPathShareIc
        }
 }
 
+func (ck *PlistChecker) checkPathCond(pline *PlistLine) {
+       if ck.pkg == nil {
+               return
+       }
+
+       for _, cond := range pline.conditions {
+               ck.checkCond(pline, cond[6:])
+       }
+}
+
+func (ck *PlistChecker) checkCond(pline *PlistLine, cond string) {
+       vars := ck.pkg.vars
+       mkline := vars.LastDefinition("PLIST_VARS")
+       if mkline == nil || ck.once.SeenSlice("cond", cond) {
+               return
+       }
+
+       plistVars := vars.LastValue("PLIST_VARS")
+       resolvedPlistVars := resolveVariableRefs(plistVars, nil, ck.pkg)
+       for _, varparam := range mkline.ValueFields(resolvedPlistVars) {
+               if varparam == cond {
+                       return
+               }
+               if containsVarUse(varparam) {
+                       trace.Stepf(
+                               "Skipping check for condition %q because PLIST_VARS "+
+                                       "contains the unresolved %q as part of %q.",
+                               cond, varparam, resolvedPlistVars)
+                       return
+               }
+       }
+
+       assert(ck.once.FirstTimeSlice("cond", cond))
+       pline.Warnf(
+               "Condition %q should be added to PLIST_VARS in the package Makefile.",
+               cond)
+}
+
 type PlistLine struct {
        *Line
        conditions []string // e.g. PLIST.docs

Index: pkgsrc/pkgtools/pkglint/files/plist_test.go
diff -u pkgsrc/pkgtools/pkglint/files/plist_test.go:1.44 pkgsrc/pkgtools/pkglint/files/plist_test.go:1.45
--- pkgsrc/pkgtools/pkglint/files/plist_test.go:1.44    Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/plist_test.go Mon Jan  6 20:38:42 2020
@@ -1010,6 +1010,102 @@ func (s *Suite) Test_PlistChecker_checkP
        t.CheckOutputEmpty()
 }
 
+func (s *Suite) Test_PlistChecker_checkPathCond(c *check.C) {
+       t := s.Init(c)
+
+       pkg := t.SetUpPackage("category/package",
+               "PLIST_VARS+=\tmk-undefined mk-yes both",
+               "PLIST.mk-yes=\tyes",
+               "PLIST.both=\tyes")
+       t.CreateFileLines("category/package/PLIST",
+               PlistCvsID,
+               "${PLIST.both}${PLIST.plist}bin/program")
+       t.FinishSetUp()
+
+       G.Check(pkg)
+
+       t.CheckOutputLines(
+               "WARN: ~/category/package/Makefile:20: "+
+                       "\"mk-undefined\" is added to PLIST_VARS, "+
+                       "but PLIST.mk-undefined is not defined in this file.",
+               "WARN: ~/category/package/PLIST:2: "+
+                       "Condition \"plist\" should be added to PLIST_VARS "+
+                       "in the package Makefile.")
+}
+
+func (s *Suite) Test_PlistChecker_checkCond(c *check.C) {
+       t := s.Init(c)
+
+       pkg := t.SetUpPackage("category/package",
+               "PLIST_VARS+=\tboth mk-yes",
+               "PLIST.mk-yes=\tyes",
+               "PLIST.both=\tyes")
+       t.CreateFileLines("category/package/PLIST",
+               PlistCvsID,
+               "${PLIST.both}${PLIST.plist}bin/program",
+               "${PLIST.both}${PLIST.plist}bin/program2")
+       t.FinishSetUp()
+
+       G.Check(pkg)
+
+       t.CheckOutputLines(
+               "WARN: ~/category/package/PLIST:2: " +
+                       "Condition \"plist\" should be added to PLIST_VARS " +
+                       "in the package Makefile.")
+}
+
+// Because of the unresolvable variable in the package Makefile,
+// pkglint cannot be absolutely sure about the possible PLIST
+// conditions. Therefore all such warnings are suppressed.
+//
+// As of January 2020, this case typically occurs when PLIST_VARS
+// is defined based on PKG_SUPPORTED_OPTIONS. Expanding that variable
+// typically contains ${_o_} and ${_opt_}.
+//
+// See audio/cmus for an example package.
+func (s *Suite) Test_PlistChecker_checkCond__unresolvable_variable(c *check.C) {
+       t := s.Init(c)
+
+       pkg := t.SetUpPackage("category/package",
+               "PLIST_VARS+=\tmk-only ${UNRESOLVABLE}",
+               "PLIST.mk-only=\tyes")
+       t.CreateFileLines("category/package/PLIST",
+               PlistCvsID,
+               "${PLIST.plist}bin/program")
+       t.FinishSetUp()
+
+       G.Check(pkg)
+
+       t.CheckOutputLines(
+               "WARN: ~/category/package/Makefile:20: " +
+                       "UNRESOLVABLE is used but not defined.")
+}
+
+func (s *Suite) Test_PlistChecker_checkCond__hacks_mk(c *check.C) {
+       t := s.Init(c)
+
+       t.SetUpPackage("category/package",
+               "PLIST_VARS+=\tmk", // To get past the mkline == nil condition.
+               "PLIST.mk=\tyes")
+       t.Chdir("category/package")
+       t.CreateFileLines("hacks.mk",
+               MkCvsID,
+               "PLIST_VARS+=\thack",
+               "PLIST.hack=\tyes")
+       t.CreateFileLines("PLIST",
+               PlistCvsID,
+               "${PLIST.hack}${PLIST.plist}bin/program")
+       t.FinishSetUp()
+
+       G.Check(".")
+
+       // Since hacks.mk is included implicitly into the package Makefile,
+       // the condition that is defined there may be used in the PLIST.
+       t.CheckOutputLines(
+               "WARN: PLIST:2: Condition \"plist\" should be added to PLIST_VARS " +
+                       "in the package Makefile.")
+}
+
 func (s *Suite) Test_PlistLine_Path(c *check.C) {
        t := s.Init(c)
 

Index: pkgsrc/pkgtools/pkglint/files/util.go
diff -u pkgsrc/pkgtools/pkglint/files/util.go:1.69 pkgsrc/pkgtools/pkglint/files/util.go:1.70
--- pkgsrc/pkgtools/pkglint/files/util.go:1.69  Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/util.go       Mon Jan  6 20:38:42 2020
@@ -558,6 +558,11 @@ func (o *Once) Seen(what string) bool {
        return seen
 }
 
+func (o *Once) SeenSlice(whats ...string) bool {
+       _, seen := o.seen[o.keyStrings(whats)]
+       return seen
+}
+
 func (*Once) keyString(what string) uint64 {
        return crc64.Checksum([]byte(what), crc64.MakeTable(crc64.ECMA))
 }
@@ -656,6 +661,7 @@ func (s *Scope) def(name string, mkline 
                s.value[name] += " " + value
        case opAssignDefault:
                // No change to the value.
+               // FIXME: If there is no value yet, set it.
        case opAssignShell:
                delete(s.value, name)
        default:

Index: pkgsrc/pkgtools/pkglint/files/util_test.go
diff -u pkgsrc/pkgtools/pkglint/files/util_test.go:1.46 pkgsrc/pkgtools/pkglint/files/util_test.go:1.47
--- pkgsrc/pkgtools/pkglint/files/util_test.go:1.46     Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/util_test.go  Mon Jan  6 20:38:42 2020
@@ -85,6 +85,34 @@ func (s *Suite) Test_replaceOnce(c *chec
        test("aaa", "aa", "b", "aaa")
 }
 
+func (s *Suite) Test_condStr(c *check.C) {
+       t := s.Init(c)
+
+       t.CheckEquals(condStr(true, "T", "F"), "T")
+       t.CheckEquals(condStr(false, "T", "F"), "F")
+}
+
+func (s *Suite) Test_condInt(c *check.C) {
+       t := s.Init(c)
+
+       t.CheckEquals(condInt(true, 123, 456), 123)
+       t.CheckEquals(condInt(false, 123, 456), 456)
+}
+
+func (s *Suite) Test_imax(c *check.C) {
+       t := s.Init(c)
+
+       t.CheckEquals(imax(2, 5), 5)
+       t.CheckEquals(imax(5, 2), 5)
+}
+
+func (s *Suite) Test_imin(c *check.C) {
+       t := s.Init(c)
+
+       t.CheckEquals(imin(2, 5), 2)
+       t.CheckEquals(imin(5, 2), 2)
+}
+
 func (s *Suite) Test_assertNil(c *check.C) {
        t := s.Init(c)
 
@@ -108,6 +136,13 @@ func (s *Suite) Test_assertNotNil(c *che
                "Pkglint internal error: unexpected nil pointer")
 }
 
+func (s *Suite) Test_assert(c *check.C) {
+       t := s.Init(c)
+
+       assert(true)
+       t.ExpectAssert(func() { assert(false) })
+}
+
 func (s *Suite) Test_isEmptyDir(c *check.C) {
        t := s.Init(c)
 
@@ -656,6 +691,27 @@ func (s *Suite) Test_Scope_LastValue(c *
                "WARN: file.mk:2: VAR is defined but not used.")
 }
 
+// Up to 2020-01-06, pkglint wrongly returned "one" as the variable value,
+// even though Makefile.common is included before appending "two".
+func (s *Suite) Test_Scope_LastValue__append_in_multiple_files(c *check.C) {
+       t := s.Init(c)
+
+       t.SetUpPackage("category/package",
+               ".include \"Makefile.common\"",
+               "PLIST_VARS+=\ttwo",
+               "PLIST.two=\tyes")
+       t.CreateFileLines("category/package/Makefile.common",
+               MkCvsID,
+               "PLIST_VARS=\tone",
+               "PLIST.one=\tyes")
+       pkg := NewPackage(t.File("category/package"))
+       t.FinishSetUp()
+
+       pkg.Check()
+
+       t.CheckEquals(pkg.vars.LastValue("PLIST_VARS"), "one two")
+}
+
 func (s *Suite) Test_Scope_DefineAll(c *check.C) {
        t := s.Init(c)
 

Index: pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go
diff -u pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.70 pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.71
--- pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.70     Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go  Mon Jan  6 20:38:42 2020
@@ -1096,18 +1096,18 @@ func (s *Suite) Test_VartypeCheck_Licens
 
        t.Chdir(".")
        // Adds the gnu-gpl-v2 and 2-clause-bsd licenses
-       t.SetUpPackage("category/package")
-       t.CreateFileLines("licenses/mit", "...")
-       t.FinishSetUp()
-
-       pkg := NewPackage(t.File("category/package"))
-
-       mklines := t.SetUpFileMkLinesPkg("perl5.mk", pkg,
+       t.SetUpPackage("category/package",
+               ".include \"perl5.mk\"")
+       t.CreateFileLines("licenses/mit",
+               "Permission is hereby granted, ...")
+       t.CreateFileLines("category/package/perl5.mk",
                MkCvsID,
                "PERL5_LICENSE= gnu-gpl-v2 OR artistic")
-       // Also registers the PERL5_LICENSE variable in the package.
-       mklines.collectVariables()
-
+       t.FinishSetUp()
+       pkg := NewPackage(t.File("category/package"))
+       // This registers the PERL5_LICENSE variable in the package,
+       // since Makefile includes perl5.mk.
+       pkg.load()
        vt := NewVartypeCheckTester(t, BtLicense)
 
        vt.Package(pkg)
@@ -2285,7 +2285,7 @@ func (vt *VartypeCheckTester) Values(val
                text := toText(value)
 
                line := vt.tester.NewLine(vt.filename, vt.lineno, text)
-               mklines := NewMkLines(NewLines(vt.filename, []*Line{line}), vt.pkg)
+               mklines := NewMkLines(NewLines(vt.filename, []*Line{line}), vt.pkg, nil)
                vt.lineno++
 
                mklines.ForEach(func(mkline *MkLine) { test(mklines, mkline, value) })



Home | Main Index | Thread Index | Old Index