pkgsrc-Changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
CVS commit: pkgsrc/pkgtools/pkglint
Module Name: pkgsrc
Committed By: rillig
Date: Thu Aug 16 20:41:42 UTC 2018
Modified Files:
pkgsrc/pkgtools/pkglint: Makefile
pkgsrc/pkgtools/pkglint/files: alternatives.go alternatives_test.go
autofix_test.go buildlink3_test.go category.go check_test.go
distinfo.go distinfo_test.go files.go files_test.go
licenses_test.go logging.go mkline.go mkline_test.go
mklinechecker.go mklinechecker_test.go mklines.go mklines_test.go
mkparser.go mkparser_test.go options.go options_test.go package.go
package_test.go parser_test.go patches_test.go pkglint.go
pkglint_test.go pkgsrc.go pkgsrc_test.go plist.go plist_test.go
shell_test.go shtypes_test.go substcontext.go substcontext_test.go
tools.go tools_test.go toplevel.go util.go util_test.go vardefs.go
vardefs_test.go vartype.go vartypecheck.go vartypecheck_test.go
pkgsrc/pkgtools/pkglint/files/regex: regex.go
Log Message:
pkgtools/pkglint: update to 5.6.1
Changes since 5.6.0:
* Fix output of relative paths in the diagnostics (thanks @wiz)
* Fix parsing of ${VAR:ts---}; it is now a syntax error
* Load more type definitions from mk/* instead of hard-coding them
* Lots of refactoring to improve test coverage, fixing several
small bugs as they were found
To generate a diff of this commit:
cvs rdiff -u -r1.546 -r1.547 pkgsrc/pkgtools/pkglint/Makefile
cvs rdiff -u -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/alternatives.go \
pkgsrc/pkgtools/pkglint/files/shtypes_test.go
cvs rdiff -u -r1.2 -r1.3 pkgsrc/pkgtools/pkglint/files/alternatives_test.go \
pkgsrc/pkgtools/pkglint/files/options.go \
pkgsrc/pkgtools/pkglint/files/options_test.go \
pkgsrc/pkgtools/pkglint/files/tools.go \
pkgsrc/pkgtools/pkglint/files/tools_test.go
cvs rdiff -u -r1.8 -r1.9 pkgsrc/pkgtools/pkglint/files/autofix_test.go
cvs rdiff -u -r1.15 -r1.16 pkgsrc/pkgtools/pkglint/files/buildlink3_test.go \
pkgsrc/pkgtools/pkglint/files/distinfo_test.go \
pkgsrc/pkgtools/pkglint/files/files_test.go
cvs rdiff -u -r1.13 -r1.14 pkgsrc/pkgtools/pkglint/files/category.go \
pkgsrc/pkgtools/pkglint/files/licenses_test.go
cvs rdiff -u -r1.23 -r1.24 pkgsrc/pkgtools/pkglint/files/check_test.go \
pkgsrc/pkgtools/pkglint/files/plist_test.go
cvs rdiff -u -r1.21 -r1.22 pkgsrc/pkgtools/pkglint/files/distinfo.go
cvs rdiff -u -r1.17 -r1.18 pkgsrc/pkgtools/pkglint/files/files.go
cvs rdiff -u -r1.12 -r1.13 pkgsrc/pkgtools/pkglint/files/logging.go \
pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go \
pkgsrc/pkgtools/pkglint/files/mkparser_test.go \
pkgsrc/pkgtools/pkglint/files/substcontext_test.go \
pkgsrc/pkgtools/pkglint/files/toplevel.go
cvs rdiff -u -r1.35 -r1.36 pkgsrc/pkgtools/pkglint/files/mkline.go \
pkgsrc/pkgtools/pkglint/files/pkglint.go
cvs rdiff -u -r1.39 -r1.40 pkgsrc/pkgtools/pkglint/files/mkline_test.go
cvs rdiff -u -r1.16 -r1.17 pkgsrc/pkgtools/pkglint/files/mklinechecker.go
cvs rdiff -u -r1.29 -r1.30 pkgsrc/pkgtools/pkglint/files/mklines.go \
pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go
cvs rdiff -u -r1.25 -r1.26 pkgsrc/pkgtools/pkglint/files/mklines_test.go
cvs rdiff -u -r1.14 -r1.15 pkgsrc/pkgtools/pkglint/files/mkparser.go \
pkgsrc/pkgtools/pkglint/files/vartype.go
cvs rdiff -u -r1.33 -r1.34 pkgsrc/pkgtools/pkglint/files/package.go
cvs rdiff -u -r1.27 -r1.28 pkgsrc/pkgtools/pkglint/files/package_test.go
cvs rdiff -u -r1.7 -r1.8 pkgsrc/pkgtools/pkglint/files/parser_test.go \
pkgsrc/pkgtools/pkglint/files/pkgsrc.go
cvs rdiff -u -r1.18 -r1.19 pkgsrc/pkgtools/pkglint/files/patches_test.go
cvs rdiff -u -r1.22 -r1.23 pkgsrc/pkgtools/pkglint/files/pkglint_test.go
cvs rdiff -u -r1.5 -r1.6 pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go
cvs rdiff -u -r1.26 -r1.27 pkgsrc/pkgtools/pkglint/files/plist.go \
pkgsrc/pkgtools/pkglint/files/util.go
cvs rdiff -u -r1.28 -r1.29 pkgsrc/pkgtools/pkglint/files/shell_test.go
cvs rdiff -u -r1.11 -r1.12 pkgsrc/pkgtools/pkglint/files/substcontext.go \
pkgsrc/pkgtools/pkglint/files/util_test.go
cvs rdiff -u -r1.43 -r1.44 pkgsrc/pkgtools/pkglint/files/vardefs.go
cvs rdiff -u -r1.1 -r1.2 pkgsrc/pkgtools/pkglint/files/vardefs_test.go
cvs rdiff -u -r1.37 -r1.38 pkgsrc/pkgtools/pkglint/files/vartypecheck.go
cvs rdiff -u -r1.2 -r1.3 pkgsrc/pkgtools/pkglint/files/regex/regex.go
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: pkgsrc/pkgtools/pkglint/Makefile
diff -u pkgsrc/pkgtools/pkglint/Makefile:1.546 pkgsrc/pkgtools/pkglint/Makefile:1.547
--- pkgsrc/pkgtools/pkglint/Makefile:1.546 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/Makefile Thu Aug 16 20:41:42 2018
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.546 2018/08/12 16:31:56 rillig Exp $
+# $NetBSD: Makefile,v 1.547 2018/08/16 20:41:42 rillig Exp $
-PKGNAME= pkglint-5.6.0
+PKGNAME= pkglint-5.6.1
DISTFILES= # none
CATEGORIES= pkgtools
Index: pkgsrc/pkgtools/pkglint/files/alternatives.go
diff -u pkgsrc/pkgtools/pkglint/files/alternatives.go:1.3 pkgsrc/pkgtools/pkglint/files/alternatives.go:1.4
--- pkgsrc/pkgtools/pkglint/files/alternatives.go:1.3 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/alternatives.go Thu Aug 16 20:41:42 2018
@@ -6,8 +6,8 @@ import (
)
func CheckfileAlternatives(filename string, plistFiles map[string]bool) {
- lines, err := readLines(filename, false)
- if err != nil {
+ lines := Load(filename, NotEmpty|LogErrors)
+ if lines == nil {
return
}
Index: pkgsrc/pkgtools/pkglint/files/shtypes_test.go
diff -u pkgsrc/pkgtools/pkglint/files/shtypes_test.go:1.3 pkgsrc/pkgtools/pkglint/files/shtypes_test.go:1.4
--- pkgsrc/pkgtools/pkglint/files/shtypes_test.go:1.3 Sat Apr 28 23:32:52 2018
+++ pkgsrc/pkgtools/pkglint/files/shtypes_test.go Thu Aug 16 20:41:42 2018
@@ -32,3 +32,10 @@ func (s *Suite) Test_ShAtom_String(c *ch
func (s *Suite) Test_ShQuoting_String(c *check.C) {
c.Check(shqDquotBacktSquot.String(), equals, "dbs")
}
+
+func (s *Suite) Test_ShToken_String(c *check.C) {
+ tokenizer := NewShTokenizer(dummyLine, "${ECHO} \"hello, world\"", false)
+
+ c.Check(tokenizer.ShToken().String(), equals, "ShToken([varuse(\"ECHO\")])")
+ c.Check(tokenizer.ShToken().String(), equals, "ShToken([ShAtom(word, \"\\\"\", d) ShAtom(word, \"hello, world\", d) \"\\\"\"])")
+}
Index: pkgsrc/pkgtools/pkglint/files/alternatives_test.go
diff -u pkgsrc/pkgtools/pkglint/files/alternatives_test.go:1.2 pkgsrc/pkgtools/pkglint/files/alternatives_test.go:1.3
--- pkgsrc/pkgtools/pkglint/files/alternatives_test.go:1.2 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/alternatives_test.go Thu Aug 16 20:41:42 2018
@@ -5,23 +5,24 @@ import "gopkg.in/check.v1"
func (s *Suite) Test_Alternatives_PLIST(c *check.C) {
t := s.Init(c)
+ t.Chdir("category/package")
t.SetupFileLines("ALTERNATIVES",
"sbin/sendmail @PREFIX@/sbin/sendmail.postfix@POSTFIXVER@",
"sbin/sendmail @PREFIX@/sbin/sendmail.exim@EXIMVER@",
"bin/echo bin/gnu-echo",
"bin/editor bin/vim -e")
- G.Pkg = NewPackage("")
+ G.Pkg = NewPackage(".")
G.Pkg.PlistFiles["bin/echo"] = true
G.Pkg.PlistFiles["bin/vim"] = true
G.Pkg.PlistFiles["sbin/sendmail.exim${EXIMVER}"] = true
- CheckfileAlternatives(t.File("ALTERNATIVES"), G.Pkg.PlistFiles)
+ CheckfileAlternatives("ALTERNATIVES", G.Pkg.PlistFiles)
t.CheckOutputLines(
- "ERROR: ~/ALTERNATIVES:1: Alternative implementation \"@PREFIX@/sbin/sendmail.postfix@POSTFIXVER@\" must appear in the PLIST as \"sbin/sendmail.postfix${POSTFIXVER}\".",
- "NOTE: ~/ALTERNATIVES:1: @PREFIX@/ can be omitted from the file name.",
- "NOTE: ~/ALTERNATIVES:2: @PREFIX@/ can be omitted from the file name.",
- "ERROR: ~/ALTERNATIVES:3: Alternative wrapper \"bin/echo\" must not appear in the PLIST.",
- "ERROR: ~/ALTERNATIVES:3: Alternative implementation \"bin/gnu-echo\" must appear in the PLIST.")
+ "ERROR: ALTERNATIVES:1: Alternative implementation \"@PREFIX@/sbin/sendmail.postfix@POSTFIXVER@\" must appear in the PLIST as \"sbin/sendmail.postfix${POSTFIXVER}\".",
+ "NOTE: ALTERNATIVES:1: @PREFIX@/ can be omitted from the file name.",
+ "NOTE: ALTERNATIVES:2: @PREFIX@/ can be omitted from the file name.",
+ "ERROR: ALTERNATIVES:3: Alternative wrapper \"bin/echo\" must not appear in the PLIST.",
+ "ERROR: ALTERNATIVES:3: Alternative implementation \"bin/gnu-echo\" must appear in the PLIST.")
}
Index: pkgsrc/pkgtools/pkglint/files/options.go
diff -u pkgsrc/pkgtools/pkglint/files/options.go:1.2 pkgsrc/pkgtools/pkglint/files/options.go:1.3
--- pkgsrc/pkgtools/pkglint/files/options.go:1.2 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/options.go Thu Aug 16 20:41:42 2018
@@ -45,7 +45,7 @@ loop:
}
}
- case mkline.IsCond():
+ case mkline.IsDirective():
// The conditionals are typically for OPSYS and MACHINE_ARCH.
case mkline.IsInclude():
@@ -74,7 +74,7 @@ loop:
for ; !exp.EOF(); exp.Advance() {
mkline := exp.CurrentMkLine()
- if mkline.IsCond() && (mkline.Directive() == "if" || mkline.Directive() == "elif") {
+ if mkline.IsDirective() && (mkline.Directive() == "if" || mkline.Directive() == "elif") {
cond := NewMkParser(mkline.Line, mkline.Args(), false).MkCond()
if cond == nil {
continue
Index: pkgsrc/pkgtools/pkglint/files/options_test.go
diff -u pkgsrc/pkgtools/pkglint/files/options_test.go:1.2 pkgsrc/pkgtools/pkglint/files/options_test.go:1.3
--- pkgsrc/pkgtools/pkglint/files/options_test.go:1.2 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/options_test.go Thu Aug 16 20:41:42 2018
@@ -87,7 +87,7 @@ func (s *Suite) Test_ChecklinesOptionsMk
"WARN: ~/category/package/options.mk:7: Expected inclusion of \"../../mk/bsd.options.mk\".")
}
-func (s *Suite) Test_ChecklinesOptionsMk__malformed_conditional(c *check.C) {
+func (s *Suite) Test_ChecklinesOptionsMk__malformed_condition(c *check.C) {
t := s.Init(c)
t.SetupCommandLine("-Wno-space")
@@ -115,5 +115,5 @@ func (s *Suite) Test_ChecklinesOptionsMk
ChecklinesOptionsMk(mklines)
t.CheckOutputLines(
- "WARN: ~/category/package/options.mk:9: Invalid conditional \"${OPSYS} == 'Darwin'\".")
+ "WARN: ~/category/package/options.mk:9: Invalid condition, unrecognized part: \"${OPSYS} == 'Darwin'\".")
}
Index: pkgsrc/pkgtools/pkglint/files/tools.go
diff -u pkgsrc/pkgtools/pkglint/files/tools.go:1.2 pkgsrc/pkgtools/pkglint/files/tools.go:1.3
--- pkgsrc/pkgtools/pkglint/files/tools.go:1.2 Sat Apr 28 23:32:52 2018
+++ pkgsrc/pkgtools/pkglint/files/tools.go Thu Aug 16 20:41:42 2018
@@ -6,13 +6,17 @@ import (
"strings"
)
+// Tool is one of the many standard shell utilities that are typically
+// provided by the operating system, or, if missing, are installed via
+// pkgsrc.
+//
// See `mk/tools/`.
type Tool struct {
Name string // e.g. "sed", "gzip"
Varname string // e.g. "SED", "GZIP_CMD"
MustUseVarForm bool // True for `echo`, because of many differing implementations.
Predefined bool // This tool is used by the pkgsrc infrastructure, therefore the package does not need to add it to `USE_TOOLS` explicitly.
- UsableAtLoadtime bool // May be used after including `bsd.prefs.mk`.
+ UsableAtLoadTime bool // May be used after including `bsd.prefs.mk`.
}
type ToolRegistry struct {
@@ -28,9 +32,9 @@ func NewToolRegistry() ToolRegistry {
// The tool may then be used by this name (e.g. "awk"),
// but not by a corresponding variable (e.g. ${AWK}).
// The toolname may include the scope (:pkgsrc, :run, etc.).
-func (tr *ToolRegistry) Register(toolname string, line Line) *Tool {
+func (tr *ToolRegistry) Register(toolname string, mkline MkLine) *Tool {
name := strings.SplitN(toolname, ":", 2)[0]
- tr.validateToolName(name, line)
+ tr.validateToolName(name, mkline)
tool := tr.byName[name]
if tool == nil {
@@ -40,15 +44,15 @@ func (tr *ToolRegistry) Register(toolnam
return tool
}
-func (tr *ToolRegistry) RegisterVarname(toolname, varname string, line Line) *Tool {
- tool := tr.Register(toolname, line)
+func (tr *ToolRegistry) RegisterVarname(toolname, varname string, mkline MkLine) *Tool {
+ tool := tr.Register(toolname, mkline)
tool.Varname = varname
tr.byVarname[varname] = tool
return tool
}
-func (tr *ToolRegistry) RegisterTool(tool *Tool, line Line) {
- tr.validateToolName(tool.Name, line)
+func (tr *ToolRegistry) RegisterTool(tool *Tool, mkline MkLine) {
+ tr.validateToolName(tool.Name, mkline)
if tool.Name != "" && tr.byName[tool.Name] == nil {
tr.byName[tool.Name] = tool
@@ -90,24 +94,23 @@ func (tr *ToolRegistry) Trace() {
// ParseToolLine parses a tool definition from the pkgsrc infrastructure,
// e.g. in mk/tools/replace.mk.
-func (tr *ToolRegistry) ParseToolLine(line Line) {
- if m, commented, varname, _, _, _, value, _, _ := MatchVarassign(line.Text); m {
- if commented {
- return
- }
+func (tr *ToolRegistry) ParseToolLine(mkline MkLine) {
+ if mkline.IsVarassign() {
+ varname := mkline.Varname()
+ value := mkline.Value()
if varname == "TOOLS_CREATE" && (value == "[" || matches(value, `^?[-\w.]+$`)) {
- tr.Register(value, line)
+ tr.Register(value, mkline)
} else if m, toolname := match1(varname, `^_TOOLS_VARNAME\.([-\w.]+|\[)$`); m {
- tr.RegisterVarname(toolname, value, line)
+ tr.RegisterVarname(toolname, value, mkline)
- } else if m, toolname := match1(varname, `^(?:TOOLS_PATH|_TOOLS_DEPMETHOD)\.([-\w.]+|\[)$`); m {
- tr.Register(toolname, line)
+ } else if m, toolname = match1(varname, `^(?:TOOLS_PATH|_TOOLS_DEPMETHOD)\.([-\w.]+|\[)$`); m {
+ tr.Register(toolname, mkline)
- } else if m, toolname := match1(varname, `^_TOOLS\.(.*)`); m {
- tr.Register(toolname, line)
+ } else if m, toolname = match1(varname, `^_TOOLS\.(.*)`); m {
+ tr.Register(toolname, mkline)
for _, tool := range splitOnSpace(value) {
- tr.Register(tool, line)
+ tr.Register(tool, mkline)
}
}
}
@@ -127,8 +130,8 @@ func (tr *ToolRegistry) ForEach(action f
}
}
-func (tr *ToolRegistry) validateToolName(toolName string, line Line) {
+func (tr *ToolRegistry) validateToolName(toolName string, mkline MkLine) {
if toolName != "echo -n" && !matches(toolName, `^([-a-z0-9.]+|\[)$`) {
- line.Errorf("Invalid tool name %q", toolName)
+ mkline.Errorf("Invalid tool name %q.", toolName)
}
}
Index: pkgsrc/pkgtools/pkglint/files/tools_test.go
diff -u pkgsrc/pkgtools/pkglint/files/tools_test.go:1.2 pkgsrc/pkgtools/pkglint/files/tools_test.go:1.3
--- pkgsrc/pkgtools/pkglint/files/tools_test.go:1.2 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/tools_test.go Thu Aug 16 20:41:42 2018
@@ -17,3 +17,16 @@ func (s *Suite) Test_ToolRegistry_ParseT
// No error about "Unknown tool \"NetBSD\"."
t.CheckOutputEmpty()
}
+
+func (s *Suite) Test_ToolRegistry_validateToolName__invalid(c *check.C) {
+ t := s.Init(c)
+
+ reg := NewToolRegistry()
+
+ reg.Register("tool_name", dummyMkLine)
+
+ // Currently, the underscore is not used in any tool name.
+ // If there should ever be such a case, just use a different character.
+ t.CheckOutputLines(
+ "ERROR: Invalid tool name \"tool_name\".")
+}
Index: pkgsrc/pkgtools/pkglint/files/autofix_test.go
diff -u pkgsrc/pkgtools/pkglint/files/autofix_test.go:1.8 pkgsrc/pkgtools/pkglint/files/autofix_test.go:1.9
--- pkgsrc/pkgtools/pkglint/files/autofix_test.go:1.8 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/autofix_test.go Thu Aug 16 20:41:42 2018
@@ -117,7 +117,7 @@ func (s *Suite) Test_autofix_MkLines(c *
"line1 := value1",
"line2 := value2",
"line3 := value3")
- pkg := NewPackage("category/basename")
+ pkg := NewPackage(t.File("category/basename"))
G.Pkg = pkg
mklines := pkg.loadPackageMakefile()
G.Pkg = nil
@@ -259,7 +259,7 @@ func (s *Suite) Test_Autofix_show_source
t.SetupCommandLine("--show-autofix", "--source")
mklines := t.SetupFileMkLines("Makefile",
MkRcsID,
- "before \\",
+ "# before \\",
"The old song \\",
"after")
line := mklines.lines[1]
@@ -274,7 +274,7 @@ func (s *Suite) Test_Autofix_show_source
t.CheckOutputLines(
"WARN: ~/Makefile:2--4: Using \"old\" is deprecated.",
"AUTOFIX: ~/Makefile:3: Replacing \"old\" with \"new\".",
- ">\tbefore \\",
+ ">\t# before \\",
"-\tThe old song \\",
"+\tThe new song \\",
">\tafter")
Index: pkgsrc/pkgtools/pkglint/files/buildlink3_test.go
diff -u pkgsrc/pkgtools/pkglint/files/buildlink3_test.go:1.15 pkgsrc/pkgtools/pkglint/files/buildlink3_test.go:1.16
--- pkgsrc/pkgtools/pkglint/files/buildlink3_test.go:1.15 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/buildlink3_test.go Thu Aug 16 20:41:42 2018
@@ -41,7 +41,7 @@ func (s *Suite) Test_ChecklinesBuildlink
t := s.Init(c)
t.SetupVartypes()
- G.Pkg = NewPackage("x11/hs-X11")
+ G.Pkg = NewPackage(t.File("x11/hs-X11"))
G.Pkg.EffectivePkgbase = "X11"
G.Pkg.EffectivePkgnameLine = t.NewMkLine("Makefile", 3, "DISTNAME=\tX11-1.0")
mklines := t.NewMkLines("buildlink3.mk",
Index: pkgsrc/pkgtools/pkglint/files/distinfo_test.go
diff -u pkgsrc/pkgtools/pkglint/files/distinfo_test.go:1.15 pkgsrc/pkgtools/pkglint/files/distinfo_test.go:1.16
--- pkgsrc/pkgtools/pkglint/files/distinfo_test.go:1.15 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/distinfo_test.go Thu Aug 16 20:41:42 2018
@@ -5,28 +5,33 @@ import "gopkg.in/check.v1"
func (s *Suite) Test_ChecklinesDistinfo(c *check.C) {
t := s.Init(c)
- t.SetupFileLines("category/package/patches/patch-aa",
- "$"+"NetBSD$ line is ignored",
+ t.Chdir("category/package")
+ t.SetupFileLines("patches/patch-aa",
+ RcsID+" line is ignored for computing the SHA1 hash",
"patch contents")
- t.SetupFileLines("category/package/patches/patch-ab",
+ t.SetupFileLines("patches/patch-ab",
"patch contents")
- lines := t.SetupFileLines("category/package/distinfo",
+ lines := t.SetupFileLines("distinfo",
"should be the RCS ID",
"should be empty",
"MD5 (distfile.tar.gz) = 12345678901234567890123456789012",
"SHA1 (distfile.tar.gz) = 1234567890123456789012345678901234567890",
"SHA1 (patch-aa) = 6b98dd609f85a9eb9c4c1e4e7055a6aaa62b7cc7",
+ "Size (patch-aa) = 104",
"SHA1 (patch-ab) = 6b98dd609f85a9eb9c4c1e4e7055a6aaa62b7cc7",
+ "Another invalid line",
"SHA1 (patch-nonexistent) = 1234")
- G.Pkg = NewPackage("category/package")
+ G.Pkg = NewPackage(".")
ChecklinesDistinfo(lines)
t.CheckOutputLines(
- "ERROR: ~/category/package/distinfo:1: Expected \"$"+"NetBSD$\".",
- "NOTE: ~/category/package/distinfo:2: Empty line expected.",
- "ERROR: ~/category/package/distinfo:5: Expected SHA1, RMD160, SHA512, Size checksums for \"distfile.tar.gz\", got MD5, SHA1.",
- "WARN: ~/category/package/distinfo:7: Patch file \"patch-nonexistent\" does not exist in directory \"patches\".")
+ "ERROR: distinfo:1: Expected \"$"+"NetBSD$\".",
+ "NOTE: distinfo:2: Empty line expected.",
+ "ERROR: distinfo:5: Expected SHA1, RMD160, SHA512, Size checksums for \"distfile.tar.gz\", got MD5, SHA1.",
+ "ERROR: distinfo:7: Expected SHA1 hash for patch-aa, got SHA1, Size.",
+ "ERROR: distinfo:8: Invalid line.",
+ "WARN: distinfo:9: Patch file \"patch-nonexistent\" does not exist in directory \"patches\".")
}
func (s *Suite) Test_ChecklinesDistinfo_global_hash_mismatch(c *check.C) {
@@ -49,7 +54,8 @@ func (s *Suite) Test_ChecklinesDistinfo_
func (s *Suite) Test_ChecklinesDistinfo_uncommitted_patch(c *check.C) {
t := s.Init(c)
- t.SetupFileLines("category/package/patches/patch-aa",
+ t.Chdir("category/package")
+ t.SetupFileLines("patches/patch-aa",
RcsID,
"",
"--- oldfile",
@@ -57,45 +63,47 @@ func (s *Suite) Test_ChecklinesDistinfo_
"@@ -1,1 +1,1 @@",
"-old",
"+new")
- t.SetupFileLines("category/package/CVS/Entries",
+ t.SetupFileLines("CVS/Entries",
"/distinfo/...")
- lines := t.SetupFileLines("category/package/distinfo",
+ lines := t.SetupFileLines("distinfo",
RcsID,
"",
"SHA1 (patch-aa) = 5ad1fb9b3c328fff5caa1a23e8f330e707dd50c0")
- G.Pkg = NewPackage("category/package")
+ G.Pkg = NewPackage(".")
ChecklinesDistinfo(lines)
t.CheckOutputLines(
- "WARN: ~/category/package/distinfo:3: patches/patch-aa is registered in distinfo but not added to CVS.")
+ "WARN: distinfo:3: patches/patch-aa is registered in distinfo but not added to CVS.")
}
func (s *Suite) Test_ChecklinesDistinfo_unrecorded_patches(c *check.C) {
t := s.Init(c)
- t.SetupFileLines("category/package/patches/CVS/Entries")
- t.SetupFileLines("category/package/patches/patch-aa")
- t.SetupFileLines("category/package/patches/patch-src-Makefile")
- lines := t.SetupFileLines("category/package/distinfo",
+ t.Chdir("category/package")
+ t.SetupFileLines("patches/CVS/Entries")
+ t.SetupFileLines("patches/patch-aa")
+ t.SetupFileLines("patches/patch-src-Makefile")
+ lines := t.SetupFileLines("distinfo",
RcsID,
"",
"SHA1 (distfile.tar.gz) = ...",
"RMD160 (distfile.tar.gz) = ...",
"SHA512 (distfile.tar.gz) = ...",
"Size (distfile.tar.gz) = 1024 bytes")
- G.Pkg = NewPackage("category/package")
+ G.Pkg = NewPackage(".")
ChecklinesDistinfo(lines)
t.CheckOutputLines(
- "ERROR: ~/category/package/distinfo: patch \"patches/patch-aa\" is not recorded. Run \""+confMake+" makepatchsum\".",
- "ERROR: ~/category/package/distinfo: patch \"patches/patch-src-Makefile\" is not recorded. Run \""+confMake+" makepatchsum\".")
+ "ERROR: distinfo: patch \"patches/patch-aa\" is not recorded. Run \""+confMake+" makepatchsum\".",
+ "ERROR: distinfo: patch \"patches/patch-src-Makefile\" is not recorded. Run \""+confMake+" makepatchsum\".")
}
func (s *Suite) Test_ChecklinesDistinfo_manual_patches(c *check.C) {
t := s.Init(c)
+ t.Chdir("category/package")
t.CreateFileLines("patches/manual-libtool.m4")
lines := t.SetupFileLines("distinfo",
RcsID,
@@ -115,7 +123,7 @@ func (s *Suite) Test_ChecklinesDistinfo_
// When a distinfo file is checked in the context of a package,
// the PATCHDIR is known, therefore the checks are active.
t.CheckOutputLines(
- "WARN: ~/distinfo:3: Patch file \"patch-aa\" does not exist in directory \"patches\".")
+ "WARN: distinfo:3: Patch file \"patch-aa\" does not exist in directory \"patches\".")
}
// PHP modules that are not PECL use the distinfo file from lang/php* but
Index: pkgsrc/pkgtools/pkglint/files/files_test.go
diff -u pkgsrc/pkgtools/pkglint/files/files_test.go:1.15 pkgsrc/pkgtools/pkglint/files/files_test.go:1.16
--- pkgsrc/pkgtools/pkglint/files/files_test.go:1.15 Thu Aug 9 20:08:12 2018
+++ pkgsrc/pkgtools/pkglint/files/files_test.go Thu Aug 16 20:41:42 2018
@@ -150,3 +150,23 @@ func (s *Suite) Test_splitRawLine(c *che
c.Check(trailingWhitespace, equals, " ")
c.Check(continuation, equals, "\\")
}
+
+func (s *Suite) Test_Load(c *check.C) {
+ t := s.Init(c)
+
+ t.CreateFileLines("empty")
+
+ func() {
+ defer t.ExpectFatalError()
+ Load(t.File("does-not-exist"), MustSucceed)
+ }()
+
+ func() {
+ defer t.ExpectFatalError()
+ Load(t.File("empty"), MustSucceed|NotEmpty)
+ }()
+
+ t.CheckOutputLines(
+ "FATAL: ~/does-not-exist: Cannot be read.",
+ "FATAL: ~/empty: Must not be empty.")
+}
Index: pkgsrc/pkgtools/pkglint/files/category.go
diff -u pkgsrc/pkgtools/pkglint/files/category.go:1.13 pkgsrc/pkgtools/pkglint/files/category.go:1.14
--- pkgsrc/pkgtools/pkglint/files/category.go:1.13 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/category.go Thu Aug 16 20:41:42 2018
@@ -10,12 +10,11 @@ func CheckdirCategory(dir string) {
defer trace.Call1(dir)()
}
- lines := LoadNonemptyLines(dir+"/Makefile", true)
- if lines == nil {
+ mklines := LoadMk(dir+"/Makefile", NotEmpty|LogErrors)
+ if mklines == nil {
return
}
- mklines := NewMkLines(lines)
mklines.Check()
exp := NewMkExpecter(mklines)
@@ -164,7 +163,7 @@ func CheckdirCategory(dir string) {
exp.CurrentLine().Errorf("The file should end here.")
}
- SaveAutofixChanges(lines)
+ mklines.SaveAutofixChanges()
if G.opts.Recursive {
G.Todo = append(append([]string(nil), subdirs...), G.Todo...)
Index: pkgsrc/pkgtools/pkglint/files/licenses_test.go
diff -u pkgsrc/pkgtools/pkglint/files/licenses_test.go:1.13 pkgsrc/pkgtools/pkglint/files/licenses_test.go:1.14
--- pkgsrc/pkgtools/pkglint/files/licenses_test.go:1.13 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/licenses_test.go Thu Aug 16 20:41:42 2018
@@ -47,16 +47,7 @@ func (s *Suite) Test_checklineLicense(c
func (s *Suite) Test_checkToplevelUnusedLicenses(c *check.C) {
t := s.Init(c)
- t.SetupFileLines("mk/bsd.pkg.mk", "# dummy")
- t.SetupFileLines("mk/fetch/sites.mk", "# dummy")
- t.SetupFileLines("mk/defaults/options.description", "option\tdescription")
- t.SetupFileLines("doc/TODO")
- t.SetupFileLines("mk/defaults/mk.conf")
- t.SetupFileLines("mk/tools/bsd.tools.mk",
- ".include \"actual-tools.mk\"")
- t.SetupFileLines("mk/tools/actual-tools.mk")
- t.SetupFileLines("mk/tools/defaults.mk")
- t.SetupFileLines("mk/bsd.prefs.mk")
+ t.SetupPkgsrc()
t.SetupFileLines("mk/misc/category.mk")
t.SetupFileLines("licenses/2-clause-bsd")
t.SetupFileLines("licenses/gnu-gpl-v3")
@@ -90,3 +81,36 @@ func (s *Suite) Test_checkToplevelUnused
"WARN: ~/licenses/gnu-gpl-v3: This license seems to be unused.",
"0 errors and 1 warning found.")
}
+
+func (s *Suite) Test_LicenseChecker_checkLicenseName__LICENSE_FILE(c *check.C) {
+ t := s.Init(c)
+
+ t.SetupPkgsrc()
+ t.SetupCommandLine("-Wno-space")
+ t.SetupFileLines("category/package/DESCR",
+ "Package description")
+ t.SetupFileMkLines("category/package/Makefile",
+ MkRcsID,
+ "",
+ "CATEGORIES= chinese",
+ "",
+ "COMMENT= Useful tools",
+ "LICENSE= my-license",
+ "",
+ "LICENSE_FILE= my-license",
+ "NO_CHECKSUM= yes",
+ "",
+ ".include \"../../mk/bsd.pkg.mk\"")
+ t.SetupFileLines("category/package/PLIST",
+ PlistRcsID,
+ "bin/program")
+ t.SetupFileLines("category/package/my-license",
+ "An individual license file.")
+
+ G.Main("pkglint", t.File("category/package"))
+
+ // FIXME: It should be allowed to place a license file directly into
+ // the package directory.
+ t.CheckOutputLines(
+ "WARN: ~/category/package/my-license: Unexpected file found.", "0 errors and 1 warning found.")
+}
Index: pkgsrc/pkgtools/pkglint/files/check_test.go
diff -u pkgsrc/pkgtools/pkglint/files/check_test.go:1.23 pkgsrc/pkgtools/pkglint/files/check_test.go:1.24
--- pkgsrc/pkgtools/pkglint/files/check_test.go:1.23 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/check_test.go Thu Aug 16 20:41:42 2018
@@ -58,12 +58,23 @@ func (s *Suite) SetUpTest(c *check.C) {
t.checkC = nil
G.opts.LogVerbose = true // To detect duplicate work being done
+ t.EnableSilentTracing()
+
+ prevdir, err := os.Getwd()
+ if err != nil {
+ c.Fatalf("Cannot get current working directory: %s", err)
+ }
+ t.prevdir = prevdir
}
func (s *Suite) TearDownTest(c *check.C) {
t := s.Tester
t.checkC = nil // No longer usable; see https://github.com/go-check/check/issues/22
+ if err := os.Chdir(t.prevdir); err != nil {
+ fmt.Fprintf(os.Stderr, "Cannot chdir back to previous dir: %s", err)
+ }
+
G = Pkglint{} // unusable because of missing logOut and logErr
textproc.Testing = false
if out := t.Output(); out != "" {
@@ -71,6 +82,7 @@ func (s *Suite) TearDownTest(c *check.C)
c.TestName(), strings.Split(out, "\n"))
}
t.tmpdir = ""
+ t.DisableTracing()
}
var _ = check.Suite(new(Suite))
@@ -82,10 +94,12 @@ func Test(t *testing.T) { check.TestingT
// all the test methods, which makes it difficult to find
// a method by auto-completion.
type Tester struct {
- stdout bytes.Buffer
- stderr bytes.Buffer
- tmpdir string
- checkC *check.C
+ stdout bytes.Buffer
+ stderr bytes.Buffer
+ tmpdir string
+ checkC *check.C // Only usable during the test method itself
+ prevdir string // The current working directory before the test started
+ relcwd string
}
func (t *Tester) c() *check.C {
@@ -98,6 +112,11 @@ func (t *Tester) c() *check.C {
// SetupCommandLine simulates a command line for the remainder of the test.
// See Pkglint.ParseCommandLine.
func (t *Tester) SetupCommandLine(args ...string) {
+
+ // Prevent tracing from being disabled; see EnableSilentTracing.
+ prevTracing := trace.Tracing
+ defer func() { trace.Tracing = prevTracing }()
+
exitcode := G.ParseCommandLine(append([]string{"pkglint"}, args...))
if exitcode != nil && *exitcode != 0 {
t.CheckOutputEmpty()
@@ -149,15 +168,14 @@ func (t *Tester) SetupTool(tool *Tool) {
// The file is then read in, without considering line continuations.
func (t *Tester) SetupFileLines(relativeFilename string, lines ...string) []Line {
filename := t.CreateFileLines(relativeFilename, lines...)
- return LoadExistingLines(filename, false)
+ return Load(filename, MustSucceed)
}
// SetupFileLines creates a temporary file and writes the given lines to it.
// The file is then read in, handling line continuations for Makefiles.
func (t *Tester) SetupFileMkLines(relativeFilename string, lines ...string) *MkLines {
filename := t.CreateFileLines(relativeFilename, lines...)
- plainLines := LoadExistingLines(filename, true)
- return NewMkLines(plainLines)
+ return LoadMk(filename, MustSucceed)
}
// SetupPkgsrc sets up a minimal but complete pkgsrc installation in the
@@ -222,21 +240,62 @@ func (t *Tester) CreateFileLines(relativ
// File returns the absolute path to the given file in the
// temporary directory. It doesn't check whether that file exists.
+// Calls to Tester.Chdir change the base directory for the relative file name.
func (t *Tester) File(relativeFilename string) string {
if t.tmpdir == "" {
t.tmpdir = filepath.ToSlash(t.c().MkDir())
}
- return t.tmpdir + "/" + relativeFilename
+ if t.relcwd != "" {
+ return cleanpath(relativeFilename)
+ }
+ return cleanpath(t.tmpdir + "/" + relativeFilename)
}
-// ExpectFatalError, when run in a defer statement, runs the action
-// if the current function panics with a pkglintFatal
-// (typically from line.Fatalf).
-func (t *Tester) ExpectFatalError(action func()) {
+// Chdir changes the current working directory to the given subdirectory
+// of the temporary directory, creating it if necessary.
+//
+// After this call, all files loaded from the temporary directory via
+// SetupFileLines or CreateFileLines or similar methods will use path names
+// relative to this directory.
+//
+// After the test, the previous working directory is restored, so that
+// the other tests are unaffected.
+//
+// As long as this method is not called in a test, the current working
+// directory is indeterminate.
+func (t *Tester) Chdir(relativeFilename string) {
+ if t.relcwd != "" {
+ // When multiple calls of Chdir are mixed with calls to CreateFileLines,
+ // the resulting []Line and MkLines variables will use relative file names,
+ // and these will point to different areas in the file system. This is
+ // usually not indented and therefore prevented.
+ t.checkC.Fatalf("Chdir must only be called once per test; already in %q.", t.relcwd)
+ }
+
+ _ = os.MkdirAll(t.File(relativeFilename), 0700)
+ if err := os.Chdir(t.File(relativeFilename)); err != nil {
+ t.checkC.Fatalf("Cannot chdir: %s", err)
+ }
+ t.relcwd = relativeFilename
+}
+
+// ExpectFatalError promises that in the remainder of the current function
+// call, a panic with a pkglintFatal will occur (typically from Line.Fatalf).
+//
+// Usage:
+// func() {
+// defer t.ExpectFatalError()
+//
+// // The code that causes the fatal error.
+// Load(t.File("nonexistent"), MustSucceed)
+// }()
+// t.CheckOutputLines(
+// "FATAL: ~/nonexistent: Does not exist.")
+func (t *Tester) ExpectFatalError() {
r := recover()
- if _, ok := r.(pkglintFatal); ok {
- action()
- } else {
+ if r == nil {
+ panic("Expected a pkglint fatal error, but didn't get one.")
+ } else if _, ok := r.(pkglintFatal); !ok {
panic(r)
}
}
@@ -344,12 +403,28 @@ func (t *Tester) EnableTracing() {
trace.Tracing = true
}
+// EnableTracingToLog enables the tracing and writes the tracing output
+// to the test log that can be examined with Tester.Output.
+func (t *Tester) EnableTracingToLog() {
+ G.logOut = NewSeparatorWriter(io.MultiWriter(os.Stdout, &t.stdout))
+ trace.Out = &t.stdout
+ trace.Tracing = true
+}
+
+// EnableSilentTracing enables tracing mode, but discards any tracing output.
+// This can be used to improve code coverage without any side-effects,
+// since tracing output is quite large.
+func (t *Tester) EnableSilentTracing() {
+ trace.Out = ioutil.Discard
+ trace.Tracing = true
+}
+
// DisableTracing logs the output to the buffers again, ready to be
// checked with CheckOutputLines.
func (t *Tester) DisableTracing() {
G.logOut = NewSeparatorWriter(&t.stdout)
- trace.Out = &t.stdout
trace.Tracing = false
+ trace.Out = nil
}
// CheckFileLines loads the lines from the temporary file and checks that
@@ -368,10 +443,7 @@ func (t *Tester) CheckFileLines(relative
// for indentation, while the lines in the code use spaces exclusively,
// in order to make the depth of the indentation clearly visible.
func (t *Tester) CheckFileLinesDetab(relativeFileName string, lines ...string) {
- actualLines, err := readLines(t.File(relativeFileName), false)
- if !t.c().Check(err, check.IsNil) {
- return
- }
+ actualLines := Load(t.File(relativeFileName), MustSucceed)
var detabbed []string
for _, line := range actualLines {
Index: pkgsrc/pkgtools/pkglint/files/plist_test.go
diff -u pkgsrc/pkgtools/pkglint/files/plist_test.go:1.23 pkgsrc/pkgtools/pkglint/files/plist_test.go:1.24
--- pkgsrc/pkgtools/pkglint/files/plist_test.go:1.23 Sat Mar 24 14:32:49 2018
+++ pkgsrc/pkgtools/pkglint/files/plist_test.go Thu Aug 16 20:41:42 2018
@@ -6,7 +6,7 @@ func (s *Suite) Test_ChecklinesPlist(c *
t := s.Init(c)
t.SetupCommandLine("-Wall")
- G.Pkg = NewPackage("category/pkgbase")
+ G.Pkg = NewPackage(t.File("category/pkgbase"))
lines := t.NewLines("PLIST",
"bin/i386/6c",
"bin/program",
@@ -76,10 +76,10 @@ func (s *Suite) Test_ChecklinesPlist__co
t.CheckOutputEmpty()
}
-func (s *Suite) Test_ChecklinesPlist__conditional(c *check.C) {
+func (s *Suite) Test_ChecklinesPlist__condition(c *check.C) {
t := s.Init(c)
- G.Pkg = NewPackage("category/pkgbase")
+ G.Pkg = NewPackage(t.File("category/pkgbase"))
G.Pkg.plistSubstCond["PLIST.bincmds"] = true
lines := t.NewLines("PLIST",
PlistRcsID,
@@ -101,7 +101,7 @@ func (s *Suite) Test_ChecklinesPlist__so
"sbin/i386/6c",
"sbin/program",
"bin/otherprogram",
- "${PLIST.conditional}bin/cat")
+ "${PLIST.condition}bin/cat")
ChecklinesPlist(lines)
@@ -129,7 +129,7 @@ func (s *Suite) Test_PlistLineSorter_Sor
"man/man1/program.1",
"${PLIST.two}bin/program2",
"lib/before.la",
- "${PLIST.linux}${PLIST.x86_64}lib/lib-linux-x86_64.so", // Double conditional, see graphics/graphviz
+ "${PLIST.linux}${PLIST.x86_64}lib/lib-linux-x86_64.so", // Double condition, see graphics/graphviz
"lib/after.la",
"@exec echo \"after lib/after.la\"")
ck := &PlistChecker{nil, nil, "", Once{}}
@@ -155,7 +155,7 @@ func (s *Suite) Test_PlistLineSorter_Sor
"C",
"CCC",
"b",
- "${PLIST.one}bin/program", // Conditionals are ignored while sorting
+ "${PLIST.one}bin/program", // Conditional lines are ignored during sorting
"${PLIST.two}bin/program2",
"ddd",
"lib/after.la",
@@ -169,7 +169,7 @@ func (s *Suite) Test_PlistLineSorter_Sor
func (s *Suite) Test_PlistChecker_checkpathMan_gz(c *check.C) {
t := s.Init(c)
- G.Pkg = NewPackage("category/pkgbase")
+ G.Pkg = NewPackage(t.File("category/pkgbase"))
lines := t.NewLines("PLIST",
PlistRcsID,
"man/man3/strerror.3.gz")
@@ -211,7 +211,7 @@ func (s *Suite) Test_PlistChecker__autof
t.SetupCommandLine("-Wall")
- fname := t.CreateFileLines("PLIST",
+ lines := t.SetupFileLines("PLIST",
PlistRcsID,
"lib/libvirt/connection-driver/libvirt_driver_storage.la",
"${PLIST.hal}lib/libvirt/connection-driver/libvirt_driver_nodedev.la",
@@ -232,7 +232,7 @@ func (s *Suite) Test_PlistChecker__autof
"@pkgdir etc/libvirt/qemu/networks/autostart",
"@pkgdir etc/logrotate.d",
"@pkgdir etc/sasl2")
- lines := LoadExistingLines(fname, false)
+
ChecklinesPlist(lines)
t.CheckOutputLines(
@@ -245,12 +245,9 @@ func (s *Suite) Test_PlistChecker__autof
t.SetupCommandLine("-Wall", "--autofix")
ChecklinesPlist(lines)
- fixedLines := LoadExistingLines(fname, false)
-
t.CheckOutputLines(
"AUTOFIX: ~/PLIST:6: Replacing \"${PKGMANDIR}/\" with \"man/\".",
"AUTOFIX: ~/PLIST:2: Sorting the whole file.")
- c.Check(len(lines), equals, len(fixedLines))
t.CheckFileLines("PLIST",
PlistRcsID,
"${PLIST.xen}lib/libvirt/connection-driver/libvirt_driver_libxl.la",
@@ -274,9 +271,9 @@ func (s *Suite) Test_PlistChecker__autof
"@pkgdir etc/sasl2")
}
-// When the same entry appears both with and without a conditional,
-// the one with the conditional can be removed.
-// When the same entry appears with several different conditionals,
+// When the same entry appears both with and without a condition,
+// the one with the condition can be removed.
+// When the same entry appears with several different conditions,
// all of them must stay.
func (s *Suite) Test_PlistChecker__remove_same_entries(c *check.C) {
t := s.Init(c)
Index: pkgsrc/pkgtools/pkglint/files/distinfo.go
diff -u pkgsrc/pkgtools/pkglint/files/distinfo.go:1.21 pkgsrc/pkgtools/pkglint/files/distinfo.go:1.22
--- pkgsrc/pkgtools/pkglint/files/distinfo.go:1.21 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/distinfo.go Thu Aug 16 20:41:42 2018
@@ -68,7 +68,7 @@ func (ck *distinfoLinesChecker) checkLin
ck.algorithms = append(ck.algorithms, alg)
ck.checkGlobalMismatch(line, filename, alg, hash)
- ck.checkUncommittedPatch(line, filename, hash)
+ ck.checkUncommittedPatch(line, filename, alg, hash)
}
ck.onFilenameChange(NewLineEOF(ck.distinfoFilename), "")
}
@@ -149,13 +149,15 @@ func (ck *distinfoLinesChecker) checkGlo
}
}
-func (ck *distinfoLinesChecker) checkUncommittedPatch(line Line, patchName, sha1Hash string) {
+func (ck *distinfoLinesChecker) checkUncommittedPatch(line Line, patchName, alg, hash string) {
if ck.isPatch == yes {
patchFname := ck.patchdir + "/" + patchName
if ck.distinfoIsCommitted && !isCommitted(G.Pkg.File(patchFname)) {
line.Warnf("%s is registered in distinfo but not added to CVS.", patchFname)
}
- ck.checkPatchSha1(line, patchFname, sha1Hash)
+ if alg == "SHA1" {
+ ck.checkPatchSha1(line, patchFname, hash)
+ }
ck.patches[patchName] = true
}
}
@@ -194,7 +196,7 @@ func computePatchSha1Hex(patchFilename s
func AutofixDistinfo(oldSha1, newSha1 string) {
distinfoFilename := G.Pkg.File(G.Pkg.DistinfoFile)
- if lines, err := readLines(distinfoFilename, false); err == nil {
+ if lines := Load(distinfoFilename, NotEmpty|LogErrors); lines != nil {
for _, line := range lines {
fix := line.Autofix()
fix.Warnf("Silent-Magic-Diagnostic")
Index: pkgsrc/pkgtools/pkglint/files/files.go
diff -u pkgsrc/pkgtools/pkglint/files/files.go:1.17 pkgsrc/pkgtools/pkglint/files/files.go:1.18
--- pkgsrc/pkgtools/pkglint/files/files.go:1.17 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/files.go Thu Aug 16 20:41:42 2018
@@ -6,29 +6,51 @@ import (
"strings"
)
-// LoadNonemptyLines loads the given file.
-// If the file doesn't exist or is empty, an error is logged.
-//
-// See [LoadExistingLines].
-func LoadNonemptyLines(fname string, joinBackslashLines bool) []Line {
- lines, err := readLines(fname, joinBackslashLines)
+type LoadOptions uint8
+
+const (
+ MustSucceed LoadOptions = 1 << iota // It's a fatal error if loading fails.
+ NotEmpty // It is an error if the file is empty.
+ Makefile // Lines ending in a backslash are continued in the next line.
+ LogErrors //
+)
+
+func Load(fileName string, options LoadOptions) []Line {
+ rawBytes, err := ioutil.ReadFile(fileName)
if err != nil {
- NewLineWhole(fname).Errorf("Cannot be read.")
+ switch {
+ case options&MustSucceed != 0:
+ NewLineWhole(fileName).Fatalf("Cannot be read.")
+ case options&LogErrors != 0:
+ NewLineWhole(fileName).Errorf("Cannot be read.")
+ }
return nil
}
- if len(lines) == 0 {
- NewLineWhole(fname).Errorf("Must not be empty.")
+
+ rawText := string(rawBytes)
+ if rawText == "" && options&NotEmpty != 0 {
+ switch {
+ case options&MustSucceed != 0:
+ NewLineWhole(fileName).Fatalf("Must not be empty.")
+ case options&LogErrors != 0:
+ NewLineWhole(fileName).Errorf("Must not be empty.")
+ }
return nil
}
- return lines
+
+ if G.opts.Profiling {
+ G.loaded.Add(path.Clean(fileName), 1)
+ }
+
+ return convertToLogicalLines(fileName, rawText, options&Makefile != 0)
}
-func LoadExistingLines(fname string, joinBackslashLines bool) []Line {
- lines, err := readLines(fname, joinBackslashLines)
- if err != nil {
- NewLineWhole(fname).Fatalf("Cannot be read.")
+func LoadMk(fileName string, options LoadOptions) *MkLines {
+ lines := Load(fileName, options|Makefile)
+ if lines == nil {
+ return nil
}
- return lines
+ return NewMkLines(lines)
}
func nextLogicalLine(fname string, rawLines []*RawLine, pindex *int) Line {
@@ -106,18 +128,6 @@ func splitRawLine(textnl string) (leadin
return
}
-func readLines(fname string, joinBackslashLines bool) ([]Line, error) {
- rawText, err := ioutil.ReadFile(fname)
- if err != nil {
- return nil, err
- }
-
- if G.opts.Profiling {
- G.loaded.Add(path.Clean(fname), 1)
- }
- return convertToLogicalLines(fname, string(rawText), joinBackslashLines), nil
-}
-
func convertToLogicalLines(fname string, rawText string, joinBackslashLines bool) []Line {
var rawLines []*RawLine
for lineno, rawLine := range strings.SplitAfter(rawText, "\n") {
Index: pkgsrc/pkgtools/pkglint/files/logging.go
diff -u pkgsrc/pkgtools/pkglint/files/logging.go:1.12 pkgsrc/pkgtools/pkglint/files/logging.go:1.13
--- pkgsrc/pkgtools/pkglint/files/logging.go:1.12 Thu Jul 12 16:23:36 2018
+++ pkgsrc/pkgtools/pkglint/files/logging.go Thu Aug 16 20:41:42 2018
@@ -21,6 +21,7 @@ var (
)
var dummyLine = NewLine("", 0, "", nil)
+var dummyMkLine = NewMkLine(dummyLine)
func shallBeLogged(msg string) bool {
if len(G.opts.LogOnly) > 0 {
@@ -57,7 +58,7 @@ func logs(level *LogLevel, fname, lineno
fname = cleanpath(fname)
}
if G.Testing && format != "Magic-Autofix-Format" && !hasSuffix(format, ".") && !hasSuffix(format, ": %s") && !hasSuffix(format, ". %s") {
- panic(fmt.Sprintf("Format %q must end in a period.", format))
+ panic(fmt.Sprintf("Diagnostic format %q must end in a period.", format))
}
if !G.opts.LogVerbose && loggedAlready(fname, lineno, msg) {
Index: pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.12 pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.13
--- pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.12 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go Thu Aug 16 20:41:42 2018
@@ -42,7 +42,7 @@ func (s *Suite) Test_MkLineChecker_Check
func (s *Suite) Test_MkLineChecker_checkVarassign__URL_with_shell_special_characters(c *check.C) {
t := s.Init(c)
- G.Pkg = NewPackage("graphics/gimp-fix-ca")
+ G.Pkg = NewPackage(t.File("graphics/gimp-fix-ca"))
t.SetupVartypes()
mkline := t.NewMkLine("fname", 10, "MASTER_SITES=http://registry.gimp.org/file/fix-ca.c?action=download&id=9884&file=")
@@ -57,37 +57,37 @@ func (s *Suite) Test_MkLineChecker_Check
t.SetupCommandLine("-Wtypes")
t.SetupVartypes()
- MkLineChecker{t.NewMkLine("fname", 1, ".if !empty(PKGSRC_COMPILER:Mmycc)")}.CheckCond()
+ MkLineChecker{t.NewMkLine("fname", 1, ".if !empty(PKGSRC_COMPILER:Mmycc)")}.checkDirectiveCond()
t.CheckOutputLines(
"WARN: fname:1: The pattern \"mycc\" cannot match any of " +
"{ ccache ccc clang distcc f2c gcc hp icc ido " +
"mipspro mipspro-ucode pcc sunpro xlc } for PKGSRC_COMPILER.")
- MkLineChecker{t.NewMkLine("fname", 1, ".elif ${A} != ${B}")}.CheckCond()
+ MkLineChecker{t.NewMkLine("fname", 1, ".elif ${A} != ${B}")}.checkDirectiveCond()
t.CheckOutputEmpty()
- MkLineChecker{t.NewMkLine("fname", 1, ".if ${HOMEPAGE} == \"mailto:someone%example.org@localhost\"")}.CheckCond()
+ MkLineChecker{t.NewMkLine("fname", 1, ".if ${HOMEPAGE} == \"mailto:someone%example.org@localhost\"")}.checkDirectiveCond()
t.CheckOutputLines(
"WARN: fname:1: \"mailto:someone%example.org@localhost\" is not a valid URL.")
- MkLineChecker{t.NewMkLine("fname", 1, ".if !empty(PKGSRC_RUN_TEST:M[Y][eE][sS])")}.CheckCond()
+ MkLineChecker{t.NewMkLine("fname", 1, ".if !empty(PKGSRC_RUN_TEST:M[Y][eE][sS])")}.checkDirectiveCond()
t.CheckOutputLines(
"WARN: fname:1: PKGSRC_RUN_TEST should be matched against \"[yY][eE][sS]\" or \"[nN][oO]\", not \"[Y][eE][sS]\".")
- MkLineChecker{t.NewMkLine("fname", 1, ".if !empty(IS_BUILTIN.Xfixes:M[yY][eE][sS])")}.CheckCond()
+ MkLineChecker{t.NewMkLine("fname", 1, ".if !empty(IS_BUILTIN.Xfixes:M[yY][eE][sS])")}.checkDirectiveCond()
t.CheckOutputEmpty()
- MkLineChecker{t.NewMkLine("fname", 1, ".if !empty(${IS_BUILTIN.Xfixes:M[yY][eE][sS]})")}.CheckCond()
+ MkLineChecker{t.NewMkLine("fname", 1, ".if !empty(${IS_BUILTIN.Xfixes:M[yY][eE][sS]})")}.checkDirectiveCond()
t.CheckOutputLines(
"WARN: fname:1: The empty() function takes a variable name as parameter, not a variable expression.")
- MkLineChecker{t.NewMkLine("fname", 1, ".if ${EMUL_PLATFORM} == \"linux-x386\"")}.CheckCond()
+ MkLineChecker{t.NewMkLine("fname", 1, ".if ${EMUL_PLATFORM} == \"linux-x386\"")}.checkDirectiveCond()
t.CheckOutputLines(
"WARN: fname:1: " +
@@ -100,7 +100,7 @@ func (s *Suite) Test_MkLineChecker_Check
"mlrisc ns32k pc532 pmax powerpc powerpc64 rs6000 s390 sh3eb sh3el sparc sparc64 vax x86_64 " +
"} instead.")
- MkLineChecker{t.NewMkLine("fname", 1, ".if ${EMUL_PLATFORM:Mlinux-x386}")}.CheckCond()
+ MkLineChecker{t.NewMkLine("fname", 1, ".if ${EMUL_PLATFORM:Mlinux-x386}")}.checkDirectiveCond()
t.CheckOutputLines(
"WARN: fname:1: "+
@@ -113,7 +113,7 @@ func (s *Suite) Test_MkLineChecker_Check
"for the hardware architecture part of EMUL_PLATFORM.",
"NOTE: fname:1: EMUL_PLATFORM should be compared using == instead of the :M or :N modifier without wildcards.")
- MkLineChecker{t.NewMkLine("fname", 98, ".if ${MACHINE_PLATFORM:MUnknownOS-*-*} || ${MACHINE_ARCH:Mx86}")}.CheckCond()
+ MkLineChecker{t.NewMkLine("fname", 98, ".if ${MACHINE_PLATFORM:MUnknownOS-*-*} || ${MACHINE_ARCH:Mx86}")}.checkDirectiveCond()
t.CheckOutputLines(
"WARN: fname:98: "+
Index: pkgsrc/pkgtools/pkglint/files/mkparser_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mkparser_test.go:1.12 pkgsrc/pkgtools/pkglint/files/mkparser_test.go:1.13
--- pkgsrc/pkgtools/pkglint/files/mkparser_test.go:1.12 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/mkparser_test.go Thu Aug 16 20:41:42 2018
@@ -110,6 +110,10 @@ func (s *Suite) Test_MkParser_MkTokens(c
check("${VAR:ts\\000012}", varuse("VAR", "ts\\000012")) // The separator character can be a long octal number.
check("${VAR:ts\\124}", varuse("VAR", "ts\\124")) // Or even decimal.
+ checkRest("${VAR:ts---}", nil, "${VAR:ts---}") // The :ts modifier only takes single-character separators.
+
+ check("$<", varuseText("$<", "<")) // Same as ${.IMPSRC}
+
check("$(GNUSTEP_USER_ROOT)", varuseText("$(GNUSTEP_USER_ROOT)", "GNUSTEP_USER_ROOT"))
t.CheckOutputLines(
"WARN: Test_MkParser_MkTokens.mk:1: Please use curly braces {} instead of round parentheses () for GNUSTEP_USER_ROOT.")
@@ -222,6 +226,15 @@ func (s *Suite) Test_MkParser_MkCond(c *
checkRest("!empty(PKG_OPTIONS:Msndfile) || defined(PKG_OPTIONS:Msamplerate)",
&mkCond{Not: &mkCond{Empty: varuse("PKG_OPTIONS", "Msndfile")}},
" || defined(PKG_OPTIONS:Msamplerate)")
+ checkRest("${LEFT} &&",
+ &mkCond{Not: &mkCond{Empty: varuse("LEFT")}},
+ " &&")
+ checkRest("\"unfinished string literal",
+ nil,
+ "\"unfinished string literal")
+ checkRest("${VAR} == \"unfinished string literal",
+ nil, // Not even the ${VAR} gets through here, although that can be expected.
+ "${VAR} == \"unfinished string literal")
}
func (s *Suite) Test_MkParser__varuse_parentheses_autofix(c *check.C) {
Index: pkgsrc/pkgtools/pkglint/files/substcontext_test.go
diff -u pkgsrc/pkgtools/pkglint/files/substcontext_test.go:1.12 pkgsrc/pkgtools/pkglint/files/substcontext_test.go:1.13
--- pkgsrc/pkgtools/pkglint/files/substcontext_test.go:1.12 Thu Jul 12 16:23:36 2018
+++ pkgsrc/pkgtools/pkglint/files/substcontext_test.go Thu Aug 16 20:41:42 2018
@@ -90,7 +90,7 @@ func (s *Suite) Test_SubstContext__no_cl
"WARN: Makefile:13: Incomplete SUBST block: SUBST_STAGE.repl missing.")
}
-func (s *Suite) Test_SubstContext__conditionals(c *check.C) {
+func (s *Suite) Test_SubstContext__directives(c *check.C) {
t := s.Init(c)
t.SetupCommandLine("-Wextra")
@@ -119,7 +119,7 @@ func (s *Suite) Test_SubstContext__condi
"WARN: Makefile:18: All but the first \"SUBST_SED.os\" lines should use the \"+=\" operator.")
}
-func (s *Suite) Test_SubstContext__one_conditional_missing_transformation(c *check.C) {
+func (s *Suite) Test_SubstContext__missing_transformation_in_one_branch(c *check.C) {
t := s.Init(c)
t.SetupCommandLine("-Wextra")
@@ -254,7 +254,7 @@ func simulateSubstLines(t *Tester, texts
case text == "":
ctx.Finish(line)
case hasPrefix(text, "."):
- ctx.Conditional(line)
+ ctx.Directive(line)
default:
ctx.Varassign(line)
}
Index: pkgsrc/pkgtools/pkglint/files/toplevel.go
diff -u pkgsrc/pkgtools/pkglint/files/toplevel.go:1.12 pkgsrc/pkgtools/pkglint/files/toplevel.go:1.13
--- pkgsrc/pkgtools/pkglint/files/toplevel.go:1.12 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/toplevel.go Thu Aug 16 20:41:42 2018
@@ -18,18 +18,18 @@ func CheckdirToplevel(dir string) {
ctx := &Toplevel{dir, "", nil}
fname := dir + "/Makefile"
- lines := LoadNonemptyLines(fname, true)
- if lines == nil {
+ mklines := LoadMk(fname, NotEmpty|LogErrors)
+ if mklines == nil {
return
}
- for _, line := range lines {
- if m, commentedOut, indentation, subdir, comment := match4(line.Text, `^(#?)SUBDIR\s*\+=(\s*)(\S+)\s*(?:#\s*(.*?)\s*|)$`); m {
- ctx.checkSubdir(line, commentedOut == "#", indentation, subdir, comment)
+ for _, mkline := range mklines.mklines {
+ if (mkline.IsVarassign() || mkline.IsCommentedVarassign()) && mkline.Varname() == "SUBDIR" {
+ ctx.checkSubdir(mkline)
}
}
- NewMkLines(lines).Check()
+ mklines.Check()
if G.opts.Recursive {
if G.opts.CheckGlobal {
@@ -40,13 +40,15 @@ func CheckdirToplevel(dir string) {
}
}
-func (ctx *Toplevel) checkSubdir(line Line, commentedOut bool, indentation, subdir, comment string) {
- if commentedOut && comment == "" {
- line.Warnf("%q commented out without giving a reason.", subdir)
+func (ctx *Toplevel) checkSubdir(mkline MkLine) {
+ subdir := mkline.Value()
+
+ if mkline.IsCommentedVarassign() && (mkline.VarassignComment() == "#" || mkline.VarassignComment() == "") {
+ mkline.Warnf("%q commented out without giving a reason.", subdir)
}
- if indentation != "\t" {
- line.Warnf("Indentation should be a single tab character.")
+ if !hasSuffix(mkline.ValueAlign(), "=\t") {
+ mkline.Warnf("Indentation should be a single tab character.")
}
if contains(subdir, "$") || !fileExists(ctx.dir+"/"+subdir+"/Makefile") {
@@ -58,15 +60,15 @@ func (ctx *Toplevel) checkSubdir(line Li
case subdir > prev:
// Correctly ordered
case subdir == prev:
- line.Errorf("Each subdir must only appear once.")
+ mkline.Errorf("Each subdir must only appear once.")
case subdir == "archivers" && prev == "x11":
// This exception is documented in the top-level Makefile.
default:
- line.Warnf("%s should come before %s.", subdir, prev)
+ mkline.Warnf("%s should come before %s.", subdir, prev)
}
ctx.previousSubdir = subdir
- if !commentedOut {
+ if !mkline.IsCommentedVarassign() {
ctx.subdirs = append(ctx.subdirs, ctx.dir+"/"+subdir)
}
}
Index: pkgsrc/pkgtools/pkglint/files/mkline.go
diff -u pkgsrc/pkgtools/pkglint/files/mkline.go:1.35 pkgsrc/pkgtools/pkglint/files/mkline.go:1.36
--- pkgsrc/pkgtools/pkglint/files/mkline.go:1.35 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/mkline.go Thu Aug 16 20:41:42 2018
@@ -35,7 +35,7 @@ type mkLineShell struct {
}
type mkLineComment struct{}
type mkLineEmpty struct{}
-type mkLineConditional struct {
+type mkLineDirective struct {
indent string
directive string
args string
@@ -43,11 +43,11 @@ type mkLineConditional struct {
elseLine MkLine // (filled in later)
}
type mkLineInclude struct {
- mustExist bool
- sys bool
- indent string
- includeFile string
- conditionVars string // (filled in later)
+ mustExist bool
+ sys bool
+ indent string
+ includeFile string
+ conditionalVars string // (filled in later)
}
type mkLineDependency struct {
targets string
@@ -115,8 +115,8 @@ func NewMkLine(line Line) *MkLineImpl {
return &MkLineImpl{line, mkLineEmpty{}}
}
- if m, indent, directive, args, comment := matchMkCond(text); m {
- return &MkLineImpl{line, mkLineConditional{indent, directive, args, comment, nil}}
+ if m, indent, directive, args, comment := matchMkDirective(text); m {
+ return &MkLineImpl{line, mkLineDirective{indent, directive, args, comment, nil}}
}
if m, indent, directive, includefile := MatchMkInclude(text); m {
@@ -179,9 +179,9 @@ func (mkline *MkLineImpl) IsEmpty() bool
return ok
}
-// IsCond checks whether the line is a conditional (.if/.ifelse/.else/.if) or a loop (.for/.endfor).
-func (mkline *MkLineImpl) IsCond() bool {
- _, ok := mkline.data.(mkLineConditional)
+// IsDirective checks whether the line is a conditional (.if/.elif/.else/.if) or a loop (.for/.endfor).
+func (mkline *MkLineImpl) IsDirective() bool {
+ _, ok := mkline.data.(mkLineDirective)
return ok
}
@@ -233,8 +233,8 @@ func (mkline *MkLineImpl) Value() string
func (mkline *MkLineImpl) VarassignComment() string { return mkline.data.(mkLineAssign).comment }
func (mkline *MkLineImpl) ShellCommand() string { return mkline.data.(mkLineShell).command }
func (mkline *MkLineImpl) Indent() string {
- if mkline.IsCond() {
- return mkline.data.(mkLineConditional).indent
+ if mkline.IsDirective() {
+ return mkline.data.(mkLineDirective).indent
} else {
return mkline.data.(mkLineInclude).indent
}
@@ -242,15 +242,17 @@ func (mkline *MkLineImpl) Indent() strin
// Directive returns one of "if", "ifdef", "ifndef", "else", "elif", "endif", "for", "endfor", "undef".
//
-// See matchMkCond.
-func (mkline *MkLineImpl) Directive() string { return mkline.data.(mkLineConditional).directive }
-func (mkline *MkLineImpl) Args() string { return mkline.data.(mkLineConditional).args }
-
-// CondComment is the trailing end-of-line comment, typically at a deeply nested .endif or .endfor.
-func (mkline *MkLineImpl) CondComment() string { return mkline.data.(mkLineConditional).comment }
-func (mkline *MkLineImpl) HasElseBranch() bool { return mkline.data.(mkLineConditional).elseLine != nil }
+// See matchMkDirective.
+func (mkline *MkLineImpl) Directive() string { return mkline.data.(mkLineDirective).directive }
+
+// Args returns the arguments from an .if, .ifdef, .ifndef, .elif, .for, .undef.
+func (mkline *MkLineImpl) Args() string { return mkline.data.(mkLineDirective).args }
+
+// DirectiveComment is the trailing end-of-line comment, typically at a deeply nested .endif or .endfor.
+func (mkline *MkLineImpl) DirectiveComment() string { return mkline.data.(mkLineDirective).comment }
+func (mkline *MkLineImpl) HasElseBranch() bool { return mkline.data.(mkLineDirective).elseLine != nil }
func (mkline *MkLineImpl) SetHasElseBranch(elseLine MkLine) {
- data := mkline.data.(mkLineConditional)
+ data := mkline.data.(mkLineDirective)
data.elseLine = elseLine
mkline.data = data
}
@@ -261,13 +263,13 @@ func (mkline *MkLineImpl) IncludeFile()
func (mkline *MkLineImpl) Targets() string { return mkline.data.(mkLineDependency).targets }
func (mkline *MkLineImpl) Sources() string { return mkline.data.(mkLineDependency).sources }
-// ConditionVars is a space-separated list of those variable names
+// ConditionalVars is a space-separated list of those variable names
// on which the inclusion depends. It is initialized later,
// step by step, when parsing other lines
-func (mkline *MkLineImpl) ConditionVars() string { return mkline.data.(mkLineInclude).conditionVars }
-func (mkline *MkLineImpl) SetConditionVars(varnames string) {
+func (mkline *MkLineImpl) ConditionalVars() string { return mkline.data.(mkLineInclude).conditionalVars }
+func (mkline *MkLineImpl) SetConditionalVars(varnames string) {
include := mkline.data.(mkLineInclude)
- include.conditionVars = varnames
+ include.conditionalVars = varnames
mkline.data = include
}
@@ -406,7 +408,7 @@ func (mkline *MkLineImpl) ExplainRelativ
"main pkgsrc repository.")
}
-func matchMkCond(text string) (m bool, indent, directive, args, comment string) {
+func matchMkDirective(text string) (m bool, indent, directive, args, comment string) {
i, n := 0, len(text)
if i < n && text[i] == '.' {
i++
@@ -552,13 +554,6 @@ func (mkline *MkLineImpl) VariableNeedsQ
return nqNo
}
- // Assigning lists to lists does not require any quoting, though
- // there may be cases like "CONFIGURE_ARGS+= -libs ${LDFLAGS:Q}"
- // where quoting is necessary.
- if wantList && haveList && !vuc.IsWordPart {
- return nqDoesntMatter
- }
-
if wantList != haveList {
if vuc.vartype != nil && vartype != nil {
if vuc.vartype.basicType == BtFetchURL && vartype.basicType == BtHomepage {
@@ -602,7 +597,7 @@ func (mkline *MkLineImpl) VariableType(v
if trace.Tracing {
trace.Stepf("Use of tool %+v", tool)
}
- if tool.UsableAtLoadtime {
+ if tool.UsableAtLoadTime {
if G.Pkg == nil || G.Pkg.SeenBsdPrefsMk || G.Pkg.loadTimeTools[tool.Name] {
perms |= aclpUseLoadtime
}
@@ -650,8 +645,6 @@ func (mkline *MkLineImpl) VariableType(v
gtype = &Vartype{lkShell, BtLdFlag, allowRuntime, true}
case hasSuffix(varbase, "_MK"):
gtype = &Vartype{lkNone, BtUnknown, allowAll, true}
- case hasPrefix(varbase, "PLIST."):
- gtype = &Vartype{lkNone, BtYes, allowAll, true}
}
if trace.Tracing {
@@ -753,8 +746,8 @@ type vucTime uint8
const (
vucTimeUnknown vucTime = iota
- // When Makefiles are loaded, the operators := and != are evaluated,
- // as well as the conditionals .if, .elif and .for.
+ // When Makefiles are loaded, the operators := and != evaluate their
+ // right-hand side, as well as the directives .if, .elif and .for.
// During loading, not all variables are available yet.
// Variable values are still subject to change, especially lists.
vucTimeParse
@@ -815,18 +808,18 @@ func (ind *Indentation) String() string
s := ""
for _, level := range ind.levels[1:] {
s += fmt.Sprintf(" %d", level.depth)
- if len(level.conditionVars) != 0 {
- s += " (" + strings.Join(level.conditionVars, " ") + ")"
+ if len(level.conditionalVars) != 0 {
+ s += " (" + strings.Join(level.conditionalVars, " ") + ")"
}
}
return "[" + strings.TrimSpace(s) + "]"
}
type indentationLevel struct {
- mkline MkLine // The line in which the indentation started; the .if/.for
- depth int // Number of space characters; always a multiple of 2
- condition string // The corresponding condition from the .if or .elif
- conditionVars []string // Variables on which the current path depends
+ mkline MkLine // The line in which the indentation started; the .if/.for
+ depth int // Number of space characters; always a multiple of 2
+ condition string // The corresponding condition from the .if or latest .elif
+ conditionalVars []string // Variables on which the current path depends
// Files whose existence has been checked in a related path.
// The check counts for both the "if" and the "else" branch,
@@ -861,7 +854,7 @@ func (ind *Indentation) Push(mkline MkLi
}
func (ind *Indentation) AddVar(varname string) {
- vars := &ind.top().conditionVars
+ vars := &ind.top().conditionalVars
for _, existingVarname := range *vars {
if varname == existingVarname {
return
@@ -873,7 +866,7 @@ func (ind *Indentation) AddVar(varname s
func (ind *Indentation) DependsOn(varname string) bool {
for _, level := range ind.levels {
- for _, levelVarname := range level.conditionVars {
+ for _, levelVarname := range level.conditionalVars {
if varname == levelVarname {
return true
}
@@ -882,9 +875,11 @@ func (ind *Indentation) DependsOn(varnam
return false
}
+// IsConditional returns whether the current line depends on evaluating
+// any variable in an .if or .elif expression or from a .for loop.
func (ind *Indentation) IsConditional() bool {
for _, level := range ind.levels {
- for _, varname := range level.conditionVars {
+ for _, varname := range level.conditionalVars {
if !hasSuffix(varname, "_MK") {
return true
}
@@ -900,7 +895,7 @@ func (ind *Indentation) Varnames() strin
sep := ""
varnames := ""
for _, level := range ind.levels {
- for _, levelVarname := range level.conditionVars {
+ for _, levelVarname := range level.conditionalVars {
if !hasSuffix(levelVarname, "_MK") {
varnames += sep + levelVarname
sep = ", "
@@ -910,7 +905,7 @@ func (ind *Indentation) Varnames() strin
return varnames
}
-// Condition returns the condition for the innermost .if, .elif or .for.
+// Condition returns the condition of the innermost .if, .elif or .for.
func (ind *Indentation) Condition() string {
return ind.top().condition
}
@@ -932,7 +927,7 @@ func (ind *Indentation) IsCheckedFile(fi
}
func (ind *Indentation) TrackBefore(mkline MkLine) {
- if !mkline.IsCond() {
+ if !mkline.IsDirective() {
return
}
if trace.Tracing {
@@ -949,7 +944,7 @@ func (ind *Indentation) TrackBefore(mkli
}
func (ind *Indentation) TrackAfter(mkline MkLine) {
- if !mkline.IsCond() {
+ if !mkline.IsDirective() {
return
}
@@ -966,7 +961,7 @@ func (ind *Indentation) TrackAfter(mklin
}
// Note: adding the used variables for arbitrary conditions
- // happens in MkLineChecker.CheckCond for performance reasons.
+ // happens in MkLineChecker.checkDirectiveCond for performance reasons.
if contains(args, "exists") {
cond := NewMkParser(mkline.Line, args, false).MkCond()
@@ -984,7 +979,7 @@ func (ind *Indentation) TrackAfter(mklin
ind.top().depth += 2
case "elif":
- // Handled here instead of TrackAfter to allow the action to access the previous condition.
+ // Handled here instead of TrackBefore to allow the action to access the previous condition.
ind.top().condition = args
case "else":
Index: pkgsrc/pkgtools/pkglint/files/pkglint.go
diff -u pkgsrc/pkgtools/pkglint/files/pkglint.go:1.35 pkgsrc/pkgtools/pkglint/files/pkglint.go:1.36
--- pkgsrc/pkgtools/pkglint/files/pkglint.go:1.35 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/pkglint.go Thu Aug 16 20:41:42 2018
@@ -138,7 +138,10 @@ func (pkglint *Pkglint) Main(argv ...str
dummyLine.Fatalf("Cannot create profiling file: %s", err)
}
pprof.StartCPUProfile(f)
- defer pprof.StopCPUProfile()
+ defer func() {
+ pprof.StopCPUProfile()
+ f.Close()
+ }()
regex.Profiling = true
pkglint.loghisto = histogram.New()
@@ -146,7 +149,7 @@ func (pkglint *Pkglint) Main(argv ...str
defer func() {
pkglint.logOut.Write("")
pkglint.loghisto.PrintStats("loghisto", pkglint.logOut.out, -1)
- regex.PrintStats()
+ regex.PrintStats(pkglint.logOut.out)
pkglint.loaded.PrintStats("loaded", pkglint.logOut.out, 50)
}()
}
@@ -168,7 +171,7 @@ func (pkglint *Pkglint) Main(argv ...str
}
pkglint.Pkgsrc = NewPkgsrc(firstArg + "/" + relTopdir)
- pkglint.Pkgsrc.Load()
+ pkglint.Pkgsrc.LoadInfrastructure()
currentUser, err := user.Current()
if err == nil {
@@ -296,13 +299,13 @@ func (pkglint *Pkglint) CheckDirent(fnam
isDir := st.Mode().IsDir()
isReg := st.Mode().IsRegular()
- currentDir := ifelseStr(isReg, path.Dir(fname), fname)
- absCurrentDir := abspath(currentDir)
+ dir := ifelseStr(isReg, path.Dir(fname), fname)
+ absCurrentDir := abspath(dir)
pkglint.Wip = !pkglint.opts.Import && matches(absCurrentDir, `/wip/|/wip$`)
pkglint.Infrastructure = matches(absCurrentDir, `/mk/|/mk$`)
- pkgsrcdir := findPkgsrcTopdir(currentDir)
+ pkgsrcdir := findPkgsrcTopdir(dir)
if pkgsrcdir == "" {
- NewLineWhole(fname).Errorf("Cannot determine the pkgsrc root directory for %q.", cleanpath(currentDir))
+ NewLineWhole(fname).Errorf("Cannot determine the pkgsrc root directory for %q.", cleanpath(dir))
return
}
@@ -316,11 +319,11 @@ func (pkglint *Pkglint) CheckDirent(fnam
switch pkgsrcdir {
case "../..":
- pkglint.checkdirPackage(pkglint.Pkgsrc.ToRel(currentDir))
+ pkglint.checkdirPackage(dir)
case "..":
- CheckdirCategory(currentDir)
+ CheckdirCategory(dir)
case ".":
- CheckdirToplevel(currentDir)
+ CheckdirToplevel(dir)
default:
NewLineWhole(fname).Errorf("Cannot check directories outside a pkgsrc tree.")
}
@@ -374,7 +377,7 @@ func CheckfileExtra(fname string) {
defer trace.Call1(fname)()
}
- if lines := LoadNonemptyLines(fname, false); lines != nil {
+ if lines := Load(fname, NotEmpty|LogErrors); lines != nil {
ChecklinesTrailingEmptyLines(lines)
}
}
@@ -458,13 +461,13 @@ func CheckfileMk(fname string) {
defer trace.Call1(fname)()
}
- lines := LoadNonemptyLines(fname, true)
- if lines == nil {
+ mklines := LoadMk(fname, NotEmpty|LogErrors)
+ if mklines == nil {
return
}
- NewMkLines(lines).Check()
- SaveAutofixChanges(lines)
+ mklines.Check()
+ mklines.SaveAutofixChanges()
}
func (pkglint *Pkglint) Checkfile(fname string) {
@@ -514,21 +517,21 @@ func (pkglint *Pkglint) Checkfile(fname
case basename == "buildlink3.mk":
if pkglint.opts.CheckBuildlink3 {
- if lines := LoadNonemptyLines(fname, true); lines != nil {
- ChecklinesBuildlink3Mk(NewMkLines(lines))
+ if mklines := LoadMk(fname, NotEmpty|LogErrors); mklines != nil {
+ ChecklinesBuildlink3Mk(mklines)
}
}
case hasPrefix(basename, "DESCR"):
if pkglint.opts.CheckDescr {
- if lines := LoadNonemptyLines(fname, false); lines != nil {
+ if lines := Load(fname, NotEmpty|LogErrors); lines != nil {
ChecklinesDescr(lines)
}
}
case basename == "distinfo":
if pkglint.opts.CheckDistinfo {
- if lines := LoadNonemptyLines(fname, false); lines != nil {
+ if lines := Load(fname, NotEmpty|LogErrors); lines != nil {
ChecklinesDistinfo(lines)
}
}
@@ -540,21 +543,21 @@ func (pkglint *Pkglint) Checkfile(fname
case hasPrefix(basename, "MESSAGE"):
if pkglint.opts.CheckMessage {
- if lines := LoadNonemptyLines(fname, false); lines != nil {
+ if lines := Load(fname, NotEmpty|LogErrors); lines != nil {
ChecklinesMessage(lines)
}
}
case basename == "options.mk":
if pkglint.opts.CheckOptions {
- if lines := LoadNonemptyLines(fname, true); lines != nil {
- ChecklinesOptionsMk(NewMkLines(lines))
+ if mklines := LoadMk(fname, NotEmpty|LogErrors); mklines != nil {
+ ChecklinesOptionsMk(mklines)
}
}
case matches(basename, `^patch-[-A-Za-z0-9_.~+]*[A-Za-z0-9_]$`):
if pkglint.opts.CheckPatches {
- if lines := LoadNonemptyLines(fname, false); lines != nil {
+ if lines := Load(fname, NotEmpty|LogErrors); lines != nil {
ChecklinesPatch(lines)
}
}
@@ -574,7 +577,7 @@ func (pkglint *Pkglint) Checkfile(fname
case hasPrefix(basename, "PLIST"):
if pkglint.opts.CheckPlist {
- if lines := LoadNonemptyLines(fname, false); lines != nil {
+ if lines := Load(fname, NotEmpty|LogErrors); lines != nil {
ChecklinesPlist(lines)
}
}
Index: pkgsrc/pkgtools/pkglint/files/mkline_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.39 pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.40
--- pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.39 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/mkline_test.go Thu Aug 16 20:41:42 2018
@@ -123,12 +123,13 @@ func (s *Suite) Test_NewMkLine(c *check.
"\tshell command # shell comment",
"# whole line comment",
"",
- ". if !empty(PKGNAME:M*-*) && ${RUBY_RAILS_SUPPORTED:[\\#]} == 1 # cond comment",
+ ". if !empty(PKGNAME:M*-*) && ${RUBY_RAILS_SUPPORTED:[\\#]} == 1 # directive comment",
". include \"../../mk/bsd.prefs.mk\" # include comment",
". include <subdir.mk> # sysinclude comment",
"target1 target2: source1 source2",
"target : source",
- "VARNAME+=value")
+ "VARNAME+=value",
+ "<<<<<<<<<<<<<<<<<")
ln := mklines.mklines
c.Check(ln[0].IsVarassign(), equals, true)
@@ -146,11 +147,11 @@ func (s *Suite) Test_NewMkLine(c *check.
c.Check(ln[3].IsEmpty(), equals, true)
- c.Check(ln[4].IsCond(), equals, true)
+ c.Check(ln[4].IsDirective(), equals, true)
c.Check(ln[4].Indent(), equals, " ")
c.Check(ln[4].Directive(), equals, "if")
c.Check(ln[4].Args(), equals, "!empty(PKGNAME:M*-*) && ${RUBY_RAILS_SUPPORTED:[#]} == 1")
- c.Check(ln[4].CondComment(), equals, "cond comment")
+ c.Check(ln[4].DirectiveComment(), equals, "directive comment")
c.Check(ln[5].IsInclude(), equals, true)
c.Check(ln[5].Indent(), equals, " ")
@@ -171,6 +172,16 @@ func (s *Suite) Test_NewMkLine(c *check.
c.Check(ln[9].Varcanon(), equals, "VARNAME")
c.Check(ln[9].Varparam(), equals, "")
+ // Merge conflicts are of neither type.
+ c.Check(ln[10].IsVarassign(), equals, false)
+ c.Check(ln[10].IsDirective(), equals, false)
+ c.Check(ln[10].IsInclude(), equals, false)
+ c.Check(ln[10].IsEmpty(), equals, false)
+ c.Check(ln[10].IsComment(), equals, false)
+ c.Check(ln[10].IsDependency(), equals, false)
+ c.Check(ln[10].IsShellCommand(), equals, false)
+ c.Check(ln[10].IsSysinclude(), equals, false)
+
t.CheckOutputLines(
"WARN: test.mk:9: Space before colon in dependency line.")
}
@@ -207,6 +218,7 @@ func (s *Suite) Test_NewMkLine__autofix_
"pkgbase := pkglint")
}
+// Guessing the variable type works for both plain and parameterized variable names.
func (s *Suite) Test_MkLine_VariableType_varparam(c *check.C) {
t := s.Init(c)
@@ -216,12 +228,12 @@ func (s *Suite) Test_MkLine_VariableType
t1 := mkline.VariableType("FONT_DIRS")
c.Assert(t1, check.NotNil)
- c.Check(t1.String(), equals, "ShellList of Pathmask")
+ c.Check(t1.String(), equals, "ShellList of Pathmask (guessed)")
t2 := mkline.VariableType("FONT_DIRS.ttf")
c.Assert(t2, check.NotNil)
- c.Check(t2.String(), equals, "ShellList of Pathmask")
+ c.Check(t2.String(), equals, "ShellList of Pathmask (guessed)")
}
func (s *Suite) Test_VarUseContext_String(c *check.C) {
@@ -277,7 +289,7 @@ func (s *Suite) Test_MkLines_Check__extr
t.SetupCommandLine("-Wextra")
t.SetupVartypes()
- G.Pkg = NewPackage("category/pkgbase")
+ G.Pkg = NewPackage(t.File("category/pkgbase"))
G.Mk = t.NewMkLines("options.mk",
MkRcsID,
".for word in ${PKG_FAIL_REASON}",
@@ -379,7 +391,7 @@ func (s *Suite) Test_MkLine_variableNeed
t.SetupVartypes()
t.SetupTool(&Tool{Name: "find", Varname: "FIND", Predefined: true})
t.SetupTool(&Tool{Name: "sort", Varname: "SORT", Predefined: true})
- G.Pkg = NewPackage("category/pkgbase")
+ G.Pkg = NewPackage(t.File("category/pkgbase"))
G.Mk = t.NewMkLines("Makefile",
MkRcsID,
"GENERATE_PLIST= cd ${DESTDIR}${PREFIX}; ${FIND} * \\( -type f -or -type l \\) | ${SORT};")
@@ -629,7 +641,7 @@ func (s *Suite) Test_MkLine_variableNeed
t.SetupCommandLine("-Wall")
t.SetupVartypes()
- G.Pkgsrc.Tools.RegisterVarname("tar", "TAR", dummyLine)
+ G.Pkgsrc.Tools.RegisterVarname("tar", "TAR", dummyMkLine)
mklines := t.NewMkLines("Makefile",
MkRcsID,
"",
@@ -650,7 +662,7 @@ func (s *Suite) Test_MkLine_variableNeed
t.SetupCommandLine("-Wall")
t.SetupVartypes()
- G.Pkgsrc.Tools.RegisterVarname("cat", "CAT", dummyLine)
+ G.Pkgsrc.Tools.RegisterVarname("cat", "CAT", dummyMkLine)
mklines := t.NewMkLines("Makefile",
MkRcsID,
"",
@@ -698,6 +710,69 @@ func (s *Suite) Test_MkLine_variableNeed
"\t${ECHO} ${FOODIR:Q}")
}
+// TODO: COMPILER_RPATH_FLAG and LINKER_RPATH_FLAG have different types
+// defined in vardefs.go; examine why.
+func (s *Suite) Test_MkLine_variableNeedsQuoting__shellword_part(c *check.C) {
+ t := s.Init(c)
+
+ t.SetupCommandLine("-Wall,no-space")
+ t.SetupVartypes()
+
+ mklines := t.SetupFileMkLines("Makefile",
+ MkRcsID,
+ "",
+ "SUBST_CLASSES+= class",
+ "SUBST_STAGE.class= pre-configure",
+ "SUBST_FILES.class= files",
+ "SUBST_SED.class=-e s:@LINKER_RPATH_FLAG@:${LINKER_RPATH_FLAG}:g")
+
+ mklines.Check()
+
+ t.CheckOutputEmpty()
+}
+
+// Tools, when used in a shell command, must not be quoted.
+func (s *Suite) Test_MkLine_variableNeedsQuoting__tool_in_shell_command(c *check.C) {
+ t := s.Init(c)
+
+ t.SetupCommandLine("-Wall,no-space")
+ t.SetupVartypes()
+ t.SetupTool(&Tool{Varname: "BASH"})
+
+ mklines := t.SetupFileMkLines("Makefile",
+ MkRcsID,
+ "",
+ "CONFIG_SHELL= ${BASH}")
+
+ mklines.Check()
+
+ t.CheckOutputEmpty()
+}
+
+// These examples from real pkgsrc end up in the final nqDontKnow case.
+func (s *Suite) Test_MkLine_variableNeedsQuoting__uncovered_cases(c *check.C) {
+ t := s.Init(c)
+
+ t.SetupCommandLine("-Wall,no-space")
+ t.SetupVartypes()
+
+ mklines := t.SetupFileMkLines("Makefile",
+ MkRcsID,
+ "",
+ "GO_SRCPATH= ${HOMEPAGE:S,https://,,}",
+ "LINKER_RPATH_FLAG:= ${LINKER_RPATH_FLAG:S/-rpath/& /}",
+ "HOMEPAGE= http://godoc.org/${GO_SRCPATH}",
+ "PATH:= ${PREFIX}/cross/bin:${PATH}",
+ "NO_SRC_ON_FTP= ${RESTRICTED}")
+
+ mklines.Check()
+
+ t.CheckOutputLines(
+ "WARN: ~/Makefile:4: The variable LINKER_RPATH_FLAG may not be set by any package.",
+ "WARN: ~/Makefile:4: Please use ${LINKER_RPATH_FLAG:S/-rpath/& /:Q} instead of ${LINKER_RPATH_FLAG:S/-rpath/& /}.",
+ "WARN: ~/Makefile:4: LINKER_RPATH_FLAG should not be evaluated at load time.")
+}
+
func (s *Suite) Test_MkLine_Pkgmandir(c *check.C) {
t := s.Init(c)
@@ -767,11 +842,31 @@ func (s *Suite) Test_MkLine_shell_varuse
// See PR 46570, Ctrl+F "3. In lang/perl5".
func (s *Suite) Test_MkLine_VariableType(c *check.C) {
- mkline := NewMkLine(dummyLine)
+ t := s.Init(c)
+
+ t.SetupVartypes()
+
+ checkType := func(varname string, vartype string) {
+ actualType := dummyMkLine.VariableType(varname)
+ if vartype == "" {
+ c.Check(actualType, check.IsNil)
+ } else {
+ if c.Check(actualType, check.NotNil) {
+ c.Check(actualType.String(), equals, vartype)
+ }
+ }
+ }
- c.Check(mkline.VariableType("_PERL5_PACKLIST_AWK_STRIP_DESTDIR"), check.IsNil)
- c.Check(mkline.VariableType("SOME_DIR").guessed, equals, true)
- c.Check(mkline.VariableType("SOMEDIR").guessed, equals, true)
+ checkType("_PERL5_PACKLIST_AWK_STRIP_DESTDIR", "")
+ checkType("SOME_DIR", "Pathname (guessed)")
+ checkType("SOMEDIR", "Pathname (guessed)")
+ checkType("SEARCHPATHS", "ShellList of Pathname (guessed)")
+ checkType("APACHE_USER", "UserGroupName (guessed)")
+ checkType("APACHE_GROUP", "UserGroupName (guessed)")
+ checkType("MY_CMD_ENV", "ShellList of ShellWord (guessed)")
+ checkType("MY_CMD_ARGS", "ShellList of ShellWord (guessed)")
+ checkType("MY_CMD_CFLAGS", "ShellList of CFlag (guessed)")
+ checkType("PLIST.abcde", "Yes")
}
// PR 51696, security/py-pbkdf2/Makefile, r1.2
@@ -789,16 +884,16 @@ func (s *Suite) Test_MkLine__comment_in_
"WARN: Makefile:2: The # character starts a comment.")
}
-func (s *Suite) Test_MkLine_ConditionVars(c *check.C) {
+func (s *Suite) Test_MkLine_ConditionalVars(c *check.C) {
t := s.Init(c)
mkline := t.NewMkLine("Makefile", 45, ".include \"../../category/package/buildlink3.mk\"")
- c.Check(mkline.ConditionVars(), equals, "")
+ c.Check(mkline.ConditionalVars(), equals, "")
- mkline.SetConditionVars("OPSYS")
+ mkline.SetConditionalVars("OPSYS")
- c.Check(mkline.ConditionVars(), equals, "OPSYS")
+ c.Check(mkline.ConditionalVars(), equals, "OPSYS")
}
func (s *Suite) Test_MkLine_ValueSplit(c *check.C) {
@@ -830,6 +925,33 @@ func (s *Suite) Test_MkLine_ValueSplit(c
"${DESTDIR:S,/,\\:,:S,:,:,}/sbin")
}
+func (s *Suite) Test_MkLine_ResolveVarsInRelativePath(c *check.C) {
+ t := s.Init(c)
+
+ checkResolve := func(before string, after string) {
+ c.Check(dummyMkLine.ResolveVarsInRelativePath(before, false), equals, after)
+ }
+
+ t.CreateFileLines("lang/lua53/Makefile")
+ t.CreateFileLines("lang/php72/Makefile")
+ t.CreateFileLines("emulators/suse100_base/Makefile")
+ t.CreateFileLines("lang/python36/Makefile")
+
+ checkResolve("", "")
+ checkResolve("${LUA_PKGSRCDIR}", "../../lang/lua53")
+ checkResolve("${PHPPKGSRCDIR}", "../../lang/php72")
+ checkResolve("${SUSE_DIR_PREFIX}", "suse100")
+ checkResolve("${PYPKGSRCDIR}", "../../lang/python36")
+ checkResolve("${PYPACKAGE}", "python36")
+ checkResolve("${FILESDIR}", "${FILESDIR}")
+ checkResolve("${PKGDIR}", "${PKGDIR}")
+
+ G.Pkg = NewPackage(t.File("category/package"))
+
+ checkResolve("${FILESDIR}", "files")
+ checkResolve("${PKGDIR}", ".")
+}
+
func (s *Suite) Test_MatchVarassign(c *check.C) {
s.Init(c)
@@ -918,3 +1040,31 @@ func (s *Suite) Test_Indentation(c *chec
c.Check(ind.IsConditional(), equals, false)
c.Check(ind.String(), equals, "[]")
}
+
+func (s *Suite) Test_Indentation_RememberUsedVariables(c *check.C) {
+ t := s.Init(c)
+
+ mkline := t.NewMkLine("Makefile", 123, ".if ${PKGREVISION} > 0")
+ ind := NewIndentation()
+ cond := NewMkParser(mkline.Line, mkline.Args(), false)
+
+ ind.RememberUsedVariables(cond.MkCond())
+
+ t.CheckOutputEmpty()
+ c.Check(ind.Varnames(), equals, "PKGREVISION")
+}
+
+func (s *Suite) Test_MkLine_ExtractUsedVariables(c *check.C) {
+ t := s.Init(c)
+
+ mkline := t.NewMkLine("Makefile", 123, "")
+
+ nestedVarnames := mkline.ExtractUsedVariables("${VAR.${param}}")
+
+ // ExtractUsedVariables is very old code, should be more advanced.
+ c.Check(nestedVarnames, check.IsNil)
+
+ plainVarnames := mkline.ExtractUsedVariables("${VAR}and${VAR2}")
+
+ c.Check(plainVarnames, deepEquals, []string{"VAR", "VAR2"})
+}
Index: pkgsrc/pkgtools/pkglint/files/mklinechecker.go
diff -u pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.16 pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.17
--- pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.16 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/mklinechecker.go Thu Aug 16 20:41:42 2018
@@ -105,32 +105,17 @@ func (ck MkLineChecker) checkInclude() {
}
}
-func (ck MkLineChecker) checkCond(forVars map[string]bool, indentation *Indentation) {
+func (ck MkLineChecker) checkDirective(forVars map[string]bool, ind *Indentation) {
mkline := ck.MkLine
directive := mkline.Directive()
args := mkline.Args()
- comment := mkline.CondComment()
- expectedDepth := indentation.Depth(directive)
+ expectedDepth := ind.Depth(directive)
ck.checkDirectiveIndentation(expectedDepth)
if directive == "endfor" || directive == "endif" {
- if directive == "endif" && comment != "" {
- if condition := indentation.Condition(); !contains(condition, comment) {
- mkline.Warnf("Comment %q does not match condition %q.", comment, condition)
- }
- }
-
- if directive == "endfor" && comment != "" {
- if condition := indentation.Condition(); !contains(condition, comment) {
- mkline.Warnf("Comment %q does not match loop %q.", comment, condition)
- }
- }
-
- if indentation.Len() <= 1 {
- mkline.Errorf("Unmatched .%s.", directive)
- }
+ ck.checkDirectiveEnd(ind)
}
needsArgument := false
@@ -150,55 +135,82 @@ func (ck MkLineChecker) checkCond(forVar
}
} else if directive == "if" || directive == "elif" {
- ck.CheckCond()
+ ck.checkDirectiveCond()
} else if directive == "ifdef" || directive == "ifndef" {
mkline.Warnf("The \".%s\" directive is deprecated. Please use \".if %sdefined(%s)\" instead.",
directive, ifelseStr(directive == "ifdef", "", "!"), args)
} else if directive == "for" {
- if m, vars, values := match2(args, `^(\S+(?:\s*\S+)*?)\s+in\s+(.*)$`); m {
- for _, forvar := range splitOnSpace(vars) {
- indentation.AddVar(forvar)
- if !G.Infrastructure && hasPrefix(forvar, "_") {
- mkline.Warnf("Variable names starting with an underscore (%s) are reserved for internal pkgsrc use.", forvar)
- }
-
- if matches(forvar, `^[_a-z][_a-z0-9]*$`) {
- // Fine.
- } else if matches(forvar, `[A-Z]`) {
- mkline.Warnf(".for variable names should not contain uppercase letters.")
- } else {
- mkline.Errorf("Invalid variable name %q.", forvar)
- }
+ ck.checkDirectiveFor(forVars, ind)
- forVars[forvar] = true
+ } else if directive == "undef" && args != "" {
+ for _, varname := range splitOnSpace(args) {
+ if forVars[varname] {
+ mkline.Notef("Using \".undef\" after a \".for\" loop is unnecessary.")
}
+ }
+ }
+}
- // Check if any of the value's types is not guessed.
- guessed := true
- for _, value := range splitOnSpace(values) {
- if m, vname := match1(value, `^\$\{(.*)\}`); m {
- vartype := mkline.VariableType(vname)
- if vartype != nil && !vartype.guessed {
- guessed = false
- }
- }
+func (ck MkLineChecker) checkDirectiveEnd(ind *Indentation) {
+ mkline := ck.MkLine
+ directive := mkline.Directive()
+ comment := mkline.DirectiveComment()
+
+ if directive == "endif" && comment != "" {
+ if condition := ind.Condition(); !contains(condition, comment) {
+ mkline.Warnf("Comment %q does not match condition %q.", comment, condition)
+ }
+ }
+ if directive == "endfor" && comment != "" {
+ if condition := ind.Condition(); !contains(condition, comment) {
+ mkline.Warnf("Comment %q does not match loop %q.", comment, condition)
+ }
+ }
+ if ind.Len() <= 1 {
+ mkline.Errorf("Unmatched .%s.", directive)
+ }
+}
+
+func (ck MkLineChecker) checkDirectiveFor(forVars map[string]bool, indentation *Indentation) {
+ mkline := ck.MkLine
+ args := mkline.Args()
+
+ if m, vars, values := match2(args, `^(\S+(?:\s*\S+)*?)\s+in\s+(.*)$`); m {
+ for _, forvar := range splitOnSpace(vars) {
+ indentation.AddVar(forvar)
+ if !G.Infrastructure && hasPrefix(forvar, "_") {
+ mkline.Warnf("Variable names starting with an underscore (%s) are reserved for internal pkgsrc use.", forvar)
}
- forLoopType := &Vartype{lkSpace, BtUnknown, []ACLEntry{{"*", aclpAllRead}}, guessed}
- forLoopContext := &VarUseContext{forLoopType, vucTimeParse, vucQuotFor, false}
- for _, forLoopVar := range mkline.ExtractUsedVariables(values) {
- ck.CheckVaruse(&MkVarUse{forLoopVar, nil}, forLoopContext)
+ if matches(forvar, `^[_a-z][_a-z0-9]*$`) {
+ // Fine.
+ } else if matches(forvar, `[A-Z]`) {
+ mkline.Warnf(".for variable names should not contain uppercase letters.")
+ } else {
+ mkline.Errorf("Invalid variable name %q.", forvar)
}
+
+ forVars[forvar] = true
}
- } else if directive == "undef" && args != "" {
- for _, uvar := range splitOnSpace(args) {
- if forVars[uvar] {
- mkline.Notef("Using \".undef\" after a \".for\" loop is unnecessary.")
+ // Check if any of the value's types is not guessed.
+ guessed := true
+ for _, value := range splitOnSpace(values) {
+ if m, vname := match1(value, `^\$\{(.*)\}`); m {
+ vartype := mkline.VariableType(vname)
+ if vartype != nil && !vartype.guessed {
+ guessed = false
+ }
}
}
+
+ forLoopType := &Vartype{lkSpace, BtUnknown, []ACLEntry{{"*", aclpAllRead}}, guessed}
+ forLoopContext := &VarUseContext{forLoopType, vucTimeParse, vucQuotFor, false}
+ for _, forLoopVar := range mkline.ExtractUsedVariables(values) {
+ ck.CheckVaruse(&MkVarUse{forLoopVar, nil}, forLoopContext)
+ }
}
}
@@ -330,11 +342,14 @@ func (ck MkLineChecker) CheckVaruse(varu
varname := varuse.varname
vartype := mkline.VariableType(varname)
- if G.opts.WarnExtra &&
- (vartype == nil || vartype.guessed) &&
- !varIsUsed(varname) &&
- !(G.Mk != nil && G.Mk.forVars[varname]) &&
- !containsVarRef(varname) {
+ switch {
+ case !G.opts.WarnExtra:
+ case vartype != nil && !vartype.guessed:
+ // Well-known variables are probably defined by the infrastructure.
+ case varIsUsed(varname):
+ case G.Mk != nil && G.Mk.forVars[varname]:
+ case containsVarRef(varname):
+ default:
mkline.Warnf("%s is used but not defined.", varname)
}
@@ -886,7 +901,7 @@ func (ck MkLineChecker) checkVarassignPl
contains(value, "@comment") && !matches(value, `="@comment "`) {
ck.MkLine.Warnf("Please don't use @comment in %s.", varname)
Explain(
- "If you are defining a PLIST conditional here, use one of the",
+ "If you are defining a PLIST condition here, use one of the",
"following patterns instead:",
"",
"1. The direct way, without intermediate variable",
@@ -941,18 +956,6 @@ func (ck MkLineChecker) CheckVartype(var
case vartype.kindOfList == lkNone:
ck.CheckVartypePrimitive(varname, vartype.basicType, op, value, comment, vartype.guessed)
- if op == opUseMatch && matches(value, `^[\w-/]+$`) && !vartype.IsConsideredList() {
- mkline.Notef("%s should be compared using == instead of the :M or :N modifier without wildcards.", varname)
- Explain(
- "This variable has a single value, not a list of values. Therefore",
- "it feels strange to apply list operators like :M and :N onto it.",
- "A more direct approach is to use the == and != operators.",
- "",
- "An entirely different case is when the pattern contains wildcards",
- "like ^, *, $. In such a case, using the :M or :N modifiers is",
- "useful and preferred.")
- }
-
case value == "":
break
@@ -1030,7 +1033,7 @@ func (ck MkLineChecker) checkText(text s
}
}
-func (ck MkLineChecker) CheckCond() {
+func (ck MkLineChecker) checkDirectiveCond() {
mkline := ck.MkLine
if trace.Tracing {
defer trace.Call1(mkline.Args())()
@@ -1039,7 +1042,7 @@ func (ck MkLineChecker) CheckCond() {
p := NewMkParser(mkline.Line, mkline.Args(), false)
cond := p.MkCond()
if !p.EOF() {
- mkline.Warnf("Invalid conditional %q.", mkline.Args())
+ mkline.Warnf("Invalid condition, unrecognized part: %q.", p.Rest())
return
}
@@ -1060,9 +1063,25 @@ func (ck MkLineChecker) CheckCond() {
"\t!empty(VARNAME:Mpattern)",
"\t${VARNAME:Mpattern}")
}
- for _, modifier := range varuse.modifiers {
- if modifier[0] == 'M' || modifier[0] == 'N' {
+
+ modifiers := varuse.modifiers
+ for _, modifier := range modifiers {
+ if modifier[0] == 'M' || (modifier[0] == 'N' && len(modifiers) == 1) {
ck.CheckVartype(varname, opUseMatch, modifier[1:], "")
+
+ value := modifier[1:]
+ vartype := mkline.VariableType(varname)
+ if matches(value, `^[\w-/]+$`) && vartype != nil && !vartype.IsConsideredList() {
+ mkline.Notef("%s should be compared using == instead of the :M or :N modifier without wildcards.", varname)
+ Explain(
+ "This variable has a single value, not a list of values. Therefore",
+ "it feels strange to apply list operators like :M and :N onto it.",
+ "A more direct approach is to use the == and != operators.",
+ "",
+ "An entirely different case is when the pattern contains wildcards",
+ "like ^, *, $. In such a case, using the :M or :N modifiers is",
+ "useful and preferred.")
+ }
}
}
}
Index: pkgsrc/pkgtools/pkglint/files/mklines.go
diff -u pkgsrc/pkgtools/pkglint/files/mklines.go:1.29 pkgsrc/pkgtools/pkglint/files/mklines.go:1.30
--- pkgsrc/pkgtools/pkglint/files/mklines.go:1.29 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/mklines.go Thu Aug 16 20:41:42 2018
@@ -140,9 +140,9 @@ func (mklines *MkLines) Check() {
G.Pkg.CheckInclude(mkline, mklines.indentation)
}
- case mkline.IsCond():
- ck.checkCond(mklines.forVars, mklines.indentation)
- substcontext.Conditional(mkline)
+ case mkline.IsDirective():
+ ck.checkDirective(mklines.forVars, mklines.indentation)
+ substcontext.Directive(mkline)
case mkline.IsDependency():
ck.checkDependencyRule(allowedTargets)
@@ -173,7 +173,7 @@ func (mklines *MkLines) Check() {
}
// ForEach calls the action for each line, until the action returns false.
-// It keeps track of the indentation and all conditionals.
+// It keeps track of the indentation and all conditional variables.
func (mklines *MkLines) ForEach(action func(mkline MkLine) bool, atEnd func(mkline MkLine)) {
mklines.indentation = NewIndentation()
@@ -256,7 +256,7 @@ func (mklines *MkLines) DetermineDefined
}
}
- mklines.toolRegistry.ParseToolLine(mkline.Line)
+ mklines.toolRegistry.ParseToolLine(mkline)
}
}
@@ -396,6 +396,10 @@ func (mklines *MkLines) CheckRedundantVa
func(mkline MkLine) {})
}
+func (mklines *MkLines) SaveAutofixChanges() {
+ SaveAutofixChanges(mklines.lines)
+}
+
// VaralignBlock checks that all variable assignments from a paragraph
// use the same indentation depth for their values.
// It also checks that the indentation uses tabs instead of spaces.
@@ -433,7 +437,7 @@ func (va *VaralignBlock) Check(mkline Mk
case mkline.IsComment():
return
- case mkline.IsCond():
+ case mkline.IsDirective():
return
case !mkline.IsVarassign():
@@ -613,7 +617,7 @@ func (va *VaralignBlock) realign(mkline
"alignment at all.",
"",
"When the block contains something else than variable definitions",
- "and conditionals, it is not checked at all.")
+ "and directives like .if or .for, it is not checked at all.")
}
fix.ReplaceAfter(varnameOp, oldSpace, newSpace)
fix.Apply()
Index: pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go
diff -u pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.29 pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.30
--- pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.29 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go Thu Aug 16 20:41:42 2018
@@ -78,7 +78,7 @@ func (s *Suite) Test_VartypeCheck_CFlag(
func (s *Suite) Test_VartypeCheck_Comment(c *check.C) {
t := s.Init(c)
- G.Pkg = NewPackage("category/converter")
+ G.Pkg = NewPackage(t.File("category/converter"))
G.Pkg.EffectivePkgbase = "converter"
runVartypeChecks(t, "COMMENT", opAssign, (*VartypeCheck).Comment,
@@ -168,13 +168,13 @@ func (s *Suite) Test_VartypeCheck_Depend
t.CreateFileLines("x11/alacarte/Makefile")
t.CreateFileLines("category/package/Makefile")
- G.Pkg = NewPackage("category/package")
+ G.Pkg = NewPackage(t.File("category/package"))
// Since this test involves relative paths, the filename of the line must be realistic.
// Therefore this custom implementation of runVartypeChecks.
runChecks := func(values ...string) {
for i, value := range values {
- mkline := t.NewMkLine(t.File("category/package/fname.mk"), i+1, "DEPENDS+=\t"+value)
+ mkline := t.NewMkLine(G.Pkg.File("fname.mk"), i+1, "DEPENDS+=\t"+value)
mkline.Tokenize(mkline.Value())
valueNovar := mkline.WithoutMakeVariables(mkline.Value())
vc := &VartypeCheck{mkline, mkline.Line, mkline.Varname(), mkline.Op(), mkline.Value(), valueNovar, "", false}
@@ -272,6 +272,8 @@ func (s *Suite) Test_VartypeCheck_Enum__
".if !empty(MACHINE_ARCH:Mi386) || ${MACHINE_ARCH} == i386",
".endif",
".if !empty(PKGSRC_COMPILER:Mclang) || ${PKGSRC_COMPILER} == clang",
+ ".endif",
+ ".if ${MACHINE_ARCH:Ni386:Nx86_64:Nsparc64}",
".endif")
mklines.Check()
@@ -661,9 +663,9 @@ func (s *Suite) Test_VartypeCheck_Yes(c
"${YESVAR}")
t.CheckOutputLines(
- "WARN: fname:1: PKG_DEVELOPER should only be used in a \".if defined(...)\" conditional.",
- "WARN: fname:2: PKG_DEVELOPER should only be used in a \".if defined(...)\" conditional.",
- "WARN: fname:3: PKG_DEVELOPER should only be used in a \".if defined(...)\" conditional.")
+ "WARN: fname:1: PKG_DEVELOPER should only be used in a \".if defined(...)\" condition.",
+ "WARN: fname:2: PKG_DEVELOPER should only be used in a \".if defined(...)\" condition.",
+ "WARN: fname:3: PKG_DEVELOPER should only be used in a \".if defined(...)\" condition.")
}
func (s *Suite) Test_VartypeCheck_YesNo(c *check.C) {
Index: pkgsrc/pkgtools/pkglint/files/mklines_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.25 pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.26
--- pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.25 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/mklines_test.go Thu Aug 16 20:41:42 2018
@@ -6,7 +6,7 @@ import (
"sort"
)
-func (s *Suite) Test_MkLines_Check__autofix_conditional_indentation(c *check.C) {
+func (s *Suite) Test_MkLines_Check__autofix_directive_indentation(c *check.C) {
t := s.Init(c)
t.SetupCommandLine("--autofix", "-Wspace")
@@ -69,7 +69,7 @@ func (s *Suite) Test_MkLines_quoting_LDF
t.SetupCommandLine("-Wall")
t.SetupVartypes()
- G.Pkg = NewPackage("category/pkgbase")
+ G.Pkg = NewPackage(t.File("category/pkgbase"))
mklines := t.NewMkLines("Makefile",
MkRcsID,
"GNU_CONFIGURE=\tyes",
@@ -443,7 +443,7 @@ func (s *Suite) Test_MkLines_Check__endi
".elif ${OPSYS} == FreeBSD",
".endif # NetBSD") // Wrong, should be FreeBSD from the .elif.
- // See MkLineChecker.checkCond
+ // See MkLineChecker.checkDirective
mklines.Check()
t.CheckOutputLines(""+
Index: pkgsrc/pkgtools/pkglint/files/mkparser.go
diff -u pkgsrc/pkgtools/pkglint/files/mkparser.go:1.14 pkgsrc/pkgtools/pkglint/files/mkparser.go:1.15
--- pkgsrc/pkgtools/pkglint/files/mkparser.go:1.14 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/mkparser.go Thu Aug 16 20:41:42 2018
@@ -108,6 +108,7 @@ func (p *MkParser) VarUseModifiers(varna
var modifiers []string
mayOmitColon := false
+loop:
for repl.AdvanceStr(":") || mayOmitColon {
mayOmitColon = false
modifierMark := repl.Mark()
@@ -125,7 +126,7 @@ func (p *MkParser) VarUseModifiers(varna
} else if len(rest) >= 1 && (rest[0] == closing[0] || rest[0] == ':') {
} else if repl.AdvanceRegexp(`^\\\d+`) {
} else {
- break
+ break loop
}
modifiers = append(modifiers, repl.Since(modifierMark))
continue
Index: pkgsrc/pkgtools/pkglint/files/vartype.go
diff -u pkgsrc/pkgtools/pkglint/files/vartype.go:1.14 pkgsrc/pkgtools/pkglint/files/vartype.go:1.15
--- pkgsrc/pkgtools/pkglint/files/vartype.go:1.14 Sat Apr 28 23:32:52 2018
+++ pkgsrc/pkgtools/pkglint/files/vartype.go Thu Aug 16 20:41:42 2018
@@ -122,16 +122,21 @@ func (vt *Vartype) MayBeAppendedTo() boo
}
func (vt *Vartype) String() string {
+ listPrefix := ""
switch vt.kindOfList {
case lkNone:
- return vt.basicType.name
+ listPrefix = ""
case lkSpace:
- return "SpaceList of " + vt.basicType.name
+ listPrefix = "SpaceList of "
case lkShell:
- return "ShellList of " + vt.basicType.name
+ listPrefix = "ShellList of "
default:
panic("Unknown list type")
}
+
+ guessedSuffix := ifelseStr(vt.guessed, " (guessed)", "")
+
+ return listPrefix + vt.basicType.name + guessedSuffix
}
func (vt *Vartype) IsShell() bool {
Index: pkgsrc/pkgtools/pkglint/files/package.go
diff -u pkgsrc/pkgtools/pkglint/files/package.go:1.33 pkgsrc/pkgtools/pkglint/files/package.go:1.34
--- pkgsrc/pkgtools/pkglint/files/package.go:1.33 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/package.go Thu Aug 16 20:41:42 2018
@@ -15,6 +15,7 @@ const rePkgname = `^([\w\-.+]+)-(\d[.0-9
// Package contains data for the pkgsrc package that is currently checked.
type Package struct {
+ dir string // The directory of the package, for resolving files
Pkgpath string // e.g. "category/pkgdir"
Pkgdir string // PKGDIR from the package Makefile
Filesdir string // FILESDIR from the package Makefile
@@ -30,7 +31,7 @@ type Package struct {
vars Scope
bl3 map[string]Line // buildlink3.mk name => line; contains only buildlink3.mk files that are directly included.
- plistSubstCond map[string]bool // varname => true; list of all variables that are used as conditionals (@comment or nothing) in PLISTs.
+ plistSubstCond map[string]bool // varname => true; all variables that are used as conditions (@comment or nothing) in PLISTs.
included map[string]Line // fname => line
seenMakefileCommon bool // Does the package have any .includes?
loadTimeTools map[string]bool // true=ok, false=not ok, absent=not mentioned in USE_TOOLS.
@@ -40,12 +41,19 @@ type Package struct {
IgnoreMissingPatches bool // In distinfo, don't warn about patches that cannot be found.
}
-func NewPackage(pkgpath string) *Package {
+func NewPackage(dir string) *Package {
+ pkgpath := G.Pkgsrc.ToRel(dir)
+ if strings.Count(pkgpath, "/") != 1 {
+ NewLineWhole(dir).Errorf("Package directory %q must be two subdirectories below the pkgsrc root %q.", dir, G.Pkgsrc.File("."))
+ }
+
pkg := &Package{
+ dir: dir,
Pkgpath: pkgpath,
Pkgdir: ".",
Filesdir: "files",
Patchdir: "patches",
+ DistinfoFile: "distinfo",
PlistDirs: make(map[string]bool),
PlistFiles: make(map[string]bool),
vars: NewScope(),
@@ -65,7 +73,7 @@ func NewPackage(pkgpath string) *Package
// File returns the (possibly absolute) path to relativeFilename,
// as resolved from the package's directory.
func (pkg *Package) File(relativeFilename string) string {
- return G.Pkgsrc.File(pkg.Pkgpath + "/" + relativeFilename)
+ return cleanpath(pkg.dir + "/" + relativeFilename)
}
func (pkg *Package) varValue(varname string) (string, bool) {
@@ -151,21 +159,14 @@ func (pkg *Package) checklinesBuildlink3
}
}
-// Given the package path relative to the pkgsrc top directory,
-// checks a complete pkgsrc package.
-//
-// Example:
-// checkdirPackage("category/pkgbase")
-func (pkglint *Pkglint) checkdirPackage(pkgpath string) {
+// checkdirPackage checks a complete pkgsrc package, including each
+// of the files individually, and also when seen in combination.
+func (pkglint *Pkglint) checkdirPackage(dir string) {
if trace.Tracing {
- defer trace.Call1(pkgpath)()
+ defer trace.Call1(dir)()
}
- if strings.Count(pkgpath, "/") != 1 {
- dummyLine.Fatalf("Internal pkglint error: Wrong pkgpath %q.", pkgpath)
- }
-
- G.Pkg = NewPackage(pkgpath)
+ G.Pkg = NewPackage(dir)
defer func() { G.Pkg = nil }()
pkg := G.Pkg
@@ -195,8 +196,8 @@ func (pkglint *Pkglint) checkdirPackage(
!matches(fname, `patch-`) &&
!contains(fname, pkg.Pkgdir+"/") &&
!contains(fname, pkg.Filesdir+"/") {
- if lines, err := readLines(fname, true); err == nil && lines != nil {
- NewMkLines(lines).DetermineUsedVariables()
+ if mklines := LoadMk(fname, MustSucceed); mklines != nil {
+ mklines.DetermineUsedVariables()
}
}
if hasPrefix(path.Base(fname), "PLIST") {
@@ -301,11 +302,10 @@ func (pkg *Package) readMakefile(fname s
defer trace.Call1(fname)()
}
- fileLines := LoadNonemptyLines(fname, true)
- if fileLines == nil {
+ fileMklines := LoadMk(fname, NotEmpty|LogErrors)
+ if fileMklines == nil {
return false
}
- fileMklines := NewMkLines(fileLines)
isMainMakefile := len(mainLines.mklines) == 0
@@ -916,10 +916,10 @@ func (pkg *Package) checkLocallyModified
}
func (pkg *Package) CheckInclude(mkline MkLine, indentation *Indentation) {
- conditionVars := mkline.ConditionVars()
- if conditionVars == "" {
- conditionVars = indentation.Varnames()
- mkline.SetConditionVars(conditionVars)
+ conditionalVars := mkline.ConditionalVars()
+ if conditionalVars == "" {
+ conditionalVars = indentation.Varnames()
+ mkline.SetConditionalVars(conditionalVars)
}
if path.Dir(abspath(mkline.Filename)) == abspath(pkg.File(".")) {
@@ -929,27 +929,23 @@ func (pkg *Package) CheckInclude(mkline
pkg.conditionalIncludes[includefile] = mkline
if other := pkg.unconditionalIncludes[includefile]; other != nil {
mkline.Warnf("%q is included conditionally here (depending on %s) and unconditionally in %s.",
- cleanpath(includefile), mkline.ConditionVars(), other.ReferenceFrom(mkline.Line))
+ cleanpath(includefile), mkline.ConditionalVars(), other.ReferenceFrom(mkline.Line))
}
} else {
pkg.unconditionalIncludes[includefile] = mkline
if other := pkg.conditionalIncludes[includefile]; other != nil {
mkline.Warnf("%q is included unconditionally here and conditionally in %s (depending on %s).",
- cleanpath(includefile), other.ReferenceFrom(mkline.Line), other.ConditionVars())
+ cleanpath(includefile), other.ReferenceFrom(mkline.Line), other.ConditionalVars())
}
}
}
}
func (pkg *Package) loadPlistDirs(plistFilename string) {
- lines, err := readLines(plistFilename, false)
- if err != nil {
- return
- }
-
+ lines := Load(plistFilename, MustSucceed)
for _, line := range lines {
text := line.Text
- pkg.PlistFiles[text] = true // XXX: ignores PLIST conditionals for now
+ pkg.PlistFiles[text] = true // XXX: ignores PLIST conditions for now
// Keep in sync with PlistChecker.collectFilesAndDirs
if !contains(text, "$") && !contains(text, "@") {
for dir := path.Dir(text); dir != "."; dir = path.Dir(dir) {
Index: pkgsrc/pkgtools/pkglint/files/package_test.go
diff -u pkgsrc/pkgtools/pkglint/files/package_test.go:1.27 pkgsrc/pkgtools/pkglint/files/package_test.go:1.28
--- pkgsrc/pkgtools/pkglint/files/package_test.go:1.27 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/package_test.go Thu Aug 16 20:41:42 2018
@@ -5,7 +5,7 @@ import "gopkg.in/check.v1"
func (s *Suite) Test_Package_pkgnameFromDistname(c *check.C) {
t := s.Init(c)
- pkg := NewPackage("dummy")
+ pkg := NewPackage(t.File("category/package"))
pkg.vars.Define("PKGNAME", t.NewMkLine("Makefile", 5, "PKGNAME=dummy"))
c.Check(pkg.pkgnameFromDistname("pkgname-1.0", "whatever"), equals, "pkgname-1.0")
@@ -25,7 +25,7 @@ func (s *Suite) Test_Package_CheckVarord
t := s.Init(c)
t.SetupCommandLine("-Worder")
- pkg := NewPackage("x11/9term")
+ pkg := NewPackage(t.File("x11/9term"))
pkg.CheckVarorder(t.NewMkLines("Makefile",
MkRcsID,
@@ -56,7 +56,7 @@ func (s *Suite) Test_Package_CheckVarord
t := s.Init(c)
t.SetupCommandLine("-Worder")
- pkg := NewPackage("x11/9term")
+ pkg := NewPackage(t.File("x11/9term"))
pkg.CheckVarorder(t.NewMkLines("Makefile",
MkRcsID,
@@ -79,7 +79,7 @@ func (s *Suite) Test_Package_CheckVarord
t.SetupCommandLine("-Worder")
- pkg := NewPackage("x11/9term")
+ pkg := NewPackage(t.File("x11/9term"))
pkg.CheckVarorder(t.NewMkLines("Makefile",
MkRcsID,
@@ -95,12 +95,12 @@ func (s *Suite) Test_Package_CheckVarord
t.CheckOutputEmpty()
}
-func (s *Suite) Test_Package_CheckVarorder__conditionals_skip(c *check.C) {
+func (s *Suite) Test_Package_CheckVarorder__skip_if_there_are_directives(c *check.C) {
t := s.Init(c)
t.SetupCommandLine("-Worder")
- pkg := NewPackage("x11/9term")
+ pkg := NewPackage(t.File("category/package"))
pkg.CheckVarorder(t.NewMkLines("Makefile",
MkRcsID,
@@ -113,8 +113,8 @@ func (s *Suite) Test_Package_CheckVarord
".endif",
"LICENSE=\tgnu-gpl-v2"))
- // No warning about the missing COMMENT since the conditional
- // skips the whole check.
+ // No warning about the missing COMMENT since the directive
+ // causes the whole check to be skipped.
t.CheckOutputEmpty()
}
@@ -122,7 +122,7 @@ func (s *Suite) Test_Package_CheckVarord
t := s.Init(c)
t.SetupCommandLine("-Worder")
- pkg := NewPackage("x11/9term")
+ pkg := NewPackage(t.File("x11/9term"))
pkg.CheckVarorder(t.NewMkLines("Makefile",
MkRcsID,
@@ -172,7 +172,7 @@ func (s *Suite) Test_Package_CheckVarord
t := s.Init(c)
t.SetupCommandLine("-Worder")
- pkg := NewPackage("category/package")
+ pkg := NewPackage(t.File("category/package"))
pkg.CheckVarorder(t.NewMkLines("Makefile",
MkRcsID,
@@ -196,7 +196,7 @@ func (s *Suite) Test_Package_CheckVarord
t.SetupCommandLine("-Worder")
t.SetupVartypes()
- pkg := NewPackage("category/package")
+ pkg := NewPackage(t.File("category/package"))
pkg.CheckVarorder(t.NewMkLines("Makefile",
MkRcsID,
@@ -246,7 +246,7 @@ func (s *Suite) Test_Package_CheckVarord
func (s *Suite) Test_Package_getNbpart(c *check.C) {
t := s.Init(c)
- pkg := NewPackage("category/pkgbase")
+ pkg := NewPackage(t.File("category/pkgbase"))
pkg.vars.Define("PKGREVISION", t.NewMkLine("Makefile", 1, "PKGREVISION=14"))
c.Check(pkg.getNbpart(), equals, "nb14")
@@ -260,7 +260,7 @@ func (s *Suite) Test_Package_getNbpart(c
func (s *Suite) Test_Package_determineEffectivePkgVars__precedence(c *check.C) {
t := s.Init(c)
- pkg := NewPackage("category/pkgbase")
+ pkg := NewPackage(t.File("category/pkgbase"))
pkgnameLine := t.NewMkLine("Makefile", 3, "PKGNAME=pkgname-1.0")
distnameLine := t.NewMkLine("Makefile", 4, "DISTNAME=distname-1.0")
pkgrevisionLine := t.NewMkLine("Makefile", 5, "PKGREVISION=13")
@@ -279,21 +279,19 @@ func (s *Suite) Test_Package_determineEf
func (s *Suite) Test_Package_checkPossibleDowngrade(c *check.C) {
t := s.Init(c)
- G.Pkg = NewPackage("category/pkgbase")
+ t.CreateFileLines("doc/CHANGES-2018",
+ "\tUpdated category/pkgbase to 1.8 [committer 2018-01-05]")
+ G.Pkgsrc.loadDocChanges()
+
+ t.Chdir("category/pkgbase")
+ G.Pkg = NewPackage(".")
G.Pkg.EffectivePkgname = "package-1.0nb15"
- G.Pkg.EffectivePkgnameLine = t.NewMkLine("category/pkgbase/Makefile", 5, "PKGNAME=dummy")
- G.Pkgsrc.LastChange = map[string]*Change{
- "category/pkgbase": {
- Action: "Updated",
- Version: "1.8",
- Line: t.NewLine("doc/CHANGES", 116, "dummy"),
- },
- }
+ G.Pkg.EffectivePkgnameLine = t.NewMkLine("Makefile", 5, "PKGNAME=dummy")
G.Pkg.checkPossibleDowngrade()
t.CheckOutputLines(
- "WARN: category/pkgbase/Makefile:5: The package is being downgraded from 1.8 (see ../../doc/CHANGES:116) to 1.0nb15.")
+ "WARN: Makefile:5: The package is being downgraded from 1.8 (see ../../doc/CHANGES-2018:1) to 1.0nb15.")
G.Pkgsrc.LastChange["category/pkgbase"].Version = "1.0nb22"
@@ -305,31 +303,33 @@ func (s *Suite) Test_Package_checkPossib
func (s *Suite) Test_checkdirPackage(c *check.C) {
t := s.Init(c)
- t.SetupFileLines("category/package/Makefile",
+ t.Chdir("category/package")
+ t.SetupFileLines("Makefile",
MkRcsID)
- G.checkdirPackage("category/package")
+ G.checkdirPackage(".")
t.CheckOutputLines(
- "WARN: ~/category/package/Makefile: Neither PLIST nor PLIST.common exist, and PLIST_SRC is unset.",
- "WARN: ~/category/package/distinfo: File not found. Please run \""+confMake+" makesum\" or define NO_CHECKSUM=yes in the package Makefile.",
- "ERROR: ~/category/package/Makefile: Each package must define its LICENSE.",
- "WARN: ~/category/package/Makefile: No COMMENT given.")
+ "WARN: Makefile: Neither PLIST nor PLIST.common exist, and PLIST_SRC is unset.",
+ "WARN: distinfo: File not found. Please run \""+confMake+" makesum\" or define NO_CHECKSUM=yes in the package Makefile.",
+ "ERROR: Makefile: Each package must define its LICENSE.",
+ "WARN: Makefile: No COMMENT given.")
}
func (s *Suite) Test_Pkglint_checkdirPackage__meta_package_without_license(c *check.C) {
t := s.Init(c)
- t.CreateFileLines("category/package/Makefile",
+ t.Chdir("category/package")
+ t.CreateFileLines("Makefile",
MkRcsID,
"",
"META_PACKAGE=\tyes")
t.SetupVartypes()
- G.checkdirPackage("category/package")
+ G.checkdirPackage(".")
t.CheckOutputLines(
- "WARN: ~/category/package/Makefile: No COMMENT given.") // No error about missing LICENSE.
+ "WARN: Makefile: No COMMENT given.") // No error about missing LICENSE.
}
func (s *Suite) Test_Package__varuse_at_load_time(c *check.C) {
@@ -391,10 +391,9 @@ func (s *Suite) Test_Package_loadPackage
"PKGNAME=pkgname-1.67",
"DISTNAME=distfile_1_67",
".include \"../../category/package/Makefile\"")
- pkg := NewPackage("category/package")
- G.Pkg = pkg
+ G.Pkg = NewPackage(t.File("category/package"))
- pkg.loadPackageMakefile()
+ G.Pkg.loadPackageMakefile()
// Including a package Makefile directly is an error (in the last line),
// but that is checked later.
@@ -409,7 +408,13 @@ func (s *Suite) Test_Package_conditional
t := s.Init(c)
t.SetupVartypes()
- t.CreateFileLines("category/package/Makefile",
+ t.CreateFileLines("devel/zlib/buildlink3.mk", "")
+ t.CreateFileLines("licenses/gnu-gpl-v2", "")
+ t.CreateFileLines("mk/bsd.pkg.mk", "")
+ t.CreateFileLines("sysutils/coreutils/buildlink3.mk", "")
+
+ t.Chdir("category/package")
+ t.CreateFileLines("Makefile",
MkRcsID,
"",
"COMMENT\t=Description",
@@ -419,37 +424,29 @@ func (s *Suite) Test_Package_conditional
".include \"../../sysutils/coreutils/buildlink3.mk\"",
".endif",
".include \"../../mk/bsd.pkg.mk\"")
- t.CreateFileLines("category/package/options.mk",
+ t.CreateFileLines("options.mk",
MkRcsID,
"",
".if !empty(PKG_OPTIONS:Mzlib)",
". include \"../../devel/zlib/buildlink3.mk\"",
".endif",
".include \"../../sysutils/coreutils/buildlink3.mk\"")
- t.CreateFileLines("category/package/PLIST",
+ t.CreateFileLines("PLIST",
PlistRcsID,
"bin/program")
- t.CreateFileLines("category/package/distinfo",
+ t.CreateFileLines("distinfo",
RcsID)
- t.CreateFileLines("devel/zlib/buildlink3.mk", "")
- t.CreateFileLines("licenses/gnu-gpl-v2", "")
- t.CreateFileLines("mk/bsd.pkg.mk", "")
- t.CreateFileLines("sysutils/coreutils/buildlink3.mk", "")
-
- pkg := NewPackage("category/package")
- G.Pkg = pkg
-
- G.checkdirPackage("category/package")
+ G.checkdirPackage(".")
t.CheckOutputLines(
- "WARN: ~/category/package/Makefile:3: The canonical order of the variables is CATEGORIES, empty line, COMMENT, LICENSE.",
- "WARN: ~/category/package/options.mk:3: Unknown option \"zlib\".",
- "WARN: ~/category/package/options.mk:4: \"../../devel/zlib/buildlink3.mk\" is "+
+ "WARN: Makefile:3: The canonical order of the variables is CATEGORIES, empty line, COMMENT, LICENSE.",
+ "WARN: options.mk:3: Unknown option \"zlib\".",
+ "WARN: options.mk:4: \"../../devel/zlib/buildlink3.mk\" is "+
"included conditionally here (depending on PKG_OPTIONS) and unconditionally in Makefile:5.",
- "WARN: ~/category/package/options.mk:6: \"../../sysutils/coreutils/buildlink3.mk\" is "+
+ "WARN: options.mk:6: \"../../sysutils/coreutils/buildlink3.mk\" is "+
"included unconditionally here and conditionally in Makefile:7 (depending on OPSYS).",
- "WARN: ~/category/package/options.mk:3: Expected definition of PKG_OPTIONS_VAR.")
+ "WARN: options.mk:3: Expected definition of PKG_OPTIONS_VAR.")
}
// See https://github.com/rillig/pkglint/issues/1
@@ -465,7 +462,7 @@ func (s *Suite) Test_Package_includeWith
"",
".include \"../../mk/bsd.pkg.mk\"")
- G.checkdirPackage("category/package")
+ G.checkdirPackage(t.File("category/package"))
t.CheckOutputLines(
"ERROR: ~/category/package/options.mk: Cannot be read.")
@@ -477,7 +474,8 @@ func (s *Suite) Test_Package_includeAfte
t.SetupVartypes()
t.CreateFileLines("mk/bsd.pkg.mk")
- t.CreateFileLines("category/package/Makefile",
+ t.Chdir("category/package")
+ t.CreateFileLines("Makefile",
MkRcsID,
"",
".if exists(options.mk)",
@@ -486,14 +484,14 @@ func (s *Suite) Test_Package_includeAfte
"",
".include \"../../mk/bsd.pkg.mk\"")
- G.checkdirPackage("category/package")
+ G.checkdirPackage(".")
t.CheckOutputLines(
- "WARN: ~/category/package/Makefile: Neither PLIST nor PLIST.common exist, and PLIST_SRC is unset.",
- "WARN: ~/category/package/distinfo: File not found. Please run \""+confMake+" makesum\" or define NO_CHECKSUM=yes in the package Makefile.",
- "ERROR: ~/category/package/Makefile: Each package must define its LICENSE.",
- "WARN: ~/category/package/Makefile: No COMMENT given.",
- "ERROR: ~/category/package/Makefile:4: \"options.mk\" does not exist.")
+ "WARN: Makefile: Neither PLIST nor PLIST.common exist, and PLIST_SRC is unset.",
+ "WARN: distinfo: File not found. Please run \""+confMake+" makesum\" or define NO_CHECKSUM=yes in the package Makefile.",
+ "ERROR: Makefile: Each package must define its LICENSE.",
+ "WARN: Makefile: No COMMENT given.",
+ "ERROR: Makefile:4: \"options.mk\" does not exist.")
}
// See https://github.com/rillig/pkglint/issues/1
@@ -511,7 +509,7 @@ func (s *Suite) Test_Package_includeOthe
"",
".include \"../../mk/bsd.pkg.mk\"")
- G.checkdirPackage("category/package")
+ G.checkdirPackage(t.File("category/package"))
t.CheckOutputLines(
"ERROR: ~/category/package/another.mk: Cannot be read.")
@@ -547,7 +545,7 @@ func (s *Suite) Test_Package__redundant_
// See Package.checkfilePackageMakefile
// See Scope.uncond
- G.checkdirPackage("math/R-date")
+ G.checkdirPackage(t.File("math/R-date"))
t.CheckOutputLines(
"NOTE: ~/math/R-date/Makefile:6: Definition of MASTER_SITES is redundant because of ../R/Makefile.extension:4.")
Index: pkgsrc/pkgtools/pkglint/files/parser_test.go
diff -u pkgsrc/pkgtools/pkglint/files/parser_test.go:1.7 pkgsrc/pkgtools/pkglint/files/parser_test.go:1.8
--- pkgsrc/pkgtools/pkglint/files/parser_test.go:1.7 Sat Jan 27 18:50:36 2018
+++ pkgsrc/pkgtools/pkglint/files/parser_test.go Thu Aug 16 20:41:42 2018
@@ -31,6 +31,14 @@ func (s *Suite) Test_Parser_Dependency(c
}
}
+ checkNil := func(pattern string) {
+ parser := NewParser(dummyLine, pattern, false)
+ dp := parser.Dependency()
+ if c.Check(dp, check.IsNil) {
+ c.Check(parser.Rest(), equals, pattern)
+ }
+ }
+
check := func(pattern string, expected DependencyPattern) {
checkRest(pattern, expected, "")
}
@@ -50,5 +58,7 @@ func (s *Suite) Test_Parser_Dependency(c
check("ncurses-${NC_VERS}{,nb*}", DependencyPattern{"ncurses", "", "", "", "", "${NC_VERS}{,nb*}"})
check("xulrunner10>=${MOZ_BRANCH}${MOZ_BRANCH_MINOR}", DependencyPattern{"xulrunner10", ">=", "${MOZ_BRANCH}${MOZ_BRANCH_MINOR}", "", "", ""})
checkRest("gnome-control-center>=2.20.1{,nb*}", DependencyPattern{"gnome-control-center", ">=", "2.20.1", "", "", ""}, "{,nb*}")
+ checkNil(">=2.20.1{,nb*}")
+ checkNil("pkgbase<=")
// "{ssh{,6}-[0-9]*,openssh-[0-9]*}" is not representable using the current data structure
}
Index: pkgsrc/pkgtools/pkglint/files/pkgsrc.go
diff -u pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.7 pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.8
--- pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.7 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/pkgsrc.go Thu Aug 16 20:41:42 2018
@@ -79,14 +79,14 @@ func NewPkgsrc(dir string) *Pkgsrc {
return src
}
-// Load reads the pkgsrc infrastructure files to
+// LoadInfrastructure reads the pkgsrc infrastructure files to
// extract information like the tools, packages to update,
// user-defined variables.
//
// This work is not done in the constructor to keep the tests
// simple, since setting up a realistic pkgsrc environment requires
// a lot of files.
-func (src *Pkgsrc) Load() {
+func (src *Pkgsrc) LoadInfrastructure() {
src.InitVartypes()
src.loadMasterSites()
src.loadPkgOptions()
@@ -148,9 +148,10 @@ func (src *Pkgsrc) loadTools() {
toolFiles := []string{"defaults.mk"}
{
toc := G.Pkgsrc.File("mk/tools/bsd.tools.mk")
- lines := LoadExistingLines(toc, true)
- for _, line := range lines {
- if m, _, _, includefile := MatchMkInclude(line.Text); m {
+ mklines := LoadMk(toc, MustSucceed|NotEmpty)
+ for _, mkline := range mklines.mklines {
+ if mkline.IsInclude() {
+ includefile := mkline.IncludeFile()
if !contains(includefile, "/") {
toolFiles = append(toolFiles, includefile)
}
@@ -162,41 +163,38 @@ func (src *Pkgsrc) loadTools() {
}
reg := src.Tools
- reg.RegisterTool(&Tool{"echo", "ECHO", true, true, true}, dummyLine)
- reg.RegisterTool(&Tool{"echo -n", "ECHO_N", true, true, true}, dummyLine)
- reg.RegisterTool(&Tool{"false", "FALSE", true /*why?*/, true, false}, dummyLine)
- reg.RegisterTool(&Tool{"test", "TEST", true, true, true}, dummyLine)
- reg.RegisterTool(&Tool{"true", "TRUE", true /*why?*/, true, true}, dummyLine)
+ reg.RegisterTool(&Tool{"echo", "ECHO", true, true, true}, dummyMkLine)
+ reg.RegisterTool(&Tool{"echo -n", "ECHO_N", true, true, true}, dummyMkLine)
+ reg.RegisterTool(&Tool{"false", "FALSE", true /*why?*/, true, false}, dummyMkLine)
+ reg.RegisterTool(&Tool{"test", "TEST", true, true, true}, dummyMkLine)
+ reg.RegisterTool(&Tool{"true", "TRUE", true /*why?*/, true, true}, dummyMkLine)
for _, basename := range toolFiles {
- lines := G.Pkgsrc.LoadExistingLines("mk/tools/"+basename, true)
- for _, line := range lines {
- reg.ParseToolLine(line)
+ mklines := G.Pkgsrc.LoadMk("mk/tools/"+basename, MustSucceed|NotEmpty)
+ for _, mkline := range mklines.mklines {
+ reg.ParseToolLine(mkline)
}
}
for _, relativeName := range [...]string{"mk/bsd.prefs.mk", "mk/bsd.pkg.mk"} {
- condDepth := 0
+ dirDepth := 0
- lines := G.Pkgsrc.LoadExistingLines(relativeName, true)
- for _, line := range lines {
- text := line.Text
- if hasPrefix(text, "#") {
- continue
- }
-
- if m, _, varname, _, _, _, value, _, _ := MatchVarassign(text); m {
+ mklines := G.Pkgsrc.LoadMk(relativeName, MustSucceed|NotEmpty)
+ for _, mkline := range mklines.mklines {
+ if mkline.IsVarassign() {
+ varname := mkline.Varname()
+ value := mkline.Value()
if varname == "USE_TOOLS" {
if trace.Tracing {
- trace.Stepf("[condDepth=%d] %s", condDepth, value)
+ trace.Stepf("[dirDepth=%d] %s", dirDepth, value)
}
- if condDepth == 0 || condDepth == 1 && relativeName == "mk/bsd.prefs.mk" {
+ if dirDepth == 0 || dirDepth == 1 && relativeName == "mk/bsd.prefs.mk" {
for _, toolname := range splitOnSpace(value) {
if !containsVarRef(toolname) {
- tool := reg.Register(toolname, line)
+ tool := reg.Register(toolname, mkline)
tool.Predefined = true
if relativeName == "mk/bsd.prefs.mk" {
- tool.UsableAtLoadtime = true
+ tool.UsableAtLoadTime = true
}
}
}
@@ -208,12 +206,12 @@ func (src *Pkgsrc) loadTools() {
}
}
- } else if m, _, cond, _, _ := matchMkCond(text); m {
- switch cond {
+ } else if mkline.IsDirective() {
+ switch mkline.Directive() {
case "if", "ifdef", "ifndef", "for":
- condDepth++
+ dirDepth++
case "endif", "endfor":
- condDepth--
+ dirDepth--
}
}
}
@@ -224,11 +222,6 @@ func (src *Pkgsrc) loadTools() {
}
}
-func (src *Pkgsrc) loadSuggestedUpdatesFile(fname string) []SuggestedUpdate {
- lines := LoadExistingLines(fname, false)
- return src.parseSuggestedUpdates(lines)
-}
-
func (src *Pkgsrc) parseSuggestedUpdates(lines []Line) []SuggestedUpdate {
var updates []SuggestedUpdate
state := 0
@@ -261,14 +254,11 @@ func (src *Pkgsrc) parseSuggestedUpdates
}
func (src *Pkgsrc) loadSuggestedUpdates() {
- src.suggestedUpdates = src.loadSuggestedUpdatesFile(G.Pkgsrc.File("doc/TODO"))
- if wipFilename := G.Pkgsrc.File("wip/TODO"); fileExists(wipFilename) {
- src.suggestedWipUpdates = src.loadSuggestedUpdatesFile(wipFilename)
- }
+ src.suggestedUpdates = src.parseSuggestedUpdates(Load(G.Pkgsrc.File("doc/TODO"), MustSucceed))
+ src.suggestedWipUpdates = src.parseSuggestedUpdates(Load(G.Pkgsrc.File("wip/TODO"), NotEmpty))
}
func (src *Pkgsrc) loadDocChangesFromFile(fname string) []*Change {
- lines := LoadExistingLines(fname, false)
parseChange := func(line Line) *Change {
text := line.Text
@@ -306,6 +296,7 @@ func (src *Pkgsrc) loadDocChangesFromFil
year = yyyy
}
+ lines := Load(fname, MustSucceed|NotEmpty)
var changes []*Change
for _, line := range lines {
if change := parseChange(line); change != nil {
@@ -371,8 +362,7 @@ func (src *Pkgsrc) loadDocChanges() {
}
func (src *Pkgsrc) loadUserDefinedVars() {
- lines := G.Pkgsrc.LoadExistingLines("mk/defaults/mk.conf", true)
- mklines := NewMkLines(lines)
+ mklines := G.Pkgsrc.LoadMk("mk/defaults/mk.conf", MustSucceed|NotEmpty)
for _, mkline := range mklines.mklines {
if mkline.IsVarassign() {
@@ -542,9 +532,14 @@ func (src *Pkgsrc) initDeprecatedVars()
}
}
-// LoadExistingLines loads the file relative to the pkgsrc top directory.
-func (src *Pkgsrc) LoadExistingLines(fileName string, joinBackslashLines bool) []Line {
- return LoadExistingLines(src.File(fileName), joinBackslashLines)
+// Load loads the file relative to the pkgsrc top directory.
+func (src *Pkgsrc) Load(fileName string, options LoadOptions) []Line {
+ return Load(src.File(fileName), options)
+}
+
+// LoadMk loads the Makefile relative to the pkgsrc top directory.
+func (src *Pkgsrc) LoadMk(fileName string, options LoadOptions) *MkLines {
+ return LoadMk(src.File(fileName), options)
}
// File resolves a file name relative to the pkgsrc top directory.
@@ -572,14 +567,15 @@ func (src *Pkgsrc) IsBuildDef(varname st
}
func (src *Pkgsrc) loadMasterSites() {
- lines := src.LoadExistingLines("mk/fetch/sites.mk", true)
+ mklines := src.LoadMk("mk/fetch/sites.mk", MustSucceed|NotEmpty)
nameToUrl := src.MasterSiteVarToURL
urlToName := src.MasterSiteURLToVar
- for _, line := range lines {
- if m, commented, varname, _, _, _, urls, _, _ := MatchVarassign(line.Text); m {
- if !commented && hasPrefix(varname, "MASTER_SITE_") && varname != "MASTER_SITE_BACKUP" {
- for _, url := range splitOnSpace(urls) {
+ for _, mkline := range mklines.mklines {
+ if mkline.IsVarassign() {
+ varname := mkline.Varname()
+ if hasPrefix(varname, "MASTER_SITE_") && varname != "MASTER_SITE_BACKUP" {
+ for _, url := range splitOnSpace(mkline.Value()) {
if matches(url, `^(?:http://|https://|ftp://)`) {
if nameToUrl[varname] == "" {
nameToUrl[varname] = url
@@ -600,7 +596,7 @@ func (src *Pkgsrc) loadMasterSites() {
}
func (src *Pkgsrc) loadPkgOptions() {
- lines := src.LoadExistingLines("mk/defaults/options.description", false)
+ lines := src.Load("mk/defaults/options.description", MustSucceed)
for _, line := range lines {
if m, optname, optdescr := match2(line.Text, `^([-0-9a-z_+]+)(?:\s+(.*))?$`); m {
Index: pkgsrc/pkgtools/pkglint/files/patches_test.go
diff -u pkgsrc/pkgtools/pkglint/files/patches_test.go:1.18 pkgsrc/pkgtools/pkglint/files/patches_test.go:1.19
--- pkgsrc/pkgtools/pkglint/files/patches_test.go:1.18 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/patches_test.go Thu Aug 16 20:41:42 2018
@@ -31,6 +31,7 @@ func (s *Suite) Test_ChecklinesPatch__wi
func (s *Suite) Test_ChecklinesPatch__without_empty_line__autofix(c *check.C) {
t := s.Init(c)
+ t.Chdir("category/package")
patchLines := t.SetupFileLines("patch-WithoutEmptyLines",
RcsID,
"Text",
@@ -48,14 +49,14 @@ func (s *Suite) Test_ChecklinesPatch__wi
"SHA1 (some patch) = 49abd735b7e706ea9ed6671628bb54e91f7f5ffb")
t.SetupCommandLine("-Wall", "--autofix")
- G.Pkg = &Package{DistinfoFile: "distinfo"}
+ G.Pkg = NewPackage(".")
ChecklinesPatch(patchLines)
t.CheckOutputLines(
- "AUTOFIX: ~/patch-WithoutEmptyLines:2: Inserting a line \"\" before this line.",
- "AUTOFIX: ~/patch-WithoutEmptyLines:3: Inserting a line \"\" before this line.",
- "AUTOFIX: ~/distinfo:3: Replacing \"49abd735b7e706ea9ed6671628bb54e91f7f5ffb\" "+
+ "AUTOFIX: patch-WithoutEmptyLines:2: Inserting a line \"\" before this line.",
+ "AUTOFIX: patch-WithoutEmptyLines:3: Inserting a line \"\" before this line.",
+ "AUTOFIX: distinfo:3: Replacing \"49abd735b7e706ea9ed6671628bb54e91f7f5ffb\" "+
"with \"4938fc8c0b483dc2e33e741b0da883d199e78164\".")
t.CheckFileLines("patch-WithoutEmptyLines",
Index: pkgsrc/pkgtools/pkglint/files/pkglint_test.go
diff -u pkgsrc/pkgtools/pkglint/files/pkglint_test.go:1.22 pkgsrc/pkgtools/pkglint/files/pkglint_test.go:1.23
--- pkgsrc/pkgtools/pkglint/files/pkglint_test.go:1.22 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/pkglint_test.go Thu Aug 16 20:41:42 2018
@@ -291,7 +291,7 @@ func (s *Suite) Test_resolveVariableRefs
t := s.Init(c)
mkline := t.NewMkLine("fname", 1, "GCC_VERSION=${GCC_VERSION}")
- G.Pkg = NewPackage(".")
+ G.Pkg = NewPackage(t.File("category/pkgbase"))
G.Pkg.vars.Define("GCC_VERSION", mkline)
resolved := resolveVariableRefs("gcc-${GCC_VERSION}")
@@ -305,7 +305,7 @@ func (s *Suite) Test_resolveVariableRefs
mkline1 := t.NewMkLine("fname", 10, "_=${SECOND}")
mkline2 := t.NewMkLine("fname", 11, "_=${THIRD}")
mkline3 := t.NewMkLine("fname", 12, "_=got it")
- G.Pkg = NewPackage(".")
+ G.Pkg = NewPackage(t.File("category/pkgbase"))
defineVar(mkline1, "FIRST")
defineVar(mkline2, "SECOND")
defineVar(mkline3, "THIRD")
@@ -322,7 +322,7 @@ func (s *Suite) Test_resolveVariableRefs
t := s.Init(c)
mkline := t.NewMkLine("fname", 10, "_=x11")
- G.Pkg = NewPackage("category/pkg")
+ G.Pkg = NewPackage(t.File("category/pkg"))
G.Pkg.vars.Define("GST_PLUGINS0.10_TYPE", mkline)
resolved := resolveVariableRefs("gst-plugins0.10-${GST_PLUGINS0.10_TYPE}/distinfo")
@@ -484,3 +484,52 @@ func (s *Suite) Test_Pkglint_Checkfile__
"Looks fine.",
"(Run \"pkglint -e\" to show explanations.)")
}
+
+func (s *Suite) Test_Pkglint__profiling(c *check.C) {
+ t := s.Init(c)
+
+ t.SetupPkgsrc()
+ G.Main("pkglint", "--profiling", t.File("."))
+
+ // Pkglint always writes the profiling data into the current directory.
+ // Luckily, this directory is usually writable.
+ c.Check(fileExists("pkglint.pprof"), equals, true)
+
+ err := os.Remove("pkglint.pprof")
+ c.Check(err, check.IsNil)
+
+ // Everything but the first few lines of output is not easily testable
+ // or not interesting enough, since that info includes the exact timing
+ // that the top time-consuming regular expressions took.
+ firstOutput := strings.Split(t.Output(), "\n")[0]
+ c.Check(firstOutput, equals, "ERROR: ~/Makefile: Cannot be read.")
+}
+
+func (s *Suite) Test_Pkglint_Checkfile__in_current_working_directory(c *check.C) {
+ t := s.Init(c)
+
+ t.SetupPkgsrc()
+ t.SetupVartypes()
+ t.CreateFileLines("licenses/mit")
+ t.Chdir("category/package")
+ t.CreateFileLines("log")
+ t.CreateFileLines("Makefile",
+ MkRcsID,
+ "",
+ "NO_CHECKSUM= yes",
+ "COMMENT= Useful utilities",
+ "LICENSE= mit",
+ "",
+ ".include \"../../mk/bsd.pkg.mk\"")
+ t.CreateFileLines("PLIST",
+ PlistRcsID,
+ "bin/program")
+ t.CreateFileLines("DESCR",
+ "Package description")
+
+ G.Main("pkglint")
+
+ t.CheckOutputLines(
+ "WARN: log: Unexpected file found.",
+ "0 errors and 1 warning found.")
+}
Index: pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go
diff -u pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go:1.5 pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go:1.6
--- pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go:1.5 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go Thu Aug 16 20:41:42 2018
@@ -1,9 +1,6 @@
package main
-import (
- "gopkg.in/check.v1"
- "netbsd.org/pkglint/trace"
-)
+import "gopkg.in/check.v1"
// Ensures that pkglint can handle MASTER_SITES definitions with and
// without line continuations.
@@ -99,25 +96,26 @@ func (s *Suite) Test_Pkgsrc_loadTools(c
G.Pkgsrc.loadTools()
- trace.Tracing = true
+ t.EnableTracingToLog()
G.Pkgsrc.Tools.Trace()
+ t.DisableTracing()
t.CheckOutputLines(
"TRACE: + (*ToolRegistry).Trace()",
- "TRACE: 1 tool &{Name:bzcat Varname: MustUseVarForm:false Predefined:false UsableAtLoadtime:false}",
- "TRACE: 1 tool &{Name:bzip2 Varname: MustUseVarForm:false Predefined:false UsableAtLoadtime:false}",
- "TRACE: 1 tool &{Name:chown Varname:CHOWN MustUseVarForm:false Predefined:false UsableAtLoadtime:false}",
- "TRACE: 1 tool &{Name:echo Varname:ECHO MustUseVarForm:true Predefined:true UsableAtLoadtime:true}",
- "TRACE: 1 tool &{Name:echo -n Varname:ECHO_N MustUseVarForm:true Predefined:true UsableAtLoadtime:true}",
- "TRACE: 1 tool &{Name:false Varname:FALSE MustUseVarForm:true Predefined:true UsableAtLoadtime:false}",
- "TRACE: 1 tool &{Name:gawk Varname:AWK MustUseVarForm:false Predefined:false UsableAtLoadtime:false}",
- "TRACE: 1 tool &{Name:m4 Varname: MustUseVarForm:false Predefined:true UsableAtLoadtime:true}",
- "TRACE: 1 tool &{Name:msgfmt Varname: MustUseVarForm:false Predefined:false UsableAtLoadtime:false}",
- "TRACE: 1 tool &{Name:mv Varname:MV MustUseVarForm:false Predefined:true UsableAtLoadtime:false}",
- "TRACE: 1 tool &{Name:pwd Varname:PWD MustUseVarForm:false Predefined:true UsableAtLoadtime:true}",
- "TRACE: 1 tool &{Name:strip Varname: MustUseVarForm:false Predefined:false UsableAtLoadtime:false}",
- "TRACE: 1 tool &{Name:test Varname:TEST MustUseVarForm:true Predefined:true UsableAtLoadtime:true}",
- "TRACE: 1 tool &{Name:true Varname:TRUE MustUseVarForm:true Predefined:true UsableAtLoadtime:true}",
+ "TRACE: 1 tool &{Name:bzcat Varname: MustUseVarForm:false Predefined:false UsableAtLoadTime:false}",
+ "TRACE: 1 tool &{Name:bzip2 Varname: MustUseVarForm:false Predefined:false UsableAtLoadTime:false}",
+ "TRACE: 1 tool &{Name:chown Varname:CHOWN MustUseVarForm:false Predefined:false UsableAtLoadTime:false}",
+ "TRACE: 1 tool &{Name:echo Varname:ECHO MustUseVarForm:true Predefined:true UsableAtLoadTime:true}",
+ "TRACE: 1 tool &{Name:echo -n Varname:ECHO_N MustUseVarForm:true Predefined:true UsableAtLoadTime:true}",
+ "TRACE: 1 tool &{Name:false Varname:FALSE MustUseVarForm:true Predefined:true UsableAtLoadTime:false}",
+ "TRACE: 1 tool &{Name:gawk Varname:AWK MustUseVarForm:false Predefined:false UsableAtLoadTime:false}",
+ "TRACE: 1 tool &{Name:m4 Varname: MustUseVarForm:false Predefined:true UsableAtLoadTime:true}",
+ "TRACE: 1 tool &{Name:msgfmt Varname: MustUseVarForm:false Predefined:false UsableAtLoadTime:false}",
+ "TRACE: 1 tool &{Name:mv Varname:MV MustUseVarForm:false Predefined:true UsableAtLoadTime:false}",
+ "TRACE: 1 tool &{Name:pwd Varname:PWD MustUseVarForm:false Predefined:true UsableAtLoadTime:true}",
+ "TRACE: 1 tool &{Name:strip Varname: MustUseVarForm:false Predefined:false UsableAtLoadTime:false}",
+ "TRACE: 1 tool &{Name:test Varname:TEST MustUseVarForm:true Predefined:true UsableAtLoadTime:true}",
+ "TRACE: 1 tool &{Name:true Varname:TRUE MustUseVarForm:true Predefined:true UsableAtLoadTime:true}",
"TRACE: - (*ToolRegistry).Trace()")
}
Index: pkgsrc/pkgtools/pkglint/files/plist.go
diff -u pkgsrc/pkgtools/pkglint/files/plist.go:1.26 pkgsrc/pkgtools/pkglint/files/plist.go:1.27
--- pkgsrc/pkgtools/pkglint/files/plist.go:1.26 Thu Jul 12 16:23:36 2018
+++ pkgsrc/pkgtools/pkglint/files/plist.go Thu Aug 16 20:41:42 2018
@@ -45,9 +45,9 @@ type PlistChecker struct {
}
type PlistLine struct {
- line Line
- conditional string // e.g. PLIST.docs
- text string // Like line.text, without the conditional
+ line Line
+ condition string // e.g. PLIST.docs
+ text string // Like line.text, without the condition
}
func (ck *PlistChecker) Check(plainLines []Line) {
@@ -55,8 +55,8 @@ func (ck *PlistChecker) Check(plainLines
ck.collectFilesAndDirs(plines)
if fname := plines[0].line.Filename; path.Base(fname) == "PLIST.common_end" {
- commonLines, err := readLines(strings.TrimSuffix(fname, "_end"), false)
- if err == nil {
+ commonLines := Load(strings.TrimSuffix(fname, "_end"), NotEmpty)
+ if commonLines != nil {
ck.collectFilesAndDirs(ck.NewLines(commonLines))
}
}
@@ -81,13 +81,13 @@ func (ck *PlistChecker) Check(plainLines
func (ck *PlistChecker) NewLines(lines []Line) []*PlistLine {
plines := make([]*PlistLine, len(lines))
for i, line := range lines {
- conditional, text := "", line.Text
+ condition, text := "", line.Text
if hasPrefix(text, "${PLIST.") {
if m, cond, rest := match2(text, `^(?:\$\{(PLIST\.[\w-.]+)\})+(.*)`); m {
- conditional, text = cond, rest
+ condition, text = cond, rest
}
}
- plines[i] = &PlistLine{line, conditional, text}
+ plines[i] = &PlistLine{line, condition, text}
}
return plines
}
@@ -101,7 +101,7 @@ func (ck *PlistChecker) collectFilesAndD
first == '$',
'A' <= first && first <= 'Z',
'0' <= first && first <= '9':
- if prev := ck.allFiles[text]; prev == nil || pline.conditional < prev.conditional {
+ if prev := ck.allFiles[text]; prev == nil || pline.condition < prev.condition {
ck.allFiles[text] = pline
}
for dir := path.Dir(text); dir != "."; dir = path.Dir(dir) {
@@ -224,7 +224,7 @@ func (ck *PlistChecker) checkDuplicate(p
}
prev := ck.allFiles[text]
- if prev == pline || prev.conditional != "" {
+ if prev == pline || prev.condition != "" {
return
}
@@ -518,7 +518,7 @@ func (s *plistLineSorter) Sort() {
mi := s.middle[i]
mj := s.middle[j]
less := mi.text < mj.text || (mi.text == mj.text &&
- mi.conditional < mj.conditional)
+ mi.condition < mj.condition)
if (i < j) != less {
s.changed = true
}
Index: pkgsrc/pkgtools/pkglint/files/util.go
diff -u pkgsrc/pkgtools/pkglint/files/util.go:1.26 pkgsrc/pkgtools/pkglint/files/util.go:1.27
--- pkgsrc/pkgtools/pkglint/files/util.go:1.26 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/util.go Thu Aug 16 20:41:42 2018
@@ -169,8 +169,8 @@ func loadCvsEntries(fname string) []Line
return G.CvsEntriesLines
}
- lines, err := readLines(dir+"/CVS/Entries", false)
- if err != nil {
+ lines := Load(dir+"/CVS/Entries", 0)
+ if lines == nil {
return nil
}
G.CvsEntriesDir = dir
@@ -301,7 +301,7 @@ func dirglob(dirname string) []string {
var fnames []string
for _, fi := range fis {
if !(isIgnoredFilename(fi.Name())) {
- fnames = append(fnames, dirname+"/"+fi.Name())
+ fnames = append(fnames, cleanpath(dirname+"/"+fi.Name()))
}
}
return fnames
@@ -585,7 +585,7 @@ func naturalLess(str1, str2 string) bool
// but that's deep in the infrastructure and only affects the "nb13" extension.)
type RedundantScope struct {
vars map[string]*redundantScopeVarinfo
- condLevel int
+ dirLevel int
OnIgnore func(old, new MkLine)
OnOverwrite func(old, new MkLine)
}
@@ -602,7 +602,7 @@ func (s *RedundantScope) Handle(mkline M
switch {
case mkline.IsVarassign():
varname := mkline.Varname()
- if s.condLevel != 0 {
+ if s.dirLevel != 0 {
s.vars[varname] = nil
break
}
@@ -645,12 +645,12 @@ func (s *RedundantScope) Handle(mkline M
}
}
- case mkline.IsCond():
+ case mkline.IsDirective():
switch mkline.Directive() {
case "for", "if", "ifdef", "ifndef":
- s.condLevel++
+ s.dirLevel++
case "endfor", "endif":
- s.condLevel--
+ s.dirLevel--
}
}
}
Index: pkgsrc/pkgtools/pkglint/files/shell_test.go
diff -u pkgsrc/pkgtools/pkglint/files/shell_test.go:1.28 pkgsrc/pkgtools/pkglint/files/shell_test.go:1.29
--- pkgsrc/pkgtools/pkglint/files/shell_test.go:1.28 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/shell_test.go Thu Aug 16 20:41:42 2018
@@ -184,7 +184,7 @@ func (s *Suite) Test_ShellLine_CheckShel
t.CheckOutputEmpty()
- checkShellCommandLine("${RUN} echo $${variable+set}")
+ checkShellCommandLine("${RUN} set +x; echo $${variable+set}")
t.CheckOutputEmpty()
@@ -234,7 +234,7 @@ func (s *Suite) Test_ShellLine_CheckShel
"WARN: fname:1: The shell command \"cp\" should not be hidden.",
"WARN: fname:1: Unknown shell command \"cp\".")
- G.Pkg = NewPackage("category/pkgbase")
+ G.Pkg = NewPackage(t.File("category/pkgbase"))
G.Pkg.PlistDirs["share/pkgbase"] = true
// A directory that is found in the PLIST.
Index: pkgsrc/pkgtools/pkglint/files/substcontext.go
diff -u pkgsrc/pkgtools/pkglint/files/substcontext.go:1.11 pkgsrc/pkgtools/pkglint/files/substcontext.go:1.12
--- pkgsrc/pkgtools/pkglint/files/substcontext.go:1.11 Thu Jul 12 16:23:36 2018
+++ pkgsrc/pkgtools/pkglint/files/substcontext.go Thu Aug 16 20:41:42 2018
@@ -134,13 +134,13 @@ func (ctx *SubstContext) Varassign(mklin
}
}
-func (ctx *SubstContext) Conditional(mkline MkLine) {
+func (ctx *SubstContext) Directive(mkline MkLine) {
if ctx.id == "" || !G.opts.WarnExtra {
return
}
if trace.Tracing {
- trace.Stepf("+ SubstContext.Conditional %#v %v#", ctx.curr, ctx.inAllBranches)
+ trace.Stepf("+ SubstContext.Directive %#v %v#", ctx.curr, ctx.inAllBranches)
}
dir := mkline.Directive()
if dir == "if" {
@@ -159,7 +159,7 @@ func (ctx *SubstContext) Conditional(mkl
ctx.curr.Or(ctx.inAllBranches)
}
if trace.Tracing {
- trace.Stepf("- SubstContext.Conditional %#v %v#", ctx.curr, ctx.inAllBranches)
+ trace.Stepf("- SubstContext.Directive %#v %v#", ctx.curr, ctx.inAllBranches)
}
}
Index: pkgsrc/pkgtools/pkglint/files/util_test.go
diff -u pkgsrc/pkgtools/pkglint/files/util_test.go:1.11 pkgsrc/pkgtools/pkglint/files/util_test.go:1.12
--- pkgsrc/pkgtools/pkglint/files/util_test.go:1.11 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/util_test.go Thu Aug 16 20:41:42 2018
@@ -86,11 +86,13 @@ func (s *Suite) Test_isEmptyDir_and_getS
if absent := t.File("nonexistent"); true {
c.Check(isEmptyDir(absent), equals, true) // Counts as empty.
- defer t.ExpectFatalError(func() {
- c.Check(t.Output(), check.Matches, `FATAL: (.+): Cannot be read: open (.+): (.+)\n`)
- })
- getSubdirs(absent) // Panics with a pkglintFatal.
- c.FailNow()
+
+ func() {
+ defer t.ExpectFatalError()
+ getSubdirs(absent) // Panics with a pkglintFatal.
+ }()
+ // The last group from the error message is localized, therefore the matching.
+ c.Check(t.Output(), check.Matches, `FATAL: ~/nonexistent: Cannot be read: open ~/nonexistent: (.+)\n`)
}
}
Index: pkgsrc/pkgtools/pkglint/files/vardefs.go
diff -u pkgsrc/pkgtools/pkglint/files/vardefs.go:1.43 pkgsrc/pkgtools/pkglint/files/vardefs.go:1.44
--- pkgsrc/pkgtools/pkglint/files/vardefs.go:1.43 Thu Jul 19 06:38:15 2018
+++ pkgsrc/pkgtools/pkglint/files/vardefs.go Thu Aug 16 20:41:42 2018
@@ -71,41 +71,18 @@ func (src *Pkgsrc) InitVartypes() {
acl(varname, kindOfList, checker, "buildlink3.mk, builtin.mk:; *: use-loadtime, use")
}
- jvms := enum(func() string {
- lines, _ := readLines(src.File("mk/java-vm.mk"), true)
- mklines := NewMkLines(lines)
- jvms := make(map[string]bool)
- for _, mkline := range mklines.mklines {
- if mkline.IsVarassign() && mkline.Varcanon() == "_PKG_JVMS.*" {
- words, _ := splitIntoMkWords(mkline.Line, mkline.Value())
- for _, word := range words {
- if !contains(word, "$") {
- jvms[word] = true
- }
- }
- }
- }
- if len(jvms) == 0 {
- return "openjdk8 oracle-jdk8 openjdk7 sun-jdk7 sun-jdk6 jdk16 jdk15 kaffe"
- }
- joined := keysJoined(jvms)
- if trace.Tracing {
- trace.Stepf("JVMs from mk/java-vm.mk: %s", joined)
- }
- return joined
- }())
-
languages := enum(
func() string {
- lines, _ := readLines(src.File("mk/compiler.mk"), true)
- mklines := NewMkLines(lines)
+ mklines := LoadMk(src.File("mk/compiler.mk"), NotEmpty)
languages := make(map[string]bool)
- for _, mkline := range mklines.mklines {
- if mkline.IsCond() && mkline.Directive() == "for" {
- words := splitOnSpace(mkline.Args())
- if len(words) > 2 && words[0] == "_version_" {
- for _, word := range words[2:] {
- languages[word] = true
+ if mklines != nil {
+ for _, mkline := range mklines.mklines {
+ if mkline.IsDirective() && mkline.Directive() == "for" {
+ words := splitOnSpace(mkline.Args())
+ if len(words) > 2 && words[0] == "_version_" {
+ for _, word := range words[2:] {
+ languages[word] = true
+ }
}
}
}
@@ -121,17 +98,68 @@ func (src *Pkgsrc) InitVartypes() {
return joined
}())
- enumFrom := func(fileName, varname, defval string) *BasicType {
- lines, _ := readLines(src.File(fileName), true)
- mklines := NewMkLines(lines)
- for _, mkline := range mklines.mklines {
- if mkline.IsVarassign() && mkline.Varname() == varname {
- return enum(mkline.Value())
+ enumFrom := func(fileName string, defval string, varcanons ...string) *BasicType {
+ mklines := LoadMk(src.File(fileName), NotEmpty)
+ values := make(map[string]bool)
+
+ if mklines != nil {
+ for _, mkline := range mklines.mklines {
+ if mkline.IsVarassign() {
+ varcanon := mkline.Varcanon()
+ for _, vc := range varcanons {
+ if vc == varcanon {
+ words, _ := splitIntoMkWords(mkline.Line, mkline.Value())
+ for _, word := range words {
+ if !contains(word, "$") {
+ values[word] = true
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if len(values) != 0 {
+ joined := keysJoined(values)
+ if trace.Tracing {
+ trace.Stepf("Enum from %s in: %s", strings.Join(varcanons, " "), fileName, joined)
}
+ return enum(joined)
+ }
+
+ if trace.Tracing {
+ trace.Stepf("Enum from default value: %s", defval)
}
return enum(defval)
}
+ compilers := enumFrom(
+ "mk/compiler.mk",
+ "ccache ccc clang distcc f2c gcc hp icc ido mipspro mipspro-ucode pcc sunpro xlc",
+ "_COMPILERS",
+ "_PSEUDO_COMPILERS")
+
+ emacsVersions := enumFrom(
+ "editors/emacs/modules.mk",
+ "emacs25 emacs21 emacs21nox emacs20 xemacs215 xemacs215nox xemacs214 xemacs214nox",
+ "_EMACS_VERSIONS_ALL")
+
+ mysqlVersions := enumFrom(
+ "mk/mysql.buildlink3.mk",
+ "57 56 55 51 MARIADB55",
+ "MYSQL_VERSIONS_ACCEPTED")
+
+ pgsqlVersions := enumFrom(
+ "mk/pgsql.buildlink3.mk",
+ "10 96 95 94 93",
+ "PGSQL_VERSIONS_ACCEPTED")
+
+ jvms := enumFrom(
+ "mk/java-vm.mk",
+ "openjdk8 oracle-jdk8 openjdk7 sun-jdk7 sun-jdk6 jdk16 jdk15 kaffe",
+ "_PKG_JVMS.*")
+
// Last synced with mk/defaults/mk.conf revision 1.269
usr("USE_CWRAPPERS", lkNone, enum("yes no auto"))
usr("ALLOW_VULNERABLE_PACKAGES", lkNone, BtYes)
@@ -153,7 +181,7 @@ func (src *Pkgsrc) InitVartypes() {
usr("PKG_DEVELOPER", lkNone, BtYesNo)
usr("USE_ABI_DEPENDS", lkNone, BtYesNo)
usr("PKG_REGISTER_SHELLS", lkNone, enum("YES NO"))
- usr("PKGSRC_COMPILER", lkShell, enum("ccache ccc clang distcc f2c gcc hp icc ido mipspro mipspro-ucode pcc sunpro xlc"))
+ usr("PKGSRC_COMPILER", lkShell, compilers)
usr("PKGSRC_KEEP_BIN_PKGS", lkNone, BtYesNo)
usr("PKGSRC_MESSAGE_RECIPIENTS", lkShell, BtMailAddress)
usr("PKGSRC_SHOW_BUILD_DEFS", lkNone, BtYesNo)
@@ -599,10 +627,10 @@ func (src *Pkgsrc) InitVartypes() {
sys("EMACS_PKGNAME_PREFIX", lkNone, BtIdentifier) // Or the empty string.
sys("EMACS_TYPE", lkNone, enum("emacs xemacs"))
acl("EMACS_USE_LEIM", lkNone, BtYes, "")
- acl("EMACS_VERSIONS_ACCEPTED", lkShell, enumFrom("editors/emacs/modules.mk", "_EMACS_VERSIONS_ALL", "emacs25 emacs21 emacs21nox emacs20 xemacs215 xemacs215nox xemacs214 xemacs214nox"),
"Makefile: set")
+ acl("EMACS_VERSIONS_ACCEPTED", lkShell, emacsVersions, "Makefile: set")
sys("EMACS_VERSION_MAJOR", lkNone, BtInteger)
sys("EMACS_VERSION_MINOR", lkNone, BtInteger)
- acl("EMACS_VERSION_REQD", lkShell, enum("emacs25 emacs25nox emacs21 emacs21nox emacs20 xemacs215 xemacs214"), "Makefile: set, append")
+ acl("EMACS_VERSION_REQD", lkShell, emacsVersions, "Makefile: set, append")
sys("EMULDIR", lkNone, BtPathname)
sys("EMULSUBDIR", lkNone, BtPathname)
sys("OPSYS_EMULDIR", lkNone, BtPathname)
@@ -796,11 +824,11 @@ func (src *Pkgsrc) InitVartypes() {
acl("MESSAGE_SUBST", lkShell, BtShellWord, "Makefile, Makefile.common, options.mk: append")
pkg("META_PACKAGE", lkNone, BtYes)
sys("MISSING_FEATURES", lkShell, BtIdentifier)
- acl("MYSQL_VERSIONS_ACCEPTED", lkShell, enumFrom("mk/mysql.buildlink3.mk", "MYSQL_VERSIONS_ACCEPTED", "57 56 55 51 MARIADB55"), "Makefile: set")
+ acl("MYSQL_VERSIONS_ACCEPTED", lkShell, mysqlVersions, "Makefile: set")
usr("MYSQL_VERSION_DEFAULT", lkNone, BtVersion)
sys("NM", lkNone, BtShellCommand)
sys("NONBINMODE", lkNone, BtFileMode)
- pkg("NOT_FOR_COMPILER", lkShell, enum("ccache ccc clang distcc f2c gcc hp icc ido mipspro mipspro-ucode pcc sunpro xlc"))
+ pkg("NOT_FOR_COMPILER", lkShell, compilers)
pkglist("NOT_FOR_BULK_PLATFORM", lkSpace, BtMachinePlatformPattern)
pkglist("NOT_FOR_PLATFORM", lkSpace, BtMachinePlatformPattern)
pkg("NOT_FOR_UNPRIVILEGED", lkNone, BtYesNo)
@@ -817,7 +845,7 @@ func (src *Pkgsrc) InitVartypes() {
acl("NO_PKGTOOLS_REQD_CHECK", lkNone, BtYes, "Makefile: set")
acl("NO_SRC_ON_CDROM", lkNone, BtRestricted, "Makefile, Makefile.common: set")
acl("NO_SRC_ON_FTP", lkNone, BtRestricted, "Makefile, Makefile.common: set")
- pkglist("ONLY_FOR_COMPILER", lkShell, enum("ccc clang gcc hp icc ido mipspro mipspro-ucode pcc sunpro xlc"))
+ pkglist("ONLY_FOR_COMPILER", lkShell, compilers)
pkglist("ONLY_FOR_PLATFORM", lkSpace, BtMachinePlatformPattern)
pkg("ONLY_FOR_UNPRIVILEGED", lkNone, BtYesNo)
sys("OPSYS", lkNone, BtIdentifier)
@@ -844,7 +872,7 @@ func (src *Pkgsrc) InitVartypes() {
pkg("PERL5_REQD", lkShell, BtVersion)
pkg("PERL5_USE_PACKLIST", lkNone, BtYesNo)
sys("PGSQL_PREFIX", lkNone, BtPathname)
- acl("PGSQL_VERSIONS_ACCEPTED", lkShell, enumFrom("mk/pgsql.buildlink3.mk", "PGSQL_VERSIONS_ACCEPTED", "10 96 95 94 93"), "")
+ acl("PGSQL_VERSIONS_ACCEPTED", lkShell, pgsqlVersions, "")
usr("PGSQL_VERSION_DEFAULT", lkNone, BtVersion)
sys("PG_LIB_EXT", lkNone, enum("dylib so"))
sys("PGSQL_TYPE", lkNone, enum("postgresql81-client postgresql80-client"))
@@ -924,7 +952,7 @@ func (src *Pkgsrc) InitVartypes() {
acl("PKG_USERS", lkShell, BtShellWord, "Makefile: set, append")
pkg("PKG_USERS_VARS", lkShell, BtVariableName)
acl("PKG_USE_KERBEROS", lkNone, BtYes, "Makefile, Makefile.common: set")
- // PLIST.* has special handling code
+ pkg("PLIST.*", lkNone, BtYes)
pkglist("PLIST_VARS", lkShell, BtIdentifier)
pkglist("PLIST_SRC", lkShell, BtRelativePkgPath)
pkglist("PLIST_SUBST", lkShell, BtShellWord)
Index: pkgsrc/pkgtools/pkglint/files/vardefs_test.go
diff -u pkgsrc/pkgtools/pkglint/files/vardefs_test.go:1.1 pkgsrc/pkgtools/pkglint/files/vardefs_test.go:1.2
--- pkgsrc/pkgtools/pkglint/files/vardefs_test.go:1.1 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/vardefs_test.go Thu Aug 16 20:41:42 2018
@@ -8,14 +8,39 @@ func (s *Suite) Test_InitVartypes__enumF
t.SetupFileMkLines("editors/emacs/modules.mk",
MkRcsID,
"",
- "_EMACS_VERSIONS_ALL=\temacs31",
- "_EMACS_VERSIONS_ALL=\tignored")
+ "_EMACS_VERSIONS_ALL= emacs31",
+ "_EMACS_VERSIONS_ALL+= emacs29")
+ t.SetupFileMkLines("mk/java-vm.mk",
+ MkRcsID,
+ "",
+ "_PKG_JVMS.8= openjdk8 oracle-jdk8",
+ "_PKG_JVMS.7= ${_PKG_JVMS.8} openjdk7 sun-jdk7",
+ "_PKG_JVMS.6= ${_PKG_JVMS.7} sun-jdk6 jdk16")
+ t.SetupFileMkLines("mk/compiler.mk",
+ MkRcsID,
+ "",
+ "_COMPILERS= gcc ido mipspro-ucode \\",
+ " sunpro",
+ "_PSEUDO_COMPILERS= ccache distcc f2c g95",
+ "",
+ ".for _version_ in gnu++14 c++14 gnu++11 c++11 gnu++0x c++0x gnu++03 c++03",
+ ". if !empty(USE_LANGUAGES:M${_version_})",
+ "USE_LANGUAGES+= c++",
+ ". endif",
+ ".endfor")
mklines := t.SetupFileMkLines("Makefile",
MkRcsID,
"")
t.SetupVartypes()
- vartype := mklines.mklines[1].VariableType("EMACS_VERSIONS_ACCEPTED")
- c.Check(vartype.String(), equals, "ShellList of enum: emacs31 ")
+ checkEnumValues := func(varname, values string) {
+ vartype := mklines.mklines[1].VariableType(varname).String()
+ c.Check(vartype, equals, values)
+ }
+
+ checkEnumValues("EMACS_VERSIONS_ACCEPTED", "ShellList of enum: emacs29 emacs31 ")
+ checkEnumValues("PKG_JVM", "enum: jdk16 openjdk7 openjdk8 oracle-jdk8 sun-jdk6 sun-jdk7 ")
+ checkEnumValues("USE_LANGUAGES", "ShellList of enum: ada c c++ c++03 c++0x c++11 c++14 c99 fortran fortran77 gnu++03 gnu++0x gnu++11 gnu++14 java obj-c++ objc ")
+ checkEnumValues("PKGSRC_COMPILER", "ShellList of enum: ccache distcc f2c g95 gcc ido mipspro-ucode sunpro ")
}
Index: pkgsrc/pkgtools/pkglint/files/vartypecheck.go
diff -u pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.37 pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.38
--- pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.37 Sun Aug 12 16:31:56 2018
+++ pkgsrc/pkgtools/pkglint/files/vartypecheck.go Thu Aug 16 20:41:42 2018
@@ -39,7 +39,7 @@ const (
opAssignEval // :=
opAssignAppend // +=
opAssignDefault // ?=
- opUseCompare // A variable is compared to a value, e.g. in a conditional.
+ opUseCompare // A variable is compared to a value, e.g. in a condition.
opUseMatch // A variable is matched using the :M or :N modifier.
)
@@ -1085,7 +1085,7 @@ func (cv *VartypeCheck) WrksrcSubdirecto
func (cv *VartypeCheck) Yes() {
switch cv.Op {
case opUseMatch:
- cv.Line.Warnf("%s should only be used in a \".if defined(...)\" conditional.", cv.Varname)
+ cv.Line.Warnf("%s should only be used in a \".if defined(...)\" condition.", cv.Varname)
Explain(
"This variable can have only two values: defined or undefined.",
"When it is defined, it means \"yes\", even when its value is",
Index: pkgsrc/pkgtools/pkglint/files/regex/regex.go
diff -u pkgsrc/pkgtools/pkglint/files/regex/regex.go:1.2 pkgsrc/pkgtools/pkglint/files/regex/regex.go:1.3
--- pkgsrc/pkgtools/pkglint/files/regex/regex.go:1.2 Sun Oct 8 22:31:13 2017
+++ pkgsrc/pkgtools/pkglint/files/regex/regex.go Thu Aug 16 20:41:42 2018
@@ -6,8 +6,8 @@ package regex
import (
"fmt"
+ "io"
"netbsd.org/pkglint/histogram"
- "os"
"regexp"
"time"
)
@@ -19,16 +19,13 @@ var (
)
var (
- res map[Pattern]*regexp.Regexp
- rematch *histogram.Histogram
- renomatch *histogram.Histogram
- retime *histogram.Histogram
+ res = make(map[Pattern]*regexp.Regexp)
+ rematch = histogram.New()
+ renomatch = histogram.New()
+ retime = histogram.New()
)
func Compile(re Pattern) *regexp.Regexp {
- if res == nil {
- res = make(map[Pattern]*regexp.Regexp)
- }
cre := res[re]
if cre == nil {
cre = regexp.MustCompile(string(re))
@@ -50,12 +47,6 @@ func Match(s string, re Pattern) []strin
delay := immediatelyBefore.UnixNano() - before.UnixNano()
timeTaken := after.UnixNano() - immediatelyBefore.UnixNano() - delay
- if retime == nil {
- retime = histogram.New()
- rematch = histogram.New()
- renomatch = histogram.New()
- }
-
retime.Add(string(re), int(timeTaken))
if m != nil {
rematch.Add(string(re), 1)
@@ -124,11 +115,11 @@ func ReplaceFirst(s string, re Pattern,
return nil, s
}
-func PrintStats() {
+func PrintStats(out io.Writer) {
if Profiling {
- rematch.PrintStats("rematch", os.Stdout, 10)
- renomatch.PrintStats("renomatch", os.Stdout, 10)
- retime.PrintStats("retime", os.Stdout, 10)
+ rematch.PrintStats("rematch", out, 10)
+ renomatch.PrintStats("renomatch", out, 10)
+ retime.PrintStats("retime", out, 10)
}
}
Home |
Main Index |
Thread Index |
Old Index