Fri May 29 20:13:17 2020 UTC ()
pkgtools/pkglint: update to 20.1.11

Changes since 20.1.10:

PKG_SYSCONFDIR and VARBASE must not appear in INSTALLATION_DIRS.

Patch files in which the line number have been edited manually are marked
with notes.


(rillig)
diff -r1.649 -r1.650 pkgsrc/pkgtools/pkglint/Makefile
diff -r1.78 -r1.79 pkgsrc/pkgtools/pkglint/files/mkline.go
diff -r1.40 -r1.41 pkgsrc/pkgtools/pkglint/files/patches.go
diff -r1.39 -r1.40 pkgsrc/pkgtools/pkglint/files/patches_test.go
diff -r1.88 -r1.89 pkgsrc/pkgtools/pkglint/files/vartypecheck.go
diff -r1.79 -r1.80 pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go

cvs diff -r1.649 -r1.650 pkgsrc/pkgtools/pkglint/Makefile (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/Makefile 2020/05/24 19:12:29 1.649
+++ pkgsrc/pkgtools/pkglint/Makefile 2020/05/29 20:13:17 1.650
@@ -1,16 +1,16 @@ @@ -1,16 +1,16 @@
1# $NetBSD: Makefile,v 1.649 2020/05/24 19:12:29 rillig Exp $ 1# $NetBSD: Makefile,v 1.650 2020/05/29 20:13:17 rillig Exp $
2 2
3PKGNAME= pkglint-20.1.10 3PKGNAME= pkglint-20.1.11
4CATEGORIES= pkgtools 4CATEGORIES= pkgtools
5DISTNAME= tools 5DISTNAME= tools
6MASTER_SITES= ${MASTER_SITE_GITHUB:=golang/} 6MASTER_SITES= ${MASTER_SITE_GITHUB:=golang/}
7GITHUB_PROJECT= tools 7GITHUB_PROJECT= tools
8GITHUB_TAG= 92d8274bd7b8a4c65f24bafe401a029e58392704 8GITHUB_TAG= 92d8274bd7b8a4c65f24bafe401a029e58392704
9 9
10MAINTAINER= rillig@NetBSD.org 10MAINTAINER= rillig@NetBSD.org
11HOMEPAGE= https://github.com/rillig/pkglint 11HOMEPAGE= https://github.com/rillig/pkglint
12COMMENT= Verifier for NetBSD packages 12COMMENT= Verifier for NetBSD packages
13LICENSE= 2-clause-bsd 13LICENSE= 2-clause-bsd
14CONFLICTS+= pkglint4-[0-9]* 14CONFLICTS+= pkglint4-[0-9]*
15 15
16USE_TOOLS+= pax 16USE_TOOLS+= pax

cvs diff -r1.78 -r1.79 pkgsrc/pkgtools/pkglint/files/Attic/mkline.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/mkline.go 2020/05/08 19:50:04 1.78
+++ pkgsrc/pkgtools/pkglint/files/Attic/mkline.go 2020/05/29 20:13:17 1.79
@@ -811,77 +811,74 @@ func (mkline *MkLine) VariableNeedsQuoti @@ -811,77 +811,74 @@ func (mkline *MkLine) VariableNeedsQuoti
811 // Good: LDADD+= ${LIBS:S,^,-l,} 811 // Good: LDADD+= ${LIBS:S,^,-l,}
812 if wantList { 812 if wantList {
813 return yes 813 return yes
814 } 814 }
815 815
816 if trace.Tracing { 816 if trace.Tracing {
817 trace.Step1("Don't know whether :Q is needed for %q", varuse.varname) 817 trace.Step1("Don't know whether :Q is needed for %q", varuse.varname)
818 } 818 }
819 return unknown 819 return unknown
820} 820}
821 821
822// ForEachUsed calls the action for each variable that is used in the line. 822// ForEachUsed calls the action for each variable that is used in the line.
823func (mkline *MkLine) ForEachUsed(action func(varUse *MkVarUse, time VucTime)) { 823func (mkline *MkLine) ForEachUsed(action func(varUse *MkVarUse, time VucTime)) {
824 
825 var searchIn func(text string, time VucTime) // mutually recursive with searchInVarUse 
826 
827 searchInVarUse := func(varuse *MkVarUse, time VucTime) { 
828 varname := varuse.varname 
829 if !varuse.IsExpression() { 
830 action(varuse, time) 
831 } 
832 searchIn(varname, time) 
833 for _, mod := range varuse.modifiers { 
834 searchIn(mod.Text, time) 
835 } 
836 } 
837 
838 searchIn = func(text string, time VucTime) { 
839 if !contains(text, "$") { 
840 return 
841 } 
842 
843 tokens, _ := NewMkLexer(text, nil).MkTokens() 
844 for _, token := range tokens { 
845 if token.Varuse != nil { 
846 searchInVarUse(token.Varuse, time) 
847 } 
848 } 
849 } 
850 
851 switch { 824 switch {
852 825
853 case mkline.IsVarassign(): 826 case mkline.IsVarassign():
854 searchIn(mkline.Varname(), VucLoadTime) 827 mkline.ForEachUsedText(mkline.Varname(), VucLoadTime, action)
855 searchIn(mkline.Value(), mkline.Op().Time()) 828 mkline.ForEachUsedText(mkline.Value(), mkline.Op().Time(), action)
856 829
857 case mkline.IsDirective() && mkline.Directive() == "for": 830 case mkline.IsDirective() && mkline.Directive() == "for":
858 searchIn(mkline.Args(), VucLoadTime) 831 mkline.ForEachUsedText(mkline.Args(), VucLoadTime, action)
859 832
860 case mkline.IsDirective() && (mkline.Directive() == "if" || mkline.Directive() == "elif") && mkline.Cond() != nil: 833 case mkline.IsDirective() && (mkline.Directive() == "if" || mkline.Directive() == "elif") && mkline.Cond() != nil:
861 mkline.Cond().Walk(&MkCondCallback{ 834 mkline.Cond().Walk(&MkCondCallback{
862 VarUse: func(varuse *MkVarUse) { 835 VarUse: func(varuse *MkVarUse) {
863 searchInVarUse(varuse, VucLoadTime) 836 mkline.ForEachUsedVarUse(varuse, VucLoadTime, action)
864 }}) 837 }})
865 838
866 case mkline.IsShellCommand(): 839 case mkline.IsShellCommand():
867 searchIn(mkline.ShellCommand(), VucRunTime) 840 mkline.ForEachUsedText(mkline.ShellCommand(), VucRunTime, action)
868 841
869 case mkline.IsDependency(): 842 case mkline.IsDependency():
870 searchIn(mkline.Targets(), VucLoadTime) 843 mkline.ForEachUsedText(mkline.Targets(), VucLoadTime, action)
871 searchIn(mkline.Sources(), VucLoadTime) 844 mkline.ForEachUsedText(mkline.Sources(), VucLoadTime, action)
872 845
873 case mkline.IsInclude(): 846 case mkline.IsInclude():
874 searchIn(mkline.IncludedFile().String(), VucLoadTime) 847 mkline.ForEachUsedText(mkline.IncludedFile().String(), VucLoadTime, action)
 848 }
 849}
 850
 851func (mkline *MkLine) ForEachUsedText(text string, time VucTime, action func(varUse *MkVarUse, time VucTime)) {
 852 if !contains(text, "$") {
 853 return
 854 }
 855
 856 tokens, _ := NewMkLexer(text, nil).MkTokens()
 857 for _, token := range tokens {
 858 if token.Varuse != nil {
 859 mkline.ForEachUsedVarUse(token.Varuse, time, action)
 860 }
 861 }
 862}
 863
 864func (mkline *MkLine) ForEachUsedVarUse(varuse *MkVarUse, time VucTime, action func(varUse *MkVarUse, time VucTime)) {
 865 varname := varuse.varname
 866 if !varuse.IsExpression() {
 867 action(varuse, time)
 868 }
 869 mkline.ForEachUsedText(varname, time, action)
 870 for _, mod := range varuse.modifiers {
 871 mkline.ForEachUsedText(mod.Text, time, action)
875 } 872 }
876} 873}
877 874
878// UnquoteShell removes one level of double and single quotes, 875// UnquoteShell removes one level of double and single quotes,
879// like in the shell. 876// like in the shell.
880// 877//
881// See ValueFields. 878// See ValueFields.
882func (mkline *MkLine) UnquoteShell(str string, warn bool) string { 879func (mkline *MkLine) UnquoteShell(str string, warn bool) string {
883 sb := NewLazyStringBuilder(str) 880 sb := NewLazyStringBuilder(str)
884 lexer := NewMkTokensLexer(mkline.Tokenize(str, false)) 881 lexer := NewMkTokensLexer(mkline.Tokenize(str, false))
885 882
886 plain := func() { 883 plain := func() {
887 varUse := lexer.NextVarUse() 884 varUse := lexer.NextVarUse()

cvs diff -r1.40 -r1.41 pkgsrc/pkgtools/pkglint/files/Attic/patches.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/patches.go 2020/05/08 19:50:04 1.40
+++ pkgsrc/pkgtools/pkglint/files/Attic/patches.go 2020/05/29 20:13:17 1.41
@@ -91,37 +91,56 @@ func (ck *PatchChecker) Check(pkg *Packa @@ -91,37 +91,56 @@ func (ck *PatchChecker) Check(pkg *Packa
91 CheckLinesTrailingEmptyLines(ck.lines) 91 CheckLinesTrailingEmptyLines(ck.lines)
92 sha1Before := computePatchSha1Hex(ck.lines) 92 sha1Before := computePatchSha1Hex(ck.lines)
93 if SaveAutofixChanges(ck.lines) && pkg != nil { 93 if SaveAutofixChanges(ck.lines) && pkg != nil {
94 linesAfter := Load(ck.lines.Filename, 0) 94 linesAfter := Load(ck.lines.Filename, 0)
95 sha1After := computePatchSha1Hex(linesAfter) 95 sha1After := computePatchSha1Hex(linesAfter)
96 pkg.AutofixDistinfo(sha1Before, sha1After) 96 pkg.AutofixDistinfo(sha1Before, sha1After)
97 } 97 }
98} 98}
99 99
100// See https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html 100// See https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html
101func (ck *PatchChecker) checkUnifiedDiff(patchedFile Path) { 101func (ck *PatchChecker) checkUnifiedDiff(patchedFile Path) {
102 isConfigure := ck.isConfigure(patchedFile) 102 isConfigure := ck.isConfigure(patchedFile)
103 103
 104 linesDiff := 0
104 hasHunks := false 105 hasHunks := false
105 for { 106 for {
106 m := ck.llex.NextRegexp(rePatchUniHunk) 107 m := ck.llex.NextRegexp(rePatchUniHunk)
107 if m == nil { 108 if m == nil {
108 break 109 break
109 } 110 }
110 111
111 text := m[0] 112 text := m[0]
112 hasHunks = true 113 hasHunks = true
 114 linenoDel := toInt(m[1], 0)
113 linesToDel := toInt(m[2], 1) 115 linesToDel := toInt(m[2], 1)
 116 linenoAdd := toInt(m[3], 0)
114 linesToAdd := toInt(m[4], 1) 117 linesToAdd := toInt(m[4], 1)
 118 if linenoDel > 0 && linenoAdd > 0 && linenoDel+linesDiff != linenoAdd {
 119 line := ck.llex.PreviousLine()
 120 line.Notef("The difference between the line numbers %d and %d should be %d, not %d.",
 121 linenoDel, linenoAdd, linesDiff, linenoAdd-linenoDel)
 122 line.Explain(
 123 "This only happens when patches are edited manually.",
 124 "",
 125 "To fix this, either regenerate the line numbers by first running",
 126 bmake("patch"),
 127 "and then \"mkpatches\", or edit the line numbers by hand.",
 128 "",
 129 "While here, it's a good idea to make the patch apply really cleanly,",
 130 "by ensuring that the output from the patch command does not contain",
 131 "the word \"offset\", like in \"Hunk #11 succeeded at 2598 (offset 10 lines).")
 132 }
 133 linesDiff += linesToAdd - linesToDel
115 134
116 ck.checktextUniHunkCr() 135 ck.checktextUniHunkCr()
117 ck.checktextCvsID(text) 136 ck.checktextCvsID(text)
118 137
119 for !ck.llex.EOF() && (linesToDel > 0 || linesToAdd > 0 || hasPrefix(ck.llex.CurrentLine().Text, "\\")) { 138 for !ck.llex.EOF() && (linesToDel > 0 || linesToAdd > 0 || hasPrefix(ck.llex.CurrentLine().Text, "\\")) {
120 line := ck.llex.CurrentLine() 139 line := ck.llex.CurrentLine()
121 ck.llex.Skip() 140 ck.llex.Skip()
122 141
123 text := line.Text 142 text := line.Text
124 switch { 143 switch {
125 144
126 case text == "": 145 case text == "":
127 // There should be a space here, but that was a trailing space and 146 // There should be a space here, but that was a trailing space and

cvs diff -r1.39 -r1.40 pkgsrc/pkgtools/pkglint/files/Attic/patches_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/patches_test.go 2020/05/08 19:50:04 1.39
+++ pkgsrc/pkgtools/pkglint/files/Attic/patches_test.go 2020/05/29 20:13:17 1.40
@@ -609,45 +609,69 @@ func (s *Suite) Test_PatchChecker_Check_ @@ -609,45 +609,69 @@ func (s *Suite) Test_PatchChecker_Check_
609 "@@ -1,1 +1,1 @@", 609 "@@ -1,1 +1,1 @@",
610 "- prefix := @prefix@", 610 "- prefix := @prefix@",
611 "+ prefix := /usr/pkg") 611 "+ prefix := /usr/pkg")
612 612
613 CheckLinesPatch(lines, nil) 613 CheckLinesPatch(lines, nil)
614 614
615 t.CheckOutputLines( 615 t.CheckOutputLines(
616 "ERROR: ~/patch-aa:9: Patches must not hard-code the pkgsrc PREFIX.") 616 "ERROR: ~/patch-aa:9: Patches must not hard-code the pkgsrc PREFIX.")
617} 617}
618 618
619func (s *Suite) Test_PatchChecker_checkUnifiedDiff__lines_at_end(c *check.C) { 619func (s *Suite) Test_PatchChecker_checkUnifiedDiff__lines_at_end(c *check.C) {
620 t := s.Init(c) 620 t := s.Init(c)
621 621
622 lines := t.SetUpFileLines("patch-aa", 622 lines := t.NewLines("patch-aa",
623 CvsID, 623 CvsID,
624 "", 624 "",
625 "Documentation", 625 "Documentation",
626 "", 626 "",
627 "--- old", 627 "--- old",
628 "+++ new", 628 "+++ new",
629 "@@ -1,1 +1,1 @@", 629 "@@ -1,1 +1,1 @@",
630 "- old", 630 "- old",
631 "+ new", 631 "+ new",
632 "", 632 "",
633 "This line is not part of the patch. Since it is separated from", 633 "This line is not part of the patch. Since it is separated from",
634 "the patch by an empty line, there is no reason for a warning.") 634 "the patch by an empty line, there is no reason for a warning.")
635 635
636 CheckLinesPatch(lines, nil) 636 CheckLinesPatch(lines, nil)
637 637
638 t.CheckOutputEmpty() 638 t.CheckOutputEmpty()
639} 639}
640 640
 641func (s *Suite) Test_PatchChecker_checkUnifiedDiff__line_number_mismatch(c *check.C) {
 642 t := s.Init(c)
 643
 644 lines := t.NewLines("patch-aa",
 645 CvsID,
 646 "",
 647 "Documentation",
 648 "",
 649 "--- old",
 650 "+++ new",
 651 "@@ -2,1 +1,1 @@",
 652 "- old",
 653 "+ new",
 654 "@@ -5,1 +7,1 @@",
 655 "- old",
 656 "+ new")
 657
 658 CheckLinesPatch(lines, nil)
 659
 660 t.CheckOutputLines(
 661 "NOTE: patch-aa:7: The difference between the line numbers 2 and 1 should be 0, not -1.",
 662 "NOTE: patch-aa:10: The difference between the line numbers 5 and 7 should be 0, not 2.")
 663}
 664
641func (s *Suite) Test_PatchChecker_checkBeginDiff__multiple_patches_without_documentation(c *check.C) { 665func (s *Suite) Test_PatchChecker_checkBeginDiff__multiple_patches_without_documentation(c *check.C) {
642 t := s.Init(c) 666 t := s.Init(c)
643 667
644 lines := t.SetUpFileLines("patch-aa", 668 lines := t.SetUpFileLines("patch-aa",
645 CvsID, 669 CvsID,
646 "", 670 "",
647 "--- old", 671 "--- old",
648 "+++ new", 672 "+++ new",
649 "@@ -1,1 +1,1 @@", 673 "@@ -1,1 +1,1 @@",
650 "- old", 674 "- old",
651 "+ new", 675 "+ new",
652 "", 676 "",
653 "--- old", 677 "--- old",

cvs diff -r1.88 -r1.89 pkgsrc/pkgtools/pkglint/files/Attic/vartypecheck.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/vartypecheck.go 2020/05/23 08:51:08 1.88
+++ pkgsrc/pkgtools/pkglint/files/Attic/vartypecheck.go 2020/05/29 20:13:17 1.89
@@ -1132,26 +1132,34 @@ func (cv *VartypeCheck) PlistIdentifier( @@ -1132,26 +1132,34 @@ func (cv *VartypeCheck) PlistIdentifier(
1132 "there should be a corresponding ${PLIST.identifier}", 1132 "there should be a corresponding ${PLIST.identifier}",
1133 "in any of the PLIST files of the package.") 1133 "in any of the PLIST files of the package.")
1134 } 1134 }
1135} 1135}
1136 1136
1137// PrefixPathname checks for a pathname relative to ${PREFIX}. 1137// PrefixPathname checks for a pathname relative to ${PREFIX}.
1138func (cv *VartypeCheck) PrefixPathname() { 1138func (cv *VartypeCheck) PrefixPathname() {
1139 if NewPath(cv.Value).IsAbs() { 1139 if NewPath(cv.Value).IsAbs() {
1140 cv.Errorf("The pathname %q in %s must be relative to ${PREFIX}.", 1140 cv.Errorf("The pathname %q in %s must be relative to ${PREFIX}.",
1141 cv.Value, cv.Varname) 1141 cv.Value, cv.Varname)
1142 return 1142 return
1143 } 1143 }
1144 1144
 1145 cv.MkLine.ForEachUsedText(cv.Value, VucRunTime, func(varUse *MkVarUse, time VucTime) {
 1146 varname := varUse.varname
 1147 if varname == "PKG_SYSCONFDIR" || varname == "VARBASE" {
 1148 cv.Errorf("%s must not be used in %s since it is not relative to PREFIX.",
 1149 varname, cv.Varname)
 1150 }
 1151 })
 1152
1145 if m, manSubdir := match1(cv.Value, `^man/(.+)`); m { 1153 if m, manSubdir := match1(cv.Value, `^man/(.+)`); m {
1146 from := "${PKGMANDIR}/" + manSubdir 1154 from := "${PKGMANDIR}/" + manSubdir
1147 fix := cv.Autofix() 1155 fix := cv.Autofix()
1148 fix.Warnf("Please use %q instead of %q.", from, cv.Value) 1156 fix.Warnf("Please use %q instead of %q.", from, cv.Value)
1149 fix.Replace(cv.Value, from) 1157 fix.Replace(cv.Value, from)
1150 fix.Apply() 1158 fix.Apply()
1151 } 1159 }
1152} 1160}
1153 1161
1154func (cv *VartypeCheck) PythonDependency() { 1162func (cv *VartypeCheck) PythonDependency() {
1155 if cv.Value != cv.ValueNoVar { 1163 if cv.Value != cv.ValueNoVar {
1156 cv.Warnf("Python dependencies should not contain variables.") 1164 cv.Warnf("Python dependencies should not contain variables.")
1157 } else if !matches(cv.ValueNoVar, `^[+\-.0-9A-Z_a-z]+(?:|:link|:build|:test|:tool)$`) { 1165 } else if !matches(cv.ValueNoVar, `^[+\-.0-9A-Z_a-z]+(?:|:link|:build|:test|:tool)$`) {

cvs diff -r1.79 -r1.80 pkgsrc/pkgtools/pkglint/files/Attic/vartypecheck_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/vartypecheck_test.go 2020/04/13 19:46:44 1.79
+++ pkgsrc/pkgtools/pkglint/files/Attic/vartypecheck_test.go 2020/05/29 20:13:17 1.80
@@ -1610,26 +1610,36 @@ func (s *Suite) Test_VartypeCheck_Prefix @@ -1610,26 +1610,36 @@ func (s *Suite) Test_VartypeCheck_Prefix
1610 vt := NewVartypeCheckTester(s.Init(c), BtPrefixPathname) 1610 vt := NewVartypeCheckTester(s.Init(c), BtPrefixPathname)
1611 1611
1612 vt.Varname("PKGMANDIR") 1612 vt.Varname("PKGMANDIR")
1613 vt.Values( 1613 vt.Values(
1614 "man/man1", 1614 "man/man1",
1615 "share/locale", 1615 "share/locale",
1616 "/absolute") 1616 "/absolute")
1617 1617
1618 vt.Output( 1618 vt.Output(
1619 "WARN: filename.mk:1: "+ 1619 "WARN: filename.mk:1: "+
1620 "Please use \"${PKGMANDIR}/man1\" instead of \"man/man1\".", 1620 "Please use \"${PKGMANDIR}/man1\" instead of \"man/man1\".",
1621 "ERROR: filename.mk:3: The pathname \"/absolute\" in PKGMANDIR "+ 1621 "ERROR: filename.mk:3: The pathname \"/absolute\" in PKGMANDIR "+
1622 "must be relative to ${PREFIX}.") 1622 "must be relative to ${PREFIX}.")
 1623
 1624 vt.Varname("INSTALLATION_DIRS")
 1625 vt.Values(
 1626 "bin ${PKG_SYSCONFDIR} ${VARBASE}")
 1627
 1628 vt.Output(
 1629 "ERROR: filename.mk:11: PKG_SYSCONFDIR must not be used in INSTALLATION_DIRS "+
 1630 "since it is not relative to PREFIX.",
 1631 "ERROR: filename.mk:11: VARBASE must not be used in INSTALLATION_DIRS "+
 1632 "since it is not relative to PREFIX.")
1623} 1633}
1624 1634
1625func (s *Suite) Test_VartypeCheck_PythonDependency(c *check.C) { 1635func (s *Suite) Test_VartypeCheck_PythonDependency(c *check.C) {
1626 vt := NewVartypeCheckTester(s.Init(c), BtPythonDependency) 1636 vt := NewVartypeCheckTester(s.Init(c), BtPythonDependency)
1627 1637
1628 vt.Varname("PYTHON_VERSIONED_DEPENDENCIES") 1638 vt.Varname("PYTHON_VERSIONED_DEPENDENCIES")
1629 vt.Values( 1639 vt.Values(
1630 "cairo", 1640 "cairo",
1631 "${PYDEP}", 1641 "${PYDEP}",
1632 "cairo,X") 1642 "cairo,X")
1633 1643
1634 vt.Output( 1644 vt.Output(
1635 "WARN: filename.mk:2: Python dependencies should not contain variables.", 1645 "WARN: filename.mk:2: Python dependencies should not contain variables.",