Mon Feb 19 12:40:38 2018 UTC ()
pkgtools/pkglint: update to 5.5.5

Changes since 5.5.3:

- Removed check for PERL5_PACKLIST, since it was not fixable by the
  package author.

- Completely rewrote the check for ordering variables in simple
  package Makefiles. Now it reports the variables in the correct order
  instead of just saying "this above that" for a few variables.

- Lots of code cleanup and documentation.


(rillig)
diff -r1.528 -r1.529 pkgsrc/pkgtools/pkglint/Makefile
diff -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/autofix.go
diff -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/autofix_test.go
diff -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/mktypes.go
diff -r1.11 -r1.12 pkgsrc/pkgtools/pkglint/files/buildlink3_test.go
diff -r1.7 -r1.8 pkgsrc/pkgtools/pkglint/files/category_test.go
diff -r1.16 -r1.17 pkgsrc/pkgtools/pkglint/files/check_test.go
diff -r1.16 -r1.17 pkgsrc/pkgtools/pkglint/files/mklines_test.go
diff -r1.12 -r1.13 pkgsrc/pkgtools/pkglint/files/distinfo_test.go
diff -r1.12 -r1.13 pkgsrc/pkgtools/pkglint/files/vartype.go
diff -r1.15 -r1.16 pkgsrc/pkgtools/pkglint/files/files.go
diff -r1.15 -r1.16 pkgsrc/pkgtools/pkglint/files/patches_test.go
diff -r1.24 -r1.25 pkgsrc/pkgtools/pkglint/files/globaldata.go
diff -r1.24 -r1.25 pkgsrc/pkgtools/pkglint/files/package.go
diff -r1.13 -r1.14 pkgsrc/pkgtools/pkglint/files/globaldata_test.go
diff -r1.27 -r1.28 pkgsrc/pkgtools/pkglint/files/mkline.go
diff -r1.30 -r1.31 pkgsrc/pkgtools/pkglint/files/mkline_test.go
diff -r1.8 -r1.9 pkgsrc/pkgtools/pkglint/files/mklinechecker.go
diff -r1.8 -r1.9 pkgsrc/pkgtools/pkglint/files/mkparser_test.go
diff -r1.8 -r1.9 pkgsrc/pkgtools/pkglint/files/toplevel.go
diff -r1.8 -r1.9 pkgsrc/pkgtools/pkglint/files/toplevel_test.go
diff -r1.6 -r1.7 pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go
diff -r1.6 -r1.7 pkgsrc/pkgtools/pkglint/files/shtypes.go
diff -r1.17 -r1.18 pkgsrc/pkgtools/pkglint/files/package_test.go
diff -r1.19 -r1.20 pkgsrc/pkgtools/pkglint/files/patches.go
diff -r1.26 -r1.27 pkgsrc/pkgtools/pkglint/files/pkglint.go
diff -r1.14 -r1.15 pkgsrc/pkgtools/pkglint/files/pkglint_test.go
diff -r1.21 -r1.22 pkgsrc/pkgtools/pkglint/files/plist.go
diff -r1.20 -r1.21 pkgsrc/pkgtools/pkglint/files/plist_test.go
diff -r1.20 -r1.21 pkgsrc/pkgtools/pkglint/files/shell.go
diff -r1.20 -r1.21 pkgsrc/pkgtools/pkglint/files/shell_test.go
diff -r1.35 -r1.36 pkgsrc/pkgtools/pkglint/files/vardefs.go
diff -r1.4 -r1.5 pkgsrc/pkgtools/pkglint/files/vartype_test.go
diff -r1.28 -r1.29 pkgsrc/pkgtools/pkglint/files/vartypecheck.go
diff -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/textproc/prefixreplacer.go

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

--- pkgsrc/pkgtools/pkglint/Makefile 2018/01/28 23:21:16 1.528
+++ pkgsrc/pkgtools/pkglint/Makefile 2018/02/19 12:40:38 1.529
@@ -1,16 +1,16 @@ @@ -1,16 +1,16 @@
1# $NetBSD: Makefile,v 1.528 2018/01/28 23:21:16 rillig Exp $ 1# $NetBSD: Makefile,v 1.529 2018/02/19 12:40:38 rillig Exp $
2 2
3PKGNAME= pkglint-5.5.3 3PKGNAME= pkglint-5.5.5
4DISTFILES= # none 4DISTFILES= # none
5CATEGORIES= pkgtools 5CATEGORIES= pkgtools
6 6
7MAINTAINER= rillig@NetBSD.org 7MAINTAINER= rillig@NetBSD.org
8HOMEPAGE= https://github.com/rillig/pkglint 8HOMEPAGE= https://github.com/rillig/pkglint
9COMMENT= Verifier for NetBSD packages 9COMMENT= Verifier for NetBSD packages
10LICENSE= 2-clause-bsd 10LICENSE= 2-clause-bsd
11CONFLICTS+= pkglint4-[0-9]* 11CONFLICTS+= pkglint4-[0-9]*
12 12
13NO_CHECKSUM= yes 13NO_CHECKSUM= yes
14USE_LANGUAGES= c 14USE_LANGUAGES= c
15USE_TOOLS+= pax 15USE_TOOLS+= pax
16AUTO_MKDIRS= yes 16AUTO_MKDIRS= yes

cvs diff -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/Attic/autofix.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/autofix.go 2018/01/28 23:21:16 1.3
+++ pkgsrc/pkgtools/pkglint/files/Attic/autofix.go 2018/02/19 12:40:38 1.4
@@ -150,27 +150,27 @@ func (fix *Autofix) Realign(mkline MkLin @@ -150,27 +150,27 @@ func (fix *Autofix) Realign(mkline MkLin
150} 150}
151 151
152// InsertBefore prepends a line before the current line. 152// InsertBefore prepends a line before the current line.
153// The newline is added internally. 153// The newline is added internally.
154func (fix *Autofix) InsertBefore(text string) { 154func (fix *Autofix) InsertBefore(text string) {
155 if fix.skip() { 155 if fix.skip() {
156 return 156 return
157 } 157 }
158 158
159 fix.linesBefore = append(fix.linesBefore, text+"\n") 159 fix.linesBefore = append(fix.linesBefore, text+"\n")
160 fix.Describef(fix.lines[0].Lineno, "Inserting a line %q before this line.", text) 160 fix.Describef(fix.lines[0].Lineno, "Inserting a line %q before this line.", text)
161} 161}
162 162
163// InsertBefore appends a line after the current line. 163// InsertAfter appends a line after the current line.
164// The newline is added internally. 164// The newline is added internally.
165func (fix *Autofix) InsertAfter(text string) { 165func (fix *Autofix) InsertAfter(text string) {
166 if fix.skip() { 166 if fix.skip() {
167 return 167 return
168 } 168 }
169 169
170 fix.linesAfter = append(fix.linesAfter, text+"\n") 170 fix.linesAfter = append(fix.linesAfter, text+"\n")
171 fix.Describef(fix.lines[len(fix.lines)-1].Lineno, "Inserting a line %q after this line.", text) 171 fix.Describef(fix.lines[len(fix.lines)-1].Lineno, "Inserting a line %q after this line.", text)
172} 172}
173 173
174func (fix *Autofix) Delete() { 174func (fix *Autofix) Delete() {
175 if fix.skip() { 175 if fix.skip() {
176 return 176 return
@@ -186,46 +186,47 @@ func (fix *Autofix) Delete() { @@ -186,46 +186,47 @@ func (fix *Autofix) Delete() {
186// for logging it later when Apply is called. 186// for logging it later when Apply is called.
187// There may be multiple fixes in one pass. 187// There may be multiple fixes in one pass.
188func (fix *Autofix) Describef(lineno int, format string, args ...interface{}) { 188func (fix *Autofix) Describef(lineno int, format string, args ...interface{}) {
189 fix.actions = append(fix.actions, autofixAction{fmt.Sprintf(format, args...), lineno}) 189 fix.actions = append(fix.actions, autofixAction{fmt.Sprintf(format, args...), lineno})
190} 190}
191 191
192// Notef remembers the note for logging it later when Apply is called. 192// Notef remembers the note for logging it later when Apply is called.
193func (fix *Autofix) Notef(format string, args ...interface{}) { 193func (fix *Autofix) Notef(format string, args ...interface{}) {
194 fix.level = llNote 194 fix.level = llNote
195 fix.diagFormat = format 195 fix.diagFormat = format
196 fix.diagArgs = args 196 fix.diagArgs = args
197} 197}
198 198
199// Notef remembers the warning for logging it later when Apply is called. 199// Warnf remembers the warning for logging it later when Apply is called.
200func (fix *Autofix) Warnf(format string, args ...interface{}) { 200func (fix *Autofix) Warnf(format string, args ...interface{}) {
201 fix.level = llWarn 201 fix.level = llWarn
202 fix.diagFormat = format 202 fix.diagFormat = format
203 fix.diagArgs = args 203 fix.diagArgs = args
204} 204}
205 205
206// Notef remembers the error for logging it later when Apply is called. 206// Errorf remembers the error for logging it later when Apply is called.
207func (fix *Autofix) Errorf(format string, args ...interface{}) { 207func (fix *Autofix) Errorf(format string, args ...interface{}) {
208 fix.level = llError 208 fix.level = llError
209 fix.diagFormat = format 209 fix.diagFormat = format
210 fix.diagArgs = args 210 fix.diagArgs = args
211} 211}
212 212
213// Explain remembers the explanation for logging it later when Apply is called. 213// Explain remembers the explanation for logging it later when Apply is called.
214func (fix *Autofix) Explain(explanation ...string) { 214func (fix *Autofix) Explain(explanation ...string) {
215 fix.explanation = explanation 215 fix.explanation = explanation
216} 216}
217 217
218// Depending on the pkglint mode, either: 218// Apply does the actual work.
 219// Depending on the pkglint mode, it either:
219// 220//
220// * logs the associated message (default) 221// * logs the associated message (default)
221// * logs what would be fixed (--show-autofix) 222// * logs what would be fixed (--show-autofix)
222// * records the fixes in the line (--autofix) 223// * records the fixes in the line (--autofix)
223func (fix *Autofix) Apply() { 224func (fix *Autofix) Apply() {
224 line := fix.line 225 line := fix.line
225 if line.firstLine < 1 { 226 if line.firstLine < 1 {
226 return 227 return
227 } 228 }
228 229
229 if shallBeLogged(fix.diagFormat) { 230 if shallBeLogged(fix.diagFormat) {
230 logDiagnostic := fix.level != nil && fix.diagFormat != "Silent-Magic-Diagnostic" && 231 logDiagnostic := fix.level != nil && fix.diagFormat != "Silent-Magic-Diagnostic" &&
231 !(G.opts.Autofix && !G.opts.PrintAutofix) && len(fix.actions) > 0 232 !(G.opts.Autofix && !G.opts.PrintAutofix) && len(fix.actions) > 0

cvs diff -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/Attic/autofix_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/autofix_test.go 2018/01/28 23:21:16 1.3
+++ pkgsrc/pkgtools/pkglint/files/Attic/autofix_test.go 2018/02/19 12:40:38 1.4
@@ -245,27 +245,27 @@ func (s *Suite) Test_Autofix_multiple_mo @@ -245,27 +245,27 @@ func (s *Suite) Test_Autofix_multiple_mo
245 c.Check(line.autofix.lines[0].textnl, equals, "") 245 c.Check(line.autofix.lines[0].textnl, equals, "")
246 c.Check(line.autofix.linesAfter, deepEquals, []string{ 246 c.Check(line.autofix.linesAfter, deepEquals, []string{
247 "between middle and after\n", 247 "between middle and after\n",
248 "after\n"}) 248 "after\n"})
249 t.CheckOutputLines( 249 t.CheckOutputLines(
250 "AUTOFIX: fname:1: Deleting this line.") 250 "AUTOFIX: fname:1: Deleting this line.")
251} 251}
252 252
253func (s *Suite) Test_Autofix_show_source_code(c *check.C) { 253func (s *Suite) Test_Autofix_show_source_code(c *check.C) {
254 t := s.Init(c) 254 t := s.Init(c)
255 255
256 t.SetupCommandLine("--show-autofix", "--source") 256 t.SetupCommandLine("--show-autofix", "--source")
257 lines := t.SetupFileLinesContinuation("Makefile", 257 lines := t.SetupFileLinesContinuation("Makefile",
258 MkRcsId, 258 MkRcsID,
259 "before \\", 259 "before \\",
260 "The old song \\", 260 "The old song \\",
261 "after") 261 "after")
262 line := lines[1] 262 line := lines[1]
263 263
264 { 264 {
265 fix := line.Autofix() 265 fix := line.Autofix()
266 fix.Warnf("Using \"old\" is deprecated.") 266 fix.Warnf("Using \"old\" is deprecated.")
267 fix.Replace("old", "new") 267 fix.Replace("old", "new")
268 fix.Apply() 268 fix.Apply()
269 } 269 }
270 270
271 t.CheckOutputLines( 271 t.CheckOutputLines(

cvs diff -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/Attic/mktypes.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/mktypes.go 2018/01/01 18:04:15 1.3
+++ pkgsrc/pkgtools/pkglint/files/Attic/mktypes.go 2018/02/19 12:40:38 1.4
@@ -1,21 +1,26 @@ @@ -1,21 +1,26 @@
1package main 1package main
2 2
 3// MkToken represents a contiguous string from a Makefile.
 4// It is either a literal string or a variable use.
 5//
3// Example (3 tokens): /usr/share/${PKGNAME}/data 6// Example (3 tokens): /usr/share/${PKGNAME}/data
4type MkToken struct { 7type MkToken struct {
5 Text string // Used for both literals and varuses. 8 Text string // Used for both literals and varuses.
6 Varuse *MkVarUse 9 Varuse *MkVarUse
7} 10}
8 11
 12// MkVarUse represents a reference to a Make variable, with optional modifiers.
 13//
9// Example: ${PKGNAME} 14// Example: ${PKGNAME}
10// Example: ${PKGNAME:S/from/to/} 15// Example: ${PKGNAME:S/from/to/}
11type MkVarUse struct { 16type MkVarUse struct {
12 varname string 17 varname string
13 modifiers []string // E.g. "Q", "S/from/to/" 18 modifiers []string // E.g. "Q", "S/from/to/"
14} 19}
15 20
16func (vu *MkVarUse) Mod() string { 21func (vu *MkVarUse) Mod() string {
17 mod := "" 22 mod := ""
18 for _, modifier := range vu.modifiers { 23 for _, modifier := range vu.modifiers {
19 mod += ":" + modifier 24 mod += ":" + modifier
20 } 25 }
21 return mod 26 return mod

cvs diff -r1.11 -r1.12 pkgsrc/pkgtools/pkglint/files/Attic/buildlink3_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/buildlink3_test.go 2018/01/27 18:50:36 1.11
+++ pkgsrc/pkgtools/pkglint/files/Attic/buildlink3_test.go 2018/02/19 12:40:38 1.12
@@ -1,23 +1,23 @@ @@ -1,23 +1,23 @@
1package main 1package main
2 2
3import "gopkg.in/check.v1" 3import "gopkg.in/check.v1"
4 4
5func (s *Suite) Test_ChecklinesBuildlink3Mk(c *check.C) { 5func (s *Suite) Test_ChecklinesBuildlink3Mk(c *check.C) {
6 t := s.Init(c) 6 t := s.Init(c)
7 7
8 G.globalData.InitVartypes() 8 G.globalData.InitVartypes()
9 mklines := t.NewMkLines("buildlink3.mk", 9 mklines := t.NewMkLines("buildlink3.mk",
10 MkRcsId, 10 MkRcsID,
11 "# XXX This file was created automatically using createbuildlink-@PKGVERSION@", 11 "# XXX This file was created automatically using createbuildlink-@PKGVERSION@",
12 "", 12 "",
13 "BUILDLINK_TREE+= Xbae", 13 "BUILDLINK_TREE+= Xbae",
14 "", 14 "",
15 "BUILDLINK_DEPMETHOD.Xbae?=\tfull", 15 "BUILDLINK_DEPMETHOD.Xbae?=\tfull",
16 ".if !defined(XBAE_BUILDLINK3_MK)", 16 ".if !defined(XBAE_BUILDLINK3_MK)",
17 "XBAE_BUILDLINK3_MK:=", 17 "XBAE_BUILDLINK3_MK:=",
18 "", 18 "",
19 "BUILDLINK_API_DEPENDS.Xbae+= Xbae>=4.8.4", 19 "BUILDLINK_API_DEPENDS.Xbae+= Xbae>=4.8.4",
20 "BUILDLINK_ABI_DEPENDS.Xbae+= Xbae>=4.51.01nb2", 20 "BUILDLINK_ABI_DEPENDS.Xbae+= Xbae>=4.51.01nb2",
21 "BUILDLINK_PKGSRCDIR.Xbae?= ../../x11/Xbae", 21 "BUILDLINK_PKGSRCDIR.Xbae?= ../../x11/Xbae",
22 "", 22 "",
23 ".include \"../../mk/motif.buildlink3.mk\"", 23 ".include \"../../mk/motif.buildlink3.mk\"",
@@ -35,149 +35,149 @@ func (s *Suite) Test_ChecklinesBuildlink @@ -35,149 +35,149 @@ func (s *Suite) Test_ChecklinesBuildlink
35} 35}
36 36
37// Before version 5.3, pkglint wrongly warned here. 37// Before version 5.3, pkglint wrongly warned here.
38// The mk/haskell.mk file takes care of constructing the correct PKGNAME, 38// The mk/haskell.mk file takes care of constructing the correct PKGNAME,
39// but pkglint had not looked at that file. 39// but pkglint had not looked at that file.
40func (s *Suite) Test_ChecklinesBuildlink3Mk_name_mismatch(c *check.C) { 40func (s *Suite) Test_ChecklinesBuildlink3Mk_name_mismatch(c *check.C) {
41 t := s.Init(c) 41 t := s.Init(c)
42 42
43 G.globalData.InitVartypes() 43 G.globalData.InitVartypes()
44 G.Pkg = NewPackage("x11/hs-X11") 44 G.Pkg = NewPackage("x11/hs-X11")
45 G.Pkg.EffectivePkgbase = "X11" 45 G.Pkg.EffectivePkgbase = "X11"
46 G.Pkg.EffectivePkgnameLine = t.NewMkLine("Makefile", 3, "DISTNAME=\tX11-1.0") 46 G.Pkg.EffectivePkgnameLine = t.NewMkLine("Makefile", 3, "DISTNAME=\tX11-1.0")
47 mklines := t.NewMkLines("buildlink3.mk", 47 mklines := t.NewMkLines("buildlink3.mk",
48 MkRcsId, 48 MkRcsID,
49 "", 49 "",
50 "BUILDLINK_TREE+=\ths-X11", 50 "BUILDLINK_TREE+=\ths-X11",
51 "", 51 "",
52 ".if !defined(HS_X11_BUILDLINK3_MK)", 52 ".if !defined(HS_X11_BUILDLINK3_MK)",
53 "HS_X11_BUILDLINK3_MK:=", 53 "HS_X11_BUILDLINK3_MK:=",
54 "", 54 "",
55 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11>=1.6.1", 55 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11>=1.6.1",
56 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X11>=1.6.1.2nb2", 56 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X11>=1.6.1.2nb2",
57 "", 57 "",
58 ".endif\t# HS_X11_BUILDLINK3_MK", 58 ".endif\t# HS_X11_BUILDLINK3_MK",
59 "", 59 "",
60 "BUILDLINK_TREE+=\t-hs-X11") 60 "BUILDLINK_TREE+=\t-hs-X11")
61 61
62 ChecklinesBuildlink3Mk(mklines) 62 ChecklinesBuildlink3Mk(mklines)
63 63
64 t.CheckOutputLines( 64 t.CheckOutputLines(
65 "ERROR: buildlink3.mk:3: Package name mismatch between \"hs-X11\" in this file and \"X11\" from Makefile:3.") 65 "ERROR: buildlink3.mk:3: Package name mismatch between \"hs-X11\" in this file and \"X11\" from Makefile:3.")
66} 66}
67 67
68func (s *Suite) Test_ChecklinesBuildlink3Mk_name_mismatch_multiple_inclusion(c *check.C) { 68func (s *Suite) Test_ChecklinesBuildlink3Mk_name_mismatch_multiple_inclusion(c *check.C) {
69 t := s.Init(c) 69 t := s.Init(c)
70 70
71 G.globalData.InitVartypes() 71 G.globalData.InitVartypes()
72 mklines := t.NewMkLines("buildlink3.mk", 72 mklines := t.NewMkLines("buildlink3.mk",
73 MkRcsId, 73 MkRcsID,
74 "", 74 "",
75 "BUILDLINK_TREE+=\tpkgbase1", 75 "BUILDLINK_TREE+=\tpkgbase1",
76 "", 76 "",
77 ".if !defined(PKGBASE2_BUILDLINK3_MK)", 77 ".if !defined(PKGBASE2_BUILDLINK3_MK)",
78 "PKGBASE2_BUILDLINK3_MK:=", 78 "PKGBASE2_BUILDLINK3_MK:=",
79 "", 79 "",
80 ".endif", 80 ".endif",
81 "", 81 "",
82 "BUILDLINK_TREE+=\t-pkgbase1") 82 "BUILDLINK_TREE+=\t-pkgbase1")
83 83
84 ChecklinesBuildlink3Mk(mklines) 84 ChecklinesBuildlink3Mk(mklines)
85 85
86 t.CheckOutputLines( 86 t.CheckOutputLines(
87 "ERROR: buildlink3.mk:5: Package name mismatch between multiple-inclusion guard \"PKGBASE2\" (expected \"PKGBASE1\") and package name \"pkgbase1\" (from line 3).", 87 "ERROR: buildlink3.mk:5: Package name mismatch between multiple-inclusion guard \"PKGBASE2\" (expected \"PKGBASE1\") and package name \"pkgbase1\" (from line 3).",
88 "WARN: buildlink3.mk:9: Definition of BUILDLINK_API_DEPENDS is missing.") 88 "WARN: buildlink3.mk:9: Definition of BUILDLINK_API_DEPENDS is missing.")
89} 89}
90 90
91func (s *Suite) Test_ChecklinesBuildlink3Mk_name_mismatch_abi_api(c *check.C) { 91func (s *Suite) Test_ChecklinesBuildlink3Mk_name_mismatch_abi_api(c *check.C) {
92 t := s.Init(c) 92 t := s.Init(c)
93 93
94 G.globalData.InitVartypes() 94 G.globalData.InitVartypes()
95 mklines := t.NewMkLines("buildlink3.mk", 95 mklines := t.NewMkLines("buildlink3.mk",
96 MkRcsId, 96 MkRcsID,
97 "", 97 "",
98 "BUILDLINK_TREE+=\ths-X11", 98 "BUILDLINK_TREE+=\ths-X11",
99 "", 99 "",
100 ".if !defined(HS_X11_BUILDLINK3_MK)", 100 ".if !defined(HS_X11_BUILDLINK3_MK)",
101 "HS_X11_BUILDLINK3_MK:=", 101 "HS_X11_BUILDLINK3_MK:=",
102 "", 102 "",
103 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11>=1.6.1", 103 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11>=1.6.1",
104 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X12>=1.6.1.2nb2", 104 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X12>=1.6.1.2nb2",
105 "", 105 "",
106 ".endif\t# HS_X11_BUILDLINK3_MK", 106 ".endif\t# HS_X11_BUILDLINK3_MK",
107 "", 107 "",
108 "BUILDLINK_TREE+=\t-hs-X11") 108 "BUILDLINK_TREE+=\t-hs-X11")
109 109
110 ChecklinesBuildlink3Mk(mklines) 110 ChecklinesBuildlink3Mk(mklines)
111 111
112 t.CheckOutputLines( 112 t.CheckOutputLines(
113 "WARN: buildlink3.mk:9: Package name mismatch between ABI \"hs-X12\" and API \"hs-X11\" (from line 8).") 113 "WARN: buildlink3.mk:9: Package name mismatch between ABI \"hs-X12\" and API \"hs-X11\" (from line 8).")
114} 114}
115 115
116func (s *Suite) Test_ChecklinesBuildlink3Mk_abi_api_versions(c *check.C) { 116func (s *Suite) Test_ChecklinesBuildlink3Mk_abi_api_versions(c *check.C) {
117 t := s.Init(c) 117 t := s.Init(c)
118 118
119 G.globalData.InitVartypes() 119 G.globalData.InitVartypes()
120 mklines := t.NewMkLines("buildlink3.mk", 120 mklines := t.NewMkLines("buildlink3.mk",
121 MkRcsId, 121 MkRcsID,
122 "", 122 "",
123 "BUILDLINK_TREE+=\ths-X11", 123 "BUILDLINK_TREE+=\ths-X11",
124 "", 124 "",
125 ".if !defined(HS_X11_BUILDLINK3_MK)", 125 ".if !defined(HS_X11_BUILDLINK3_MK)",
126 "HS_X11_BUILDLINK3_MK:=", 126 "HS_X11_BUILDLINK3_MK:=",
127 "", 127 "",
128 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11>=1.6.1", 128 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11>=1.6.1",
129 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X11>=1.6.0", 129 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X11>=1.6.0",
130 "", 130 "",
131 ".endif\t# HS_X11_BUILDLINK3_MK", 131 ".endif\t# HS_X11_BUILDLINK3_MK",
132 "", 132 "",
133 "BUILDLINK_TREE+=\t-hs-X11") 133 "BUILDLINK_TREE+=\t-hs-X11")
134 134
135 ChecklinesBuildlink3Mk(mklines) 135 ChecklinesBuildlink3Mk(mklines)
136 136
137 t.CheckOutputLines( 137 t.CheckOutputLines(
138 "WARN: buildlink3.mk:9: ABI version \"1.6.0\" should be at least API version \"1.6.1\" (see line 8).") 138 "WARN: buildlink3.mk:9: ABI version \"1.6.0\" should be at least API version \"1.6.1\" (see line 8).")
139} 139}
140 140
141func (s *Suite) Test_ChecklinesBuildlink3Mk_no_BUILDLINK_TREE_at_beginning(c *check.C) { 141func (s *Suite) Test_ChecklinesBuildlink3Mk_no_BUILDLINK_TREE_at_beginning(c *check.C) {
142 t := s.Init(c) 142 t := s.Init(c)
143 143
144 G.globalData.InitVartypes() 144 G.globalData.InitVartypes()
145 mklines := t.NewMkLines("buildlink3.mk", 145 mklines := t.NewMkLines("buildlink3.mk",
146 MkRcsId, 146 MkRcsID,
147 "", 147 "",
148 ".if !defined(HS_X11_BUILDLINK3_MK)", 148 ".if !defined(HS_X11_BUILDLINK3_MK)",
149 "HS_X11_BUILDLINK3_MK:=", 149 "HS_X11_BUILDLINK3_MK:=",
150 "", 150 "",
151 "BUILDLINK_DEPMETHOD.hs-X11?=\tfull", 151 "BUILDLINK_DEPMETHOD.hs-X11?=\tfull",
152 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11>=1.6.1", 152 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11>=1.6.1",
153 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X11>=1.6.1.2nb2", 153 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X11>=1.6.1.2nb2",
154 "", 154 "",
155 ".endif\t# HS_X11_BUILDLINK3_MK", 155 ".endif\t# HS_X11_BUILDLINK3_MK",
156 "", 156 "",
157 "BUILDLINK_TREE+=\t-hs-X11") 157 "BUILDLINK_TREE+=\t-hs-X11")
158 158
159 ChecklinesBuildlink3Mk(mklines) 159 ChecklinesBuildlink3Mk(mklines)
160 160
161 t.CheckOutputLines( 161 t.CheckOutputLines(
162 "WARN: buildlink3.mk:3: Expected a BUILDLINK_TREE line.") 162 "WARN: buildlink3.mk:3: Expected a BUILDLINK_TREE line.")
163} 163}
164 164
165func (s *Suite) Test_ChecklinesBuildlink3Mk_no_BUILDLINK_TREE_at_end(c *check.C) { 165func (s *Suite) Test_ChecklinesBuildlink3Mk_no_BUILDLINK_TREE_at_end(c *check.C) {
166 t := s.Init(c) 166 t := s.Init(c)
167 167
168 G.globalData.InitVartypes() 168 G.globalData.InitVartypes()
169 mklines := t.NewMkLines("buildlink3.mk", 169 mklines := t.NewMkLines("buildlink3.mk",
170 MkRcsId, 170 MkRcsID,
171 "", 171 "",
172 "BUILDLINK_DEPMETHOD.hs-X11?=\tfull", 172 "BUILDLINK_DEPMETHOD.hs-X11?=\tfull",
173 "", 173 "",
174 "BUILDLINK_TREE+=\ths-X11", 174 "BUILDLINK_TREE+=\ths-X11",
175 "", 175 "",
176 ".if !defined(HS_X11_BUILDLINK3_MK)", 176 ".if !defined(HS_X11_BUILDLINK3_MK)",
177 "HS_X11_BUILDLINK3_MK:=", 177 "HS_X11_BUILDLINK3_MK:=",
178 "", 178 "",
179 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11>=1.6.1", 179 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11>=1.6.1",
180 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X11>=1.6.1.2nb2", 180 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X11>=1.6.1.2nb2",
181 "", 181 "",
182 ".endif\t# HS_X11_BUILDLINK3_MK", 182 ".endif\t# HS_X11_BUILDLINK3_MK",
183 "", 183 "",
@@ -186,116 +186,116 @@ func (s *Suite) Test_ChecklinesBuildlink @@ -186,116 +186,116 @@ func (s *Suite) Test_ChecklinesBuildlink
186 186
187 ChecklinesBuildlink3Mk(mklines) 187 ChecklinesBuildlink3Mk(mklines)
188 188
189 t.CheckOutputLines( 189 t.CheckOutputLines(
190 "WARN: buildlink3.mk:3: This line belongs inside the .ifdef block.", 190 "WARN: buildlink3.mk:3: This line belongs inside the .ifdef block.",
191 "WARN: buildlink3.mk:15: This line should contain the following text: BUILDLINK_TREE+=\t-hs-X11") 191 "WARN: buildlink3.mk:15: This line should contain the following text: BUILDLINK_TREE+=\t-hs-X11")
192} 192}
193 193
194func (s *Suite) Test_ChecklinesBuildlink3Mk_multiple_inclusion_wrong(c *check.C) { 194func (s *Suite) Test_ChecklinesBuildlink3Mk_multiple_inclusion_wrong(c *check.C) {
195 t := s.Init(c) 195 t := s.Init(c)
196 196
197 G.globalData.InitVartypes() 197 G.globalData.InitVartypes()
198 mklines := t.NewMkLines("buildlink3.mk", 198 mklines := t.NewMkLines("buildlink3.mk",
199 MkRcsId, 199 MkRcsID,
200 "", 200 "",
201 "BUILDLINK_TREE+=\ths-X11", 201 "BUILDLINK_TREE+=\ths-X11",
202 "", 202 "",
203 ".if !defined(HS_X11_BUILDLINK3_MK)", 203 ".if !defined(HS_X11_BUILDLINK3_MK)",
204 "UNRELATED_BUILDLINK3_MK:=") 204 "UNRELATED_BUILDLINK3_MK:=")
205 205
206 ChecklinesBuildlink3Mk(mklines) 206 ChecklinesBuildlink3Mk(mklines)
207 207
208 t.CheckOutputLines( 208 t.CheckOutputLines(
209 "WARN: buildlink3.mk:6: UNRELATED_BUILDLINK3_MK is defined but not used. Spelling mistake?", 209 "WARN: buildlink3.mk:6: UNRELATED_BUILDLINK3_MK is defined but not used. Spelling mistake?",
210 "WARN: buildlink3.mk:6: This line should contain the following text: HS_X11_BUILDLINK3_MK:=") 210 "WARN: buildlink3.mk:6: This line should contain the following text: HS_X11_BUILDLINK3_MK:=")
211} 211}
212 212
213func (s *Suite) Test_ChecklinesBuildlink3Mk_missing_endif(c *check.C) { 213func (s *Suite) Test_ChecklinesBuildlink3Mk_missing_endif(c *check.C) {
214 t := s.Init(c) 214 t := s.Init(c)
215 215
216 G.globalData.InitVartypes() 216 G.globalData.InitVartypes()
217 mklines := t.NewMkLines("buildlink3.mk", 217 mklines := t.NewMkLines("buildlink3.mk",
218 MkRcsId, 218 MkRcsID,
219 "", 219 "",
220 "BUILDLINK_TREE+=\tpkgbase1", 220 "BUILDLINK_TREE+=\tpkgbase1",
221 "", 221 "",
222 ".if !defined(PKGBASE1_BUILDLINK3_MK)", 222 ".if !defined(PKGBASE1_BUILDLINK3_MK)",
223 "PKGBASE1_BUILDLINK3_MK:=") 223 "PKGBASE1_BUILDLINK3_MK:=")
224 224
225 ChecklinesBuildlink3Mk(mklines) 225 ChecklinesBuildlink3Mk(mklines)
226 226
227 t.CheckOutputLines( 227 t.CheckOutputLines(
228 "WARN: buildlink3.mk:EOF: Expected .endif") 228 "WARN: buildlink3.mk:EOF: Expected .endif")
229} 229}
230 230
231func (s *Suite) Test_ChecklinesBuildlink3Mk_unknown_dependency_patterns(c *check.C) { 231func (s *Suite) Test_ChecklinesBuildlink3Mk_unknown_dependency_patterns(c *check.C) {
232 t := s.Init(c) 232 t := s.Init(c)
233 233
234 G.globalData.InitVartypes() 234 G.globalData.InitVartypes()
235 mklines := t.NewMkLines("buildlink3.mk", 235 mklines := t.NewMkLines("buildlink3.mk",
236 MkRcsId, 236 MkRcsID,
237 "", 237 "",
238 "BUILDLINK_TREE+= hs-X11", 238 "BUILDLINK_TREE+= hs-X11",
239 "", 239 "",
240 ".if !defined(HS_X11_BUILDLINK3_MK)", 240 ".if !defined(HS_X11_BUILDLINK3_MK)",
241 "HS_X11_BUILDLINK3_MK:=", 241 "HS_X11_BUILDLINK3_MK:=",
242 "", 242 "",
243 "BUILDLINK_DEPMETHOD.hs-X11?=\tfull", 243 "BUILDLINK_DEPMETHOD.hs-X11?=\tfull",
244 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11!=1.6.1", 244 "BUILDLINK_API_DEPENDS.hs-X11+=\ths-X11!=1.6.1",
245 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X11!=1.6.1.2nb2", 245 "BUILDLINK_ABI_DEPENDS.hs-X11+=\ths-X11!=1.6.1.2nb2",
246 "", 246 "",
247 ".endif\t# HS_X11_BUILDLINK3_MK", 247 ".endif\t# HS_X11_BUILDLINK3_MK",
248 "", 248 "",
249 "BUILDLINK_TREE+=\t-hs-X11") 249 "BUILDLINK_TREE+=\t-hs-X11")
250 250
251 ChecklinesBuildlink3Mk(mklines) 251 ChecklinesBuildlink3Mk(mklines)
252 252
253 t.CheckOutputLines( 253 t.CheckOutputLines(
254 "WARN: buildlink3.mk:9: Unknown dependency pattern \"hs-X11!=1.6.1\".", 254 "WARN: buildlink3.mk:9: Unknown dependency pattern \"hs-X11!=1.6.1\".",
255 "WARN: buildlink3.mk:10: Unknown dependency pattern \"hs-X11!=1.6.1.2nb2\".") 255 "WARN: buildlink3.mk:10: Unknown dependency pattern \"hs-X11!=1.6.1.2nb2\".")
256} 256}
257 257
258func (s *Suite) Test_ChecklinesBuildlink3Mk_PKGBASE_with_variable(c *check.C) { 258func (s *Suite) Test_ChecklinesBuildlink3Mk_PKGBASE_with_variable(c *check.C) {
259 t := s.Init(c) 259 t := s.Init(c)
260 260
261 G.globalData.InitVartypes() 261 G.globalData.InitVartypes()
262 mklines := t.NewMkLines("buildlink3.mk", 262 mklines := t.NewMkLines("buildlink3.mk",
263 MkRcsId, 263 MkRcsID,
264 "", 264 "",
265 "BUILDLINK_TREE+=\t${PYPKGPREFIX}-wxWidgets", 265 "BUILDLINK_TREE+=\t${PYPKGPREFIX}-wxWidgets",
266 "", 266 "",
267 ".if !defined(PY_WXWIDGETS_BUILDLINK3_MK)", 267 ".if !defined(PY_WXWIDGETS_BUILDLINK3_MK)",
268 "PY_WXWIDGETS_BUILDLINK3_MK:=", 268 "PY_WXWIDGETS_BUILDLINK3_MK:=",
269 "", 269 "",
270 "BUILDLINK_API_DEPENDS.${PYPKGPREFIX}-wxWidgets+=\t${PYPKGPREFIX}-wxWidgets>=2.6.1.0", 270 "BUILDLINK_API_DEPENDS.${PYPKGPREFIX}-wxWidgets+=\t${PYPKGPREFIX}-wxWidgets>=2.6.1.0",
271 "BUILDLINK_ABI_DEPENDS.${PYPKGPREFIX}-wxWidgets+=\t${PYPKGPREFIX}-wxWidgets>=2.8.10.1nb26", 271 "BUILDLINK_ABI_DEPENDS.${PYPKGPREFIX}-wxWidgets+=\t${PYPKGPREFIX}-wxWidgets>=2.8.10.1nb26",
272 "", 272 "",
273 ".endif", 273 ".endif",
274 "", 274 "",
275 "BUILDLINK_TREE+=\t-${PYPKGPREFIX}-wxWidgets") 275 "BUILDLINK_TREE+=\t-${PYPKGPREFIX}-wxWidgets")
276 276
277 ChecklinesBuildlink3Mk(mklines) 277 ChecklinesBuildlink3Mk(mklines)
278 278
279 t.CheckOutputLines( 279 t.CheckOutputLines(
280 "WARN: buildlink3.mk:3: Please use \"py\" instead of \"${PYPKGPREFIX}\" (also in other variables in this file).") 280 "WARN: buildlink3.mk:3: Please use \"py\" instead of \"${PYPKGPREFIX}\" (also in other variables in this file).")
281} 281}
282 282
283func (s *Suite) Test_ChecklinesBuildlink3Mk_PKGBASE_with_unknown_variable(c *check.C) { 283func (s *Suite) Test_ChecklinesBuildlink3Mk_PKGBASE_with_unknown_variable(c *check.C) {
284 t := s.Init(c) 284 t := s.Init(c)
285 285
286 G.globalData.InitVartypes() 286 G.globalData.InitVartypes()
287 mklines := t.NewMkLines("buildlink3.mk", 287 mklines := t.NewMkLines("buildlink3.mk",
288 MkRcsId, 288 MkRcsID,
289 "", 289 "",
290 "BUILDLINK_TREE+=\t${LICENSE}-wxWidgets", 290 "BUILDLINK_TREE+=\t${LICENSE}-wxWidgets",
291 "", 291 "",
292 ".if !defined(LICENSE_BUILDLINK3_MK)", 292 ".if !defined(LICENSE_BUILDLINK3_MK)",
293 "LICENSE_BUILDLINK3_MK:=", 293 "LICENSE_BUILDLINK3_MK:=",
294 "", 294 "",
295 "BUILDLINK_API_DEPENDS.${LICENSE}-wxWidgets+=\t${PYPKGPREFIX}-wxWidgets>=2.6.1.0", 295 "BUILDLINK_API_DEPENDS.${LICENSE}-wxWidgets+=\t${PYPKGPREFIX}-wxWidgets>=2.6.1.0",
296 "BUILDLINK_ABI_DEPENDS.${LICENSE}-wxWidgets+=\t${PYPKGPREFIX}-wxWidgets>=2.8.10.1nb26", 296 "BUILDLINK_ABI_DEPENDS.${LICENSE}-wxWidgets+=\t${PYPKGPREFIX}-wxWidgets>=2.8.10.1nb26",
297 "", 297 "",
298 ".endif", 298 ".endif",
299 "", 299 "",
300 "BUILDLINK_TREE+=\t-${PYPKGPREFIX}-wxWidgets") 300 "BUILDLINK_TREE+=\t-${PYPKGPREFIX}-wxWidgets")
301 301
@@ -306,27 +306,27 @@ func (s *Suite) Test_ChecklinesBuildlink @@ -306,27 +306,27 @@ func (s *Suite) Test_ChecklinesBuildlink
306 "WARN: buildlink3.mk:13: This line should contain the following text: BUILDLINK_TREE+=\t-${LICENSE}-wxWidgets") 306 "WARN: buildlink3.mk:13: This line should contain the following text: BUILDLINK_TREE+=\t-${LICENSE}-wxWidgets")
307} 307}
308 308
309// Those .include lines that are not indented at all may stay as-is. 309// Those .include lines that are not indented at all may stay as-is.
310// This special exception might have been for backwards-compatibility, 310// This special exception might have been for backwards-compatibility,
311// but ideally should be handled like everywhere else. 311// but ideally should be handled like everywhere else.
312// See MkLineChecker.checkInclude. 312// See MkLineChecker.checkInclude.
313func (s *Suite) Test_ChecklinesBuildlink3Mk_indentation(c *check.C) { 313func (s *Suite) Test_ChecklinesBuildlink3Mk_indentation(c *check.C) {
314 t := s.Init(c) 314 t := s.Init(c)
315 315
316 t.SetupCommandLine("-Wall") 316 t.SetupCommandLine("-Wall")
317 G.globalData.InitVartypes() 317 G.globalData.InitVartypes()
318 mklines := t.NewMkLines("buildlink3.mk", 318 mklines := t.NewMkLines("buildlink3.mk",
319 MkRcsId, 319 MkRcsID,
320 "", 320 "",
321 ".if ${VAAPI_AVAILABLE} == \"yes\"", 321 ".if ${VAAPI_AVAILABLE} == \"yes\"",
322 "", 322 "",
323 "BUILDLINK_TREE+= libva", 323 "BUILDLINK_TREE+= libva",
324 "", 324 "",
325 ". if !defined(LIBVA_BUILDLINK3_MK)", 325 ". if !defined(LIBVA_BUILDLINK3_MK)",
326 "LIBVA_BUILDLINK3_MK:=", 326 "LIBVA_BUILDLINK3_MK:=",
327 "", 327 "",
328 "BUILDLINK_API_DEPENDS.libva+= libva>=1.0.6", 328 "BUILDLINK_API_DEPENDS.libva+= libva>=1.0.6",
329 "BUILDLINK_PKGSRCDIR.libva?= ../../multimedia/libva", 329 "BUILDLINK_PKGSRCDIR.libva?= ../../multimedia/libva",
330 "", 330 "",
331 ".include \"../../x11/libX11/buildlink3.mk\"", 331 ".include \"../../x11/libX11/buildlink3.mk\"",
332 "", 332 "",

cvs diff -r1.7 -r1.8 pkgsrc/pkgtools/pkglint/files/Attic/category_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/category_test.go 2018/01/27 18:50:36 1.7
+++ pkgsrc/pkgtools/pkglint/files/Attic/category_test.go 2018/02/19 12:40:38 1.8
@@ -28,27 +28,27 @@ func (s *Suite) Test_CheckdirCategory_to @@ -28,27 +28,27 @@ func (s *Suite) Test_CheckdirCategory_to
28 "WARN: ~/archivers/Makefile:3: \"aaaaa\" should come before \"pkg1\".", 28 "WARN: ~/archivers/Makefile:3: \"aaaaa\" should come before \"pkg1\".",
29 "ERROR: ~/archivers/Makefile:4: SUBDIR+= line or empty line expected.", 29 "ERROR: ~/archivers/Makefile:4: SUBDIR+= line or empty line expected.",
30 "ERROR: ~/archivers/Makefile:2: \"pkg1\" exists in the Makefile, but not in the file system.", 30 "ERROR: ~/archivers/Makefile:2: \"pkg1\" exists in the Makefile, but not in the file system.",
31 "ERROR: ~/archivers/Makefile:3: \"aaaaa\" exists in the Makefile, but not in the file system.", 31 "ERROR: ~/archivers/Makefile:3: \"aaaaa\" exists in the Makefile, but not in the file system.",
32 "WARN: ~/archivers/Makefile:4: This line should contain the following text: .include \"../mk/misc/category.mk\"", 32 "WARN: ~/archivers/Makefile:4: This line should contain the following text: .include \"../mk/misc/category.mk\"",
33 "ERROR: ~/archivers/Makefile:4: The file should end here.") 33 "ERROR: ~/archivers/Makefile:4: The file should end here.")
34} 34}
35 35
36func (s *Suite) Test_CheckdirCategory_invalid_comment(c *check.C) { 36func (s *Suite) Test_CheckdirCategory_invalid_comment(c *check.C) {
37 t := s.Init(c) 37 t := s.Init(c)
38 38
39 G.globalData.InitVartypes() 39 G.globalData.InitVartypes()
40 t.SetupFileLines("archivers/Makefile", 40 t.SetupFileLines("archivers/Makefile",
41 MkRcsId, 41 MkRcsID,
42 "COMMENT=\t\\Make $$$$ fast\"", 42 "COMMENT=\t\\Make $$$$ fast\"",
43 "", 43 "",
44 "SUBDIR+=\tpackage", 44 "SUBDIR+=\tpackage",
45 "", 45 "",
46 ".include \"../mk/misc/category.mk\"") 46 ".include \"../mk/misc/category.mk\"")
47 t.SetupFileLines("archivers/package/Makefile", 47 t.SetupFileLines("archivers/package/Makefile",
48 "# dummy") 48 "# dummy")
49 t.SetupFileLines("mk/misc/category.mk", 49 t.SetupFileLines("mk/misc/category.mk",
50 "# dummy") 50 "# dummy")
51 G.CurrentDir = t.TempFilename("archivers") 51 G.CurrentDir = t.TempFilename("archivers")
52 G.CurPkgsrcdir = ".." 52 G.CurPkgsrcdir = ".."
53 53
54 CheckdirCategory() 54 CheckdirCategory()

cvs diff -r1.16 -r1.17 pkgsrc/pkgtools/pkglint/files/Attic/check_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/check_test.go 2018/01/27 18:50:36 1.16
+++ pkgsrc/pkgtools/pkglint/files/Attic/check_test.go 2018/02/19 12:40:38 1.17
@@ -8,36 +8,40 @@ import ( @@ -8,36 +8,40 @@ import (
8 "path" 8 "path"
9 "path/filepath" 9 "path/filepath"
10 "strings" 10 "strings"
11 "testing" 11 "testing"
12 12
13 "gopkg.in/check.v1" 13 "gopkg.in/check.v1"
14 "netbsd.org/pkglint/textproc" 14 "netbsd.org/pkglint/textproc"
15 "netbsd.org/pkglint/trace" 15 "netbsd.org/pkglint/trace"
16) 16)
17 17
18var equals = check.Equals 18var equals = check.Equals
19var deepEquals = check.DeepEquals 19var deepEquals = check.DeepEquals
20 20
21const RcsId = "$" + "NetBSD$" 21const RcsID = "$" + "NetBSD$"
22const MkRcsId = "# $" + "NetBSD$" 22const MkRcsID = "# $" + "NetBSD$"
23const PlistRcsId = "@comment $" + "NetBSD$" 23const PlistRcsID = "@comment $" + "NetBSD$"
24 24
25type Suite struct { 25type Suite struct {
26 Tester *Tester 26 Tester *Tester
27} 27}
28 28
29// Init initializes the suite with the check.C instance for the actual 29// Init initializes the suite with the check.C instance for the actual
30// test run. See https://github.com/go-check/check/issues/22 30// test run.
 31// The returned tester can be used to easily setup the test environment
 32// and check the results using a high-level API.
 33//
 34// See https://github.com/go-check/check/issues/22
31func (s *Suite) Init(c *check.C) *Tester { 35func (s *Suite) Init(c *check.C) *Tester {
32 t := s.Tester // Has been initialized by SetUpTest 36 t := s.Tester // Has been initialized by SetUpTest
33 if t.checkC != nil { 37 if t.checkC != nil {
34 panic("Suite.Init must only be called once.") 38 panic("Suite.Init must only be called once.")
35 } 39 }
36 t.checkC = c 40 t.checkC = c
37 return t 41 return t
38} 42}
39 43
40func (s *Suite) SetUpTest(c *check.C) { 44func (s *Suite) SetUpTest(c *check.C) {
41 t := &Tester{checkC: c} 45 t := &Tester{checkC: c}
42 s.Tester = t 46 s.Tester = t
43 47
@@ -266,38 +270,38 @@ func (t *Tester) CheckOutputEmpty() { @@ -266,38 +270,38 @@ func (t *Tester) CheckOutputEmpty() {
266 t.CheckOutputLines( /* none */ ) 270 t.CheckOutputLines( /* none */ )
267} 271}
268 272
269// CheckOutputLines checks that the output up to now equals the given lines. 273// CheckOutputLines checks that the output up to now equals the given lines.
270// After the comparison, the output buffers are cleared so that later 274// After the comparison, the output buffers are cleared so that later
271// calls only check against the newly added output. 275// calls only check against the newly added output.
272func (t *Tester) CheckOutputLines(expectedLines ...string) { 276func (t *Tester) CheckOutputLines(expectedLines ...string) {
273 output := t.Output() 277 output := t.Output()
274 actualLines := strings.Split(output, "\n") 278 actualLines := strings.Split(output, "\n")
275 actualLines = actualLines[:len(actualLines)-1] 279 actualLines = actualLines[:len(actualLines)-1]
276 t.c().Check(emptyToNil(actualLines), deepEquals, emptyToNil(expectedLines)) 280 t.c().Check(emptyToNil(actualLines), deepEquals, emptyToNil(expectedLines))
277} 281}
278 282
279// BeginDebugToStdout redirects all logging output to stdout instead of 283// EnableTracing redirects all logging output to stdout instead of
280// the buffer. This is useful when stepping through the code, especially 284// the buffer. This is useful when stepping through the code, especially
281// in combination with SetupCommandLine("--debug"). 285// in combination with SetupCommandLine("--debug").
282func (t *Tester) BeginDebugToStdout() { 286func (t *Tester) EnableTracing() {
283 G.logOut = NewSeparatorWriter(os.Stdout) 287 G.logOut = NewSeparatorWriter(os.Stdout)
284 trace.Out = os.Stdout 288 trace.Out = os.Stdout
285 trace.Tracing = true 289 trace.Tracing = true
286} 290}
287 291
288// EndDebugToStdout logs the output to the buffers again, ready to be 292// DisableTracing logs the output to the buffers again, ready to be
289// checked with CheckOutputLines. 293// checked with CheckOutputLines.
290func (t *Tester) EndDebugToStdout() { 294func (t *Tester) DisableTracing() {
291 G.logOut = NewSeparatorWriter(&t.stdout) 295 G.logOut = NewSeparatorWriter(&t.stdout)
292 trace.Out = &t.stdout 296 trace.Out = &t.stdout
293 trace.Tracing = false 297 trace.Tracing = false
294} 298}
295 299
296// CheckFileLines loads the lines from the temporary file and checks that 300// CheckFileLines loads the lines from the temporary file and checks that
297// they equal the given lines. 301// they equal the given lines.
298func (t *Tester) CheckFileLines(relativeFileName string, lines ...string) { 302func (t *Tester) CheckFileLines(relativeFileName string, lines ...string) {
299 text := t.LoadTmpFile(relativeFileName) 303 text := t.LoadTmpFile(relativeFileName)
300 actualLines := strings.Split(text, "\n") 304 actualLines := strings.Split(text, "\n")
301 actualLines = actualLines[:len(actualLines)-1] 305 actualLines = actualLines[:len(actualLines)-1]
302 t.c().Check(emptyToNil(actualLines), deepEquals, emptyToNil(lines)) 306 t.c().Check(emptyToNil(actualLines), deepEquals, emptyToNil(lines))
303} 307}

cvs diff -r1.16 -r1.17 pkgsrc/pkgtools/pkglint/files/Attic/mklines_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/mklines_test.go 2018/01/27 18:50:36 1.16
+++ pkgsrc/pkgtools/pkglint/files/Attic/mklines_test.go 2018/02/19 12:40:38 1.17
@@ -1,25 +1,25 @@ @@ -1,25 +1,25 @@
1package main 1package main
2 2
3import ( 3import (
4 "gopkg.in/check.v1" 4 "gopkg.in/check.v1"
5) 5)
6 6
7func (s *Suite) Test_MkLines_Check__autofix_conditional_indentation(c *check.C) { 7func (s *Suite) Test_MkLines_Check__autofix_conditional_indentation(c *check.C) {
8 t := s.Init(c) 8 t := s.Init(c)
9 9
10 t.SetupCommandLine("--autofix", "-Wspace") 10 t.SetupCommandLine("--autofix", "-Wspace")
11 lines := t.SetupFileLines("fname.mk", 11 lines := t.SetupFileLines("fname.mk",
12 MkRcsId, 12 MkRcsID,
13 ".if defined(A)", 13 ".if defined(A)",
14 ".for a in ${A}", 14 ".for a in ${A}",
15 ".if defined(C)", 15 ".if defined(C)",
16 ".endif", 16 ".endif",
17 ".endfor", 17 ".endfor",
18 ".endif") 18 ".endif")
19 mklines := NewMkLines(lines) 19 mklines := NewMkLines(lines)
20 20
21 mklines.Check() 21 mklines.Check()
22 22
23 t.CheckOutputLines( 23 t.CheckOutputLines(
24 "AUTOFIX: ~/fname.mk:3: Replacing \".\" with \". \".", 24 "AUTOFIX: ~/fname.mk:3: Replacing \".\" with \". \".",
25 "AUTOFIX: ~/fname.mk:4: Replacing \".\" with \". \".", 25 "AUTOFIX: ~/fname.mk:4: Replacing \".\" with \". \".",
@@ -29,27 +29,27 @@ func (s *Suite) Test_MkLines_Check__auto @@ -29,27 +29,27 @@ func (s *Suite) Test_MkLines_Check__auto
29 "# $"+"NetBSD$", 29 "# $"+"NetBSD$",
30 ".if defined(A)", 30 ".if defined(A)",
31 ". for a in ${A}", 31 ". for a in ${A}",
32 ". if defined(C)", 32 ". if defined(C)",
33 ". endif", 33 ". endif",
34 ". endfor", 34 ". endfor",
35 ".endif") 35 ".endif")
36} 36}
37 37
38func (s *Suite) Test_MkLines_Check__unusual_target(c *check.C) { 38func (s *Suite) Test_MkLines_Check__unusual_target(c *check.C) {
39 t := s.Init(c) 39 t := s.Init(c)
40 40
41 mklines := t.NewMkLines("Makefile", 41 mklines := t.NewMkLines("Makefile",
42 MkRcsId, 42 MkRcsID,
43 "", 43 "",
44 "echo: echo.c", 44 "echo: echo.c",
45 "\tcc -o ${.TARGET} ${.IMPSRC}") 45 "\tcc -o ${.TARGET} ${.IMPSRC}")
46 46
47 mklines.Check() 47 mklines.Check()
48 48
49 t.CheckOutputLines( 49 t.CheckOutputLines(
50 "WARN: Makefile:3: Unusual target \"echo\".") 50 "WARN: Makefile:3: Unusual target \"echo\".")
51} 51}
52 52
53func (s *Suite) Test_MkLineChecker_checkInclude__Makefile(c *check.C) { 53func (s *Suite) Test_MkLineChecker_checkInclude__Makefile(c *check.C) {
54 t := s.Init(c) 54 t := s.Init(c)
55 55
@@ -59,256 +59,256 @@ func (s *Suite) Test_MkLineChecker_check @@ -59,256 +59,256 @@ func (s *Suite) Test_MkLineChecker_check
59 59
60 t.CheckOutputLines( 60 t.CheckOutputLines(
61 "ERROR: Makefile:2: \"/other/package/Makefile\" does not exist.", 61 "ERROR: Makefile:2: \"/other/package/Makefile\" does not exist.",
62 "ERROR: Makefile:2: Other Makefiles must not be included directly.") 62 "ERROR: Makefile:2: Other Makefiles must not be included directly.")
63} 63}
64 64
65func (s *Suite) Test_MkLines_quoting_LDFLAGS_for_GNU_configure(c *check.C) { 65func (s *Suite) Test_MkLines_quoting_LDFLAGS_for_GNU_configure(c *check.C) {
66 t := s.Init(c) 66 t := s.Init(c)
67 67
68 t.SetupCommandLine("-Wall") 68 t.SetupCommandLine("-Wall")
69 G.globalData.InitVartypes() 69 G.globalData.InitVartypes()
70 G.Pkg = NewPackage("category/pkgbase") 70 G.Pkg = NewPackage("category/pkgbase")
71 mklines := t.NewMkLines("Makefile", 71 mklines := t.NewMkLines("Makefile",
72 MkRcsId, 72 MkRcsID,
73 "GNU_CONFIGURE=\tyes", 73 "GNU_CONFIGURE=\tyes",
74 "CONFIGURE_ENV+=\tX_LIBS=${X11_LDFLAGS:Q}") 74 "CONFIGURE_ENV+=\tX_LIBS=${X11_LDFLAGS:Q}")
75 75
76 mklines.Check() 76 mklines.Check()
77 77
78 t.CheckOutputLines( 78 t.CheckOutputLines(
79 "WARN: Makefile:3: Please use ${X11_LDFLAGS:M*:Q} instead of ${X11_LDFLAGS:Q}.", 79 "WARN: Makefile:3: Please use ${X11_LDFLAGS:M*:Q} instead of ${X11_LDFLAGS:Q}.",
80 "WARN: Makefile:3: Please use ${X11_LDFLAGS:M*:Q} instead of ${X11_LDFLAGS:Q}.") 80 "WARN: Makefile:3: Please use ${X11_LDFLAGS:M*:Q} instead of ${X11_LDFLAGS:Q}.")
81} 81}
82 82
83func (s *Suite) Test_MkLines__for_loop_multiple_variables(c *check.C) { 83func (s *Suite) Test_MkLines__for_loop_multiple_variables(c *check.C) {
84 t := s.Init(c) 84 t := s.Init(c)
85 85
86 t.SetupCommandLine("-Wall") 86 t.SetupCommandLine("-Wall")
87 t.SetupTool(&Tool{Name: "echo", Varname: "ECHO", Predefined: true}) 87 t.SetupTool(&Tool{Name: "echo", Varname: "ECHO", Predefined: true})
88 t.SetupTool(&Tool{Name: "find", Varname: "FIND", Predefined: true}) 88 t.SetupTool(&Tool{Name: "find", Varname: "FIND", Predefined: true})
89 t.SetupTool(&Tool{Name: "pax", Varname: "PAX", Predefined: true}) 89 t.SetupTool(&Tool{Name: "pax", Varname: "PAX", Predefined: true})
90 mklines := t.NewMkLines("Makefile", // From audio/squeezeboxserver 90 mklines := t.NewMkLines("Makefile", // From audio/squeezeboxserver
91 MkRcsId, 91 MkRcsID,
92 "", 92 "",
93 ".for _list_ _dir_ in ${SBS_COPY}", 93 ".for _list_ _dir_ in ${SBS_COPY}",
94 "\tcd ${WRKSRC} && ${FIND} ${${_list_}} -type f ! -name '*.orig' 2>/dev/null "+ 94 "\tcd ${WRKSRC} && ${FIND} ${${_list_}} -type f ! -name '*.orig' 2>/dev/null "+
95 "| pax -rw -pm ${DESTDIR}${PREFIX}/${${_dir_}}", 95 "| pax -rw -pm ${DESTDIR}${PREFIX}/${${_dir_}}",
96 ".endfor") 96 ".endfor")
97 97
98 mklines.Check() 98 mklines.Check()
99 99
100 t.CheckOutputLines( 100 t.CheckOutputLines(
101 "WARN: Makefile:3: Variable names starting with an underscore (_list_) are reserved for internal pkgsrc use.", 101 "WARN: Makefile:3: Variable names starting with an underscore (_list_) are reserved for internal pkgsrc use.",
102 "WARN: Makefile:3: Variable names starting with an underscore (_dir_) are reserved for internal pkgsrc use.", 102 "WARN: Makefile:3: Variable names starting with an underscore (_dir_) are reserved for internal pkgsrc use.",
103 "WARN: Makefile:4: The exitcode of \"${FIND}\" at the left of the | operator is ignored.") 103 "WARN: Makefile:4: The exitcode of \"${FIND}\" at the left of the | operator is ignored.")
104} 104}
105 105
106func (s *Suite) Test_MkLines__comparing_YesNo_variable_to_string(c *check.C) { 106func (s *Suite) Test_MkLines__comparing_YesNo_variable_to_string(c *check.C) {
107 t := s.Init(c) 107 t := s.Init(c)
108 108
109 t.SetupCommandLine("-Wall") 109 t.SetupCommandLine("-Wall")
110 G.globalData.InitVartypes() 110 G.globalData.InitVartypes()
111 mklines := t.NewMkLines("databases/gdbm_compat/builtin.mk", 111 mklines := t.NewMkLines("databases/gdbm_compat/builtin.mk",
112 MkRcsId, 112 MkRcsID,
113 ".if ${USE_BUILTIN.gdbm} == \"no\"", 113 ".if ${USE_BUILTIN.gdbm} == \"no\"",
114 ".endif", 114 ".endif",
115 ".if ${USE_BUILTIN.gdbm:tu} == \"no\"", // Can never be true, since "no" is not uppercase. 115 ".if ${USE_BUILTIN.gdbm:tu} == \"no\"", // Can never be true, since "no" is not uppercase.
116 ".endif") 116 ".endif")
117 117
118 mklines.Check() 118 mklines.Check()
119 119
120 t.CheckOutputLines( 120 t.CheckOutputLines(
121 "WARN: databases/gdbm_compat/builtin.mk:2: " + 121 "WARN: databases/gdbm_compat/builtin.mk:2: " +
122 "USE_BUILTIN.gdbm should be matched against \"[yY][eE][sS]\" or \"[nN][oO]\", not compared with \"no\".") 122 "USE_BUILTIN.gdbm should be matched against \"[yY][eE][sS]\" or \"[nN][oO]\", not compared with \"no\".")
123} 123}
124 124
125func (s *Suite) Test_MkLines__varuse_sh_modifier(c *check.C) { 125func (s *Suite) Test_MkLines__varuse_sh_modifier(c *check.C) {
126 t := s.Init(c) 126 t := s.Init(c)
127 127
128 t.SetupCommandLine("-Wall") 128 t.SetupCommandLine("-Wall")
129 G.globalData.InitVartypes() 129 G.globalData.InitVartypes()
130 mklines := t.NewMkLines("lang/qore/module.mk", 130 mklines := t.NewMkLines("lang/qore/module.mk",
131 MkRcsId, 131 MkRcsID,
132 "qore-version=\tqore --short-version | ${SED} -e s/-.*//", 132 "qore-version=\tqore --short-version | ${SED} -e s/-.*//",
133 "PLIST_SUBST+=\tQORE_VERSION=\"${qore-version:sh}\"") 133 "PLIST_SUBST+=\tQORE_VERSION=\"${qore-version:sh}\"")
134 134
135 vars2 := mklines.mklines[1].DetermineUsedVariables() 135 vars2 := mklines.mklines[1].DetermineUsedVariables()
136 136
137 c.Check(vars2, deepEquals, []string{"SED"}) 137 c.Check(vars2, deepEquals, []string{"SED"})
138 138
139 vars3 := mklines.mklines[2].DetermineUsedVariables() 139 vars3 := mklines.mklines[2].DetermineUsedVariables()
140 140
141 c.Check(vars3, deepEquals, []string{"qore-version"}) 141 c.Check(vars3, deepEquals, []string{"qore-version"})
142 142
143 mklines.Check() 143 mklines.Check()
144 144
145 // No warnings about defined but not used or vice versa 145 // No warnings about defined but not used or vice versa
146 t.CheckOutputEmpty() 146 t.CheckOutputEmpty()
147} 147}
148 148
149func (s *Suite) Test_MkLines__varuse_parameterized(c *check.C) { 149func (s *Suite) Test_MkLines__varuse_parameterized(c *check.C) {
150 t := s.Init(c) 150 t := s.Init(c)
151 151
152 t.SetupCommandLine("-Wall") 152 t.SetupCommandLine("-Wall")
153 G.globalData.InitVartypes() 153 G.globalData.InitVartypes()
154 mklines := t.NewMkLines("converters/wv2/Makefile", 154 mklines := t.NewMkLines("converters/wv2/Makefile",
155 MkRcsId, 155 MkRcsID,
156 "CONFIGURE_ARGS+=\t\t${CONFIGURE_ARGS.${ICONV_TYPE}-iconv}", 156 "CONFIGURE_ARGS+=\t\t${CONFIGURE_ARGS.${ICONV_TYPE}-iconv}",
157 "CONFIGURE_ARGS.gnu-iconv=\t--with-libiconv=${BUILDLINK_PREFIX.iconv}") 157 "CONFIGURE_ARGS.gnu-iconv=\t--with-libiconv=${BUILDLINK_PREFIX.iconv}")
158 158
159 mklines.Check() 159 mklines.Check()
160 160
161 // No warnings about defined but not used or vice versa 161 // No warnings about defined but not used or vice versa
162 t.CheckOutputEmpty() 162 t.CheckOutputEmpty()
163} 163}
164 164
165func (s *Suite) Test_MkLines__loop_modifier(c *check.C) { 165func (s *Suite) Test_MkLines__loop_modifier(c *check.C) {
166 t := s.Init(c) 166 t := s.Init(c)
167 167
168 t.SetupCommandLine("-Wall") 168 t.SetupCommandLine("-Wall")
169 G.globalData.InitVartypes() 169 G.globalData.InitVartypes()
170 mklines := t.NewMkLines("chat/xchat/Makefile", 170 mklines := t.NewMkLines("chat/xchat/Makefile",
171 MkRcsId, 171 MkRcsID,
172 "GCONF_SCHEMAS=\tapps_xchat_url_handler.schemas", 172 "GCONF_SCHEMAS=\tapps_xchat_url_handler.schemas",
173 "post-install:", 173 "post-install:",
174 "\t${GCONF_SCHEMAS:@.s.@"+ 174 "\t${GCONF_SCHEMAS:@.s.@"+
175 "${INSTALL_DATA} ${WRKSRC}/src/common/dbus/${.s.} ${DESTDIR}${GCONF_SCHEMAS_DIR}/@}") 175 "${INSTALL_DATA} ${WRKSRC}/src/common/dbus/${.s.} ${DESTDIR}${GCONF_SCHEMAS_DIR}/@}")
176 176
177 mklines.Check() 177 mklines.Check()
178 178
179 t.CheckOutputLines( 179 t.CheckOutputLines(
180 // No warning about missing @ at the end 180 // No warning about missing @ at the end
181 "WARN: chat/xchat/Makefile:4: " + 181 "WARN: chat/xchat/Makefile:4: " +
182 "Unknown shell command \"${GCONF_SCHEMAS:@.s.@" + 182 "Unknown shell command \"${GCONF_SCHEMAS:@.s.@" +
183 "${INSTALL_DATA} ${WRKSRC}/src/common/dbus/${.s.} ${DESTDIR}${GCONF_SCHEMAS_DIR}/@}\".") 183 "${INSTALL_DATA} ${WRKSRC}/src/common/dbus/${.s.} ${DESTDIR}${GCONF_SCHEMAS_DIR}/@}\".")
184} 184}
185 185
186// PR 46570 186// PR 46570
187func (s *Suite) Test_MkLines__PKG_SKIP_REASON_depending_on_OPSYS(c *check.C) { 187func (s *Suite) Test_MkLines__PKG_SKIP_REASON_depending_on_OPSYS(c *check.C) {
188 t := s.Init(c) 188 t := s.Init(c)
189 189
190 G.globalData.InitVartypes() 190 G.globalData.InitVartypes()
191 mklines := t.NewMkLines("Makefile", 191 mklines := t.NewMkLines("Makefile",
192 MkRcsId, 192 MkRcsID,
193 "PKG_SKIP_REASON+=\t\"Fails everywhere\"", 193 "PKG_SKIP_REASON+=\t\"Fails everywhere\"",
194 ".if ${OPSYS} == \"Cygwin\"", 194 ".if ${OPSYS} == \"Cygwin\"",
195 "PKG_SKIP_REASON+=\t\"Fails on Cygwin\"", 195 "PKG_SKIP_REASON+=\t\"Fails on Cygwin\"",
196 ".endif") 196 ".endif")
197 197
198 mklines.Check() 198 mklines.Check()
199 199
200 t.CheckOutputLines( 200 t.CheckOutputLines(
201 "NOTE: Makefile:4: Consider defining NOT_FOR_PLATFORM instead of setting PKG_SKIP_REASON depending on ${OPSYS}.") 201 "NOTE: Makefile:4: Consider defining NOT_FOR_PLATFORM instead of setting PKG_SKIP_REASON depending on ${OPSYS}.")
202} 202}
203 203
204// PR 46570, item "15. net/uucp/Makefile has a make loop" 204// PR 46570, item "15. net/uucp/Makefile has a make loop"
205func (s *Suite) Test_MkLines__indirect_variables(c *check.C) { 205func (s *Suite) Test_MkLines__indirect_variables(c *check.C) {
206 t := s.Init(c) 206 t := s.Init(c)
207 207
208 t.SetupCommandLine("-Wall") 208 t.SetupCommandLine("-Wall")
209 mklines := t.NewMkLines("net/uucp/Makefile", 209 mklines := t.NewMkLines("net/uucp/Makefile",
210 MkRcsId, 210 MkRcsID,
211 "", 211 "",
212 "post-configure:", 212 "post-configure:",
213 ".for var in MAIL_PROGRAM CMDPATH", 213 ".for var in MAIL_PROGRAM CMDPATH",
214 "\t"+`${RUN} ${ECHO} "#define ${var} \""${UUCP_${var}}"\"`, 214 "\t"+`${RUN} ${ECHO} "#define ${var} \""${UUCP_${var}}"\"`,
215 ".endfor") 215 ".endfor")
216 216
217 mklines.Check() 217 mklines.Check()
218 218
219 // No warning about UUCP_${var} being used but not defined. 219 // No warning about UUCP_${var} being used but not defined.
220 t.CheckOutputLines( 220 t.CheckOutputLines(
221 "WARN: net/uucp/Makefile:5: Unknown shell command \"${ECHO}\".") 221 "WARN: net/uucp/Makefile:5: Unknown shell command \"${ECHO}\".")
222} 222}
223 223
224func (s *Suite) Test_MkLines_Check__list_variable_as_part_of_word(c *check.C) { 224func (s *Suite) Test_MkLines_Check__list_variable_as_part_of_word(c *check.C) {
225 t := s.Init(c) 225 t := s.Init(c)
226 226
227 t.SetupCommandLine("-Wall") 227 t.SetupCommandLine("-Wall")
228 mklines := t.NewMkLines("converters/chef/Makefile", 228 mklines := t.NewMkLines("converters/chef/Makefile",
229 MkRcsId, 229 MkRcsID,
230 "\tcd ${WRKSRC} && tr '\\r' '\\n' < ${DISTDIR}/${DIST_SUBDIR}/${DISTFILES} > chef.l") 230 "\tcd ${WRKSRC} && tr '\\r' '\\n' < ${DISTDIR}/${DIST_SUBDIR}/${DISTFILES} > chef.l")
231 231
232 mklines.Check() 232 mklines.Check()
233 233
234 t.CheckOutputLines( 234 t.CheckOutputLines(
235 "WARN: converters/chef/Makefile:2: Unknown shell command \"tr\".", 235 "WARN: converters/chef/Makefile:2: Unknown shell command \"tr\".",
236 "WARN: converters/chef/Makefile:2: The list variable DISTFILES should not be embedded in a word.") 236 "WARN: converters/chef/Makefile:2: The list variable DISTFILES should not be embedded in a word.")
237} 237}
238 238
239func (s *Suite) Test_MkLines_Check__absolute_pathname_depending_on_OPSYS(c *check.C) { 239func (s *Suite) Test_MkLines_Check__absolute_pathname_depending_on_OPSYS(c *check.C) {
240 t := s.Init(c) 240 t := s.Init(c)
241 241
242 t.SetupCommandLine("-Wall") 242 t.SetupCommandLine("-Wall")
243 G.globalData.InitVartypes() 243 G.globalData.InitVartypes()
244 mklines := t.NewMkLines("games/heretic2-demo/Makefile", 244 mklines := t.NewMkLines("games/heretic2-demo/Makefile",
245 MkRcsId, 245 MkRcsID,
246 ".if ${OPSYS} == \"DragonFly\"", 246 ".if ${OPSYS} == \"DragonFly\"",
247 "TOOLS_PLATFORM.gtar=\t/usr/bin/bsdtar", 247 "TOOLS_PLATFORM.gtar=\t/usr/bin/bsdtar",
248 ".endif", 248 ".endif",
249 "TOOLS_PLATFORM.gtar=\t/usr/bin/bsdtar") 249 "TOOLS_PLATFORM.gtar=\t/usr/bin/bsdtar")
250 250
251 mklines.Check() 251 mklines.Check()
252 252
253 // No warning about an unknown shell command in line 3, 253 // No warning about an unknown shell command in line 3,
254 // since that line depends on OPSYS. 254 // since that line depends on OPSYS.
255 t.CheckOutputLines( 255 t.CheckOutputLines(
256 "WARN: games/heretic2-demo/Makefile:3: The variable TOOLS_PLATFORM.gtar may not be set by any package.", 256 "WARN: games/heretic2-demo/Makefile:3: The variable TOOLS_PLATFORM.gtar may not be set by any package.",
257 "WARN: games/heretic2-demo/Makefile:5: The variable TOOLS_PLATFORM.gtar may not be set by any package.", 257 "WARN: games/heretic2-demo/Makefile:5: The variable TOOLS_PLATFORM.gtar may not be set by any package.",
258 "WARN: games/heretic2-demo/Makefile:5: Unknown shell command \"/usr/bin/bsdtar\".") 258 "WARN: games/heretic2-demo/Makefile:5: Unknown shell command \"/usr/bin/bsdtar\".")
259} 259}
260 260
261func (s *Suite) Test_MkLines_checkForUsedComment(c *check.C) { 261func (s *Suite) Test_MkLines_checkForUsedComment(c *check.C) {
262 t := s.Init(c) 262 t := s.Init(c)
263 263
264 t.SetupCommandLine("--show-autofix") 264 t.SetupCommandLine("--show-autofix")
265 t.NewMkLines("Makefile.common", 265 t.NewMkLines("Makefile.common",
266 MkRcsId, 266 MkRcsID,
267 "", 267 "",
268 "# used by sysutils/mc", 268 "# used by sysutils/mc",
269 ).checkForUsedComment("sysutils/mc") 269 ).checkForUsedComment("sysutils/mc")
270 270
271 t.CheckOutputEmpty() 271 t.CheckOutputEmpty()
272 272
273 t.NewMkLines("Makefile.common").checkForUsedComment("category/package") 273 t.NewMkLines("Makefile.common").checkForUsedComment("category/package")
274 274
275 t.CheckOutputEmpty() 275 t.CheckOutputEmpty()
276 276
277 t.NewMkLines("Makefile.common", 277 t.NewMkLines("Makefile.common",
278 MkRcsId, 278 MkRcsID,
279 ).checkForUsedComment("category/package") 279 ).checkForUsedComment("category/package")
280 280
281 t.CheckOutputEmpty() 281 t.CheckOutputEmpty()
282 282
283 t.NewMkLines("Makefile.common", 283 t.NewMkLines("Makefile.common",
284 MkRcsId, 284 MkRcsID,
285 "", 285 "",
286 ).checkForUsedComment("category/package") 286 ).checkForUsedComment("category/package")
287 287
288 t.CheckOutputEmpty() 288 t.CheckOutputEmpty()
289 289
290 t.NewMkLines("Makefile.common", 290 t.NewMkLines("Makefile.common",
291 MkRcsId, 291 MkRcsID,
292 "", 292 "",
293 "VARNAME=\tvalue", 293 "VARNAME=\tvalue",
294 ).checkForUsedComment("category/package") 294 ).checkForUsedComment("category/package")
295 295
296 t.CheckOutputLines( 296 t.CheckOutputLines(
297 "WARN: Makefile.common:2: Please add a line \"# used by category/package\" here.", 297 "WARN: Makefile.common:2: Please add a line \"# used by category/package\" here.",
298 "AUTOFIX: Makefile.common:2: Inserting a line \"# used by category/package\" before this line.") 298 "AUTOFIX: Makefile.common:2: Inserting a line \"# used by category/package\" before this line.")
299 299
300 t.NewMkLines("Makefile.common", 300 t.NewMkLines("Makefile.common",
301 MkRcsId, 301 MkRcsID,
302 "#", 302 "#",
303 "#", 303 "#",
304 ).checkForUsedComment("category/package") 304 ).checkForUsedComment("category/package")
305 305
306 t.CheckOutputLines( 306 t.CheckOutputLines(
307 "WARN: Makefile.common:3: Please add a line \"# used by category/package\" here.", 307 "WARN: Makefile.common:3: Please add a line \"# used by category/package\" here.",
308 "AUTOFIX: Makefile.common:3: Inserting a line \"# used by category/package\" before this line.") 308 "AUTOFIX: Makefile.common:3: Inserting a line \"# used by category/package\" before this line.")
309 309
310 c.Check(G.autofixAvailable, equals, true) 310 c.Check(G.autofixAvailable, equals, true)
311} 311}
312 312
313func (s *Suite) Test_MkLines_DetermineUsedVariables__simple(c *check.C) { 313func (s *Suite) Test_MkLines_DetermineUsedVariables__simple(c *check.C) {
314 t := s.Init(c) 314 t := s.Init(c)
@@ -336,58 +336,58 @@ func (s *Suite) Test_MkLines_DetermineUs @@ -336,58 +336,58 @@ func (s *Suite) Test_MkLines_DetermineUs
336 336
337 c.Check(len(mklines.varuse), equals, 3) 337 c.Check(len(mklines.varuse), equals, 3)
338 c.Check(mklines.varuse["inner"], equals, mkline) 338 c.Check(mklines.varuse["inner"], equals, mkline)
339 c.Check(mklines.varuse["outer."], equals, mkline) 339 c.Check(mklines.varuse["outer."], equals, mkline)
340 c.Check(mklines.varuse["outer.*"], equals, mkline) 340 c.Check(mklines.varuse["outer.*"], equals, mkline)
341} 341}
342 342
343func (s *Suite) Test_MkLines_PrivateTool_Undefined(c *check.C) { 343func (s *Suite) Test_MkLines_PrivateTool_Undefined(c *check.C) {
344 t := s.Init(c) 344 t := s.Init(c)
345 345
346 t.SetupCommandLine("-Wall") 346 t.SetupCommandLine("-Wall")
347 G.globalData.InitVartypes() 347 G.globalData.InitVartypes()
348 mklines := t.NewMkLines("fname", 348 mklines := t.NewMkLines("fname",
349 MkRcsId, 349 MkRcsID,
350 "", 350 "",
351 "\tmd5sum filename") 351 "\tmd5sum filename")
352 352
353 mklines.Check() 353 mklines.Check()
354 354
355 t.CheckOutputLines( 355 t.CheckOutputLines(
356 "WARN: fname:3: Unknown shell command \"md5sum\".") 356 "WARN: fname:3: Unknown shell command \"md5sum\".")
357} 357}
358 358
359func (s *Suite) Test_MkLines_PrivateTool_Defined(c *check.C) { 359func (s *Suite) Test_MkLines_PrivateTool_Defined(c *check.C) {
360 t := s.Init(c) 360 t := s.Init(c)
361 361
362 t.SetupCommandLine("-Wall") 362 t.SetupCommandLine("-Wall")
363 G.globalData.InitVartypes() 363 G.globalData.InitVartypes()
364 mklines := t.NewMkLines("fname", 364 mklines := t.NewMkLines("fname",
365 MkRcsId, 365 MkRcsID,
366 "TOOLS_CREATE+=\tmd5sum", 366 "TOOLS_CREATE+=\tmd5sum",
367 "", 367 "",
368 "\tmd5sum filename") 368 "\tmd5sum filename")
369 369
370 mklines.Check() 370 mklines.Check()
371 371
372 t.CheckOutputEmpty() 372 t.CheckOutputEmpty()
373} 373}
374 374
375func (s *Suite) Test_MkLines_Check_indentation(c *check.C) { 375func (s *Suite) Test_MkLines_Check_indentation(c *check.C) {
376 t := s.Init(c) 376 t := s.Init(c)
377 377
378 t.SetupCommandLine("-Wall") 378 t.SetupCommandLine("-Wall")
379 mklines := t.NewMkLines("options.mk", 379 mklines := t.NewMkLines("options.mk",
380 MkRcsId, 380 MkRcsID,
381 ". if !defined(GUARD_MK)", 381 ". if !defined(GUARD_MK)",
382 ". if ${OPSYS} == ${OPSYS}", 382 ". if ${OPSYS} == ${OPSYS}",
383 ". for i in ${FILES}", 383 ". for i in ${FILES}",
384 ". if !defined(GUARD2_MK)", 384 ". if !defined(GUARD2_MK)",
385 ". else", 385 ". else",
386 ". endif", 386 ". endif",
387 ". endfor", 387 ". endfor",
388 ". if ${COND1}", 388 ". if ${COND1}",
389 ". elif ${COND2}", 389 ". elif ${COND2}",
390 ". else ${COND3}", 390 ". else ${COND3}",
391 ". endif", 391 ". endif",
392 ". endif", 392 ". endif",
393 ". endif", 393 ". endif",
@@ -413,27 +413,27 @@ func (s *Suite) Test_MkLines_Check_inden @@ -413,27 +413,27 @@ func (s *Suite) Test_MkLines_Check_inden
413 "NOTE: options.mk:14: This directive should be indented by 0 spaces.", 413 "NOTE: options.mk:14: This directive should be indented by 0 spaces.",
414 "ERROR: options.mk:15: Unmatched .endif.", 414 "ERROR: options.mk:15: Unmatched .endif.",
415 "NOTE: options.mk:15: This directive should be indented by 0 spaces.") 415 "NOTE: options.mk:15: This directive should be indented by 0 spaces.")
416} 416}
417 417
418// Demonstrates how to define your own make(1) targets. 418// Demonstrates how to define your own make(1) targets.
419func (s *Suite) Test_MkLines_wip_category_Makefile(c *check.C) { 419func (s *Suite) Test_MkLines_wip_category_Makefile(c *check.C) {
420 t := s.Init(c) 420 t := s.Init(c)
421 421
422 t.SetupCommandLine("-Wall") 422 t.SetupCommandLine("-Wall")
423 G.globalData.InitVartypes() 423 G.globalData.InitVartypes()
424 t.SetupTool(&Tool{Name: "rm", Varname: "RM", Predefined: true}) 424 t.SetupTool(&Tool{Name: "rm", Varname: "RM", Predefined: true})
425 mklines := t.NewMkLines("Makefile", 425 mklines := t.NewMkLines("Makefile",
426 MkRcsId, 426 MkRcsID,
427 "", 427 "",
428 "COMMENT=\tWIP pkgsrc packages", 428 "COMMENT=\tWIP pkgsrc packages",
429 "", 429 "",
430 "SUBDIR+=\taaa", 430 "SUBDIR+=\taaa",
431 "SUBDIR+=\tzzz", 431 "SUBDIR+=\tzzz",
432 "", 432 "",
433 "${.CURDIR}/PKGDB:", 433 "${.CURDIR}/PKGDB:",
434 "\t${RM} -f ${.CURDIR}/PKGDB", 434 "\t${RM} -f ${.CURDIR}/PKGDB",
435 "", 435 "",
436 "${.CURDIR}/INDEX:", 436 "${.CURDIR}/INDEX:",
437 "\t${RM} -f ${.CURDIR}/INDEX", 437 "\t${RM} -f ${.CURDIR}/INDEX",
438 "", 438 "",
439 ".include \"../../mk/misc/category.mk\"") 439 ".include \"../../mk/misc/category.mk\"")

cvs diff -r1.12 -r1.13 pkgsrc/pkgtools/pkglint/files/Attic/distinfo_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/distinfo_test.go 2018/01/27 18:50:36 1.12
+++ pkgsrc/pkgtools/pkglint/files/Attic/distinfo_test.go 2018/02/19 12:40:38 1.13
@@ -24,86 +24,86 @@ func (s *Suite) Test_ChecklinesDistinfo( @@ -24,86 +24,86 @@ func (s *Suite) Test_ChecklinesDistinfo(
24 t.CheckOutputLines( 24 t.CheckOutputLines(
25 "ERROR: distinfo:1: Expected \"$"+"NetBSD$\".", 25 "ERROR: distinfo:1: Expected \"$"+"NetBSD$\".",
26 "NOTE: distinfo:2: Empty line expected.", 26 "NOTE: distinfo:2: Empty line expected.",
27 "ERROR: distinfo:5: Expected SHA1, RMD160, SHA512, Size checksums for \"distfile.tar.gz\", got MD5, SHA1.", 27 "ERROR: distinfo:5: Expected SHA1, RMD160, SHA512, Size checksums for \"distfile.tar.gz\", got MD5, SHA1.",
28 "WARN: distinfo:7: Patch file \"patch-nonexistent\" does not exist in directory \"patches\".") 28 "WARN: distinfo:7: Patch file \"patch-nonexistent\" does not exist in directory \"patches\".")
29} 29}
30 30
31func (s *Suite) Test_ChecklinesDistinfo_global_hash_mismatch(c *check.C) { 31func (s *Suite) Test_ChecklinesDistinfo_global_hash_mismatch(c *check.C) {
32 t := s.Init(c) 32 t := s.Init(c)
33 33
34 otherLine := t.NewLine("other/distinfo", 7, "dummy") 34 otherLine := t.NewLine("other/distinfo", 7, "dummy")
35 G.Hash = map[string]*Hash{"SHA512:pkgname-1.0.tar.gz": {"Some-512-bit-hash", otherLine}} 35 G.Hash = map[string]*Hash{"SHA512:pkgname-1.0.tar.gz": {"Some-512-bit-hash", otherLine}}
36 lines := t.NewLines("distinfo", 36 lines := t.NewLines("distinfo",
37 RcsId, 37 RcsID,
38 "", 38 "",
39 "SHA512 (pkgname-1.0.tar.gz) = 12341234") 39 "SHA512 (pkgname-1.0.tar.gz) = 12341234")
40 40
41 ChecklinesDistinfo(lines) 41 ChecklinesDistinfo(lines)
42 42
43 t.CheckOutputLines( 43 t.CheckOutputLines(
44 "ERROR: distinfo:3: The hash SHA512 for pkgname-1.0.tar.gz is 12341234, which differs from Some-512-bit-hash in other/distinfo:7.", 44 "ERROR: distinfo:3: The hash SHA512 for pkgname-1.0.tar.gz is 12341234, which differs from Some-512-bit-hash in other/distinfo:7.",
45 "ERROR: distinfo:EOF: Expected SHA1, RMD160, SHA512, Size checksums for \"pkgname-1.0.tar.gz\", got SHA512.") 45 "ERROR: distinfo:EOF: Expected SHA1, RMD160, SHA512, Size checksums for \"pkgname-1.0.tar.gz\", got SHA512.")
46} 46}
47 47
48func (s *Suite) Test_ChecklinesDistinfo_uncommitted_patch(c *check.C) { 48func (s *Suite) Test_ChecklinesDistinfo_uncommitted_patch(c *check.C) {
49 t := s.Init(c) 49 t := s.Init(c)
50 50
51 t.SetupFileLines("patches/patch-aa", 51 t.SetupFileLines("patches/patch-aa",
52 RcsId, 52 RcsID,
53 "", 53 "",
54 "--- oldfile", 54 "--- oldfile",
55 "+++ newfile", 55 "+++ newfile",
56 "@@ -1,1 +1,1 @@", 56 "@@ -1,1 +1,1 @@",
57 "-old", 57 "-old",
58 "+new") 58 "+new")
59 t.SetupFileLines("CVS/Entries", 59 t.SetupFileLines("CVS/Entries",
60 "/distinfo/...") 60 "/distinfo/...")
61 lines := t.SetupFileLines("distinfo", 61 lines := t.SetupFileLines("distinfo",
62 RcsId, 62 RcsID,
63 "", 63 "",
64 "SHA1 (patch-aa) = 5ad1fb9b3c328fff5caa1a23e8f330e707dd50c0") 64 "SHA1 (patch-aa) = 5ad1fb9b3c328fff5caa1a23e8f330e707dd50c0")
65 G.CurrentDir = t.TmpDir() 65 G.CurrentDir = t.TmpDir()
66 66
67 ChecklinesDistinfo(lines) 67 ChecklinesDistinfo(lines)
68 68
69 t.CheckOutputLines( 69 t.CheckOutputLines(
70 "WARN: ~/distinfo:3: patches/patch-aa is registered in distinfo but not added to CVS.") 70 "WARN: ~/distinfo:3: patches/patch-aa is registered in distinfo but not added to CVS.")
71} 71}
72 72
73func (s *Suite) Test_ChecklinesDistinfo_unrecorded_patches(c *check.C) { 73func (s *Suite) Test_ChecklinesDistinfo_unrecorded_patches(c *check.C) {
74 t := s.Init(c) 74 t := s.Init(c)
75 75
76 t.SetupFileLines("patches/CVS/Entries") 76 t.SetupFileLines("patches/CVS/Entries")
77 t.SetupFileLines("patches/patch-aa") 77 t.SetupFileLines("patches/patch-aa")
78 t.SetupFileLines("patches/patch-src-Makefile") 78 t.SetupFileLines("patches/patch-src-Makefile")
79 lines := t.SetupFileLines("distinfo", 79 lines := t.SetupFileLines("distinfo",
80 RcsId, 80 RcsID,
81 "", 81 "",
82 "SHA1 (distfile.tar.gz) = ...", 82 "SHA1 (distfile.tar.gz) = ...",
83 "RMD160 (distfile.tar.gz) = ...", 83 "RMD160 (distfile.tar.gz) = ...",
84 "SHA512 (distfile.tar.gz) = ...", 84 "SHA512 (distfile.tar.gz) = ...",
85 "Size (distfile.tar.gz) = 1024 bytes") 85 "Size (distfile.tar.gz) = 1024 bytes")
86 G.CurrentDir = t.TmpDir() 86 G.CurrentDir = t.TmpDir()
87 87
88 ChecklinesDistinfo(lines) 88 ChecklinesDistinfo(lines)
89 89
90 t.CheckOutputLines( 90 t.CheckOutputLines(
91 "ERROR: ~/distinfo: patch \"patches/patch-aa\" is not recorded. Run \""+confMake+" makepatchsum\".", 91 "ERROR: ~/distinfo: patch \"patches/patch-aa\" is not recorded. Run \""+confMake+" makepatchsum\".",
92 "ERROR: ~/distinfo: patch \"patches/patch-src-Makefile\" is not recorded. Run \""+confMake+" makepatchsum\".") 92 "ERROR: ~/distinfo: patch \"patches/patch-src-Makefile\" is not recorded. Run \""+confMake+" makepatchsum\".")
93} 93}
94 94
95func (s *Suite) Test_ChecklinesDistinfo_manual_patches(c *check.C) { 95func (s *Suite) Test_ChecklinesDistinfo_manual_patches(c *check.C) {
96 t := s.Init(c) 96 t := s.Init(c)
97 97
98 t.SetupFileLines("patches/manual-libtool.m4") 98 t.SetupFileLines("patches/manual-libtool.m4")
99 lines := t.SetupFileLines("distinfo", 99 lines := t.SetupFileLines("distinfo",
100 RcsId, 100 RcsID,
101 "", 101 "",
102 "SHA1 (patch-aa) = ...") 102 "SHA1 (patch-aa) = ...")
103 G.CurrentDir = t.TmpDir() 103 G.CurrentDir = t.TmpDir()
104 104
105 ChecklinesDistinfo(lines) 105 ChecklinesDistinfo(lines)
106 106
107 t.CheckOutputLines( 107 t.CheckOutputLines(
108 "WARN: ~/distinfo:3: Patch file \"patch-aa\" does not exist in directory \"patches\".") 108 "WARN: ~/distinfo:3: Patch file \"patch-aa\" does not exist in directory \"patches\".")
109} 109}

cvs diff -r1.12 -r1.13 pkgsrc/pkgtools/pkglint/files/Attic/vartype.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/vartype.go 2017/01/01 16:41:37 1.12
+++ pkgsrc/pkgtools/pkglint/files/Attic/vartype.go 2018/02/19 12:40:38 1.13
@@ -1,106 +1,106 @@ @@ -1,106 +1,106 @@
1package main 1package main
2 2
3import ( 3import (
4 "path" 4 "path"
5 "strings" 5 "strings"
6) 6)
7 7
8// Vartype is a combination of a data type and a permission specification. 8// Vartype is a combination of a data type and a permission specification.
9// See vardefs.go for examples, and vartypecheck.go for the implementation. 9// See vardefs.go for examples, and vartypecheck.go for the implementation.
10type Vartype struct { 10type Vartype struct {
11 kindOfList KindOfList 11 kindOfList KindOfList
12 basicType *BasicType 12 basicType *BasicType
13 aclEntries []AclEntry 13 aclEntries []ACLEntry
14 guessed bool 14 guessed bool
15} 15}
16 16
17type KindOfList uint8 17type KindOfList uint8
18 18
19const ( 19const (
20 lkNone KindOfList = iota // Plain data type 20 lkNone KindOfList = iota // Plain data type
21 lkSpace // List entries are separated by whitespace; used in .for loops. 21 lkSpace // List entries are separated by whitespace; used in .for loops.
22 lkShell // List entries are shell words; used in the :M, :S modifiers. 22 lkShell // List entries are shell words; used in the :M, :S modifiers.
23) 23)
24 24
25type AclEntry struct { 25type ACLEntry struct {
26 glob string // Examples: "Makefile", "*.mk" 26 glob string // Examples: "Makefile", "*.mk"
27 permissions AclPermissions 27 permissions ACLPermissions
28} 28}
29 29
30type AclPermissions uint8 30type ACLPermissions uint8
31 31
32const ( 32const (
33 aclpSet AclPermissions = 1 << iota // VAR = value 33 aclpSet ACLPermissions = 1 << iota // VAR = value
34 aclpSetDefault // VAR ?= value 34 aclpSetDefault // VAR ?= value
35 aclpAppend // VAR += value 35 aclpAppend // VAR += value
36 aclpUseLoadtime // OTHER := ${VAR}, OTHER != ${VAR} 36 aclpUseLoadtime // OTHER := ${VAR}, OTHER != ${VAR}
37 aclpUse // OTHER = ${VAR} 37 aclpUse // OTHER = ${VAR}
38 aclpUnknown 38 aclpUnknown
39 aclpAll AclPermissions = aclpAppend | aclpSetDefault | aclpSet | aclpUseLoadtime | aclpUse 39 aclpAll = aclpAppend | aclpSetDefault | aclpSet | aclpUseLoadtime | aclpUse
40 aclpAllRuntime AclPermissions = aclpAppend | aclpSetDefault | aclpSet | aclpUse 40 aclpAllRuntime = aclpAppend | aclpSetDefault | aclpSet | aclpUse
41 aclpAllWrite AclPermissions = aclpSet | aclpSetDefault | aclpAppend 41 aclpAllWrite = aclpSet | aclpSetDefault | aclpAppend
42 aclpAllRead AclPermissions = aclpUseLoadtime | aclpUse 42 aclpAllRead = aclpUseLoadtime | aclpUse
43) 43)
44 44
45func (perms AclPermissions) Contains(subset AclPermissions) bool { 45func (perms ACLPermissions) Contains(subset ACLPermissions) bool {
46 return perms&subset == subset 46 return perms&subset == subset
47} 47}
48 48
49func (perms AclPermissions) String() string { 49func (perms ACLPermissions) String() string {
50 if perms == 0 { 50 if perms == 0 {
51 return "none" 51 return "none"
52 } 52 }
53 result := "" + 53 result := "" +
54 ifelseStr(perms.Contains(aclpSet), "set, ", "") + 54 ifelseStr(perms.Contains(aclpSet), "set, ", "") +
55 ifelseStr(perms.Contains(aclpSetDefault), "set-default, ", "") + 55 ifelseStr(perms.Contains(aclpSetDefault), "set-default, ", "") +
56 ifelseStr(perms.Contains(aclpAppend), "append, ", "") + 56 ifelseStr(perms.Contains(aclpAppend), "append, ", "") +
57 ifelseStr(perms.Contains(aclpUseLoadtime), "use-loadtime, ", "") + 57 ifelseStr(perms.Contains(aclpUseLoadtime), "use-loadtime, ", "") +
58 ifelseStr(perms.Contains(aclpUse), "use, ", "") + 58 ifelseStr(perms.Contains(aclpUse), "use, ", "") +
59 ifelseStr(perms.Contains(aclpUnknown), "unknown, ", "") 59 ifelseStr(perms.Contains(aclpUnknown), "unknown, ", "")
60 return strings.TrimRight(result, ", ") 60 return strings.TrimRight(result, ", ")
61} 61}
62 62
63func (perms AclPermissions) HumanString() string { 63func (perms ACLPermissions) HumanString() string {
64 result := "" + 64 result := "" +
65 ifelseStr(perms.Contains(aclpSet), "set, ", "") + 65 ifelseStr(perms.Contains(aclpSet), "set, ", "") +
66 ifelseStr(perms.Contains(aclpSetDefault), "given a default value, ", "") + 66 ifelseStr(perms.Contains(aclpSetDefault), "given a default value, ", "") +
67 ifelseStr(perms.Contains(aclpAppend), "appended to, ", "") + 67 ifelseStr(perms.Contains(aclpAppend), "appended to, ", "") +
68 ifelseStr(perms.Contains(aclpUseLoadtime), "used at load time, ", "") + 68 ifelseStr(perms.Contains(aclpUseLoadtime), "used at load time, ", "") +
69 ifelseStr(perms.Contains(aclpUse), "used, ", "") 69 ifelseStr(perms.Contains(aclpUse), "used, ", "")
70 return strings.TrimRight(result, ", ") 70 return strings.TrimRight(result, ", ")
71} 71}
72 72
73func (vt *Vartype) EffectivePermissions(fname string) AclPermissions { 73func (vt *Vartype) EffectivePermissions(fname string) ACLPermissions {
74 for _, aclEntry := range vt.aclEntries { 74 for _, aclEntry := range vt.aclEntries {
75 if m, _ := path.Match(aclEntry.glob, path.Base(fname)); m { 75 if m, _ := path.Match(aclEntry.glob, path.Base(fname)); m {
76 return aclEntry.permissions 76 return aclEntry.permissions
77 } 77 }
78 } 78 }
79 return aclpUnknown 79 return aclpUnknown
80} 80}
81 81
82// Returns the union of all possible permissions. This can be used to 82// Returns the union of all possible permissions. This can be used to
83// check whether a variable may be defined or used at all, or if it is 83// check whether a variable may be defined or used at all, or if it is
84// read-only. 84// read-only.
85func (vt *Vartype) Union() AclPermissions { 85func (vt *Vartype) Union() ACLPermissions {
86 var permissions AclPermissions 86 var permissions ACLPermissions
87 for _, aclEntry := range vt.aclEntries { 87 for _, aclEntry := range vt.aclEntries {
88 permissions |= aclEntry.permissions 88 permissions |= aclEntry.permissions
89 } 89 }
90 return permissions 90 return permissions
91} 91}
92 92
93func (vt *Vartype) AllowedFiles(perms AclPermissions) string { 93func (vt *Vartype) AllowedFiles(perms ACLPermissions) string {
94 files := make([]string, 0, len(vt.aclEntries)) 94 files := make([]string, 0, len(vt.aclEntries))
95 for _, aclEntry := range vt.aclEntries { 95 for _, aclEntry := range vt.aclEntries {
96 if aclEntry.permissions.Contains(perms) { 96 if aclEntry.permissions.Contains(perms) {
97 files = append(files, aclEntry.glob) 97 files = append(files, aclEntry.glob)
98 } 98 }
99 } 99 }
100 return strings.Join(files, ", ") 100 return strings.Join(files, ", ")
101} 101}
102 102
103// Returns whether the type is considered a shell list. 103// Returns whether the type is considered a shell list.
104// This distinction between "real lists" and "considered a list" makes 104// This distinction between "real lists" and "considered a list" makes
105// the implementation of checklineMkVartype easier. 105// the implementation of checklineMkVartype easier.
106func (vt *Vartype) IsConsideredList() bool { 106func (vt *Vartype) IsConsideredList() bool {

cvs diff -r1.15 -r1.16 pkgsrc/pkgtools/pkglint/files/Attic/files.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/files.go 2018/01/28 23:21:16 1.15
+++ pkgsrc/pkgtools/pkglint/files/Attic/files.go 2018/02/19 12:40:38 1.16
@@ -1,20 +1,24 @@ @@ -1,20 +1,24 @@
1package main 1package main
2 2
3import ( 3import (
4 "io/ioutil" 4 "io/ioutil"
5 "strings" 5 "strings"
6) 6)
7 7
 8// LoadNonemptyLines loads the given file.
 9// If the file doesn't exist or is empty, an error is logged.
 10//
 11// See [LoadExistingLines].
8func LoadNonemptyLines(fname string, joinBackslashLines bool) []Line { 12func LoadNonemptyLines(fname string, joinBackslashLines bool) []Line {
9 lines, err := readLines(fname, joinBackslashLines) 13 lines, err := readLines(fname, joinBackslashLines)
10 if err != nil { 14 if err != nil {
11 NewLineWhole(fname).Errorf("Cannot be read.") 15 NewLineWhole(fname).Errorf("Cannot be read.")
12 return nil 16 return nil
13 } 17 }
14 if len(lines) == 0 { 18 if len(lines) == 0 {
15 NewLineWhole(fname).Errorf("Must not be empty.") 19 NewLineWhole(fname).Errorf("Must not be empty.")
16 return nil 20 return nil
17 } 21 }
18 return lines 22 return lines
19} 23}
20 24

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

--- pkgsrc/pkgtools/pkglint/files/Attic/patches_test.go 2018/01/28 23:21:16 1.15
+++ pkgsrc/pkgtools/pkglint/files/Attic/patches_test.go 2018/02/19 12:40:38 1.16
@@ -1,115 +1,115 @@ @@ -1,115 +1,115 @@
1package main 1package main
2 2
3import "gopkg.in/check.v1" 3import "gopkg.in/check.v1"
4 4
5func (s *Suite) Test_ChecklinesPatch__with_comment(c *check.C) { 5func (s *Suite) Test_ChecklinesPatch__with_comment(c *check.C) {
6 t := s.Init(c) 6 t := s.Init(c)
7 7
8 t.SetupCommandLine("-Wall") 8 t.SetupCommandLine("-Wall")
9 lines := t.NewLines("patch-WithComment", 9 lines := t.NewLines("patch-WithComment",
10 RcsId, 10 RcsID,
11 "", 11 "",
12 "Text", 12 "Text",
13 "Text", 13 "Text",
14 "", 14 "",
15 "--- file.orig", 15 "--- file.orig",
16 "+++ file", 16 "+++ file",
17 "@@ -5,3 +5,3 @@", 17 "@@ -5,3 +5,3 @@",
18 " context before", 18 " context before",
19 "-old line", 19 "-old line",
20 "+old line", 20 "+old line",
21 " context after") 21 " context after")
22 22
23 ChecklinesPatch(lines) 23 ChecklinesPatch(lines)
24 24
25 t.CheckOutputEmpty() 25 t.CheckOutputEmpty()
26} 26}
27 27
28func (s *Suite) Test_ChecklinesPatch__without_empty_line__autofix(c *check.C) { 28func (s *Suite) Test_ChecklinesPatch__without_empty_line__autofix(c *check.C) {
29 t := s.Init(c) 29 t := s.Init(c)
30 30
31 patchLines := t.SetupFileLines("patch-WithoutEmptyLines", 31 patchLines := t.SetupFileLines("patch-WithoutEmptyLines",
32 RcsId, 32 RcsID,
33 "Text", 33 "Text",
34 "--- file.orig", 34 "--- file.orig",
35 "+++ file", 35 "+++ file",
36 "@@ -5,3 +5,3 @@", 36 "@@ -5,3 +5,3 @@",
37 " context before", 37 " context before",
38 "-old line", 38 "-old line",
39 "+old line", 39 "+old line",
40 " context after") 40 " context after")
41 t.SetupFileLines("distinfo", 41 t.SetupFileLines("distinfo",
42 RcsId, 42 RcsID,
43 "", 43 "",
44 "SHA1 (some patch) = 87ffcaaa0b0677ec679fff612b44df1af05f04df") // Taken from breakpoint at AutofixDistinfo 44 "SHA1 (some patch) = 87ffcaaa0b0677ec679fff612b44df1af05f04df") // Taken from breakpoint at AutofixDistinfo
45 45
46 t.SetupCommandLine("-Wall", "--autofix") 46 t.SetupCommandLine("-Wall", "--autofix")
47 G.CurrentDir = t.TmpDir() 47 G.CurrentDir = t.TmpDir()
48 G.Pkg = &Package{DistinfoFile: "distinfo"} 48 G.Pkg = &Package{DistinfoFile: "distinfo"}
49 49
50 ChecklinesPatch(patchLines) 50 ChecklinesPatch(patchLines)
51 51
52 t.CheckOutputLines( 52 t.CheckOutputLines(
53 "AUTOFIX: ~/patch-WithoutEmptyLines:2: Inserting a line \"\" before this line.", 53 "AUTOFIX: ~/patch-WithoutEmptyLines:2: Inserting a line \"\" before this line.",
54 "AUTOFIX: ~/patch-WithoutEmptyLines:3: Inserting a line \"\" before this line.", 54 "AUTOFIX: ~/patch-WithoutEmptyLines:3: Inserting a line \"\" before this line.",
55 "AUTOFIX: ~/distinfo:3: Replacing \"87ffcaaa0b0677ec679fff612b44df1af05f04df\" "+ 55 "AUTOFIX: ~/distinfo:3: Replacing \"87ffcaaa0b0677ec679fff612b44df1af05f04df\" "+
56 "with \"a7c35294b3853da0acedf8a972cb266baa9582a3\".") 56 "with \"a7c35294b3853da0acedf8a972cb266baa9582a3\".")
57 57
58 t.CheckFileLines("patch-WithoutEmptyLines", 58 t.CheckFileLines("patch-WithoutEmptyLines",
59 RcsId, 59 RcsID,
60 "", 60 "",
61 "Text", 61 "Text",
62 "", 62 "",
63 "--- file.orig", 63 "--- file.orig",
64 "+++ file", 64 "+++ file",
65 "@@ -5,3 +5,3 @@", 65 "@@ -5,3 +5,3 @@",
66 " context before", 66 " context before",
67 "-old line", 67 "-old line",
68 "+old line", 68 "+old line",
69 " context after") 69 " context after")
70 t.CheckFileLines("distinfo", 70 t.CheckFileLines("distinfo",
71 RcsId, 71 RcsID,
72 "", 72 "",
73 "SHA1 (some patch) = a7c35294b3853da0acedf8a972cb266baa9582a3") 73 "SHA1 (some patch) = a7c35294b3853da0acedf8a972cb266baa9582a3")
74} 74}
75 75
76func (s *Suite) Test_ChecklinesPatch__without_comment(c *check.C) { 76func (s *Suite) Test_ChecklinesPatch__without_comment(c *check.C) {
77 t := s.Init(c) 77 t := s.Init(c)
78 78
79 t.SetupCommandLine("-Wall") 79 t.SetupCommandLine("-Wall")
80 lines := t.NewLines("patch-WithoutComment", 80 lines := t.NewLines("patch-WithoutComment",
81 RcsId, 81 RcsID,
82 "", 82 "",
83 "--- file.orig", 83 "--- file.orig",
84 "+++ file", 84 "+++ file",
85 "@@ -5,3 +5,3 @@", 85 "@@ -5,3 +5,3 @@",
86 " context before", 86 " context before",
87 "-old line", 87 "-old line",
88 "+old line", 88 "+old line",
89 " context after") 89 " context after")
90 90
91 ChecklinesPatch(lines) 91 ChecklinesPatch(lines)
92 92
93 t.CheckOutputLines( 93 t.CheckOutputLines(
94 "ERROR: patch-WithoutComment:3: Each patch must be documented.") 94 "ERROR: patch-WithoutComment:3: Each patch must be documented.")
95} 95}
96 96
97func (s *Suite) Test_ChecklinesPatch__git_without_comment(c *check.C) { 97func (s *Suite) Test_ChecklinesPatch__git_without_comment(c *check.C) {
98 t := s.Init(c) 98 t := s.Init(c)
99 99
100 t.SetupCommandLine("-Wall") 100 t.SetupCommandLine("-Wall")
101 lines := t.NewLines("patch-aa", 101 lines := t.NewLines("patch-aa",
102 RcsId, 102 RcsID,
103 "", 103 "",
104 "diff --git a/aa b/aa", 104 "diff --git a/aa b/aa",
105 "index 1234567..1234567 100644", 105 "index 1234567..1234567 100644",
106 "--- a/aa", 106 "--- a/aa",
107 "+++ b/aa", 107 "+++ b/aa",
108 "@@ -1,1 +1,1 @@", 108 "@@ -1,1 +1,1 @@",
109 "-old", 109 "-old",
110 "+new") 110 "+new")
111 111
112 ChecklinesPatch(lines) 112 ChecklinesPatch(lines)
113 113
114 t.CheckOutputLines( 114 t.CheckOutputLines(
115 "ERROR: patch-aa:5: Each patch must be documented.") 115 "ERROR: patch-aa:5: Each patch must be documented.")
@@ -120,183 +120,183 @@ func (s *Suite) Test_checklineOtherAbsol @@ -120,183 +120,183 @@ func (s *Suite) Test_checklineOtherAbsol
120 120
121 line := t.NewLine("patch-ag", 1, "+$install -s -c ./bin/rosegarden ${DESTDIR}$BINDIR") 121 line := t.NewLine("patch-ag", 1, "+$install -s -c ./bin/rosegarden ${DESTDIR}$BINDIR")
122 122
123 checklineOtherAbsolutePathname(line, line.Text) 123 checklineOtherAbsolutePathname(line, line.Text)
124 124
125 t.CheckOutputEmpty() 125 t.CheckOutputEmpty()
126} 126}
127 127
128func (s *Suite) Test_ChecklinesPatch__error_code(c *check.C) { 128func (s *Suite) Test_ChecklinesPatch__error_code(c *check.C) {
129 t := s.Init(c) 129 t := s.Init(c)
130 130
131 t.SetupCommandLine("-Wall") 131 t.SetupCommandLine("-Wall")
132 lines := t.NewLines("patch-ErrorCode", 132 lines := t.NewLines("patch-ErrorCode",
133 RcsId, 133 RcsID,
134 "", 134 "",
135 "*** Error code 1", // Looks like a context diff, but isn't. 135 "*** Error code 1", // Looks like a context diff, but isn't.
136 "", 136 "",
137 "--- file.orig", 137 "--- file.orig",
138 "+++ file", 138 "+++ file",
139 "@@ -5,3 +5,3 @@", 139 "@@ -5,3 +5,3 @@",
140 " context before", 140 " context before",
141 "-old line", 141 "-old line",
142 "+old line", 142 "+old line",
143 " context after") 143 " context after")
144 144
145 ChecklinesPatch(lines) 145 ChecklinesPatch(lines)
146 146
147 t.CheckOutputEmpty() 147 t.CheckOutputEmpty()
148} 148}
149 149
150func (s *Suite) Test_ChecklinesPatch__wrong_header_order(c *check.C) { 150func (s *Suite) Test_ChecklinesPatch__wrong_header_order(c *check.C) {
151 t := s.Init(c) 151 t := s.Init(c)
152 152
153 t.SetupCommandLine("-Wall") 153 t.SetupCommandLine("-Wall")
154 lines := t.NewLines("patch-WrongOrder", 154 lines := t.NewLines("patch-WrongOrder",
155 RcsId, 155 RcsID,
156 "", 156 "",
157 "Text", 157 "Text",
158 "Text", 158 "Text",
159 "", 159 "",
160 "+++ file", // Wrong 160 "+++ file", // Wrong
161 "--- file.orig", // Wrong 161 "--- file.orig", // Wrong
162 "@@ -5,3 +5,3 @@", 162 "@@ -5,3 +5,3 @@",
163 " context before", 163 " context before",
164 "-old line", 164 "-old line",
165 "+old line", 165 "+old line",
166 " context after") 166 " context after")
167 167
168 ChecklinesPatch(lines) 168 ChecklinesPatch(lines)
169 169
170 t.CheckOutputLines( 170 t.CheckOutputLines(
171 "WARN: patch-WrongOrder:7: Unified diff headers should be first ---, then +++.") 171 "WARN: patch-WrongOrder:7: Unified diff headers should be first ---, then +++.")
172} 172}
173 173
174func (s *Suite) Test_ChecklinesPatch__context_diff(c *check.C) { 174func (s *Suite) Test_ChecklinesPatch__context_diff(c *check.C) {
175 t := s.Init(c) 175 t := s.Init(c)
176 176
177 t.SetupCommandLine("-Wall") 177 t.SetupCommandLine("-Wall")
178 lines := t.NewLines("patch-ctx", 178 lines := t.NewLines("patch-ctx",
179 RcsId, 179 RcsID,
180 "", 180 "",
181 "diff -cr history.c.orig history.c", 181 "diff -cr history.c.orig history.c",
182 "*** history.c.orig", 182 "*** history.c.orig",
183 "--- history.c") 183 "--- history.c")
184 184
185 ChecklinesPatch(lines) 185 ChecklinesPatch(lines)
186 186
187 t.CheckOutputLines( 187 t.CheckOutputLines(
188 "ERROR: patch-ctx:4: Each patch must be documented.", 188 "ERROR: patch-ctx:4: Each patch must be documented.",
189 "WARN: patch-ctx:4: Please use unified diffs (diff -u) for patches.") 189 "WARN: patch-ctx:4: Please use unified diffs (diff -u) for patches.")
190} 190}
191 191
192func (s *Suite) Test_ChecklinesPatch__no_patch(c *check.C) { 192func (s *Suite) Test_ChecklinesPatch__no_patch(c *check.C) {
193 t := s.Init(c) 193 t := s.Init(c)
194 194
195 lines := t.NewLines("patch-aa", 195 lines := t.NewLines("patch-aa",
196 RcsId, 196 RcsID,
197 "", 197 "",
198 "-- oldfile", 198 "-- oldfile",
199 "++ newfile") 199 "++ newfile")
200 200
201 ChecklinesPatch(lines) 201 ChecklinesPatch(lines)
202 202
203 t.CheckOutputLines( 203 t.CheckOutputLines(
204 "ERROR: patch-aa: Contains no patch.") 204 "ERROR: patch-aa: Contains no patch.")
205} 205}
206 206
207func (s *Suite) Test_ChecklinesPatch__two_patched_files(c *check.C) { 207func (s *Suite) Test_ChecklinesPatch__two_patched_files(c *check.C) {
208 t := s.Init(c) 208 t := s.Init(c)
209 209
210 lines := t.NewLines("patch-aa", 210 lines := t.NewLines("patch-aa",
211 RcsId, 211 RcsID,
212 "", 212 "",
213 "--- oldfile", 213 "--- oldfile",
214 "+++ newfile", 214 "+++ newfile",
215 "@@ -1 +1 @@", 215 "@@ -1 +1 @@",
216 "-old", 216 "-old",
217 "+new", 217 "+new",
218 "--- oldfile2", 218 "--- oldfile2",
219 "+++ newfile2", 219 "+++ newfile2",
220 "@@ -1 +1 @@", 220 "@@ -1 +1 @@",
221 "-old", 221 "-old",
222 "+new") 222 "+new")
223 223
224 ChecklinesPatch(lines) 224 ChecklinesPatch(lines)
225 225
226 t.CheckOutputLines( 226 t.CheckOutputLines(
227 "ERROR: patch-aa:3: Each patch must be documented.", 227 "ERROR: patch-aa:3: Each patch must be documented.",
228 "WARN: patch-aa: Contains patches for 2 files, should be only one.") 228 "WARN: patch-aa: Contains patches for 2 files, should be only one.")
229} 229}
230 230
231func (s *Suite) Test_ChecklinesPatch__documentation_that_looks_like_patch_lines(c *check.C) { 231func (s *Suite) Test_ChecklinesPatch__documentation_that_looks_like_patch_lines(c *check.C) {
232 t := s.Init(c) 232 t := s.Init(c)
233 233
234 lines := t.NewLines("patch-aa", 234 lines := t.NewLines("patch-aa",
235 RcsId, 235 RcsID,
236 "", 236 "",
237 "--- oldfile", 237 "--- oldfile",
238 "", 238 "",
239 "+++ newfile", 239 "+++ newfile",
240 "", 240 "",
241 "*** oldOrNewFile") 241 "*** oldOrNewFile")
242 242
243 ChecklinesPatch(lines) 243 ChecklinesPatch(lines)
244 244
245 t.CheckOutputLines( 245 t.CheckOutputLines(
246 "ERROR: patch-aa: Contains no patch.") 246 "ERROR: patch-aa: Contains no patch.")
247} 247}
248 248
249func (s *Suite) Test_ChecklinesPatch__only_unified_header_but_no_content(c *check.C) { 249func (s *Suite) Test_ChecklinesPatch__only_unified_header_but_no_content(c *check.C) {
250 t := s.Init(c) 250 t := s.Init(c)
251 251
252 lines := t.NewLines("patch-unified", 252 lines := t.NewLines("patch-unified",
253 RcsId, 253 RcsID,
254 "", 254 "",
255 "Documentation for the patch", 255 "Documentation for the patch",
256 "", 256 "",
257 "--- file.orig", 257 "--- file.orig",
258 "+++ file") 258 "+++ file")
259 259
260 ChecklinesPatch(lines) 260 ChecklinesPatch(lines)
261 261
262 t.CheckOutputLines( 262 t.CheckOutputLines(
263 "ERROR: patch-unified:EOF: No patch hunks for \"file\".") 263 "ERROR: patch-unified:EOF: No patch hunks for \"file\".")
264} 264}
265 265
266func (s *Suite) Test_ChecklinesPatch__only_context_header_but_no_content(c *check.C) { 266func (s *Suite) Test_ChecklinesPatch__only_context_header_but_no_content(c *check.C) {
267 t := s.Init(c) 267 t := s.Init(c)
268 268
269 lines := t.NewLines("patch-context", 269 lines := t.NewLines("patch-context",
270 RcsId, 270 RcsID,
271 "", 271 "",
272 "Documentation for the patch", 272 "Documentation for the patch",
273 "", 273 "",
274 "*** file.orig", 274 "*** file.orig",
275 "--- file") 275 "--- file")
276 276
277 ChecklinesPatch(lines) 277 ChecklinesPatch(lines)
278 278
279 // Context diffs are deprecated, therefore it is not worth 279 // Context diffs are deprecated, therefore it is not worth
280 // adding extra code for checking them thoroughly. 280 // adding extra code for checking them thoroughly.
281 t.CheckOutputLines( 281 t.CheckOutputLines(
282 "WARN: patch-context:5: Please use unified diffs (diff -u) for patches.") 282 "WARN: patch-context:5: Please use unified diffs (diff -u) for patches.")
283} 283}
284 284
285func (s *Suite) Test_ChecklinesPatch__Makefile_with_absolute_pathnames(c *check.C) { 285func (s *Suite) Test_ChecklinesPatch__Makefile_with_absolute_pathnames(c *check.C) {
286 t := s.Init(c) 286 t := s.Init(c)
287 287
288 lines := t.NewLines("patch-unified", 288 lines := t.NewLines("patch-unified",
289 RcsId, 289 RcsID,
290 "", 290 "",
291 "Documentation for the patch", 291 "Documentation for the patch",
292 "", 292 "",
293 "--- Makefile.orig", 293 "--- Makefile.orig",
294 "+++ Makefile", 294 "+++ Makefile",
295 "@@ -1,3 +1,7 @@", 295 "@@ -1,3 +1,7 @@",
296 " \t/bin/cp context before", 296 " \t/bin/cp context before",
297 "-\t/bin/cp deleted", 297 "-\t/bin/cp deleted",
298 "+\t/bin/cp added", 298 "+\t/bin/cp added",
299 "+#\t/bin/cp added comment", 299 "+#\t/bin/cp added comment",
300 "+# added comment", 300 "+# added comment",
301 "+\t${DESTDIR}/bin/cp added", 301 "+\t${DESTDIR}/bin/cp added",
302 "+\t${prefix}/bin/cp added", 302 "+\t${prefix}/bin/cp added",
@@ -313,125 +313,125 @@ func (s *Suite) Test_ChecklinesPatch__Ma @@ -313,125 +313,125 @@ func (s *Suite) Test_ChecklinesPatch__Ma
313 ChecklinesPatch(lines) 313 ChecklinesPatch(lines)
314 314
315 t.CheckOutputLines( 315 t.CheckOutputLines(
316 "WARN: patch-unified:8: Found absolute pathname: /bin/cp", 316 "WARN: patch-unified:8: Found absolute pathname: /bin/cp",
317 "WARN: patch-unified:10: Found absolute pathname: /bin/cp", 317 "WARN: patch-unified:10: Found absolute pathname: /bin/cp",
318 "WARN: patch-unified:13: Found absolute pathname: /bin/cp", 318 "WARN: patch-unified:13: Found absolute pathname: /bin/cp",
319 "WARN: patch-unified:15: Found absolute pathname: /bin/cp") 319 "WARN: patch-unified:15: Found absolute pathname: /bin/cp")
320} 320}
321 321
322func (s *Suite) Test_ChecklinesPatch__no_newline_with_text_following(c *check.C) { 322func (s *Suite) Test_ChecklinesPatch__no_newline_with_text_following(c *check.C) {
323 t := s.Init(c) 323 t := s.Init(c)
324 324
325 lines := t.NewLines("patch-aa", 325 lines := t.NewLines("patch-aa",
326 RcsId, 326 RcsID,
327 "", 327 "",
328 "comment", 328 "comment",
329 "", 329 "",
330 "--- oldfile", 330 "--- oldfile",
331 "+++ newfile", 331 "+++ newfile",
332 "@@ -1 +1 @@", 332 "@@ -1 +1 @@",
333 "-old", 333 "-old",
334 "\\ No newline at end of file", 334 "\\ No newline at end of file",
335 "+new", 335 "+new",
336 "\\ No newline at end of file", 336 "\\ No newline at end of file",
337 "last line (a comment)") 337 "last line (a comment)")
338 338
339 ChecklinesPatch(lines) 339 ChecklinesPatch(lines)
340 340
341 t.CheckOutputLines( 341 t.CheckOutputLines(
342 "WARN: patch-aa:12: Empty line or end of file expected.") 342 "WARN: patch-aa:12: Empty line or end of file expected.")
343} 343}
344 344
345func (s *Suite) Test_ChecklinesPatch__no_newline(c *check.C) { 345func (s *Suite) Test_ChecklinesPatch__no_newline(c *check.C) {
346 t := s.Init(c) 346 t := s.Init(c)
347 347
348 lines := t.NewLines("patch-aa", 348 lines := t.NewLines("patch-aa",
349 RcsId, 349 RcsID,
350 "", 350 "",
351 "comment", 351 "comment",
352 "", 352 "",
353 "--- oldfile", 353 "--- oldfile",
354 "+++ newfile", 354 "+++ newfile",
355 "@@ -1 +1 @@", 355 "@@ -1 +1 @@",
356 "-old", 356 "-old",
357 "\\ No newline at end of file", 357 "\\ No newline at end of file",
358 "+new", 358 "+new",
359 "\\ No newline at end of file") 359 "\\ No newline at end of file")
360 360
361 ChecklinesPatch(lines) 361 ChecklinesPatch(lines)
362 362
363 t.CheckOutputEmpty() 363 t.CheckOutputEmpty()
364} 364}
365 365
366func (s *Suite) Test_ChecklinesPatch__empty_lines_left_out_at_eof(c *check.C) { 366func (s *Suite) Test_ChecklinesPatch__empty_lines_left_out_at_eof(c *check.C) {
367 t := s.Init(c) 367 t := s.Init(c)
368 368
369 lines := t.NewLines("patch-aa", 369 lines := t.NewLines("patch-aa",
370 RcsId, 370 RcsID,
371 "", 371 "",
372 "comment", 372 "comment",
373 "", 373 "",
374 "--- oldfile", 374 "--- oldfile",
375 "+++ newfile", 375 "+++ newfile",
376 "@@ -1,7 +1,6 @@", 376 "@@ -1,7 +1,6 @@",
377 " 1", 377 " 1",
378 " 2", 378 " 2",
379 " 3", 379 " 3",
380 "-4", 380 "-4",
381 " 5", 381 " 5",
382 " 6") // Line 7 was empty, therefore omitted 382 " 6") // Line 7 was empty, therefore omitted
383 383
384 ChecklinesPatch(lines) 384 ChecklinesPatch(lines)
385 385
386 t.CheckOutputEmpty() 386 t.CheckOutputEmpty()
387} 387}
388 388
389// In some context lines, the leading space character is missing. 389// In some context lines, the leading space character is missing.
390// Since this is no problem for patch(1), pkglint also doesn't complain. 390// Since this is no problem for patch(1), pkglint also doesn't complain.
391func (s *Suite) Test_ChecklinesPatch__context_lines_with_tab_instead_of_space(c *check.C) { 391func (s *Suite) Test_ChecklinesPatch__context_lines_with_tab_instead_of_space(c *check.C) {
392 t := s.Init(c) 392 t := s.Init(c)
393 393
394 lines := t.NewLines("patch-aa", 394 lines := t.NewLines("patch-aa",
395 RcsId, 395 RcsID,
396 "", 396 "",
397 "comment", 397 "comment",
398 "", 398 "",
399 "--- oldfile", 399 "--- oldfile",
400 "+++ newfile", 400 "+++ newfile",
401 "@@ -1,3 +1,3 @@", 401 "@@ -1,3 +1,3 @@",
402 "\tcontext", 402 "\tcontext",
403 "-old", 403 "-old",
404 "+new", 404 "+new",
405 "\tcontext") 405 "\tcontext")
406 406
407 ChecklinesPatch(lines) 407 ChecklinesPatch(lines)
408 408
409 t.CheckOutputEmpty() 409 t.CheckOutputEmpty()
410} 410}
411 411
412// Must not panic. 412// Must not panic.
413func (s *Suite) Test_ChecklinesPatch__autofix_empty_patch(c *check.C) { 413func (s *Suite) Test_ChecklinesPatch__autofix_empty_patch(c *check.C) {
414 t := s.Init(c) 414 t := s.Init(c)
415 415
416 t.SetupCommandLine("-Wall", "--autofix") 416 t.SetupCommandLine("-Wall", "--autofix")
417 lines := t.NewLines("patch-aa", 417 lines := t.NewLines("patch-aa",
418 RcsId) 418 RcsID)
419 419
420 ChecklinesPatch(lines) 420 ChecklinesPatch(lines)
421 421
422 t.CheckOutputEmpty() 422 t.CheckOutputEmpty()
423} 423}
424 424
425// Must not panic. 425// Must not panic.
426func (s *Suite) Test_ChecklinesPatch__autofix_long_empty_patch(c *check.C) { 426func (s *Suite) Test_ChecklinesPatch__autofix_long_empty_patch(c *check.C) {
427 t := s.Init(c) 427 t := s.Init(c)
428 428
429 t.SetupCommandLine("-Wall", "--autofix") 429 t.SetupCommandLine("-Wall", "--autofix")
430 lines := t.NewLines("patch-aa", 430 lines := t.NewLines("patch-aa",
431 RcsId, 431 RcsID,
432 "") 432 "")
433 433
434 ChecklinesPatch(lines) 434 ChecklinesPatch(lines)
435 435
436 t.CheckOutputEmpty() 436 t.CheckOutputEmpty()
437} 437}

cvs diff -r1.24 -r1.25 pkgsrc/pkgtools/pkglint/files/Attic/globaldata.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/globaldata.go 2018/01/28 23:21:16 1.24
+++ pkgsrc/pkgtools/pkglint/files/Attic/globaldata.go 2018/02/19 12:40:38 1.25
@@ -10,27 +10,27 @@ import ( @@ -10,27 +10,27 @@ import (
10) 10)
11 11
12// GlobalData contains data describing pkgsrc as a whole. 12// GlobalData contains data describing pkgsrc as a whole.
13type GlobalData struct { 13type GlobalData struct {
14 Pkgsrcdir string // Relative to the current working directory. 14 Pkgsrcdir string // Relative to the current working directory.
15 MasterSiteURLToVar map[string]string // "https://github.com/" => "MASTER_SITE_GITHUB" 15 MasterSiteURLToVar map[string]string // "https://github.com/" => "MASTER_SITE_GITHUB"
16 MasterSiteVarToURL map[string]string // "MASTER_SITE_GITHUB" => "https://github.com/" 16 MasterSiteVarToURL map[string]string // "MASTER_SITE_GITHUB" => "https://github.com/"
17 PkgOptions map[string]string // "x11" => "Provides X11 support" 17 PkgOptions map[string]string // "x11" => "Provides X11 support"
18 Tools ToolRegistry // 18 Tools ToolRegistry //
19 SystemBuildDefs map[string]bool // The set of user-defined variables that are added to BUILD_DEFS within the bsd.pkg.mk file. 19 SystemBuildDefs map[string]bool // The set of user-defined variables that are added to BUILD_DEFS within the bsd.pkg.mk file.
20 suggestedUpdates []SuggestedUpdate // 20 suggestedUpdates []SuggestedUpdate //
21 suggestedWipUpdates []SuggestedUpdate // 21 suggestedWipUpdates []SuggestedUpdate //
22 LastChange map[string]*Change // 22 LastChange map[string]*Change //
23 UserDefinedVars map[string]MkLine // varname => line 23 UserDefinedVars map[string]MkLine // varname => line; used for checking BUILD_DEFS
24 Deprecated map[string]string // 24 Deprecated map[string]string //
25 vartypes map[string]*Vartype // varcanon => type 25 vartypes map[string]*Vartype // varcanon => type
26 latest map[string]string // "lang/php[0-9]*" => "lang/php70" 26 latest map[string]string // "lang/php[0-9]*" => "lang/php70"
27} 27}
28 28
29// Change is a change entry from the `doc/CHANGES-*` files. 29// Change is a change entry from the `doc/CHANGES-*` files.
30type Change struct { 30type Change struct {
31 Line Line 31 Line Line
32 Action string 32 Action string
33 Pkgpath string 33 Pkgpath string
34 Version string 34 Version string
35 Author string 35 Author string
36 Date string 36 Date string
@@ -95,51 +95,51 @@ func (gd *GlobalData) Latest(category st @@ -95,51 +95,51 @@ func (gd *GlobalData) Latest(category st
95 } 95 }
96 if latest == "" { 96 if latest == "" {
97 return error() 97 return error()
98 } 98 }
99 99
100 gd.latest[key] = latest 100 gd.latest[key] = latest
101 return latest 101 return latest
102} 102}
103 103
104func (gd *GlobalData) loadDistSites() { 104func (gd *GlobalData) loadDistSites() {
105 fname := gd.Pkgsrcdir + "/mk/fetch/sites.mk" 105 fname := gd.Pkgsrcdir + "/mk/fetch/sites.mk"
106 lines := LoadExistingLines(fname, true) 106 lines := LoadExistingLines(fname, true)
107 107
108 name2url := make(map[string]string) 108 nameToUrl := make(map[string]string)
109 url2name := make(map[string]string) 109 urlToName := make(map[string]string)
110 for _, line := range lines { 110 for _, line := range lines {
111 if m, commented, varname, _, _, _, urls, _, _ := MatchVarassign(line.Text); m { 111 if m, commented, varname, _, _, _, urls, _, _ := MatchVarassign(line.Text); m {
112 if !commented && hasPrefix(varname, "MASTER_SITE_") && varname != "MASTER_SITE_BACKUP" { 112 if !commented && hasPrefix(varname, "MASTER_SITE_") && varname != "MASTER_SITE_BACKUP" {
113 for _, url := range splitOnSpace(urls) { 113 for _, url := range splitOnSpace(urls) {
114 if matches(url, `^(?:http://|https://|ftp://)`) { 114 if matches(url, `^(?:http://|https://|ftp://)`) {
115 if name2url[varname] == "" { 115 if nameToUrl[varname] == "" {
116 name2url[varname] = url 116 nameToUrl[varname] = url
117 } 117 }
118 url2name[url] = varname 118 urlToName[url] = varname
119 } 119 }
120 } 120 }
121 } 121 }
122 } 122 }
123 } 123 }
124 124
125 // Explicitly allowed, although not defined in mk/fetch/sites.mk. 125 // Explicitly allowed, although not defined in mk/fetch/sites.mk.
126 name2url["MASTER_SITE_LOCAL"] = "ftp://ftp.NetBSD.org/pub/pkgsrc/distfiles/LOCAL_PORTS/" 126 nameToUrl["MASTER_SITE_LOCAL"] = "ftp://ftp.NetBSD.org/pub/pkgsrc/distfiles/LOCAL_PORTS/"
127 127
128 if trace.Tracing { 128 if trace.Tracing {
129 trace.Stepf("Loaded %d MASTER_SITE_* URLs.", len(url2name)) 129 trace.Stepf("Loaded %d MASTER_SITE_* URLs.", len(urlToName))
130 } 130 }
131 gd.MasterSiteURLToVar = url2name 131 gd.MasterSiteURLToVar = urlToName
132 gd.MasterSiteVarToURL = name2url 132 gd.MasterSiteVarToURL = nameToUrl
133} 133}
134 134
135func (gd *GlobalData) loadPkgOptions() { 135func (gd *GlobalData) loadPkgOptions() {
136 fname := gd.Pkgsrcdir + "/mk/defaults/options.description" 136 fname := gd.Pkgsrcdir + "/mk/defaults/options.description"
137 lines := LoadExistingLines(fname, false) 137 lines := LoadExistingLines(fname, false)
138 138
139 gd.PkgOptions = make(map[string]string) 139 gd.PkgOptions = make(map[string]string)
140 for _, line := range lines { 140 for _, line := range lines {
141 if m, optname, optdescr := match2(line.Text, `^([-0-9a-z_+]+)(?:\s+(.*))?$`); m { 141 if m, optname, optdescr := match2(line.Text, `^([-0-9a-z_+]+)(?:\s+(.*))?$`); m {
142 gd.PkgOptions[optname] = optdescr 142 gd.PkgOptions[optname] = optdescr
143 } else { 143 } else {
144 line.Fatalf("Unknown line format.") 144 line.Fatalf("Unknown line format.")
145 } 145 }
@@ -170,48 +170,48 @@ func (gd *GlobalData) loadTools() { @@ -170,48 +170,48 @@ func (gd *GlobalData) loadTools() {
170 reg.RegisterTool(&Tool{"test", "TEST", true, true, true}) 170 reg.RegisterTool(&Tool{"test", "TEST", true, true, true})
171 reg.RegisterTool(&Tool{"true", "TRUE", true /*why?*/, true, true}) 171 reg.RegisterTool(&Tool{"true", "TRUE", true /*why?*/, true, true})
172 172
173 systemBuildDefs := make(map[string]bool) 173 systemBuildDefs := make(map[string]bool)
174 174
175 for _, basename := range toolFiles { 175 for _, basename := range toolFiles {
176 fname := G.globalData.Pkgsrcdir + "/mk/tools/" + basename 176 fname := G.globalData.Pkgsrcdir + "/mk/tools/" + basename
177 lines := LoadExistingLines(fname, true) 177 lines := LoadExistingLines(fname, true)
178 for _, line := range lines { 178 for _, line := range lines {
179 reg.ParseToolLine(line) 179 reg.ParseToolLine(line)
180 } 180 }
181 } 181 }
182 182
183 for _, basename := range [...]string{"bsd.prefs.mk", "bsd.pkg.mk"} { 183 for _, relativeName := range [...]string{"mk/bsd.prefs.mk", "mk/bsd.pkg.mk"} {
184 fname := G.globalData.Pkgsrcdir + "/mk/" + basename 184 fname := G.globalData.Pkgsrcdir + "/" + relativeName
185 condDepth := 0 185 condDepth := 0
186 186
187 lines := LoadExistingLines(fname, true) 187 lines := LoadExistingLines(fname, true)
188 for _, line := range lines { 188 for _, line := range lines {
189 text := line.Text 189 text := line.Text
190 if hasPrefix(text, "#") { 190 if hasPrefix(text, "#") {
191 continue 191 continue
192 } 192 }
193 193
194 if m, _, varname, _, _, _, value, _, _ := MatchVarassign(text); m { 194 if m, _, varname, _, _, _, value, _, _ := MatchVarassign(text); m {
195 if varname == "USE_TOOLS" { 195 if varname == "USE_TOOLS" {
196 if trace.Tracing { 196 if trace.Tracing {
197 trace.Stepf("[condDepth=%d] %s", condDepth, value) 197 trace.Stepf("[condDepth=%d] %s", condDepth, value)
198 } 198 }
199 if condDepth == 0 || condDepth == 1 && basename == "bsd.prefs.mk" { 199 if condDepth == 0 || condDepth == 1 && relativeName == "mk/bsd.prefs.mk" {
200 for _, toolname := range splitOnSpace(value) { 200 for _, toolname := range splitOnSpace(value) {
201 if !containsVarRef(toolname) { 201 if !containsVarRef(toolname) {
202 for _, tool := range [...]*Tool{reg.Register(toolname), reg.Register("TOOLS_" + toolname)} { 202 for _, tool := range [...]*Tool{reg.Register(toolname), reg.Register("TOOLS_" + toolname)} {
203 tool.Predefined = true 203 tool.Predefined = true
204 if basename == "bsd.prefs.mk" { 204 if relativeName == "mk/bsd.prefs.mk" {
205 tool.UsableAtLoadtime = true 205 tool.UsableAtLoadtime = true
206 } 206 }
207 } 207 }
208 } 208 }
209 } 209 }
210 } 210 }
211 211
212 } else if varname == "_BUILD_DEFS" { 212 } else if varname == "_BUILD_DEFS" {
213 for _, bdvar := range splitOnSpace(value) { 213 for _, bdvar := range splitOnSpace(value) {
214 systemBuildDefs[bdvar] = true 214 systemBuildDefs[bdvar] = true
215 } 215 }
216 } 216 }
217 217

cvs diff -r1.24 -r1.25 pkgsrc/pkgtools/pkglint/files/Attic/package.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/package.go 2018/01/27 18:50:36 1.24
+++ pkgsrc/pkgtools/pkglint/files/Attic/package.go 2018/02/19 12:40:38 1.25
@@ -427,27 +427,27 @@ func (pkg *Package) checkfilePackageMake @@ -427,27 +427,27 @@ func (pkg *Package) checkfilePackageMake
427 427
428 if vardef["COMMENT"] == nil { 428 if vardef["COMMENT"] == nil {
429 NewLineWhole(fname).Warnf("No COMMENT given.") 429 NewLineWhole(fname).Warnf("No COMMENT given.")
430 } 430 }
431 431
432 if imake, x11 := vardef["USE_IMAKE"], vardef["USE_X11"]; imake != nil && x11 != nil { 432 if imake, x11 := vardef["USE_IMAKE"], vardef["USE_X11"]; imake != nil && x11 != nil {
433 if !hasSuffix(x11.Filename, "/mk/x11.buildlink3.mk") { 433 if !hasSuffix(x11.Filename, "/mk/x11.buildlink3.mk") {
434 imake.Notef("USE_IMAKE makes USE_X11 in %s superfluous.", x11.ReferenceFrom(imake.Line)) 434 imake.Notef("USE_IMAKE makes USE_X11 in %s superfluous.", x11.ReferenceFrom(imake.Line))
435 } 435 }
436 } 436 }
437 437
438 pkg.checkUpdate() 438 pkg.checkUpdate()
439 mklines.Check() 439 mklines.Check()
440 pkg.ChecklinesPackageMakefileVarorder(mklines) 440 pkg.CheckVarorder(mklines)
441 SaveAutofixChanges(mklines.lines) 441 SaveAutofixChanges(mklines.lines)
442} 442}
443 443
444func (pkg *Package) getNbpart() string { 444func (pkg *Package) getNbpart() string {
445 line := pkg.vardef["PKGREVISION"] 445 line := pkg.vardef["PKGREVISION"]
446 if line == nil { 446 if line == nil {
447 return "" 447 return ""
448 } 448 }
449 pkgrevision := line.Value() 449 pkgrevision := line.Value()
450 if rev, err := strconv.Atoi(pkgrevision); err == nil { 450 if rev, err := strconv.Atoi(pkgrevision); err == nil {
451 return "nb" + strconv.Itoa(rev) 451 return "nb" + strconv.Itoa(rev)
452 } 452 }
453 return "" 453 return ""
@@ -578,224 +578,230 @@ func (pkg *Package) checkUpdate() { @@ -578,224 +578,230 @@ func (pkg *Package) checkUpdate() {
578 pkgnameLine.Warnf("This package should be updated to %s%s.", sugg.Version, comment) 578 pkgnameLine.Warnf("This package should be updated to %s%s.", sugg.Version, comment)
579 Explain( 579 Explain(
580 "The wishlist for package updates in doc/TODO mentions that a newer", 580 "The wishlist for package updates in doc/TODO mentions that a newer",
581 "version of this package is available.") 581 "version of this package is available.")
582 case cmp > 0: 582 case cmp > 0:
583 pkgnameLine.Notef("This package is newer than the update request to %s%s.", suggver, comment) 583 pkgnameLine.Notef("This package is newer than the update request to %s%s.", suggver, comment)
584 default: 584 default:
585 pkgnameLine.Notef("The update request to %s from doc/TODO%s has been done.", suggver, comment) 585 pkgnameLine.Notef("The update request to %s from doc/TODO%s has been done.", suggver, comment)
586 } 586 }
587 } 587 }
588 } 588 }
589} 589}
590 590
591func (pkg *Package) ChecklinesPackageMakefileVarorder(mklines *MkLines) { 591// CheckVarorder checks that in simple package Makefiles,
 592// the most common variables appear in a fixed order.
 593// The order itself is a little arbitrary but provides
 594// at least a bit of consistency.
 595func (pkg *Package) CheckVarorder(mklines *MkLines) {
592 if trace.Tracing { 596 if trace.Tracing {
593 defer trace.Call0()() 597 defer trace.Call0()()
594 } 598 }
595 599
596 if !G.opts.WarnOrder || pkg.seenMakefileCommon { 600 if !G.opts.WarnOrder || pkg.seenMakefileCommon {
597 return 601 return
598 } 602 }
599 603
600 type OccCount uint8 604 type Repetition uint8
601 const ( 605 const (
602 once OccCount = iota 606 optional Repetition = iota
603 optional 607 once
604 many 608 many
605 ) 609 )
606 type OccDef struct { 610 type Variable struct {
607 varname string 611 varname string
608 count OccCount 612 repetition Repetition
609 } 613 }
610 type OccGroup struct { 614 type Section struct {
611 name string 615 repetition Repetition
612 count OccCount 616 vars []Variable
613 occ []OccDef 617 }
614 } 618 variable := func(name string, repetition Repetition) Variable { return Variable{name, repetition} }
615 619 section := func(repetition Repetition, vars ...Variable) Section { return Section{repetition, vars} }
616 var sections = []OccGroup{ 620
617 {"Initial comments", once, 621 var sections = []Section{
618 []OccDef{}, 622 section(once,
619 }, 623 variable("GITHUB_PROJECT", optional), // either here or below MASTER_SITES
620 {"Unsorted stuff, part 1", once, 624 variable("GITHUB_TAG", optional),
621 []OccDef{ 625 variable("DISTNAME", optional),
622 {"DISTNAME", optional}, 626 variable("PKGNAME", optional),
623 {"PKGNAME", optional}, 627 variable("PKGREVISION", optional),
624 {"PKGREVISION", optional}, 628 variable("CATEGORIES", once),
625 {"CATEGORIES", once}, 629 variable("MASTER_SITES", many),
626 {"MASTER_SITES", many}, 630 variable("GITHUB_PROJECT", optional), // either here or at the very top
627 {"DIST_SUBDIR", optional}, 631 variable("GITHUB_TAG", optional),
628 {"EXTRACT_SUFX", optional}, 632 variable("DIST_SUBDIR", optional),
629 {"DISTFILES", many}, 633 variable("EXTRACT_SUFX", optional),
630 {"SITES.*", many}, 634 variable("DISTFILES", many),
631 }, 635 variable("SITES.*", many)),
632 }, 636 section(optional,
633 {"Distribution patches", optional, 637 variable("PATCH_SITES", optional), // or once?
634 []OccDef{ 638 variable("PATCH_SITE_SUBDIR", optional),
635 {"PATCH_SITES", optional}, // or once? 639 variable("PATCHFILES", optional), // or once?
636 {"PATCH_SITE_SUBDIR", optional}, 640 variable("PATCH_DIST_ARGS", optional),
637 {"PATCHFILES", optional}, // or once? 641 variable("PATCH_DIST_STRIP", optional),
638 {"PATCH_DIST_ARGS", optional}, 642 variable("PATCH_DIST_CAT", optional)),
639 {"PATCH_DIST_STRIP", optional}, 643 section(once,
640 {"PATCH_DIST_CAT", optional}, 644 variable("MAINTAINER", optional),
641 }, 645 variable("OWNER", optional),
642 }, 646 variable("HOMEPAGE", optional),
643 {"Unsorted stuff, part 2", once, 647 variable("COMMENT", once),
644 []OccDef{ 648 variable("LICENSE", once)),
645 {"MAINTAINER", optional}, 649 section(optional,
646 {"OWNER", optional}, 650 variable("LICENSE_FILE", optional),
647 {"HOMEPAGE", optional}, 651 variable("RESTRICTED", optional),
648 {"COMMENT", once}, 652 variable("NO_BIN_ON_CDROM", optional),
649 {"LICENSE", once}, 653 variable("NO_BIN_ON_FTP", optional),
650 }, 654 variable("NO_SRC_ON_CDROM", optional),
651 }, 655 variable("NO_SRC_ON_FTP", optional)),
652 {"Legal issues", optional, 656 section(optional,
653 []OccDef{ 657 variable("BROKEN_EXCEPT_ON_PLATFORM", many),
654 {"LICENSE_FILE", optional}, 658 variable("BROKEN_ON_PLATFORM", many),
655 {"RESTRICTED", optional}, 659 variable("NOT_FOR_PLATFORM", many),
656 {"NO_BIN_ON_CDROM", optional}, 660 variable("ONLY_FOR_PLATFORM", many),
657 {"NO_BIN_ON_FTP", optional}, 661 variable("NOT_FOR_COMPILER", many),
658 {"NO_SRC_ON_CDROM", optional}, 662 variable("ONLY_FOR_COMPILER", many),
659 {"NO_SRC_ON_FTP", optional}, 663 variable("NOT_FOR_UNPRIVILEGED", optional),
660 }, 664 variable("ONLY_FOR_UNPRIVILEGED", optional)),
661 }, 665 section(optional,
662 {"Technical restrictions", optional, 666 variable("BUILD_DEPENDS", many),
663 []OccDef{ 667 variable("TOOL_DEPENDS", many),
664 {"BROKEN_EXCEPT_ON_PLATFORM", many}, 668 variable("DEPENDS", many)),
665 {"BROKEN_ON_PLATFORM", many}, 669 }
666 {"NOT_FOR_PLATFORM", many}, 670
667 {"ONLY_FOR_PLATFORM", many}, 671 firstRelevant := -1
668 {"NOT_FOR_COMPILER", many}, 672 lastRelevant := -1
669 {"ONLY_FOR_COMPILER", many}, 673 skip := func() bool {
670 {"NOT_FOR_UNPRIVILEGED", optional}, 674 relevantVars := make(map[string]bool)
671 {"ONLY_FOR_UNPRIVILEGED", optional}, 675 for _, section := range sections {
672 }, 676 for _, variable := range section.vars {
673 }, 677 relevantVars[variable.varname] = true
674 {"Dependencies", optional, 678 }
675 []OccDef{ 
676 {"BUILD_DEPENDS", many}, 
677 {"TOOL_DEPENDS", many}, 
678 {"DEPENDS", many}, 
679 }, 
680 }, 
681 } 
682 
683 lineno := 0 
684 sectindex := -1 
685 varindex := 0 
686 nextSection := true 
687 var vars []OccDef 
688 below := make(map[string]string) 
689 var belowWhat string 
690 
691 // If the current section is optional but contains non-optional 
692 // fields, the complete section may be skipped as long as there 
693 // has not been a non-optional variable. 
694 maySkipSection := false 
695 
696 // In each iteration, one of the following becomes true: 
697 // - new lineno > old lineno 
698 // - new sectindex > old sectindex 
699 // - new sectindex == old sectindex && new varindex > old varindex 
700 // - new nextSection == true && old nextSection == false 
701 for lineno < len(mklines.lines) { 
702 mkline := mklines.mklines[lineno] 
703 line := mklines.lines[lineno] 
704 text := line.Text 
705 
706 if trace.Tracing { 
707 trace.Stepf("[varorder] section %d variable %d vars %v", sectindex, varindex, vars) 
708 } 679 }
709 680
710 if nextSection { 681 firstIrrelevant := -1
711 nextSection = false 682 for i, mkline := range mklines.mklines {
712 sectindex++ 683 switch {
713 if !(sectindex < len(sections)) { 684 case mkline.IsVarassign(), mkline.IsCommentedVarassign():
 685 varcanon := mkline.Varcanon()
 686 if relevantVars[varcanon] {
 687 if firstRelevant == -1 {
 688 firstRelevant = i
 689 }
 690 if firstIrrelevant != -1 {
 691 if trace.Tracing {
 692 trace.Stepf("Skipping varorder because of line %s.",
 693 mklines.mklines[firstIrrelevant].Linenos())
 694 }
 695 return true
 696 }
 697 lastRelevant = i
 698 } else {
 699 if firstIrrelevant == -1 {
 700 firstIrrelevant = i
 701 }
 702 }
 703
 704 case mkline.IsComment(), mkline.IsEmpty():
714 break 705 break
 706
 707 default:
 708 if firstIrrelevant == -1 {
 709 firstIrrelevant = i
 710 }
715 } 711 }
716 vars = sections[sectindex].occ 
717 maySkipSection = sections[sectindex].count == optional 
718 varindex = 0 
719 } 712 }
720 713
721 switch { 714 interesting := mklines.mklines[firstRelevant : lastRelevant+1]
722 case hasPrefix(text, "#"): 
723 lineno++ 
724 715
725 case mkline.IsVarassign(): 716 varcanon := func() string {
726 varcanon := mkline.Varcanon() 717 for len(interesting) != 0 && interesting[0].IsComment() {
 718 interesting = interesting[1:]
 719 }
 720 if len(interesting) != 0 && (interesting[0].IsVarassign() || interesting[0].IsCommentedVarassign()) {
 721 return interesting[0].Varcanon()
 722 }
 723 return ""
 724 }
727 725
728 if belowText, exists := below[varcanon]; exists { 726 for _, section := range sections {
729 if belowText != "" { 727 for _, variable := range section.vars {
730 line.Warnf("%s appears too late. Please put it below %s.", varcanon, belowText) 728 switch variable.repetition {
731 } else { 729 case optional:
732 line.Warnf("%s appears too late. It should be the very first definition.", varcanon) 730 if varcanon() == variable.varname {
 731 interesting = interesting[1:]
 732 }
 733 case once:
 734 if varcanon() == variable.varname {
 735 interesting = interesting[1:]
 736 } else if section.repetition == once {
 737 if variable.varname != "LICENSE" {
 738 if trace.Tracing {
 739 trace.Stepf("Wrong varorder because %s is missing.", variable.varname)
 740 }
 741 return false
 742 }
 743 }
 744 case many:
 745 for varcanon() == variable.varname {
 746 interesting = interesting[1:]
 747 }
733 } 748 }
734 lineno++ 
735 continue 
736 } 749 }
737 750
738 for varindex < len(vars) && varcanon != vars[varindex].varname && (vars[varindex].count != once || maySkipSection) { 751 for len(interesting) != 0 && (interesting[0].IsEmpty() || interesting[0].IsComment()) {
739 if vars[varindex].count == once { 752 interesting = interesting[1:]
740 maySkipSection = false 
741 } 
742 below[vars[varindex].varname] = belowWhat 
743 varindex++ 
744 } 753 }
745 switch { 754 }
746 case !(varindex < len(vars)): 
747 if sections[sectindex].count != optional { 
748 line.Warnf("Empty line expected.") 
749 } 
750 nextSection = true 
751 755
752 case varcanon != vars[varindex].varname: 756 return len(interesting) == 0
753 line.Warnf("Expected %s, but found %s.", vars[varindex].varname, varcanon) 757 }
754 lineno++ 
755 758
756 default: 759 if skip() {
757 if vars[varindex].count != many { 760 return
758 below[vars[varindex].varname] = belowWhat 761 }
759 varindex++ 
760 } 
761 lineno++ 
762 } 
763 belowWhat = varcanon 
764 762
765 default: 763 var canonical []string
766 for varindex < len(vars) { 764 for _, section := range sections {
767 varname := vars[varindex].varname 765 for _, variable := range section.vars {
768 if vars[varindex].count == once && !maySkipSection { 766 found := false
769 if varname != "LICENSE" || pkg.once.FirstTime("LICENSE") { 767 for _, mkline := range mklines.mklines[firstRelevant : lastRelevant+1] {
770 line.Warnf("The canonical position for the required variable %s is here.", varname) 768 if mkline.IsVarassign() || mkline.IsCommentedVarassign() {
771 Explain( 769 if mkline.Varcanon() == variable.varname {
772 "In simple package Makefiles, some common variables should be", 770 canonical = append(canonical, mkline.Varname())
773 "arranged in a specific order.", 771 found = true
774 "", 
775 "See doc/Makefile-example or the pkgsrc guide, section", 
776 "\"Package components\", subsection \"Makefile\" for more information.") 
777 } 772 }
778 } 773 }
779 below[varname] = belowWhat 
780 varindex++ 
781 } 774 }
782 nextSection = true 775 if !found && section.repetition == once && variable.repetition == once {
783 if text == "" { 776 canonical = append(canonical, variable.varname)
784 belowWhat = "the previous empty line" 
785 lineno++ 
786 } 777 }
787 } 778 }
 779 if len(canonical) != 0 && canonical[len(canonical)-1] != "empty line" {
 780 canonical = append(canonical, "empty line")
 781 }
 782 }
 783 if len(canonical) != 0 && canonical[len(canonical)-1] == "empty line" {
 784 canonical = canonical[:len(canonical)-1]
788 } 785 }
 786
 787 mkline := mklines.mklines[firstRelevant]
 788 mkline.Warnf("The canonical order of the variables is %s.", strings.Join(canonical, ", "))
 789 Explain(
 790 "In simple package Makefiles, some common variables should be",
 791 "arranged in a specific order.",
 792 "",
 793 "See doc/Makefile-example or the pkgsrc guide, section",
 794 "\"Package components\", subsection \"Makefile\" for more information.")
789} 795}
790 796
791func (mklines *MkLines) checkForUsedComment(relativeName string) { 797func (mklines *MkLines) checkForUsedComment(relativeName string) {
792 lines := mklines.lines 798 lines := mklines.lines
793 if len(lines) < 3 { 799 if len(lines) < 3 {
794 return 800 return
795 } 801 }
796 802
797 expected := "# used by " + relativeName 803 expected := "# used by " + relativeName
798 for _, line := range lines { 804 for _, line := range lines {
799 if line.Text == expected { 805 if line.Text == expected {
800 return 806 return
801 } 807 }

cvs diff -r1.13 -r1.14 pkgsrc/pkgtools/pkglint/files/Attic/globaldata_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/globaldata_test.go 2018/01/27 18:50:36 1.13
+++ pkgsrc/pkgtools/pkglint/files/Attic/globaldata_test.go 2018/02/19 12:40:38 1.14
@@ -114,27 +114,27 @@ func (s *Suite) Test_GlobalData_deprecat @@ -114,27 +114,27 @@ func (s *Suite) Test_GlobalData_deprecat
114 t.CheckOutputLines( 114 t.CheckOutputLines(
115 "WARN: Makefile:5: Definition of USE_PERL5 is deprecated. Use USE_TOOLS+=perl or USE_TOOLS+=perl:run instead.") 115 "WARN: Makefile:5: Definition of USE_PERL5 is deprecated. Use USE_TOOLS+=perl or USE_TOOLS+=perl:run instead.")
116} 116}
117 117
118// Ensures that pkglint can handle MASTER_SITES definitions with and 118// Ensures that pkglint can handle MASTER_SITES definitions with and
119// without line continuations. 119// without line continuations.
120// 120//
121// See https://mail-index.netbsd.org/tech-pkg/2017/01/18/msg017698.html. 121// See https://mail-index.netbsd.org/tech-pkg/2017/01/18/msg017698.html.
122func (s *Suite) Test_GlobalData_loadDistSites(c *check.C) { 122func (s *Suite) Test_GlobalData_loadDistSites(c *check.C) {
123 t := s.Init(c) 123 t := s.Init(c)
124 124
125 G.globalData.Pkgsrcdir = t.TmpDir() 125 G.globalData.Pkgsrcdir = t.TmpDir()
126 t.CreateFileLines("mk/fetch/sites.mk", 126 t.CreateFileLines("mk/fetch/sites.mk",
127 MkRcsId, 127 MkRcsID,
128 "", 128 "",
129 "MASTER_SITE_A+= https://example.org/distfiles/", 129 "MASTER_SITE_A+= https://example.org/distfiles/",
130 "MASTER_SITE_B+= https://b.example.org/distfiles/ \\", 130 "MASTER_SITE_B+= https://b.example.org/distfiles/ \\",
131 " https://b2.example.org/distfiles/", 131 " https://b2.example.org/distfiles/",
132 "MASTER_SITE_A+= https://a.example.org/distfiles/") 132 "MASTER_SITE_A+= https://a.example.org/distfiles/")
133 133
134 G.globalData.loadDistSites() 134 G.globalData.loadDistSites()
135 135
136 c.Check(G.globalData.MasterSiteURLToVar["https://example.org/distfiles/"], equals, "MASTER_SITE_A") 136 c.Check(G.globalData.MasterSiteURLToVar["https://example.org/distfiles/"], equals, "MASTER_SITE_A")
137 c.Check(G.globalData.MasterSiteURLToVar["https://b.example.org/distfiles/"], equals, "MASTER_SITE_B") 137 c.Check(G.globalData.MasterSiteURLToVar["https://b.example.org/distfiles/"], equals, "MASTER_SITE_B")
138 c.Check(G.globalData.MasterSiteURLToVar["https://b2.example.org/distfiles/"], equals, "MASTER_SITE_B") 138 c.Check(G.globalData.MasterSiteURLToVar["https://b2.example.org/distfiles/"], equals, "MASTER_SITE_B")
139 c.Check(G.globalData.MasterSiteURLToVar["https://a.example.org/distfiles/"], equals, "MASTER_SITE_A") 139 c.Check(G.globalData.MasterSiteURLToVar["https://a.example.org/distfiles/"], equals, "MASTER_SITE_A")
140 c.Check(G.globalData.MasterSiteVarToURL["MASTER_SITE_A"], equals, "https://example.org/distfiles/") 140 c.Check(G.globalData.MasterSiteVarToURL["MASTER_SITE_A"], equals, "https://example.org/distfiles/")

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

--- pkgsrc/pkgtools/pkglint/files/Attic/mkline.go 2018/01/28 23:21:16 1.27
+++ pkgsrc/pkgtools/pkglint/files/Attic/mkline.go 2018/02/19 12:40:38 1.28
@@ -193,34 +193,53 @@ func (mkline *MkLineImpl) IsCond() bool  @@ -193,34 +193,53 @@ func (mkline *MkLineImpl) IsCond() bool
193func (mkline *MkLineImpl) IsInclude() bool { 193func (mkline *MkLineImpl) IsInclude() bool {
194 incl, ok := mkline.data.(mkLineInclude) 194 incl, ok := mkline.data.(mkLineInclude)
195 return ok && !incl.sys 195 return ok && !incl.sys
196} 196}
197func (mkline *MkLineImpl) IsSysinclude() bool { 197func (mkline *MkLineImpl) IsSysinclude() bool {
198 incl, ok := mkline.data.(mkLineInclude) 198 incl, ok := mkline.data.(mkLineInclude)
199 return ok && incl.sys 199 return ok && incl.sys
200} 200}
201func (mkline *MkLineImpl) IsDependency() bool { 201func (mkline *MkLineImpl) IsDependency() bool {
202 _, ok := mkline.data.(mkLineDependency) 202 _, ok := mkline.data.(mkLineDependency)
203 return ok 203 return ok
204} 204}
205 205
206func (mkline *MkLineImpl) Varname() string { return mkline.data.(mkLineAssign).varname } 206// Varname applies to variable assignments and returns the variable name, exactly as given in the Makefile.
 207func (mkline *MkLineImpl) Varname() string { return mkline.data.(mkLineAssign).varname }
 208
 209// Varcanon applies to variable assignments and returns the canonicalized variable name for parameterized variables.
 210// Examples:
 211// HOMEPAGE => HOMEPAGE
 212// SUBST_SED.anything => SUBST_SED.*
207func (mkline *MkLineImpl) Varcanon() string { return mkline.data.(mkLineAssign).varcanon } 213func (mkline *MkLineImpl) Varcanon() string { return mkline.data.(mkLineAssign).varcanon }
 214
 215// Varparam applies to variable assignments and returns the parameter for parameterized variables.
 216// Examples:
 217// HOMEPAGE => ""
 218// SUBST_SED.anything => anything
208func (mkline *MkLineImpl) Varparam() string { return mkline.data.(mkLineAssign).varparam } 219func (mkline *MkLineImpl) Varparam() string { return mkline.data.(mkLineAssign).varparam }
209func (mkline *MkLineImpl) Op() MkOperator { return mkline.data.(mkLineAssign).op } 220
 221// Op applies to variable assignments and returns the assignment operator.
 222func (mkline *MkLineImpl) Op() MkOperator { return mkline.data.(mkLineAssign).op }
210 223
211// For a variable assignment, the text up to and including the assignment operator, e.g. VARNAME+=\t 224// For a variable assignment, the text up to and including the assignment operator, e.g. VARNAME+=\t
212func (mkline *MkLineImpl) ValueAlign() string { return mkline.data.(mkLineAssign).valueAlign } 225func (mkline *MkLineImpl) ValueAlign() string { return mkline.data.(mkLineAssign).valueAlign }
213func (mkline *MkLineImpl) Value() string { return mkline.data.(mkLineAssign).value } 226func (mkline *MkLineImpl) Value() string { return mkline.data.(mkLineAssign).value }
 227
 228// VarassignComment applies to variable assignments and returns the comment.
 229// Example:
 230// VAR=value # comment
 231// In the above line, the comment is "# comment".
 232// The leading "#" is included so that pkglint can distinguish between no comment at all and an empty comment.
214func (mkline *MkLineImpl) VarassignComment() string { return mkline.data.(mkLineAssign).comment } 233func (mkline *MkLineImpl) VarassignComment() string { return mkline.data.(mkLineAssign).comment }
215func (mkline *MkLineImpl) Shellcmd() string { return mkline.data.(mkLineShell).command } 234func (mkline *MkLineImpl) Shellcmd() string { return mkline.data.(mkLineShell).command }
216func (mkline *MkLineImpl) Indent() string { 235func (mkline *MkLineImpl) Indent() string {
217 if mkline.IsCond() { 236 if mkline.IsCond() {
218 return mkline.data.(mkLineConditional).indent 237 return mkline.data.(mkLineConditional).indent
219 } else { 238 } else {
220 return mkline.data.(mkLineInclude).indent 239 return mkline.data.(mkLineInclude).indent
221 } 240 }
222} 241}
223func (mkline *MkLineImpl) Directive() string { return mkline.data.(mkLineConditional).directive } 242func (mkline *MkLineImpl) Directive() string { return mkline.data.(mkLineConditional).directive }
224func (mkline *MkLineImpl) Args() string { return mkline.data.(mkLineConditional).args } 243func (mkline *MkLineImpl) Args() string { return mkline.data.(mkLineConditional).args }
225func (mkline *MkLineImpl) MustExist() bool { return mkline.data.(mkLineInclude).mustexist } 244func (mkline *MkLineImpl) MustExist() bool { return mkline.data.(mkLineInclude).mustexist }
226func (mkline *MkLineImpl) Includefile() string { return mkline.data.(mkLineInclude).includeFile } 245func (mkline *MkLineImpl) Includefile() string { return mkline.data.(mkLineInclude).includeFile }
@@ -402,40 +421,40 @@ func (mkline *MkLineImpl) VariableNeedsQ @@ -402,40 +421,40 @@ func (mkline *MkLineImpl) VariableNeedsQ
402 } 421 }
403 if vartype.kindOfList == lkShell && !vuc.IsWordPart { 422 if vartype.kindOfList == lkShell && !vuc.IsWordPart {
404 return nqNo 423 return nqNo
405 } 424 }
406 } 425 }
407 426
408 // In .for loops, the :Q operator is always misplaced, since 427 // In .for loops, the :Q operator is always misplaced, since
409 // the items are broken up at white-space, not as shell words 428 // the items are broken up at white-space, not as shell words
410 // like in all other parts of make(1). 429 // like in all other parts of make(1).
411 if vuc.quoting == vucQuotFor { 430 if vuc.quoting == vucQuotFor {
412 return nqNo 431 return nqNo
413 } 432 }
414 433
415 // Determine whether the context expects a list of shell words or not. 
416 wantList := vuc.vartype.IsConsideredList() 
417 haveList := vartype.IsConsideredList() 
418 if trace.Tracing { 
419 trace.Stepf("wantList=%v, haveList=%v", wantList, haveList) 
420 } 
421 
422 // A shell word may appear as part of a shell word, for example COMPILER_RPATH_FLAG. 434 // A shell word may appear as part of a shell word, for example COMPILER_RPATH_FLAG.
423 if vuc.IsWordPart && vuc.quoting == vucQuotPlain { 435 if vuc.IsWordPart && vuc.quoting == vucQuotPlain {
424 if vartype.kindOfList == lkNone && vartype.basicType == BtShellWord { 436 if vartype.kindOfList == lkNone && vartype.basicType == BtShellWord {
425 return nqNo 437 return nqNo
426 } 438 }
427 } 439 }
428 440
 441 // Determine whether the context expects a list of shell words or not.
 442 wantList := vuc.vartype.IsConsideredList()
 443 haveList := vartype.IsConsideredList()
 444 if trace.Tracing {
 445 trace.Stepf("wantList=%v, haveList=%v", wantList, haveList)
 446 }
 447
429 // Both of these can be correct, depending on the situation: 448 // Both of these can be correct, depending on the situation:
430 // 1. echo ${PERL5:Q} 449 // 1. echo ${PERL5:Q}
431 // 2. xargs ${PERL5} 450 // 2. xargs ${PERL5}
432 if !vuc.IsWordPart && vuc.quoting == vucQuotPlain { 451 if !vuc.IsWordPart && vuc.quoting == vucQuotPlain {
433 if wantList && haveList { 452 if wantList && haveList {
434 return nqDontKnow 453 return nqDontKnow
435 } 454 }
436 } 455 }
437 456
438 // Assuming the tool definitions don't include very special characters, 457 // Assuming the tool definitions don't include very special characters,
439 // so they can safely be used inside any quotes. 458 // so they can safely be used inside any quotes.
440 if G.globalData.Tools.byVarname[varname] != nil { 459 if G.globalData.Tools.byVarname[varname] != nil {
441 switch vuc.quoting { 460 switch vuc.quoting {
@@ -508,35 +527,35 @@ func (mkline *MkLineImpl) VariableType(v @@ -508,35 +527,35 @@ func (mkline *MkLineImpl) VariableType(v
508 return vartype 527 return vartype
509 } 528 }
510 529
511 if tool := G.globalData.Tools.byVarname[varname]; tool != nil { 530 if tool := G.globalData.Tools.byVarname[varname]; tool != nil {
512 perms := aclpUse 531 perms := aclpUse
513 if trace.Tracing { 532 if trace.Tracing {
514 trace.Stepf("Use of tool %+v", tool) 533 trace.Stepf("Use of tool %+v", tool)
515 } 534 }
516 if tool.UsableAtLoadtime { 535 if tool.UsableAtLoadtime {
517 if G.Pkg == nil || G.Pkg.SeenBsdPrefsMk || G.Pkg.loadTimeTools[tool.Name] { 536 if G.Pkg == nil || G.Pkg.SeenBsdPrefsMk || G.Pkg.loadTimeTools[tool.Name] {
518 perms |= aclpUseLoadtime 537 perms |= aclpUseLoadtime
519 } 538 }
520 } 539 }
521 return &Vartype{lkNone, BtShellCommand, []AclEntry{{"*", perms}}, false} 540 return &Vartype{lkNone, BtShellCommand, []ACLEntry{{"*", perms}}, false}
522 } 541 }
523 542
524 if m, toolvarname := match1(varname, `^TOOLS_(.*)`); m && G.globalData.Tools.byVarname[toolvarname] != nil { 543 if m, toolvarname := match1(varname, `^TOOLS_(.*)`); m && G.globalData.Tools.byVarname[toolvarname] != nil {
525 return &Vartype{lkNone, BtPathname, []AclEntry{{"*", aclpUse}}, false} 544 return &Vartype{lkNone, BtPathname, []ACLEntry{{"*", aclpUse}}, false}
526 } 545 }
527 546
528 allowAll := []AclEntry{{"*", aclpAll}} 547 allowAll := []ACLEntry{{"*", aclpAll}}
529 allowRuntime := []AclEntry{{"*", aclpAllRuntime}} 548 allowRuntime := []ACLEntry{{"*", aclpAllRuntime}}
530 549
531 // Guess the datatype of the variable based on naming conventions. 550 // Guess the datatype of the variable based on naming conventions.
532 varbase := varnameBase(varname) 551 varbase := varnameBase(varname)
533 var gtype *Vartype 552 var gtype *Vartype
534 switch { 553 switch {
535 case hasSuffix(varbase, "DIRS"): 554 case hasSuffix(varbase, "DIRS"):
536 gtype = &Vartype{lkShell, BtPathmask, allowRuntime, true} 555 gtype = &Vartype{lkShell, BtPathmask, allowRuntime, true}
537 case hasSuffix(varbase, "DIR") && !hasSuffix(varbase, "DESTDIR"), hasSuffix(varname, "_HOME"): 556 case hasSuffix(varbase, "DIR") && !hasSuffix(varbase, "DESTDIR"), hasSuffix(varname, "_HOME"):
538 gtype = &Vartype{lkNone, BtPathname, allowRuntime, true} 557 gtype = &Vartype{lkNone, BtPathname, allowRuntime, true}
539 case hasSuffix(varbase, "FILES"): 558 case hasSuffix(varbase, "FILES"):
540 gtype = &Vartype{lkShell, BtPathmask, allowRuntime, true} 559 gtype = &Vartype{lkShell, BtPathmask, allowRuntime, true}
541 case hasSuffix(varbase, "FILE"): 560 case hasSuffix(varbase, "FILE"):
542 gtype = &Vartype{lkNone, BtPathname, allowRuntime, true} 561 gtype = &Vartype{lkNone, BtPathname, allowRuntime, true}
@@ -625,27 +644,26 @@ func (mkline *MkLineImpl) DetermineUsedV @@ -625,27 +644,26 @@ func (mkline *MkLineImpl) DetermineUsedV
625 if min == -1 || (p4 != -1 && p4 < min) { 644 if min == -1 || (p4 != -1 && p4 < min) {
626 min = p4 645 min = p4
627 } 646 }
628 rest = rest[min:] 647 rest = rest[min:]
629 648
630 m := regex.Compile(`(?:\$\{|\$\(|defined\(|empty\()([*+\-.0-9A-Z_a-z]+)[:})]`).FindStringSubmatchIndex(rest) 649 m := regex.Compile(`(?:\$\{|\$\(|defined\(|empty\()([*+\-.0-9A-Z_a-z]+)[:})]`).FindStringSubmatchIndex(rest)
631 if m == nil { 650 if m == nil {
632 return 651 return
633 } 652 }
634 varname := rest[m[2]:m[3]] 653 varname := rest[m[2]:m[3]]
635 varnames = append(varnames, varname) 654 varnames = append(varnames, varname)
636 rest = rest[:m[0]] + rest[m[1]:] 655 rest = rest[:m[0]] + rest[m[1]:]
637 } 656 }
638 return 
639} 657}
640 658
641// VarUseContext defines the context in which a variable is defined 659// VarUseContext defines the context in which a variable is defined
642// or used. Whether that is allowed depends on: 660// or used. Whether that is allowed depends on:
643// 661//
644// * The variable's data type, as defined in vardefs.go. 662// * The variable's data type, as defined in vardefs.go.
645// 663//
646// * When used on the right-hand side of an assigment, the variable can 664// * When used on the right-hand side of an assigment, the variable can
647// represent a list of words, a single word or even only part of a 665// represent a list of words, a single word or even only part of a
648// word. This distinction decides upon the correct use of the :Q 666// word. This distinction decides upon the correct use of the :Q
649// operator. 667// operator.
650// 668//
651// * When used in preprocessing statements like .if or .for, the other 669// * When used in preprocessing statements like .if or .for, the other

cvs diff -r1.30 -r1.31 pkgsrc/pkgtools/pkglint/files/Attic/mkline_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/mkline_test.go 2018/01/28 23:21:16 1.30
+++ pkgsrc/pkgtools/pkglint/files/Attic/mkline_test.go 2018/02/19 12:40:38 1.31
@@ -169,47 +169,47 @@ func (s *Suite) Test_NewMkLine(c *check. @@ -169,47 +169,47 @@ func (s *Suite) Test_NewMkLine(c *check.
169 c.Check(ln[9].Varname(), equals, "VARNAME") 169 c.Check(ln[9].Varname(), equals, "VARNAME")
170 c.Check(ln[9].Varcanon(), equals, "VARNAME") 170 c.Check(ln[9].Varcanon(), equals, "VARNAME")
171 c.Check(ln[9].Varparam(), equals, "") 171 c.Check(ln[9].Varparam(), equals, "")
172 172
173 t.CheckOutputLines( 173 t.CheckOutputLines(
174 "WARN: test.mk:9: Space before colon in dependency line.") 174 "WARN: test.mk:9: Space before colon in dependency line.")
175} 175}
176 176
177func (s *Suite) Test_NewMkLine__autofix_space_after_varname(c *check.C) { 177func (s *Suite) Test_NewMkLine__autofix_space_after_varname(c *check.C) {
178 t := s.Init(c) 178 t := s.Init(c)
179 179
180 t.SetupCommandLine("-Wspace") 180 t.SetupCommandLine("-Wspace")
181 fname := t.CreateFileLines("Makefile", 181 fname := t.CreateFileLines("Makefile",
182 MkRcsId, 182 MkRcsID,
183 "VARNAME +=\t${VARNAME}", 183 "VARNAME +=\t${VARNAME}",
184 "VARNAME+ =\t${VARNAME+}", 184 "VARNAME+ =\t${VARNAME+}",
185 "VARNAME+ +=\t${VARNAME+}", 185 "VARNAME+ +=\t${VARNAME+}",
186 "pkgbase := pkglint") 186 "pkgbase := pkglint")
187 187
188 CheckfileMk(fname) 188 CheckfileMk(fname)
189 189
190 t.CheckOutputLines( 190 t.CheckOutputLines(
191 "WARN: ~/Makefile:2: Unnecessary space after variable name \"VARNAME\".", 191 "WARN: ~/Makefile:2: Unnecessary space after variable name \"VARNAME\".",
192 "WARN: ~/Makefile:4: Unnecessary space after variable name \"VARNAME+\".") 192 "WARN: ~/Makefile:4: Unnecessary space after variable name \"VARNAME+\".")
193 193
194 t.SetupCommandLine("-Wspace", "--autofix") 194 t.SetupCommandLine("-Wspace", "--autofix")
195 195
196 CheckfileMk(fname) 196 CheckfileMk(fname)
197 197
198 t.CheckOutputLines( 198 t.CheckOutputLines(
199 "AUTOFIX: ~/Makefile:2: Replacing \"VARNAME +=\" with \"VARNAME+=\".", 199 "AUTOFIX: ~/Makefile:2: Replacing \"VARNAME +=\" with \"VARNAME+=\".",
200 "AUTOFIX: ~/Makefile:4: Replacing \"VARNAME+ +=\" with \"VARNAME++=\".") 200 "AUTOFIX: ~/Makefile:4: Replacing \"VARNAME+ +=\" with \"VARNAME++=\".")
201 t.CheckFileLines("Makefile", 201 t.CheckFileLines("Makefile",
202 MkRcsId+"", 202 MkRcsID+"",
203 "VARNAME+=\t${VARNAME}", 203 "VARNAME+=\t${VARNAME}",
204 "VARNAME+ =\t${VARNAME+}", 204 "VARNAME+ =\t${VARNAME+}",
205 "VARNAME++=\t${VARNAME+}", 205 "VARNAME++=\t${VARNAME+}",
206 "pkgbase := pkglint") 206 "pkgbase := pkglint")
207} 207}
208 208
209func (s *Suite) Test_MkLine_VariableType_varparam(c *check.C) { 209func (s *Suite) Test_MkLine_VariableType_varparam(c *check.C) {
210 t := s.Init(c) 210 t := s.Init(c)
211 211
212 mkline := t.NewMkLine("fname", 1, "# dummy") 212 mkline := t.NewMkLine("fname", 1, "# dummy")
213 G.globalData.InitVartypes() 213 G.globalData.InitVartypes()
214 214
215 t1 := mkline.VariableType("FONT_DIRS") 215 t1 := mkline.VariableType("FONT_DIRS")
@@ -268,27 +268,27 @@ func (s *Suite) Test_NewMkLine_leading_s @@ -268,27 +268,27 @@ func (s *Suite) Test_NewMkLine_leading_s
268 _ = t.NewMkLine("rubyversion.mk", 427, " _RUBYVER=\t2.15") 268 _ = t.NewMkLine("rubyversion.mk", 427, " _RUBYVER=\t2.15")
269 269
270 t.CheckOutputLines( 270 t.CheckOutputLines(
271 "WARN: rubyversion.mk:427: Makefile lines should not start with space characters.") 271 "WARN: rubyversion.mk:427: Makefile lines should not start with space characters.")
272} 272}
273 273
274func (s *Suite) Test_MkLines_Check__extra(c *check.C) { 274func (s *Suite) Test_MkLines_Check__extra(c *check.C) {
275 t := s.Init(c) 275 t := s.Init(c)
276 276
277 t.SetupCommandLine("-Wextra") 277 t.SetupCommandLine("-Wextra")
278 G.globalData.InitVartypes() 278 G.globalData.InitVartypes()
279 G.Pkg = NewPackage("category/pkgbase") 279 G.Pkg = NewPackage("category/pkgbase")
280 G.Mk = t.NewMkLines("options.mk", 280 G.Mk = t.NewMkLines("options.mk",
281 MkRcsId, 281 MkRcsID,
282 ".for word in ${PKG_FAIL_REASON}", 282 ".for word in ${PKG_FAIL_REASON}",
283 "PYTHON_VERSIONS_ACCEPTED=\t27 35 30", 283 "PYTHON_VERSIONS_ACCEPTED=\t27 35 30",
284 "CONFIGURE_ARGS+=\t--sharedir=${PREFIX}/share/kde", 284 "CONFIGURE_ARGS+=\t--sharedir=${PREFIX}/share/kde",
285 "COMMENT=\t# defined", 285 "COMMENT=\t# defined",
286 ".endfor", 286 ".endfor",
287 "GAMES_USER?=pkggames", 287 "GAMES_USER?=pkggames",
288 "PLIST_SUBST+= CONDITIONAL=${CONDITIONAL}", 288 "PLIST_SUBST+= CONDITIONAL=${CONDITIONAL}",
289 "CONDITIONAL=\"@comment\"", 289 "CONDITIONAL=\"@comment\"",
290 "BUILD_DIRS=\t${WRKSRC}/../build") 290 "BUILD_DIRS=\t${WRKSRC}/../build")
291 291
292 G.Mk.Check() 292 G.Mk.Check()
293 293
294 t.CheckOutputLines( 294 t.CheckOutputLines(
@@ -369,187 +369,187 @@ func (s *Suite) Test_MkLine_variableNeed @@ -369,187 +369,187 @@ func (s *Suite) Test_MkLine_variableNeed
369 t.CheckOutputLines( 369 t.CheckOutputLines(
370 "WARN: Makefile:3: Please use ${INSTALL:Q} instead of ${INSTALL} and make sure the variable appears outside of any quoting characters.") 370 "WARN: Makefile:3: Please use ${INSTALL:Q} instead of ${INSTALL} and make sure the variable appears outside of any quoting characters.")
371} 371}
372 372
373func (s *Suite) Test_MkLine_variableNeedsQuoting__command_in_command(c *check.C) { 373func (s *Suite) Test_MkLine_variableNeedsQuoting__command_in_command(c *check.C) {
374 t := s.Init(c) 374 t := s.Init(c)
375 375
376 t.SetupCommandLine("-Wall") 376 t.SetupCommandLine("-Wall")
377 G.globalData.InitVartypes() 377 G.globalData.InitVartypes()
378 t.SetupTool(&Tool{Name: "find", Varname: "FIND", Predefined: true}) 378 t.SetupTool(&Tool{Name: "find", Varname: "FIND", Predefined: true})
379 t.SetupTool(&Tool{Name: "sort", Varname: "SORT", Predefined: true}) 379 t.SetupTool(&Tool{Name: "sort", Varname: "SORT", Predefined: true})
380 G.Pkg = NewPackage("category/pkgbase") 380 G.Pkg = NewPackage("category/pkgbase")
381 G.Mk = t.NewMkLines("Makefile", 381 G.Mk = t.NewMkLines("Makefile",
382 MkRcsId, 382 MkRcsID,
383 "GENERATE_PLIST= cd ${DESTDIR}${PREFIX}; ${FIND} * \\( -type f -or -type l \\) | ${SORT};") 383 "GENERATE_PLIST= cd ${DESTDIR}${PREFIX}; ${FIND} * \\( -type f -or -type l \\) | ${SORT};")
384 384
385 G.Mk.DetermineDefinedVariables() 385 G.Mk.DetermineDefinedVariables()
386 MkLineChecker{G.Mk.mklines[1]}.Check() 386 MkLineChecker{G.Mk.mklines[1]}.Check()
387 387
388 t.CheckOutputLines( 388 t.CheckOutputLines(
389 "WARN: Makefile:2: The exitcode of \"${FIND}\" at the left of the | operator is ignored.") 389 "WARN: Makefile:2: The exitcode of \"${FIND}\" at the left of the | operator is ignored.")
390} 390}
391 391
392func (s *Suite) Test_MkLine_variableNeedsQuoting__word_as_part_of_word(c *check.C) { 392func (s *Suite) Test_MkLine_variableNeedsQuoting__word_as_part_of_word(c *check.C) {
393 t := s.Init(c) 393 t := s.Init(c)
394 394
395 t.SetupCommandLine("-Wall") 395 t.SetupCommandLine("-Wall")
396 G.globalData.InitVartypes() 396 G.globalData.InitVartypes()
397 G.Mk = t.NewMkLines("Makefile", 397 G.Mk = t.NewMkLines("Makefile",
398 MkRcsId, 398 MkRcsID,
399 "EGDIR=\t${EGDIR}/${MACHINE_GNU_PLATFORM}") 399 "EGDIR=\t${EGDIR}/${MACHINE_GNU_PLATFORM}")
400 400
401 MkLineChecker{G.Mk.mklines[1]}.Check() 401 MkLineChecker{G.Mk.mklines[1]}.Check()
402 402
403 t.CheckOutputEmpty() 403 t.CheckOutputEmpty()
404} 404}
405 405
406// As an argument to ${ECHO}, the :Q modifier should be used, but pkglint 406// As an argument to ${ECHO}, the :Q modifier should be used, but pkglint
407// currently does not know all shell commands and how they handle their 407// currently does not know all shell commands and how they handle their
408// arguments. As an argument to xargs(1), the :Q modifier would be misplaced, 408// arguments. As an argument to xargs(1), the :Q modifier would be misplaced,
409// therefore no warning is issued in both these cases. 409// therefore no warning is issued in both these cases.
410// 410//
411// Based on graphics/circos/Makefile. 411// Based on graphics/circos/Makefile.
412func (s *Suite) Test_MkLine_variableNeedsQuoting__command_as_command_argument(c *check.C) { 412func (s *Suite) Test_MkLine_variableNeedsQuoting__command_as_command_argument(c *check.C) {
413 t := s.Init(c) 413 t := s.Init(c)
414 414
415 t.SetupCommandLine("-Wall") 415 t.SetupCommandLine("-Wall")
416 t.SetupTool(&Tool{Name: "perl", Varname: "PERL5", Predefined: true}) 416 t.SetupTool(&Tool{Name: "perl", Varname: "PERL5", Predefined: true})
417 t.SetupTool(&Tool{Name: "bash", Varname: "BASH", Predefined: true}) 417 t.SetupTool(&Tool{Name: "bash", Varname: "BASH", Predefined: true})
418 G.globalData.InitVartypes() 418 G.globalData.InitVartypes()
419 G.Mk = t.NewMkLines("Makefile", 419 G.Mk = t.NewMkLines("Makefile",
420 MkRcsId, 420 MkRcsID,
421 "\t${RUN} cd ${WRKSRC} && ( ${ECHO} ${PERL5:Q} ; ${ECHO} ) | ${BASH} ./install", 421 "\t${RUN} cd ${WRKSRC} && ( ${ECHO} ${PERL5:Q} ; ${ECHO} ) | ${BASH} ./install",
422 "\t${RUN} cd ${WRKSRC} && ( ${ECHO} ${PERL5} ; ${ECHO} ) | ${BASH} ./install") 422 "\t${RUN} cd ${WRKSRC} && ( ${ECHO} ${PERL5} ; ${ECHO} ) | ${BASH} ./install")
423 423
424 MkLineChecker{G.Mk.mklines[1]}.Check() 424 MkLineChecker{G.Mk.mklines[1]}.Check()
425 MkLineChecker{G.Mk.mklines[2]}.Check() 425 MkLineChecker{G.Mk.mklines[2]}.Check()
426 426
427 t.CheckOutputLines( 427 t.CheckOutputLines(
428 "WARN: Makefile:2: The exitcode of the command at the left of the | operator is ignored.", 428 "WARN: Makefile:2: The exitcode of the command at the left of the | operator is ignored.",
429 "WARN: Makefile:3: The exitcode of the command at the left of the | operator is ignored.") 429 "WARN: Makefile:3: The exitcode of the command at the left of the | operator is ignored.")
430} 430}
431 431
432// Based on mail/mailfront/Makefile. 432// Based on mail/mailfront/Makefile.
433func (s *Suite) Test_MkLine_variableNeedsQuoting__URL_as_part_of_word_in_list(c *check.C) { 433func (s *Suite) Test_MkLine_variableNeedsQuoting__URL_as_part_of_word_in_list(c *check.C) {
434 t := s.Init(c) 434 t := s.Init(c)
435 435
436 t.SetupCommandLine("-Wall") 436 t.SetupCommandLine("-Wall")
437 G.globalData.InitVartypes() 437 G.globalData.InitVartypes()
438 G.Mk = t.NewMkLines("Makefile", 438 G.Mk = t.NewMkLines("Makefile",
439 MkRcsId, 439 MkRcsID,
440 "MASTER_SITES=${HOMEPAGE}archive/") 440 "MASTER_SITES=${HOMEPAGE}archive/")
441 441
442 MkLineChecker{G.Mk.mklines[1]}.Check() 442 MkLineChecker{G.Mk.mklines[1]}.Check()
443 443
444 t.CheckOutputEmpty() // Don't suggest to use ${HOMEPAGE:Q}. 444 t.CheckOutputEmpty() // Don't suggest to use ${HOMEPAGE:Q}.
445} 445}
446 446
447// Pkglint currently does not parse $$(subshell) commands very well. As 447// Pkglint currently does not parse $$(subshell) commands very well. As
448// a side effect, it sometimes issues wrong warnings about the :Q 448// a side effect, it sometimes issues wrong warnings about the :Q
449// modifier. 449// modifier.
450// 450//
451// Based on www/firefox31/xpi.mk. 451// Based on www/firefox31/xpi.mk.
452func (s *Suite) Test_MkLine_variableNeedsQuoting__command_in_subshell(c *check.C) { 452func (s *Suite) Test_MkLine_variableNeedsQuoting__command_in_subshell(c *check.C) {
453 t := s.Init(c) 453 t := s.Init(c)
454 454
455 t.SetupCommandLine("-Wall") 455 t.SetupCommandLine("-Wall")
456 G.globalData.InitVartypes() 456 G.globalData.InitVartypes()
457 t.SetupTool(&Tool{Name: "awk", Varname: "AWK", Predefined: true}) 457 t.SetupTool(&Tool{Name: "awk", Varname: "AWK", Predefined: true})
458 t.SetupTool(&Tool{Name: "echo", Varname: "ECHO", Predefined: true}) 458 t.SetupTool(&Tool{Name: "echo", Varname: "ECHO", Predefined: true})
459 G.Mk = t.NewMkLines("xpi.mk", 459 G.Mk = t.NewMkLines("xpi.mk",
460 MkRcsId, 460 MkRcsID,
461 "\t id=$$(${AWK} '{print}' < ${WRKSRC}/idfile) && echo \"$$id\"", 461 "\t id=$$(${AWK} '{print}' < ${WRKSRC}/idfile) && echo \"$$id\"",
462 "\t id=`${AWK} '{print}' < ${WRKSRC}/idfile` && echo \"$$id\"") 462 "\t id=`${AWK} '{print}' < ${WRKSRC}/idfile` && echo \"$$id\"")
463 463
464 MkLineChecker{G.Mk.mklines[1]}.Check() 464 MkLineChecker{G.Mk.mklines[1]}.Check()
465 MkLineChecker{G.Mk.mklines[2]}.Check() 465 MkLineChecker{G.Mk.mklines[2]}.Check()
466 466
467 // Don't suggest to use ${AWK:Q}. 467 // Don't suggest to use ${AWK:Q}.
468 t.CheckOutputLines( 468 t.CheckOutputLines(
469 "WARN: xpi.mk:2: Invoking subshells via $(...) is not portable enough.") 469 "WARN: xpi.mk:2: Invoking subshells via $(...) is not portable enough.")
470} 470}
471 471
472// LDFLAGS (and even more so CPPFLAGS and CFLAGS) may contain special 472// LDFLAGS (and even more so CPPFLAGS and CFLAGS) may contain special
473// shell characters like quotes or backslashes. Therefore, quoting them 473// shell characters like quotes or backslashes. Therefore, quoting them
474// correctly is more tricky than with other variables. 474// correctly is more tricky than with other variables.
475func (s *Suite) Test_MkLine_variableNeedsQuoting__LDFLAGS_in_single_quotes(c *check.C) { 475func (s *Suite) Test_MkLine_variableNeedsQuoting__LDFLAGS_in_single_quotes(c *check.C) {
476 t := s.Init(c) 476 t := s.Init(c)
477 477
478 t.SetupCommandLine("-Wall") 478 t.SetupCommandLine("-Wall")
479 G.globalData.InitVartypes() 479 G.globalData.InitVartypes()
480 G.Mk = t.NewMkLines("x11/mlterm/Makefile", 480 G.Mk = t.NewMkLines("x11/mlterm/Makefile",
481 MkRcsId, 481 MkRcsID,
482 "SUBST_SED.link=-e 's|(LIBTOOL_LINK).*(LIBS)|& ${LDFLAGS:M*:Q}|g'", 482 "SUBST_SED.link=-e 's|(LIBTOOL_LINK).*(LIBS)|& ${LDFLAGS:M*:Q}|g'",
483 "SUBST_SED.link=-e 's|(LIBTOOL_LINK).*(LIBS)|& '${LDFLAGS:M*:Q}'|g'") 483 "SUBST_SED.link=-e 's|(LIBTOOL_LINK).*(LIBS)|& '${LDFLAGS:M*:Q}'|g'")
484 484
485 MkLineChecker{G.Mk.mklines[1]}.Check() 485 MkLineChecker{G.Mk.mklines[1]}.Check()
486 MkLineChecker{G.Mk.mklines[2]}.Check() 486 MkLineChecker{G.Mk.mklines[2]}.Check()
487 487
488 t.CheckOutputLines( 488 t.CheckOutputLines(
489 "WARN: x11/mlterm/Makefile:2: Please move ${LDFLAGS:M*:Q} outside of any quoting characters.") 489 "WARN: x11/mlterm/Makefile:2: Please move ${LDFLAGS:M*:Q} outside of any quoting characters.")
490} 490}
491 491
492// No quoting is necessary here. 492// No quoting is necessary here.
493// PKG_OPTIONS are declared as "lkShell" although they are processed 493// PKG_OPTIONS are declared as "lkShell" although they are processed
494// using make's .for loop, which splits them at whitespace and usually 494// using make's .for loop, which splits them at whitespace and usually
495// requires the variable to be declared as "lkSpace". 495// requires the variable to be declared as "lkSpace".
496// In this case it doesn't matter though since each option is an identifier, 496// In this case it doesn't matter though since each option is an identifier,
497// and these do not pose any quoting or escaping problems. 497// and these do not pose any quoting or escaping problems.
498func (s *Suite) Test_MkLine_variableNeedsQuoting__package_options(c *check.C) { 498func (s *Suite) Test_MkLine_variableNeedsQuoting__package_options(c *check.C) {
499 t := s.Init(c) 499 t := s.Init(c)
500 500
501 t.SetupCommandLine("-Wall") 501 t.SetupCommandLine("-Wall")
502 G.globalData.InitVartypes() 502 G.globalData.InitVartypes()
503 G.Mk = t.NewMkLines("Makefile", 503 G.Mk = t.NewMkLines("Makefile",
504 MkRcsId, 504 MkRcsID,
505 "PKG_SUGGESTED_OPTIONS+=\t${PKG_DEFAULT_OPTIONS:Mcdecimal} ${PKG_OPTIONS.py-trytond:Mcdecimal}") 505 "PKG_SUGGESTED_OPTIONS+=\t${PKG_DEFAULT_OPTIONS:Mcdecimal} ${PKG_OPTIONS.py-trytond:Mcdecimal}")
506 506
507 MkLineChecker{G.Mk.mklines[1]}.Check() 507 MkLineChecker{G.Mk.mklines[1]}.Check()
508 508
509 t.CheckOutputEmpty() 509 t.CheckOutputEmpty()
510} 510}
511 511
512func (s *Suite) Test_MkLines_Check__MASTER_SITE_in_HOMEPAGE(c *check.C) { 512func (s *Suite) Test_MkLines_Check__MASTER_SITE_in_HOMEPAGE(c *check.C) {
513 t := s.Init(c) 513 t := s.Init(c)
514 514
515 t.SetupCommandLine("-Wall") 515 t.SetupCommandLine("-Wall")
516 t.SetupMasterSite("MASTER_SITE_GITHUB", "https://github.com/") 516 t.SetupMasterSite("MASTER_SITE_GITHUB", "https://github.com/")
517 G.globalData.InitVartypes() 517 G.globalData.InitVartypes()
518 G.Mk = t.NewMkLines("devel/catch/Makefile", 518 G.Mk = t.NewMkLines("devel/catch/Makefile",
519 MkRcsId, 519 MkRcsID,
520 "HOMEPAGE=\t${MASTER_SITE_GITHUB:=philsquared/Catch/}", 520 "HOMEPAGE=\t${MASTER_SITE_GITHUB:=philsquared/Catch/}",
521 "HOMEPAGE=\t${MASTER_SITE_GITHUB}", 521 "HOMEPAGE=\t${MASTER_SITE_GITHUB}",
522 "HOMEPAGE=\t${MASTER_SITES}", 522 "HOMEPAGE=\t${MASTER_SITES}",
523 "HOMEPAGE=\t${MASTER_SITES}${GITHUB_PROJECT}") 523 "HOMEPAGE=\t${MASTER_SITES}${GITHUB_PROJECT}")
524 524
525 G.Mk.Check() 525 G.Mk.Check()
526 526
527 t.CheckOutputLines( 527 t.CheckOutputLines(
528 "WARN: devel/catch/Makefile:2: HOMEPAGE should not be defined in terms of MASTER_SITEs. Use https://github.com/philsquared/Catch/ directly.", 528 "WARN: devel/catch/Makefile:2: HOMEPAGE should not be defined in terms of MASTER_SITEs. Use https://github.com/philsquared/Catch/ directly.",
529 "WARN: devel/catch/Makefile:3: HOMEPAGE should not be defined in terms of MASTER_SITEs. Use https://github.com/ directly.", 529 "WARN: devel/catch/Makefile:3: HOMEPAGE should not be defined in terms of MASTER_SITEs. Use https://github.com/ directly.",
530 "WARN: devel/catch/Makefile:4: HOMEPAGE should not be defined in terms of MASTER_SITEs.", 530 "WARN: devel/catch/Makefile:4: HOMEPAGE should not be defined in terms of MASTER_SITEs.",
531 "WARN: devel/catch/Makefile:5: HOMEPAGE should not be defined in terms of MASTER_SITEs.") 531 "WARN: devel/catch/Makefile:5: HOMEPAGE should not be defined in terms of MASTER_SITEs.")
532} 532}
533 533
534func (s *Suite) Test_MkLine_variableNeedsQuoting__tool_in_quotes_in_subshell_in_shellwords(c *check.C) { 534func (s *Suite) Test_MkLine_variableNeedsQuoting__tool_in_quotes_in_subshell_in_shellwords(c *check.C) {
535 t := s.Init(c) 535 t := s.Init(c)
536 536
537 t.SetupCommandLine("-Wall") 537 t.SetupCommandLine("-Wall")
538 t.SetupTool(&Tool{Name: "echo", Varname: "ECHO", Predefined: true}) 538 t.SetupTool(&Tool{Name: "echo", Varname: "ECHO", Predefined: true})
539 t.SetupTool(&Tool{Name: "sh", Varname: "SH", Predefined: true}) 539 t.SetupTool(&Tool{Name: "sh", Varname: "SH", Predefined: true})
540 G.globalData.InitVartypes() 540 G.globalData.InitVartypes()
541 G.Mk = t.NewMkLines("x11/labltk/Makefile", 541 G.Mk = t.NewMkLines("x11/labltk/Makefile",
542 MkRcsId, 542 MkRcsID,
543 "CONFIGURE_ARGS+=\t-tklibs \"`${SH} -c '${ECHO} $$TK_LD_FLAGS'`\"") 543 "CONFIGURE_ARGS+=\t-tklibs \"`${SH} -c '${ECHO} $$TK_LD_FLAGS'`\"")
544 544
545 MkLineChecker{G.Mk.mklines[1]}.Check() 545 MkLineChecker{G.Mk.mklines[1]}.Check()
546 546
547 // Don't suggest ${ECHO:Q} here. 547 // Don't suggest ${ECHO:Q} here.
548 t.CheckOutputEmpty() 548 t.CheckOutputEmpty()
549} 549}
550 550
551func (s *Suite) Test_MkLine_variableNeedsQuoting__LDADD_in_BUILDLINK_TRANSFORM(c *check.C) { 551func (s *Suite) Test_MkLine_variableNeedsQuoting__LDADD_in_BUILDLINK_TRANSFORM(c *check.C) {
552 t := s.Init(c) 552 t := s.Init(c)
553 553
554 t.SetupCommandLine("-Wall") 554 t.SetupCommandLine("-Wall")
555 G.globalData.InitVartypes() 555 G.globalData.InitVartypes()
@@ -573,200 +573,225 @@ func (s *Suite) Test_MkLine_variableNeed @@ -573,200 +573,225 @@ func (s *Suite) Test_MkLine_variableNeed
573 573
574 MkLineChecker{G.Mk.mklines[0]}.Check() 574 MkLineChecker{G.Mk.mklines[0]}.Check()
575 575
576 // Don't suggest ${REPLACE_PERL:Q}. 576 // Don't suggest ${REPLACE_PERL:Q}.
577 t.CheckOutputEmpty() 577 t.CheckOutputEmpty()
578} 578}
579 579
580func (s *Suite) Test_MkLine_variableNeedsQuoting__guessed_list_variable_in_quotes(c *check.C) { 580func (s *Suite) Test_MkLine_variableNeedsQuoting__guessed_list_variable_in_quotes(c *check.C) {
581 t := s.Init(c) 581 t := s.Init(c)
582 582
583 t.SetupCommandLine("-Wall") 583 t.SetupCommandLine("-Wall")
584 G.globalData.InitVartypes() 584 G.globalData.InitVartypes()
585 G.Mk = t.NewMkLines("audio/jack-rack/Makefile", 585 G.Mk = t.NewMkLines("audio/jack-rack/Makefile",
586 MkRcsId, 586 MkRcsID,
587 "LADSPA_PLUGIN_PATH?=\t${PREFIX}/lib/ladspa", 587 "LADSPA_PLUGIN_PATH?=\t${PREFIX}/lib/ladspa",
588 "CPPFLAGS+=\t\t-DLADSPA_PATH=\"\\\"${LADSPA_PLUGIN_PATH}\\\"\"") 588 "CPPFLAGS+=\t\t-DLADSPA_PATH=\"\\\"${LADSPA_PLUGIN_PATH}\\\"\"")
589 589
590 G.Mk.Check() 590 G.Mk.Check()
591 591
592 t.CheckOutputLines( 592 t.CheckOutputLines(
593 "WARN: audio/jack-rack/Makefile:3: The list variable LADSPA_PLUGIN_PATH should not be embedded in a word.") 593 "WARN: audio/jack-rack/Makefile:3: The variable LADSPA_PLUGIN_PATH should be quoted as part of a shell word.")
594} 594}
595 595
596func (s *Suite) Test_MkLine_variableNeedsQuoting__list_in_list(c *check.C) { 596func (s *Suite) Test_MkLine_variableNeedsQuoting__list_in_list(c *check.C) {
597 t := s.Init(c) 597 t := s.Init(c)
598 598
599 t.SetupCommandLine("-Wall") 599 t.SetupCommandLine("-Wall")
600 G.globalData.InitVartypes() 600 G.globalData.InitVartypes()
601 G.Mk = t.NewMkLines("x11/eterm/Makefile", 601 G.Mk = t.NewMkLines("x11/eterm/Makefile",
602 MkRcsId, 602 MkRcsID,
603 "DISTFILES=\t${DEFAULT_DISTFILES} ${PIXMAP_FILES}") 603 "DISTFILES=\t${DEFAULT_DISTFILES} ${PIXMAP_FILES}")
604 604
605 G.Mk.Check() 605 G.Mk.Check()
606 606
607 t.CheckOutputEmpty() // Don't warn about missing :Q modifiers. 607 t.CheckOutputEmpty() // Don't warn about missing :Q modifiers.
608} 608}
609 609
610func (s *Suite) Test_MkLine_variableNeedsQuoting__PKGNAME_and_URL_list_in_URL_list(c *check.C) { 610func (s *Suite) Test_MkLine_variableNeedsQuoting__PKGNAME_and_URL_list_in_URL_list(c *check.C) {
611 t := s.Init(c) 611 t := s.Init(c)
612 612
613 t.SetupCommandLine("-Wall") 613 t.SetupCommandLine("-Wall")
614 t.SetupMasterSite("MASTER_SITE_GNOME", "http://ftp.gnome.org/") 614 t.SetupMasterSite("MASTER_SITE_GNOME", "http://ftp.gnome.org/")
615 G.globalData.InitVartypes() 615 G.globalData.InitVartypes()
616 G.Mk = t.NewMkLines("x11/gtk3/Makefile", 616 G.Mk = t.NewMkLines("x11/gtk3/Makefile",
617 MkRcsId, 617 MkRcsID,
618 "MASTER_SITES=\tftp://ftp.gtk.org/${PKGNAME}/ ${MASTER_SITE_GNOME:=subdir/}") 618 "MASTER_SITES=\tftp://ftp.gtk.org/${PKGNAME}/ ${MASTER_SITE_GNOME:=subdir/}")
619 619
620 MkLineChecker{G.Mk.mklines[1]}.checkVarassignVaruse() 620 MkLineChecker{G.Mk.mklines[1]}.checkVarassignVaruse()
621 621
622 t.CheckOutputEmpty() // Don't warn about missing :Q modifiers. 622 t.CheckOutputEmpty() // Don't warn about missing :Q modifiers.
623} 623}
624 624
625func (s *Suite) Test_MkLine_variableNeedsQuoting__tool_in_CONFIGURE_ENV(c *check.C) { 625func (s *Suite) Test_MkLine_variableNeedsQuoting__tool_in_CONFIGURE_ENV(c *check.C) {
626 t := s.Init(c) 626 t := s.Init(c)
627 627
628 t.SetupCommandLine("-Wall") 628 t.SetupCommandLine("-Wall")
629 G.globalData.InitVartypes() 629 G.globalData.InitVartypes()
630 G.globalData.Tools = NewToolRegistry() 630 G.globalData.Tools = NewToolRegistry()
631 G.globalData.Tools.RegisterVarname("tar", "TAR") 631 G.globalData.Tools.RegisterVarname("tar", "TAR")
632 mklines := t.NewMkLines("Makefile", 632 mklines := t.NewMkLines("Makefile",
633 MkRcsId, 633 MkRcsID,
634 "", 634 "",
635 "CONFIGURE_ENV+=\tSYS_TAR_COMMAND_PATH=${TOOLS_TAR:Q}") 635 "CONFIGURE_ENV+=\tSYS_TAR_COMMAND_PATH=${TOOLS_TAR:Q}")
636 636
637 MkLineChecker{mklines.mklines[2]}.checkVarassignVaruse() 637 MkLineChecker{mklines.mklines[2]}.checkVarassignVaruse()
638 638
639 // The TOOLS_* variables only contain the path to the tool, 639 // The TOOLS_* variables only contain the path to the tool,
640 // without any additional arguments that might be necessary 640 // without any additional arguments that might be necessary
641 // for invoking the tool properly (e.g. touch -t). 641 // for invoking the tool properly (e.g. touch -t).
642 // Therefore, no quoting is necessary. 642 // Therefore, no quoting is necessary.
643 t.CheckOutputLines( 643 t.CheckOutputLines(
644 "NOTE: Makefile:3: The :Q operator isn't necessary for ${TOOLS_TAR} here.") 644 "NOTE: Makefile:3: The :Q operator isn't necessary for ${TOOLS_TAR} here.")
645} 645}
646 646
 647func (s *Suite) Test_MkLine_variableNeedsQuoting__backticks(c *check.C) {
 648 t := s.Init(c)
 649
 650 t.SetupCommandLine("-Wall")
 651 G.globalData.InitVartypes()
 652 G.globalData.Tools = NewToolRegistry()
 653 G.globalData.Tools.RegisterVarname("cat", "CAT")
 654 mklines := t.NewMkLines("Makefile",
 655 MkRcsID,
 656 "",
 657 "COMPILE_CMD=\tcc `${CAT} ${WRKDIR}/compileflags`",
 658 "COMMENT_CMD=\techo `echo ${COMMENT}`")
 659
 660 MkLineChecker{mklines.mklines[2]}.checkVarassignVaruse()
 661 MkLineChecker{mklines.mklines[3]}.checkVarassignVaruse()
 662
 663 // Both CAT and WRKDIR are safe from quoting, therefore no warnings.
 664 // But COMMENT may contain arbitrary characters and therefore must
 665 // only appear completely unquoted. There is no practical way of
 666 // using it inside backticks, and luckily there is no need for it.
 667 t.CheckOutputLines(
 668 "WARN: Makefile:4: COMMENT may not be used in any file; it is a write-only variable.",
 669 "WARN: Makefile:4: The variable COMMENT should be quoted as part of a shell word.")
 670}
 671
647// For some well-known directory variables like WRKDIR, PREFIX, LOCALBASE, 672// For some well-known directory variables like WRKDIR, PREFIX, LOCALBASE,
648// the :Q modifier can be safely removed since pkgsrc will never support 673// the :Q modifier can be safely removed since pkgsrc will never support
649// having special characters in these directory names. 674// having special characters in these directory names.
650// For guessed variable types be cautious and don't autofix them. 675// For guessed variable types be cautious and don't autofix them.
651func (s *Suite) Test_MkLine_variableNeedsQuoting__only_remove_known(c *check.C) { 676func (s *Suite) Test_MkLine_variableNeedsQuoting__only_remove_known(c *check.C) {
652 t := s.Init(c) 677 t := s.Init(c)
653 678
654 t.SetupCommandLine("-Wall", "--autofix") 679 t.SetupCommandLine("-Wall", "--autofix")
655 G.globalData.InitVartypes() 680 G.globalData.InitVartypes()
656 681
657 lines := t.SetupFileLinesContinuation("Makefile", 682 lines := t.SetupFileLinesContinuation("Makefile",
658 MkRcsId, 683 MkRcsID,
659 "", 684 "",
660 "demo: .PHONY", 685 "demo: .PHONY",
661 "\t${ECHO} ${WRKSRC:Q}", 686 "\t${ECHO} ${WRKSRC:Q}",
662 "\t${ECHO} ${FOODIR:Q}") 687 "\t${ECHO} ${FOODIR:Q}")
663 mklines := NewMkLines(lines) 688 mklines := NewMkLines(lines)
664 689
665 mklines.Check() 690 mklines.Check()
666 691
667 t.CheckOutputLines( 692 t.CheckOutputLines(
668 "AUTOFIX: ~/Makefile:4: Replacing \"${WRKSRC:Q}\" with \"${WRKSRC}\".") 693 "AUTOFIX: ~/Makefile:4: Replacing \"${WRKSRC:Q}\" with \"${WRKSRC}\".")
669 t.CheckFileLines("Makefile", 694 t.CheckFileLines("Makefile",
670 MkRcsId, 695 MkRcsID,
671 "", 696 "",
672 "demo: .PHONY", 697 "demo: .PHONY",
673 "\t${ECHO} ${WRKSRC}", 698 "\t${ECHO} ${WRKSRC}",
674 "\t${ECHO} ${FOODIR:Q}") 699 "\t${ECHO} ${FOODIR:Q}")
675} 700}
676 701
677func (s *Suite) Test_MkLine_Pkgmandir(c *check.C) { 702func (s *Suite) Test_MkLine_Pkgmandir(c *check.C) {
678 t := s.Init(c) 703 t := s.Init(c)
679 704
680 t.SetupCommandLine("-Wall") 705 t.SetupCommandLine("-Wall")
681 G.globalData.InitVartypes() 706 G.globalData.InitVartypes()
682 G.Mk = t.NewMkLines("chat/ircII/Makefile", 707 G.Mk = t.NewMkLines("chat/ircII/Makefile",
683 MkRcsId, 708 MkRcsID,
684 "CONFIGURE_ARGS+=--mandir=${DESTDIR}${PREFIX}/man", 709 "CONFIGURE_ARGS+=--mandir=${DESTDIR}${PREFIX}/man",
685 "CONFIGURE_ARGS+=--mandir=${DESTDIR}${PREFIX}/${PKGMANDIR}") 710 "CONFIGURE_ARGS+=--mandir=${DESTDIR}${PREFIX}/${PKGMANDIR}")
686 711
687 G.Mk.Check() 712 G.Mk.Check()
688 713
689 t.CheckOutputLines( 714 t.CheckOutputLines(
690 "WARN: chat/ircII/Makefile:2: Please use ${PKGMANDIR} instead of \"man\".", 715 "WARN: chat/ircII/Makefile:2: Please use ${PKGMANDIR} instead of \"man\".",
691 "NOTE: chat/ircII/Makefile:2: This variable value should be aligned to column 25.", 716 "NOTE: chat/ircII/Makefile:2: This variable value should be aligned to column 25.",
692 "NOTE: chat/ircII/Makefile:3: This variable value should be aligned to column 25.") 717 "NOTE: chat/ircII/Makefile:3: This variable value should be aligned to column 25.")
693} 718}
694 719
695func (s *Suite) Test_MkLines_Check__VERSION_as_wordpart_in_MASTER_SITES(c *check.C) { 720func (s *Suite) Test_MkLines_Check__VERSION_as_wordpart_in_MASTER_SITES(c *check.C) {
696 t := s.Init(c) 721 t := s.Init(c)
697 722
698 t.SetupCommandLine("-Wall") 723 t.SetupCommandLine("-Wall")
699 G.globalData.InitVartypes() 724 G.globalData.InitVartypes()
700 mklines := t.NewMkLines("geography/viking/Makefile", 725 mklines := t.NewMkLines("geography/viking/Makefile",
701 MkRcsId, 726 MkRcsID,
702 "MASTER_SITES=\t${MASTER_SITE_SOURCEFORGE:=viking/}${VERSION}/") 727 "MASTER_SITES=\t${MASTER_SITE_SOURCEFORGE:=viking/}${VERSION}/")
703 728
704 mklines.Check() 729 mklines.Check()
705 730
706 t.CheckOutputLines( 731 t.CheckOutputLines(
707 "WARN: geography/viking/Makefile:2: " + 732 "WARN: geography/viking/Makefile:2: " +
708 "The list variable MASTER_SITE_SOURCEFORGE should not be embedded in a word.") 733 "The list variable MASTER_SITE_SOURCEFORGE should not be embedded in a word.")
709} 734}
710 735
711func (s *Suite) Test_MkLines_Check__shell_command_as_wordpart_in_ENV_list(c *check.C) { 736func (s *Suite) Test_MkLines_Check__shell_command_as_wordpart_in_ENV_list(c *check.C) {
712 t := s.Init(c) 737 t := s.Init(c)
713 738
714 t.SetupCommandLine("-Wall") 739 t.SetupCommandLine("-Wall")
715 G.globalData.InitVartypes() 740 G.globalData.InitVartypes()
716 mklines := t.NewMkLines("x11/lablgtk1/Makefile", 741 mklines := t.NewMkLines("x11/lablgtk1/Makefile",
717 MkRcsId, 742 MkRcsID,
718 "CONFIGURE_ENV+=\tCC=${CC}") 743 "CONFIGURE_ENV+=\tCC=${CC}")
719 744
720 mklines.Check() 745 mklines.Check()
721 746
722 t.CheckOutputLines( 747 t.CheckOutputLines(
723 "WARN: x11/lablgtk1/Makefile:2: Please use ${CC:Q} instead of ${CC}.", 748 "WARN: x11/lablgtk1/Makefile:2: Please use ${CC:Q} instead of ${CC}.",
724 "WARN: x11/lablgtk1/Makefile:2: Please use ${CC:Q} instead of ${CC}.") 749 "WARN: x11/lablgtk1/Makefile:2: Please use ${CC:Q} instead of ${CC}.")
725} 750}
726 751
727func (s *Suite) Test_MkLine_shell_varuse_in_backt_dquot(c *check.C) { 752func (s *Suite) Test_MkLine_shell_varuse_in_backt_dquot(c *check.C) {
728 t := s.Init(c) 753 t := s.Init(c)
729 754
730 t.SetupCommandLine("-Wall") 755 t.SetupCommandLine("-Wall")
731 G.globalData.InitVartypes() 756 G.globalData.InitVartypes()
732 mklines := t.NewMkLines("x11/motif/Makefile", 757 mklines := t.NewMkLines("x11/motif/Makefile",
733 MkRcsId, 758 MkRcsID,
734 "post-patch:", 759 "post-patch:",
735 "\tfiles=`${GREP} -l \".fB$${name}.fP(3)\" *.3`") 760 "\tfiles=`${GREP} -l \".fB$${name}.fP(3)\" *.3`")
736 761
737 mklines.Check() 762 mklines.Check()
738 763
739 // Just ensure that there are no parse errors. 764 // Just ensure that there are no parse errors.
740 t.CheckOutputLines( 765 t.CheckOutputLines(
741 "WARN: x11/motif/Makefile:3: Unknown shell command \"${GREP}\".") 766 "WARN: x11/motif/Makefile:3: Unknown shell command \"${GREP}\".")
742} 767}
743 768
744// See PR 46570, Ctrl+F "3. In lang/perl5". 769// See PR 46570, Ctrl+F "3. In lang/perl5".
745func (s *Suite) Test_MkLine_VariableType(c *check.C) { 770func (s *Suite) Test_MkLine_VariableType(c *check.C) {
746 mkline := NewMkLine(dummyLine) 771 mkline := NewMkLine(dummyLine)
747 772
748 c.Check(mkline.VariableType("_PERL5_PACKLIST_AWK_STRIP_DESTDIR"), check.IsNil) 773 c.Check(mkline.VariableType("_PERL5_PACKLIST_AWK_STRIP_DESTDIR"), check.IsNil)
749 c.Check(mkline.VariableType("SOME_DIR").guessed, equals, true) 774 c.Check(mkline.VariableType("SOME_DIR").guessed, equals, true)
750 c.Check(mkline.VariableType("SOMEDIR").guessed, equals, true) 775 c.Check(mkline.VariableType("SOMEDIR").guessed, equals, true)
751} 776}
752 777
753// PR 51696, security/py-pbkdf2/Makefile, r1.2 778// PR 51696, security/py-pbkdf2/Makefile, r1.2
754func (s *Suite) Test_MkLine__comment_in_comment(c *check.C) { 779func (s *Suite) Test_MkLine__comment_in_comment(c *check.C) {
755 t := s.Init(c) 780 t := s.Init(c)
756 781
757 G.globalData.InitVartypes() 782 G.globalData.InitVartypes()
758 mklines := t.NewMkLines("Makefile", 783 mklines := t.NewMkLines("Makefile",
759 MkRcsId, 784 MkRcsID,
760 "COMMENT=\tPKCS#5 v2.0 PBKDF2 Module") 785 "COMMENT=\tPKCS#5 v2.0 PBKDF2 Module")
761 786
762 mklines.Check() 787 mklines.Check()
763 788
764 t.CheckOutputLines( 789 t.CheckOutputLines(
765 "WARN: Makefile:2: The # character starts a comment.") 790 "WARN: Makefile:2: The # character starts a comment.")
766} 791}
767 792
768func (s *Suite) Test_MkLine_ConditionVars(c *check.C) { 793func (s *Suite) Test_MkLine_ConditionVars(c *check.C) {
769 t := s.Init(c) 794 t := s.Init(c)
770 795
771 mkline := t.NewMkLine("Makefile", 45, ".include \"../../category/package/buildlink3.mk\"") 796 mkline := t.NewMkLine("Makefile", 45, ".include \"../../category/package/buildlink3.mk\"")
772 797

cvs diff -r1.8 -r1.9 pkgsrc/pkgtools/pkglint/files/Attic/mklinechecker.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/mklinechecker.go 2018/01/28 23:21:16 1.8
+++ pkgsrc/pkgtools/pkglint/files/Attic/mklinechecker.go 2018/02/19 12:40:38 1.9
@@ -156,27 +156,27 @@ func (ck MkLineChecker) checkCond(forVar @@ -156,27 +156,27 @@ func (ck MkLineChecker) checkCond(forVar
156 } 156 }
157 157
158 // Check if any of the value's types is not guessed. 158 // Check if any of the value's types is not guessed.
159 guessed := true 159 guessed := true
160 for _, value := range splitOnSpace(values) { 160 for _, value := range splitOnSpace(values) {
161 if m, vname := match1(value, `^\$\{(.*)\}`); m { 161 if m, vname := match1(value, `^\$\{(.*)\}`); m {
162 vartype := mkline.VariableType(vname) 162 vartype := mkline.VariableType(vname)
163 if vartype != nil && !vartype.guessed { 163 if vartype != nil && !vartype.guessed {
164 guessed = false 164 guessed = false
165 } 165 }
166 } 166 }
167 } 167 }
168 168
169 forLoopType := &Vartype{lkSpace, BtUnknown, []AclEntry{{"*", aclpAllRead}}, guessed} 169 forLoopType := &Vartype{lkSpace, BtUnknown, []ACLEntry{{"*", aclpAllRead}}, guessed}
170 forLoopContext := &VarUseContext{forLoopType, vucTimeParse, vucQuotFor, false} 170 forLoopContext := &VarUseContext{forLoopType, vucTimeParse, vucQuotFor, false}
171 for _, forLoopVar := range mkline.ExtractUsedVariables(values) { 171 for _, forLoopVar := range mkline.ExtractUsedVariables(values) {
172 ck.CheckVaruse(&MkVarUse{forLoopVar, nil}, forLoopContext) 172 ck.CheckVaruse(&MkVarUse{forLoopVar, nil}, forLoopContext)
173 } 173 }
174 } 174 }
175 175
176 } else if directive == "undef" && args != "" { 176 } else if directive == "undef" && args != "" {
177 for _, uvar := range splitOnSpace(args) { 177 for _, uvar := range splitOnSpace(args) {
178 if forVars[uvar] { 178 if forVars[uvar] {
179 mkline.Notef("Using \".undef\" after a \".for\" loop is unnecessary.") 179 mkline.Notef("Using \".undef\" after a \".for\" loop is unnecessary.")
180 } 180 }
181 } 181 }
182 } 182 }
@@ -246,27 +246,27 @@ func (ck MkLineChecker) checkVarassignDe @@ -246,27 +246,27 @@ func (ck MkLineChecker) checkVarassignDe
246 246
247 mkline := ck.MkLine 247 mkline := ck.MkLine
248 varname := mkline.Varname() 248 varname := mkline.Varname()
249 op := mkline.Op() 249 op := mkline.Op()
250 vartype := mkline.VariableType(varname) 250 vartype := mkline.VariableType(varname)
251 if vartype == nil { 251 if vartype == nil {
252 if trace.Tracing { 252 if trace.Tracing {
253 trace.Step1("No type definition found for %q.", varname) 253 trace.Step1("No type definition found for %q.", varname)
254 } 254 }
255 return 255 return
256 } 256 }
257 257
258 perms := vartype.EffectivePermissions(mkline.Filename) 258 perms := vartype.EffectivePermissions(mkline.Filename)
259 var needed AclPermissions 259 var needed ACLPermissions
260 switch op { 260 switch op {
261 case opAssign, opAssignShell, opAssignEval: 261 case opAssign, opAssignShell, opAssignEval:
262 needed = aclpSet 262 needed = aclpSet
263 case opAssignDefault: 263 case opAssignDefault:
264 needed = aclpSetDefault 264 needed = aclpSetDefault
265 case opAssignAppend: 265 case opAssignAppend:
266 needed = aclpAppend 266 needed = aclpAppend
267 } 267 }
268 268
269 switch { 269 switch {
270 case perms.Contains(needed): 270 case perms.Contains(needed):
271 break 271 break
272 case perms == aclpUnknown: 272 case perms == aclpUnknown:
@@ -492,69 +492,78 @@ func (ck MkLineChecker) checkVaruseFor(v @@ -492,69 +492,78 @@ func (ck MkLineChecker) checkVaruseFor(v
492 if false && // Too many false positives 492 if false && // Too many false positives
493 vartype != nil && 493 vartype != nil &&
494 vartype.kindOfList != lkSpace && 494 vartype.kindOfList != lkSpace &&
495 needsQuoting != nqDoesntMatter { 495 needsQuoting != nqDoesntMatter {
496 ck.MkLine.Warnf("The variable %s should not be used in .for loops.", varname) 496 ck.MkLine.Warnf("The variable %s should not be used in .for loops.", varname)
497 Explain( 497 Explain(
498 "The .for loop splits its argument at sequences of white-space, as", 498 "The .for loop splits its argument at sequences of white-space, as",
499 "opposed to all other places in make(1), which act like the shell.", 499 "opposed to all other places in make(1), which act like the shell.",
500 "Therefore only variables that are split at whitespace or don't", 500 "Therefore only variables that are split at whitespace or don't",
501 "contain any special characters should be used here.") 501 "contain any special characters should be used here.")
502 } 502 }
503} 503}
504 504
 505// CheckVaruseShellword checks whether a variable use of the form ${VAR}
 506// or ${VAR:Modifier} is allowed in a certain context.
505func (ck MkLineChecker) CheckVaruseShellword(varname string, vartype *Vartype, vuc *VarUseContext, mod string, needsQuoting NeedsQuoting) { 507func (ck MkLineChecker) CheckVaruseShellword(varname string, vartype *Vartype, vuc *VarUseContext, mod string, needsQuoting NeedsQuoting) {
506 if trace.Tracing { 508 if trace.Tracing {
507 defer trace.Call(varname, vartype, vuc, mod, needsQuoting)() 509 defer trace.Call(varname, vartype, vuc, mod, needsQuoting)()
508 } 510 }
509 511
510 // In GNU configure scripts, a few variables need to be 512 // In GNU configure scripts, a few variables need to be
511 // passed through the :M* operator before they reach the 513 // passed through the :M* operator before they reach the
512 // configure scripts. 514 // configure scripts.
513 // 515 //
514 // When doing checks outside a package, the :M* operator is needed for safety. 516 // When doing checks outside a package, the :M* operator is needed for safety.
515 needMstar := matches(varname, `^(?:.*_)?(?:CFLAGS||CPPFLAGS|CXXFLAGS|FFLAGS|LDFLAGS|LIBS)$`) && 517 needMstar := matches(varname, `^(?:.*_)?(?:CFLAGS||CPPFLAGS|CXXFLAGS|FFLAGS|LDFLAGS|LIBS)$`) &&
516 (G.Pkg == nil || G.Pkg.vardef["GNU_CONFIGURE"] != nil) 518 (G.Pkg == nil || G.Pkg.vardef["GNU_CONFIGURE"] != nil)
517 519
518 strippedMod := mod 520 strippedMod := mod
519 if m, stripped := match1(mod, `(.*?)(?::M\*)?(?::Q)?$`); m { 521 if m, stripped := match1(mod, `(.*?)(?::M\*)?(?::Q)?$`); m {
520 strippedMod = stripped 522 strippedMod = stripped
521 } 523 }
522 524
523 mkline := ck.MkLine 525 mkline := ck.MkLine
524 if mod == ":M*:Q" && !needMstar { 526 if mod == ":M*:Q" && !needMstar {
525 mkline.Notef("The :M* modifier is not needed here.") 527 mkline.Notef("The :M* modifier is not needed here.")
526 528
527 } else if needsQuoting == nqYes { 529 } else if needsQuoting == nqYes {
528 correctMod := strippedMod + ifelseStr(needMstar, ":M*:Q", ":Q") 530 correctMod := strippedMod + ifelseStr(needMstar, ":M*:Q", ":Q")
529 if correctMod == mod+":Q" && vuc.IsWordPart && !vartype.IsShell() { 531 if correctMod == mod+":Q" && vuc.IsWordPart && !vartype.IsShell() {
530 mkline.Warnf("The list variable %s should not be embedded in a word.", varname) 532 if vartype.IsConsideredList() {
531 Explain( 533 mkline.Warnf("The list variable %s should not be embedded in a word.", varname)
532 "When a list variable has multiple elements, this expression expands", 534 Explain(
533 "to something unexpected:", 535 "When a list variable has multiple elements, this expression expands",
534 "", 536 "to something unexpected:",
535 "Example: ${MASTER_SITE_SOURCEFORGE}directory/ expands to", 537 "",
536 "", 538 "Example: ${MASTER_SITE_SOURCEFORGE}directory/ expands to",
537 "\thttps://mirror1.sf.net/ https://mirror2.sf.net/directory/", 539 "",
538 "", 540 "\thttps://mirror1.sf.net/ https://mirror2.sf.net/directory/",
539 "The first URL is missing the directory. To fix this, write", 541 "",
540 "\t${MASTER_SITE_SOURCEFORGE:=directory/}.", 542 "The first URL is missing the directory. To fix this, write",
541 "", 543 "\t${MASTER_SITE_SOURCEFORGE:=directory/}.",
542 "Example: -l${LIBS} expands to", 544 "",
543 "", 545 "Example: -l${LIBS} expands to",
544 "\t-llib1 lib2", 546 "",
545 "", 547 "\t-llib1 lib2",
546 "The second library is missing the -l. To fix this, write", 548 "",
547 "${LIBS:@lib@-l${lib}@}.") 549 "The second library is missing the -l. To fix this, write",
 550 "${LIBS:@lib@-l${lib}@}.")
 551 } else {
 552 mkline.Warnf("The variable %s should be quoted as part of a shell word.", varname)
 553 Explain(
 554 "This variable can contain spaces or other special characters.",
 555 "Therefore it should be quoted by replacing ${VAR} with ${VAR:Q}.")
 556 }
548 557
549 } else if mod != correctMod { 558 } else if mod != correctMod {
550 if vuc.quoting == vucQuotPlain { 559 if vuc.quoting == vucQuotPlain {
551 fix := mkline.Line.Autofix() 560 fix := mkline.Line.Autofix()
552 fix.Warnf("Please use ${%s%s} instead of ${%s%s}.", varname, correctMod, varname, mod) 561 fix.Warnf("Please use ${%s%s} instead of ${%s%s}.", varname, correctMod, varname, mod)
553 fix.Replace("${"+varname+mod+"}", "${"+varname+correctMod+"}") 562 fix.Replace("${"+varname+mod+"}", "${"+varname+correctMod+"}")
554 fix.Apply() 563 fix.Apply()
555 } else { 564 } else {
556 mkline.Warnf("Please use ${%s%s} instead of ${%s%s} and make sure"+ 565 mkline.Warnf("Please use ${%s%s} instead of ${%s%s} and make sure"+
557 " the variable appears outside of any quoting characters.", varname, correctMod, varname, mod) 566 " the variable appears outside of any quoting characters.", varname, correctMod, varname, mod)
558 } 567 }
559 Explain( 568 Explain(
560 "See the pkgsrc guide, section \"quoting guideline\", for details.") 569 "See the pkgsrc guide, section \"quoting guideline\", for details.")
@@ -773,37 +782,26 @@ func (ck MkLineChecker) checkVarassignVa @@ -773,37 +782,26 @@ func (ck MkLineChecker) checkVarassignVa
773func (ck MkLineChecker) checkVarassignSpecific() { 782func (ck MkLineChecker) checkVarassignSpecific() {
774 mkline := ck.MkLine 783 mkline := ck.MkLine
775 varname := mkline.Varname() 784 varname := mkline.Varname()
776 value := mkline.Value() 785 value := mkline.Value()
777 786
778 if contains(value, "/etc/rc.d") { 787 if contains(value, "/etc/rc.d") {
779 mkline.Warnf("Please use the RCD_SCRIPTS mechanism to install rc.d scripts automatically to ${RCD_SCRIPTS_EXAMPLEDIR}.") 788 mkline.Warnf("Please use the RCD_SCRIPTS mechanism to install rc.d scripts automatically to ${RCD_SCRIPTS_EXAMPLEDIR}.")
780 } 789 }
781 790
782 if hasPrefix(varname, "_") && !G.Infrastructure { 791 if hasPrefix(varname, "_") && !G.Infrastructure {
783 mkline.Warnf("Variable names starting with an underscore (%s) are reserved for internal pkgsrc use.", varname) 792 mkline.Warnf("Variable names starting with an underscore (%s) are reserved for internal pkgsrc use.", varname)
784 } 793 }
785 794
786 if varname == "PERL5_PACKLIST" && G.Pkg != nil { 
787 if m, p5pkgname := match1(G.Pkg.EffectivePkgbase, `^p5-(.*)`); m { 
788 guess := "auto/" + strings.Replace(p5pkgname, "-", "/", -1) + "/.packlist" 
789 
790 ucvalue, ucguess := strings.ToUpper(value), strings.ToUpper(guess) 
791 if ucvalue != ucguess && ucvalue != "${PERL5_SITEARCH}/"+ucguess { 
792 mkline.Warnf("Unusual value for PERL5_PACKLIST -- %q expected.", guess) 
793 } 
794 } 
795 } 
796 
797 if varname == "PYTHON_VERSIONS_ACCEPTED" { 795 if varname == "PYTHON_VERSIONS_ACCEPTED" {
798 ck.checkVarassignPythonVersions(varname, value) 796 ck.checkVarassignPythonVersions(varname, value)
799 } 797 }
800 798
801 if mkline.VarassignComment() == "# defined" && !hasSuffix(varname, "_MK") && !hasSuffix(varname, "_COMMON") { 799 if mkline.VarassignComment() == "# defined" && !hasSuffix(varname, "_MK") && !hasSuffix(varname, "_COMMON") {
802 mkline.Notef("Please use \"# empty\", \"# none\" or \"yes\" instead of \"# defined\".") 800 mkline.Notef("Please use \"# empty\", \"# none\" or \"yes\" instead of \"# defined\".")
803 Explain( 801 Explain(
804 "The value #defined says something about the state of the variable,", 802 "The value #defined says something about the state of the variable,",
805 "but not what that _means_. In some cases a variable that is defined", 803 "but not what that _means_. In some cases a variable that is defined",
806 "means \"yes\", in other cases it is an empty list (which is also", 804 "means \"yes\", in other cases it is an empty list (which is also",
807 "only the state of the variable), whose meaning could be described", 805 "only the state of the variable), whose meaning could be described",
808 "with \"none\". It is this meaning that should be described.") 806 "with \"none\". It is this meaning that should be described.")
809 } 807 }

cvs diff -r1.8 -r1.9 pkgsrc/pkgtools/pkglint/files/Attic/mkparser_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/mkparser_test.go 2018/01/27 18:50:36 1.8
+++ pkgsrc/pkgtools/pkglint/files/Attic/mkparser_test.go 2018/02/19 12:40:38 1.9
@@ -213,27 +213,27 @@ func (s *Suite) Test_MkParser_MkCond(c * @@ -213,27 +213,27 @@ func (s *Suite) Test_MkParser_MkCond(c *
213 213
214 // Errors 214 // Errors
215 checkRest("!empty(PKG_OPTIONS:Msndfile) || defined(PKG_OPTIONS:Msamplerate)", 215 checkRest("!empty(PKG_OPTIONS:Msndfile) || defined(PKG_OPTIONS:Msamplerate)",
216 NewTree("not", NewTree("empty", varuse("PKG_OPTIONS", "Msndfile"))), 216 NewTree("not", NewTree("empty", varuse("PKG_OPTIONS", "Msndfile"))),
217 " || defined(PKG_OPTIONS:Msamplerate)") 217 " || defined(PKG_OPTIONS:Msamplerate)")
218} 218}
219 219
220func (s *Suite) Test_MkParser__varuse_parentheses_autofix(c *check.C) { 220func (s *Suite) Test_MkParser__varuse_parentheses_autofix(c *check.C) {
221 t := s.Init(c) 221 t := s.Init(c)
222 222
223 t.SetupCommandLine("--autofix") 223 t.SetupCommandLine("--autofix")
224 G.globalData.InitVartypes() 224 G.globalData.InitVartypes()
225 lines := t.SetupFileLines("Makefile", 225 lines := t.SetupFileLines("Makefile",
226 MkRcsId, 226 MkRcsID,
227 "COMMENT=$(P1) $(P2)) $(P3:Q) ${BRACES}") 227 "COMMENT=$(P1) $(P2)) $(P3:Q) ${BRACES}")
228 mklines := NewMkLines(lines) 228 mklines := NewMkLines(lines)
229 229
230 mklines.Check() 230 mklines.Check()
231 231
232 t.CheckOutputLines( 232 t.CheckOutputLines(
233 "AUTOFIX: ~/Makefile:2: Replacing \"$(P1)\" with \"${P1}\".", 233 "AUTOFIX: ~/Makefile:2: Replacing \"$(P1)\" with \"${P1}\".",
234 "AUTOFIX: ~/Makefile:2: Replacing \"$(P2)\" with \"${P2}\".", 234 "AUTOFIX: ~/Makefile:2: Replacing \"$(P2)\" with \"${P2}\".",
235 "AUTOFIX: ~/Makefile:2: Replacing \"$(P3:Q)\" with \"${P3:Q}\".") 235 "AUTOFIX: ~/Makefile:2: Replacing \"$(P3:Q)\" with \"${P3:Q}\".")
236 t.CheckFileLines("Makefile", 236 t.CheckFileLines("Makefile",
237 MkRcsId, 237 MkRcsID,
238 "COMMENT=${P1} ${P2}) ${P3:Q} ${BRACES}") 238 "COMMENT=${P1} ${P2}) ${P3:Q} ${BRACES}")
239} 239}

cvs diff -r1.8 -r1.9 pkgsrc/pkgtools/pkglint/files/Attic/toplevel.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/toplevel.go 2018/01/01 18:04:15 1.8
+++ pkgsrc/pkgtools/pkglint/files/Attic/toplevel.go 2018/02/19 12:40:38 1.9
@@ -25,27 +25,27 @@ func CheckdirToplevel() { @@ -25,27 +25,27 @@ func CheckdirToplevel() {
25 for _, line := range lines { 25 for _, line := range lines {
26 if m, commentedOut, indentation, subdir, comment := match4(line.Text, `^(#?)SUBDIR\s*\+=(\s*)(\S+)\s*(?:#\s*(.*?)\s*|)$`); m { 26 if m, commentedOut, indentation, subdir, comment := match4(line.Text, `^(#?)SUBDIR\s*\+=(\s*)(\S+)\s*(?:#\s*(.*?)\s*|)$`); m {
27 ctx.checkSubdir(line, commentedOut == "#", indentation, subdir, comment) 27 ctx.checkSubdir(line, commentedOut == "#", indentation, subdir, comment)
28 } 28 }
29 } 29 }
30 30
31 NewMkLines(lines).Check() 31 NewMkLines(lines).Check()
32 32
33 if G.opts.Recursive { 33 if G.opts.Recursive {
34 if G.opts.CheckGlobal { 34 if G.opts.CheckGlobal {
35 G.UsedLicenses = make(map[string]bool) 35 G.UsedLicenses = make(map[string]bool)
36 G.Hash = make(map[string]*Hash) 36 G.Hash = make(map[string]*Hash)
37 } 37 }
38 G.Todo = append(G.Todo, ctx.subdirs...) 38 G.Todo = append(append([]string(nil), ctx.subdirs...), G.Todo...)
39 } 39 }
40} 40}
41 41
42func (ctx *Toplevel) checkSubdir(line Line, commentedOut bool, indentation, subdir, comment string) { 42func (ctx *Toplevel) checkSubdir(line Line, commentedOut bool, indentation, subdir, comment string) {
43 if commentedOut && comment == "" { 43 if commentedOut && comment == "" {
44 line.Warnf("%q commented out without giving a reason.", subdir) 44 line.Warnf("%q commented out without giving a reason.", subdir)
45 } 45 }
46 46
47 if indentation != "\t" { 47 if indentation != "\t" {
48 line.Warnf("Indentation should be a single tab character.") 48 line.Warnf("Indentation should be a single tab character.")
49 } 49 }
50 50
51 if contains(subdir, "$") || !fileExists(G.CurrentDir+"/"+subdir+"/Makefile") { 51 if contains(subdir, "$") || !fileExists(G.CurrentDir+"/"+subdir+"/Makefile") {

cvs diff -r1.8 -r1.9 pkgsrc/pkgtools/pkglint/files/Attic/toplevel_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/toplevel_test.go 2018/01/27 18:50:36 1.8
+++ pkgsrc/pkgtools/pkglint/files/Attic/toplevel_test.go 2018/02/19 12:40:38 1.9
@@ -1,22 +1,22 @@ @@ -1,22 +1,22 @@
1package main 1package main
2 2
3import "gopkg.in/check.v1" 3import "gopkg.in/check.v1"
4 4
5func (s *Suite) Test_CheckdirToplevel(c *check.C) { 5func (s *Suite) Test_CheckdirToplevel(c *check.C) {
6 t := s.Init(c) 6 t := s.Init(c)
7 7
8 t.SetupFileLines("Makefile", 8 t.SetupFileLines("Makefile",
9 MkRcsId, 9 MkRcsID,
10 "", 10 "",
11 "SUBDIR+= x11", 11 "SUBDIR+= x11",
12 "SUBDIR+=\tarchivers", 12 "SUBDIR+=\tarchivers",
13 "SUBDIR+=\tccc", 13 "SUBDIR+=\tccc",
14 "SUBDIR+=\tccc", 14 "SUBDIR+=\tccc",
15 "#SUBDIR+=\tignoreme", 15 "#SUBDIR+=\tignoreme",
16 "SUBDIR+=\tnonexisting", // This doesn't happen in practice, therefore no warning. 16 "SUBDIR+=\tnonexisting", // This doesn't happen in practice, therefore no warning.
17 "SUBDIR+=\tbbb") 17 "SUBDIR+=\tbbb")
18 t.SetupFileLines("archivers/Makefile") 18 t.SetupFileLines("archivers/Makefile")
19 t.SetupFileLines("bbb/Makefile") 19 t.SetupFileLines("bbb/Makefile")
20 t.SetupFileLines("ccc/Makefile") 20 t.SetupFileLines("ccc/Makefile")
21 t.SetupFileLines("x11/Makefile") 21 t.SetupFileLines("x11/Makefile")
22 G.globalData.InitVartypes() 22 G.globalData.InitVartypes()

cvs diff -r1.6 -r1.7 pkgsrc/pkgtools/pkglint/files/Attic/mklinechecker_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/mklinechecker_test.go 2018/01/28 23:21:16 1.6
+++ pkgsrc/pkgtools/pkglint/files/Attic/mklinechecker_test.go 2018/02/19 12:40:38 1.7
@@ -126,27 +126,27 @@ func (s *Suite) Test_MkLineChecker_Check @@ -126,27 +126,27 @@ func (s *Suite) Test_MkLineChecker_Check
126 "earmeb earmhf earmhfeb earmv4 earmv4eb earmv5 earmv5eb earmv6 earmv6eb earmv6hf earmv6hfeb "+ 126 "earmeb earmhf earmhfeb earmv4 earmv4eb earmv5 earmv5eb earmv6 earmv6eb earmv6hf earmv6hfeb "+
127 "earmv7 earmv7eb earmv7hf earmv7hfeb evbarm hpcmips hpcsh hppa hppa64 i386 i586 i686 ia64 "+ 127 "earmv7 earmv7eb earmv7hf earmv7hfeb evbarm hpcmips hpcsh hppa hppa64 i386 i586 i686 ia64 "+
128 "m68000 m68k m88k mips mips64 mips64eb mips64el mipseb mipsel mipsn32 mlrisc ns32k pc532 pmax "+ 128 "m68000 m68k m88k mips mips64 mips64eb mips64el mipseb mipsel mipsn32 mlrisc ns32k pc532 pmax "+
129 "powerpc powerpc64 rs6000 s390 sh3eb sh3el sparc sparc64 vax x86_64 "+ 129 "powerpc powerpc64 rs6000 s390 sh3eb sh3el sparc sparc64 vax x86_64 "+
130 "} for MACHINE_ARCH.") 130 "} for MACHINE_ARCH.")
131} 131}
132 132
133func (s *Suite) Test_MkLineChecker_checkVarassign(c *check.C) { 133func (s *Suite) Test_MkLineChecker_checkVarassign(c *check.C) {
134 t := s.Init(c) 134 t := s.Init(c)
135 135
136 G.globalData.InitVartypes() 136 G.globalData.InitVartypes()
137 137
138 G.Mk = t.NewMkLines("Makefile", 138 G.Mk = t.NewMkLines("Makefile",
139 MkRcsId, 139 MkRcsID,
140 "ac_cv_libpari_libs+=\t-L${BUILDLINK_PREFIX.pari}/lib") // From math/clisp-pari/Makefile, rev. 1.8 140 "ac_cv_libpari_libs+=\t-L${BUILDLINK_PREFIX.pari}/lib") // From math/clisp-pari/Makefile, rev. 1.8
141 141
142 MkLineChecker{G.Mk.mklines[1]}.checkVarassign() 142 MkLineChecker{G.Mk.mklines[1]}.checkVarassign()
143 143
144 t.CheckOutputLines( 144 t.CheckOutputLines(
145 "WARN: Makefile:2: ac_cv_libpari_libs is defined but not used. Spelling mistake?") 145 "WARN: Makefile:2: ac_cv_libpari_libs is defined but not used. Spelling mistake?")
146} 146}
147 147
148func (s *Suite) Test_MkLineChecker_checkVarassignDefPermissions(c *check.C) { 148func (s *Suite) Test_MkLineChecker_checkVarassignDefPermissions(c *check.C) {
149 t := s.Init(c) 149 t := s.Init(c)
150 150
151 t.SetupCommandLine("-Wall") 151 t.SetupCommandLine("-Wall")
152 G.globalData.InitVartypes() 152 G.globalData.InitVartypes()
@@ -154,51 +154,51 @@ func (s *Suite) Test_MkLineChecker_check @@ -154,51 +154,51 @@ func (s *Suite) Test_MkLineChecker_check
154 154
155 MkLineChecker{mkline}.checkVarassignDefPermissions() 155 MkLineChecker{mkline}.checkVarassignDefPermissions()
156 156
157 t.CheckOutputLines( 157 t.CheckOutputLines(
158 "WARN: options.mk:2: The variable PKG_DEVELOPER may not be given a default value by any package.") 158 "WARN: options.mk:2: The variable PKG_DEVELOPER may not be given a default value by any package.")
159} 159}
160 160
161func (s *Suite) Test_MkLineChecker_CheckVarusePermissions(c *check.C) { 161func (s *Suite) Test_MkLineChecker_CheckVarusePermissions(c *check.C) {
162 t := s.Init(c) 162 t := s.Init(c)
163 163
164 t.SetupCommandLine("-Wall") 164 t.SetupCommandLine("-Wall")
165 G.globalData.InitVartypes() 165 G.globalData.InitVartypes()
166 mklines := t.NewMkLines("options.mk", 166 mklines := t.NewMkLines("options.mk",
167 MkRcsId, 167 MkRcsID,
168 "COMMENT=\t${GAMES_USER}", 168 "COMMENT=\t${GAMES_USER}",
169 "COMMENT:=\t${PKGBASE}", 169 "COMMENT:=\t${PKGBASE}",
170 "PYPKGPREFIX=${PKGBASE}") 170 "PYPKGPREFIX=${PKGBASE}")
171 G.globalData.UserDefinedVars = map[string]MkLine{ 171 G.globalData.UserDefinedVars = map[string]MkLine{
172 "GAMES_USER": mklines.mklines[0], 172 "GAMES_USER": mklines.mklines[0],
173 } 173 }
174 174
175 mklines.Check() 175 mklines.Check()
176 176
177 t.CheckOutputLines( 177 t.CheckOutputLines(
178 "WARN: options.mk:2: The user-defined variable GAMES_USER is used but not added to BUILD_DEFS.", 178 "WARN: options.mk:2: The user-defined variable GAMES_USER is used but not added to BUILD_DEFS.",
179 "WARN: options.mk:3: PKGBASE should not be evaluated at load time.", 179 "WARN: options.mk:3: PKGBASE should not be evaluated at load time.",
180 "WARN: options.mk:4: The variable PYPKGPREFIX may not be set in this file; it would be ok in pyversion.mk.", 180 "WARN: options.mk:4: The variable PYPKGPREFIX may not be set in this file; it would be ok in pyversion.mk.",
181 "WARN: options.mk:4: PKGBASE should not be evaluated indirectly at load time.", 181 "WARN: options.mk:4: PKGBASE should not be evaluated indirectly at load time.",
182 "NOTE: options.mk:4: This variable value should be aligned to column 17.") 182 "NOTE: options.mk:4: This variable value should be aligned to column 17.")
183} 183}
184 184
185func (s *Suite) Test_MkLineChecker_CheckVarusePermissions__load_time(c *check.C) { 185func (s *Suite) Test_MkLineChecker_CheckVarusePermissions__load_time(c *check.C) {
186 t := s.Init(c) 186 t := s.Init(c)
187 187
188 t.SetupCommandLine("-Wall") 188 t.SetupCommandLine("-Wall")
189 G.globalData.InitVartypes() 189 G.globalData.InitVartypes()
190 mklines := t.NewMkLines("options.mk", 190 mklines := t.NewMkLines("options.mk",
191 MkRcsId, 191 MkRcsID,
192 "WRKSRC:=${.CURDIR}") 192 "WRKSRC:=${.CURDIR}")
193 193
194 mklines.Check() 194 mklines.Check()
195 195
196 // Don't warn that ".CURDIR should not be evaluated at load time." 196 // Don't warn that ".CURDIR should not be evaluated at load time."
197 t.CheckOutputLines( 197 t.CheckOutputLines(
198 "NOTE: options.mk:2: This variable value should be aligned to column 17.") 198 "NOTE: options.mk:2: This variable value should be aligned to column 17.")
199} 199}
200 200
201func (s *Suite) Test_MkLineChecker_WarnVaruseLocalbase(c *check.C) { 201func (s *Suite) Test_MkLineChecker_WarnVaruseLocalbase(c *check.C) {
202 t := s.Init(c) 202 t := s.Init(c)
203 203
204 mkline := t.NewMkLine("options.mk", 56, "PKGNAME=${LOCALBASE}") 204 mkline := t.NewMkLine("options.mk", 56, "PKGNAME=${LOCALBASE}")
@@ -247,109 +247,134 @@ func (s *Suite) Test_MkLineChecker__Varu @@ -247,109 +247,134 @@ func (s *Suite) Test_MkLineChecker__Varu
247 247
248 MkLineChecker{G.Mk.mklines[0]}.Check() 248 MkLineChecker{G.Mk.mklines[0]}.Check()
249 249
250 // Don't warn that ${XKBBASE}/xkbcomp is used but not defined. 250 // Don't warn that ${XKBBASE}/xkbcomp is used but not defined.
251 t.CheckOutputEmpty() 251 t.CheckOutputEmpty()
252} 252}
253 253
254func (s *Suite) Test_MkLineChecker_CheckCond__comparison_with_shell_command(c *check.C) { 254func (s *Suite) Test_MkLineChecker_CheckCond__comparison_with_shell_command(c *check.C) {
255 t := s.Init(c) 255 t := s.Init(c)
256 256
257 t.SetupCommandLine("-Wall") 257 t.SetupCommandLine("-Wall")
258 G.globalData.InitVartypes() 258 G.globalData.InitVartypes()
259 G.Mk = t.NewMkLines("security/openssl/Makefile", 259 G.Mk = t.NewMkLines("security/openssl/Makefile",
260 MkRcsId, 260 MkRcsID,
261 ".if ${PKGSRC_COMPILER} == \"gcc\" && ${CC} == \"cc\"", 261 ".if ${PKGSRC_COMPILER} == \"gcc\" && ${CC} == \"cc\"",
262 ".endif") 262 ".endif")
263 263
264 G.Mk.Check() 264 G.Mk.Check()
265 265
266 // Don't warn about unknown shell command "cc". 266 // Don't warn about unknown shell command "cc".
267 t.CheckOutputLines( 267 t.CheckOutputLines(
268 "WARN: security/openssl/Makefile:2: Use ${PKGSRC_COMPILER:Mgcc} instead of the == operator.") 268 "WARN: security/openssl/Makefile:2: Use ${PKGSRC_COMPILER:Mgcc} instead of the == operator.")
269} 269}
270 270
271func (s *Suite) Test_MkLine_CheckCond_comparing_PKGSRC_COMPILER_with_eqeq(c *check.C) { 271func (s *Suite) Test_MkLine_CheckCond_comparing_PKGSRC_COMPILER_with_eqeq(c *check.C) {
272 t := s.Init(c) 272 t := s.Init(c)
273 273
274 t.SetupCommandLine("-Wall") 274 t.SetupCommandLine("-Wall")
275 G.globalData.InitVartypes() 275 G.globalData.InitVartypes()
276 G.Mk = t.NewMkLines("audio/pulseaudio/Makefile", 276 G.Mk = t.NewMkLines("audio/pulseaudio/Makefile",
277 MkRcsId, 277 MkRcsID,
278 ".if ${OPSYS} == \"Darwin\" && ${PKGSRC_COMPILER} == \"clang\"", 278 ".if ${OPSYS} == \"Darwin\" && ${PKGSRC_COMPILER} == \"clang\"",
279 ".endif") 279 ".endif")
280 280
281 G.Mk.Check() 281 G.Mk.Check()
282 282
283 t.CheckOutputLines( 283 t.CheckOutputLines(
284 "WARN: audio/pulseaudio/Makefile:2: Use ${PKGSRC_COMPILER:Mclang} instead of the == operator.") 284 "WARN: audio/pulseaudio/Makefile:2: Use ${PKGSRC_COMPILER:Mclang} instead of the == operator.")
285} 285}
286 286
287func (s *Suite) Test_MkLineChecker_CheckVartype__CFLAGS_with_backticks(c *check.C) { 287func (s *Suite) Test_MkLineChecker_CheckVartype__CFLAGS_with_backticks(c *check.C) {
288 t := s.Init(c) 288 t := s.Init(c)
289 289
290 t.SetupCommandLine("-Wall") 290 t.SetupCommandLine("-Wall")
291 G.globalData.InitVartypes() 291 G.globalData.InitVartypes()
292 G.Mk = t.NewMkLines("chat/pidgin-icb/Makefile", 292 G.Mk = t.NewMkLines("chat/pidgin-icb/Makefile",
293 MkRcsId, 293 MkRcsID,
294 "CFLAGS+=\t`pkg-config pidgin --cflags`") 294 "CFLAGS+=\t`pkg-config pidgin --cflags`")
295 mkline := G.Mk.mklines[1] 295 mkline := G.Mk.mklines[1]
296 296
297 words, rest := splitIntoMkWords(mkline.Line, mkline.Value()) 297 words, rest := splitIntoMkWords(mkline.Line, mkline.Value())
298 298
299 c.Check(words, deepEquals, []string{"`pkg-config pidgin --cflags`"}) 299 c.Check(words, deepEquals, []string{"`pkg-config pidgin --cflags`"})
300 c.Check(rest, equals, "") 300 c.Check(rest, equals, "")
301 301
302 MkLineChecker{G.Mk.mklines[1]}.CheckVartype("CFLAGS", opAssignAppend, "`pkg-config pidgin --cflags`", "") 302 MkLineChecker{G.Mk.mklines[1]}.CheckVartype("CFLAGS", opAssignAppend, "`pkg-config pidgin --cflags`", "")
303 303
304 // No warning about "`pkg-config" being an unknown CFlag. 304 // No warning about "`pkg-config" being an unknown CFlag.
305 t.CheckOutputEmpty() 305 t.CheckOutputEmpty()
306} 306}
307 307
308// See PR 46570, Ctrl+F "4. Shell quoting". 308// See PR 46570, Ctrl+F "4. Shell quoting".
309// Pkglint is correct, since the shell sees this definition for 309// Pkglint is correct, since the shell sees this definition for
310// CPPFLAGS as three words, not one word. 310// CPPFLAGS as three words, not one word.
311func (s *Suite) Test_MkLineChecker_CheckVartype_CFLAGS(c *check.C) { 311func (s *Suite) Test_MkLineChecker_CheckVartype_CFLAGS(c *check.C) {
312 t := s.Init(c) 312 t := s.Init(c)
313 313
314 G.globalData.InitVartypes() 314 G.globalData.InitVartypes()
315 mklines := t.NewMkLines("Makefile", 315 mklines := t.NewMkLines("Makefile",
316 MkRcsId, 316 MkRcsID,
317 "CPPFLAGS.SunOS+=\t-DPIPECOMMAND=\\\"/usr/sbin/sendmail -bs %s\\\"") 317 "CPPFLAGS.SunOS+=\t-DPIPECOMMAND=\\\"/usr/sbin/sendmail -bs %s\\\"")
318 318
319 mklines.Check() 319 mklines.Check()
320 320
321 t.CheckOutputLines( 321 t.CheckOutputLines(
322 "WARN: Makefile:2: Unknown compiler flag \"-bs\".", 322 "WARN: Makefile:2: Unknown compiler flag \"-bs\".",
323 "WARN: Makefile:2: Compiler flag \"%s\\\\\\\"\" should start with a hyphen.") 323 "WARN: Makefile:2: Compiler flag \"%s\\\\\\\"\" should start with a hyphen.")
324} 324}
325 325
326// Up to 2018-01-28, pkglint applied the autofix also to the continuation 326// Up to 2018-01-28, pkglint applied the autofix also to the continuation
327// lines, which is incorrect. It replaced the dot in "4.*" with spaces. 327// lines, which is incorrect. It replaced the dot in "4.*" with spaces.
328func (s *Suite) Test_MkLineChecker_checkDirectiveIndentation_autofix(c *check.C) { 328func (s *Suite) Test_MkLineChecker_checkDirectiveIndentation_autofix(c *check.C) {
329 t := s.Init(c) 329 t := s.Init(c)
330 330
331 t.SetupCommandLine("-Wall", "--autofix") 331 t.SetupCommandLine("-Wall", "--autofix")
332 G.globalData.InitVartypes() 332 G.globalData.InitVartypes()
333 lines := t.SetupFileLinesContinuation("options.mk", 333 lines := t.SetupFileLinesContinuation("options.mk",
334 MkRcsId, 334 MkRcsID,
335 ".if ${PKGNAME} == pkgname", 335 ".if ${PKGNAME} == pkgname",
336 ".if \\", 336 ".if \\",
337 " ${PLATFORM:MNetBSD-4.*}", 337 " ${PLATFORM:MNetBSD-4.*}",
338 ".endif", 338 ".endif",
339 ".endif") 339 ".endif")
340 mklines := NewMkLines(lines) 340 mklines := NewMkLines(lines)
341 341
342 mklines.Check() 342 mklines.Check()
343 343
344 t.CheckOutputLines( 344 t.CheckOutputLines(
345 "AUTOFIX: ~/options.mk:3: Replacing \".\" with \". \".", 345 "AUTOFIX: ~/options.mk:3: Replacing \".\" with \". \".",
346 "AUTOFIX: ~/options.mk:5: Replacing \".\" with \". \".") 346 "AUTOFIX: ~/options.mk:5: Replacing \".\" with \". \".")
347 347
348 t.CheckFileLines("options.mk", 348 t.CheckFileLines("options.mk",
349 MkRcsId, 349 MkRcsID,
350 ".if ${PKGNAME} == pkgname", 350 ".if ${PKGNAME} == pkgname",
351 ". if \\", 351 ". if \\",
352 " ${PLATFORM:MNetBSD-4.*}", 352 " ${PLATFORM:MNetBSD-4.*}",
353 ". endif", 353 ". endif",
354 ".endif") 354 ".endif")
355} 355}
 356
 357func (s *Suite) Test_MkLineChecker_CheckVaruseShellword(c *check.C) {
 358 t := s.Init(c)
 359
 360 t.SetupCommandLine("-Wall")
 361 G.globalData.InitVartypes()
 362 lines := t.SetupFileLinesContinuation("options.mk",
 363 MkRcsID,
 364 "GOPATH=\t${WRKDIR}",
 365 "do-build:",
 366 "\tcd ${WRKSRC} && GOPATH=${GOPATH} PATH=${PATH} :")
 367 mklines := NewMkLines(lines)
 368
 369 mklines.Check()
 370
 371 // For WRKSRC and GOPATH, no quoting is necessary since pkgsrc directories by
 372 // definition don't contain special characters. Therefore they don't need the
 373 // :Q, not even when used as part of a shell word.
 374
 375 // For PATH, the quoting is necessary because it may contain directories outside
 376 // of pkgsrc, and these may contain special characters.
 377
 378 t.CheckOutputLines(
 379 "WARN: ~/options.mk:4: The variable PATH should be quoted as part of a shell word.")
 380}

cvs diff -r1.6 -r1.7 pkgsrc/pkgtools/pkglint/files/Attic/shtypes.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/shtypes.go 2018/01/07 01:13:21 1.6
+++ pkgsrc/pkgtools/pkglint/files/Attic/shtypes.go 2018/02/19 12:40:38 1.7
@@ -1,30 +1,30 @@ @@ -1,30 +1,30 @@
1package main 1package main
2 2
3import ( 3import (
4 "fmt" 4 "fmt"
5) 5)
6 6
7//go:generate goyacc -o shellyacc.go -v shellyacc.log -p shyy shell.y 7//go:generate goyacc -o shellyacc.go -v shellyacc.log -p shyy shell.y
8 8
9type ShAtomType uint8 9type ShAtomType uint8
10 10
11const ( 11const (
12 shtSpace ShAtomType = iota 12 shtSpace ShAtomType = iota
13 shtVaruse // ${PREFIX} 13 shtVaruse // ${PREFIX}
14 shtWord // 14 shtWord // while, cat, ENV=value
15 shtOperator 15 shtOperator // (, ;, |
16 shtComment // # ... 16 shtComment // # ...
17 shtSubshell // $$( 17 shtSubshell // $$(
18) 18)
19 19
20func (t ShAtomType) String() string { 20func (t ShAtomType) String() string {
21 return [...]string{ 21 return [...]string{
22 "space", 22 "space",
23 "varuse", 23 "varuse",
24 "word", 24 "word",
25 "operator", 25 "operator",
26 "comment", 26 "comment",
27 "subshell", 27 "subshell",
28 }[t] 28 }[t]
29} 29}
30 30
@@ -46,29 +46,29 @@ type ShAtom struct { @@ -46,29 +46,29 @@ type ShAtom struct {
46 46
47func (token *ShAtom) String() string { 47func (token *ShAtom) String() string {
48 if token.Type == shtWord && token.Quoting == shqPlain && token.Data == nil { 48 if token.Type == shtWord && token.Quoting == shqPlain && token.Data == nil {
49 return fmt.Sprintf("%q", token.MkText) 49 return fmt.Sprintf("%q", token.MkText)
50 } 50 }
51 if token.Type == shtVaruse { 51 if token.Type == shtVaruse {
52 varuse := token.Data.(*MkVarUse) 52 varuse := token.Data.(*MkVarUse)
53 return fmt.Sprintf("varuse(%q)", varuse.varname+varuse.Mod()) 53 return fmt.Sprintf("varuse(%q)", varuse.varname+varuse.Mod())
54 } 54 }
55 return fmt.Sprintf("ShAtom(%v, %q, %s)", token.Type, token.MkText, token.Quoting) 55 return fmt.Sprintf("ShAtom(%v, %q, %s)", token.Type, token.MkText, token.Quoting)
56} 56}
57 57
58// Returns nil for plain shell tokens. 58// Returns nil for plain shell tokens.
59func (atom *ShAtom) VarUse() *MkVarUse { 59func (token *ShAtom) VarUse() *MkVarUse {
60 if atom.Type == shtVaruse { 60 if token.Type == shtVaruse {
61 return atom.Data.(*MkVarUse) 61 return token.Data.(*MkVarUse)
62 } 62 }
63 return nil 63 return nil
64} 64}
65 65
66// ShQuoting describes the context in which a string appears 66// ShQuoting describes the context in which a string appears
67// and how it must be unescaped to get its literal value. 67// and how it must be unescaped to get its literal value.
68type ShQuoting uint8 68type ShQuoting uint8
69 69
70const ( 70const (
71 shqPlain ShQuoting = iota 71 shqPlain ShQuoting = iota
72 shqDquot 72 shqDquot
73 shqSquot 73 shqSquot
74 shqBackt 74 shqBackt
@@ -107,21 +107,13 @@ func (q ShQuoting) ToVarUseContext() vuc @@ -107,21 +107,13 @@ func (q ShQuoting) ToVarUseContext() vuc
107// See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_10_02 107// See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_10_02
108type ShToken struct { 108type ShToken struct {
109 MkText string // The text as it appeared in the Makefile, after replacing `\#` with `#` 109 MkText string // The text as it appeared in the Makefile, after replacing `\#` with `#`
110 Atoms []*ShAtom 110 Atoms []*ShAtom
111} 111}
112 112
113func NewShToken(mkText string, atoms ...*ShAtom) *ShToken { 113func NewShToken(mkText string, atoms ...*ShAtom) *ShToken {
114 return &ShToken{mkText, atoms} 114 return &ShToken{mkText, atoms}
115} 115}
116 116
117func (token *ShToken) String() string { 117func (token *ShToken) String() string {
118 return fmt.Sprintf("ShToken(%v)", token.Atoms) 118 return fmt.Sprintf("ShToken(%v)", token.Atoms)
119} 119}
120 
121func (token *ShToken) IsAssignment() bool { 
122 return matches(token.MkText, `^[A-Za-z_]\w*=`) 
123} 
124 
125func (token *ShToken) IsWord() bool { 
126 return token.Atoms[0].Type.IsWord() 
127} 

cvs diff -r1.17 -r1.18 pkgsrc/pkgtools/pkglint/files/Attic/package_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/package_test.go 2018/01/27 18:50:36 1.17
+++ pkgsrc/pkgtools/pkglint/files/Attic/package_test.go 2018/02/19 12:40:38 1.18
@@ -11,102 +11,250 @@ func (s *Suite) Test_Package_pkgnameFrom @@ -11,102 +11,250 @@ func (s *Suite) Test_Package_pkgnameFrom
11 c.Check(pkg.pkgnameFromDistname("pkgname-1.0", "whatever"), equals, "pkgname-1.0") 11 c.Check(pkg.pkgnameFromDistname("pkgname-1.0", "whatever"), equals, "pkgname-1.0")
12 c.Check(pkg.pkgnameFromDistname("${DISTNAME}", "distname-1.0"), equals, "distname-1.0") 12 c.Check(pkg.pkgnameFromDistname("${DISTNAME}", "distname-1.0"), equals, "distname-1.0")
13 c.Check(pkg.pkgnameFromDistname("${DISTNAME:S/dist/pkg/}", "distname-1.0"), equals, "pkgname-1.0") 13 c.Check(pkg.pkgnameFromDistname("${DISTNAME:S/dist/pkg/}", "distname-1.0"), equals, "pkgname-1.0")
14 c.Check(pkg.pkgnameFromDistname("${DISTNAME:S|a|b|g}", "panama-0.13"), equals, "pbnbmb-0.13") 14 c.Check(pkg.pkgnameFromDistname("${DISTNAME:S|a|b|g}", "panama-0.13"), equals, "pbnbmb-0.13")
15 c.Check(pkg.pkgnameFromDistname("${DISTNAME:S|^lib||}", "libncurses"), equals, "ncurses") 15 c.Check(pkg.pkgnameFromDistname("${DISTNAME:S|^lib||}", "libncurses"), equals, "ncurses")
16 c.Check(pkg.pkgnameFromDistname("${DISTNAME:S|^lib||}", "mylib"), equals, "mylib") 16 c.Check(pkg.pkgnameFromDistname("${DISTNAME:S|^lib||}", "mylib"), equals, "mylib")
17 c.Check(pkg.pkgnameFromDistname("${DISTNAME:tl:S/-/./g:S/he/-/1}", "SaxonHE9-5-0-1J"), equals, "saxon-9.5.0.1j") 17 c.Check(pkg.pkgnameFromDistname("${DISTNAME:tl:S/-/./g:S/he/-/1}", "SaxonHE9-5-0-1J"), equals, "saxon-9.5.0.1j")
18 c.Check(pkg.pkgnameFromDistname("${DISTNAME:C/beta/.0./}", "fspanel-0.8beta1"), equals, "${DISTNAME:C/beta/.0./}") 18 c.Check(pkg.pkgnameFromDistname("${DISTNAME:C/beta/.0./}", "fspanel-0.8beta1"), equals, "${DISTNAME:C/beta/.0./}")
19 c.Check(pkg.pkgnameFromDistname("${DISTNAME:S/-0$/.0/1}", "aspell-af-0.50-0"), equals, "aspell-af-0.50.0") 19 c.Check(pkg.pkgnameFromDistname("${DISTNAME:S/-0$/.0/1}", "aspell-af-0.50-0"), equals, "aspell-af-0.50.0")
20 20
21 t.CheckOutputEmpty() 21 t.CheckOutputEmpty()
22} 22}
23 23
24func (s *Suite) Test_Package_ChecklinesPackageMakefileVarorder(c *check.C) { 24func (s *Suite) Test_Package_CheckVarorder(c *check.C) {
25 t := s.Init(c) 25 t := s.Init(c)
26 26
27 t.SetupCommandLine("-Worder") 27 t.SetupCommandLine("-Worder")
28 pkg := NewPackage("x11/9term") 28 pkg := NewPackage("x11/9term")
29 29
30 pkg.ChecklinesPackageMakefileVarorder(t.NewMkLines("Makefile", 30 pkg.CheckVarorder(t.NewMkLines("Makefile",
31 MkRcsId, 31 MkRcsID,
32 "", 32 "",
 33 "GITHUB_PROJECT=project",
33 "DISTNAME=9term", 34 "DISTNAME=9term",
34 "CATEGORIES=x11")) 35 "CATEGORIES=x11"))
35 36
36 t.CheckOutputEmpty() 37 t.CheckOutputLines(
 38 "WARN: Makefile:3: The canonical order of the variables is " +
 39 "GITHUB_PROJECT, DISTNAME, CATEGORIES, GITHUB_PROJECT, empty line, COMMENT, LICENSE.")
37 40
38 pkg.ChecklinesPackageMakefileVarorder(t.NewMkLines("Makefile", 41 pkg.CheckVarorder(t.NewMkLines("Makefile",
39 MkRcsId, 42 MkRcsID,
40 "", 43 "",
41 "DISTNAME=9term", 44 "DISTNAME=9term",
42 "CATEGORIES=x11", 45 "CATEGORIES=x11",
43 "", 46 "",
44 ".include \"../../mk/bsd.pkg.mk\"")) 47 ".include \"../../mk/bsd.pkg.mk\""))
45 48
46 t.CheckOutputLines( 49 t.CheckOutputLines(
47 "WARN: Makefile:6: The canonical position for the required variable COMMENT is here.", 50 "WARN: Makefile:3: The canonical order of the variables is " +
48 "WARN: Makefile:6: The canonical position for the required variable LICENSE is here.") 51 "DISTNAME, CATEGORIES, empty line, COMMENT, LICENSE.")
 52}
 53
 54// Ensure that comments and empty lines do not lead to panics.
 55func (s *Suite) Test_Package_CheckVarorder__comments_do_not_crash(c *check.C) {
 56 t := s.Init(c)
 57
 58 t.SetupCommandLine("-Worder")
 59 pkg := NewPackage("x11/9term")
 60
 61 pkg.CheckVarorder(t.NewMkLines("Makefile",
 62 MkRcsID,
 63 "",
 64 "GITHUB_PROJECT=project",
 65 "",
 66 "# comment",
 67 "",
 68 "DISTNAME=9term",
 69 "# comment",
 70 "CATEGORIES=x11"))
 71
 72 t.CheckOutputLines(
 73 "WARN: Makefile:3: The canonical order of the variables is " +
 74 "GITHUB_PROJECT, DISTNAME, CATEGORIES, GITHUB_PROJECT, empty line, COMMENT, LICENSE.")
 75}
 76
 77func (s *Suite) Test_Package_CheckVarorder__comments_are_ignored(c *check.C) {
 78 t := s.Init(c)
 79
 80 t.SetupCommandLine("-Worder")
 81
 82 pkg := NewPackage("x11/9term")
 83
 84 pkg.CheckVarorder(t.NewMkLines("Makefile",
 85 MkRcsID,
 86 "",
 87 "DISTNAME=\tdistname-1.0",
 88 "CATEGORIES=\tsysutils",
 89 "",
 90 "MAINTAINER=\tpkgsrc-users@pkgsrc.org",
 91 "# comment",
 92 "COMMENT=\tComment",
 93 "LICENSE=\tgnu-gpl-v2"))
 94
 95 t.CheckOutputEmpty()
 96}
 97
 98func (s *Suite) Test_Package_CheckVarorder__conditionals_skip(c *check.C) {
 99 t := s.Init(c)
 100
 101 t.SetupCommandLine("-Worder")
 102
 103 pkg := NewPackage("x11/9term")
 104
 105 pkg.CheckVarorder(t.NewMkLines("Makefile",
 106 MkRcsID,
 107 "",
 108 "DISTNAME=\tdistname-1.0",
 109 "CATEGORIES=\tsysutils",
 110 "",
 111 ".if ${DISTNAME:Mdistname-*}",
 112 "MAINTAINER=\tpkgsrc-users@pkgsrc.org",
 113 ".endif",
 114 "LICENSE=\tgnu-gpl-v2"))
 115
 116 // No warning about the missing COMMENT since the conditional
 117 // skips the whole check.
 118 t.CheckOutputEmpty()
 119}
 120
 121func (s *Suite) Test_Package_CheckVarorder_GitHub(c *check.C) {
 122 t := s.Init(c)
 123
 124 t.SetupCommandLine("-Worder")
 125 pkg := NewPackage("x11/9term")
 126
 127 pkg.CheckVarorder(t.NewMkLines("Makefile",
 128 MkRcsID,
 129 "",
 130 "DISTNAME=\t\tautocutsel-0.10.0",
 131 "CATEGORIES=\t\tx11",
 132 "MASTER_SITES=\t\t${MASTER_SITE_GITHUB:=sigmike/}",
 133 "GITHUB_PROJECT=\t\tautocutsel",
 134 "GITHUB_TAG=\t\t${PKGVERSION_NOREV}",
 135 "",
 136 "COMMENT=\tComment",
 137 "LICENSE=\tgnu-gpl-v2"))
 138
 139 t.CheckOutputEmpty()
49} 140}
50 141
51func (s *Suite) Test_Package_varorder_license(c *check.C) { 142func (s *Suite) Test_Package_varorder_license(c *check.C) {
52 t := s.Init(c) 143 t := s.Init(c)
53 144
54 t.SetupCommandLine("-Worder") 145 t.SetupCommandLine("-Worder")
55 146
56 t.CreateFileLines("mk/bsd.pkg.mk", "# dummy") 147 t.CreateFileLines("mk/bsd.pkg.mk", "# dummy")
57 t.CreateFileLines("x11/Makefile", MkRcsId) 148 t.CreateFileLines("x11/Makefile", MkRcsID)
58 t.CreateFileLines("x11/9term/PLIST", PlistRcsId, "bin/9term") 149 t.CreateFileLines("x11/9term/PLIST", PlistRcsID, "bin/9term")
59 t.CreateFileLines("x11/9term/distinfo", RcsId) 150 t.CreateFileLines("x11/9term/distinfo", RcsID)
60 t.CreateFileLines("x11/9term/Makefile", 151 t.CreateFileLines("x11/9term/Makefile",
61 MkRcsId, 152 MkRcsID,
62 "", 153 "",
63 "DISTNAME=9term-1.0", 154 "DISTNAME=9term-1.0",
64 "CATEGORIES=x11", 155 "CATEGORIES=x11",
65 "", 156 "",
66 "COMMENT=Terminal", 157 "COMMENT=Terminal",
67 "", 158 "",
68 ".include \"../../mk/bsd.pkg.mk\"") 159 ".include \"../../mk/bsd.pkg.mk\"")
69 160
70 G.globalData.InitVartypes() 161 G.globalData.InitVartypes()
71 G.globalData.Pkgsrcdir = t.TmpDir() 162 G.globalData.Pkgsrcdir = t.TmpDir()
72 G.CurrentDir = t.TmpDir() 163 G.CurrentDir = t.TmpDir()
73 164
74 (&Pkglint{}).CheckDirent(t.TmpDir() + "/x11/9term") 165 (&Pkglint{}).CheckDirent(t.TmpDir() + "/x11/9term")
75 166
76 // Since the error is grave enough, the warning about the correct position is suppressed. 167 // Since the error is grave enough, the warning about the correct position is suppressed.
77 t.CheckOutputLines( 168 t.CheckOutputLines(
78 "ERROR: ~/x11/9term/Makefile: Each package must define its LICENSE.") 169 "ERROR: ~/x11/9term/Makefile: Each package must define its LICENSE.")
79} 170}
80 171
81// https://mail-index.netbsd.org/tech-pkg/2017/01/18/msg017698.html 172// https://mail-index.netbsd.org/tech-pkg/2017/01/18/msg017698.html
82func (s *Suite) Test_Package_ChecklinesPackageMakefileVarorder__MASTER_SITES(c *check.C) { 173func (s *Suite) Test_Package_CheckVarorder__MASTER_SITES(c *check.C) {
83 t := s.Init(c) 174 t := s.Init(c)
84 175
85 t.SetupCommandLine("-Worder") 176 t.SetupCommandLine("-Worder")
86 pkg := NewPackage("category/package") 177 pkg := NewPackage("category/package")
87 178
88 pkg.ChecklinesPackageMakefileVarorder(t.NewMkLines("Makefile", 179 pkg.CheckVarorder(t.NewMkLines("Makefile",
89 MkRcsId, 180 MkRcsID,
90 "", 181 "",
91 "PKGNAME=\tpackage-1.0", 182 "PKGNAME=\tpackage-1.0",
92 "CATEGORIES=\tcategory", 183 "CATEGORIES=\tcategory",
93 "MASTER_SITES=\thttp://example.org/", 184 "MASTER_SITES=\thttp://example.org/",
94 "MASTER_SITES+=\thttp://mirror.example.org/")) 185 "MASTER_SITES+=\thttp://mirror.example.org/",
 186 "",
 187 "COMMENT=\tComment",
 188 "LICENSE=\tgnu-gpl-v2"))
95 189
96 // No warning that "MASTER_SITES appears too late" 190 // No warning that "MASTER_SITES appears too late"
97 t.CheckOutputEmpty() 191 t.CheckOutputEmpty()
98} 192}
99 193
 194// The diagnostics must be helpful.
 195// In the case of wip/ioping, they were ambiguous and wrong.
 196func (s *Suite) Test_Package_CheckVarorder__diagnostics(c *check.C) {
 197 t := s.Init(c)
 198
 199 t.SetupCommandLine("-Worder")
 200 G.globalData.InitVartypes()
 201 pkg := NewPackage("category/package")
 202
 203 pkg.CheckVarorder(t.NewMkLines("Makefile",
 204 MkRcsID,
 205 "",
 206 "CATEGORIES= net",
 207 "",
 208 "COMMENT= Comment",
 209 "LICENSE= gnu-gpl-v3",
 210 "",
 211 "GITHUB_PROJECT= pkgbase",
 212 "DISTNAME= v1.0",
 213 "PKGNAME= ${GITHUB_PROJECT}-${DISTNAME}",
 214 "MASTER_SITES= ${MASTER_SITE_GITHUB:=project/}",
 215 "DIST_SUBDIR= ${GITHUB_PROJECT}",
 216 "",
 217 "MAINTAINER= maintainer@example.org",
 218 "HOMEPAGE= https://github.com/project/pkgbase/",
 219 "",
 220 ".include \"../../mk/bsd.pkg.mk\""))
 221
 222 t.CheckOutputLines(
 223 "WARN: Makefile:3: The canonical order of the variables is " +
 224 "GITHUB_PROJECT, DISTNAME, PKGNAME, CATEGORIES, MASTER_SITES, GITHUB_PROJECT, DIST_SUBDIR, empty line, " +
 225 "MAINTAINER, HOMEPAGE, COMMENT, LICENSE.")
 226
 227 // After moving the variables according to the warning:
 228 pkg.CheckVarorder(t.NewMkLines("Makefile",
 229 MkRcsID,
 230 "",
 231 "GITHUB_PROJECT= pkgbase",
 232 "DISTNAME= v1.0",
 233 "PKGNAME= ${GITHUB_PROJECT}-${DISTNAME}",
 234 "CATEGORIES= net",
 235 "MASTER_SITES= ${MASTER_SITE_GITHUB:=project/}",
 236 "DIST_SUBDIR= ${GITHUB_PROJECT}",
 237 "",
 238 "MAINTAINER= maintainer@example.org",
 239 "HOMEPAGE= https://github.com/project/pkgbase/",
 240 "COMMENT= Comment",
 241 "LICENSE= gnu-gpl-v3",
 242 "",
 243 ".include \"../../mk/bsd.pkg.mk\""))
 244
 245 t.CheckOutputEmpty()
 246}
 247
100func (s *Suite) Test_Package_getNbpart(c *check.C) { 248func (s *Suite) Test_Package_getNbpart(c *check.C) {
101 t := s.Init(c) 249 t := s.Init(c)
102 250
103 pkg := NewPackage("category/pkgbase") 251 pkg := NewPackage("category/pkgbase")
104 pkg.vardef["PKGREVISION"] = t.NewMkLine("Makefile", 1, "PKGREVISION=14") 252 pkg.vardef["PKGREVISION"] = t.NewMkLine("Makefile", 1, "PKGREVISION=14")
105 253
106 c.Check(pkg.getNbpart(), equals, "nb14") 254 c.Check(pkg.getNbpart(), equals, "nb14")
107 255
108 pkg.vardef["PKGREVISION"] = t.NewMkLine("Makefile", 1, "PKGREVISION=asdf") 256 pkg.vardef["PKGREVISION"] = t.NewMkLine("Makefile", 1, "PKGREVISION=asdf")
109 257
110 c.Check(pkg.getNbpart(), equals, "") 258 c.Check(pkg.getNbpart(), equals, "")
111} 259}
112 260
@@ -150,43 +298,43 @@ func (s *Suite) Test_Package_checkPossib @@ -150,43 +298,43 @@ func (s *Suite) Test_Package_checkPossib
150 "WARN: category/pkgbase/Makefile:5: The package is being downgraded from 1.8 (see ../../doc/CHANGES:116) to 1.0nb15") 298 "WARN: category/pkgbase/Makefile:5: The package is being downgraded from 1.8 (see ../../doc/CHANGES:116) to 1.0nb15")
151 299
152 G.globalData.LastChange["category/pkgbase"].Version = "1.0nb22" 300 G.globalData.LastChange["category/pkgbase"].Version = "1.0nb22"
153 301
154 G.Pkg.checkPossibleDowngrade() 302 G.Pkg.checkPossibleDowngrade()
155 303
156 t.CheckOutputEmpty() 304 t.CheckOutputEmpty()
157} 305}
158 306
159func (s *Suite) Test_checkdirPackage(c *check.C) { 307func (s *Suite) Test_checkdirPackage(c *check.C) {
160 t := s.Init(c) 308 t := s.Init(c)
161 309
162 t.SetupFileLines("Makefile", 310 t.SetupFileLines("Makefile",
163 MkRcsId) 311 MkRcsID)
164 G.CurrentDir = t.TmpDir() 312 G.CurrentDir = t.TmpDir()
165 313
166 checkdirPackage(t.TmpDir()) 314 checkdirPackage(t.TmpDir())
167 315
168 t.CheckOutputLines( 316 t.CheckOutputLines(
169 "WARN: ~/Makefile: Neither PLIST nor PLIST.common exist, and PLIST_SRC is unset. Are you sure PLIST handling is ok?", 317 "WARN: ~/Makefile: Neither PLIST nor PLIST.common exist, and PLIST_SRC is unset. Are you sure PLIST handling is ok?",
170 "WARN: ~/distinfo: File not found. Please run \"@BMAKE@ makesum\".", 318 "WARN: ~/distinfo: File not found. Please run \"@BMAKE@ makesum\".",
171 "ERROR: ~/Makefile: Each package must define its LICENSE.", 319 "ERROR: ~/Makefile: Each package must define its LICENSE.",
172 "WARN: ~/Makefile: No COMMENT given.") 320 "WARN: ~/Makefile: No COMMENT given.")
173} 321}
174 322
175func (s *Suite) Test_checkdirPackage__meta_package_without_license(c *check.C) { 323func (s *Suite) Test_checkdirPackage__meta_package_without_license(c *check.C) {
176 t := s.Init(c) 324 t := s.Init(c)
177 325
178 t.CreateFileLines("Makefile", 326 t.CreateFileLines("Makefile",
179 MkRcsId, 327 MkRcsID,
180 "", 328 "",
181 "META_PACKAGE=\tyes") 329 "META_PACKAGE=\tyes")
182 G.CurrentDir = t.TmpDir() 330 G.CurrentDir = t.TmpDir()
183 G.globalData.InitVartypes() 331 G.globalData.InitVartypes()
184 332
185 checkdirPackage(t.TmpDir()) 333 checkdirPackage(t.TmpDir())
186 334
187 t.CheckOutputLines( 335 t.CheckOutputLines(
188 "WARN: ~/Makefile: No COMMENT given.") // No error about missing LICENSE. 336 "WARN: ~/Makefile: No COMMENT given.") // No error about missing LICENSE.
189} 337}
190 338
191func (s *Suite) Test_Package__varuse_at_load_time(c *check.C) { 339func (s *Suite) Test_Package__varuse_at_load_time(c *check.C) {
192 t := s.Init(c) 340 t := s.Init(c)
@@ -206,109 +354,109 @@ func (s *Suite) Test_Package__varuse_at_ @@ -206,109 +354,109 @@ func (s *Suite) Test_Package__varuse_at_
206 t.CreateFileLines("mk/defaults/mk.conf", 354 t.CreateFileLines("mk/defaults/mk.conf",
207 "# dummy") 355 "# dummy")
208 t.CreateFileLines("mk/tools/bsd.tools.mk", 356 t.CreateFileLines("mk/tools/bsd.tools.mk",
209 ".include \"defaults.mk\"") 357 ".include \"defaults.mk\"")
210 t.CreateFileLines("mk/tools/defaults.mk", 358 t.CreateFileLines("mk/tools/defaults.mk",
211 "TOOLS_CREATE+=false", 359 "TOOLS_CREATE+=false",
212 "TOOLS_CREATE+=nice", 360 "TOOLS_CREATE+=nice",
213 "TOOLS_CREATE+=true", 361 "TOOLS_CREATE+=true",
214 "_TOOLS_VARNAME.nice=NICE") 362 "_TOOLS_VARNAME.nice=NICE")
215 t.CreateFileLines("mk/bsd.prefs.mk", 363 t.CreateFileLines("mk/bsd.prefs.mk",
216 "# dummy") 364 "# dummy")
217 365
218 t.CreateFileLines("category/pkgbase/Makefile", 366 t.CreateFileLines("category/pkgbase/Makefile",
219 MkRcsId, 367 MkRcsID,
220 "", 368 "",
221 "COMMENT= Unit test", 369 "COMMENT= Unit test",
222 "LICENSE= bsd-2", 370 "LICENSE= bsd-2",
223 "PLIST_SRC=#none", 371 "PLIST_SRC=#none",
224 "", 372 "",
225 "USE_TOOLS+= echo false", 373 "USE_TOOLS+= echo false",
226 "FALSE_BEFORE!= echo false=${FALSE}", 374 "FALSE_BEFORE!= echo false=${FALSE}",
227 "NICE_BEFORE!= echo nice=${NICE}", 375 "NICE_BEFORE!= echo nice=${NICE}",
228 "TRUE_BEFORE!= echo true=${TRUE}", 376 "TRUE_BEFORE!= echo true=${TRUE}",
229 "", 377 "",
230 ".include \"../../mk/bsd.prefs.mk\"", 378 ".include \"../../mk/bsd.prefs.mk\"",
231 "", 379 "",
232 "USE_TOOLS+= nice", 380 "USE_TOOLS+= nice",
233 "FALSE_AFTER!= echo false=${FALSE}", 381 "FALSE_AFTER!= echo false=${FALSE}",
234 "NICE_AFTER!= echo nice=${NICE}", 382 "NICE_AFTER!= echo nice=${NICE}",
235 "TRUE_AFTER!= echo true=${TRUE}", 383 "TRUE_AFTER!= echo true=${TRUE}",
236 "", 384 "",
237 "do-build:", 385 "do-build:",
238 "\t${ECHO} before: ${FALSE_BEFORE} ${NICE_BEFORE} ${TRUE_BEFORE}", 386 "\t${ECHO} before: ${FALSE_BEFORE} ${NICE_BEFORE} ${TRUE_BEFORE}",
239 "\t${ECHO} after: ${FALSE_AFTER} ${NICE_AFTER} ${TRUE_AFTER}", 387 "\t${ECHO} after: ${FALSE_AFTER} ${NICE_AFTER} ${TRUE_AFTER}",
240 "\t${ECHO}; ${FALSE}; ${NICE}; ${TRUE}", 388 "\t${ECHO}; ${FALSE}; ${NICE}; ${TRUE}",
241 "", 389 "",
242 ".include \"../../mk/bsd.pkg.mk\"") 390 ".include \"../../mk/bsd.pkg.mk\"")
243 t.CreateFileLines("category/pkgbase/distinfo", 391 t.CreateFileLines("category/pkgbase/distinfo",
244 RcsId) 392 RcsID)
245 393
246 (&Pkglint{}).Main("pkglint", "-q", "-Wperm", t.TmpDir()+"/category/pkgbase") 394 (&Pkglint{}).Main("pkglint", "-q", "-Wperm", t.TmpDir()+"/category/pkgbase")
247 395
248 t.CheckOutputLines( 396 t.CheckOutputLines(
249 "WARN: ~/category/pkgbase/Makefile:8: To use the tool \"FALSE\" at load time, bsd.prefs.mk has to be included before.", 397 "WARN: ~/category/pkgbase/Makefile:8: To use the tool \"FALSE\" at load time, bsd.prefs.mk has to be included before.",
250 "WARN: ~/category/pkgbase/Makefile:9: To use the tool \"NICE\" at load time, bsd.prefs.mk has to be included before.", 398 "WARN: ~/category/pkgbase/Makefile:9: To use the tool \"NICE\" at load time, bsd.prefs.mk has to be included before.",
251 "WARN: ~/category/pkgbase/Makefile:10: To use the tool \"TRUE\" at load time, bsd.prefs.mk has to be included before.", 399 "WARN: ~/category/pkgbase/Makefile:10: To use the tool \"TRUE\" at load time, bsd.prefs.mk has to be included before.",
252 "WARN: ~/category/pkgbase/Makefile:16: To use the tool \"NICE\" at load time, it has to be added to USE_TOOLS before including bsd.prefs.mk.") 400 "WARN: ~/category/pkgbase/Makefile:16: To use the tool \"NICE\" at load time, it has to be added to USE_TOOLS before including bsd.prefs.mk.")
253} 401}
254 402
255func (s *Suite) Test_Package_loadPackageMakefile(c *check.C) { 403func (s *Suite) Test_Package_loadPackageMakefile(c *check.C) {
256 t := s.Init(c) 404 t := s.Init(c)
257 405
258 t.SetupFileLines("category/package/Makefile", 406 t.SetupFileLines("category/package/Makefile",
259 MkRcsId, 407 MkRcsID,
260 "", 408 "",
261 "PKGNAME=pkgname-1.67", 409 "PKGNAME=pkgname-1.67",
262 "DISTNAME=distfile_1_67", 410 "DISTNAME=distfile_1_67",
263 ".include \"../../category/package/Makefile\"") 411 ".include \"../../category/package/Makefile\"")
264 pkg := NewPackage("category/package") 412 pkg := NewPackage("category/package")
265 G.CurrentDir = t.TempFilename("category/package") 413 G.CurrentDir = t.TempFilename("category/package")
266 G.CurPkgsrcdir = "../.." 414 G.CurPkgsrcdir = "../.."
267 G.Pkg = pkg 415 G.Pkg = pkg
268 416
269 pkg.loadPackageMakefile(t.TempFilename("category/package/Makefile")) 417 pkg.loadPackageMakefile(t.TempFilename("category/package/Makefile"))
270 418
271 // Including a package Makefile directly is an error (in the last line), 419 // Including a package Makefile directly is an error (in the last line),
272 // but that is checked later. 420 // but that is checked later.
273 t.CheckOutputEmpty() 421 t.CheckOutputEmpty()
274} 422}
275 423
276func (s *Suite) Test_Package_conditionalAndUnconditionalInclude(c *check.C) { 424func (s *Suite) Test_Package_conditionalAndUnconditionalInclude(c *check.C) {
277 t := s.Init(c) 425 t := s.Init(c)
278 426
279 G.globalData.InitVartypes() 427 G.globalData.InitVartypes()
280 t.CreateFileLines("category/package/Makefile", 428 t.CreateFileLines("category/package/Makefile",
281 MkRcsId, 429 MkRcsID,
282 "", 430 "",
283 "COMMENT\t=Description", 431 "COMMENT\t=Description",
284 "LICENSE\t= gnu-gpl-v2", 432 "LICENSE\t= gnu-gpl-v2",
285 ".include \"../../devel/zlib/buildlink3.mk\"", 433 ".include \"../../devel/zlib/buildlink3.mk\"",
286 ".if ${OPSYS} == \"Linux\"", 434 ".if ${OPSYS} == \"Linux\"",
287 ".include \"../../sysutils/coreutils/buildlink3.mk\"", 435 ".include \"../../sysutils/coreutils/buildlink3.mk\"",
288 ".endif", 436 ".endif",
289 ".include \"../../mk/bsd.pkg.mk\"") 437 ".include \"../../mk/bsd.pkg.mk\"")
290 t.CreateFileLines("category/package/options.mk", 438 t.CreateFileLines("category/package/options.mk",
291 MkRcsId, 439 MkRcsID,
292 "", 440 "",
293 ".if !empty(PKG_OPTIONS:Mzlib)", 441 ".if !empty(PKG_OPTIONS:Mzlib)",
294 ". include \"../../devel/zlib/buildlink3.mk\"", 442 ". include \"../../devel/zlib/buildlink3.mk\"",
295 ".endif", 443 ".endif",
296 ".include \"../../sysutils/coreutils/buildlink3.mk\"") 444 ".include \"../../sysutils/coreutils/buildlink3.mk\"")
297 t.CreateFileLines("category/package/PLIST", 445 t.CreateFileLines("category/package/PLIST",
298 PlistRcsId, 446 PlistRcsID,
299 "bin/program") 447 "bin/program")
300 t.CreateFileLines("category/package/distinfo", 448 t.CreateFileLines("category/package/distinfo",
301 RcsId) 449 RcsID)
302 450
303 t.CreateFileLines("devel/zlib/buildlink3.mk", "") 451 t.CreateFileLines("devel/zlib/buildlink3.mk", "")
304 t.CreateFileLines("licenses/gnu-gpl-v2", "") 452 t.CreateFileLines("licenses/gnu-gpl-v2", "")
305 t.CreateFileLines("mk/bsd.pkg.mk", "") 453 t.CreateFileLines("mk/bsd.pkg.mk", "")
306 t.CreateFileLines("sysutils/coreutils/buildlink3.mk", "") 454 t.CreateFileLines("sysutils/coreutils/buildlink3.mk", "")
307 455
308 pkg := NewPackage("category/package") 456 pkg := NewPackage("category/package")
309 G.globalData.Pkgsrcdir = t.TmpDir() 457 G.globalData.Pkgsrcdir = t.TmpDir()
310 G.CurrentDir = t.TmpDir() + "/category/package" 458 G.CurrentDir = t.TmpDir() + "/category/package"
311 G.CurPkgsrcdir = "../.." 459 G.CurPkgsrcdir = "../.."
312 G.Pkg = pkg 460 G.Pkg = pkg
313 461
314 checkdirPackage("category/package") 462 checkdirPackage("category/package")

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

--- pkgsrc/pkgtools/pkglint/files/Attic/patches.go 2018/01/28 23:21:16 1.19
+++ pkgsrc/pkgtools/pkglint/files/Attic/patches.go 2018/02/19 12:40:38 1.20
@@ -115,50 +115,60 @@ func (ck *PatchChecker) checkUnifiedDiff @@ -115,50 +115,60 @@ func (ck *PatchChecker) checkUnifiedDiff
115 trace.Stepf("guessFileType(%q) = %s", patchedFile, patchedFileType) 115 trace.Stepf("guessFileType(%q) = %s", patchedFile, patchedFileType)
116 } 116 }
117 117
118 hasHunks := false 118 hasHunks := false
119 for ck.exp.AdvanceIfMatches(rePatchUniHunk) { 119 for ck.exp.AdvanceIfMatches(rePatchUniHunk) {
120 hasHunks = true 120 hasHunks = true
121 linesToDel := toInt(ck.exp.Group(2), 1) 121 linesToDel := toInt(ck.exp.Group(2), 1)
122 linesToAdd := toInt(ck.exp.Group(4), 1) 122 linesToAdd := toInt(ck.exp.Group(4), 1)
123 if trace.Tracing { 123 if trace.Tracing {
124 trace.Stepf("hunk -%d +%d", linesToDel, linesToAdd) 124 trace.Stepf("hunk -%d +%d", linesToDel, linesToAdd)
125 } 125 }
126 ck.checktextUniHunkCr() 126 ck.checktextUniHunkCr()
127 127
128 for linesToDel > 0 || linesToAdd > 0 || hasPrefix(ck.exp.CurrentLine().Text, "\\") { 128 for !ck.exp.EOF() && (linesToDel > 0 || linesToAdd > 0 || hasPrefix(ck.exp.CurrentLine().Text, "\\")) {
129 line := ck.exp.CurrentLine() 129 line := ck.exp.CurrentLine()
130 ck.exp.Advance() 130 ck.exp.Advance()
131 text := line.Text 131 text := line.Text
132 switch { 132 switch {
133 case text == "": 133 case text == "":
134 linesToDel-- 134 linesToDel--
135 linesToAdd-- 135 linesToAdd--
136 case hasPrefix(text, " "), hasPrefix(text, "\t"): 136 case hasPrefix(text, " "), hasPrefix(text, "\t"):
137 linesToDel-- 137 linesToDel--
138 linesToAdd-- 138 linesToAdd--
139 ck.checklineContext(text[1:], patchedFileType) 139 ck.checklineContext(text[1:], patchedFileType)
140 case hasPrefix(text, "-"): 140 case hasPrefix(text, "-"):
141 linesToDel-- 141 linesToDel--
142 case hasPrefix(text, "+"): 142 case hasPrefix(text, "+"):
143 linesToAdd-- 143 linesToAdd--
144 ck.checklineAdded(text[1:], patchedFileType) 144 ck.checklineAdded(text[1:], patchedFileType)
145 case hasPrefix(text, "\\"): 145 case hasPrefix(text, "\\"):
146 // \ No newline at end of file 146 // \ No newline at end of file
147 default: 147 default:
148 line.Errorf("Invalid line in unified patch hunk") 148 line.Errorf("Invalid line in unified patch hunk")
149 return 149 return
150 } 150 }
151 } 151 }
 152
 153 // When these two counts are equal, they may refer to context
 154 // lines that consist only of whitespace and have therefore
 155 // been lost during transmission. There is no way to detect
 156 // this by looking only at the patch file.
 157 if linesToAdd != linesToDel {
 158 line := ck.exp.PreviousLine()
 159 line.Warnf("Premature end of patch hunk (expected %d lines to be deleted and %d lines to be added)",
 160 linesToDel, linesToAdd)
 161 }
152 } 162 }
153 if !hasHunks { 163 if !hasHunks {
154 ck.exp.CurrentLine().Errorf("No patch hunks for %q.", patchedFile) 164 ck.exp.CurrentLine().Errorf("No patch hunks for %q.", patchedFile)
155 } 165 }
156 if !ck.exp.EOF() { 166 if !ck.exp.EOF() {
157 line := ck.exp.CurrentLine() 167 line := ck.exp.CurrentLine()
158 if !ck.isEmptyLine(line.Text) && !matches(line.Text, rePatchUniFileDel) { 168 if !ck.isEmptyLine(line.Text) && !matches(line.Text, rePatchUniFileDel) {
159 line.Warnf("Empty line or end of file expected.") 169 line.Warnf("Empty line or end of file expected.")
160 Explain( 170 Explain(
161 "This empty line makes the end of the patch clearly visible.", 171 "This empty line makes the end of the patch clearly visible.",
162 "Otherwise the reader would have to count lines to see where", 172 "Otherwise the reader would have to count lines to see where",
163 "the patch ends.") 173 "the patch ends.")
164 } 174 }

cvs diff -r1.26 -r1.27 pkgsrc/pkgtools/pkglint/files/Attic/pkglint.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/pkglint.go 2018/01/28 23:21:16 1.26
+++ pkgsrc/pkgtools/pkglint/files/Attic/pkglint.go 2018/02/19 12:40:38 1.27
@@ -16,26 +16,28 @@ import ( @@ -16,26 +16,28 @@ import (
16 16
17const confMake = "@BMAKE@" 17const confMake = "@BMAKE@"
18const confVersion = "@VERSION@" 18const confVersion = "@VERSION@"
19 19
20func main() { 20func main() {
21 G.logOut = NewSeparatorWriter(os.Stdout) 21 G.logOut = NewSeparatorWriter(os.Stdout)
22 G.logErr = NewSeparatorWriter(os.Stderr) 22 G.logErr = NewSeparatorWriter(os.Stderr)
23 trace.Out = os.Stdout 23 trace.Out = os.Stdout
24 os.Exit(new(Pkglint).Main(os.Args...)) 24 os.Exit(new(Pkglint).Main(os.Args...))
25} 25}
26 26
27type Pkglint struct{} 27type Pkglint struct{}
28 28
 29// Main runs the main program with the given arguments.
 30// args[0] is the program name.
29func (pkglint *Pkglint) Main(args ...string) (exitcode int) { 31func (pkglint *Pkglint) Main(args ...string) (exitcode int) {
30 defer func() { 32 defer func() {
31 if r := recover(); r != nil { 33 if r := recover(); r != nil {
32 if _, ok := r.(pkglintFatal); ok { 34 if _, ok := r.(pkglintFatal); ok {
33 exitcode = 1 35 exitcode = 1
34 } else { 36 } else {
35 panic(r) 37 panic(r)
36 } 38 }
37 } 39 }
38 }() 40 }()
39 41
40 if exitcode := pkglint.ParseCommandLine(args); exitcode != nil { 42 if exitcode := pkglint.ParseCommandLine(args); exitcode != nil {
41 return *exitcode 43 return *exitcode
@@ -471,27 +473,27 @@ func Checkfile(fname string) { @@ -471,27 +473,27 @@ func Checkfile(fname string) {
471 473
472 case hasPrefix(basename, "PLIST"): 474 case hasPrefix(basename, "PLIST"):
473 if G.opts.CheckPlist { 475 if G.opts.CheckPlist {
474 if lines := LoadNonemptyLines(fname, false); lines != nil { 476 if lines := LoadNonemptyLines(fname, false); lines != nil {
475 ChecklinesPlist(lines) 477 ChecklinesPlist(lines)
476 } 478 }
477 } 479 }
478 480
479 case basename == "TODO" || basename == "README": 481 case basename == "TODO" || basename == "README":
480 // Ok 482 // Ok
481 483
482 case hasPrefix(basename, "CHANGES-"): 484 case hasPrefix(basename, "CHANGES-"):
483 // This only checks the file, but doesn't register the changes globally. 485 // This only checks the file, but doesn't register the changes globally.
484 G.globalData.loadDocChangesFromFile(fname) 486 _ = G.globalData.loadDocChangesFromFile(fname)
485 487
486 case matches(fname, `(?:^|/)files/[^/]*$`): 488 case matches(fname, `(?:^|/)files/[^/]*$`):
487 // Skip 489 // Skip
488 490
489 case basename == "spec": 491 case basename == "spec":
490 // Ok in regression tests 492 // Ok in regression tests
491 493
492 default: 494 default:
493 NewLineWhole(fname).Warnf("Unexpected file found.") 495 NewLineWhole(fname).Warnf("Unexpected file found.")
494 if G.opts.CheckExtra { 496 if G.opts.CheckExtra {
495 CheckfileExtra(fname) 497 CheckfileExtra(fname)
496 } 498 }
497 } 499 }

cvs diff -r1.14 -r1.15 pkgsrc/pkgtools/pkglint/files/Attic/pkglint_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/pkglint_test.go 2018/01/28 23:21:16 1.14
+++ pkgsrc/pkgtools/pkglint/files/Attic/pkglint_test.go 2018/02/19 12:40:38 1.15
@@ -32,32 +32,242 @@ func (s *Suite) Test_Pkglint_Main_no_arg @@ -32,32 +32,242 @@ func (s *Suite) Test_Pkglint_Main_no_arg
32 32
33 exitcode := new(Pkglint).Main("pkglint") 33 exitcode := new(Pkglint).Main("pkglint")
34 34
35 c.Check(exitcode, equals, 1) 35 c.Check(exitcode, equals, 1)
36 t.CheckOutputLines( 36 t.CheckOutputLines(
37 "FATAL: \".\" is not inside a pkgsrc tree.") 37 "FATAL: \".\" is not inside a pkgsrc tree.")
38} 38}
39 39
40func (s *Suite) Test_Pkglint_Main__only(c *check.C) { 40func (s *Suite) Test_Pkglint_Main__only(c *check.C) {
41 t := s.Init(c) 41 t := s.Init(c)
42 42
43 exitcode := new(Pkglint).ParseCommandLine([]string{"pkglint", "-Wall", "-o", ":Q", "--version"}) 43 exitcode := new(Pkglint).ParseCommandLine([]string{"pkglint", "-Wall", "-o", ":Q", "--version"})
44 44
45 c.Check(exitcode, deepEquals, new(int)) 45 if c.Check(exitcode, check.NotNil) {
 46 c.Check(*exitcode, equals, 0)
 47 }
46 c.Check(G.opts.LogOnly, deepEquals, []string{":Q"}) 48 c.Check(G.opts.LogOnly, deepEquals, []string{":Q"})
47 t.CheckOutputLines( 49 t.CheckOutputLines(
48 "@VERSION@") 50 "@VERSION@")
49} 51}
50 52
 53func (s *Suite) Test_Pkglint_Main__unknown_option(c *check.C) {
 54 t := s.Init(c)
 55
 56 exitcode := new(Pkglint).Main("pkglint", "--unknown-option")
 57
 58 c.Check(exitcode, equals, 1)
 59 t.CheckOutputLines(
 60 "pkglint: unknown option: --unknown-option",
 61 "",
 62 "usage: pkglint [options] dir...",
 63 "",
 64 " -C, --check=check,... enable or disable specific checks",
 65 " -d, --debug log verbose call traces for debugging",
 66 " -e, --explain explain the diagnostics or give further help",
 67 " -f, --show-autofix show what pkglint can fix automatically",
 68 " -F, --autofix try to automatically fix some errors (experimental)",
 69 " -g, --gcc-output-format mimic the gcc output format",
 70 " -h, --help print a detailed usage message",
 71 " -I, --dumpmakefile dump the Makefile after parsing",
 72 " -i, --import prepare the import of a wip package",
 73 " -m, --log-verbose allow the same log message more than once",
 74 " -o, --only only log messages containing the given text",
 75 " -p, --profiling profile the executing program",
 76 " -q, --quiet don't print a summary line when finishing",
 77 " -r, --recursive check subdirectories, too",
 78 " -s, --source show the source lines together with diagnostics",
 79 " -V, --version print the version number of pkglint",
 80 " -W, --warning=warning,... enable or disable groups of warnings",
 81 "",
 82 " Flags for -C, --check:",
 83 " all all of the following",
 84 " none none of the following",
 85 " ALTERNATIVES check ALTERNATIVES files (enabled)",
 86 " bl3 check buildlink3.mk files (enabled)",
 87 " DESCR check DESCR file (enabled)",
 88 " distinfo check distinfo file (enabled)",
 89 " extra check various additional files (disabled)",
 90 " global inter-package checks (disabled)",
 91 " INSTALL check INSTALL and DEINSTALL scripts (enabled)",
 92 " Makefile check Makefiles (enabled)",
 93 " MESSAGE check MESSAGE file (enabled)",
 94 " mk check other .mk files (enabled)",
 95 " patches check patches (enabled)",
 96 " PLIST check PLIST files (enabled)",
 97 "",
 98 " Flags for -W, --warning:",
 99 " all all of the following",
 100 " none none of the following",
 101 " absname warn about use of absolute file names (enabled)",
 102 " directcmd warn about use of direct command names instead of Make variables (enabled)",
 103 " extra enable some extra warnings (disabled)",
 104 " order warn if Makefile entries are unordered (disabled)",
 105 " perm warn about unforeseen variable definition and use (disabled)",
 106 " plist-depr warn about deprecated paths in PLISTs (disabled)",
 107 " plist-sort warn about unsorted entries in PLISTs (disabled)",
 108 " quoting warn about quoting issues (disabled)",
 109 " space warn about inconsistent use of white-space (disabled)",
 110 " style warn about stylistic issues (disabled)",
 111 " types do some simple type checking in Makefiles (enabled)",
 112 "",
 113 " (Prefix a flag with \"no-\" to disable it.)")
 114}
 115
 116// Demonstrates which infrastructure files are necessary to actually run
 117// pkglint in a realistic scenario.
 118// For most tests, this setup is too much work, therefore they
 119// initialize only those parts of the infrastructure they really
 120// need.
 121//
 122// Especially covers Pkglint.PrintSummary and Pkglint.Checkfile.
 123func (s *Suite) Test_Pkglint_Main__complete_package(c *check.C) {
 124 t := s.Init(c)
 125
 126 // This file is needed to locate the pkgsrc root directory.
 127 // See findPkgsrcTopdir.
 128 t.CreateFileLines("mk/bsd.pkg.mk",
 129 "# dummy")
 130
 131 // See GlobalData.loadDocChanges.
 132 // FIXME: pkglint should warn that the latest version in this file
 133 // (1.10) doesn't match the current version in the package (1.11).
 134 t.CreateFileLines("doc/CHANGES-2018",
 135 RcsID,
 136 "",
 137 "Changes to the packages collection and infrastructure in 2018:",
 138 "",
 139 "\tUpdated sysutils/checkperms to 1.10 [rillig 2018-01-05]")
 140
 141 // See GlobalData.loadSuggestedUpdates.
 142 t.CreateFileLines("doc/TODO",
 143 RcsID,
 144 "",
 145 "Suggested package updates",
 146 "",
 147 "\to checkperms-1.13 [supports more file formats]")
 148
 149 // The LICENSE in the package Makefile is searched here.
 150 t.CreateFileLines("licenses/bsd-2",
 151 "# dummy")
 152
 153 // The MASTER_SITES in the package Makefile are searched here.
 154 // See GlobalData.loadDistSites.
 155 t.CreateFileLines("mk/fetch/sites.mk",
 156 MkRcsID,
 157 "",
 158 "MASTER_SITE_GITHUB+=\thttps://github.com/")
 159
 160 // The options for the PKG_OPTIONS framework must be readable.
 161 // See GlobalData.loadPkgOptions.
 162 t.CreateFileLines("mk/defaults/options.description",
 163 "option Description")
 164
 165 // The user-defined variables are read in to check for missing
 166 // BUILD_DEFS declarations in the package Makefile.
 167 t.CreateFileLines("mk/defaults/mk.conf",
 168 "# dummy")
 169
 170 // The tool definitions are read in to check for missing
 171 // USE_TOOLS declarations in the package Makefile.
 172 // They spread over several files from the pkgsrc infrastructure.
 173 t.CreateFileLines("mk/tools/bsd.tools.mk",
 174 ".include \"defaults.mk\"")
 175 t.CreateFileLines("mk/tools/defaults.mk",
 176 "# dummy")
 177 t.CreateFileLines("mk/bsd.prefs.mk",
 178 "# dummy")
 179
 180 // The existence of this file makes the category "sysutils" valid.
 181 // The category "tools" on the other hand is not valid.
 182 t.CreateFileLines("sysutils/Makefile",
 183 "# dummy")
 184
 185 // The package Makefile is quite simple, containing just the
 186 // standard variable definitions. The data for checking the variable
 187 // values is partly defined in the pkgsrc infrastructure files
 188 // (as defined in the previous lines), and partly in the pkglint
 189 // code directly. Many details can be found in vartypecheck.go.
 190 t.CreateFileLines("sysutils/checkperms/Makefile",
 191 MkRcsID,
 192 "",
 193 "DISTNAME=\tcheckperms-1.11",
 194 "CATEGORIES=\tsysutils tools",
 195 "MASTER_SITES=\t${MASTER_SITE_GITHUB:=rillig/}",
 196 "",
 197 "MAINTAINER=\tpkgsrc-users@pkgsrc.org",
 198 "HOMEPAGE=\thttps://github.com/rillig/checkperms/",
 199 "COMMENT=\tCheck file permissions",
 200 "LICENSE=\tbsd-2",
 201 "",
 202 ".include \"../../mk/bsd.pkg.mk\"")
 203
 204 t.CreateFileLines("sysutils/checkperms/MESSAGE",
 205 "===========================================================================",
 206 RcsID,
 207 "",
 208 "After installation, this package has to be configured in a special way.",
 209 "",
 210 "===========================================================================")
 211
 212 t.CreateFileLines("sysutils/checkperms/PLIST",
 213 PlistRcsID,
 214 "bin/checkperms",
 215 "man/man1/checkperms.1")
 216
 217 t.CreateFileLines("sysutils/checkperms/README",
 218 "When updating this package, test the pkgsrc bootstrap.")
 219
 220 t.CreateFileLines("sysutils/checkperms/TODO",
 221 "Make the package work on MS-DOS")
 222
 223 t.CreateFileLines("sysutils/checkperms/patches/patch-checkperms.c",
 224 RcsID,
 225 "",
 226 "A simple patch demonstrating that pkglint checks for missing",
 227 "removed lines. The hunk headers says that one line is to be",
 228 "removed, but in fact, there is no deletion line below it.",
 229 "",
 230 "--- a/checkperms.c",
 231 "+++ b/checkperms.c",
 232 "@@ -1,1 +1,3 @@", // at line 1, delete 1 line; at line 1, add 3 lines
 233 "+// Header 1",
 234 "+// Header 2",
 235 "+// Header 3")
 236 t.CreateFileLines("sysutils/checkperms/distinfo",
 237 RcsID,
 238 "",
 239 "SHA1 (checkperms-1.12.tar.gz) = 34c084b4d06bcd7a8bba922ff57677e651eeced5",
 240 "RMD160 (checkperms-1.12.tar.gz) = cd95029aa930b6201e9580b3ab7e36dd30b8f925",
 241 "SHA512 (checkperms-1.12.tar.gz) = 43e37b5963c63fdf716acdb470928d7e21a7bdfddd6c85cf626a11acc7f45fa52a53d4bcd83d543150328fe8cec5587987d2d9a7c5f0aaeb02ac1127ab41f8ae",
 242 "Size (checkperms-1.12.tar.gz) = 6621 bytes",
 243 "SHA1 (patch-checkperms.c) = asdfasdf") // Invalid SHA-1 checksum
 244
 245 new(Pkglint).Main("pkglint", "-Wall", "-Call", t.TempFilename("sysutils/checkperms"))
 246
 247 t.CheckOutputLines(
 248 "WARN: ~/sysutils/checkperms/Makefile:3: This package should be updated to 1.13 ([supports more file formats]).",
 249 "ERROR: ~/sysutils/checkperms/Makefile:4: Invalid category \"tools\".",
 250 "ERROR: ~/sysutils/checkperms/distinfo:7: SHA1 hash of patches/patch-checkperms.c differs "+
 251 "(distinfo has asdfasdf, patch file has e775969de639ec703866c0336c4c8e0fdd96309c). "+
 252 "Run \"@BMAKE@ makepatchsum\".",
 253 "WARN: ~/sysutils/checkperms/patches/patch-checkperms.c:12: Premature end of patch hunk "+
 254 "(expected 1 lines to be deleted and 0 lines to be added)",
 255 "2 errors and 2 warnings found.",
 256 "(Run \"pkglint -e\" to show explanations.)",
 257 "(Run \"pkglint -fs\" to show what can be fixed automatically.)",
 258 "(Run \"pkglint -F\" to automatically fix some issues.)")
 259}
 260
51// go test -c -covermode count 261// go test -c -covermode count
52// pkgsrcdir=... 262// pkgsrcdir=...
53// env PKGLINT_TESTCMDLINE="$pkgsrcdir -r" ./pkglint.test -test.coverprofile pkglint.cov 263// env PKGLINT_TESTCMDLINE="$pkgsrcdir -r" ./pkglint.test -test.coverprofile pkglint.cov
54// go tool cover -html=pkglint.cov -o coverage.html 264// go tool cover -html=pkglint.cov -o coverage.html
55func (s *Suite) Test_Pkglint_coverage(c *check.C) { 265func (s *Suite) Test_Pkglint_coverage(c *check.C) {
56 cmdline := os.Getenv("PKGLINT_TESTCMDLINE") 266 cmdline := os.Getenv("PKGLINT_TESTCMDLINE")
57 if cmdline != "" { 267 if cmdline != "" {
58 G.logOut, G.logErr, trace.Out = NewSeparatorWriter(os.Stdout), NewSeparatorWriter(os.Stderr), os.Stdout 268 G.logOut, G.logErr, trace.Out = NewSeparatorWriter(os.Stdout), NewSeparatorWriter(os.Stderr), os.Stdout
59 new(Pkglint).Main(append([]string{"pkglint"}, splitOnSpace(cmdline)...)...) 269 new(Pkglint).Main(append([]string{"pkglint"}, splitOnSpace(cmdline)...)...)
60 } 270 }
61} 271}
62 272
63func (s *Suite) Test_Pkglint_CheckDirent__outside(c *check.C) { 273func (s *Suite) Test_Pkglint_CheckDirent__outside(c *check.C) {
@@ -194,34 +404,36 @@ func (s *Suite) Test_ChecklinesMessage__ @@ -194,34 +404,36 @@ func (s *Suite) Test_ChecklinesMessage__
194 t := s.Init(c) 404 t := s.Init(c)
195 405
196 t.SetupCommandLine("-Wall", "--autofix") 406 t.SetupCommandLine("-Wall", "--autofix")
197 lines := t.SetupFileLines("MESSAGE", 407 lines := t.SetupFileLines("MESSAGE",
198 "1", 408 "1",
199 "2", 409 "2",
200 "3", 410 "3",
201 "4", 411 "4",
202 "5") 412 "5")
203 413
204 ChecklinesMessage(lines) 414 ChecklinesMessage(lines)
205 415
206 t.CheckOutputLines( 416 t.CheckOutputLines(
207 "AUTOFIX: ~/MESSAGE:1: Inserting a line \"===================================="+ 417 "AUTOFIX: ~/MESSAGE:1: Inserting a line "+
208 "=======================================\" before this line.", 418 "\"===========================================================================\" "+
209 "AUTOFIX: ~/MESSAGE:1: Inserting a line \"$NetBSD: pkglint_test.go,v 1.14 2018/01/28 23:21:16 rillig Exp $\" before this line.", 419 "before this line.",
210 "AUTOFIX: ~/MESSAGE:5: Inserting a line \"===================================="+ 420 "AUTOFIX: ~/MESSAGE:1: Inserting a line \"$"+"NetBSD$\" before this line.",
211 "=======================================\" after this line.") 421 "AUTOFIX: ~/MESSAGE:5: Inserting a line "+
 422 "\"===========================================================================\" "+
 423 "after this line.")
212 t.CheckFileLines("MESSAGE", 424 t.CheckFileLines("MESSAGE",
213 "===========================================================================", 425 "===========================================================================",
214 "$NetBSD: pkglint_test.go,v 1.14 2018/01/28 23:21:16 rillig Exp $", 426 RcsID,
215 "1", 427 "1",
216 "2", 428 "2",
217 "3", 429 "3",
218 "4", 430 "4",
219 "5", 431 "5",
220 "===========================================================================") 432 "===========================================================================")
221} 433}
222 434
223func (s *Suite) Test_GlobalData_Latest(c *check.C) { 435func (s *Suite) Test_GlobalData_Latest(c *check.C) {
224 t := s.Init(c) 436 t := s.Init(c)
225 437
226 G.globalData.Pkgsrcdir = t.TmpDir() 438 G.globalData.Pkgsrcdir = t.TmpDir()
227 439

cvs diff -r1.21 -r1.22 pkgsrc/pkgtools/pkglint/files/Attic/plist.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/plist.go 2018/01/28 23:21:16 1.21
+++ pkgsrc/pkgtools/pkglint/files/Attic/plist.go 2018/02/19 12:40:38 1.22
@@ -332,37 +332,26 @@ func (ck *PlistChecker) checkpathMan(pli @@ -332,37 +332,26 @@ func (ck *PlistChecker) checkpathMan(pli
332 fix.Explain( 332 fix.Explain(
333 "Whether the manual pages are installed in compressed form or not is", 333 "Whether the manual pages are installed in compressed form or not is",
334 "configured by the pkgsrc user. Compression and decompression takes", 334 "configured by the pkgsrc user. Compression and decompression takes",
335 "place automatically, no matter if the .gz extension is mentioned in", 335 "place automatically, no matter if the .gz extension is mentioned in",
336 "the PLIST or not.") 336 "the PLIST or not.")
337 fix.ReplaceRegex(`\.gz\n`, "\n", 1) 337 fix.ReplaceRegex(`\.gz\n`, "\n", 1)
338 fix.Apply() 338 fix.Apply()
339 } 339 }
340} 340}
341 341
342func (ck *PlistChecker) checkpathShare(pline *PlistLine) { 342func (ck *PlistChecker) checkpathShare(pline *PlistLine) {
343 line, text := pline.line, pline.text 343 line, text := pline.line, pline.text
344 switch { 344 switch {
345 // Disabled due to PR 46570, item "10. It should stop". 
346 case false && hasPrefix(text, "share/applications/") && hasSuffix(text, ".desktop"): 
347 f := "../../sysutils/desktop-file-utils/desktopdb.mk" 
348 if G.opts.WarnExtra && G.Pkg != nil && G.Pkg.included[f] == nil { 
349 line.Warnf("Packages that install a .desktop entry should .include %q.", f) 
350 Explain( 
351 "If *.desktop files contain MimeType keys, the global MIME type", 
352 "registry must be updated by desktop-file-utils. Otherwise, this", 
353 "warning is harmless.") 
354 } 
355 
356 case hasPrefix(text, "share/icons/") && G.Pkg != nil: 345 case hasPrefix(text, "share/icons/") && G.Pkg != nil:
357 if hasPrefix(text, "share/icons/hicolor/") && G.Pkg.Pkgpath != "graphics/hicolor-icon-theme" { 346 if hasPrefix(text, "share/icons/hicolor/") && G.Pkg.Pkgpath != "graphics/hicolor-icon-theme" {
358 f := "../../graphics/hicolor-icon-theme/buildlink3.mk" 347 f := "../../graphics/hicolor-icon-theme/buildlink3.mk"
359 if G.Pkg.included[f] == nil && ck.once.FirstTime("hicolor-icon-theme") { 348 if G.Pkg.included[f] == nil && ck.once.FirstTime("hicolor-icon-theme") {
360 line.Errorf("Packages that install hicolor icons must include %q in the Makefile.", f) 349 line.Errorf("Packages that install hicolor icons must include %q in the Makefile.", f)
361 } 350 }
362 } 351 }
363 352
364 if hasPrefix(text, "share/icons/gnome") && G.Pkg.Pkgpath != "graphics/gnome-icon-theme" { 353 if hasPrefix(text, "share/icons/gnome") && G.Pkg.Pkgpath != "graphics/gnome-icon-theme" {
365 f := "../../graphics/gnome-icon-theme/buildlink3.mk" 354 f := "../../graphics/gnome-icon-theme/buildlink3.mk"
366 if G.Pkg.included[f] == nil { 355 if G.Pkg.included[f] == nil {
367 line.Errorf("The package Makefile must include %q.", f) 356 line.Errorf("The package Makefile must include %q.", f)
368 Explain( 357 Explain(

cvs diff -r1.20 -r1.21 pkgsrc/pkgtools/pkglint/files/Attic/plist_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/plist_test.go 2018/01/28 23:21:16 1.20
+++ pkgsrc/pkgtools/pkglint/files/Attic/plist_test.go 2018/02/19 12:40:38 1.21
@@ -44,89 +44,89 @@ func (s *Suite) Test_ChecklinesPlist(c * @@ -44,89 +44,89 @@ func (s *Suite) Test_ChecklinesPlist(c *
44 "WARN: PLIST:11: IMAKE_MANNEWSUFFIX is not meant to appear in PLISTs.", 44 "WARN: PLIST:11: IMAKE_MANNEWSUFFIX is not meant to appear in PLISTs.",
45 "WARN: PLIST:12: Please remove this line. It is no longer necessary.", 45 "WARN: PLIST:12: Please remove this line. It is no longer necessary.",
46 "ERROR: PLIST:14: The package Makefile must include \"../../graphics/gnome-icon-theme/buildlink3.mk\".", 46 "ERROR: PLIST:14: The package Makefile must include \"../../graphics/gnome-icon-theme/buildlink3.mk\".",
47 "WARN: PLIST:14: Packages that install icon theme files should set ICON_THEMES.", 47 "WARN: PLIST:14: Packages that install icon theme files should set ICON_THEMES.",
48 "ERROR: PLIST:15: Packages that install hicolor icons "+ 48 "ERROR: PLIST:15: Packages that install hicolor icons "+
49 "must include \"../../graphics/hicolor-icon-theme/buildlink3.mk\" in the Makefile.", 49 "must include \"../../graphics/hicolor-icon-theme/buildlink3.mk\" in the Makefile.",
50 "ERROR: PLIST:18: Duplicate filename \"share/tzinfo\", already appeared in line 17.") 50 "ERROR: PLIST:18: Duplicate filename \"share/tzinfo\", already appeared in line 17.")
51} 51}
52 52
53func (s *Suite) Test_ChecklinesPlist__empty(c *check.C) { 53func (s *Suite) Test_ChecklinesPlist__empty(c *check.C) {
54 t := s.Init(c) 54 t := s.Init(c)
55 55
56 lines := t.NewLines("PLIST", 56 lines := t.NewLines("PLIST",
57 PlistRcsId) 57 PlistRcsID)
58 58
59 ChecklinesPlist(lines) 59 ChecklinesPlist(lines)
60 60
61 t.CheckOutputLines( 61 t.CheckOutputLines(
62 "WARN: PLIST:1: PLIST files shouldn't be empty.") 62 "WARN: PLIST:1: PLIST files shouldn't be empty.")
63} 63}
64 64
65func (s *Suite) Test_ChecklinesPlist__commonEnd(c *check.C) { 65func (s *Suite) Test_ChecklinesPlist__commonEnd(c *check.C) {
66 t := s.Init(c) 66 t := s.Init(c)
67 67
68 t.SetupFileLines("PLIST.common", 68 t.SetupFileLines("PLIST.common",
69 PlistRcsId, 69 PlistRcsID,
70 "bin/common") 70 "bin/common")
71 lines := t.SetupFileLines("PLIST.common_end", 71 lines := t.SetupFileLines("PLIST.common_end",
72 PlistRcsId, 72 PlistRcsID,
73 "sbin/common_end") 73 "sbin/common_end")
74 74
75 ChecklinesPlist(lines) 75 ChecklinesPlist(lines)
76 76
77 t.CheckOutputEmpty() 77 t.CheckOutputEmpty()
78} 78}
79 79
80func (s *Suite) Test_ChecklinesPlist__conditional(c *check.C) { 80func (s *Suite) Test_ChecklinesPlist__conditional(c *check.C) {
81 t := s.Init(c) 81 t := s.Init(c)
82 82
83 G.Pkg = NewPackage("category/pkgbase") 83 G.Pkg = NewPackage("category/pkgbase")
84 G.Pkg.plistSubstCond["PLIST.bincmds"] = true 84 G.Pkg.plistSubstCond["PLIST.bincmds"] = true
85 lines := t.NewLines("PLIST", 85 lines := t.NewLines("PLIST",
86 PlistRcsId, 86 PlistRcsID,
87 "${PLIST.bincmds}bin/subdir/command") 87 "${PLIST.bincmds}bin/subdir/command")
88 88
89 ChecklinesPlist(lines) 89 ChecklinesPlist(lines)
90 90
91 t.CheckOutputLines( 91 t.CheckOutputLines(
92 "WARN: PLIST:2: The bin/ directory should not have subdirectories.") 92 "WARN: PLIST:2: The bin/ directory should not have subdirectories.")
93} 93}
94 94
95func (s *Suite) Test_ChecklinesPlist__sorting(c *check.C) { 95func (s *Suite) Test_ChecklinesPlist__sorting(c *check.C) {
96 t := s.Init(c) 96 t := s.Init(c)
97 97
98 t.SetupCommandLine("-Wplist-sort") 98 t.SetupCommandLine("-Wplist-sort")
99 lines := t.NewLines("PLIST", 99 lines := t.NewLines("PLIST",
100 PlistRcsId, 100 PlistRcsID,
101 "@comment Do not remove", 101 "@comment Do not remove",
102 "sbin/i386/6c", 102 "sbin/i386/6c",
103 "sbin/program", 103 "sbin/program",
104 "bin/otherprogram", 104 "bin/otherprogram",
105 "${PLIST.conditional}bin/cat") 105 "${PLIST.conditional}bin/cat")
106 106
107 ChecklinesPlist(lines) 107 ChecklinesPlist(lines)
108 108
109 t.CheckOutputLines( 109 t.CheckOutputLines(
110 "WARN: PLIST:5: \"bin/otherprogram\" should be sorted before \"sbin/program\".", 110 "WARN: PLIST:5: \"bin/otherprogram\" should be sorted before \"sbin/program\".",
111 "WARN: PLIST:6: \"bin/cat\" should be sorted before \"bin/otherprogram\".") 111 "WARN: PLIST:6: \"bin/cat\" should be sorted before \"bin/otherprogram\".")
112} 112}
113 113
114func (s *Suite) Test_PlistLineSorter_Sort(c *check.C) { 114func (s *Suite) Test_PlistLineSorter_Sort(c *check.C) {
115 t := s.Init(c) 115 t := s.Init(c)
116 116
117 t.SetupCommandLine("--autofix") 117 t.SetupCommandLine("--autofix")
118 lines := t.SetupFileLines("PLIST", 118 lines := t.SetupFileLines("PLIST",
119 PlistRcsId, 119 PlistRcsID,
120 "@comment Do not remove", 120 "@comment Do not remove",
121 "A", 121 "A",
122 "b", 122 "b",
123 "CCC", 123 "CCC",
124 "lib/${UNKNOWN}.la", 124 "lib/${UNKNOWN}.la",
125 "C", 125 "C",
126 "ddd", 126 "ddd",
127 "@exec echo \"after ddd\"", // Makes the PLIST unsortable 127 "@exec echo \"after ddd\"", // Makes the PLIST unsortable
128 "sbin/program", 128 "sbin/program",
129 "${PLIST.one}bin/program", 129 "${PLIST.one}bin/program",
130 "man/man1/program.1", 130 "man/man1/program.1",
131 "${PLIST.two}bin/program2", 131 "${PLIST.two}bin/program2",
132 "lib/before.la", 132 "lib/before.la",
@@ -140,108 +140,90 @@ func (s *Suite) Test_PlistLineSorter_Sor @@ -140,108 +140,90 @@ func (s *Suite) Test_PlistLineSorter_Sor
140 c.Check(sorter1.unsortable, equals, lines[5]) 140 c.Check(sorter1.unsortable, equals, lines[5])
141 141
142 cleanedLines := append(append(lines[0:5], lines[6:8]...), lines[9:]...) // Remove ${UNKNOWN} and @exec 142 cleanedLines := append(append(lines[0:5], lines[6:8]...), lines[9:]...) // Remove ${UNKNOWN} and @exec
143 143
144 sorter2 := NewPlistLineSorter((&PlistChecker{nil, nil, "", Once{}}).NewLines(cleanedLines)) 144 sorter2 := NewPlistLineSorter((&PlistChecker{nil, nil, "", Once{}}).NewLines(cleanedLines))
145 145
146 c.Check(sorter2.unsortable, check.IsNil) 146 c.Check(sorter2.unsortable, check.IsNil)
147 147
148 sorter2.Sort() 148 sorter2.Sort()
149 149
150 t.CheckOutputLines( 150 t.CheckOutputLines(
151 "AUTOFIX: ~/PLIST:3: Sorting the whole file.") 151 "AUTOFIX: ~/PLIST:3: Sorting the whole file.")
152 t.CheckFileLines("PLIST", 152 t.CheckFileLines("PLIST",
153 PlistRcsId, 153 PlistRcsID,
154 "@comment Do not remove", // The header ends here 154 "@comment Do not remove", // The header ends here
155 "A", 155 "A",
156 "C", 156 "C",
157 "CCC", 157 "CCC",
158 "b", 158 "b",
159 "${PLIST.one}bin/program", // Conditionals are ignored while sorting 159 "${PLIST.one}bin/program", // Conditionals are ignored while sorting
160 "${PLIST.two}bin/program2", 160 "${PLIST.two}bin/program2",
161 "ddd", 161 "ddd",
162 "lib/after.la", 162 "lib/after.la",
163 "lib/before.la", 163 "lib/before.la",
164 "${PLIST.linux}${PLIST.x86_64}lib/lib-linux-x86_64.so", 164 "${PLIST.linux}${PLIST.x86_64}lib/lib-linux-x86_64.so",
165 "man/man1/program.1", 165 "man/man1/program.1",
166 "sbin/program", 166 "sbin/program",
167 "@exec echo \"after lib/after.la\"") // The footer starts here 167 "@exec echo \"after lib/after.la\"") // The footer starts here
168} 168}
169 169
170func (s *Suite) Test_PlistChecker_checkpathShare_Desktop(c *check.C) { 
171 // Disabled due to PR 46570, item "10. It should stop". 
172 return 
173 
174 t := s.Init(c) 
175 
176 t.SetupCommandLine("-Wextra") 
177 G.Pkg = NewPackage("category/pkgpath") 
178 
179 ChecklinesPlist(t.NewLines("PLIST", 
180 PlistRcsId, 
181 "share/applications/pkgbase.desktop")) 
182 
183 t.CheckOutputLines( 
184 "WARN: PLIST:2: Packages that install a .desktop entry " + 
185 "should .include \"../../sysutils/desktop-file-utils/desktopdb.mk\".") 
186} 
187 
188func (s *Suite) Test_PlistChecker_checkpathMan_gz(c *check.C) { 170func (s *Suite) Test_PlistChecker_checkpathMan_gz(c *check.C) {
189 t := s.Init(c) 171 t := s.Init(c)
190 172
191 G.Pkg = NewPackage("category/pkgbase") 173 G.Pkg = NewPackage("category/pkgbase")
192 lines := t.NewLines("PLIST", 174 lines := t.NewLines("PLIST",
193 PlistRcsId, 175 PlistRcsID,
194 "man/man3/strerror.3.gz") 176 "man/man3/strerror.3.gz")
195 177
196 ChecklinesPlist(lines) 178 ChecklinesPlist(lines)
197 179
198 t.CheckOutputLines( 180 t.CheckOutputLines(
199 "NOTE: PLIST:2: The .gz extension is unnecessary for manual pages.") 181 "NOTE: PLIST:2: The .gz extension is unnecessary for manual pages.")
200} 182}
201 183
202func (s *Suite) TestPlistChecker_checkpath__PKGMANDIR(c *check.C) { 184func (s *Suite) TestPlistChecker_checkpath__PKGMANDIR(c *check.C) {
203 t := s.Init(c) 185 t := s.Init(c)
204 186
205 lines := t.NewLines("PLIST", 187 lines := t.NewLines("PLIST",
206 PlistRcsId, 188 PlistRcsID,
207 "${PKGMANDIR}/man1/sh.1") 189 "${PKGMANDIR}/man1/sh.1")
208 190
209 ChecklinesPlist(lines) 191 ChecklinesPlist(lines)
210 192
211 t.CheckOutputLines( 193 t.CheckOutputLines(
212 "NOTE: PLIST:2: PLIST files should mention \"man/\" instead of \"${PKGMANDIR}\".") 194 "NOTE: PLIST:2: PLIST files should mention \"man/\" instead of \"${PKGMANDIR}\".")
213} 195}
214 196
215func (s *Suite) TestPlistChecker_checkpath__python_egg(c *check.C) { 197func (s *Suite) TestPlistChecker_checkpath__python_egg(c *check.C) {
216 t := s.Init(c) 198 t := s.Init(c)
217 199
218 lines := t.NewLines("PLIST", 200 lines := t.NewLines("PLIST",
219 PlistRcsId, 201 PlistRcsID,
220 "${PYSITELIB}/gdspy-${PKGVERSION}-py${PYVERSSUFFIX}.egg-info/PKG-INFO") 202 "${PYSITELIB}/gdspy-${PKGVERSION}-py${PYVERSSUFFIX}.egg-info/PKG-INFO")
221 203
222 ChecklinesPlist(lines) 204 ChecklinesPlist(lines)
223 205
224 t.CheckOutputLines( 206 t.CheckOutputLines(
225 "WARN: PLIST:2: Include \"../../lang/python/egg.mk\" instead of listing .egg-info files directly.") 207 "WARN: PLIST:2: Include \"../../lang/python/egg.mk\" instead of listing .egg-info files directly.")
226} 208}
227 209
228func (s *Suite) Test_PlistChecker__autofix(c *check.C) { 210func (s *Suite) Test_PlistChecker__autofix(c *check.C) {
229 t := s.Init(c) 211 t := s.Init(c)
230 212
231 t.SetupCommandLine("-Wall") 213 t.SetupCommandLine("-Wall")
232 214
233 fname := t.CreateFileLines("PLIST", 215 fname := t.CreateFileLines("PLIST",
234 PlistRcsId, 216 PlistRcsID,
235 "lib/libvirt/connection-driver/libvirt_driver_storage.la", 217 "lib/libvirt/connection-driver/libvirt_driver_storage.la",
236 "${PLIST.hal}lib/libvirt/connection-driver/libvirt_driver_nodedev.la", 218 "${PLIST.hal}lib/libvirt/connection-driver/libvirt_driver_nodedev.la",
237 "${PLIST.xen}lib/libvirt/connection-driver/libvirt_driver_libxl.la", 219 "${PLIST.xen}lib/libvirt/connection-driver/libvirt_driver_libxl.la",
238 "lib/libvirt/lock-driver/lockd.la", 220 "lib/libvirt/lock-driver/lockd.la",
239 "${PKGMANDIR}/man1/sh.1", 221 "${PKGMANDIR}/man1/sh.1",
240 "share/augeas/lenses/virtlockd.aug", 222 "share/augeas/lenses/virtlockd.aug",
241 "share/doc/pkgname-1.0/html/32favicon.png", 223 "share/doc/pkgname-1.0/html/32favicon.png",
242 "share/doc/pkgname-1.0/html/404.html", 224 "share/doc/pkgname-1.0/html/404.html",
243 "share/doc/pkgname-1.0/html/acl.html", 225 "share/doc/pkgname-1.0/html/acl.html",
244 "share/doc/pkgname-1.0/html/aclpolkit.html", 226 "share/doc/pkgname-1.0/html/aclpolkit.html",
245 "share/doc/pkgname-1.0/html/windows.html", 227 "share/doc/pkgname-1.0/html/windows.html",
246 "share/examples/libvirt/libvirt.conf", 228 "share/examples/libvirt/libvirt.conf",
247 "share/locale/zh_CN/LC_MESSAGES/libvirt.mo", 229 "share/locale/zh_CN/LC_MESSAGES/libvirt.mo",
@@ -261,27 +243,27 @@ func (s *Suite) Test_PlistChecker__autof @@ -261,27 +243,27 @@ func (s *Suite) Test_PlistChecker__autof
261 "should be sorted before \"lib/libvirt/connection-driver/libvirt_driver_nodedev.la\".", 243 "should be sorted before \"lib/libvirt/connection-driver/libvirt_driver_nodedev.la\".",
262 "NOTE: ~/PLIST:6: PLIST files should mention \"man/\" instead of \"${PKGMANDIR}\".") 244 "NOTE: ~/PLIST:6: PLIST files should mention \"man/\" instead of \"${PKGMANDIR}\".")
263 245
264 t.SetupCommandLine("-Wall", "--autofix") 246 t.SetupCommandLine("-Wall", "--autofix")
265 ChecklinesPlist(lines) 247 ChecklinesPlist(lines)
266 248
267 fixedLines := LoadExistingLines(fname, false) 249 fixedLines := LoadExistingLines(fname, false)
268 250
269 t.CheckOutputLines( 251 t.CheckOutputLines(
270 "AUTOFIX: ~/PLIST:6: Replacing \"${PKGMANDIR}/\" with \"man/\".", 252 "AUTOFIX: ~/PLIST:6: Replacing \"${PKGMANDIR}/\" with \"man/\".",
271 "AUTOFIX: ~/PLIST:2: Sorting the whole file.") 253 "AUTOFIX: ~/PLIST:2: Sorting the whole file.")
272 c.Check(len(lines), equals, len(fixedLines)) 254 c.Check(len(lines), equals, len(fixedLines))
273 t.CheckFileLines("PLIST", 255 t.CheckFileLines("PLIST",
274 PlistRcsId, 256 PlistRcsID,
275 "${PLIST.xen}lib/libvirt/connection-driver/libvirt_driver_libxl.la", 257 "${PLIST.xen}lib/libvirt/connection-driver/libvirt_driver_libxl.la",
276 "${PLIST.hal}lib/libvirt/connection-driver/libvirt_driver_nodedev.la", 258 "${PLIST.hal}lib/libvirt/connection-driver/libvirt_driver_nodedev.la",
277 "lib/libvirt/connection-driver/libvirt_driver_storage.la", 259 "lib/libvirt/connection-driver/libvirt_driver_storage.la",
278 "lib/libvirt/lock-driver/lockd.la", 260 "lib/libvirt/lock-driver/lockd.la",
279 "man/man1/sh.1", 261 "man/man1/sh.1",
280 "share/augeas/lenses/virtlockd.aug", 262 "share/augeas/lenses/virtlockd.aug",
281 "share/doc/pkgname-1.0/html/32favicon.png", 263 "share/doc/pkgname-1.0/html/32favicon.png",
282 "share/doc/pkgname-1.0/html/404.html", 264 "share/doc/pkgname-1.0/html/404.html",
283 "share/doc/pkgname-1.0/html/acl.html", 265 "share/doc/pkgname-1.0/html/acl.html",
284 "share/doc/pkgname-1.0/html/aclpolkit.html", 266 "share/doc/pkgname-1.0/html/aclpolkit.html",
285 "share/doc/pkgname-1.0/html/windows.html", 267 "share/doc/pkgname-1.0/html/windows.html",
286 "share/examples/libvirt/libvirt.conf", 268 "share/examples/libvirt/libvirt.conf",
287 "share/locale/zh_CN/LC_MESSAGES/libvirt.mo", 269 "share/locale/zh_CN/LC_MESSAGES/libvirt.mo",
@@ -292,27 +274,27 @@ func (s *Suite) Test_PlistChecker__autof @@ -292,27 +274,27 @@ func (s *Suite) Test_PlistChecker__autof
292 "@pkgdir etc/logrotate.d", 274 "@pkgdir etc/logrotate.d",
293 "@pkgdir etc/sasl2") 275 "@pkgdir etc/sasl2")
294} 276}
295 277
296// When the same entry appears both with and without a conditional, 278// When the same entry appears both with and without a conditional,
297// the one with the conditional can be removed. 279// the one with the conditional can be removed.
298// When the same entry appears with several different conditionals, 280// When the same entry appears with several different conditionals,
299// all of them must stay. 281// all of them must stay.
300func (s *Suite) Test_PlistChecker__remove_same_entries(c *check.C) { 282func (s *Suite) Test_PlistChecker__remove_same_entries(c *check.C) {
301 t := s.Init(c) 283 t := s.Init(c)
302 284
303 t.SetupCommandLine("-Wall") 285 t.SetupCommandLine("-Wall")
304 lines := t.SetupFileLines("PLIST", 286 lines := t.SetupFileLines("PLIST",
305 PlistRcsId, 287 PlistRcsID,
306 "${PLIST.option1}bin/true", 288 "${PLIST.option1}bin/true",
307 "bin/true", 289 "bin/true",
308 "${PLIST.option1}bin/true", 290 "${PLIST.option1}bin/true",
309 "bin/true", 291 "bin/true",
310 "${PLIST.option3}bin/false", 292 "${PLIST.option3}bin/false",
311 "${PLIST.option2}bin/false", 293 "${PLIST.option2}bin/false",
312 "bin/true") 294 "bin/true")
313 295
314 ChecklinesPlist(lines) 296 ChecklinesPlist(lines)
315 297
316 t.CheckOutputLines( 298 t.CheckOutputLines(
317 "ERROR: ~/PLIST:2: Duplicate filename \"bin/true\", already appeared in line 3.", 299 "ERROR: ~/PLIST:2: Duplicate filename \"bin/true\", already appeared in line 3.",
318 "ERROR: ~/PLIST:4: Duplicate filename \"bin/true\", already appeared in line 3.", 300 "ERROR: ~/PLIST:4: Duplicate filename \"bin/true\", already appeared in line 3.",
@@ -321,18 +303,18 @@ func (s *Suite) Test_PlistChecker__remov @@ -321,18 +303,18 @@ func (s *Suite) Test_PlistChecker__remov
321 "ERROR: ~/PLIST:8: Duplicate filename \"bin/true\", already appeared in line 3.") 303 "ERROR: ~/PLIST:8: Duplicate filename \"bin/true\", already appeared in line 3.")
322 304
323 t.SetupCommandLine("-Wall", "--autofix") 305 t.SetupCommandLine("-Wall", "--autofix")
324 306
325 ChecklinesPlist(lines) 307 ChecklinesPlist(lines)
326 308
327 t.CheckOutputLines( 309 t.CheckOutputLines(
328 "AUTOFIX: ~/PLIST:2: Deleting this line.", 310 "AUTOFIX: ~/PLIST:2: Deleting this line.",
329 "AUTOFIX: ~/PLIST:4: Deleting this line.", 311 "AUTOFIX: ~/PLIST:4: Deleting this line.",
330 "AUTOFIX: ~/PLIST:5: Deleting this line.", 312 "AUTOFIX: ~/PLIST:5: Deleting this line.",
331 "AUTOFIX: ~/PLIST:8: Deleting this line.", 313 "AUTOFIX: ~/PLIST:8: Deleting this line.",
332 "AUTOFIX: ~/PLIST:2: Sorting the whole file.") 314 "AUTOFIX: ~/PLIST:2: Sorting the whole file.")
333 t.CheckFileLines("PLIST", 315 t.CheckFileLines("PLIST",
334 PlistRcsId, 316 PlistRcsID,
335 "${PLIST.option2}bin/false", 317 "${PLIST.option2}bin/false",
336 "${PLIST.option3}bin/false", 318 "${PLIST.option3}bin/false",
337 "bin/true") 319 "bin/true")
338} 320}

cvs diff -r1.20 -r1.21 pkgsrc/pkgtools/pkglint/files/Attic/shell.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/shell.go 2018/01/10 00:39:52 1.20
+++ pkgsrc/pkgtools/pkglint/files/Attic/shell.go 2018/02/19 12:40:38 1.21
@@ -14,27 +14,27 @@ const ( @@ -14,27 +14,27 @@ const (
14 reShVarexpansion = `(?:(?:#|##|%|%%|:-|:=|:\?|:\+|\+)[^$\\{}]*)` 14 reShVarexpansion = `(?:(?:#|##|%|%%|:-|:=|:\?|:\+|\+)[^$\\{}]*)`
15 reShVaruse = `\$\$` + `(?:` + reShVarname + `|` + `\{` + reShVarname + `(?:` + reShVarexpansion + `)?` + `\})` 15 reShVaruse = `\$\$` + `(?:` + reShVarname + `|` + `\{` + reShVarname + `(?:` + reShVarexpansion + `)?` + `\})`
16 reShDollar = `\\\$\$|` + reShVaruse + `|\$\$[,\-/|]` 16 reShDollar = `\\\$\$|` + reShVaruse + `|\$\$[,\-/|]`
17) 17)
18 18
19type ShellLine struct { 19type ShellLine struct {
20 mkline MkLine 20 mkline MkLine
21} 21}
22 22
23func NewShellLine(mkline MkLine) *ShellLine { 23func NewShellLine(mkline MkLine) *ShellLine {
24 return &ShellLine{mkline} 24 return &ShellLine{mkline}
25} 25}
26 26
27var shellcommandsContextType = &Vartype{lkNone, BtShellCommands, []AclEntry{{"*", aclpAllRuntime}}, false} 27var shellcommandsContextType = &Vartype{lkNone, BtShellCommands, []ACLEntry{{"*", aclpAllRuntime}}, false}
28var shellwordVuc = &VarUseContext{shellcommandsContextType, vucTimeUnknown, vucQuotPlain, false} 28var shellwordVuc = &VarUseContext{shellcommandsContextType, vucTimeUnknown, vucQuotPlain, false}
29 29
30func (shline *ShellLine) CheckWord(token string, checkQuoting bool) { 30func (shline *ShellLine) CheckWord(token string, checkQuoting bool) {
31 if trace.Tracing { 31 if trace.Tracing {
32 defer trace.Call(token, checkQuoting)() 32 defer trace.Call(token, checkQuoting)()
33 } 33 }
34 34
35 if token == "" || hasPrefix(token, "#") { 35 if token == "" || hasPrefix(token, "#") {
36 return 36 return
37 } 37 }
38 38
39 var line = shline.mkline.Line 39 var line = shline.mkline.Line
40 40
@@ -762,27 +762,27 @@ func (spc *ShellProgramChecker) checkWor @@ -762,27 +762,27 @@ func (spc *ShellProgramChecker) checkWor
762 for _, word := range words { 762 for _, word := range words {
763 spc.checkWord(word, checkQuoting) 763 spc.checkWord(word, checkQuoting)
764 } 764 }
765} 765}
766 766
767func (spc *ShellProgramChecker) checkWord(word *ShToken, checkQuoting bool) { 767func (spc *ShellProgramChecker) checkWord(word *ShToken, checkQuoting bool) {
768 if trace.Tracing { 768 if trace.Tracing {
769 defer trace.Call(word.MkText)() 769 defer trace.Call(word.MkText)()
770 } 770 }
771 771
772 spc.shline.CheckWord(word.MkText, checkQuoting) 772 spc.shline.CheckWord(word.MkText, checkQuoting)
773} 773}
774 774
775func (scc *ShellProgramChecker) checkPipeExitcode(line Line, pipeline *MkShPipeline) { 775func (spc *ShellProgramChecker) checkPipeExitcode(line Line, pipeline *MkShPipeline) {
776 if trace.Tracing { 776 if trace.Tracing {
777 defer trace.Call()() 777 defer trace.Call()()
778 } 778 }
779 779
780 oneOf := func(s string, others ...string) bool { 780 oneOf := func(s string, others ...string) bool {
781 for _, other := range others { 781 for _, other := range others {
782 if s == other { 782 if s == other {
783 return true 783 return true
784 } 784 }
785 } 785 }
786 return false 786 return false
787 } 787 }
788 788
@@ -817,35 +817,35 @@ func (scc *ShellProgramChecker) checkPip @@ -817,35 +817,35 @@ func (scc *ShellProgramChecker) checkPip
817 line.Warnf("The exitcode of the command at the left of the | operator is ignored.") 817 line.Warnf("The exitcode of the command at the left of the | operator is ignored.")
818 } 818 }
819 Explain( 819 Explain(
820 "In a shell command like \"cat *.txt | grep keyword\", if the command", 820 "In a shell command like \"cat *.txt | grep keyword\", if the command",
821 "on the left side of the \"|\" fails, this failure is ignored.", 821 "on the left side of the \"|\" fails, this failure is ignored.",
822 "", 822 "",
823 "If you need to detect the failure of the left-hand-side command, use", 823 "If you need to detect the failure of the left-hand-side command, use",
824 "temporary files to save the output of the command. A good place to", 824 "temporary files to save the output of the command. A good place to",
825 "create those files is in ${WRKDIR}.") 825 "create those files is in ${WRKDIR}.")
826 } 826 }
827 } 827 }
828} 828}
829 829
830func (scc *ShellProgramChecker) checkSetE(list *MkShList, eflag *bool) { 830func (spc *ShellProgramChecker) checkSetE(list *MkShList, eflag *bool) {
831 if trace.Tracing { 831 if trace.Tracing {
832 defer trace.Call()() 832 defer trace.Call()()
833 } 833 }
834 834
835 // Disabled until the shell parser can recognize "command || exit 1" reliably. 835 // Disabled until the shell parser can recognize "command || exit 1" reliably.
836 if false && G.opts.WarnExtra && !*eflag && "the current token" == ";" { 836 if false && G.opts.WarnExtra && !*eflag && "the current token" == ";" {
837 *eflag = true 837 *eflag = true
838 scc.shline.mkline.Warnf("Please switch to \"set -e\" mode before using a semicolon (the one after %q) to separate commands.", "previous token") 838 spc.shline.mkline.Warnf("Please switch to \"set -e\" mode before using a semicolon (the one after %q) to separate commands.", "previous token")
839 Explain( 839 Explain(
840 "Normally, when a shell command fails (returns non-zero), the", 840 "Normally, when a shell command fails (returns non-zero), the",
841 "remaining commands are still executed. For example, the following", 841 "remaining commands are still executed. For example, the following",
842 "commands would remove all files from the HOME directory:", 842 "commands would remove all files from the HOME directory:",
843 "", 843 "",
844 "\tcd \"$HOME\"; cd /nonexistent; rm -rf *", 844 "\tcd \"$HOME\"; cd /nonexistent; rm -rf *",
845 "", 845 "",
846 "To fix this warning, you can:", 846 "To fix this warning, you can:",
847 "", 847 "",
848 "* insert ${RUN} at the beginning of the line", 848 "* insert ${RUN} at the beginning of the line",
849 " (which among other things does \"set -e\")", 849 " (which among other things does \"set -e\")",
850 "* insert \"set -e\" explicitly at the beginning of the line", 850 "* insert \"set -e\" explicitly at the beginning of the line",
851 "* use \"&&\" instead of \";\" to separate the commands") 851 "* use \"&&\" instead of \";\" to separate the commands")

cvs diff -r1.20 -r1.21 pkgsrc/pkgtools/pkglint/files/Attic/shell_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/shell_test.go 2018/01/27 18:50:36 1.20
+++ pkgsrc/pkgtools/pkglint/files/Attic/shell_test.go 2018/02/19 12:40:38 1.21
@@ -579,27 +579,27 @@ func (s *Suite) Test_ShellLine_CheckShel @@ -579,27 +579,27 @@ func (s *Suite) Test_ShellLine_CheckShel
579 shline := t.NewShellLine("Makefile", 85, "\t${RUN} ${INSTALL} -d ${DESTDIR}${PREFIX}/dir1 ${DESTDIR}${PREFIX}/dir2") 579 shline := t.NewShellLine("Makefile", 85, "\t${RUN} ${INSTALL} -d ${DESTDIR}${PREFIX}/dir1 ${DESTDIR}${PREFIX}/dir2")
580 580
581 shline.CheckShellCommandLine(shline.mkline.Shellcmd()) 581 shline.CheckShellCommandLine(shline.mkline.Shellcmd())
582 582
583 t.CheckOutputLines( 583 t.CheckOutputLines(
584 "NOTE: Makefile:85: You can use \"INSTALLATION_DIRS+= dir1\" instead of \"${INSTALL} -d\".", 584 "NOTE: Makefile:85: You can use \"INSTALLATION_DIRS+= dir1\" instead of \"${INSTALL} -d\".",
585 "NOTE: Makefile:85: You can use \"INSTALLATION_DIRS+= dir2\" instead of \"${INSTALL} -d\".") 585 "NOTE: Makefile:85: You can use \"INSTALLATION_DIRS+= dir2\" instead of \"${INSTALL} -d\".")
586} 586}
587 587
588func (s *Suite) Test_ShellLine__shell_comment_with_line_continuation(c *check.C) { 588func (s *Suite) Test_ShellLine__shell_comment_with_line_continuation(c *check.C) {
589 t := s.Init(c) 589 t := s.Init(c)
590 590
591 lines := t.SetupFileLinesContinuation("Makefile", 591 lines := t.SetupFileLinesContinuation("Makefile",
592 MkRcsId, 592 MkRcsID,
593 "pre-install:", 593 "pre-install:",
594 "\t"+"# comment\\", 594 "\t"+"# comment\\",
595 "\t"+"echo \"hello\"") 595 "\t"+"echo \"hello\"")
596 596
597 NewMkLines(lines).Check() 597 NewMkLines(lines).Check()
598 598
599 t.CheckOutputLines( 599 t.CheckOutputLines(
600 "WARN: ~/Makefile:3--4: A shell comment does not stop at the end of line.") 600 "WARN: ~/Makefile:3--4: A shell comment does not stop at the end of line.")
601} 601}
602 602
603func (s *Suite) Test_ShellLine_unescapeBackticks(c *check.C) { 603func (s *Suite) Test_ShellLine_unescapeBackticks(c *check.C) {
604 t := s.Init(c) 604 t := s.Init(c)
605 605
@@ -612,23 +612,23 @@ func (s *Suite) Test_ShellLine_unescapeB @@ -612,23 +612,23 @@ func (s *Suite) Test_ShellLine_unescapeB
612 backtCommand, newQuoting := shline.unescapeBackticks(text, repl, shqDquotBackt) 612 backtCommand, newQuoting := shline.unescapeBackticks(text, repl, shqDquotBackt)
613 613
614 c.Check(backtCommand, equals, "echo \"foo bar\"") 614 c.Check(backtCommand, equals, "echo \"foo bar\"")
615 c.Check(newQuoting, equals, shqDquot) 615 c.Check(newQuoting, equals, shqDquot)
616 c.Check(repl.Rest(), equals, "\"") 616 c.Check(repl.Rest(), equals, "\"")
617} 617}
618 618
619func (s *Suite) Test_ShellLine__variable_outside_quotes(c *check.C) { 619func (s *Suite) Test_ShellLine__variable_outside_quotes(c *check.C) {
620 t := s.Init(c) 620 t := s.Init(c)
621 621
622 t.SetupCommandLine("-Wall") 622 t.SetupCommandLine("-Wall")
623 G.globalData.InitVartypes() 623 G.globalData.InitVartypes()
624 mklines := t.NewMkLines("dummy.mk", 624 mklines := t.NewMkLines("dummy.mk",
625 MkRcsId, 625 MkRcsID,
626 "GZIP=\t${ECHO} $$comment") 626 "GZIP=\t${ECHO} $$comment")
627 627
628 mklines.Check() 628 mklines.Check()
629 629
630 t.CheckOutputLines( 630 t.CheckOutputLines(
631 "WARN: dummy.mk:2: The variable GZIP may not be set by any package.", 631 "WARN: dummy.mk:2: The variable GZIP may not be set by any package.",
632 "WARN: dummy.mk:2: Unquoted shell variable \"comment\".", 632 "WARN: dummy.mk:2: Unquoted shell variable \"comment\".",
633 "WARN: dummy.mk:2: ECHO should not be evaluated indirectly at load time.") 633 "WARN: dummy.mk:2: ECHO should not be evaluated indirectly at load time.")
634} 634}

cvs diff -r1.35 -r1.36 pkgsrc/pkgtools/pkglint/files/Attic/vardefs.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/vardefs.go 2018/01/27 18:50:36 1.35
+++ pkgsrc/pkgtools/pkglint/files/Attic/vardefs.go 2018/02/19 12:40:38 1.36
@@ -575,26 +575,27 @@ func (gd *GlobalData) InitVartypes() { @@ -575,26 +575,27 @@ func (gd *GlobalData) InitVartypes() {
575 pkglist("GENERATE_PLIST", lkNone, BtShellCommands) 575 pkglist("GENERATE_PLIST", lkNone, BtShellCommands)
576 pkg("GITHUB_PROJECT", lkNone, BtIdentifier) 576 pkg("GITHUB_PROJECT", lkNone, BtIdentifier)
577 pkg("GITHUB_TAG", lkNone, BtIdentifier) 577 pkg("GITHUB_TAG", lkNone, BtIdentifier)
578 pkg("GITHUB_RELEASE", lkNone, BtFilename) 578 pkg("GITHUB_RELEASE", lkNone, BtFilename)
579 pkg("GITHUB_TYPE", lkNone, enum("tag release")) 579 pkg("GITHUB_TYPE", lkNone, enum("tag release"))
580 pkg("GMAKE_REQD", lkNone, BtVersion) 580 pkg("GMAKE_REQD", lkNone, BtVersion)
581 acl("GNU_ARCH", lkNone, enum("mips"), "") 581 acl("GNU_ARCH", lkNone, enum("mips"), "")
582 acl("GNU_CONFIGURE", lkNone, BtYes, "Makefile, Makefile.common: set") 582 acl("GNU_CONFIGURE", lkNone, BtYes, "Makefile, Makefile.common: set")
583 acl("GNU_CONFIGURE_INFODIR", lkNone, BtPathname, "Makefile, Makefile.common: set") 583 acl("GNU_CONFIGURE_INFODIR", lkNone, BtPathname, "Makefile, Makefile.common: set")
584 acl("GNU_CONFIGURE_LIBDIR", lkNone, BtPathname, "Makefile, Makefile.common: set") 584 acl("GNU_CONFIGURE_LIBDIR", lkNone, BtPathname, "Makefile, Makefile.common: set")
585 pkg("GNU_CONFIGURE_LIBSUBDIR", lkNone, BtPathname) 585 pkg("GNU_CONFIGURE_LIBSUBDIR", lkNone, BtPathname)
586 acl("GNU_CONFIGURE_MANDIR", lkNone, BtPathname, "Makefile, Makefile.common: set") 586 acl("GNU_CONFIGURE_MANDIR", lkNone, BtPathname, "Makefile, Makefile.common: set")
587 acl("GNU_CONFIGURE_PREFIX", lkNone, BtPathname, "Makefile: set") 587 acl("GNU_CONFIGURE_PREFIX", lkNone, BtPathname, "Makefile: set")
 588 pkg("GOPATH", lkNone, BtPathname)
588 acl("HAS_CONFIGURE", lkNone, BtYes, "Makefile, Makefile.common: set") 589 acl("HAS_CONFIGURE", lkNone, BtYes, "Makefile, Makefile.common: set")
589 pkglist("HEADER_TEMPLATES", lkShell, BtPathname) 590 pkglist("HEADER_TEMPLATES", lkShell, BtPathname)
590 pkg("HOMEPAGE", lkNone, BtHomepage) 591 pkg("HOMEPAGE", lkNone, BtHomepage)
591 pkg("ICON_THEMES", lkNone, BtYes) 592 pkg("ICON_THEMES", lkNone, BtYes)
592 acl("IGNORE_PKG.*", lkNone, BtYes, "*: set, use-loadtime") 593 acl("IGNORE_PKG.*", lkNone, BtYes, "*: set, use-loadtime")
593 sys("IMAKE", lkNone, BtShellCommand) 594 sys("IMAKE", lkNone, BtShellCommand)
594 acl("INCOMPAT_CURSES", lkSpace, BtMachinePlatformPattern, "Makefile: set, append") 595 acl("INCOMPAT_CURSES", lkSpace, BtMachinePlatformPattern, "Makefile: set, append")
595 acl("INCOMPAT_ICONV", lkSpace, BtMachinePlatformPattern, "") 596 acl("INCOMPAT_ICONV", lkSpace, BtMachinePlatformPattern, "")
596 acl("INFO_DIR", lkNone, BtPathname, "") // relative to PREFIX 597 acl("INFO_DIR", lkNone, BtPathname, "") // relative to PREFIX
597 pkg("INFO_FILES", lkNone, BtYes) 598 pkg("INFO_FILES", lkNone, BtYes)
598 sys("INSTALL", lkNone, BtShellCommand) 599 sys("INSTALL", lkNone, BtShellCommand)
599 pkglist("INSTALLATION_DIRS", lkShell, BtPrefixPathname) 600 pkglist("INSTALLATION_DIRS", lkShell, BtPrefixPathname)
600 pkg("INSTALLATION_DIRS_FROM_PLIST", lkNone, BtYes) 601 pkg("INSTALLATION_DIRS_FROM_PLIST", lkNone, BtYes)
@@ -1005,57 +1006,57 @@ func enum(values string) *BasicType { @@ -1005,57 +1006,57 @@ func enum(values string) *BasicType {
1005 return 1006 return
1006 } 1007 }
1007 1008
1008 if cv.Value == cv.ValueNoVar && !vmap[cv.Value] { 1009 if cv.Value == cv.ValueNoVar && !vmap[cv.Value] {
1009 cv.Line.Warnf("%q is not valid for %s. Use one of { %s } instead.", cv.Value, cv.Varname, values) 1010 cv.Line.Warnf("%q is not valid for %s. Use one of { %s } instead.", cv.Value, cv.Varname, values)
1010 } 1011 }
1011 }} 1012 }}
1012} 1013}
1013 1014
1014func acl(varname string, kindOfList KindOfList, checker *BasicType, aclentries string) { 1015func acl(varname string, kindOfList KindOfList, checker *BasicType, aclentries string) {
1015 m := mustMatch(varname, `^([A-Z_.][A-Z0-9_]*)(|\*|\.\*)$`) 1016 m := mustMatch(varname, `^([A-Z_.][A-Z0-9_]*)(|\*|\.\*)$`)
1016 varbase, varparam := m[1], m[2] 1017 varbase, varparam := m[1], m[2]
1017 1018
1018 vtype := &Vartype{kindOfList, checker, parseAclEntries(varname, aclentries), false} 1019 vtype := &Vartype{kindOfList, checker, parseACLEntries(varname, aclentries), false}
1019 1020
1020 if G.globalData.vartypes == nil { 1021 if G.globalData.vartypes == nil {
1021 G.globalData.vartypes = make(map[string]*Vartype) 1022 G.globalData.vartypes = make(map[string]*Vartype)
1022 } 1023 }
1023 if varparam == "" || varparam == "*" { 1024 if varparam == "" || varparam == "*" {
1024 G.globalData.vartypes[varbase] = vtype 1025 G.globalData.vartypes[varbase] = vtype
1025 } 1026 }
1026 if varparam == "*" || varparam == ".*" { 1027 if varparam == "*" || varparam == ".*" {
1027 G.globalData.vartypes[varbase+".*"] = vtype 1028 G.globalData.vartypes[varbase+".*"] = vtype
1028 } 1029 }
1029} 1030}
1030 1031
1031func parseAclEntries(varname string, aclentries string) []AclEntry { 1032func parseACLEntries(varname string, aclentries string) []ACLEntry {
1032 if aclentries == "" { 1033 if aclentries == "" {
1033 return nil 1034 return nil
1034 } 1035 }
1035 var result []AclEntry 1036 var result []ACLEntry
1036 prevperms := "(first)" 1037 prevperms := "(first)"
1037 for _, arg := range strings.Split(aclentries, "; ") { 1038 for _, arg := range strings.Split(aclentries, "; ") {
1038 var globs, perms string 1039 var globs, perms string
1039 if fields := strings.SplitN(arg, ": ", 2); len(fields) == 2 { 1040 if fields := strings.SplitN(arg, ": ", 2); len(fields) == 2 {
1040 globs, perms = fields[0], fields[1] 1041 globs, perms = fields[0], fields[1]
1041 } else { 1042 } else {
1042 globs = strings.TrimSuffix(arg, ":") 1043 globs = strings.TrimSuffix(arg, ":")
1043 } 1044 }
1044 if perms == prevperms { 1045 if perms == prevperms {
1045 fmt.Printf("Repeated permissions for %s: %s\n", varname, perms) 1046 fmt.Printf("Repeated permissions for %s: %s\n", varname, perms)
1046 } 1047 }
1047 prevperms = perms 1048 prevperms = perms
1048 var permissions AclPermissions 1049 var permissions ACLPermissions
1049 for _, perm := range strings.Split(perms, ", ") { 1050 for _, perm := range strings.Split(perms, ", ") {
1050 switch perm { 1051 switch perm {
1051 case "append": 1052 case "append":
1052 permissions |= aclpAppend 1053 permissions |= aclpAppend
1053 case "default": 1054 case "default":
1054 permissions |= aclpSetDefault 1055 permissions |= aclpSetDefault
1055 case "set": 1056 case "set":
1056 permissions |= aclpSet 1057 permissions |= aclpSet
1057 case "use": 1058 case "use":
1058 permissions |= aclpUse 1059 permissions |= aclpUse
1059 case "use-loadtime": 1060 case "use-loadtime":
1060 permissions |= aclpUseLoadtime 1061 permissions |= aclpUseLoadtime
1061 case "": 1062 case "":
@@ -1069,18 +1070,18 @@ func parseAclEntries(varname string, acl @@ -1069,18 +1070,18 @@ func parseAclEntries(varname string, acl
1069 case "*", 1070 case "*",
1070 "Makefile", "Makefile.common", "Makefile.*", 1071 "Makefile", "Makefile.common", "Makefile.*",
1071 "buildlink3.mk", "builtin.mk", "options.mk", "hacks.mk", "*.mk", 1072 "buildlink3.mk", "builtin.mk", "options.mk", "hacks.mk", "*.mk",
1072 "bsd.options.mk", "pkgconfig-builtin.mk", "pyversion.mk": 1073 "bsd.options.mk", "pkgconfig-builtin.mk", "pyversion.mk":
1073 break 1074 break
1074 default: 1075 default:
1075 print(fmt.Sprintf("Invalid ACL glob %q for varname %q.\n", glob, varname)) 1076 print(fmt.Sprintf("Invalid ACL glob %q for varname %q.\n", glob, varname))
1076 } 1077 }
1077 for _, prev := range result { 1078 for _, prev := range result {
1078 if matched, err := path.Match(prev.glob, glob); err != nil || matched { 1079 if matched, err := path.Match(prev.glob, glob); err != nil || matched {
1079 print(fmt.Sprintf("Ineffective ACL glob %q for varname %q.\n", glob, varname)) 1080 print(fmt.Sprintf("Ineffective ACL glob %q for varname %q.\n", glob, varname))
1080 } 1081 }
1081 } 1082 }
1082 result = append(result, AclEntry{glob, permissions}) 1083 result = append(result, ACLEntry{glob, permissions})
1083 } 1084 }
1084 } 1085 }
1085 return result 1086 return result
1086} 1087}

cvs diff -r1.4 -r1.5 pkgsrc/pkgtools/pkglint/files/Attic/vartype_test.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/Attic/vartype_test.go 2016/07/10 21:24:47 1.4
+++ pkgsrc/pkgtools/pkglint/files/Attic/vartype_test.go 2018/02/19 12:40:38 1.5
@@ -1,25 +1,25 @@ @@ -1,25 +1,25 @@
1package main 1package main
2 2
3import ( 3import (
4 check "gopkg.in/check.v1" 4 check "gopkg.in/check.v1"
5) 5)
6 6
7func (s *Suite) Test_Vartype_EffectivePermissions(c *check.C) { 7func (s *Suite) Test_Vartype_EffectivePermissions(c *check.C) {
8 G.globalData.InitVartypes() 8 G.globalData.InitVartypes()
9 9
10 if t := G.globalData.vartypes["PREFIX"]; c.Check(t, check.NotNil) { 10 if t := G.globalData.vartypes["PREFIX"]; c.Check(t, check.NotNil) {
11 c.Check(t.basicType.name, equals, "Pathname") 11 c.Check(t.basicType.name, equals, "Pathname")
12 c.Check(t.aclEntries, check.DeepEquals, []AclEntry{{glob: "*", permissions: aclpUse}}) 12 c.Check(t.aclEntries, check.DeepEquals, []ACLEntry{{glob: "*", permissions: aclpUse}})
13 c.Check(t.EffectivePermissions("Makefile"), equals, aclpUse) 13 c.Check(t.EffectivePermissions("Makefile"), equals, aclpUse)
14 } 14 }
15 15
16 if t := G.globalData.vartypes["EXTRACT_OPTS"]; c.Check(t, check.NotNil) { 16 if t := G.globalData.vartypes["EXTRACT_OPTS"]; c.Check(t, check.NotNil) {
17 c.Check(t.basicType.name, equals, "ShellWord") 17 c.Check(t.basicType.name, equals, "ShellWord")
18 c.Check(t.EffectivePermissions("Makefile"), equals, aclpAppend|aclpSet) 18 c.Check(t.EffectivePermissions("Makefile"), equals, aclpAppend|aclpSet)
19 c.Check(t.EffectivePermissions("../Makefile"), equals, aclpAppend|aclpSet) 19 c.Check(t.EffectivePermissions("../Makefile"), equals, aclpAppend|aclpSet)
20 c.Check(t.EffectivePermissions("options.mk"), equals, aclpUnknown) 20 c.Check(t.EffectivePermissions("options.mk"), equals, aclpUnknown)
21 } 21 }
22} 22}
23 23
24func (s *Suite) Test_VarChecker_HasEnum(c *check.C) { 24func (s *Suite) Test_VarChecker_HasEnum(c *check.C) {
25 vc := enum("catinstall middle maninstall") 25 vc := enum("catinstall middle maninstall")
@@ -28,17 +28,17 @@ func (s *Suite) Test_VarChecker_HasEnum( @@ -28,17 +28,17 @@ func (s *Suite) Test_VarChecker_HasEnum(
28 c.Check(vc.HasEnum("middle"), equals, true) 28 c.Check(vc.HasEnum("middle"), equals, true)
29 c.Check(vc.HasEnum("maninstall"), equals, true) 29 c.Check(vc.HasEnum("maninstall"), equals, true)
30} 30}
31 31
32func (s *Suite) Test_AclPermissions_Contains(c *check.C) { 32func (s *Suite) Test_AclPermissions_Contains(c *check.C) {
33 perms := aclpAllRuntime 33 perms := aclpAllRuntime
34 34
35 c.Check(perms.Contains(aclpAllRuntime), equals, true) 35 c.Check(perms.Contains(aclpAllRuntime), equals, true)
36 c.Check(perms.Contains(aclpUse), equals, true) 36 c.Check(perms.Contains(aclpUse), equals, true)
37 c.Check(perms.Contains(aclpUseLoadtime), equals, false) 37 c.Check(perms.Contains(aclpUseLoadtime), equals, false)
38} 38}
39 39
40func (s *Suite) Test_AclPermissions_String(c *check.C) { 40func (s *Suite) Test_AclPermissions_String(c *check.C) {
41 c.Check(AclPermissions(0).String(), equals, "none") 41 c.Check(ACLPermissions(0).String(), equals, "none")
42 c.Check(aclpAll.String(), equals, "set, set-default, append, use-loadtime, use") 42 c.Check(aclpAll.String(), equals, "set, set-default, append, use-loadtime, use")
43 c.Check(aclpUnknown.String(), equals, "unknown") 43 c.Check(aclpUnknown.String(), equals, "unknown")
44} 44}

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

--- pkgsrc/pkgtools/pkglint/files/Attic/vartypecheck.go 2018/01/13 23:56:14 1.28
+++ pkgsrc/pkgtools/pkglint/files/Attic/vartypecheck.go 2018/02/19 12:40:38 1.29
@@ -664,27 +664,28 @@ func (cv *VartypeCheck) Pathlist() { @@ -664,27 +664,28 @@ func (cv *VartypeCheck) Pathlist() {
664 664
665// Shell globbing including slashes. 665// Shell globbing including slashes.
666// See Filemask 666// See Filemask
667func (cv *VartypeCheck) Pathmask() { 667func (cv *VartypeCheck) Pathmask() {
668 if cv.Op == opUseMatch { 668 if cv.Op == opUseMatch {
669 return 669 return
670 } 670 }
671 if !matches(cv.ValueNoVar, `^[#\-0-9A-Za-z._~+%*?/\[\]]*`) { 671 if !matches(cv.ValueNoVar, `^[#\-0-9A-Za-z._~+%*?/\[\]]*`) {
672 cv.Line.Warnf("%q is not a valid pathname mask.", cv.Value) 672 cv.Line.Warnf("%q is not a valid pathname mask.", cv.Value)
673 } 673 }
674 CheckLineAbsolutePathname(cv.Line, cv.Value) 674 CheckLineAbsolutePathname(cv.Line, cv.Value)
675} 675}
676 676
677// Like Filename, but including slashes 677// Like Filename, but including slashes.
 678//
678// See http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_266 679// See http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_266
679func (cv *VartypeCheck) Pathname() { 680func (cv *VartypeCheck) Pathname() {
680 if cv.Op == opUseMatch { 681 if cv.Op == opUseMatch {
681 return 682 return
682 } 683 }
683 if !matches(cv.ValueNoVar, `^[#\-0-9A-Za-z._~+%/]*$`) { 684 if !matches(cv.ValueNoVar, `^[#\-0-9A-Za-z._~+%/]*$`) {
684 cv.Line.Warnf("%q is not a valid pathname.", cv.Value) 685 cv.Line.Warnf("%q is not a valid pathname.", cv.Value)
685 } 686 }
686 CheckLineAbsolutePathname(cv.Line, cv.Value) 687 CheckLineAbsolutePathname(cv.Line, cv.Value)
687} 688}
688 689
689func (cv *VartypeCheck) Perl5Packlist() { 690func (cv *VartypeCheck) Perl5Packlist() {
690 if cv.Value != cv.ValueNoVar { 691 if cv.Value != cv.ValueNoVar {

cvs diff -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/textproc/Attic/prefixreplacer.go (expand / switch to unified diff)

--- pkgsrc/pkgtools/pkglint/files/textproc/Attic/prefixreplacer.go 2018/01/01 18:04:16 1.3
+++ pkgsrc/pkgtools/pkglint/files/textproc/Attic/prefixreplacer.go 2018/02/19 12:40:38 1.4
@@ -21,32 +21,32 @@ type PrefixReplacer struct { @@ -21,32 +21,32 @@ type PrefixReplacer struct {
21 21
22func NewPrefixReplacer(s string) *PrefixReplacer { 22func NewPrefixReplacer(s string) *PrefixReplacer {
23 return &PrefixReplacer{s, "", nil} 23 return &PrefixReplacer{s, "", nil}
24} 24}
25 25
26func (pr *PrefixReplacer) EOF() bool { 26func (pr *PrefixReplacer) EOF() bool {
27 return pr.rest == "" 27 return pr.rest == ""
28} 28}
29 29
30func (pr *PrefixReplacer) Rest() string { 30func (pr *PrefixReplacer) Rest() string {
31 return pr.rest 31 return pr.rest
32} 32}
33 33
34// Match returns a matching group from the last matched AdvanceRegexp. 34// Group returns a matching group from the last matched AdvanceRegexp.
35func (pr *PrefixReplacer) Group(index int) string { 35func (pr *PrefixReplacer) Group(index int) string {
36 return pr.m[index] 36 return pr.m[index]
37} 37}
38 38
39// Rest returns the last match from AdvanceStr, AdvanceBytesFunc or AdvanceHspace. 39// Str returns the last match from AdvanceStr, AdvanceBytesFunc or AdvanceHspace.
40func (pr *PrefixReplacer) Str() string { 40func (pr *PrefixReplacer) Str() string {
41 return pr.s 41 return pr.s
42} 42}
43 43
44func (pr *PrefixReplacer) AdvanceStr(prefix string) bool { 44func (pr *PrefixReplacer) AdvanceStr(prefix string) bool {
45 pr.m = nil 45 pr.m = nil
46 pr.s = "" 46 pr.s = ""
47 if strings.HasPrefix(pr.rest, prefix) { 47 if strings.HasPrefix(pr.rest, prefix) {
48 if trace.Tracing { 48 if trace.Tracing {
49 trace.Stepf("PrefixReplacer.AdvanceStr(%q, %q)", pr.rest, prefix) 49 trace.Stepf("PrefixReplacer.AdvanceStr(%q, %q)", pr.rest, prefix)
50 } 50 }
51 pr.s = prefix 51 pr.s = prefix
52 pr.rest = pr.rest[len(prefix):] 52 pr.rest = pr.rest[len(prefix):]