summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrillig <rillig@pkgsrc.org>2020-06-07 15:49:23 +0000
committerrillig <rillig@pkgsrc.org>2020-06-07 15:49:23 +0000
commitba0dd83817065a3650202b09b852f1c4507e75b6 (patch)
tree6ae0e0fe1725be6dee3b0cb526299922a2711d74
parentd155f3c9a8a5026984ab060c5051245b9f4ae681 (diff)
downloadpkgsrc-ba0dd83817065a3650202b09b852f1c4507e75b6.tar.gz
pkgtools/pkglint: update to 20.1.15
Changes since 20.1.14: Fix confusing wording of diagnostic "should contain text". It's more precise to say "this line should consist of this text". Otherwise it's too easy to interpret it as "the text should occur somewhere in the line". Allow BUILDLINK_PREFIX.* to be used in helper files. Especially for programming language packages, files like plugin.mk often include buildlink3.mk and therefore may refer to the BUILDLINK_PREFIX of this package. Warn about redundant BUILDLINK_API_VERSION restrictions. Previously, the check had only been enabled if the operators from the default dependency pattern (buildlink3.mk) and the additional dependency pattern (package) used the same operators, which already covered most practical cases. Determine SuSE versions from the pkgsrc tree.
-rw-r--r--pkgtools/pkglint/Makefile4
-rw-r--r--pkgtools/pkglint/files/autofix_test.go3
-rw-r--r--pkgtools/pkglint/files/buildlink3.go4
-rw-r--r--pkgtools/pkglint/files/buildlink3_test.go34
-rw-r--r--pkgtools/pkglint/files/category.go2
-rw-r--r--pkgtools/pkglint/files/category_test.go6
-rw-r--r--pkgtools/pkglint/files/check_test.go7
-rw-r--r--pkgtools/pkglint/files/lineslexer.go4
-rw-r--r--pkgtools/pkglint/files/lineslexer_test.go233
-rw-r--r--pkgtools/pkglint/files/mkcondchecker.go2
-rw-r--r--pkgtools/pkglint/files/mklexer.go1
-rw-r--r--pkgtools/pkglint/files/mklinechecker_test.go11
-rw-r--r--pkgtools/pkglint/files/mklines.go3
-rw-r--r--pkgtools/pkglint/files/mkvarusechecker.go18
-rw-r--r--pkgtools/pkglint/files/mkvarusechecker_test.go99
-rw-r--r--pkgtools/pkglint/files/package.go7
-rw-r--r--pkgtools/pkglint/files/package_test.go100
-rw-r--r--pkgtools/pkglint/files/patches.go2
-rw-r--r--pkgtools/pkglint/files/patches_test.go21
-rw-r--r--pkgtools/pkglint/files/pkgsrc.go3
-rw-r--r--pkgtools/pkglint/files/pkgsrc_test.go9
-rw-r--r--pkgtools/pkglint/files/plist_test.go5
-rw-r--r--pkgtools/pkglint/files/redundantscope_test.go24
-rw-r--r--pkgtools/pkglint/files/shell.go4
-rw-r--r--pkgtools/pkglint/files/vardefs.go3
-rw-r--r--pkgtools/pkglint/files/vardefs_test.go4
-rw-r--r--pkgtools/pkglint/files/vartype_test.go2
-rw-r--r--pkgtools/pkglint/files/vartypecheck.go12
-rw-r--r--pkgtools/pkglint/files/vartypecheck_test.go104
29 files changed, 668 insertions, 63 deletions
diff --git a/pkgtools/pkglint/Makefile b/pkgtools/pkglint/Makefile
index b93f2162d86..9966cc774a4 100644
--- a/pkgtools/pkglint/Makefile
+++ b/pkgtools/pkglint/Makefile
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.653 2020/06/06 20:42:56 rillig Exp $
+# $NetBSD: Makefile,v 1.654 2020/06/07 15:49:23 rillig Exp $
-PKGNAME= pkglint-20.1.14
+PKGNAME= pkglint-20.1.15
CATEGORIES= pkgtools
DISTNAME= tools
MASTER_SITES= ${MASTER_SITE_GITHUB:=golang/}
diff --git a/pkgtools/pkglint/files/autofix_test.go b/pkgtools/pkglint/files/autofix_test.go
index 122c9cabd0f..290f998c1b9 100644
--- a/pkgtools/pkglint/files/autofix_test.go
+++ b/pkgtools/pkglint/files/autofix_test.go
@@ -2,6 +2,7 @@ package pkglint
import (
"gopkg.in/check.v1"
+ "netbsd.org/pkglint/regex"
"os"
"runtime"
"strings"
@@ -702,7 +703,7 @@ func (s *Suite) Test_Autofix_ReplaceAt(c *check.C) {
t.ExpectDiagnosticsAutofix(doTest, nil...)
}
- testPanicMatches := func(texts []string, rawIndex int, column int, from, to, panicMessage string) {
+ testPanicMatches := func(texts []string, rawIndex int, column int, from, to string, panicMessage regex.Pattern) {
doTest := func(bool) {
t.ExpectPanicMatches(
func() { mainPart(texts, rawIndex, column, from, to) },
diff --git a/pkgtools/pkglint/files/buildlink3.go b/pkgtools/pkglint/files/buildlink3.go
index 89d799ba525..fd4693e9fcc 100644
--- a/pkgtools/pkglint/files/buildlink3.go
+++ b/pkgtools/pkglint/files/buildlink3.go
@@ -54,7 +54,7 @@ func (ck *Buildlink3Checker) Check() {
}
// Fourth paragraph: Cleanup, corresponding to the first paragraph.
- if !llex.SkipContainsOrWarn("BUILDLINK_TREE+=\t-" + ck.pkgbase) {
+ if !llex.SkipTextOrWarn("BUILDLINK_TREE+=\t-" + ck.pkgbase) {
return
}
@@ -132,7 +132,7 @@ func (ck *Buildlink3Checker) checkSecondParagraph(mlex *MkLinesLexer) bool {
}
pkgupperLine, pkgupper := mlex.PreviousMkLine(), m[1]
- if !mlex.SkipContainsOrWarn(pkgupper + "_BUILDLINK3_MK:=") {
+ if !mlex.SkipTextOrWarn(pkgupper + "_BUILDLINK3_MK:=") {
return false
}
mlex.SkipEmptyOrNote()
diff --git a/pkgtools/pkglint/files/buildlink3_test.go b/pkgtools/pkglint/files/buildlink3_test.go
index 8057a829116..c5b374951aa 100644
--- a/pkgtools/pkglint/files/buildlink3_test.go
+++ b/pkgtools/pkglint/files/buildlink3_test.go
@@ -376,7 +376,7 @@ func (s *Suite) Test_CheckLinesBuildlink3Mk__missing_BUILDLINK_TREE_at_end(c *ch
CheckLinesBuildlink3Mk(mklines)
t.CheckOutputLines(
- "WARN: buildlink3.mk:13: This line should contain the following text: BUILDLINK_TREE+=\t-hs-X11")
+ "WARN: buildlink3.mk:13: This line should consist of the following text: BUILDLINK_TREE+=\t-hs-X11")
}
func (s *Suite) Test_CheckLinesBuildlink3Mk__DEPMETHOD_placement(c *check.C) {
@@ -424,7 +424,7 @@ func (s *Suite) Test_CheckLinesBuildlink3Mk__multiple_inclusion_wrong(c *check.C
t.CheckOutputLines(
"WARN: buildlink3.mk:5: HS_X11_BUILDLINK3_MK is used but not defined.",
"WARN: buildlink3.mk:6: UNRELATED_BUILDLINK3_MK is defined but not used.",
- "WARN: buildlink3.mk:6: This line should contain the following text: HS_X11_BUILDLINK3_MK:=")
+ "WARN: buildlink3.mk:6: This line should consist of the following text: HS_X11_BUILDLINK3_MK:=")
}
func (s *Suite) Test_CheckLinesBuildlink3Mk__missing_endif(c *check.C) {
@@ -631,6 +631,21 @@ func (s *Suite) Test_Buildlink3Checker_checkSecondParagraph__missing_mkbase(c *c
"WARN: ~/category/package/Makefile:4: \"\" is not a valid package name.")
}
+func (s *Suite) Test_Buildlink3Checker_checkPkgbaseMismatch(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package")
+ t.CreateFileBuildlink3Id("category/package/buildlink3.mk", "unrelated")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.Check(".")
+
+ t.CheckOutputLines(
+ "ERROR: buildlink3.mk:3: Package name mismatch between \"unrelated\" " +
+ "in this file and \"package\" from Makefile:3.")
+}
+
func (s *Suite) Test_Buildlink3Checker_checkMainPart__if_else_endif(c *check.C) {
t := s.Init(c)
@@ -1098,7 +1113,19 @@ func (s *Suite) Test_LoadBuildlink3Data(c *check.C) {
t := s.Init(c)
t.CreateFileBuildlink3("category/package/buildlink3.mk",
- "BUILDLINK_ABI_DEPENDS.package+=\tpackage>=0.1")
+ "BUILDLINK_ABI_DEPENDS.package+=\tpackage>=0.1",
+ "",
+ "BUILDLINK_API_DEPENDS.other+=\tother>=0.1",
+ "BUILDLINK_ABI_DEPENDS.other+=\tother>=0.1.3",
+ "BUILDLINK_API_DEPENDS.package+=\tinvalid",
+ "BUILDLINK_API_DEPENDS.package+=\tpackage>=0.1:extra",
+ "BUILDLINK_ABI_DEPENDS.package+=\tinvalid",
+ "BUILDLINK_ABI_DEPENDS.package+=\tpackage>=0.1:extra",
+
+ "BUILDLINK_PREFIX.package=\t${PREFIX}",
+ "BUILDLINK_PREFIX.other=\t${PREFIX}",
+
+ "BUILDLINK_PKGSRCDIR.other=\tcategory/package")
t.Chdir("category/package")
mklines := LoadMk("buildlink3.mk", nil, MustSucceed)
@@ -1106,6 +1133,7 @@ func (s *Suite) Test_LoadBuildlink3Data(c *check.C) {
t.CheckDeepEquals(data, &Buildlink3Data{
id: "package",
+ prefix: "${PREFIX}",
pkgsrcdir: "../../category/package",
apiDepends: &DependencyPattern{
Pkgbase: "package",
diff --git a/pkgtools/pkglint/files/category.go b/pkgtools/pkglint/files/category.go
index 14a40f17f6d..2ae66912699 100644
--- a/pkgtools/pkglint/files/category.go
+++ b/pkgtools/pkglint/files/category.go
@@ -145,7 +145,7 @@ func CheckdirCategory(dir CurrPath) {
// generating indexes and READMEs. Just skip them.
if !G.Wip {
mlex.SkipEmptyOrNote()
- mlex.SkipContainsOrWarn(".include \"../mk/misc/category.mk\"")
+ mlex.SkipTextOrWarn(".include \"../mk/misc/category.mk\"")
if !mlex.EOF() {
mlex.CurrentLine().Errorf("The file must end here.")
}
diff --git a/pkgtools/pkglint/files/category_test.go b/pkgtools/pkglint/files/category_test.go
index d2f274ec53c..6310743bb12 100644
--- a/pkgtools/pkglint/files/category_test.go
+++ b/pkgtools/pkglint/files/category_test.go
@@ -32,7 +32,7 @@ func (s *Suite) Test_CheckdirCategory__totally_broken(c *check.C) {
"ERROR: ~/archivers/Makefile:2: \"pkg1\" does not contain a package.",
"ERROR: ~/archivers/Makefile:3: \"aaaaa\" does not contain a package.",
"NOTE: ~/archivers/Makefile:4: Empty line expected above this line.",
- "WARN: ~/archivers/Makefile:4: This line should contain the following text: .include \"../mk/misc/category.mk\"",
+ "WARN: ~/archivers/Makefile:4: This line should consist of the following text: .include \"../mk/misc/category.mk\"",
"ERROR: ~/archivers/Makefile:4: The file must end here.")
}
@@ -303,7 +303,7 @@ func (s *Suite) Test_CheckdirCategory__comment_at_the_top(c *check.C) {
"ERROR: ~/category/Makefile:3: SUBDIR+= line or empty line expected.",
"ERROR: ~/category/Makefile:3: Package \"package\" must be listed here.",
"NOTE: ~/category/Makefile:3: Empty line expected above this line.",
- "WARN: ~/category/Makefile:3: This line should contain the following text: .include \"../mk/misc/category.mk\"",
+ "WARN: ~/category/Makefile:3: This line should consist of the following text: .include \"../mk/misc/category.mk\"",
"ERROR: ~/category/Makefile:3: The file must end here.")
}
@@ -326,7 +326,7 @@ func (s *Suite) Test_CheckdirCategory__unexpected_EOF_while_reading_SUBDIR(c *ch
// Doesn't happen in practice since categories are created very seldom.
t.CheckOutputLines(
"NOTE: ~/category/Makefile:5: Empty line expected below this line.",
- "WARN: ~/category/Makefile:EOF: This line should contain the following text: "+
+ "WARN: ~/category/Makefile:EOF: This line should consist of the following text: "+
".include \"../mk/misc/category.mk\"")
}
diff --git a/pkgtools/pkglint/files/check_test.go b/pkgtools/pkglint/files/check_test.go
index 5537fdab85b..d07d772db14 100644
--- a/pkgtools/pkglint/files/check_test.go
+++ b/pkgtools/pkglint/files/check_test.go
@@ -104,13 +104,11 @@ func (s *Suite) TearDownTest(c *check.C) {
func Test__qa(t *testing.T) {
ck := intqa.NewQAChecker(t.Errorf)
- ck.Configure("buildlink3.go", "*", "*", -intqa.EMissingTest) // TODO
ck.Configure("distinfo.go", "*", "*", -intqa.EMissingTest) // TODO
ck.Configure("files.go", "*", "*", -intqa.EMissingTest) // TODO
ck.Configure("licenses.go", "*", "*", -intqa.EMissingTest) // TODO
ck.Configure("line.go", "*", "*", -intqa.EMissingTest) // TODO
ck.Configure("linechecker.go", "*", "*", -intqa.EMissingTest) // TODO
- ck.Configure("lineslexer.go", "*", "*", -intqa.EMissingTest) // TODO
ck.Configure("lines.go", "*", "*", -intqa.EMissingTest) // TODO
ck.Configure("logging.go", "*", "*", -intqa.EMissingTest) // TODO
ck.Configure("mkline.go", "*", "*", -intqa.EMissingTest) // TODO
@@ -962,8 +960,9 @@ func (t *Tester) ExpectPanic(action func(), expectedMessage string) {
// ExpectPanicMatches runs the given action and expects that this action
// calls assert or assertf, or uses some other way to panic.
-func (t *Tester) ExpectPanicMatches(action func(), expectedMessage string) {
- t.Check(action, check.PanicMatches, expectedMessage)
+// The expectedMessage is anchored on both ends.
+func (t *Tester) ExpectPanicMatches(action func(), expectedMessage regex.Pattern) {
+ t.Check(action, check.PanicMatches, string(expectedMessage))
}
// ExpectAssert runs the given action and expects that this action calls assert.
diff --git a/pkgtools/pkglint/files/lineslexer.go b/pkgtools/pkglint/files/lineslexer.go
index ab1c7b79ac2..26336ec0507 100644
--- a/pkgtools/pkglint/files/lineslexer.go
+++ b/pkgtools/pkglint/files/lineslexer.go
@@ -109,10 +109,10 @@ func (llex *LinesLexer) SkipEmptyOrNote() bool {
return false
}
-func (llex *LinesLexer) SkipContainsOrWarn(text string) bool {
+func (llex *LinesLexer) SkipTextOrWarn(text string) bool {
result := llex.SkipText(text)
if !result {
- llex.CurrentLine().Warnf("This line should contain the following text: %s", text)
+ llex.CurrentLine().Warnf("This line should consist of the following text: %s", text)
}
return result
}
diff --git a/pkgtools/pkglint/files/lineslexer_test.go b/pkgtools/pkglint/files/lineslexer_test.go
index 02c3a59fdc4..a4676a67055 100644
--- a/pkgtools/pkglint/files/lineslexer_test.go
+++ b/pkgtools/pkglint/files/lineslexer_test.go
@@ -4,6 +4,121 @@ import (
"gopkg.in/check.v1"
)
+func (s *Suite) Test_NewLinesLexer(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1")
+
+ llex := NewLinesLexer(lines)
+
+ t.CheckEquals(llex.line, lines.Lines[0])
+}
+
+func (s *Suite) Test_LinesLexer_CurrentLine(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1")
+
+ llex := NewLinesLexer(lines)
+
+ t.CheckEquals(llex.CurrentLine(), lines.Lines[0])
+
+ llex.Skip()
+
+ t.CheckEquals(llex.CurrentLine().Linenos(), "EOF")
+}
+
+func (s *Suite) Test_LinesLexer_PreviousLine(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1")
+
+ llex := NewLinesLexer(lines)
+
+ t.ExpectPanicMatches(func() { llex.PreviousLine() }, `.*index out of range.*`)
+
+ llex.Skip()
+
+ t.CheckEquals(llex.PreviousLine(), lines.Lines[0])
+}
+
+func (s *Suite) Test_LinesLexer_EOF(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1")
+
+ llex := NewLinesLexer(lines)
+
+ t.CheckEquals(llex.EOF(), false)
+
+ llex.Skip()
+
+ t.CheckEquals(llex.EOF(), true)
+}
+
+func (s *Suite) Test_LinesLexer_Skip(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1")
+
+ llex := NewLinesLexer(lines)
+
+ t.CheckEquals(llex.Skip(), true)
+ t.CheckEquals(llex.Skip(), false)
+}
+
+func (s *Suite) Test_LinesLexer_Undo(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1")
+
+ llex := NewLinesLexer(lines)
+
+ t.CheckEquals(llex.Skip(), true)
+
+ llex.Undo()
+
+ t.CheckEquals(llex.CurrentLine(), lines.Lines[0])
+}
+
+func (s *Suite) Test_LinesLexer_NextRegexp(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1")
+
+ llex := NewLinesLexer(lines)
+
+ t.Check(llex.NextRegexp(`not found`), check.IsNil)
+ t.CheckDeepEquals(llex.NextRegexp(`ne..`), []string{"ne 1"})
+
+ t.CheckEquals(llex.EOF(), true)
+
+ t.Check(llex.NextRegexp(`^`), check.IsNil)
+}
+
+func (s *Suite) Test_LinesLexer_SkipRegexp(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1")
+
+ llex := NewLinesLexer(lines)
+
+ t.CheckEquals(llex.SkipRegexp(`not found`), false)
+ t.CheckEquals(llex.SkipRegexp(`ne..`), true)
+
+ t.CheckEquals(llex.EOF(), true)
+
+ t.CheckEquals(llex.SkipRegexp(`^`), false)
+}
+
func (s *Suite) Test_LinesLexer_SkipPrefix(c *check.C) {
t := s.Init(c)
@@ -19,6 +134,20 @@ func (s *Suite) Test_LinesLexer_SkipPrefix(c *check.C) {
t.CheckEquals(llex.SkipPrefix(""), false)
}
+func (s *Suite) Test_LinesLexer_SkipText(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1")
+ llex := NewLinesLexer(lines)
+
+ t.CheckEquals(llex.SkipText("line"), false)
+ t.CheckEquals(llex.SkipText("line 12"), false)
+ t.CheckEquals(llex.SkipText("line 1"), true)
+
+ t.CheckEquals(llex.EOF(), true)
+}
+
func (s *Suite) Test_LinesLexer_SkipEmptyOrNote__beginning_of_file(c *check.C) {
t := s.Init(c)
@@ -50,6 +179,110 @@ func (s *Suite) Test_LinesLexer_SkipEmptyOrNote__end_of_file(c *check.C) {
"NOTE: file.txt:2: Empty line expected below this line.")
}
+func (s *Suite) Test_LinesLexer_SkipTextOrWarn(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1",
+ "line 2")
+ llex := NewLinesLexer(lines)
+
+ llex.SkipTextOrWarn("ne")
+ llex.SkipTextOrWarn("line 1")
+ llex.SkipTextOrWarn("line 2")
+
+ t.CheckEquals(llex.EOF(), true)
+ t.CheckOutputLines(
+ "WARN: file.txt:1: This line should consist of the following text: ne")
+}
+
+func (s *Suite) Test_LinesLexer_setIndex(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1",
+ "line 2")
+ llex := NewLinesLexer(lines)
+
+ llex.setIndex(1)
+
+ t.CheckEquals(llex.CurrentLine(), lines.Lines[1])
+
+ llex.setIndex(0)
+
+ t.CheckEquals(llex.CurrentLine(), lines.Lines[0])
+
+ llex.setIndex(2)
+
+ t.CheckEquals(llex.EOF(), true)
+}
+
+func (s *Suite) Test_LinesLexer_next(c *check.C) {
+ t := s.Init(c)
+
+ lines := t.NewLines("file.txt",
+ "line 1",
+ "line 2")
+ llex := NewLinesLexer(lines)
+
+ llex.next()
+
+ t.CheckEquals(llex.CurrentLine(), lines.Lines[1])
+
+ llex.next()
+
+ t.CheckEquals(llex.CurrentLine().Linenos(), "EOF")
+
+ llex.next()
+
+ t.Check(llex.line, check.IsNil)
+}
+
+func (s *Suite) Test_NewMkLinesLexer(c *check.C) {
+ t := s.Init(c)
+
+ mklines := t.NewMkLines("filename.mk",
+ "# line 1",
+ "# line 2")
+ mlex := NewMkLinesLexer(mklines)
+
+ t.CheckEquals(mlex.CurrentMkLine(), mklines.mklines[0])
+}
+
+func (s *Suite) Test_MkLinesLexer_PreviousMkLine(c *check.C) {
+ t := s.Init(c)
+
+ mklines := t.NewMkLines("filename.mk",
+ "# line 1",
+ "# line 2")
+ mlex := NewMkLinesLexer(mklines)
+
+ t.ExpectPanicMatches(func() { mlex.PreviousMkLine() }, `.*index out of range.*`)
+
+ mlex.Skip()
+
+ t.CheckEquals(mlex.PreviousMkLine().Linenos(), "1")
+}
+
+func (s *Suite) Test_MkLinesLexer_CurrentMkLine(c *check.C) {
+ t := s.Init(c)
+
+ mklines := t.NewMkLines("filename.mk",
+ "# line 1",
+ "# line 2")
+ mlex := NewMkLinesLexer(mklines)
+
+ t.CheckEquals(mlex.CurrentMkLine(), mklines.mklines[0])
+
+ mlex.Skip()
+
+ t.CheckEquals(mlex.CurrentMkLine(), mklines.mklines[1])
+
+ mlex.Skip()
+
+ t.ExpectPanicMatches(func() { mlex.CurrentMkLine() }, `.*index out of range.*`)
+}
+
func (s *Suite) Test_MkLinesLexer_SkipIf(c *check.C) {
t := s.Init(c)
diff --git a/pkgtools/pkglint/files/mkcondchecker.go b/pkgtools/pkglint/files/mkcondchecker.go
index c1ca935f73f..dc901c9a3fd 100644
--- a/pkgtools/pkglint/files/mkcondchecker.go
+++ b/pkgtools/pkglint/files/mkcondchecker.go
@@ -268,7 +268,7 @@ func (ck *MkCondChecker) checkCompare(left *MkCondTerm, op string, right *MkCond
switch {
case right.Num != "":
ck.checkCompareVarNum(op, right.Num)
- case left.Var != nil && right.Var == nil && right.Num == "":
+ case left.Var != nil && right.Var == nil:
ck.checkCompareVarStr(left.Var, op, right.Str)
}
}
diff --git a/pkgtools/pkglint/files/mklexer.go b/pkgtools/pkglint/files/mklexer.go
index efb40b73dd6..20b73a6fbb9 100644
--- a/pkgtools/pkglint/files/mklexer.go
+++ b/pkgtools/pkglint/files/mklexer.go
@@ -159,7 +159,6 @@ func (p *MkLexer) varUseBrace(usingRoundParen bool) *MkVarUse {
func (p *MkLexer) Varname() string {
lexer := p.lexer
- // TODO: duplicated code in MatchVarassign
mark := lexer.Mark()
lexer.SkipByte('.')
for lexer.NextBytesSet(VarbaseBytes) != "" || p.VarUse() != nil {
diff --git a/pkgtools/pkglint/files/mklinechecker_test.go b/pkgtools/pkglint/files/mklinechecker_test.go
index d5861b03f31..f0077bce6dd 100644
--- a/pkgtools/pkglint/files/mklinechecker_test.go
+++ b/pkgtools/pkglint/files/mklinechecker_test.go
@@ -178,12 +178,17 @@ func (s *Suite) Test_MkLineChecker_checkText__WRKSRC(c *check.C) {
func (s *Suite) Test_MkLineChecker_checkTextRpath(c *check.C) {
t := s.Init(c)
- t.NewMkLines("filename.mk",
+ t.SetUpVartypes()
+ mklines := t.NewMkLines("filename.mk",
MkCvsID,
"BUILDLINK_TRANSFORM+=\trm:-Wl,-R/usr/lib",
- "BUILDLINK_TRANSFORM+=\trm:-Wl,-rpath,/usr/lib")
+ "BUILDLINK_TRANSFORM+=\trm:-Wl,-rpath,/usr/lib",
+ "BUILDLINK_TRANSFORM+=\topt:-Wl,-rpath,/usr/lib")
- t.CheckOutputEmpty()
+ mklines.Check()
+
+ t.CheckOutputLines(
+ "WARN: filename.mk:4: Please use ${COMPILER_RPATH_FLAG} instead of \"-Wl,-rpath,\".")
}
func (s *Suite) Test_MkLineChecker_checkVartype__simple_type(c *check.C) {
diff --git a/pkgtools/pkglint/files/mklines.go b/pkgtools/pkglint/files/mklines.go
index 3140067940c..f8ee6f82e08 100644
--- a/pkgtools/pkglint/files/mklines.go
+++ b/pkgtools/pkglint/files/mklines.go
@@ -656,6 +656,9 @@ func (mklines *MkLines) ExpandLoopVar(varname string) []string {
// IsUnreachable determines whether the given line is unreachable because a
// condition on the way to that line is not satisfied.
// If unsure, returns false.
+//
+// Only the current package and Makefile fragment are taken into account.
+// The line might still be reachable by another pkgsrc package.
func (mklines *MkLines) IsUnreachable(mkline *MkLine) bool {
// To make this code as simple as possible, the code should operate
// on a high-level AST, where the nodes are If, For and BasicBlock.
diff --git a/pkgtools/pkglint/files/mkvarusechecker.go b/pkgtools/pkglint/files/mkvarusechecker.go
index 0aeeb3df624..30c244b4b0f 100644
--- a/pkgtools/pkglint/files/mkvarusechecker.go
+++ b/pkgtools/pkglint/files/mkvarusechecker.go
@@ -162,11 +162,6 @@ func (ck *MkVarUseChecker) checkVarnameBuildlink(varname string) {
return
}
- basename := ck.MkLine.Basename
- if basename == "buildlink3.mk" || basename == "builtin.mk" {
- return
- }
-
varparam := varnameParam(varname)
id := Buildlink3ID(varparam)
if pkg.bl3Data[id] != nil || containsVarUse(varparam) {
@@ -176,11 +171,14 @@ func (ck *MkVarUseChecker) checkVarnameBuildlink(varname string) {
// Several packages contain Makefile fragments that are more related
// to the buildlink3.mk file than to the package Makefile.
// These may use the buildlink identifier from the package itself.
- bl3 := LoadMk(pkg.File("buildlink3.mk"), pkg, 0)
- if bl3 != nil {
- bl3Data := LoadBuildlink3Data(bl3)
- if bl3Data != nil && bl3Data.id == id {
- return
+ basename := ck.MkLine.Basename
+ if basename != "Makefile" && basename != "options.mk" {
+ bl3 := LoadMk(pkg.File("buildlink3.mk"), pkg, 0)
+ if bl3 != nil {
+ bl3Data := LoadBuildlink3Data(bl3)
+ if bl3Data != nil && bl3Data.id == id {
+ return
+ }
}
}
diff --git a/pkgtools/pkglint/files/mkvarusechecker_test.go b/pkgtools/pkglint/files/mkvarusechecker_test.go
index ddf68c1723c..fcd2dbbd83f 100644
--- a/pkgtools/pkglint/files/mkvarusechecker_test.go
+++ b/pkgtools/pkglint/files/mkvarusechecker_test.go
@@ -382,20 +382,117 @@ func (s *Suite) Test_MkVarUseChecker_checkVarname(c *check.C) {
func (s *Suite) Test_MkVarUseChecker_checkVarnameBuildlink(c *check.C) {
t := s.Init(c)
+ t.SetUpOption("option", "Description.")
+ t.CreateFileLines("mk/bsd.options.mk")
t.SetUpPackage("category/library")
t.CreateFileBuildlink3Id("category/library/buildlink3.mk", "lib")
t.SetUpPackage("category/package",
"CONFIGURE_ARGS+=\t--with-library=${BUILDLINK_PREFIX.library}",
"CONFIGURE_ARGS+=\t--with-lib=${BUILDLINK_PREFIX.lib}",
+ "CONFIGURE_ARGS+=\t--with-package=${BUILDLINK_PREFIX.package}",
+ "CONFIGURE_ARGS+=\t--with-package=${BUILDLINK_PREFIX.${PKGBASE}}",
"",
".include \"../../category/library/buildlink3.mk\"")
+ t.CreateFileLines("category/package/options.mk",
+ MkCvsID,
+ "",
+ "PKG_OPTIONS_VAR=\tPKG_OPTIONS.package",
+ "PKG_SUPPORTED_OPTIONS=\toption",
+ ".include \"../../mk/bsd.options.mk\"",
+ ".if ${PKG_OPTIONS:Moption}",
+ "CONFIGURE_ARGS+=\t--with-option=${BUILDLINK_PREFIX.package}",
+ ".endif")
+ t.CreateFileBuildlink3("category/package/buildlink3.mk",
+ "BL3=\t${BUILDLINK_PREFIX.unknown-bl3}",
+ "BL3+=\t${BUILDLINK_PREFIX.package}")
+ t.CreateFileLines("category/package/builtin.mk",
+ MkCvsID,
+ "BUILTIN=\t${BUILDLINK_PREFIX.unknown-builtin}",
+ "BUILTIN+=\t${BUILDLINK_PREFIX.package}")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.Check(".")
+
+ t.CheckOutputLines(
+ "WARN: Makefile:20: Buildlink identifier \"library\" is not known in this package.",
+ "WARN: Makefile:22: Buildlink identifier \"package\" is not known in this package.",
+ "WARN: buildlink3.mk:12: BL3 is defined but not used.",
+ "WARN: buildlink3.mk:12: Buildlink identifier \"unknown-bl3\" is not known in this package.",
+ "WARN: builtin.mk:2: BUILTIN is defined but not used.",
+ "WARN: builtin.mk:2: Buildlink identifier \"unknown-builtin\" is not known in this package.",
+ "WARN: options.mk:7: Buildlink identifier \"package\" is not known in this package.")
+}
+
+func (s *Suite) Test_MkVarUseChecker_checkVarnameBuildlink__no_buildlink3_file(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package")
+ t.CreateFileLines("category/package/module.mk",
+ MkCvsID,
+ "CONFIGURE_ARGS+=\t--prefix=${BUILDLINK_PREFIX.package}")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.Check(".")
+
+ t.CheckOutputLines(
+ "WARN: module.mk:2: Buildlink identifier \"package\" is not known in this package.")
+}
+
+func (s *Suite) Test_MkVarUseChecker_checkVarnameBuildlink__no_buildlink3_data(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package")
+ t.CreateFileLines("category/package/module.mk",
+ MkCvsID,
+ "CONFIGURE_ARGS+=\t--prefix=${BUILDLINK_PREFIX.package}")
+ t.CreateFileLines("category/package/buildlink3.mk",
+ MkCvsID,
+ "# Empty, for whatever reason. This doesn't happen in practice.")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.Check(".")
+
+ t.CheckOutputLines(
+ "NOTE: buildlink3.mk:2: Empty line expected below this line.",
+ "WARN: buildlink3.mk:EOF: Expected a BUILDLINK_TREE line.",
+ "WARN: module.mk:2: Buildlink identifier \"package\" is not known in this package.")
+}
+
+func (s *Suite) Test_MkVarUseChecker_checkVarnameBuildlink__mysql_ok(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package")
+ t.CreateFileLines("mk/mysql.buildlink3.mk")
+ t.CreateFileLines("category/package/module.mk",
+ MkCvsID,
+ "CONFIGURE_ARGS+=\t--prefix=${BUILDLINK_PREFIX.mysql-client}",
+ ".include \"../../mk/mysql.buildlink3.mk\"")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.Check(".")
+
+ t.CheckOutputEmpty()
+}
+
+func (s *Suite) Test_MkVarUseChecker_checkVarnameBuildlink__mysql_bad(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package")
+ t.CreateFileLines("mk/mysql.buildlink3.mk")
+ t.CreateFileLines("category/package/module.mk",
+ MkCvsID,
+ "CONFIGURE_ARGS+=\t--prefix=${BUILDLINK_PREFIX.mysql-client}")
t.Chdir("category/package")
t.FinishSetUp()
G.Check(".")
t.CheckOutputLines(
- "WARN: Makefile:20: Buildlink identifier \"library\" is not known in this package.")
+ "WARN: module.mk:2: Buildlink identifier \"mysql-client\" is not known in this package.")
}
func (s *Suite) Test_MkVarUseChecker_checkPermissions(c *check.C) {
diff --git a/pkgtools/pkglint/files/package.go b/pkgtools/pkglint/files/package.go
index 596ee557980..aa2e32fe68f 100644
--- a/pkgtools/pkglint/files/package.go
+++ b/pkgtools/pkglint/files/package.go
@@ -604,9 +604,6 @@ func (pkg *Package) check(filenames []CurrPath, mklines, allLines *MkLines) {
}
func (pkg *Package) checkDescr(filenames []CurrPath, mklines *MkLines) {
- if mklines == nil {
- return
- }
for _, filename := range filenames {
if filename.HasBase("DESCR") {
return
@@ -624,13 +621,13 @@ func (pkg *Package) checkDistfilesInDistinfo(mklines *MkLines) {
return
}
- if pkg.distinfoDistfiles == nil {
+ if len(pkg.distinfoDistfiles) == 0 {
return
}
redundant := pkg.redundant
distfiles := redundant.get("DISTFILES")
- if distfiles == nil {
+ if len(distfiles.vari.WriteLocations()) == 0 {
return
}
diff --git a/pkgtools/pkglint/files/package_test.go b/pkgtools/pkglint/files/package_test.go
index e936bc8c5d8..302bbf08f76 100644
--- a/pkgtools/pkglint/files/package_test.go
+++ b/pkgtools/pkglint/files/package_test.go
@@ -1348,6 +1348,20 @@ func (s *Suite) Test_Package_checkDescr__DESCR_SRC(c *check.C) {
t.CheckOutputEmpty()
}
+func (s *Suite) Test_Package_checkDescr__no_package(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPkgsrc()
+ t.CreateFileLines("category/package/module.mk")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.Check(".")
+
+ t.CheckOutputLines(
+ "ERROR: Makefile: Cannot be read.")
+}
+
// All files that can possibly be added to DISTFILES need a corresponding
// entry in the distinfo file.
//
@@ -1362,10 +1376,11 @@ func (s *Suite) Test_Package_checkDistfilesInDistinfo__indirect_conditional_DIST
".include \"../../mk/bsd.prefs.mk\"",
"",
"DISTFILES.i386=\t\tdistfile-i386.tar.gz",
+ "DISTFILES.x86=\t\tdistfile-x86.tar.gz",
"DISTFILES.other=\tdistfile-other.tar.gz",
"",
".if ${MACHINE_ARCH} == i386",
- "DISTFILES+=\t${DISTFILES.i386}",
+ "DISTFILES+=\t${DISTFILES.i386} ${DISTFILES.x86}",
".else",
"DISTFILES+=\t${DISTFILES.other}",
".endif",
@@ -1388,8 +1403,42 @@ func (s *Suite) Test_Package_checkDistfilesInDistinfo__indirect_conditional_DIST
G.Check(".")
t.CheckOutputLines(
- "WARN: Makefile:26: Distfile \"distfile-i386.tar.gz\" is not mentioned in distinfo.",
- "WARN: Makefile:28: Distfile \"distfile-other.tar.gz\" is not mentioned in distinfo.")
+ "WARN: Makefile:27: Distfile \"distfile-i386.tar.gz\" is not mentioned in distinfo.",
+ "WARN: Makefile:27: Distfile \"distfile-x86.tar.gz\" is not mentioned in distinfo.",
+ "WARN: Makefile:29: Distfile \"distfile-other.tar.gz\" is not mentioned in distinfo.")
+}
+
+func (s *Suite) Test_Package_checkDistfilesInDistinfo__unresolvable(c *check.C) {
+ G.Experimental = true
+
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package",
+ ".include \"../../mk/bsd.prefs.mk\"",
+ "",
+ ".if ${MACHINE_ARCH} == i386",
+ "DISTFILES+=\t${UNKNOWN}",
+ ".endif",
+ "",
+ "DISTFILES+=\tok-3.tar.gz")
+ t.CreateFileLines("category/package/distinfo",
+ CvsID,
+ "",
+ "SHA1 (ok-3.tar.gz) = 1234",
+ "RMD160 (ok-3.tar.gz) = 1234",
+ "SHA512 (ok-3.tar.gz) = 1234",
+ "Size (ok-3.tar.gz) = 1234",
+ "SHA1 (package-1.0.tar.gz) = 1234",
+ "RMD160 (package-1.0.tar.gz) = 1234",
+ "SHA512 (package-1.0.tar.gz) = 1234",
+ "Size (package-1.0.tar.gz) = 1234")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.Check(".")
+
+ t.CheckOutputLines(
+ "WARN: Makefile:23: UNKNOWN is used but not defined.")
}
func (s *Suite) Test_Package_checkDistfilesInDistinfo__indirect_DIST_SUBDIR(c *check.C) {
@@ -1466,6 +1515,51 @@ func (s *Suite) Test_Package_checkDistfilesInDistinfo__depending_on_package_sett
"is not mentioned in ../../print/tex-varisize/distinfo.")
}
+func (s *Suite) Test_Package_checkDistfilesInDistinfo__empty_distfiles(c *check.C) {
+ G.Experimental = true
+
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package",
+ "DISTFILES=\t# none")
+ t.CreateFileLines("category/package/distinfo",
+ CvsID)
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.Check(".")
+
+ // For completely empty distinfo files, the check is skipped.
+ t.CheckOutputLines(
+ "WARN: distinfo: This file should not exist.",
+ "NOTE: distinfo:1: Empty line expected below this line.")
+}
+
+func (s *Suite) Test_Package_checkDistfilesInDistinfo__no_distfiles(c *check.C) {
+ G.Experimental = true
+
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package",
+ "#DISTNAME=\t# undefined",
+ "#DISTFILES=\t# undefined")
+ t.CreateFileLines("category/package/distinfo",
+ CvsID,
+ "",
+ "SHA1 (distfile-1.0.tar.gz) = 1234",
+ "RMD160 (distfile-1.0.tar.gz) = 1234",
+ "SHA512 (distfile-1.0.tar.gz) = 1234",
+ "Size (distfile-1.0.tar.gz) = 1234 bytes")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.Check(".")
+
+ // For completely empty distinfo files, the check is skipped.
+ t.CheckOutputLines(
+ "WARN: distinfo: This file should not exist.")
+}
+
func (s *Suite) Test_Package_checkfilePackageMakefile__GNU_CONFIGURE(c *check.C) {
t := s.Init(c)
diff --git a/pkgtools/pkglint/files/patches.go b/pkgtools/pkglint/files/patches.go
index 66115d5176d..853feef21ce 100644
--- a/pkgtools/pkglint/files/patches.go
+++ b/pkgtools/pkglint/files/patches.go
@@ -267,7 +267,7 @@ func (ck *PatchChecker) checkAddedAbsPath(before string, dir Path, after string)
before = replaceAll(before, `^[ \t]*set\(\w+[ \t]*`, "")
// Ignore comments in shell programs.
- if m, first := match1(before, `^[ \t]*#[ \t]*(\w*)`); m && first != "define" {
+ if hasPrefix(trimHspace(before), "#") {
return
}
diff --git a/pkgtools/pkglint/files/patches_test.go b/pkgtools/pkglint/files/patches_test.go
index 9a1041988da..3822d36e2d9 100644
--- a/pkgtools/pkglint/files/patches_test.go
+++ b/pkgtools/pkglint/files/patches_test.go
@@ -938,6 +938,27 @@ func (s *Suite) Test_PatchChecker_checkAddedAbsPath(c *check.C) {
test(
"#define L 150 /* Length of a line in /etc/passwd */",
nil...)
+
+ test(
+ "#define PID_FILE \"/var/run/daemon.pid\" /* comment */",
+ "ERROR: patch-file:8: Patches must not hard-code the pkgsrc VARBASE.")
+
+ // This is a rather theoretical case.
+ // Don't worry if pkglint doesn't complain about the absolute path here.
+ test(
+ "#define PID_FILE /* */ \"/var/run/daemon.pid\" /* */",
+ nil...)
+
+ // The absolute path occurs in a comment that is only opened but not closed.
+ // It's an edge case, and it may or may not be justified to complain here.
+ test(
+ "/* See /var/run/daemon.pid for details.",
+ "ERROR: patch-file:8: Patches must not hard-code the pkgsrc VARBASE.")
+
+ // Absolute paths in shell comments are not that dangerous.
+ test(
+ "# See /var/run/daemon.pid for details.",
+ nil...)
}
func (s *Suite) Test_PatchChecker_checktextCvsID(c *check.C) {
diff --git a/pkgtools/pkglint/files/pkgsrc.go b/pkgtools/pkglint/files/pkgsrc.go
index 55fbdde60f9..e0df2345150 100644
--- a/pkgtools/pkglint/files/pkgsrc.go
+++ b/pkgtools/pkglint/files/pkgsrc.go
@@ -265,7 +265,7 @@ func (src *Pkgsrc) checkChangeVersion(change *Change, latest map[PkgsrcPath]*Cha
}
latest[change.Pkgpath] = change
- case Renamed, Moved, Removed:
+ default:
latest[change.Pkgpath] = nil
}
}
@@ -1164,6 +1164,7 @@ func (src *Pkgsrc) ReadDir(dirName PkgsrcPath) []os.FileInfo {
//
// During pkglint testing, these files often don't exist, as they are
// emulated by setting their data structures manually.
+// In that case, returns nil.
func (src *Pkgsrc) LoadMkExisting(filename PkgsrcPath) *MkLines {
options := NotEmpty
if !G.Testing {
diff --git a/pkgtools/pkglint/files/pkgsrc_test.go b/pkgtools/pkglint/files/pkgsrc_test.go
index bec6ee6d6d3..1015e36de9b 100644
--- a/pkgtools/pkglint/files/pkgsrc_test.go
+++ b/pkgtools/pkglint/files/pkgsrc_test.go
@@ -358,18 +358,23 @@ func (s *Suite) Test_Pkgsrc_checkChangeVersion(c *check.C) {
t.CreateFileLines("doc/CHANGES-2020",
"\tAdded category/package version 1.0 [author1 2020-01-01]",
"\tAdded category/package version 1.0 [author1 2020-01-01]",
+ "\tAdded category/package version 2.3 [author1 2020-01-01]",
"\tUpdated category/package to 0.9 [author1 2020-01-01]",
"\tDowngraded category/package to 1.0 [author1 2020-01-01]",
+ "\tDowngraded category/package to 0.8 [author 2020-01-01]",
"\tRenamed category/package to category/renamed [author1 2020-01-01]",
"\tMoved category/package to other/renamed [author1 2020-01-01]")
t.Chdir("doc")
G.Pkgsrc.loadDocChangesFromFile("CHANGES-2020")
+ // In line 3 there is no warning about the repeated addition since
+ // the multi-packages (Lua, PHP, Python) may add a package in
+ // several versions to the same PKGPATH.
t.CheckOutputLines(
"WARN: CHANGES-2020:2: Package \"category/package\" was already added in line 1.",
- "WARN: CHANGES-2020:3: Updating \"category/package\" from 1.0 in line 2 to 0.9 should increase the version number.",
- "WARN: CHANGES-2020:4: Downgrading \"category/package\" from 0.9 in line 3 to 1.0 should decrease the version number.")
+ "WARN: CHANGES-2020:4: Updating \"category/package\" from 2.3 in line 3 to 0.9 should increase the version number.",
+ "WARN: CHANGES-2020:5: Downgrading \"category/package\" from 0.9 in line 4 to 1.0 should decrease the version number.")
}
func (s *Suite) Test_Pkgsrc_checkChangeVersionNumber(c *check.C) {
diff --git a/pkgtools/pkglint/files/plist_test.go b/pkgtools/pkglint/files/plist_test.go
index f678811caac..164ac9f82be 100644
--- a/pkgtools/pkglint/files/plist_test.go
+++ b/pkgtools/pkglint/files/plist_test.go
@@ -936,7 +936,8 @@ func (s *Suite) Test_PlistChecker_checkPathMan(c *check.C) {
"man/cat1/formatted.0",
"man/man1/formatted.1",
"man/man1/program.8",
- "man/manx/program.x")
+ "man/manx/program.x",
+ "man/not-valid")
CheckLinesPlist(nil, lines)
@@ -1444,6 +1445,8 @@ func (s *Suite) Test_NewPlistRank(c *check.C) {
t.CheckDeepEquals(NewPlistRank("PLIST.NetBSD-x86_64"), &PlistRank{3, "NetBSD", "x86_64", ""})
t.CheckDeepEquals(NewPlistRank("PLIST.linux-x86_64"), &PlistRank{3, "linux", "x86_64", ""})
t.CheckDeepEquals(NewPlistRank("PLIST.solaris-sparc"), &PlistRank{3, "solaris", "sparc", ""})
+ t.CheckDeepEquals(NewPlistRank("PLIST.solaris-specific"), &PlistRank{3, "", "", "solaris-specific"})
+ t.CheckDeepEquals(NewPlistRank("PLIST.arch-x86_64"), &PlistRank{3, "", "", "arch-x86_64"})
t.CheckDeepEquals(NewPlistRank("PLIST.other"), &PlistRank{3, "", "", "other"})
// To list all current PLIST filenames:
diff --git a/pkgtools/pkglint/files/redundantscope_test.go b/pkgtools/pkglint/files/redundantscope_test.go
index 391fde54ac1..a919fbdf667 100644
--- a/pkgtools/pkglint/files/redundantscope_test.go
+++ b/pkgtools/pkglint/files/redundantscope_test.go
@@ -1694,6 +1694,30 @@ func (s *Suite) Test_RedundantScope_checkAppendUnique__eval_assignment(c *check.
"because it will later be appended in included.mk:2.")
}
+func (s *Suite) Test_RedundantScope_checkAppendUnique__not_redundant(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpCategory("perl")
+ t.SetUpPackage("category/package",
+ "CATEGORIES:=\tcategory",
+ ".include \"included1.mk\"",
+ ".include \"included2.mk\"")
+ t.Chdir("category/package")
+ t.CreateFileLines("included1.mk",
+ MkCvsID,
+ "CATEGORIES+=\tperl")
+ t.CreateFileLines("included2.mk",
+ MkCvsID,
+ "CATEGORIES+=\tperl")
+ t.FinishSetUp()
+
+ G.Check(".")
+
+ // The additions in included1.mk and included2.mk are not redundant
+ // since neither of them includes the other.
+ t.CheckOutputEmpty()
+}
+
func (s *Suite) Test_includePath_includes(c *check.C) {
t := s.Init(c)
diff --git a/pkgtools/pkglint/files/shell.go b/pkgtools/pkglint/files/shell.go
index 38c33538a85..3bea2dc4543 100644
--- a/pkgtools/pkglint/files/shell.go
+++ b/pkgtools/pkglint/files/shell.go
@@ -1009,10 +1009,6 @@ func (ck *ShellLineChecker) warnMultiLineComment(rawIndex int, raw *RawLine) {
"\t${:D this is commented out}")
}
-func (ck *ShellLineChecker) Errorf(format string, args ...interface{}) {
- ck.mkline.Errorf(format, args...)
-}
-
func (ck *ShellLineChecker) Warnf(format string, args ...interface{}) {
ck.mkline.Warnf(format, args...)
}
diff --git a/pkgtools/pkglint/files/vardefs.go b/pkgtools/pkglint/files/vardefs.go
index 5187efd7492..ac73b3be7b3 100644
--- a/pkgtools/pkglint/files/vardefs.go
+++ b/pkgtools/pkglint/files/vardefs.go
@@ -820,7 +820,8 @@ func (reg *VarTypeRegistry) Init(src *Pkgsrc) {
reg.usr("SNIPROXY_GROUP", BtUserGroupName)
reg.usr("SSH_SUID", BtYesNo)
reg.usr("SSYNC_PAWD", enum("pawd pwd"))
- reg.usr("SUSE_PREFER", enum("13.1 12.1 10.0")) // TODO: extract
+ reg.usr("SUSE_PREFER", reg.enumFromDirs(src,
+ "emulators", `^suse(\d\d)(\d)_base$`, "$1.$2", "13.1 12.1 10.0"))
reg.usr("TEXMFSITE", BtPathname)
reg.usr("THTTPD_LOG_FACILITY", BtIdentifierIndirect)
reg.usr("UCSPI_SSL_USER", BtUserGroupName)
diff --git a/pkgtools/pkglint/files/vardefs_test.go b/pkgtools/pkglint/files/vardefs_test.go
index 640fb9bfb85..de8f27bbafb 100644
--- a/pkgtools/pkglint/files/vardefs_test.go
+++ b/pkgtools/pkglint/files/vardefs_test.go
@@ -34,6 +34,10 @@ func (s *Suite) Test_VarTypeRegistry_compilerLanguages(c *check.C) {
// Just for code coverage
".if ${OTHER} || ${USE_LANGUAGES} \\",
" || ${USE_LANGUAGES:O} || ${USE_LANGUAGES:Mc++-*}",
+ ".endif",
+ "",
+ // Just for code coverage
+ ".if", // missing condition
".endif")
reg := NewVarTypeRegistry()
diff --git a/pkgtools/pkglint/files/vartype_test.go b/pkgtools/pkglint/files/vartype_test.go
index 75b8cdeb957..0b55b3d5011 100644
--- a/pkgtools/pkglint/files/vartype_test.go
+++ b/pkgtools/pkglint/files/vartype_test.go
@@ -250,6 +250,8 @@ func (s *Suite) Test_BasicType_NeedsQ(c *check.C) {
test("PKG_FAIL_REASON", true)
test("SUBST_MESSAGE.id", true)
test("CC", true)
+
+ test("TOOLS_NOOP", false)
}
func (s *Suite) Test_BasicType_HasEnum(c *check.C) {
diff --git a/pkgtools/pkglint/files/vartypecheck.go b/pkgtools/pkglint/files/vartypecheck.go
index 2ee1a940288..3cf8b45e3a0 100644
--- a/pkgtools/pkglint/files/vartypecheck.go
+++ b/pkgtools/pkglint/files/vartypecheck.go
@@ -394,12 +394,14 @@ func (cv *VartypeCheck) DependencyPattern() {
return
}
defpat := depends(data)
- if defpat == nil || defpat.LowerOp != deppat.LowerOp {
+ if defpat == nil || defpat.LowerOp == "" {
return
}
- if pkgver.Compare(deppat.Lower, defpat.Lower) < 0 {
- cv.Warnf("Version %s is smaller than the default version %s from %s.",
- deppat.Lower, defpat.Lower, cv.MkLine.RelMkLine(dependsLine(data)))
+ limit := condInt(defpat.LowerOp == ">=" && deppat.LowerOp == ">", 1, 0)
+ if pkgver.Compare(deppat.Lower, defpat.Lower) < limit {
+ cv.Notef("The requirement %s%s is already guaranteed by the %s%s from %s.",
+ deppat.LowerOp, deppat.Lower, defpat.LowerOp, defpat.Lower,
+ cv.MkLine.RelMkLine(dependsLine(data)))
}
}
@@ -1400,7 +1402,7 @@ func (cv *VartypeCheck) ToolName() {
//
// Used for:
// - infrastructure variables that are not in vardefs.go
-// - other variables whose type is unknown or uninteresting enough to
+// - other variables whose type is unknown or not interesting enough to
// warrant the creation of a specialized type
func (cv *VartypeCheck) Unknown() {
// Do nothing.
diff --git a/pkgtools/pkglint/files/vartypecheck_test.go b/pkgtools/pkglint/files/vartypecheck_test.go
index ee1d5a6132a..f429a2940d2 100644
--- a/pkgtools/pkglint/files/vartypecheck_test.go
+++ b/pkgtools/pkglint/files/vartypecheck_test.go
@@ -501,10 +501,100 @@ func (s *Suite) Test_VartypeCheck_DependencyPattern__smaller_version(c *check.C)
G.checkdirPackage(".")
t.CheckOutputLines(
- "WARN: Makefile:21: Version 1.0pkg is smaller than the default "+
- "version 1.3api from ../../category/lib/buildlink3.mk:12.",
- "WARN: Makefile:22: Version 1.1pkg is smaller than the default "+
- "version 1.4abi from ../../category/lib/buildlink3.mk:13.")
+ "NOTE: Makefile:21: The requirement >=1.0pkg is already guaranteed "+
+ "by the >=1.3api from ../../category/lib/buildlink3.mk:12.",
+ "NOTE: Makefile:22: The requirement >=1.1pkg is already guaranteed "+
+ "by the >=1.4abi from ../../category/lib/buildlink3.mk:13.")
+}
+
+func (s *Suite) Test_VartypeCheck_DependencyPattern__different_operators(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package",
+ ".include \"../../category/lib/buildlink3.mk\"",
+ "BUILDLINK_API_DEPENDS.lib+=\tlib>=1.0pkg",
+ "BUILDLINK_ABI_DEPENDS.lib+=\tlib>=1.1pkg")
+ t.SetUpPackage("category/lib")
+ t.CreateFileBuildlink3("category/lib/buildlink3.mk",
+ "BUILDLINK_API_DEPENDS.lib+=\tlib>1.3api",
+ "BUILDLINK_ABI_DEPENDS.lib+=\tlib>1.4abi")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.checkdirPackage(".")
+
+ t.CheckOutputLines(
+ "NOTE: Makefile:21: The requirement >=1.0pkg is already guaranteed "+
+ "by the >1.3api from ../../category/lib/buildlink3.mk:12.",
+ "NOTE: Makefile:22: The requirement >=1.1pkg is already guaranteed "+
+ "by the >1.4abi from ../../category/lib/buildlink3.mk:13.")
+}
+
+func (s *Suite) Test_VartypeCheck_DependencyPattern__additional_greater(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package",
+ ".include \"../../category/lib/buildlink3.mk\"",
+ "BUILDLINK_API_DEPENDS.lib+=\tlib>1.0pkg",
+ "BUILDLINK_ABI_DEPENDS.lib+=\tlib>1.1pkg")
+ t.SetUpPackage("category/lib")
+ t.CreateFileBuildlink3("category/lib/buildlink3.mk",
+ "BUILDLINK_API_DEPENDS.lib+=\tlib>=1.3api",
+ "BUILDLINK_ABI_DEPENDS.lib+=\tlib>=1.4abi")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.checkdirPackage(".")
+
+ t.CheckOutputLines(
+ "NOTE: Makefile:21: The requirement >1.0pkg is already guaranteed "+
+ "by the >=1.3api from ../../category/lib/buildlink3.mk:12.",
+ "NOTE: Makefile:22: The requirement >1.1pkg is already guaranteed "+
+ "by the >=1.4abi from ../../category/lib/buildlink3.mk:13.")
+}
+
+func (s *Suite) Test_VartypeCheck_DependencyPattern__upper_limit(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package",
+ ".include \"../../category/lib/buildlink3.mk\"",
+ "BUILDLINK_API_DEPENDS.lib+=\tlib<2.0",
+ "BUILDLINK_ABI_DEPENDS.lib+=\tlib<2.1")
+ t.SetUpPackage("category/lib")
+ t.CreateFileBuildlink3("category/lib/buildlink3.mk",
+ "BUILDLINK_API_DEPENDS.lib+=\tlib>1.3api",
+ "BUILDLINK_ABI_DEPENDS.lib+=\tlib>1.4abi")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.checkdirPackage(".")
+
+ // If the additional constraint doesn't have a lower bound,
+ // there is nothing to compare and warn about.
+ t.CheckOutputEmpty()
+}
+
+// Having an upper bound for a library dependency is unusual.
+// A combined lower and upper bound makes sense though.
+func (s *Suite) Test_VartypeCheck_DependencyPattern__upper_limit_in_buildlink3(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("category/package",
+ ".include \"../../category/lib/buildlink3.mk\"",
+ "BUILDLINK_API_DEPENDS.lib+=\tlib>=16",
+ "BUILDLINK_ABI_DEPENDS.lib+=\tlib>=16.1")
+ t.SetUpPackage("category/lib")
+ t.CreateFileBuildlink3("category/lib/buildlink3.mk",
+ "BUILDLINK_API_DEPENDS.lib+=\tlib<7",
+ "BUILDLINK_ABI_DEPENDS.lib+=\tlib<6")
+ t.Chdir("category/package")
+ t.FinishSetUp()
+
+ G.checkdirPackage(".")
+
+ // If the additional constraint doesn't have a lower bound,
+ // there is nothing to compare and warn about.
+ t.CheckOutputEmpty()
}
func (s *Suite) Test_VartypeCheck_DependencyPattern__API_ABI(c *check.C) {
@@ -2003,13 +2093,15 @@ func (s *Suite) Test_VartypeCheck_ToolName(c *check.C) {
"tool3:anything",
"${t}",
"mal:formed:tool",
- "unknown")
+ "unknown",
+ "c++")
vt.Output(
"ERROR: filename.mk:2: TOOLS_BROKEN accepts only plain tool names, "+
"without any colon.",
"ERROR: filename.mk:4: TOOLS_BROKEN accepts only plain tool names, "+
- "without any colon.")
+ "without any colon.",
+ "ERROR: filename.mk:6: Invalid tool name \"c++\".")
vt.Varname("TOOLS_NOOP")
vt.Op(opUseMatch)