pkgsrc-Changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
CVS commit: pkgsrc/pkgtools/pkglint
Module Name: pkgsrc
Committed By: rillig
Date: Mon Dec 2 23:32:10 UTC 2019
Modified Files:
pkgsrc/pkgtools/pkglint: Makefile PLIST
pkgsrc/pkgtools/pkglint/files: alternatives.go autofix.go buildlink3.go
buildlink3_test.go category.go category_test.go check_test.go
distinfo.go distinfo_test.go files.go files_test.go licenses.go
line.go linelexer.go linelexer_test.go lines.go logging.go
mklexer.go mkline.go mkline_test.go mklinechecker.go
mklinechecker_test.go mklineparser_test.go mklines.go
mklines_test.go mkparser.go mkshparser_test.go options_test.go
package.go package_test.go patches.go path.go path_test.go
pkglint.0 pkglint.1 pkglint.go pkglint_test.go pkgsrc.go
pkgsrc_test.go plist.go redundantscope.go redundantscope_test.go
shell.go shell_test.go shtokenizer.go substcontext_test.go
tools_test.go toplevel.go util.go util_test.go varalignblock.go
vardefs.go vardefs_test.go vartype.go vartypecheck.go
vartypecheck_test.go
pkgsrc/pkgtools/pkglint/files/histogram: histogram.go
pkgsrc/pkgtools/pkglint/files/intqa: qa.go qa_test.go
pkgsrc/pkgtools/pkglint/files/textproc: lexer_bench_test.go
pkgsrc/pkgtools/pkglint/files/trace: tracing_test.go
Removed Files:
pkgsrc/pkgtools/pkglint/files: testnames_test.go
Log Message:
pkgtools/pkglint: update to 19.3.13
Changes since 19.3.12:
The command line option -Wspace has been removed. Warnings and notes
about whitespace are now generated by default and cannot be switched
off. This is to ensure a consistent visual appearance of the package
Makefiles.
Shell programs that are indented unnecessarily deep generate a note by
default now. Before, the option -Wall was necessary to get these notes.
The check for unintended comments in multi-line shell programs is now
enabled again. It had been disabled some time ago as byproduct of a bug
fix in the shell parser.
The check for unique buildlink3 package identifiers now also works if
pkglint is run from a package directory instead of the pkgsrc root
directory.
To generate a diff of this commit:
cvs rdiff -u -r1.612 -r1.613 pkgsrc/pkgtools/pkglint/Makefile
cvs rdiff -u -r1.18 -r1.19 pkgsrc/pkgtools/pkglint/PLIST
cvs rdiff -u -r1.17 -r1.18 pkgsrc/pkgtools/pkglint/files/alternatives.go
cvs rdiff -u -r1.32 -r1.33 pkgsrc/pkgtools/pkglint/files/autofix.go
cvs rdiff -u -r1.26 -r1.27 pkgsrc/pkgtools/pkglint/files/buildlink3.go \
pkgsrc/pkgtools/pkglint/files/category.go
cvs rdiff -u -r1.36 -r1.37 pkgsrc/pkgtools/pkglint/files/buildlink3_test.go
cvs rdiff -u -r1.27 -r1.28 pkgsrc/pkgtools/pkglint/files/category_test.go
cvs rdiff -u -r1.56 -r1.57 pkgsrc/pkgtools/pkglint/files/check_test.go
cvs rdiff -u -r1.38 -r1.39 pkgsrc/pkgtools/pkglint/files/distinfo.go \
pkgsrc/pkgtools/pkglint/files/mkparser.go \
pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go \
pkgsrc/pkgtools/pkglint/files/util_test.go
cvs rdiff -u -r1.34 -r1.35 pkgsrc/pkgtools/pkglint/files/distinfo_test.go
cvs rdiff -u -r1.28 -r1.29 pkgsrc/pkgtools/pkglint/files/files.go \
pkgsrc/pkgtools/pkglint/files/licenses.go
cvs rdiff -u -r1.29 -r1.30 pkgsrc/pkgtools/pkglint/files/files_test.go
cvs rdiff -u -r1.40 -r1.41 pkgsrc/pkgtools/pkglint/files/line.go
cvs rdiff -u -r1.7 -r1.8 pkgsrc/pkgtools/pkglint/files/linelexer.go
cvs rdiff -u -r1.4 -r1.5 pkgsrc/pkgtools/pkglint/files/linelexer_test.go \
pkgsrc/pkgtools/pkglint/files/mklineparser_test.go
cvs rdiff -u -r1.10 -r1.11 pkgsrc/pkgtools/pkglint/files/lines.go
cvs rdiff -u -r1.31 -r1.32 pkgsrc/pkgtools/pkglint/files/logging.go
cvs rdiff -u -r1.2 -r1.3 pkgsrc/pkgtools/pkglint/files/mklexer.go
cvs rdiff -u -r1.66 -r1.67 pkgsrc/pkgtools/pkglint/files/mkline.go
cvs rdiff -u -r1.73 -r1.74 pkgsrc/pkgtools/pkglint/files/mkline_test.go
cvs rdiff -u -r1.55 -r1.56 pkgsrc/pkgtools/pkglint/files/mklinechecker.go
cvs rdiff -u -r1.50 -r1.51 \
pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go \
pkgsrc/pkgtools/pkglint/files/shell.go
cvs rdiff -u -r1.61 -r1.62 pkgsrc/pkgtools/pkglint/files/mklines.go \
pkgsrc/pkgtools/pkglint/files/util.go \
pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go
cvs rdiff -u -r1.52 -r1.53 pkgsrc/pkgtools/pkglint/files/mklines_test.go \
pkgsrc/pkgtools/pkglint/files/pkglint_test.go
cvs rdiff -u -r1.21 -r1.22 pkgsrc/pkgtools/pkglint/files/mkshparser_test.go \
pkgsrc/pkgtools/pkglint/files/shtokenizer.go
cvs rdiff -u -r1.19 -r1.20 pkgsrc/pkgtools/pkglint/files/options_test.go
cvs rdiff -u -r1.71 -r1.72 pkgsrc/pkgtools/pkglint/files/package.go
cvs rdiff -u -r1.60 -r1.61 pkgsrc/pkgtools/pkglint/files/package_test.go
cvs rdiff -u -r1.33 -r1.34 pkgsrc/pkgtools/pkglint/files/patches.go
cvs rdiff -u -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/path.go \
pkgsrc/pkgtools/pkglint/files/path_test.go
cvs rdiff -u -r1.41 -r1.42 pkgsrc/pkgtools/pkglint/files/pkglint.0
cvs rdiff -u -r1.58 -r1.59 pkgsrc/pkgtools/pkglint/files/pkglint.1 \
pkgsrc/pkgtools/pkglint/files/shell_test.go
cvs rdiff -u -r1.67 -r1.68 pkgsrc/pkgtools/pkglint/files/pkglint.go
cvs rdiff -u -r1.44 -r1.45 pkgsrc/pkgtools/pkglint/files/pkgsrc.go
cvs rdiff -u -r1.45 -r1.46 pkgsrc/pkgtools/pkglint/files/plist.go
cvs rdiff -u -r1.8 -r1.9 pkgsrc/pkgtools/pkglint/files/redundantscope.go \
pkgsrc/pkgtools/pkglint/files/redundantscope_test.go
cvs rdiff -u -r1.30 -r1.31 pkgsrc/pkgtools/pkglint/files/substcontext_test.go
cvs rdiff -u -r1.10 -r0 pkgsrc/pkgtools/pkglint/files/testnames_test.go
cvs rdiff -u -r1.22 -r1.23 pkgsrc/pkgtools/pkglint/files/tools_test.go
cvs rdiff -u -r1.25 -r1.26 pkgsrc/pkgtools/pkglint/files/toplevel.go \
pkgsrc/pkgtools/pkglint/files/vardefs_test.go
cvs rdiff -u -r1.9 -r1.10 pkgsrc/pkgtools/pkglint/files/varalignblock.go
cvs rdiff -u -r1.79 -r1.80 pkgsrc/pkgtools/pkglint/files/vardefs.go
cvs rdiff -u -r1.39 -r1.40 pkgsrc/pkgtools/pkglint/files/vartype.go
cvs rdiff -u -r1.68 -r1.69 pkgsrc/pkgtools/pkglint/files/vartypecheck.go
cvs rdiff -u -r1.4 -r1.5 pkgsrc/pkgtools/pkglint/files/histogram/histogram.go
cvs rdiff -u -r1.1 -r1.2 pkgsrc/pkgtools/pkglint/files/intqa/qa.go \
pkgsrc/pkgtools/pkglint/files/intqa/qa_test.go
cvs rdiff -u -r1.1 -r1.2 \
pkgsrc/pkgtools/pkglint/files/textproc/lexer_bench_test.go
cvs rdiff -u -r1.6 -r1.7 pkgsrc/pkgtools/pkglint/files/trace/tracing_test.go
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: pkgsrc/pkgtools/pkglint/Makefile
diff -u pkgsrc/pkgtools/pkglint/Makefile:1.612 pkgsrc/pkgtools/pkglint/Makefile:1.613
--- pkgsrc/pkgtools/pkglint/Makefile:1.612 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/Makefile Mon Dec 2 23:32:09 2019
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.612 2019/11/30 20:35:11 rillig Exp $
+# $NetBSD: Makefile,v 1.613 2019/12/02 23:32:09 rillig Exp $
-PKGNAME= pkglint-19.3.12
+PKGNAME= pkglint-19.3.13
CATEGORIES= pkgtools
DISTNAME= tools
MASTER_SITES= ${MASTER_SITE_GITHUB:=golang/}
Index: pkgsrc/pkgtools/pkglint/PLIST
diff -u pkgsrc/pkgtools/pkglint/PLIST:1.18 pkgsrc/pkgtools/pkglint/PLIST:1.19
--- pkgsrc/pkgtools/pkglint/PLIST:1.18 Wed Nov 27 22:10:06 2019
+++ pkgsrc/pkgtools/pkglint/PLIST Mon Dec 2 23:32:09 2019
@@ -1,4 +1,4 @@
-@comment $NetBSD: PLIST,v 1.18 2019/11/27 22:10:06 rillig Exp $
+@comment $NetBSD: PLIST,v 1.19 2019/12/02 23:32:09 rillig Exp $
bin/pkglint
gopkg/pkg/${GO_PLATFORM}/netbsd.org/pkglint.a
gopkg/pkg/${GO_PLATFORM}/netbsd.org/pkglint/getopt.a
@@ -105,7 +105,6 @@ gopkg/src/netbsd.org/pkglint/shtypes.go
gopkg/src/netbsd.org/pkglint/shtypes_test.go
gopkg/src/netbsd.org/pkglint/substcontext.go
gopkg/src/netbsd.org/pkglint/substcontext_test.go
-gopkg/src/netbsd.org/pkglint/testnames_test.go
gopkg/src/netbsd.org/pkglint/textproc/lexer.go
gopkg/src/netbsd.org/pkglint/textproc/lexer_bench_test.go
gopkg/src/netbsd.org/pkglint/textproc/lexer_test.go
Index: pkgsrc/pkgtools/pkglint/files/alternatives.go
diff -u pkgsrc/pkgtools/pkglint/files/alternatives.go:1.17 pkgsrc/pkgtools/pkglint/files/alternatives.go:1.18
--- pkgsrc/pkgtools/pkglint/files/alternatives.go:1.17 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/alternatives.go Mon Dec 2 23:32:09 2019
@@ -5,7 +5,7 @@ import (
"strings"
)
-func CheckFileAlternatives(filename Path) {
+func CheckFileAlternatives(filename CurrPath) {
lines := Load(filename, NotEmpty|LogErrors)
if lines == nil {
return
Index: pkgsrc/pkgtools/pkglint/files/autofix.go
diff -u pkgsrc/pkgtools/pkglint/files/autofix.go:1.32 pkgsrc/pkgtools/pkglint/files/autofix.go:1.33
--- pkgsrc/pkgtools/pkglint/files/autofix.go:1.32 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/autofix.go Mon Dec 2 23:32:09 2019
@@ -443,12 +443,12 @@ func SaveAutofixChanges(lines *Lines) (a
if G.Testing {
abs := G.Abs(lines.Filename)
- absTmp := G.Abs(NewPathSlash(os.TempDir()))
+ absTmp := G.Abs(NewCurrPathSlash(os.TempDir()))
assertf(abs.HasPrefixPath(absTmp), "%q must be inside %q", abs, absTmp)
}
- changes := make(map[Path][]string)
- changed := make(map[Path]bool)
+ changes := make(map[CurrPath][]string)
+ changed := make(map[CurrPath]bool)
for _, line := range lines.Lines {
chlines := changes[line.Filename]
if fix := line.autofix; fix != nil {
Index: pkgsrc/pkgtools/pkglint/files/buildlink3.go
diff -u pkgsrc/pkgtools/pkglint/files/buildlink3.go:1.26 pkgsrc/pkgtools/pkglint/files/buildlink3.go:1.27
--- pkgsrc/pkgtools/pkglint/files/buildlink3.go:1.26 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/buildlink3.go Mon Dec 2 23:32:09 2019
@@ -99,7 +99,8 @@ func (ck *Buildlink3Checker) checkUnique
return
}
- base, name := trimCommon(pkgbase, mkline.Filename.Dir().Base())
+ dirname := G.Pkgsrc.ToRel(mkline.Filename.DirNoClean()).Base()
+ base, name := trimCommon(pkgbase, dirname)
if base == "" && matches(name, `^(\d*|-cvs|-fossil|-git|-hg|-svn|-devel|-snapshot)$`) {
return
}
Index: pkgsrc/pkgtools/pkglint/files/category.go
diff -u pkgsrc/pkgtools/pkglint/files/category.go:1.26 pkgsrc/pkgtools/pkglint/files/category.go:1.27
--- pkgsrc/pkgtools/pkglint/files/category.go:1.26 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/category.go Mon Dec 2 23:32:09 2019
@@ -6,7 +6,7 @@ import (
"strings"
)
-func CheckdirCategory(dir Path) {
+func CheckdirCategory(dir CurrPath) {
if trace.Tracing {
defer trace.Call(dir)()
}
@@ -64,7 +64,7 @@ func CheckdirCategory(dir Path) {
for !mlex.EOF() {
mkline := mlex.CurrentMkLine()
- if (mkline.IsVarassignMaybeCommented()) && mkline.Varname() == "SUBDIR" {
+ if mkline.IsVarassignMaybeCommented() && mkline.Varname() == "SUBDIR" {
mlex.Skip()
name := mkline.Value() // TODO: Maybe NewPath here already
@@ -155,7 +155,7 @@ func CheckdirCategory(dir Path) {
mklines.SaveAutofixChanges()
if G.Opts.Recursive {
- var recurseInto []Path
+ var recurseInto []CurrPath
for _, msub := range mSubdirs {
if !msub.line.IsCommentedVarassign() {
recurseInto = append(recurseInto, dir.JoinNoClean(msub.name))
Index: pkgsrc/pkgtools/pkglint/files/buildlink3_test.go
diff -u pkgsrc/pkgtools/pkglint/files/buildlink3_test.go:1.36 pkgsrc/pkgtools/pkglint/files/buildlink3_test.go:1.37
--- pkgsrc/pkgtools/pkglint/files/buildlink3_test.go:1.36 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/buildlink3_test.go Mon Dec 2 23:32:09 2019
@@ -599,7 +599,7 @@ func (s *Suite) Test_Buildlink3Checker_c
G.InterPackage.Enable()
- test := func(pkgbase string, pkgpath Path, diagnostics ...string) {
+ test := func(pkgbase string, pkgpath RelPath, diagnostics ...string) {
mkline := t.NewMkLine(t.File(pkgpath+"/buildlink3.mk"), 123, "")
(*Buildlink3Checker).checkUniquePkgbase(nil, pkgbase, mkline)
@@ -611,7 +611,7 @@ func (s *Suite) Test_Buildlink3Checker_c
test("php", "lang/php56",
nil...)
- // No warning since "php" is a valid buildlink3 basename for "php56".
+ // No warning since "php" is a valid buildlink3 basename for "php72".
test("php", "lang/php72",
nil...)
@@ -647,6 +647,30 @@ func (s *Suite) Test_Buildlink3Checker_c
nil...)
}
+func (s *Suite) Test_Buildlink3Checker_checkUniquePkgbase__chdir(c *check.C) {
+ t := s.Init(c)
+
+ G.InterPackage.Enable()
+ t.Chdir("lang/php56")
+
+ test := func(pkgbase string, path CurrPath, diagnostics ...string) {
+ mkline := t.NewMkLine(path.JoinNoClean("buildlink3.mk"), 123, "")
+
+ (*Buildlink3Checker).checkUniquePkgbase(nil, pkgbase, mkline)
+
+ t.CheckOutput(diagnostics)
+ }
+
+ test("php", "../../lang/php72",
+ nil...)
+
+ // Using the identifier "php" is ok in the current directory since
+ // its relative path from the pkgsrc root is "lang/php56", which
+ // starts with "php" as well.
+ test("php", ".",
+ nil...)
+}
+
func (s *Suite) Test_Buildlink3Checker_checkSecondParagraph__missing_mkbase(c *check.C) {
t := s.Init(c)
Index: pkgsrc/pkgtools/pkglint/files/category_test.go
diff -u pkgsrc/pkgtools/pkglint/files/category_test.go:1.27 pkgsrc/pkgtools/pkglint/files/category_test.go:1.28
--- pkgsrc/pkgtools/pkglint/files/category_test.go:1.27 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/category_test.go Mon Dec 2 23:32:09 2019
@@ -208,12 +208,12 @@ func (s *Suite) Test_CheckdirCategory__r
// It is only removed in Pkglint.Main, therefore it stays there even
// after the call to CheckdirCategory. This is a bit unrealistic,
// but close enough for this test.
- t.CheckDeepEquals(G.Todo.entries, []Path{"."})
+ t.CheckDeepEquals(G.Todo.entries, []CurrPath{"."})
CheckdirCategory(".")
t.CheckOutputEmpty()
- t.CheckDeepEquals(G.Todo.entries, []Path{"./package", "."})
+ t.CheckDeepEquals(G.Todo.entries, []CurrPath{"./package", "."})
}
// Ensures that a directory in the file system can be added at the very
Index: pkgsrc/pkgtools/pkglint/files/check_test.go
diff -u pkgsrc/pkgtools/pkglint/files/check_test.go:1.56 pkgsrc/pkgtools/pkglint/files/check_test.go:1.57
--- pkgsrc/pkgtools/pkglint/files/check_test.go:1.56 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/check_test.go Mon Dec 2 23:32:09 2019
@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"io/ioutil"
+ "netbsd.org/pkglint/intqa"
"netbsd.org/pkglint/regex"
"os"
"regexp"
@@ -74,7 +75,7 @@ func (s *Suite) SetUpTest(c *check.C) {
prevdir, err := os.Getwd()
assertNil(err, "Cannot get current working directory: %s", err)
- t.prevdir = prevdir
+ t.prevdir = NewCurrPathString(prevdir)
// No longer usable; see https://github.com/go-check/check/issues/22
t.c = nil
@@ -84,7 +85,7 @@ func (s *Suite) TearDownTest(c *check.C)
t := s.Tester
t.c = nil // No longer usable; see https://github.com/go-check/check/issues/22
- err := os.Chdir(t.prevdir)
+ err := os.Chdir(t.prevdir.String())
assertNil(err, "Cannot chdir back to previous dir: %s", err)
if t.seenSetupPkgsrc > 0 && !t.seenFinish && !t.seenMain {
@@ -98,6 +99,19 @@ func (s *Suite) TearDownTest(c *check.C)
G = unusablePkglint()
}
+// Ensures that all test names follow a common naming scheme:
+//
+// Test_${Type}_${Method}__${description_using_underscores}
+func (s *Suite) Test__qa(c *check.C) {
+ ck := intqa.NewQAChecker(c.Errorf)
+ ck.Configure("*", "*", "*", -intqa.EMissingTest)
+ ck.Configure("path.go", "*", "*", +intqa.EMissingTest)
+ ck.Configure("*yacc.go", "*", "*", intqa.ENone)
+ ck.Configure("*", "*", "", -intqa.EMissingTest)
+ ck.Configure("*.go", "Suite", "*", -intqa.EMethodsSameFile)
+ ck.Check()
+}
+
var _ = check.Suite(new(Suite))
func Test(t *testing.T) { check.TestingT(t) }
@@ -113,9 +127,9 @@ type Tester struct {
stdout bytes.Buffer
stderr bytes.Buffer
- tmpdir Path
- prevdir string // The current working directory before the test started
- relCwd Path // See Tester.Chdir
+ tmpdir CurrPath
+ prevdir CurrPath // The current working directory before the test started
+ cwd RelPath // relative to tmpdir; see Tester.Chdir
seenSetUpCommandLine bool
seenSetupPkgsrc int
@@ -193,33 +207,33 @@ func (t *Tester) SetUpTool(name, varname
// The file is then read in, without interpreting line continuations.
//
// See SetUpFileMkLines for loading a Makefile fragment.
-func (t *Tester) SetUpFileLines(relativeFileName Path, lines ...string) *Lines {
- filename := t.CreateFileLines(relativeFileName, lines...)
- return Load(filename, MustSucceed)
+func (t *Tester) SetUpFileLines(filename RelPath, lines ...string) *Lines {
+ abs := t.CreateFileLines(filename, lines...)
+ return Load(abs, MustSucceed)
}
// SetUpFileLines creates a temporary file and writes the given lines to it.
// The file is then read in, handling line continuations for Makefiles.
//
// See SetUpFileLines for loading an ordinary file.
-func (t *Tester) SetUpFileMkLines(relativeFileName Path, lines ...string) *MkLines {
- filename := t.CreateFileLines(relativeFileName, lines...)
- return LoadMk(filename, MustSucceed)
+func (t *Tester) SetUpFileMkLines(filename RelPath, lines ...string) *MkLines {
+ abs := t.CreateFileLines(filename, lines...)
+ return LoadMk(abs, MustSucceed)
}
// LoadMkInclude loads the given Makefile fragment and all the files it includes,
// merging all the lines into a single MkLines object.
//
// This is useful for testing code related to Package.readMakefile.
-func (t *Tester) LoadMkInclude(relativeFileName Path) *MkLines {
+func (t *Tester) LoadMkInclude(filename RelPath) *MkLines {
var lines []*Line
// TODO: Include files with multiple-inclusion guard only once.
// TODO: Include files without multiple-inclusion guard as often as needed.
// TODO: Set an upper limit, to prevent denial of service.
- var load func(filename Path)
- load = func(filename Path) {
+ var load func(filename CurrPath)
+ load = func(filename CurrPath) {
for _, mkline := range NewMkLines(Load(filename, MustSucceed)).mklines {
lines = append(lines, mkline.Line)
@@ -229,11 +243,11 @@ func (t *Tester) LoadMkInclude(relativeF
}
}
- load(t.File(relativeFileName))
+ load(t.File(filename))
// This assumes that the test files do not contain parse errors.
// Otherwise the diagnostics would appear twice.
- return NewMkLines(NewLines(t.File(relativeFileName), lines))
+ return NewMkLines(NewLines(t.File(filename), lines))
}
// SetUpPkgsrc sets up a minimal but complete pkgsrc installation in the
@@ -319,8 +333,8 @@ func (t *Tester) SetUpPkgsrc() {
// SetUpCategory makes the given category valid by creating a dummy Makefile.
// After that, it can be mentioned in the CATEGORIES variable of a package.
-func (t *Tester) SetUpCategory(name Path) {
- assert(name.Count() == 1)
+func (t *Tester) SetUpCategory(name RelPath) {
+ assert(G.Pkgsrc.ToRel(t.File(name)).Count() == 1)
makefile := name.JoinNoClean("Makefile")
if !t.File(makefile).IsFile() {
@@ -340,11 +354,13 @@ func (t *Tester) SetUpCategory(name Path
// After calling this method, individual files can be overwritten as necessary.
// At the end of the setup phase, t.FinishSetUp() must be called to load all
// the files.
-func (t *Tester) SetUpPackage(pkgpath Path, makefileLines ...string) Path {
- assertf(matches(pkgpath.String(), `^[^/]+/[^/]+$`), "pkgpath %q must have the form \"category/package\"", pkgpath)
+func (t *Tester) SetUpPackage(pkgpath RelPath, makefileLines ...string) CurrPath {
+ assertf(
+ matches(pkgpath.String(), `^[^/]+/[^/]+$`),
+ "pkgpath %q must have the form \"category/package\"", pkgpath)
distname := pkgpath.Base()
- category := pkgpath.Dir()
+ category := pkgpath.DirNoClean()
if category == "wip" {
// To avoid boilerplate CATEGORIES definitions for wip packages.
category = "local"
@@ -431,29 +447,32 @@ line:
// given lines to it.
//
// It returns the full path to the created file.
-func (t *Tester) CreateFileLines(relativeFileName Path, lines ...string) (filename Path) {
+func (t *Tester) CreateFileLines(filename RelPath, lines ...string) CurrPath {
var content strings.Builder
for _, line := range lines {
content.WriteString(line)
content.WriteString("\n")
}
- filename = t.File(relativeFileName)
- err := os.MkdirAll(filename.Dir().String(), 0777)
+ abs := t.File(filename)
+ err := os.MkdirAll(abs.DirNoClean().String(), 0777)
t.c.Assert(err, check.IsNil)
- err = filename.WriteString(content.String())
+ err = abs.WriteString(content.String())
t.c.Assert(err, check.IsNil)
- G.fileCache.Evict(filename)
+ G.fileCache.Evict(abs)
- return filename
+ return abs
}
// CreateFileDummyPatch creates a patch file with the given name in the
// temporary directory.
-func (t *Tester) CreateFileDummyPatch(relativeFileName Path) {
- t.CreateFileLines(relativeFileName,
+func (t *Tester) CreateFileDummyPatch(filename RelPath) {
+ // Patch files only make sense in category/package/patches directories.
+ assert(G.Pkgsrc.ToRel(t.File(filename)).Count() == 4)
+
+ t.CreateFileLines(filename,
CvsID,
"",
"Documentation",
@@ -465,9 +484,11 @@ func (t *Tester) CreateFileDummyPatch(re
"+new")
}
-func (t *Tester) CreateFileDummyBuildlink3(relativeFileName Path, customLines ...string) {
- assert(relativeFileName.Count() == 3)
- dir := relativeFileName.Dir()
+func (t *Tester) CreateFileDummyBuildlink3(filename RelPath, customLines ...string) {
+ // Buildlink3.mk files only make sense in category/package directories.
+ assert(G.Pkgsrc.ToRel(t.File(filename)).Count() == 3)
+
+ dir := filename.DirClean()
lower := dir.Base()
// see pkgtools/createbuildlink/files/createbuildlink, "package specific variables"
upper := strings.Replace(strings.ToUpper(lower), "-", "_", -1)
@@ -502,32 +523,33 @@ func (t *Tester) CreateFileDummyBuildlin
"",
sprintf("BUILDLINK_TREE+=\t-%s", lower))
- t.CreateFileLines(relativeFileName, lines...)
+ t.CreateFileLines(filename, lines...)
}
// 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 filename.
-func (t *Tester) File(relativeFileName Path) Path {
- if t.tmpdir == "" {
- t.tmpdir = NewPathSlash(t.c.MkDir())
+func (t *Tester) File(filename RelPath) CurrPath {
+ if t.tmpdir.IsEmpty() {
+ t.tmpdir = NewCurrPathSlash(t.c.MkDir())
}
- if t.relCwd != "" {
- return relativeFileName.Clean()
+ if t.cwd != "" {
+ return NewCurrPath(filename.Clean().AsPath())
}
- return t.tmpdir.JoinClean(relativeFileName)
+ return t.tmpdir.JoinClean(filename.AsPath())
}
// Copy copies a file inside the temporary directory.
-func (t *Tester) Copy(relativeSrc, relativeDst Path) {
- src := t.File(relativeSrc)
- dst := t.File(relativeDst)
+func (t *Tester) Copy(source, target RelPath) {
+ absSource := t.File(source)
+ absTarget := t.File(target)
- data, err := src.ReadString()
+ data, err := absSource.ReadString()
assertNil(err, "Copy.Read")
- err = os.MkdirAll(dst.Dir().String(), 0777)
+ // FIXME: consider DirNoClean
+ err = os.MkdirAll(absTarget.DirClean().String(), 0777)
assertNil(err, "Copy.MkdirAll")
- err = dst.WriteString(data)
+ err = absTarget.WriteString(data)
assertNil(err, "Copy.Write")
}
@@ -543,29 +565,30 @@ func (t *Tester) Copy(relativeSrc, relat
//
// As long as this method is not called in a test, the current working
// directory is indeterminate.
-func (t *Tester) Chdir(relativeDirName Path) {
- if t.relCwd != "" {
+func (t *Tester) Chdir(dirname RelPath) {
+ if t.cwd != "" {
// When multiple calls of Chdir are mixed with calls to CreateFileLines,
// the resulting Lines and MkLines variables will use relative filenames,
// and these will point to different areas in the file system. This is
// usually not indented and therefore prevented.
- t.c.Fatalf("Chdir must only be called once per test; already in %q.", t.relCwd)
+ t.c.Fatalf("Chdir must only be called once per test; already in %q.", t.cwd)
}
- absDirName := t.File(relativeDirName)
+ absDirName := t.File(dirname)
assertNil(os.MkdirAll(absDirName.String(), 0700), "MkDirAll")
assertNil(os.Chdir(absDirName.String()), "Chdir")
- t.relCwd = relativeDirName
+ t.cwd = dirname
G.cwd = absDirName
+ G.Pkgsrc.topdir = NewCurrPath(absDirName.Rel(G.Pkgsrc.topdir))
}
// Remove removes the file or directory from the temporary directory.
// The file or directory must exist.
-func (t *Tester) Remove(relativeFileName Path) {
- filename := t.File(relativeFileName)
- err := os.Remove(filename.String())
+func (t *Tester) Remove(filename RelPath) {
+ abs := t.File(filename)
+ err := os.Remove(abs.String())
t.c.Assert(err, check.IsNil)
- G.fileCache.Evict(filename)
+ G.fileCache.Evict(abs)
}
// SetUpHierarchy provides a function for creating hierarchies of MkLines
@@ -588,22 +611,42 @@ func (t *Tester) Remove(relativeFileName
// module := get("subdir/module.mk")
//
// The filenames passed to the include function are all relative to the
-// same location, but that location is irrelevant in practice. The generated
-// .include lines take the relative paths into account. For example, when
-// subdir/module.mk includes subdir/version.mk, the include line is just:
+// same location, which is typically the pkgsrc root or a package directory,
+// but the code doesn't care.
+//
+// The generated .include lines take the relative paths into account.
+// For example, when subdir/module.mk includes subdir/version.mk,
+// the include line is just:
// .include "version.mk"
func (t *Tester) SetUpHierarchy() (
- include func(filename Path, args ...interface{}) *MkLines,
- get func(Path) *MkLines) {
+ include func(filename RelPath, args ...interface{}) *MkLines,
+ get func(path RelPath) *MkLines) {
- files := map[Path]*MkLines{}
+ files := map[RelPath]*MkLines{}
+ basedir := NewPath(".")
- include = func(filename Path, args ...interface{}) *MkLines {
+ // includePath returns the path to be used in an .include.
+ //
+ // This is the same mechanism that is used in Pkgsrc.Relpath.
+ includePath := func(including, included Path) Path {
+ // FIXME: consider DirNoClean
+ fromDir := including.DirClean()
+ to := basedir.Rel(included)
+ // FIXME: consider DirNoClean
+ if fromDir == to.DirClean() {
+ return NewPath(to.Base())
+ } else {
+ return fromDir.Rel(basedir).JoinNoClean(to).CleanDot()
+ }
+ }
+
+ include = func(filename RelPath, args ...interface{}) *MkLines {
var lines []*Line
lineno := 1
+ relFilename := basedir.Rel(filename.AsPath())
addLine := func(text string) {
- lines = append(lines, t.NewLine(filename, lineno, text))
+ lines = append(lines, t.NewLine(NewCurrPath(relFilename), lineno, text))
lineno++
}
@@ -612,24 +655,21 @@ func (t *Tester) SetUpHierarchy() (
case string:
addLine(arg)
case *MkLines:
- fromDir := G.Pkgsrc.File(filename.Dir())
- to := G.Pkgsrc.File(arg.lines.Filename)
- rel := G.Pkgsrc.Relpath(fromDir, to)
- text := sprintf(".include %q", rel)
- addLine(text)
+ rel := includePath(relFilename, arg.lines.Filename.AsPath())
+ addLine(sprintf(".include %q", rel))
lines = append(lines, arg.lines.Lines...)
default:
panic("invalid type")
}
}
- mklines := NewMkLines(NewLines(filename, lines))
+ mklines := NewMkLines(NewLines(NewCurrPath(relFilename), lines))
assertf(files[filename] == nil, "MkLines with name %q already exists.", filename)
files[filename] = mklines
return mklines
}
- get = func(filename Path) *MkLines {
+ get = func(filename RelPath) *MkLines {
assertf(files[filename] != nil, "MkLines with name %q doesn't exist.", filename)
return files[filename]
}
@@ -707,7 +747,7 @@ func (t *Tester) Main(args ...string) in
argv := []string{"pkglint"}
for _, arg := range args {
- fileArg := t.File(NewPath(arg))
+ fileArg := t.File(NewRelPathString(arg))
if fileArg.Exists() {
argv = append(argv, fileArg.String())
} else {
@@ -851,14 +891,14 @@ func (t *Tester) NewRawLines(args ...int
// NewLine creates an in-memory line with the given text.
// This line does not correspond to any line in a file.
-func (t *Tester) NewLine(filename Path, lineno int, text string) *Line {
+func (t *Tester) NewLine(filename CurrPath, lineno int, text string) *Line {
textnl := text + "\n"
rawLine := RawLine{lineno, textnl, textnl}
return NewLine(filename, lineno, text, &rawLine)
}
// NewMkLine creates an in-memory line in the Makefile format with the given text.
-func (t *Tester) NewMkLine(filename Path, lineno int, text string) *MkLine {
+func (t *Tester) NewMkLine(filename CurrPath, lineno int, text string) *MkLine {
basename := filename.Base()
assertf(
hasSuffix(basename, ".mk") ||
@@ -878,14 +918,14 @@ func (t *Tester) NewShellLineChecker(tex
// NewLines returns a list of simple lines that belong together.
//
// To work with line continuations like in Makefiles, use SetUpFileMkLines.
-func (t *Tester) NewLines(filename Path, lines ...string) *Lines {
+func (t *Tester) NewLines(filename CurrPath, lines ...string) *Lines {
return t.NewLinesAt(filename, 1, lines...)
}
// NewLinesAt returns a list of simple lines that belong together.
//
// To work with line continuations like in Makefiles, use SetUpFileMkLines.
-func (t *Tester) NewLinesAt(filename Path, firstLine int, texts ...string) *Lines {
+func (t *Tester) NewLinesAt(filename CurrPath, firstLine int, texts ...string) *Lines {
lines := make([]*Line, len(texts))
for i, text := range texts {
lines[i] = t.NewLine(filename, i+firstLine, text)
@@ -899,7 +939,7 @@ func (t *Tester) NewLinesAt(filename Pat
//
// No actual file is created for the lines;
// see SetUpFileMkLines for loading Makefile fragments with line continuations.
-func (t *Tester) NewMkLines(filename Path, lines ...string) *MkLines {
+func (t *Tester) NewMkLines(filename CurrPath, lines ...string) *MkLines {
basename := filename.Base()
assertf(
hasSuffix(basename, ".mk") || basename == "Makefile" || hasPrefix(basename, "Makefile."),
@@ -980,7 +1020,7 @@ func (t *Tester) CheckOutputLinesMatchin
// See CheckOutputEmpty, CheckOutputLines.
func (t *Tester) CheckOutputLinesIgnoreSpace(expectedLines ...string) {
assertf(len(expectedLines) > 0, "To check empty lines, use CheckOutputEmpty instead.")
- assertf(t.tmpdir != "", "Tester must be initialized before checking the output.")
+ assertf(!t.tmpdir.IsEmpty(), "Tester must be initialized before checking the output.")
rawOutput := t.stdout.String() + t.stderr.String()
_ = t.Output() // Just to consume the output
@@ -989,7 +1029,7 @@ func (t *Tester) CheckOutputLinesIgnoreS
t.CheckDeepEquals(actual, expected)
}
-func (t *Tester) compareOutputIgnoreSpace(rawOutput string, expectedLines []string, tmpdir Path) ([]string, []string) {
+func (t *Tester) compareOutputIgnoreSpace(rawOutput string, expectedLines []string, tmpdir CurrPath) ([]string, []string) {
whitespace := regexp.MustCompile(`\s+`)
// Replace all occurrences of tmpdir in the raw output with a tilde,
@@ -1023,7 +1063,7 @@ func (s *Suite) Test_Tester_compareOutpu
t := s.Init(c)
lines := func(lines ...string) []string { return lines }
- test := func(rawOutput string, expectedLines []string, tmpdir Path, eq bool) {
+ test := func(rawOutput string, expectedLines []string, tmpdir CurrPath, eq bool) {
actual, expected := t.compareOutputIgnoreSpace(rawOutput, expectedLines, tmpdir)
t.CheckEquals(actual == nil && expected == nil, eq)
}
@@ -1143,8 +1183,8 @@ func (t *Tester) DisableTracing() {
// CheckFileLines loads the lines from the temporary file and checks that
// they equal the given lines.
-func (t *Tester) CheckFileLines(relativeFileName Path, lines ...string) {
- content, err := t.File(relativeFileName).ReadString()
+func (t *Tester) CheckFileLines(filename RelPath, lines ...string) {
+ content, err := t.File(filename).ReadString()
t.c.Assert(err, check.IsNil)
actualLines := strings.Split(content, "\n")
actualLines = actualLines[:len(actualLines)-1]
@@ -1155,8 +1195,8 @@ func (t *Tester) CheckFileLines(relative
// that they equal the given lines. The loaded file may use tabs or spaces
// for indentation, while the lines in the code use spaces exclusively,
// in order to make the depth of the indentation clearly visible in the test code.
-func (t *Tester) CheckFileLinesDetab(relativeFileName Path, lines ...string) {
- actualLines := Load(t.File(relativeFileName), MustSucceed)
+func (t *Tester) CheckFileLinesDetab(filename RelPath, lines ...string) {
+ actualLines := Load(t.File(filename), MustSucceed)
var detabbedLines []string
for _, line := range actualLines.Lines {
Index: pkgsrc/pkgtools/pkglint/files/distinfo.go
diff -u pkgsrc/pkgtools/pkglint/files/distinfo.go:1.38 pkgsrc/pkgtools/pkglint/files/distinfo.go:1.39
--- pkgsrc/pkgtools/pkglint/files/distinfo.go:1.38 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/distinfo.go Mon Dec 2 23:32:09 2019
@@ -17,7 +17,7 @@ func CheckLinesDistinfo(pkg *Package, li
}
filename := lines.Filename
- patchdir := NewPath("patches")
+ patchdir := NewPackagePath("patches")
if pkg != nil && pkg.File(pkg.Patchdir).IsDir() {
patchdir = pkg.Patchdir
}
@@ -40,7 +40,7 @@ func CheckLinesDistinfo(pkg *Package, li
type distinfoLinesChecker struct {
pkg *Package
lines *Lines
- patchdir Path // Relative to pkg
+ patchdir PackagePath
distinfoIsCommitted bool
filenames []Path // For keeping the order from top to bottom
@@ -89,7 +89,7 @@ func (ck *distinfoLinesChecker) parse()
continue
}
- if prevFilename != "" && filename != prevFilename {
+ if !prevFilename.IsEmpty() && filename != prevFilename {
finishGroup()
}
prevFilename = filename
@@ -97,7 +97,7 @@ func (ck *distinfoLinesChecker) parse()
hashes = append(hashes, distinfoHash{line, filename, alg, hash})
}
- if prevFilename != "" {
+ if !prevFilename.IsEmpty() {
finishGroup()
}
}
@@ -194,7 +194,7 @@ func (ck *distinfoLinesChecker) checkAlg
distdir := G.Pkgsrc.File("distfiles")
- distfile := cleanpath(distdir.JoinNoClean(info.filename()))
+ distfile := distdir.JoinNoClean(info.filename()).CleanPath()
if !distfile.IsFile() {
// It's a rare situation that the explanation is generated
@@ -380,7 +380,7 @@ func (ck *distinfoLinesChecker) checkUnc
}
}
-func (ck *distinfoLinesChecker) checkPatchSha1(line *Line, patchFileName Path, distinfoSha1Hex string) {
+func (ck *distinfoLinesChecker) checkPatchSha1(line *Line, patchFileName PackagePath, distinfoSha1Hex string) {
lines := Load(ck.pkg.File(patchFileName), 0)
if lines == nil {
line.Errorf("Patch %s does not exist.", patchFileName)
Index: pkgsrc/pkgtools/pkglint/files/mkparser.go
diff -u pkgsrc/pkgtools/pkglint/files/mkparser.go:1.38 pkgsrc/pkgtools/pkglint/files/mkparser.go:1.39
--- pkgsrc/pkgtools/pkglint/files/mkparser.go:1.38 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/mkparser.go Mon Dec 2 23:32:09 2019
@@ -48,7 +48,7 @@ func (p *MkParser) MkCond() *MkCond {
for {
mark := p.lexer.Mark()
p.lexer.SkipHspace()
- if !(p.lexer.SkipString("||")) {
+ if !p.lexer.SkipString("||") {
break
}
next := p.mkCondAnd()
Index: pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go
diff -u pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go:1.38 pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go:1.39
--- pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go:1.38 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/pkgsrc_test.go Mon Dec 2 23:32:09 2019
@@ -1132,6 +1132,7 @@ func (s *Suite) Test_Pkgsrc_checkTopleve
t.CreateFileLines("category/Makefile",
MkCvsID,
+ "",
"COMMENT=\tExample category",
"",
"SUBDIR+=\tpackage",
@@ -1176,15 +1177,19 @@ func (s *Suite) Test_Pkgsrc_ReadDir(c *c
func (s *Suite) Test_Pkgsrc_Relpath(c *check.C) {
t := s.Init(c)
- t.Chdir(".")
t.CheckEquals(G.Pkgsrc.topdir, t.tmpdir)
+ t.Chdir(".")
+ t.CheckEquals(G.Pkgsrc.topdir, NewCurrPath("."))
- test := func(from, to Path, result Path) {
+ test := func(from, to CurrPath, result Path) {
t.CheckEquals(G.Pkgsrc.Relpath(from, to), result)
}
// TODO: add tests going from each of (top, cat, pkg, pkgsub) to the others
+ test("category", "other/package", "../other/package")
+ test("category/package", "other", "../../other")
+
test("some/dir", "some/directory", "../../some/directory")
test("some/directory", "some/dir", "../../some/dir")
@@ -1211,7 +1216,7 @@ func (s *Suite) Test_Pkgsrc_Relpath(c *c
"x11/frameworkintegration/../../meta-pkgs/kde/kf5.mk",
"meta-pkgs/kde/kf5.mk")
- volume := NewPathSlash(filepath.VolumeName(t.tmpdir.String()))
+ volume := NewCurrPathSlash(filepath.VolumeName(t.tmpdir.String()))
G.Pkgsrc.topdir = volume.JoinNoClean("usr/pkgsrc")
// Taken from Test_MkLineChecker_CheckRelativePath__wip_mk
@@ -1241,7 +1246,7 @@ func (s *Suite) Test_Pkgsrc_Relpath(c *c
test("some/dir", ".", "../..")
test("some/dir/.", ".", "../..")
- chdir := func(path Path) {
+ chdir := func(path CurrPath) {
// See Tester.Chdir; a direct Chdir works here since this test
// neither loads lines nor processes them.
assertNil(os.Chdir(path.String()), "Chdir %s", path)
@@ -1297,7 +1302,7 @@ func (s *Suite) Test_Pkgsrc_File(c *chec
G.Pkgsrc.topdir = "$pkgsrcdir"
- test := func(rel, resolved Path) {
+ test := func(rel PkgsrcPath, resolved CurrPath) {
t.CheckEquals(G.Pkgsrc.File(rel), resolved)
}
@@ -1337,8 +1342,8 @@ func (s *Suite) Test_Change_Target(c *ch
moved := Change{loc, Moved, "category/path", "category/other", "author", "2019-01-01"}
downgraded := Change{loc, Downgraded, "category/path", "1.0", "author", "2019-01-01"}
- t.CheckEquals(renamed.Target(), NewPath("category/other"))
- t.CheckEquals(moved.Target(), NewPath("category/other"))
+ t.CheckEquals(renamed.Target(), NewPkgsrcPath("category/other"))
+ t.CheckEquals(moved.Target(), NewPkgsrcPath("category/other"))
t.ExpectAssert(func() { downgraded.Target() })
}
Index: pkgsrc/pkgtools/pkglint/files/util_test.go
diff -u pkgsrc/pkgtools/pkglint/files/util_test.go:1.38 pkgsrc/pkgtools/pkglint/files/util_test.go:1.39
--- pkgsrc/pkgtools/pkglint/files/util_test.go:1.38 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/util_test.go Mon Dec 2 23:32:09 2019
@@ -337,56 +337,6 @@ func (s *Suite) Test__regex_ReplaceFirst
t.CheckEquals(rest, "X+c+d")
}
-func (s *Suite) Test_cleanpath(c *check.C) {
- t := s.Init(c)
-
- test := func(from, to Path) {
- t.CheckEquals(cleanpath(from), to)
- }
-
- test("simple/path", "simple/path")
- test("/absolute/path", "/absolute/path")
-
- // Single dot components are removed, unless it's the only component of the path.
- test("./././.", ".")
- test("./././", ".")
- test("dir/multi/././/file", "dir/multi/file")
- test("dir/", "dir")
-
- test("dir/", "dir")
-
- // Components like aa/bb/../.. are removed, but not in the initial part of the path,
- // and only if they are not followed by another "..".
- test("dir/../dir/../dir/../dir/subdir/../../Makefile", "dir/../dir/../dir/../Makefile")
- test("111/222/../../333/444/../../555/666/../../777/888/9", "111/222/../../777/888/9")
- test("1/2/3/../../4/5/6/../../7/8/9/../../../../10", "1/2/3/../../4/7/8/9/../../../../10")
- test("cat/pkg.v1/../../cat/pkg.v2/Makefile", "cat/pkg.v1/../../cat/pkg.v2/Makefile")
- test("aa/../../../../../a/b/c/d", "aa/../../../../../a/b/c/d")
- test("aa/bb/../../../../a/b/c/d", "aa/bb/../../../../a/b/c/d")
- test("aa/bb/cc/../../../a/b/c/d", "aa/bb/cc/../../../a/b/c/d")
- test("aa/bb/cc/dd/../../a/b/c/d", "aa/bb/a/b/c/d")
- test("aa/bb/cc/dd/ee/../a/b/c/d", "aa/bb/cc/dd/ee/../a/b/c/d")
- test("../../../../../a/b/c/d", "../../../../../a/b/c/d")
- test("aa/../../../../a/b/c/d", "aa/../../../../a/b/c/d")
- test("aa/bb/../../../a/b/c/d", "aa/bb/../../../a/b/c/d")
- test("aa/bb/cc/../../a/b/c/d", "aa/bb/cc/../../a/b/c/d")
- test("aa/bb/cc/dd/../a/b/c/d", "aa/bb/cc/dd/../a/b/c/d")
- test("aa/../cc/../../a/b/c/d", "aa/../cc/../../a/b/c/d")
-
- // The initial 2 components of the path are typically category/package, when
- // pkglint is called from the pkgsrc top-level directory.
- // This path serves as the context and therefore is always kept.
- test("aa/bb/../../cc/dd/../../ee/ff", "aa/bb/../../ee/ff")
- test("aa/bb/../../cc/dd/../..", "aa/bb/../..")
- test("aa/bb/cc/dd/../..", "aa/bb")
- test("aa/bb/../../cc/dd/../../ee/ff/buildlink3.mk", "aa/bb/../../ee/ff/buildlink3.mk")
- test("./aa/bb/../../cc/dd/../../ee/ff/buildlink3.mk", "aa/bb/../../ee/ff/buildlink3.mk")
-
- test("../.", "..")
- test("../././././././.", "..")
- test(".././././././././", "..")
-}
-
const reMkIncludeBenchmark = `^\.([\t ]*)(s?include)[\t ]+\"([^\"]+)\"[\t ]*(?:#.*)?$`
const reMkIncludeBenchmarkPositive = `^\.([\t ]*)(s?include)[\t ]+\"(.+)\"[\t ]*(?:#.*)?$`
@@ -705,15 +655,15 @@ func (s *Suite) Test_FileCache(c *check.
c.Check(cache.Get("Makefile", MustSucceed|LogErrors), check.IsNil) // Wrong LoadOptions.
linesFromCache := cache.Get("Makefile", 0)
- t.CheckEquals(linesFromCache.Filename, NewPath("Makefile"))
+ t.CheckEquals(linesFromCache.Filename, NewCurrPath("Makefile"))
c.Check(linesFromCache.Lines, check.HasLen, 2)
- t.CheckEquals(linesFromCache.Lines[0].Filename, NewPath("Makefile"))
+ t.CheckEquals(linesFromCache.Lines[0].Filename, NewCurrPath("Makefile"))
// Cache keys are normalized using path.Clean.
linesFromCache2 := cache.Get("./Makefile", 0)
- t.CheckEquals(linesFromCache2.Filename, NewPath("./Makefile"))
+ t.CheckEquals(linesFromCache2.Filename, NewCurrPath("./Makefile"))
c.Check(linesFromCache2.Lines, check.HasLen, 2)
- t.CheckEquals(linesFromCache2.Lines[0].Filename, NewPath("./Makefile"))
+ t.CheckEquals(linesFromCache2.Lines[0].Filename, NewCurrPath("./Makefile"))
cache.Put("file1.mk", 0, lines)
cache.Put("file2.mk", 0, lines)
@@ -1096,6 +1046,23 @@ func (s *Suite) Test_LazyStringBuilder_W
t.CheckDeepEquals(sb.buf, []byte{'w', 'o', 'l', 'f'})
}
+func (s *Suite) Test_LazyStringBuilder_writeToBuf__assertion(c *check.C) {
+ t := s.Init(c)
+
+ sb := NewLazyStringBuilder("0123456789abcdef0123456789abcdef")
+ sb.WriteString("0123456789abcdef0123456789abcdeX")
+
+ t.CheckEquals(cap(sb.buf), 32)
+
+ sb.Reset("0123456789abcdef")
+ sb.WriteString("01234567")
+
+ // Intentionally violate the invariant of the LazyStringBuilder that
+ // as long as sb.usingBuf is false, sb.len is at most len(sb.expected).
+ sb.expected = ""
+ t.ExpectAssert(func() { sb.writeToBuf('x') })
+}
+
func (s *Suite) Test_LazyStringBuilder_Reset(c *check.C) {
t := s.Init(c)
Index: pkgsrc/pkgtools/pkglint/files/distinfo_test.go
diff -u pkgsrc/pkgtools/pkglint/files/distinfo_test.go:1.34 pkgsrc/pkgtools/pkglint/files/distinfo_test.go:1.35
--- pkgsrc/pkgtools/pkglint/files/distinfo_test.go:1.34 Sun Nov 17 01:26:25 2019
+++ pkgsrc/pkgtools/pkglint/files/distinfo_test.go Mon Dec 2 23:32:09 2019
@@ -116,7 +116,6 @@ func (s *Suite) Test_distinfoLinesChecke
t := s.Init(c)
t.SetUpPkgsrc()
- t.SetUpCommandLine("-Wall,no-space")
t.CreateFileLines("licenses/unknown-license")
t.CreateFileLines("lang/php/ext.mk",
MkCvsID,
@@ -142,7 +141,7 @@ func (s *Suite) Test_distinfoLinesChecke
t.CreateFileLines("archivers/php-bz2/Makefile",
MkCvsID,
"",
- "USE_PHP_EXT_PATCHES= yes",
+ "USE_PHP_EXT_PATCHES=\tyes",
"",
".include \"../../lang/php/ext.mk\"",
".include \"../../mk/bsd.pkg.mk\"")
Index: pkgsrc/pkgtools/pkglint/files/files.go
diff -u pkgsrc/pkgtools/pkglint/files/files.go:1.28 pkgsrc/pkgtools/pkglint/files/files.go:1.29
--- pkgsrc/pkgtools/pkglint/files/files.go:1.28 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/files.go Mon Dec 2 23:32:09 2019
@@ -14,7 +14,7 @@ const (
LogErrors //
)
-func LoadMk(filename Path, options LoadOptions) *MkLines {
+func LoadMk(filename CurrPath, options LoadOptions) *MkLines {
lines := Load(filename, options|Makefile)
if lines == nil {
return nil
@@ -22,7 +22,7 @@ func LoadMk(filename Path, options LoadO
return NewMkLines(lines)
}
-func Load(filename Path, options LoadOptions) *Lines {
+func Load(filename CurrPath, options LoadOptions) *Lines {
if fromCache := G.fileCache.Get(filename, options); fromCache != nil {
return fromCache
}
@@ -59,7 +59,7 @@ func Load(filename Path, options LoadOpt
return result
}
-func convertToLogicalLines(filename Path, rawText string, joinBackslashLines bool) *Lines {
+func convertToLogicalLines(filename CurrPath, rawText string, joinBackslashLines bool) *Lines {
var rawLines []*RawLine
for lineno, rawLine := range strings.SplitAfter(rawText, "\n") {
if rawLine != "" {
@@ -89,7 +89,7 @@ func convertToLogicalLines(filename Path
return NewLines(filename, loglines)
}
-func nextLogicalLine(filename Path, rawLines []*RawLine, index int) (*Line, int) {
+func nextLogicalLine(filename CurrPath, rawLines []*RawLine, index int) (*Line, int) {
{ // Handle the common case efficiently
rawLine := rawLines[index]
textnl := rawLine.textnl
Index: pkgsrc/pkgtools/pkglint/files/licenses.go
diff -u pkgsrc/pkgtools/pkglint/files/licenses.go:1.28 pkgsrc/pkgtools/pkglint/files/licenses.go:1.29
--- pkgsrc/pkgtools/pkglint/files/licenses.go:1.28 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/licenses.go Mon Dec 2 23:32:09 2019
@@ -24,13 +24,14 @@ func (lc *LicenseChecker) Check(value st
}
func (lc *LicenseChecker) checkName(license string) {
- licenseFile := NewPath("")
+ licenseFile := NewCurrPath("")
if G.Pkg != nil {
if mkline := G.Pkg.vars.FirstDefinition("LICENSE_FILE"); mkline != nil {
- licenseFile = G.Pkg.File(mkline.ResolveVarsInRelativePath(NewPath(mkline.Value())))
+ rel := mkline.ResolveVarsInRelativePath(NewRelPathString(mkline.Value()))
+ licenseFile = G.Pkg.File(NewPackagePath(rel.AsPath()))
}
}
- if licenseFile == "" {
+ if licenseFile.IsEmpty() {
licenseFile = G.Pkgsrc.File("licenses").JoinNoClean(NewPath(license))
G.InterPackage.UseLicense(license)
}
Index: pkgsrc/pkgtools/pkglint/files/files_test.go
diff -u pkgsrc/pkgtools/pkglint/files/files_test.go:1.29 pkgsrc/pkgtools/pkglint/files/files_test.go:1.30
--- pkgsrc/pkgtools/pkglint/files/files_test.go:1.29 Sun Nov 17 01:26:25 2019
+++ pkgsrc/pkgtools/pkglint/files/files_test.go Mon Dec 2 23:32:09 2019
@@ -77,6 +77,28 @@ func (s *Suite) Test_convertToLogicalLin
t.CheckEquals(lines.Lines[1].String(), "filename:3: second line")
}
+// This test demonstrates that pkglint deviates from bmake.
+// Bmake keeps all the trailing whitespace from the line and replaces the
+// backslash plus any indentation with a single space. This results in:
+// "\tprintf '%s\\n' 'none none space space tab\t tab'"
+// This is another of the edge cases probably no-one relies on.
+func (s *Suite) Test_convertToLogicalLines__continuation_spacing(c *check.C) {
+ t := s.Init(c)
+
+ rawText := "" +
+ "\tprintf '%s\\n' 'none\\\n" +
+ "none\\\n" +
+ "space \\\n" +
+ " space \\\n" +
+ "tab\t\\\n" +
+ "\ttab'\n"
+
+ lines := convertToLogicalLines("filename", rawText, true)
+
+ t.CheckEquals(lines.Lines[0].Text,
+ "\tprintf '%s\\n' 'none none space space tab tab'")
+}
+
func (s *Suite) Test_convertToLogicalLines__continuation_in_last_line(c *check.C) {
t := s.Init(c)
Index: pkgsrc/pkgtools/pkglint/files/line.go
diff -u pkgsrc/pkgtools/pkglint/files/line.go:1.40 pkgsrc/pkgtools/pkglint/files/line.go:1.41
--- pkgsrc/pkgtools/pkglint/files/line.go:1.40 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/line.go Mon Dec 2 23:32:09 2019
@@ -37,7 +37,7 @@ type RawLine struct {
func (rline *RawLine) String() string { return sprintf("%d:%s", rline.Lineno, rline.textnl) }
type Location struct {
- Filename Path
+ Filename CurrPath
firstLine int32 // zero means the whole file, -1 means EOF
lastLine int32 // usually the same as firstLine, may differ in Makefiles
}
@@ -46,7 +46,7 @@ func (loc *Location) String() string {
return loc.Filename.String() + ":" + loc.Linenos()
}
-func NewLocation(filename Path, firstLine, lastLine int) Location {
+func NewLocation(filename CurrPath, firstLine, lastLine int) Location {
return Location{filename, int32(firstLine), int32(lastLine)}
}
@@ -82,23 +82,23 @@ type Line struct {
// XXX: Filename and Basename could be replaced with a pointer to a Lines object.
}
-func NewLine(filename Path, lineno int, text string, rawLine *RawLine) *Line {
+func NewLine(filename CurrPath, lineno int, text string, rawLine *RawLine) *Line {
assert(rawLine != nil) // Use NewLineMulti for creating a Line with no RawLine attached to it.
return NewLineMulti(filename, lineno, lineno, text, []*RawLine{rawLine})
}
// NewLineMulti is for logical Makefile lines that end with backslash.
-func NewLineMulti(filename Path, firstLine, lastLine int, text string, rawLines []*RawLine) *Line {
+func NewLineMulti(filename CurrPath, firstLine, lastLine int, text string, rawLines []*RawLine) *Line {
return &Line{NewLocation(filename, firstLine, lastLine), filename.Base(), text, rawLines, nil, Once{}}
}
// NewLineEOF creates a dummy line for logging, with the "line number" EOF.
-func NewLineEOF(filename Path) *Line {
+func NewLineEOF(filename CurrPath) *Line {
return NewLineMulti(filename, -1, 0, "", nil)
}
// NewLineWhole creates a dummy line for logging messages that affect a file as a whole.
-func NewLineWhole(filename Path) *Line {
+func NewLineWhole(filename CurrPath) *Line {
return NewLineMulti(filename, 0, 0, "", nil)
}
@@ -118,8 +118,9 @@ func (line *Line) RefToLocation(other Lo
// PathToFile returns the relative path from this line to the given file path.
// This is typically used for arguments in diagnostics, which should always be
// relative to the line with which the diagnostic is associated.
-func (line *Line) PathToFile(filePath Path) Path {
- return G.Pkgsrc.Relpath(line.Filename.Dir(), filePath)
+func (line *Line) PathToFile(filePath CurrPath) Path {
+ // FIXME: consider DirNoClean
+ return G.Pkgsrc.Relpath(line.Filename.DirClean(), filePath)
}
func (line *Line) IsMultiline() bool {
Index: pkgsrc/pkgtools/pkglint/files/linelexer.go
diff -u pkgsrc/pkgtools/pkglint/files/linelexer.go:1.7 pkgsrc/pkgtools/pkglint/files/linelexer.go:1.8
--- pkgsrc/pkgtools/pkglint/files/linelexer.go:1.7 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/linelexer.go Mon Dec 2 23:32:09 2019
@@ -92,19 +92,18 @@ func (llex *LinesLexer) SkipEmptyOrNote(
return true
}
- if G.Opts.WarnSpace {
- if llex.index == 0 {
- fix := llex.CurrentLine().Autofix()
- fix.Notef("Empty line expected before this line.")
- fix.InsertBefore("")
- fix.Apply()
- } else {
- fix := llex.PreviousLine().Autofix()
- fix.Notef("Empty line expected after this line.")
- fix.InsertAfter("")
- fix.Apply()
- }
+ if llex.index == 0 {
+ fix := llex.CurrentLine().Autofix()
+ fix.Notef("Empty line expected before this line.")
+ fix.InsertBefore("")
+ fix.Apply()
+ } else {
+ fix := llex.PreviousLine().Autofix()
+ fix.Notef("Empty line expected after this line.")
+ fix.InsertAfter("")
+ fix.Apply()
}
+
return false
}
Index: pkgsrc/pkgtools/pkglint/files/linelexer_test.go
diff -u pkgsrc/pkgtools/pkglint/files/linelexer_test.go:1.4 pkgsrc/pkgtools/pkglint/files/linelexer_test.go:1.5
--- pkgsrc/pkgtools/pkglint/files/linelexer_test.go:1.4 Sun Nov 17 01:26:25 2019
+++ pkgsrc/pkgtools/pkglint/files/linelexer_test.go Mon Dec 2 23:32:09 2019
@@ -49,3 +49,18 @@ func (s *Suite) Test_LinesLexer_SkipEmpt
t.CheckOutputLines(
"NOTE: file.txt:2: Empty line expected after this line.")
}
+
+func (s *Suite) Test_MkLinesLexer_SkipIf(c *check.C) {
+ t := s.Init(c)
+
+ mklines := t.NewMkLines("filename.mk",
+ "# comment",
+ "VAR=\tnot a comment")
+ mlex := NewMkLinesLexer(mklines)
+
+ t.CheckEquals(mlex.SkipIf((*MkLine).IsComment), true)
+ t.CheckEquals(mlex.SkipIf((*MkLine).IsComment), false)
+ t.CheckEquals(mlex.SkipIf((*MkLine).IsVarassign), true)
+ t.CheckEquals(mlex.SkipIf((*MkLine).IsVarassign), false)
+ t.CheckEquals(mlex.EOF(), true)
+}
Index: pkgsrc/pkgtools/pkglint/files/mklineparser_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mklineparser_test.go:1.4 pkgsrc/pkgtools/pkglint/files/mklineparser_test.go:1.5
--- pkgsrc/pkgtools/pkglint/files/mklineparser_test.go:1.4 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/mklineparser_test.go Mon Dec 2 23:32:09 2019
@@ -163,7 +163,6 @@ func (s *Suite) Test_MkLineParser_parseV
func (s *Suite) Test_MkLineParser_parseVarassign__autofix_space_after_varname(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wspace")
filename := t.CreateFileLines("Makefile",
MkCvsID,
"VARNAME +=\t${VARNAME}",
@@ -178,9 +177,12 @@ func (s *Suite) Test_MkLineParser_parseV
"NOTE: ~/Makefile:2: Unnecessary space after variable name \"VARNAME\".",
// The assignment operators other than = and += cannot lead to ambiguities.
- "NOTE: ~/Makefile:5: Unnecessary space after variable name \"VARNAME+\".")
+ "NOTE: ~/Makefile:5: Unnecessary space after variable name \"VARNAME+\".",
- t.SetUpCommandLine("-Wspace", "--autofix")
+ "WARN: ~/Makefile:5: "+
+ "Please include \"../../mk/bsd.prefs.mk\" before using \"?=\".")
+
+ t.SetUpCommandLine("-Wall", "--autofix")
CheckFileMk(filename)
Index: pkgsrc/pkgtools/pkglint/files/lines.go
diff -u pkgsrc/pkgtools/pkglint/files/lines.go:1.10 pkgsrc/pkgtools/pkglint/files/lines.go:1.11
--- pkgsrc/pkgtools/pkglint/files/lines.go:1.10 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/lines.go Mon Dec 2 23:32:09 2019
@@ -5,12 +5,12 @@ import (
)
type Lines struct {
- Filename Path
+ Filename CurrPath
BaseName string // TODO: consider converting to Path
Lines []*Line
}
-func NewLines(filename Path, lines []*Line) *Lines {
+func NewLines(filename CurrPath, lines []*Line) *Lines {
return &Lines{filename, filename.Base(), lines}
}
Index: pkgsrc/pkgtools/pkglint/files/logging.go
diff -u pkgsrc/pkgtools/pkglint/files/logging.go:1.31 pkgsrc/pkgtools/pkglint/files/logging.go:1.32
--- pkgsrc/pkgtools/pkglint/files/logging.go:1.31 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/logging.go Mon Dec 2 23:32:09 2019
@@ -57,7 +57,6 @@ var (
// that an explanation is available.
func (l *Logger) Explain(explanation ...string) {
if l.suppressExpl {
- l.suppressExpl = false
return
}
@@ -123,7 +122,7 @@ func (l *Logger) Diag(line *Line, level
l.Logf(level, filename, linenos, format, msg)
}
-func (l *Logger) FirstTime(filename Path, linenos, msg string) bool {
+func (l *Logger) FirstTime(filename CurrPath, linenos, msg string) bool {
if l.verbose {
return true
}
@@ -227,7 +226,7 @@ func (l *Logger) showSource(line *Line)
// IsAutofix returns whether one of the --show-autofix or --autofix options is active.
func (l *Logger) IsAutofix() bool { return l.Opts.Autofix || l.Opts.ShowAutofix }
-func (l *Logger) Logf(level *LogLevel, filename Path, lineno, format, msg string) {
+func (l *Logger) Logf(level *LogLevel, filename CurrPath, lineno, format, msg string) {
if l.suppressDiag {
l.suppressDiag = false
return
@@ -246,8 +245,8 @@ func (l *Logger) Logf(level *LogLevel, f
}
}
- if filename != "" {
- filename = cleanpath(filename)
+ if !filename.IsEmpty() {
+ filename = filename.CleanPath()
}
if G.Opts.Profiling && format != AutofixFormat && level != Fatal {
l.histo.Add(format, 1)
@@ -258,8 +257,8 @@ func (l *Logger) Logf(level *LogLevel, f
out = l.err
}
- filenameSep := condStr(filename != "", ": ", "")
- effLineno := condStr(filename != "", lineno, "")
+ filenameSep := condStr(!filename.IsEmpty(), ": ", "")
+ effLineno := condStr(!filename.IsEmpty(), lineno, "")
linenoSep := condStr(effLineno != "", ":", "")
var diag string
if l.Opts.GccOutput {
@@ -287,7 +286,7 @@ func (l *Logger) Logf(level *LogLevel, f
// Location.Filename. It may be followed by the usual ":123" for line numbers.
//
// For diagnostics, use Logf instead.
-func (l *Logger) TechErrorf(location Path, format string, args ...interface{}) {
+func (l *Logger) TechErrorf(location CurrPath, format string, args ...interface{}) {
msg := sprintf(format, args...)
var diag string
if l.Opts.GccOutput {
Index: pkgsrc/pkgtools/pkglint/files/mklexer.go
diff -u pkgsrc/pkgtools/pkglint/files/mklexer.go:1.2 pkgsrc/pkgtools/pkglint/files/mklexer.go:1.3
--- pkgsrc/pkgtools/pkglint/files/mklexer.go:1.2 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/mklexer.go Mon Dec 2 23:32:09 2019
@@ -262,7 +262,7 @@ func (p *MkLexer) varUseModifier(varname
modifier := p.varUseText(closing)
// ${SOURCES:%.c=%.o} or ${:!uname -a!:[2]}
- if contains(modifier, "=") || (hasPrefix(modifier, "!") && hasSuffix(modifier, "!")) {
+ if contains(modifier, "=") || hasPrefix(modifier, "!") && hasSuffix(modifier, "!") {
return modifier
}
Index: pkgsrc/pkgtools/pkglint/files/mkline.go
diff -u pkgsrc/pkgtools/pkglint/files/mkline.go:1.66 pkgsrc/pkgtools/pkglint/files/mkline.go:1.67
--- pkgsrc/pkgtools/pkglint/files/mkline.go:1.66 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/mkline.go Mon Dec 2 23:32:09 2019
@@ -278,10 +278,11 @@ func (mkline *MkLine) MustExist() bool {
func (mkline *MkLine) IncludedFile() Path { return mkline.data.(*mkLineInclude).includedFile }
-// IncludedFileFull returns the path to the included file, relative to the
-// current working directory.
-func (mkline *MkLine) IncludedFileFull() Path {
- return cleanpath(mkline.Filename.Dir().JoinClean(mkline.IncludedFile())) // FIXME: JoinNoClean?
+// IncludedFileFull returns the path to the included file.
+func (mkline *MkLine) IncludedFileFull() CurrPath {
+ // FIXME: consider DirNoClean
+ // FIXME: consider JoinNoClean
+ return mkline.Filename.DirClean().JoinClean(mkline.IncludedFile()).CleanPath()
}
func (mkline *MkLine) Targets() string { return mkline.data.(mkLineDependency).targets }
@@ -553,16 +554,17 @@ func (*MkLine) WithoutMakeVariables(valu
return valueNovar.String()
}
-func (mkline *MkLine) ResolveVarsInRelativePath(relativePath Path) Path {
+func (mkline *MkLine) ResolveVarsInRelativePath(relativePath RelPath) RelPath {
if !containsVarRef(relativePath.String()) {
- return cleanpath(relativePath)
+ return relativePath.CleanPath()
}
- var basedir Path
+ var basedir CurrPath
if G.Pkg != nil {
basedir = G.Pkg.File(".")
} else {
- basedir = mkline.Filename.Dir()
+ // FIXME: consider DirNoClean
+ basedir = mkline.Filename.DirClean()
}
tmp := relativePath
@@ -596,7 +598,7 @@ func (mkline *MkLine) ResolveVarsInRelat
// TODO: Add test that suggests ${.PARSEDIR} in .include to be omitted.
tmp = tmp.Replace("${.PARSEDIR}", ".")
- replaceLatest := func(varuse string, category Path, pattern regex.Pattern, replacement string) {
+ replaceLatest := func(varuse string, category PkgsrcPath, pattern regex.Pattern, replacement string) {
if tmp.ContainsText(varuse) {
latest := G.Pkgsrc.Latest(category, pattern, replacement)
tmp = tmp.Replace(varuse, latest)
@@ -620,7 +622,7 @@ func (mkline *MkLine) ResolveVarsInRelat
tmp = tmp.Replace("${PKGDIR}", G.Pkg.Pkgdir.String())
}
- tmp = cleanpath(tmp)
+ tmp = tmp.CleanPath()
if trace.Tracing && relativePath != tmp {
trace.Stepf("resolveVarsInRelativePath: %q => %q", relativePath, tmp)
@@ -1053,7 +1055,7 @@ type indentationLevel struct {
// pkglint will happily accept .include "fname" in both the then and
// the else branch. This is ok since the primary job of this file list
// is to prevent wrong pkglint warnings about missing files.
- checkedFiles []Path
+ checkedFiles []RelPath
// whether the line is a multiple-inclusion guard
guard bool
@@ -1158,14 +1160,16 @@ func (ind *Indentation) Args() string {
return ind.top().args
}
-func (ind *Indentation) AddCheckedFile(filename Path) {
+func (ind *Indentation) AddCheckedFile(filename RelPath) {
top := ind.top()
top.checkedFiles = append(top.checkedFiles, filename)
}
// HasExists returns whether the given filename has been tested in an
// exists(filename) condition and thus may or may not exist.
-func (ind *Indentation) HasExists(filename Path) bool {
+//
+// FIXME: Replace RelPath with PkgsrcPath, to make the filenames reliable.
+func (ind *Indentation) HasExists(filename RelPath) bool {
for _, level := range ind.levels {
for _, levelFilename := range level.checkedFiles {
if filename == levelFilename {
@@ -1240,13 +1244,13 @@ func (ind *Indentation) TrackAfter(mklin
cond.Walk(&MkCondCallback{
Call: func(name string, arg string) {
if name == "exists" {
- ind.AddCheckedFile(NewPath(arg))
+ ind.AddCheckedFile(NewRelPathString(arg))
}
}})
}
}
-func (ind *Indentation) CheckFinish(filename Path) {
+func (ind *Indentation) CheckFinish(filename CurrPath) {
if ind.IsEmpty() {
return
}
@@ -1291,7 +1295,7 @@ func MatchMkInclude(text string) (m bool
// here. But since these usually don't contain double quotes, it has
// worked fine up to now.
filename = NewPath(lexer.NextBytesFunc(func(c byte) bool { return c != '"' }))
- if filename != "" && lexer.SkipByte('"') {
+ if !filename.IsEmpty() && lexer.SkipByte('"') {
lexer.NextHspace()
if lexer.EOF() {
m = true
Index: pkgsrc/pkgtools/pkglint/files/mkline_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.73 pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.74
--- pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.73 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/mkline_test.go Mon Dec 2 23:32:09 2019
@@ -505,7 +505,7 @@ func (s *Suite) Test_MkLine_ResolveVarsI
MkCvsID)
mkline := mklines.mklines[0]
- test := func(before Path, after Path) {
+ test := func(before RelPath, after RelPath) {
t.CheckEquals(mkline.ResolveVarsInRelativePath(before), after)
}
@@ -962,16 +962,15 @@ func (s *Suite) Test_MkLine_VariableNeed
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",
MkCvsID,
"",
- "SUBST_CLASSES+= class",
- "SUBST_STAGE.class= pre-configure",
- "SUBST_FILES.class= files",
- "SUBST_SED.class=-e s:@LINKER_RPATH_FLAG@:${LINKER_RPATH_FLAG}:g")
+ "SUBST_CLASSES+=\t\tclass",
+ "SUBST_STAGE.class=\tpre-configure",
+ "SUBST_FILES.class=\tfiles",
+ "SUBST_SED.class=\t-e s:@LINKER_RPATH_FLAG@:${LINKER_RPATH_FLAG}:g")
mklines.Check()
@@ -984,14 +983,13 @@ func (s *Suite) Test_MkLine_VariableNeed
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("bash", "BASH", AtRunTime)
mklines := t.SetUpFileMkLines("Makefile",
MkCvsID,
"",
- "CONFIG_SHELL= ${BASH}")
+ "CONFIG_SHELL=\t${BASH}")
mklines.Check()
@@ -1048,17 +1046,17 @@ func (s *Suite) Test_MkLine_VariableNeed
func (s *Suite) Test_MkLine_VariableNeedsQuoting__uncovered_cases(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space", "--explain")
+ t.SetUpCommandLine("-Wall", "--explain")
t.SetUpVartypes()
mklines := t.SetUpFileMkLines("Makefile",
MkCvsID,
"",
- "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}")
+ "GO_SRCPATH=\t\t${HOMEPAGE:S,https://,,}",
+ "LINKER_RPATH_FLAG:=\t${LINKER_RPATH_FLAG:S/-rpath/& /}",
+ "HOMEPAGE=\t\thttp://godoc.org/${GO_SRCPATH}",
+ "PATH:=\t\t\t${PREFIX}/cross/bin:${PATH}",
+ "NO_SRC_ON_FTP=\t\t${RESTRICTED}")
mklines.Check()
Index: pkgsrc/pkgtools/pkglint/files/mklinechecker.go
diff -u pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.55 pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.56
--- pkgsrc/pkgtools/pkglint/files/mklinechecker.go:1.55 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/mklinechecker.go Mon Dec 2 23:32:09 2019
@@ -1085,10 +1085,10 @@ func (ck MkLineChecker) checkVarassignRi
categories := mkline.ValueFields(mkline.Value())
actual := categories[0]
- expected := mkline.Filename.Dir().Dir().Base()
- if expected == "." {
- expected = G.Pkgsrc.ToRel(mkline.Filename).Dir().Dir().Base()
- }
+ // FIXME: consider DirNoClean
+ // FIXME: consider DirNoClean
+ expected := G.Pkgsrc.ToRel(mkline.Filename).DirClean().DirClean().Base()
+
if expected == "wip" || actual == expected {
return
}
@@ -1258,7 +1258,7 @@ func (ck MkLineChecker) checkShellComman
mkline := ck.MkLine
shellCommand := mkline.ShellCommand()
- if G.Opts.WarnSpace && hasPrefix(mkline.Text, "\t\t") {
+ if hasPrefix(mkline.Text, "\t\t") {
lexer := textproc.NewLexer(mkline.raw[0].textnl)
tabs := lexer.NextBytesFunc(func(b byte) bool { return b == '\t' })
@@ -1305,7 +1305,7 @@ func (ck MkLineChecker) checkInclude() {
if trace.Tracing {
trace.Stepf("includingFile=%s includedFile=%s", mkline.Filename, includedFile)
}
- ck.CheckRelativePath(includedFile, mustExist)
+ ck.CheckRelativePath(NewRelPath(includedFile), mustExist)
switch {
case includedFile.HasBase("Makefile"):
@@ -1342,7 +1342,9 @@ func (ck MkLineChecker) checkInclude() {
case includedFile != "builtin.mk" && includedFile.HasSuffixPath("builtin.mk"):
if mkline.Basename != "hacks.mk" && !mkline.HasRationale() {
fix := mkline.Autofix()
- fix.Errorf("%s must not be included directly. Include \"%s/buildlink3.mk\" instead.", includedFile, includedFile.Dir())
+ // FIXME: Use %q instead of %s.
+ // FIXME: consider DirNoClean
+ fix.Errorf("%s must not be included directly. Include \"%s/buildlink3.mk\" instead.", includedFile, includedFile.DirClean())
fix.Replace("builtin.mk", "buildlink3.mk")
fix.Apply()
}
@@ -1350,9 +1352,6 @@ func (ck MkLineChecker) checkInclude() {
}
func (ck MkLineChecker) checkDirectiveIndentation(expectedDepth int) {
- if !G.Opts.WarnSpace {
- return
- }
mkline := ck.MkLine
indent := mkline.Indent()
if expected := strings.Repeat(" ", expectedDepth); indent != expected {
@@ -1365,7 +1364,7 @@ func (ck MkLineChecker) checkDirectiveIn
// CheckRelativePath checks a relative path that leads to the directory of another package
// or to a subdirectory thereof or a file within there.
-func (ck MkLineChecker) CheckRelativePath(relativePath Path, mustExist bool) {
+func (ck MkLineChecker) CheckRelativePath(relativePath RelPath, mustExist bool) {
if trace.Tracing {
defer trace.Call(relativePath, mustExist)()
}
@@ -1380,12 +1379,13 @@ func (ck MkLineChecker) CheckRelativePat
return
}
- if resolvedPath.IsAbs() {
+ if resolvedPath.AsPath().IsAbs() {
mkline.Errorf("The path %q must be relative.", resolvedPath)
return
}
- abs := mkline.Filename.Dir().JoinNoClean(resolvedPath)
+ // FIXME: consider DirNoClean
+ abs := mkline.Filename.DirClean().JoinNoClean(resolvedPath.AsPath())
if !abs.Exists() {
if mustExist && !ck.MkLines.indentation.HasExists(resolvedPath) {
mkline.Errorf("Relative path %q does not exist.", resolvedPath)
@@ -1428,13 +1428,13 @@ func (ck MkLineChecker) CheckRelativePat
//
// When used in .include directives, the relative package directories must be written
// with the leading ../.. anyway, so the benefit might not be too big at all.
-func (ck MkLineChecker) CheckRelativePkgdir(pkgdir Path) {
+func (ck MkLineChecker) CheckRelativePkgdir(pkgdir RelPath) {
if trace.Tracing {
defer trace.Call(pkgdir)()
}
mkline := ck.MkLine
- ck.CheckRelativePath(pkgdir+"/Makefile", true)
+ ck.CheckRelativePath(pkgdir.JoinNoClean("Makefile"), true)
pkgdir = mkline.ResolveVarsInRelativePath(pkgdir)
if !matches(pkgdir.String(), `^\.\./\.\./([^./][^/]*/[^./][^/]*)$`) && !containsVarRef(pkgdir.String()) {
Index: pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.50 pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.51
--- pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go:1.50 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/mklinechecker_test.go Mon Dec 2 23:32:09 2019
@@ -780,14 +780,13 @@ func (s *Suite) Test_MkLineChecker_Check
t.SetUpPkgsrc()
t.CreateFileLines("mk/defaults/mk.conf",
"VARBASE?= /usr/pkg/var")
- t.SetUpCommandLine("-Wall,no-space")
t.FinishSetUp()
mklines := t.SetUpFileMkLines("options.mk",
MkCvsID,
- "COMMENT= ${VARBASE} ${X11_TYPE}",
- "PKG_FAIL_REASON+= ${VARBASE} ${X11_TYPE}",
- "BUILD_DEFS+= X11_TYPE")
+ "COMMENT=\t\t${VARBASE} ${X11_TYPE}",
+ "PKG_FAIL_REASON+=\t${VARBASE} ${X11_TYPE}",
+ "BUILD_DEFS+=\t\tX11_TYPE")
mklines.Check()
@@ -1462,18 +1461,17 @@ func (s *Suite) Test_MkLineChecker_check
func (s *Suite) Test_MkLineChecker_checkVarUseQuoting__mstar(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
t.SetUpVartypes()
mklines := t.SetUpFileMkLines("options.mk",
MkCvsID,
- "CONFIGURE_ARGS+= CFLAGS=${CFLAGS:Q}",
- "CONFIGURE_ARGS+= CFLAGS=${CFLAGS:M*:Q}",
- "CONFIGURE_ARGS+= ADA_FLAGS=${ADA_FLAGS:Q}",
- "CONFIGURE_ARGS+= ADA_FLAGS=${ADA_FLAGS:M*:Q}",
- "CONFIGURE_ENV+= CFLAGS=${CFLAGS:Q}",
- "CONFIGURE_ENV+= CFLAGS=${CFLAGS:M*:Q}",
- "CONFIGURE_ENV+= ADA_FLAGS=${ADA_FLAGS:Q}",
- "CONFIGURE_ENV+= ADA_FLAGS=${ADA_FLAGS:M*:Q}")
+ "CONFIGURE_ARGS+=\tCFLAGS=${CFLAGS:Q}",
+ "CONFIGURE_ARGS+=\tCFLAGS=${CFLAGS:M*:Q}",
+ "CONFIGURE_ARGS+=\tADA_FLAGS=${ADA_FLAGS:Q}",
+ "CONFIGURE_ARGS+=\tADA_FLAGS=${ADA_FLAGS:M*:Q}",
+ "CONFIGURE_ENV+=\t\tCFLAGS=${CFLAGS:Q}",
+ "CONFIGURE_ENV+=\t\tCFLAGS=${CFLAGS:M*:Q}",
+ "CONFIGURE_ENV+=\t\tADA_FLAGS=${ADA_FLAGS:Q}",
+ "CONFIGURE_ENV+=\t\tADA_FLAGS=${ADA_FLAGS:M*:Q}")
mklines.Check()
@@ -1486,7 +1484,6 @@ func (s *Suite) Test_MkLineChecker_check
func (s *Suite) Test_MkLineChecker_checkVarUseQuoting__mstar_not_needed(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
pkg := t.SetUpPackage("category/package",
"MAKE_FLAGS+=\tCFLAGS=${CFLAGS:M*:Q}",
"MAKE_FLAGS+=\tLFLAGS=${LDFLAGS:M*:Q}")
@@ -1668,11 +1665,10 @@ func (s *Suite) Test_MkLineChecker_check
t.SetUpPkgsrc()
- t.SetUpCommandLine("-Wall,no-space")
mklines := t.SetUpFileMkLines("module.mk",
MkCvsID,
- "CFLAGS+= -Wl,--rpath,${PREFIX}/lib",
- "PKG_FAIL_REASON+= \"Group ${GAMEGRP} doesn't exist.\"")
+ "CFLAGS+=\t\t-Wl,--rpath,${PREFIX}/lib",
+ "PKG_FAIL_REASON+=\t\"Group ${GAMEGRP} doesn't exist.\"")
t.FinishSetUp()
mklines.Check()
@@ -1985,17 +1981,17 @@ func (s *Suite) Test_MkLineChecker_check
t.SetUpPkgsrc()
t.SetUpMasterSite("MASTER_SITE_GITHUB", "https://download.github.com/")
- t.SetUpCommandLine("-Wall,no-space")
+
mklines := t.SetUpFileMkLines("module.mk",
MkCvsID,
- "EGDIR= ${PREFIX}/etc/rc.d",
- "RPMIGNOREPATH+= ${PREFIX}/etc/rc.d",
- "_TOOLS_VARNAME.sed= SED",
- "DIST_SUBDIR= ${PKGNAME}",
- "WRKSRC= ${PKGNAME}",
- "SITES_distfile.tar.gz= ${MASTER_SITE_GITHUB:=user/}",
- "MASTER_SITES= https://cdn.example.org/${PKGNAME}/",
- "MASTER_SITES= https://cdn.example.org/distname-${PKGVERSION}/")
+ "EGDIR=\t\t\t${PREFIX}/etc/rc.d",
+ "RPMIGNOREPATH+=\t\t${PREFIX}/etc/rc.d",
+ "_TOOLS_VARNAME.sed=\tSED",
+ "DIST_SUBDIR=\t\t${PKGNAME}",
+ "WRKSRC=\t\t\t${PKGNAME}",
+ "SITES_distfile.tar.gz=\t${MASTER_SITE_GITHUB:=user/}",
+ "MASTER_SITES=\t\thttps://cdn.example.org/${PKGNAME}/",
+ "MASTER_SITES=\t\thttps://cdn.example.org/distname-${PKGVERSION}/")
t.FinishSetUp()
mklines.Check()
@@ -2282,7 +2278,7 @@ func (s *Suite) Test_MkLineChecker_check
func (s *Suite) Test_MkLineChecker_checkDirectiveIndentation__autofix(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("--autofix", "-Wspace")
+ t.SetUpCommandLine("--autofix")
lines := t.SetUpFileLines("filename.mk",
MkCvsID,
".if defined(A)",
@@ -2435,7 +2431,7 @@ func (s *Suite) Test_MkLineChecker_Check
t.CreateFileLines("other/package/Makefile")
- test := func(relativePkgdir Path, diagnostics ...string) {
+ test := func(relativePkgdir RelPath, diagnostics ...string) {
// Must be in the filesystem because of directory references.
mklines := t.SetUpFileMkLines("category/package/Makefile",
"# dummy")
Index: pkgsrc/pkgtools/pkglint/files/shell.go
diff -u pkgsrc/pkgtools/pkglint/files/shell.go:1.50 pkgsrc/pkgtools/pkglint/files/shell.go:1.51
--- pkgsrc/pkgtools/pkglint/files/shell.go:1.50 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/shell.go Mon Dec 2 23:32:09 2019
@@ -57,8 +57,6 @@ func (scc *SimpleCommandChecker) checkCo
break
case matches(shellword, `\$\{(PKGSRCDIR|PREFIX)(:Q)?\}`):
break
- case scc.handleComment():
- break
default:
if G.Opts.WarnExtra && !scc.MkLines.indentation.DependsOn("OPSYS") {
scc.mkline.Warnf("Unknown shell command %q.", shellword)
@@ -145,43 +143,6 @@ func (scc *SimpleCommandChecker) handleS
return false
}
-func (scc *SimpleCommandChecker) handleComment() bool {
- if trace.Tracing {
- defer trace.Call0()()
- }
-
- shellword := scc.strcmd.Name
- if trace.Tracing {
- defer trace.Call1(shellword)()
- }
-
- if !hasPrefix(shellword, "#") {
- return false
- }
-
- if !scc.mkline.IsMultiline() {
- return false
- }
-
- scc.mkline.Warnf("A shell comment does not stop at the end of line.")
- scc.Explain(
- "When a shell command is split into multiple lines that are",
- "continued with a backslash, they will nevertheless be converted to",
- "a single line before the shell sees them.",
- "",
- "This means that even if it looks as if the comment only spanned",
- "one line in the Makefile, in fact it spans until the end of the whole",
- "shell command.",
- "",
- "To insert a comment into shell code, you can write it like this:",
- "",
- "\t"+"${SHCOMMENT} \"The following command might fail; this is ok.\"",
- "",
- "Note that any special characters in the comment are still",
- "interpreted by the shell.")
- return true
-}
-
func (scc *SimpleCommandChecker) checkRegexReplace() {
if trace.Tracing {
defer trace.Call0()()
@@ -575,6 +536,8 @@ func NewShellLineChecker(mklines *MkLine
return &ShellLineChecker{mklines, mkline, true}
}
+// CheckShellCommands checks for a list of shell commands, of which each one
+// is terminated with a semicolon. These are used in GENERATE_PLIST.
func (ck *ShellLineChecker) CheckShellCommands(shellcmds string, time ToolTime) {
setE := true
ck.CheckShellCommand(shellcmds, &setE, time)
@@ -630,6 +593,7 @@ func (ck *ShellLineChecker) CheckShellCo
}
ck.CheckShellCommand(lexer.Rest(), &setE, RunTime)
+ ck.checkMultiLineComment()
}
func (ck *ShellLineChecker) checkHiddenAndSuppress(hiddenAndSuppress, rest string) {
@@ -1029,6 +993,56 @@ func (ck *ShellLineChecker) checkInstall
}
}
+func (ck *ShellLineChecker) checkMultiLineComment() {
+ mkline := ck.mkline
+ if !mkline.IsMultiline() || !contains(mkline.Text, "#") {
+ return
+ }
+
+ for _, line := range mkline.raw[:len(mkline.raw)-1] {
+ text := strings.TrimSuffix(line.textnl, "\\\n")
+
+ tokens, rest := splitIntoShellTokens(nil, text)
+ if rest != "" {
+ return
+ }
+
+ for _, token := range tokens {
+ if hasPrefix(token, "#") {
+ ck.warnMultiLineComment(line)
+ return
+ }
+ }
+ }
+}
+
+func (ck *ShellLineChecker) warnMultiLineComment(raw *RawLine) {
+ text := strings.TrimSuffix(raw.textnl, "\n")
+ line := NewLine(ck.mkline.Filename, raw.Lineno, text, raw)
+
+ line.Warnf("The shell comment does not stop at the end of this line.")
+ line.Explain(
+ "When a shell command is spread out on multiple lines that are",
+ "continued with a backslash, they will nevertheless be converted to",
+ "a single line before the shell sees them.",
+ "",
+ "This means that even if it looks as if the comment only spanned",
+ "one line in the Makefile, in fact it spans until the end of the whole",
+ "shell command.",
+ "",
+ "To insert a comment into shell code, you can write it like this:",
+ "",
+ "\t${SHCOMMENT} \"The following command might fail; this is ok.\"",
+ "",
+ "Note that any special characters in the comment are still",
+ "interpreted by the shell.",
+ "",
+ "If that is not possible, you can apply the :D modifier to the",
+ "variable with the empty name, which is guaranteed to be undefined:",
+ "",
+ "\t${:D this is commented out}")
+}
+
func (ck *ShellLineChecker) Errorf(format string, args ...interface{}) {
ck.mkline.Errorf(format, args...)
}
Index: pkgsrc/pkgtools/pkglint/files/mklines.go
diff -u pkgsrc/pkgtools/pkglint/files/mklines.go:1.61 pkgsrc/pkgtools/pkglint/files/mklines.go:1.62
--- pkgsrc/pkgtools/pkglint/files/mklines.go:1.61 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/mklines.go Mon Dec 2 23:32:09 2019
@@ -440,7 +440,7 @@ func (mklines *MkLines) checkVarassignPl
// CheckUsedBy checks that this file (a Makefile.common) has the given
// relativeName in one of the "# used by" comments at the beginning of the file.
-func (mklines *MkLines) CheckUsedBy(relativeName Path) {
+func (mklines *MkLines) CheckUsedBy(relativeName PkgsrcPath) {
lines := mklines.lines
if lines.Len() < 3 {
return
Index: pkgsrc/pkgtools/pkglint/files/util.go
diff -u pkgsrc/pkgtools/pkglint/files/util.go:1.61 pkgsrc/pkgtools/pkglint/files/util.go:1.62
--- pkgsrc/pkgtools/pkglint/files/util.go:1.61 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/util.go Mon Dec 2 23:32:09 2019
@@ -121,6 +121,7 @@ func rtrimHspace(str string) string {
return str[:end]
}
+// trimCommon returns the middle portion of the given strings that differs.
func trimCommon(a, b string) (string, string) {
// trim common prefix
for len(a) > 0 && len(b) > 0 && a[0] == b[0] {
@@ -238,7 +239,7 @@ func assertf(cond bool, format string, a
}
}
-func isEmptyDir(filename Path) bool {
+func isEmptyDir(filename CurrPath) bool {
if filename.HasSuffixPath("CVS") {
return true
}
@@ -261,7 +262,7 @@ func isEmptyDir(filename Path) bool {
return true
}
-func getSubdirs(filename Path) []Path {
+func getSubdirs(filename CurrPath) []Path {
dirents, err := filename.ReadDir()
if err != nil {
NewLineWhole(filename).Fatalf("Cannot be read: %s", err)
@@ -285,22 +286,8 @@ func isIgnoredFilename(filename string)
return hasPrefix(filename, ".#")
}
-func dirglob(dirname Path) []Path {
- infos, err := dirname.ReadDir()
- if err != nil {
- return nil
- }
- var filenames []Path
- for _, info := range infos {
- if !(isIgnoredFilename(info.Name())) {
- filenames = append(filenames, cleanpath(dirname.JoinNoClean(NewPath(info.Name()))))
- }
- }
- return filenames
-}
-
// Checks whether a file is already committed to the CVS repository.
-func isCommitted(filename Path) bool {
+func isCommitted(filename CurrPath) bool {
entries := G.loadCvsEntries(filename)
_, found := entries[filename.Base()]
return found
@@ -311,7 +298,7 @@ func isCommitted(filename Path) bool {
//
// There is no corresponding test for Git (as used by pkgsrc-wip) since that
// is more difficult to implement than simply reading a CVS/Entries file.
-func isLocallyModified(filename Path) bool {
+func isLocallyModified(filename CurrPath) bool {
entries := G.loadCvsEntries(filename)
entry, found := entries[filename.Base()]
if !found {
@@ -457,44 +444,6 @@ func mkopSubst(s string, left bool, from
})
}
-// Differs from path.Clean in that only "../../" is replaced, not "../".
-// Also, the initial directory is always kept.
-// This is to provide the package path as context in deeply nested .include chains.
-func cleanpath(filename Path) Path {
- parts := make([]string, 0, 5)
- lex := textproc.NewLexer(filename.String())
- for lex.SkipString("./") {
- }
-
- for !lex.EOF() {
- part := lex.NextBytesFunc(func(b byte) bool { return b != '/' })
- parts = append(parts, part)
- if lex.SkipByte('/') {
- for lex.SkipByte('/') || lex.SkipString("./") {
- }
- }
- }
-
- for len(parts) > 1 && parts[len(parts)-1] == "." {
- parts = parts[:len(parts)-1]
- }
-
- for i := 2; i+3 < len(parts); /* nothing */ {
- if parts[i] != ".." && parts[i+1] != ".." && parts[i+2] == ".." && parts[i+3] == ".." {
- if i+4 == len(parts) || parts[i+4] != ".." {
- parts = append(parts[:i], parts[i+4:]...)
- continue
- }
- }
- i++
- }
-
- if len(parts) == 0 {
- return "."
- }
- return NewPath(strings.Join(parts, "/"))
-}
-
func containsVarRef(s string) bool {
return contains(s, "${") || contains(s, "$(")
}
@@ -926,7 +875,7 @@ func NewFileCache(size int) *FileCache {
0}
}
-func (c *FileCache) Put(filename Path, options LoadOptions, lines *Lines) {
+func (c *FileCache) Put(filename CurrPath, options LoadOptions, lines *Lines) {
key := c.key(filename)
entry := c.mapping[key]
@@ -980,7 +929,7 @@ func (c *FileCache) removeOldEntries() {
}
}
-func (c *FileCache) Get(filename Path, options LoadOptions) *Lines {
+func (c *FileCache) Get(filename CurrPath, options LoadOptions) *Lines {
key := c.key(filename)
entry, found := c.mapping[key]
if found && entry.options == options {
@@ -997,7 +946,7 @@ func (c *FileCache) Get(filename Path, o
return nil
}
-func (c *FileCache) Evict(filename Path) {
+func (c *FileCache) Evict(filename CurrPath) {
key := c.key(filename)
entry, found := c.mapping[key]
if !found {
@@ -1015,7 +964,7 @@ func (c *FileCache) Evict(filename Path)
}
}
-func (c *FileCache) key(filename Path) string { return filename.Clean().String() }
+func (c *FileCache) key(filename CurrPath) string { return filename.Clean().String() }
func bmakeHelp(topic string) string { return bmake("help topic=" + topic) }
@@ -1265,27 +1214,27 @@ func pathMatches(pattern, s string) bool
return err == nil && matched
}
-type PathQueue struct {
- entries []Path
+type CurrPathQueue struct {
+ entries []CurrPath
}
-func (q *PathQueue) PushFront(entries ...Path) {
- q.entries = append(append([]Path(nil), entries...), q.entries...)
+func (q *CurrPathQueue) PushFront(entries ...CurrPath) {
+ q.entries = append(append([]CurrPath(nil), entries...), q.entries...)
}
-func (q *PathQueue) Push(entries ...Path) {
+func (q *CurrPathQueue) Push(entries ...CurrPath) {
q.entries = append(q.entries, entries...)
}
-func (q *PathQueue) IsEmpty() bool {
+func (q *CurrPathQueue) IsEmpty() bool {
return len(q.entries) == 0
}
-func (q *PathQueue) Front() Path {
+func (q *CurrPathQueue) Front() CurrPath {
return q.entries[0]
}
-func (q *PathQueue) Pop() Path {
+func (q *CurrPathQueue) Pop() CurrPath {
front := q.entries[0]
q.entries = q.entries[1:]
return front
@@ -1294,7 +1243,7 @@ func (q *PathQueue) Pop() Path {
// LazyStringBuilder builds a string that is most probably equal to an
// already existing string. In that case, it avoids any memory allocations.
type LazyStringBuilder struct {
- Expected string
+ expected string
len int
usingBuf bool
buf []byte
@@ -1308,7 +1257,7 @@ func (b *LazyStringBuilder) Write(p []by
}
func NewLazyStringBuilder(expected string) LazyStringBuilder {
- return LazyStringBuilder{Expected: expected}
+ return LazyStringBuilder{expected: expected}
}
func (b *LazyStringBuilder) Len() int {
@@ -1316,7 +1265,7 @@ func (b *LazyStringBuilder) Len() int {
}
func (b *LazyStringBuilder) WriteString(s string) {
- if !b.usingBuf && b.len+len(s) <= len(b.Expected) && hasPrefix(b.Expected[b.len:], s) {
+ if !b.usingBuf && b.len+len(s) <= len(b.expected) && hasPrefix(b.expected[b.len:], s) {
b.len += len(s)
return
}
@@ -1326,7 +1275,7 @@ func (b *LazyStringBuilder) WriteString(
}
func (b *LazyStringBuilder) WriteByte(c byte) {
- if !b.usingBuf && b.len < len(b.Expected) && b.Expected[b.len] == c {
+ if !b.usingBuf && b.len < len(b.expected) && b.expected[b.len] == c {
b.len++
return
}
@@ -1337,9 +1286,9 @@ func (b *LazyStringBuilder) writeToBuf(c
if !b.usingBuf {
if cap(b.buf) >= b.len {
b.buf = b.buf[:b.len]
- assert(copy(b.buf, b.Expected) == b.len)
+ assert(copy(b.buf, b.expected) == b.len)
} else {
- b.buf = []byte(b.Expected)[:b.len]
+ b.buf = []byte(b.expected)[:b.len]
}
b.usingBuf = true
}
@@ -1349,7 +1298,7 @@ func (b *LazyStringBuilder) writeToBuf(c
}
func (b *LazyStringBuilder) Reset(expected string) {
- b.Expected = expected
+ b.expected = expected
b.usingBuf = false
b.len = 0
}
@@ -1358,5 +1307,5 @@ func (b *LazyStringBuilder) String() str
if b.usingBuf {
return string(b.buf[:b.len])
}
- return b.Expected[:b.len]
+ return b.expected[:b.len]
}
Index: pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go
diff -u pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.61 pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.62
--- pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.61 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go Mon Dec 2 23:32:09 2019
@@ -341,6 +341,7 @@ func (s *Suite) Test_VartypeCheck_Depend
vt := NewVartypeCheckTester(t, BtDependencyWithPath)
t.CreateFileLines("category/package/Makefile")
+ t.CreateFileLines("category/package/files/dummy")
t.CreateFileLines("databases/py-sqlite3/Makefile")
t.CreateFileLines("devel/gettext/Makefile")
t.CreateFileLines("devel/gmake/Makefile")
@@ -404,6 +405,14 @@ func (s *Suite) Test_VartypeCheck_Depend
"Invalid dependency pattern \"${PYPKGPREFIX}-sqlite3\".",
"WARN: ~/category/package/filename.mk:22: "+
"Invalid dependency pattern \"${PYPKGPREFIX}-sqlite3\".")
+
+ vt.Values(
+ "gettext-[0-9]*:files/../../../databases/py-sqlite3")
+
+ vt.Output(
+ "WARN: ~/category/package/filename.mk:31: " +
+ "\"files/../../../databases/py-sqlite3\" is " +
+ "not a valid relative package directory.")
}
func (s *Suite) Test_VartypeCheck_DistSuffix(c *check.C) {
@@ -1544,6 +1553,16 @@ func (s *Suite) Test_VartypeCheck_Tool(c
"${t}\\:build")
vt.OutputEmpty()
+
+ vt.Op(opAssignAppend)
+ vt.Values(
+ "tool1:bootstrap",
+ "tool1:build",
+ "tool1:pkgsrc",
+ "tool1:run",
+ "tool1:test")
+
+ vt.OutputEmpty()
}
func (s *Suite) Test_VartypeCheck_URL(c *check.C) {
@@ -1771,6 +1790,24 @@ func (s *Suite) Test_VartypeCheck_YesNo(
vt.Output(
"WARN: filename.mk:3: PKG_DEVELOPER should be set to YES, yes, NO, or no.",
"WARN: filename.mk:4: PKG_DEVELOPER should be set to YES, yes, NO, or no.")
+
+ vt.Op(opUseMatch)
+ vt.Values(
+ "yes",
+ "[Yy]es",
+ "[Yy][Ee][Ss]",
+ "[yY][eE][sS]",
+ "[Nn]o",
+ "[Nn][Oo]",
+ "[nN][oO]")
+
+ vt.Output(
+ "WARN: filename.mk:11: PKG_DEVELOPER should be matched against "+
+ "\"[yY][eE][sS]\" or \"[nN][oO]\", not \"yes\".",
+ "WARN: filename.mk:12: PKG_DEVELOPER should be matched against "+
+ "\"[yY][eE][sS]\" or \"[nN][oO]\", not \"[Yy]es\".",
+ "WARN: filename.mk:15: PKG_DEVELOPER should be matched against "+
+ "\"[yY][eE][sS]\" or \"[nN][oO]\", not \"[Nn]o\".")
}
func (s *Suite) Test_VartypeCheck_YesNoIndirectly(c *check.C) {
@@ -1793,7 +1830,7 @@ func (s *Suite) Test_VartypeCheck_YesNoI
type VartypeCheckTester struct {
tester *Tester
basicType *BasicType
- filename Path
+ filename CurrPath
lineno int
varname string
op MkOperator
@@ -1821,7 +1858,7 @@ func (vt *VartypeCheckTester) Varname(va
vt.nextSection()
}
-func (vt *VartypeCheckTester) File(filename Path) {
+func (vt *VartypeCheckTester) File(filename CurrPath) {
vt.filename = filename
vt.lineno = 1
}
Index: pkgsrc/pkgtools/pkglint/files/mklines_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.52 pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.53
--- pkgsrc/pkgtools/pkglint/files/mklines_test.go:1.52 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/mklines_test.go Mon Dec 2 23:32:09 2019
@@ -557,25 +557,24 @@ func (s *Suite) Test_MkLines_collectDocu
func (s *Suite) Test_MkLines_collectVariables(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
t.SetUpPkgsrc()
t.CreateFileLines("mk/tools/defaults.mk",
"USE_TOOLS+= autoconf autoconf213")
mklines := t.NewMkLines("determine-defined-variables.mk",
MkCvsID,
"",
- "USE_TOOLS+= autoconf213 autoconf",
+ "USE_TOOLS+=\t\tautoconf213 autoconf",
"",
- "OPSYSVARS+= OSV",
- "OSV.NetBSD= NetBSD-specific value",
+ "OPSYSVARS+=\t\tOSV",
+ "OSV.NetBSD=\t\tNetBSD-specific value",
"",
- "SUBST_CLASSES+= subst",
- "SUBST_STAGE.subst= pre-configure",
- "SUBST_FILES.subst= file",
- "SUBST_VARS.subst= SUV",
- "SUV= value for substitution",
+ "SUBST_CLASSES+=\t\tsubst",
+ "SUBST_STAGE.subst=\tpre-configure",
+ "SUBST_FILES.subst=\tfile",
+ "SUBST_VARS.subst=\tSUV",
+ "SUV=\t\t\tvalue for substitution",
"",
- "#BUILD_DEFS+= VARBASE",
+ "#BUILD_DEFS+=\t\tVARBASE",
"",
"pre-configure:",
"\t${RUN} autoreconf; autoheader-2.13",
@@ -594,15 +593,14 @@ func (s *Suite) Test_MkLines_collectVari
func (s *Suite) Test_MkLines_collectVariables__BUILTIN_FIND_FILES_VAR(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
t.SetUpPackage("category/package")
t.CreateFileLines("mk/buildlink3/bsd.builtin.mk",
MkCvsID)
mklines := t.SetUpFileMkLines("category/package/builtin.mk",
MkCvsID,
"",
- "BUILTIN_FIND_FILES_VAR:= H_XFT2",
- "BUILTIN_FIND_FILES.H_XFT2= ${X11BASE}/include/X11/Xft/Xft.h",
+ "BUILTIN_FIND_FILES_VAR:=\tH_XFT2",
+ "BUILTIN_FIND_FILES.H_XFT2=\t${X11BASE}/include/X11/Xft/Xft.h",
"",
".include \"../../mk/buildlink3/bsd.builtin.mk\"",
"",
@@ -637,7 +635,6 @@ func (s *Suite) Test_MkLines_collectVari
func (s *Suite) Test_MkLines_ForEach__conditional_variables(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
t.SetUpVartypes()
mklines := t.NewMkLines("conditional.mk",
MkCvsID,
@@ -673,7 +670,6 @@ func (s *Suite) Test_MkLines_ForEach__co
func (s *Suite) Test_MkLines_collectElse(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wno-space")
t.SetUpVartypes()
mklines := t.NewMkLines("module.mk",
@@ -763,7 +759,6 @@ func (s *Suite) Test_MkLines_checkAll__u
func (s *Suite) Test_MkLines_checkAll__PLIST_VARS(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wno-space")
t.SetUpVartypes()
t.SetUpOption("both", "")
t.SetUpOption("only-added", "")
@@ -773,20 +768,20 @@ func (s *Suite) Test_MkLines_checkAll__P
mklines := t.SetUpFileMkLines("category/package/options.mk",
MkCvsID,
"",
- "PKG_OPTIONS_VAR= PKG_OPTIONS.pkg",
- "PKG_SUPPORTED_OPTIONS= both only-added only-defined",
- "PKG_SUGGESTED_OPTIONS= # none",
+ "PKG_OPTIONS_VAR=\tPKG_OPTIONS.pkg",
+ "PKG_SUPPORTED_OPTIONS=\tboth only-added only-defined",
+ "PKG_SUGGESTED_OPTIONS=\t# none",
"",
".include \"../../mk/bsd.options.mk\"",
"",
- "PLIST_VARS+= both only-added",
+ "PLIST_VARS+=\t\tboth only-added",
"",
".if !empty(PKG_OPTIONS:Mboth)",
- "PLIST.both= yes",
+ "PLIST.both=\t\tyes",
".endif",
"",
".if !empty(PKG_OPTIONS:Monly-defined)",
- "PLIST.only-defined= yes",
+ "PLIST.only-defined=\tyes",
".endif")
mklines.Check()
@@ -799,7 +794,6 @@ func (s *Suite) Test_MkLines_checkAll__P
func (s *Suite) Test_MkLines_checkAll__PLIST_VARS_indirect(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wno-space")
t.SetUpVartypes()
t.SetUpOption("option1", "")
t.SetUpOption("option2", "")
@@ -807,18 +801,18 @@ func (s *Suite) Test_MkLines_checkAll__P
mklines := t.SetUpFileMkLines("module.mk",
MkCvsID,
"",
- "MY_PLIST_VARS= option1 option2",
- "PLIST_VARS+= ${MY_PLIST_VARS}",
+ "MY_PLIST_VARS=\toption1 option2",
+ "PLIST_VARS+=\t${MY_PLIST_VARS}",
".for option in option3",
- "PLIST_VARS+= ${option}",
+ "PLIST_VARS+=\t${option}",
".endfor",
"",
".if 0",
- "PLIST.option1= yes",
+ "PLIST.option1=\tyes",
".endif",
"",
".if 1",
- "PLIST.option2= yes",
+ "PLIST.option2=\tyes",
".endif")
mklines.Check()
@@ -835,7 +829,6 @@ func (s *Suite) Test_MkLines_checkAll__P
func (s *Suite) Test_MkLines_checkAll__PLIST_VARS_indirect_2(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wno-space")
t.SetUpVartypes()
t.SetUpOption("a", "")
t.SetUpOption("b", "")
@@ -844,12 +837,12 @@ func (s *Suite) Test_MkLines_checkAll__P
mklines := t.NewMkLines("module.mk",
MkCvsID,
"",
- "PKG_SUPPORTED_OPTIONS= a b c",
- "PLIST_VARS+= ${PKG_SUPPORTED_OPTIONS:S,a,,g}",
+ "PKG_SUPPORTED_OPTIONS=\ta b c",
+ "PLIST_VARS+=\t\t${PKG_SUPPORTED_OPTIONS:S,a,,g}",
"",
- "PLIST_VARS+= only-added",
+ "PLIST_VARS+=\t\tonly-added",
"",
- "PLIST.only-defined= yes")
+ "PLIST.only-defined=\tyes")
mklines.Check()
@@ -862,21 +855,20 @@ func (s *Suite) Test_MkLines_checkAll__P
func (s *Suite) Test_MkLines_checkAll__defined_and_used_variables(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wno-space")
t.SetUpVartypes()
mklines := t.NewMkLines("module.mk",
MkCvsID,
"",
".for lang in de fr",
- "PLIST_VARS+= ${lang}",
+ "PLIST_VARS+=\t${lang}",
".endif",
"",
".for language in de fr",
- "PLIST.${language}= yes",
+ "PLIST.${language}=\tyes",
".endif",
"",
- "PLIST.other= yes")
+ "PLIST.other=\tyes")
mklines.Check()
@@ -889,12 +881,11 @@ func (s *Suite) Test_MkLines_checkAll__d
func (s *Suite) Test_MkLines_checkAll__hacks_mk(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
t.SetUpVartypes()
mklines := t.NewMkLines("hacks.mk",
MkCvsID,
"",
- "PKGNAME?= pkgbase-1.0")
+ "PKGNAME?=\tpkgbase-1.0")
mklines.Check()
@@ -1026,13 +1017,13 @@ func (s *Suite) Test_MkLines_checkAll__e
"",
".for word in ${PKG_FAIL_REASON}",
"CONFIGURE_ARGS+=\t--sharedir=${PREFIX}/share/kde",
- "COMMENT=\t# defined",
+ "COMMENT=\t\t# defined",
".endfor",
- "GAMES_USER?=pkggames",
- "GAMES_GROUP?=pkggames",
- "PLIST_SUBST+= CONDITIONAL=${CONDITIONAL}",
- "CONDITIONAL=\"@comment\"",
- "BUILD_DIRS=\t${WRKSRC}/../build")
+ "GAMES_USER?=\t\tpkggames",
+ "GAMES_GROUP?=\t\tpkggames",
+ "PLIST_SUBST+=\t\tCONDITIONAL=${CONDITIONAL}",
+ "CONDITIONAL=\t\t\"@comment\"",
+ "BUILD_DIRS=\t\t${WRKSRC}/../build")
mklines.Check()
@@ -1069,7 +1060,7 @@ func (s *Suite) Test_MkLines_CheckUsedBy
t.SetUpCommandLine("--show-autofix")
- test := func(pkgpath Path, lines []string, diagnostics []string) {
+ test := func(pkgpath PkgsrcPath, lines []string, diagnostics []string) {
mklines := t.NewMkLines("Makefile.common", lines...)
mklines.CheckUsedBy(pkgpath)
@@ -1155,7 +1146,7 @@ func (s *Suite) Test_MkLines_CheckUsedBy
func (s *Suite) Test_MkLines_CheckUsedBy(c *check.C) {
t := s.Init(c)
- test := func(pkgpath Path, lines []string, diagnostics []string) {
+ test := func(pkgpath PkgsrcPath, lines []string, diagnostics []string) {
mklines := t.NewMkLines("Makefile.common", lines...)
mklines.CheckUsedBy(pkgpath)
Index: pkgsrc/pkgtools/pkglint/files/pkglint_test.go
diff -u pkgsrc/pkgtools/pkglint/files/pkglint_test.go:1.52 pkgsrc/pkgtools/pkglint/files/pkglint_test.go:1.53
--- pkgsrc/pkgtools/pkglint/files/pkglint_test.go:1.52 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/pkglint_test.go Mon Dec 2 23:32:09 2019
@@ -77,7 +77,6 @@ func (s *Suite) Test_Pkglint_Main__help(
" extra enable some extra warnings (disabled)",
" perm warn about unforeseen variable definition and use (disabled)",
" quoting warn about quoting issues (disabled)",
- " space warn about inconsistent use of whitespace (disabled)",
"",
" (Prefix a flag with \"no-\" to disable it.)")
}
@@ -307,7 +306,7 @@ func (s *Suite) Test_Pkglint_Main__profi
// Pkglint always writes the profiling data into the current directory.
// TODO: Make the location of the profiling log a mandatory parameter.
- t.CheckEquals(NewPath("pkglint.pprof").IsFile(), true)
+ t.CheckEquals(NewCurrPath("pkglint.pprof").IsFile(), true)
err := os.Remove("pkglint.pprof")
c.Check(err, check.IsNil)
@@ -494,7 +493,7 @@ func (s *Suite) Test_Pkglint_Check(c *ch
func (s *Suite) Test_Pkglint_Check__invalid_files_before_import(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Call", "-Wall,no-space", "--import")
+ t.SetUpCommandLine("-Call", "-Wall", "--import")
pkg := t.SetUpPackage("category/package")
t.CreateFileLines("category/package/work/log")
t.CreateFileLines("category/package/Makefile~")
@@ -640,7 +639,6 @@ func (s *Suite) Test_Pkglint_checkdirPac
func (s *Suite) Test_Pkglint_checkdirPackage__ALTERNATIVES(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
pkg := t.SetUpPackage("category/package")
t.CreateFileLines("category/package/ALTERNATIVES",
"bin/wrapper bin/wrapper-impl")
@@ -929,7 +927,7 @@ func (s *Suite) Test_Pkglint_checkReg__i
func (s *Suite) Test_Pkglint_checkReg__other(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Call", "-Wall,no-space")
+ t.SetUpCommandLine("-Call", "-Wall")
pkg := t.SetUpPackage("category/package")
t.CreateFileLines("category/package/INSTALL",
"#! /bin/sh")
@@ -953,10 +951,10 @@ func (s *Suite) Test_Pkglint_checkReg__r
t.CreateFileDummyPatch("category/package/patches/patch-README")
t.CreateFileLines("category/package/Makefile",
MkCvsID,
- "CATEGORIES=category",
+ "CATEGORIES=\tcategory",
"",
- "COMMENT=Comment",
- "LICENSE=2-clause-bsd")
+ "COMMENT=\tComment",
+ "LICENSE=\t2-clause-bsd")
t.CreateFileLines("category/package/PLIST",
PlistCvsID,
"bin/program")
Index: pkgsrc/pkgtools/pkglint/files/mkshparser_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mkshparser_test.go:1.21 pkgsrc/pkgtools/pkglint/files/mkshparser_test.go:1.22
--- pkgsrc/pkgtools/pkglint/files/mkshparser_test.go:1.21 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/mkshparser_test.go Mon Dec 2 23:32:09 2019
@@ -713,7 +713,7 @@ func (s *ShSuite) Test_parseShellProgram
func (s *ShSuite) init(c *check.C) *MkShBuilder {
s.c = c
- tmpdir := NewPath("The ShSuite tests don't need a temporary directory")
+ tmpdir := NewCurrPath("The ShSuite tests don't need a temporary directory")
s.t = &Tester{c: c, testName: c.TestName(), tmpdir: tmpdir}
G = NewPkglint(&s.t.stdout, &s.t.stderr)
return NewMkShBuilder()
Index: pkgsrc/pkgtools/pkglint/files/shtokenizer.go
diff -u pkgsrc/pkgtools/pkglint/files/shtokenizer.go:1.21 pkgsrc/pkgtools/pkglint/files/shtokenizer.go:1.22
--- pkgsrc/pkgtools/pkglint/files/shtokenizer.go:1.21 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/shtokenizer.go Mon Dec 2 23:32:09 2019
@@ -4,6 +4,7 @@ import "netbsd.org/pkglint/textproc"
type ShTokenizer struct {
parser *MkLexer
+ inWord bool
}
func NewShTokenizer(line *Line, text string, emitWarnings bool) *ShTokenizer {
@@ -13,7 +14,7 @@ func NewShTokenizer(line *Line, text str
emitWarnings = true
}
mklex := NewMkLexer(text, line)
- return &ShTokenizer{mklex}
+ return &ShTokenizer{mklex, false}
}
// ShAtom parses a basic building block of a shell program.
@@ -81,6 +82,8 @@ func (p *ShTokenizer) shAtomPlain() *ShA
if op := p.shOperator(q); op != nil {
return op
}
+ inWord := p.inWord
+ p.inWord = false
lexer := p.parser.lexer
mark := lexer.Mark()
switch {
@@ -92,7 +95,7 @@ func (p *ShTokenizer) shAtomPlain() *ShA
return &ShAtom{shtText, lexer.Since(mark), shqSquot, nil}
case lexer.SkipByte('`'):
return &ShAtom{shtText, lexer.Since(mark), shqBackt, nil}
- case lexer.PeekByte() == '#':
+ case lexer.PeekByte() == '#' && !inWord:
rest := lexer.Rest()
lexer.Skip(len(rest))
return &ShAtom{shtComment, rest, q, nil}
@@ -293,6 +296,7 @@ func (p *ShTokenizer) shAtomDquotBacktSq
// ${var:=default}
func (p *ShTokenizer) shAtomInternal(q ShQuoting, dquot, squot bool) *ShAtom {
if shVarUse := p.shVarUse(q); shVarUse != nil {
+ p.inWord = true
return shVarUse
}
@@ -332,6 +336,7 @@ loop:
}
if token := lexer.Since(mark); token != "" {
+ p.inWord = true
return &ShAtom{shtText, token, q, nil}
}
return nil
Index: pkgsrc/pkgtools/pkglint/files/options_test.go
diff -u pkgsrc/pkgtools/pkglint/files/options_test.go:1.19 pkgsrc/pkgtools/pkglint/files/options_test.go:1.20
--- pkgsrc/pkgtools/pkglint/files/options_test.go:1.19 Sun Nov 17 01:26:25 2019
+++ pkgsrc/pkgtools/pkglint/files/options_test.go Mon Dec 2 23:32:09 2019
@@ -252,7 +252,6 @@ func (s *Suite) Test_CheckLinesOptionsMk
func (s *Suite) Test_CheckLinesOptionsMk(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
t.SetUpVartypes()
t.SetUpOption("mc-charset", "")
t.SetUpOption("mysql", "")
@@ -268,17 +267,17 @@ func (s *Suite) Test_CheckLinesOptionsMk
mklines := t.SetUpFileMkLines("category/package/options.mk",
MkCvsID,
"",
- "PKG_OPTIONS_VAR= PKG_OPTIONS.mc",
- "PKG_OPTIONS_REQUIRED_GROUPS= screen",
- "PKG_OPTIONS_GROUP.screen= ncurses slang",
- "PKG_SUPPORTED_OPTIONS= mc-charset x11 lang-${l} negative",
- "PKG_SUGGESTED_OPTIONS= mc-charset slang",
- "PKG_OPTIONS_NONEMPTY_SETS+= db",
- "PKG_OPTIONS_SET.db= mysql sqlite",
+ "PKG_OPTIONS_VAR=\t\tPKG_OPTIONS.mc",
+ "PKG_OPTIONS_REQUIRED_GROUPS=\tscreen",
+ "PKG_OPTIONS_GROUP.screen=\tncurses slang",
+ "PKG_SUPPORTED_OPTIONS=\t\tmc-charset x11 lang-${l} negative",
+ "PKG_SUGGESTED_OPTIONS=\t\tmc-charset slang",
+ "PKG_OPTIONS_NONEMPTY_SETS+=\tdb",
+ "PKG_OPTIONS_SET.db=\t\tmysql sqlite",
"",
".include \"../../mk/bsd.options.mk\"",
"",
- "PKGNAME?= default-pkgname-1.",
+ "PKGNAME?=\tdefault-pkgname-1.",
"",
".if !empty(PKG_OPTIONS:Mx11)",
".endif",
@@ -323,7 +322,6 @@ func (s *Suite) Test_CheckLinesOptionsMk
func (s *Suite) Test_CheckLinesOptionsMk__unexpected_line(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wno-space")
t.SetUpVartypes()
t.CreateFileLines("mk/bsd.options.mk",
@@ -332,7 +330,7 @@ func (s *Suite) Test_CheckLinesOptionsMk
mklines := t.SetUpFileMkLines("category/package/options.mk",
MkCvsID,
"",
- "PKG_OPTIONS_VAR= PKG_OPTIONS.mc",
+ "PKG_OPTIONS_VAR=\tPKG_OPTIONS.mc",
"",
"pre-configure:",
"\techo \"In the pre-configure stage.\"")
@@ -340,14 +338,15 @@ func (s *Suite) Test_CheckLinesOptionsMk
CheckLinesOptionsMk(mklines)
t.CheckOutputLines(
- "ERROR: ~/category/package/options.mk: " +
+ "WARN: ~/category/package/options.mk:6: "+
+ "Unknown shell command \"echo\".",
+ "ERROR: ~/category/package/options.mk: "+
"Each options.mk file must .include \"../../mk/bsd.options.mk\".")
}
func (s *Suite) Test_CheckLinesOptionsMk__malformed_condition(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wno-space")
t.SetUpVartypes()
t.SetUpOption("mc-charset", "")
t.SetUpOption("ncurses", "")
@@ -360,9 +359,9 @@ func (s *Suite) Test_CheckLinesOptionsMk
mklines := t.SetUpFileMkLines("category/package/options.mk",
MkCvsID,
"",
- "PKG_OPTIONS_VAR= PKG_OPTIONS.mc",
- "PKG_SUPPORTED_OPTIONS= # none",
- "PKG_SUGGESTED_OPTIONS= # none",
+ "PKG_OPTIONS_VAR=\t\tPKG_OPTIONS.mc",
+ "PKG_SUPPORTED_OPTIONS=\t\t# none",
+ "PKG_SUGGESTED_OPTIONS=\t\t# none",
"",
"# Comments and conditionals are allowed at this point.",
".if ${OPSYS} == NetBSD",
Index: pkgsrc/pkgtools/pkglint/files/package.go
diff -u pkgsrc/pkgtools/pkglint/files/package.go:1.71 pkgsrc/pkgtools/pkglint/files/package.go:1.72
--- pkgsrc/pkgtools/pkglint/files/package.go:1.71 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/package.go Mon Dec 2 23:32:09 2019
@@ -16,12 +16,12 @@ const rePkgname = `^([\w\-.+]+)-(\d[.0-9
// This is necessary because variables in Makefiles may be used before they are defined,
// and such dependencies often span multiple files that are included indirectly.
type Package struct {
- dir Path // The directory of the package, for resolving files
- Pkgpath Path // e.g. "category/pkgdir"
- Pkgdir Path // PKGDIR from the package Makefile
- Filesdir Path // FILESDIR from the package Makefile
- Patchdir Path // PATCHDIR from the package Makefile
- DistinfoFile Path // DISTINFO_FILE from the package Makefile
+ dir CurrPath // The directory of the package, for resolving files
+ Pkgpath PkgsrcPath // e.g. "category/pkgdir"
+ Pkgdir PackagePath // PKGDIR from the package Makefile
+ Filesdir PackagePath // FILESDIR from the package Makefile
+ Patchdir PackagePath // PATCHDIR from the package Makefile
+ DistinfoFile PackagePath // DISTINFO_FILE from the package Makefile
EffectivePkgname string // PKGNAME or DISTNAME from the package Makefile, including nb13, can be empty
EffectivePkgbase string // EffectivePkgname without the version
EffectivePkgversion string // The version part of the effective PKGNAME, excluding nb13
@@ -59,7 +59,7 @@ type Package struct {
Once Once
}
-func NewPackage(dir Path) *Package {
+func NewPackage(dir CurrPath) *Package {
pkgpath := G.Pkgsrc.ToRel(dir)
// Package directory must be two subdirectories below the pkgsrc root.
@@ -99,7 +99,7 @@ func NewPackage(dir Path) *Package {
return &pkg
}
-func (pkg *Package) load() ([]Path, *MkLines, *MkLines) {
+func (pkg *Package) load() ([]CurrPath, *MkLines, *MkLines) {
// Load the package Makefile and all included files,
// to collect all used and defined variables and similar data.
mklines, allLines := pkg.loadPackageMakefile()
@@ -107,26 +107,27 @@ func (pkg *Package) load() ([]Path, *MkL
return nil, nil, nil
}
- files := dirglob(pkg.File("."))
+ files := pkg.File(".").ReadPaths()
if pkg.Pkgdir != "." {
- files = append(files, dirglob(pkg.File(pkg.Pkgdir))...)
+ files = append(files, pkg.File(pkg.Pkgdir).ReadPaths()...)
}
- files = append(files, dirglob(pkg.File(pkg.Patchdir))...)
- if pkg.DistinfoFile != NewPath(pkg.vars.fallback["DISTINFO_FILE"]) {
+ files = append(files, pkg.File(pkg.Patchdir).ReadPaths()...)
+ if pkg.DistinfoFile != NewPackagePath(NewPath(pkg.vars.fallback["DISTINFO_FILE"])) {
files = append(files, pkg.File(pkg.DistinfoFile))
}
- isRelevantMk := func(filename Path, basename string) bool {
+ isRelevantMk := func(filename CurrPath, basename string) bool {
if !hasPrefix(basename, "Makefile.") && !filename.HasSuffixText(".mk") {
return false
}
- if filename.Dir().Base() == "patches" {
+ // FIXME: consider DirNoClean
+ if filename.DirClean().Base() == "patches" {
return false
}
if pkg.Pkgdir == "." {
return true
}
- return !filename.ContainsPath(pkg.Pkgdir)
+ return !filename.ContainsPath(pkg.Pkgdir.AsPath())
}
// Determine the used variables and PLIST directories before checking any of the Makefile fragments.
@@ -181,10 +182,10 @@ func (pkg *Package) loadPackageMakefile(
allLines.collectUsedVariables()
- pkg.Pkgdir = NewPath(pkg.vars.LastValue("PKGDIR"))
- pkg.DistinfoFile = NewPath(pkg.vars.LastValue("DISTINFO_FILE"))
- pkg.Filesdir = NewPath(pkg.vars.LastValue("FILESDIR"))
- pkg.Patchdir = NewPath(pkg.vars.LastValue("PATCHDIR"))
+ pkg.Pkgdir = NewPackagePath(NewPath(pkg.vars.LastValue("PKGDIR")))
+ pkg.DistinfoFile = NewPackagePath(NewPath(pkg.vars.LastValue("DISTINFO_FILE")))
+ pkg.Filesdir = NewPackagePath(NewPath(pkg.vars.LastValue("FILESDIR")))
+ pkg.Patchdir = NewPackagePath(NewPath(pkg.vars.LastValue("PATCHDIR")))
// See lang/php/ext.mk
if pkg.vars.IsDefinedSimilar("PHPEXT_MK") {
@@ -212,7 +213,7 @@ func (pkg *Package) loadPackageMakefile(
}
// TODO: What is allLines used for, is it still necessary? Would it be better as a field in Package?
-func (pkg *Package) parse(mklines *MkLines, allLines *MkLines, includingFileForUsedCheck Path) bool {
+func (pkg *Package) parse(mklines *MkLines, allLines *MkLines, includingFileForUsedCheck CurrPath) bool {
if trace.Tracing {
defer trace.Call(mklines.lines.Filename)()
}
@@ -229,7 +230,8 @@ func (pkg *Package) parse(mklines *MkLin
// automatically since the pkgsrc infrastructure does the same.
filename := mklines.lines.Filename
if filename.Base() == "buildlink3.mk" {
- builtin := cleanpath(filename.Dir().JoinNoClean("builtin.mk"))
+ // FIXME: consider DirNoClean
+ builtin := filename.DirClean().JoinNoClean("builtin.mk").CleanPath()
builtinRel := G.Pkgsrc.Relpath(pkg.dir, builtin)
if pkg.included.FirstTime(builtinRel.String()) && builtin.IsFile() {
builtinMkLines := LoadMk(builtin, MustSucceed|LogErrors)
@@ -250,16 +252,16 @@ func (pkg *Package) parseLine(mklines *M
includedMkLines, skip := pkg.loadIncluded(mkline, includingFile)
if includedMkLines == nil {
- if skip || mklines.indentation.HasExists(includedFile) {
+ if skip || mklines.indentation.HasExists(NewRelPath(includedFile)) {
return true // See https://github.com/rillig/pkglint/issues/1
}
mkline.Errorf("Cannot read %q.", includedFile)
return false
}
- filenameForUsedCheck := NewPath("")
+ filenameForUsedCheck := NewCurrPath("")
dir, base := includedFile.Split()
- if dir != "" && base == "Makefile.common" && dir != "../../"+pkg.Pkgpath+"/" {
+ if dir != "" && base == "Makefile.common" && dir.String() != "../../"+pkg.Pkgpath.String()+"/" {
filenameForUsedCheck = includingFile
}
if !pkg.parse(includedMkLines, allLines, filenameForUsedCheck) {
@@ -287,15 +289,17 @@ func (pkg *Package) parseLine(mklines *M
// the included file is not processed further for whatever reason. But if
// skip is false, the file could not be read and an appropriate error message
// has already been logged.
-func (pkg *Package) loadIncluded(mkline *MkLine, includingFile Path) (includedMklines *MkLines, skip bool) {
+func (pkg *Package) loadIncluded(mkline *MkLine, includingFile CurrPath) (includedMklines *MkLines, skip bool) {
includedFile := pkg.resolveIncludedFile(mkline, includingFile)
- if includedFile == "" {
+ if includedFile.IsEmpty() {
return nil, true
}
- dirname, _ := includingFile.Split() // TODO: .Dir?
- dirname = cleanpath(dirname)
+ // TODO: .Dir? Add test before changing this.
+ // pkglint -Wall x11/kde-runtime4
+ dirname, _ := includingFile.Split()
+ dirname = dirname.CleanPath()
fullIncluded := dirname.JoinNoClean(includedFile)
relIncludedFile := G.Pkgsrc.Relpath(pkg.dir, fullIncluded)
@@ -355,11 +359,11 @@ func (pkg *Package) loadIncluded(mkline
// resolveIncludedFile resolves Makefile variables such as ${PKGPATH} to
// their actual values.
-func (pkg *Package) resolveIncludedFile(mkline *MkLine, includingFilename Path) Path {
+func (pkg *Package) resolveIncludedFile(mkline *MkLine, includingFilename CurrPath) Path {
- // TODO: resolveVariableRefs uses G.Pkg implicitly. It should be made explicit.
+ // FIXME: resolveVariableRefs uses G.Pkg implicitly. It should be made explicit.
// TODO: Try to combine resolveVariableRefs and ResolveVarsInRelativePath.
- resolved := mkline.ResolveVarsInRelativePath(mkline.IncludedFile())
+ resolved := mkline.ResolveVarsInRelativePath(NewRelPath(mkline.IncludedFile()))
includedText := resolveVariableRefs(nil /* XXX: or maybe some mklines? */, resolved.String())
includedFile := NewPath(includedText)
if containsVarRef(includedText) {
@@ -386,7 +390,7 @@ func (pkg *Package) resolveIncludedFile(
//
// The includingFile is relative to the current working directory,
// the includedFile is taken directly from the .include directive.
-func (*Package) shouldDiveInto(includingFile, includedFile Path) bool {
+func (*Package) shouldDiveInto(includingFile CurrPath, includedFile Path) bool {
if includedFile.HasSuffixPath("bsd.pkg.mk") || IsPrefs(includedFile) {
return false
@@ -436,7 +440,7 @@ func (pkg *Package) collectConditionalIn
})
}
-func (pkg *Package) loadPlistDirs(plistFilename Path) {
+func (pkg *Package) loadPlistDirs(plistFilename CurrPath) {
lines := Load(plistFilename, MustSucceed)
ck := PlistChecker{
pkg,
@@ -455,7 +459,7 @@ func (pkg *Package) loadPlistDirs(plistF
}
}
-func (pkg *Package) check(filenames []Path, mklines, allLines *MkLines) {
+func (pkg *Package) check(filenames []CurrPath, mklines, allLines *MkLines) {
haveDistinfo := false
havePatches := false
@@ -505,7 +509,7 @@ func (pkg *Package) check(filenames []Pa
}
}
-func (pkg *Package) checkfilePackageMakefile(filename Path, mklines *MkLines, allLines *MkLines) {
+func (pkg *Package) checkfilePackageMakefile(filename CurrPath, mklines *MkLines, allLines *MkLines) {
if trace.Tracing {
defer trace.Call(filename)()
}
@@ -607,7 +611,7 @@ func (pkg *Package) checkPlist() {
needsPlist, line := pkg.needsPlist()
hasPlist := pkg.File(pkg.Pkgdir.JoinNoClean("PLIST")).IsFile() ||
- pkg.File(pkg.Pkgdir.JoinNoClean("/PLIST.common")).IsFile()
+ pkg.File(pkg.Pkgdir.JoinNoClean("PLIST.common")).IsFile()
if needsPlist && !hasPlist {
line.Warnf("This package should have a PLIST file.")
@@ -731,7 +735,7 @@ func (pkg *Package) CheckVarorder(mkline
{"TOOL_DEPENDS", many},
{"DEPENDS", many}}
- relevantLines := (func() []*MkLine {
+ relevantLines := func() []*MkLine {
firstRelevant := -1
lastRelevant := -1
@@ -779,7 +783,7 @@ func (pkg *Package) CheckVarorder(mkline
return nil
}
return mklines.mklines[firstRelevant : lastRelevant+1]
- })()
+ }()
// If there are foreign variables, skip the whole check.
// The check is only intended for the most simple packages.
@@ -1199,7 +1203,7 @@ func (pkg *Package) checkUpdate() {
// checkDirent checks a directory entry based on its filename and its mode
// (regular file, directory, symlink).
-func (pkg *Package) checkDirent(dirent Path, mode os.FileMode) {
+func (pkg *Package) checkDirent(dirent CurrPath, mode os.FileMode) {
// TODO: merge duplicate code in Pkglint.checkMode
basename := dirent.Base()
@@ -1219,7 +1223,8 @@ func (pkg *Package) checkDirent(dirent P
switch {
case basename == "files",
basename == "patches",
- dirent.Dir().Base() == "files",
+ // FIXME: consider DirNoClean
+ dirent.DirClean().Base() == "files",
isEmptyDir(dirent):
break
@@ -1241,7 +1246,7 @@ func (pkg *Package) checkDirent(dirent P
//
// Pkglint assumes that the local username is the same as the NetBSD
// username, which fits most scenarios.
-func (pkg *Package) checkOwnerMaintainer(filename Path) {
+func (pkg *Package) checkOwnerMaintainer(filename CurrPath) {
if trace.Tracing {
defer trace.Call(filename)()
}
@@ -1283,7 +1288,7 @@ func (pkg *Package) checkOwnerMaintainer
"keyword \"maintainer\", for more information.")
}
-func (pkg *Package) checkFreeze(filename Path) {
+func (pkg *Package) checkFreeze(filename CurrPath) {
freezeStart := G.Pkgsrc.LastFreezeStart
if freezeStart == "" || G.Pkgsrc.LastFreezeEnd != "" {
return
@@ -1300,7 +1305,7 @@ func (pkg *Package) checkFreeze(filename
"See https://www.NetBSD.org/developers/pkgsrc/ for the exact rules.")
}
-func (pkg *Package) checkFileMakefileExt(filename Path) {
+func (pkg *Package) checkFileMakefileExt(filename CurrPath) {
base := filename.Base()
if !hasPrefix(base, "Makefile.") || base == "Makefile.common" {
return
@@ -1392,7 +1397,7 @@ func (pkg *Package) checkIncludeConditio
mkline.Warnf(
"%q is included conditionally here%s "+
"and unconditionally in %s.",
- cleanpath(mkline.IncludedFile()),
+ mkline.IncludedFile().CleanPath(),
dependingOn(mkline.ConditionalVars()),
mkline.RefTo(other))
@@ -1408,7 +1413,7 @@ func (pkg *Package) checkIncludeConditio
mkline.Warnf(
"%q is included unconditionally here "+
"and conditionally in %s%s.",
- cleanpath(mkline.IncludedFile()),
+ mkline.IncludedFile().CleanPath(),
mkline.RefTo(other),
dependingOn(other.ConditionalVars()))
@@ -1438,10 +1443,10 @@ func (pkg *Package) AutofixDistinfo(oldS
// File returns the (possibly absolute) path to relativeFileName,
// as resolved from the package's directory.
// Variables that are known in the package are resolved, e.g. ${PKGDIR}.
-func (pkg *Package) File(relativeFileName Path) Path {
- joined := pkg.dir.JoinNoClean(relativeFileName)
+func (pkg *Package) File(relativeFileName PackagePath) CurrPath {
+ joined := pkg.dir.JoinNoClean(relativeFileName.AsPath())
resolved := resolveVariableRefs(nil /* XXX: or maybe some mklines? */, joined.String())
- return cleanpath(NewPath(resolved))
+ return NewCurrPathString(resolved).CleanPath()
}
// Rel returns the path by which the given filename (as seen from the
@@ -1450,7 +1455,7 @@ func (pkg *Package) File(relativeFileNam
//
// Example:
// NewPackage("category/package").Rel("other/package") == "../../other/package"
-func (pkg *Package) Rel(filename Path) Path {
+func (pkg *Package) Rel(filename CurrPath) Path {
return G.Pkgsrc.Relpath(pkg.dir, filename)
}
Index: pkgsrc/pkgtools/pkglint/files/package_test.go
diff -u pkgsrc/pkgtools/pkglint/files/package_test.go:1.60 pkgsrc/pkgtools/pkglint/files/package_test.go:1.61
--- pkgsrc/pkgtools/pkglint/files/package_test.go:1.60 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/package_test.go Mon Dec 2 23:32:09 2019
@@ -24,20 +24,20 @@ func (s *Suite) Test_Package__varuse_at_
t.CreateFileLines("category/pkgbase/Makefile",
MkCvsID,
"",
- "PKGNAME= loadtime-vartest-1.0",
- "CATEGORIES= category",
+ "PKGNAME=\tloadtime-vartest-1.0",
+ "CATEGORIES=\tcategory",
+ "",
+ "COMMENT=\tDemonstrate variable values during parsing",
+ "LICENSE=\t2-clause-bsd",
"",
- "COMMENT= Demonstrate variable values during parsing",
- "LICENSE= 2-clause-bsd",
+ "PLIST_SRC=\t# none",
+ "NO_CHECKSUM=\tyes",
+ "NO_CONFIGURE=\tyes",
"",
- "PLIST_SRC= # none",
- "NO_CHECKSUM= yes",
- "NO_CONFIGURE= yes",
- "",
- "USE_TOOLS+= echo false",
- "FALSE_BEFORE!= echo false=${FALSE:Q}", // false=
- "NICE_BEFORE!= echo nice=${NICE:Q}", // nice=
- "TRUE_BEFORE!= echo true=${TRUE:Q}", // true=
+ "USE_TOOLS+=\techo false",
+ "FALSE_BEFORE!=\techo false=${FALSE:Q}", // false=
+ "NICE_BEFORE!=\techo nice=${NICE:Q}", // nice=
+ "TRUE_BEFORE!=\techo true=${TRUE:Q}", // true=
//
// All three variables above are empty since the tool
// variables are initialized by bsd.prefs.mk. The variables
@@ -55,7 +55,7 @@ func (s *Suite) Test_Package__varuse_at_
// run to set up the correct PATH.
//
"",
- "USE_TOOLS+= nice",
+ "USE_TOOLS+=\tnice",
//
// The "nice" tool will only be available as ${NICE} after bsd.pkg.mk
// has been included. Even including bsd.prefs.mk another time does
@@ -64,9 +64,9 @@ func (s *Suite) Test_Package__varuse_at_
"",
".include \"../../mk/bsd.prefs.mk\"", // Has no effect.
"",
- "FALSE_AFTER!= echo false=${FALSE:Q}", // false=false
- "NICE_AFTER!= echo nice=${NICE:Q}", // nice=
- "TRUE_AFTER!= echo true=${TRUE:Q}", // true=true
+ "FALSE_AFTER!=\techo false=${FALSE:Q}", // false=false
+ "NICE_AFTER!=\techo nice=${NICE:Q}", // nice=
+ "TRUE_AFTER!=\techo true=${TRUE:Q}", // true=true
"",
"do-build:",
"\t${RUN} printf 'before: %-20s %-20s %-20s\\n' ${FALSE_BEFORE} ${NICE_BEFORE} ${TRUE_BEFORE}",
@@ -75,7 +75,7 @@ func (s *Suite) Test_Package__varuse_at_
"",
".include \"../../mk/bsd.pkg.mk\"")
- t.SetUpCommandLine("-q", "-Wall,no-space")
+ t.SetUpCommandLine("-q", "-Wall")
t.FinishSetUp()
G.Check(t.File("category/pkgbase"))
@@ -273,7 +273,6 @@ func (s *Suite) Test_Package__redundant_
func (s *Suite) Test_Package__distinfo_from_other_package(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
t.SetUpPkgsrc()
t.Chdir(".")
t.CreateFileLines("x11/gst-x11/Makefile",
@@ -496,7 +495,7 @@ func (s *Suite) Test_Package_loadPackage
t.CreateFileLines("category/package/Makefile",
MkCvsID,
"",
- "CATEGORIES=category",
+ "CATEGORIES=\tcategory",
"",
"COMMENT=\tComment",
"LICENSE=\t2-clause-bsd")
@@ -510,7 +509,7 @@ func (s *Suite) Test_Package_loadPackage
"Whole Makefile (with all included files) follows:",
"~/category/package/Makefile:1: "+MkCvsID,
"~/category/package/Makefile:2: ",
- "~/category/package/Makefile:3: CATEGORIES=category",
+ "~/category/package/Makefile:3: CATEGORIES=\tcategory",
"~/category/package/Makefile:4: ",
"~/category/package/Makefile:5: COMMENT=\tComment",
"~/category/package/Makefile:6: LICENSE=\t2-clause-bsd")
@@ -827,7 +826,6 @@ func (s *Suite) Test_Package_parse__none
func (s *Suite) Test_Package_parse__skipping(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
pkg := t.SetUpPackage("category/package",
".include \"${MYSQL_PKGSRCDIR:S/-client$/-server/}/buildlink3.mk\"")
t.FinishSetUp()
@@ -845,7 +843,7 @@ func (s *Suite) Test_Package_parse__skip
output := t.Output()
var relevant []string
for _, line := range strings.Split(output, "\n") {
- if contains(line, "Skipping") {
+ if contains(line, "Skipping unresolvable") {
relevant = append(relevant, line)
}
}
@@ -1011,6 +1009,33 @@ func (s *Suite) Test_Package_parse__fall
"The path to the included file should be \"pthread.builtin.mk\".")
}
+func (s *Suite) Test_Package_loadIncluded__nested_inclusion(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("x11/kde-runtime4",
+ ".include \"../../x11/kde-libs4/buildlink3.mk\"")
+ t.SetUpPackage("x11/kde-libs4")
+ t.CreateFileDummyBuildlink3("x11/kde-libs4/buildlink3.mk",
+ ".include \"../../databases/openldap/buildlink3.mk\"")
+ t.SetUpPackage("databases/openldap")
+ t.CreateFileDummyBuildlink3("databases/openldap/buildlink3.mk",
+ "VAR=\tvalue",
+ "VAR=\tvalue") // Provoke a warning in this file.
+ t.FinishSetUp()
+ // Without this line, the current directory is an absolute directory,
+ // and the pkgsrc top directory is as well. One of them prevents the
+ // verbose paths from being generated.
+ t.Chdir(".")
+
+ G.Check("x11/kde-runtime4")
+
+ // The first part of the path must be "x11/kde-runtime4" to easily
+ // identify the package by which all other files are included.
+ t.CheckOutputLines(
+ "NOTE: x11/kde-runtime4/../../databases/openldap/buildlink3.mk:13: " +
+ "Definition of VAR is redundant because of line 12.")
+}
+
// Just for code coverage.
func (s *Suite) Test_Package_resolveIncludedFile__no_tracing(c *check.C) {
t := s.Init(c)
@@ -1065,7 +1090,7 @@ func (s *Suite) Test_Package_shouldDiveI
t := s.Init(c)
t.Chdir("category/package")
- test := func(including, included Path, expected bool) {
+ test := func(including CurrPath, included Path, expected bool) {
actual := (*Package)(nil).shouldDiveInto(including, included)
t.CheckEquals(actual, expected)
}
@@ -1232,7 +1257,7 @@ func (s *Suite) Test_Package_check__patc
func (s *Suite) Test_Package_checkfilePackageMakefile__GNU_CONFIGURE(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
+ t.SetUpCommandLine("-Wall")
pkg := t.SetUpPackage("category/package",
"GNU_CONFIGURE=\tyes",
"USE_LANGUAGES=\t#")
@@ -1249,7 +1274,6 @@ func (s *Suite) Test_Package_checkfilePa
func (s *Suite) Test_Package_checkfilePackageMakefile__GNU_CONFIGURE_ok(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
pkg := t.SetUpPackage("category/package",
"GNU_CONFIGURE=\tyes",
"USE_LANGUAGES=\t# none, really")
@@ -1263,7 +1287,6 @@ func (s *Suite) Test_Package_checkfilePa
func (s *Suite) Test_Package_checkfilePackageMakefile__REPLACE_PERL(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
pkg := t.SetUpPackage("category/package",
"REPLACE_PERL=\t*.pl",
"NO_CONFIGURE=\tyes")
@@ -2522,11 +2545,11 @@ func (s *Suite) Test_Package_checkUpdate
// The package names intentionally differ from the package directories
// to ensure that the check uses the package name.
t.SetUpPackage("category/pkg1",
- "PKGNAME= package1-1.0")
+ "PKGNAME=\tpackage1-1.0")
t.SetUpPackage("category/pkg2",
- "PKGNAME= package2-1.0")
+ "PKGNAME=\tpackage2-1.0")
t.SetUpPackage("category/pkg3",
- "PKGNAME= package3-5.0")
+ "PKGNAME=\tpackage3-5.0")
t.CreateFileLines("doc/TODO",
CvsID,
"Suggested package updates",
@@ -2541,7 +2564,7 @@ func (s *Suite) Test_Package_checkUpdate
"\t"+"o package3-3.0 [security update]")
t.Chdir(".")
- t.Main("-Wall,no-space", "category/pkg1", "category/pkg2", "category/pkg3")
+ t.Main("-Wall", "category/pkg1", "category/pkg2", "category/pkg3")
t.CheckOutputLines(
"NOTE: category/pkg1/Makefile:4: The update request to 1.0 from ../../doc/TODO:6 has been done.",
@@ -2556,7 +2579,7 @@ func (s *Suite) Test_Package_checkUpdate
func (s *Suite) Test_Package_checkDirent__errors(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Call", "-Wall,no-space")
+ t.SetUpCommandLine("-Call", "-Wall")
t.SetUpPkgsrc()
t.CreateFileLines("category/package/files/subdir/file")
t.CreateFileLines("category/package/files/subdir/subsub/file")
@@ -2576,12 +2599,13 @@ func (s *Suite) Test_Package_checkDirent
func (s *Suite) Test_Package_checkDirent__file_selection(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Call", "-Wall,no-space")
+ t.SetUpCommandLine("-Call", "-Wall")
t.SetUpPkgsrc()
t.CreateFileLines("doc/CHANGES-2018",
CvsID)
t.CreateFileLines("category/package/buildlink3.mk",
- MkCvsID)
+ MkCvsID,
+ "")
t.CreateFileLines("category/package/unexpected.txt",
CvsID)
t.FinishSetUp()
@@ -2592,6 +2616,7 @@ func (s *Suite) Test_Package_checkDirent
pkg.checkDirent(t.File("category/package/unexpected.txt"), 0444)
t.CheckOutputLines(
+ "NOTE: ~/category/package/buildlink3.mk:2: Trailing empty lines.",
"WARN: ~/category/package/buildlink3.mk:EOF: Expected a BUILDLINK_TREE line.",
"WARN: ~/category/package/unexpected.txt: Unexpected file found.")
}
Index: pkgsrc/pkgtools/pkglint/files/patches.go
diff -u pkgsrc/pkgtools/pkglint/files/patches.go:1.33 pkgsrc/pkgtools/pkglint/files/patches.go:1.34
--- pkgsrc/pkgtools/pkglint/files/patches.go:1.33 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/patches.go Mon Dec 2 23:32:09 2019
@@ -200,7 +200,7 @@ func (ck *PatchChecker) checkBeginDiff(l
"be mentioned in this file, to prevent duplicate work.")
}
- if G.Opts.WarnSpace && !ck.previousLineEmpty {
+ if !ck.previousLineEmpty {
fix := line.Autofix()
fix.Notef("Empty line expected.")
fix.InsertBefore("")
Index: pkgsrc/pkgtools/pkglint/files/path.go
diff -u pkgsrc/pkgtools/pkglint/files/path.go:1.3 pkgsrc/pkgtools/pkglint/files/path.go:1.4
--- pkgsrc/pkgtools/pkglint/files/path.go:1.3 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/path.go Mon Dec 2 23:32:09 2019
@@ -8,22 +8,14 @@ import (
"strings"
)
-// Path is a slash-separated path in the filesystem.
+// Path is a slash-separated path.
+// It may or may not resolve to an existing file.
// It may be absolute or relative.
// Some paths may contain placeholders like @VAR@ or ${VAR}.
-// The base directory of relative paths depends on the context
-// in which the path is used.
-//
-// TODO: Consider adding several more specialized types of path:
-// TODO: CurrPath, relative to the current working directory
-// TODO: PkgsrcPath, relative to the pkgsrc root
-// TODO: PackagePath, relative to the package directory
-// TODO: RelativePath, relative to some other basedir
+// The base directory of relative paths is unspecified.
type Path string
-func NewPath(name string) Path { return Path(name) }
-
-func NewPathSlash(name string) Path { return Path(filepath.ToSlash(name)) }
+func NewPath(p string) Path { return Path(p) }
func (p Path) String() string { return string(p) }
@@ -33,7 +25,24 @@ func (p Path) GoString() string { return
// which is usually a sign of an uninitialized variable.
func (p Path) IsEmpty() bool { return p == "" }
-func (p Path) Dir() Path { return Path(path.Dir(string(p))) }
+func (p Path) DirClean() Path { return Path(path.Dir(string(p))) }
+
+// Returns the directory of the path, with only minimal cleaning.
+// Only redundant dots and slashes are removed, and only at the end.
+func (p Path) DirNoClean() Path {
+ s := p.String()
+ end := len(s)
+ for end > 0 && s[end-1] != '/' {
+ end--
+ }
+ for end > 1 && s[end-1] == '/' || end > 2 && hasPrefix(s[end-2:], "/.") {
+ end--
+ }
+ if end == 0 {
+ return "."
+ }
+ return NewPath(s[:end])
+}
func (p Path) Base() string { return path.Base(string(p)) }
@@ -48,7 +57,7 @@ func (p Path) Split() (dir Path, base st
// Absolute paths have an empty string as its first part.
// All other parts are nonempty.
func (p Path) Parts() []string {
- if p == "" {
+ if p.IsEmpty() {
return nil
}
@@ -120,11 +129,6 @@ func (p Path) ContainsPath(sub Path) boo
return sub == "."
}
-func (p Path) ContainsPathCanonical(sub Path) bool {
- cleaned := cleanpath(p)
- return cleaned.ContainsPath(sub)
-}
-
func (p Path) HasSuffixText(suffix string) bool {
return hasSuffix(string(p), suffix)
}
@@ -159,16 +163,30 @@ func (p Path) Clean() Path { return NewP
// CleanDot returns the path with single dots removed and double slashes
// collapsed.
func (p Path) CleanDot() Path {
- if !p.ContainsText(".") {
+ if !p.ContainsText(".") && !p.ContainsText("//") {
return p
}
- var parts []string
- for i, part := range p.Parts() {
- if !(part == "." || i > 0 && part == "") { // See Parts
- parts = append(parts, part)
+ parts := p.Parts()
+ return NewPath(strings.Join(parts, "/"))
+}
+
+// Differs from path.Clean in that only "../../" is replaced, not "../".
+// Also, the initial directory is always kept.
+// This is to provide the package path as context in deeply nested .include chains.
+func (p Path) CleanPath() Path {
+ parts := p.Parts()
+
+ for i := 2; i+3 < len(parts); /* nothing */ {
+ if parts[i] != ".." && parts[i+1] != ".." && parts[i+2] == ".." && parts[i+3] == ".." {
+ if i+4 == len(parts) || parts[i+4] != ".." {
+ parts = append(parts[:i], parts[i+4:]...)
+ continue
+ }
}
+ i++
}
+
if len(parts) == 0 {
return "."
}
@@ -188,44 +206,262 @@ func (p Path) Rel(other Path) Path {
return NewPath(filepath.ToSlash(rel))
}
-func (p Path) Rename(newName Path) error {
+// CurrPath is a path that is either absolute or relative to the current
+// working directory. It is used in command line arguments and for
+// loading files from the file system, and later in the diagnostics.
+type CurrPath string
+
+func NewCurrPath(p Path) CurrPath { return CurrPath(p) }
+
+func NewCurrPathString(p string) CurrPath { return CurrPath(p) }
+
+func NewCurrPathSlash(p string) CurrPath {
+ return CurrPath(filepath.ToSlash(p))
+}
+
+func (p CurrPath) GoString() string { return p.AsPath().GoString() }
+
+func (p CurrPath) String() string { return string(p) }
+
+func (p CurrPath) AsPath() Path { return Path(p) }
+
+func (p CurrPath) IsEmpty() bool { return p.AsPath().IsEmpty() }
+
+func (p CurrPath) DirClean() CurrPath {
+ return CurrPath(p.AsPath().DirClean())
+}
+
+func (p CurrPath) DirNoClean() CurrPath {
+ return CurrPath(p.AsPath().DirNoClean())
+}
+
+func (p CurrPath) Base() string { return p.AsPath().Base() }
+
+func (p CurrPath) Split() (dir CurrPath, base string) {
+ pathDir, pathBase := p.AsPath().Split()
+ return NewCurrPath(pathDir), pathBase
+}
+
+func (p CurrPath) Parts() []string { return p.AsPath().Parts() }
+
+func (p CurrPath) IsAbs() bool { return p.AsPath().IsAbs() }
+
+func (p CurrPath) HasPrefixPath(prefix CurrPath) bool {
+ return p.AsPath().HasPrefixPath(prefix.AsPath())
+}
+
+func (p CurrPath) ContainsPath(sub Path) bool {
+ return p.AsPath().ContainsPath(sub)
+}
+
+func (p CurrPath) ContainsText(text string) bool {
+ return p.AsPath().ContainsText(text)
+}
+
+func (p CurrPath) HasSuffixPath(suffix Path) bool {
+ return p.AsPath().HasSuffixPath(suffix)
+}
+
+func (p CurrPath) HasSuffixText(suffix string) bool {
+ return p.AsPath().HasSuffixText(suffix)
+}
+
+func (p CurrPath) HasBase(base string) bool {
+ return p.AsPath().HasBase(base)
+}
+
+func (p CurrPath) TrimSuffix(suffix string) CurrPath {
+ return NewCurrPath(p.AsPath().TrimSuffix(suffix))
+}
+
+func (p CurrPath) ReplaceSuffix(from string, to string) CurrPath {
+ trimmed := p.TrimSuffix(from)
+ assert(trimmed != p)
+ return NewCurrPathString(trimmed.String() + to)
+}
+
+func (p CurrPath) Clean() CurrPath { return CurrPath(p.AsPath().Clean()) }
+
+func (p CurrPath) CleanDot() CurrPath {
+ return NewCurrPath(p.AsPath().CleanDot())
+}
+
+func (p CurrPath) CleanPath() CurrPath {
+ return CurrPath(p.AsPath().CleanPath())
+}
+
+func (p CurrPath) JoinNoClean(other Path) CurrPath {
+ return CurrPath(p.AsPath().JoinNoClean(other))
+}
+
+func (p CurrPath) JoinClean(other Path) CurrPath {
+ return NewCurrPath(p.AsPath().JoinClean(other))
+}
+
+func (p CurrPath) Rel(rel CurrPath) Path {
+ return p.AsPath().Rel(rel.AsPath())
+}
+
+func (p CurrPath) Rename(newName CurrPath) error {
return os.Rename(string(p), string(newName))
}
-func (p Path) Lstat() (os.FileInfo, error) { return os.Lstat(string(p)) }
+func (p CurrPath) Lstat() (os.FileInfo, error) { return os.Lstat(string(p)) }
-func (p Path) Stat() (os.FileInfo, error) { return os.Stat(string(p)) }
+func (p CurrPath) Stat() (os.FileInfo, error) { return os.Stat(string(p)) }
-func (p Path) Exists() bool {
+func (p CurrPath) Exists() bool {
_, err := p.Lstat()
return err == nil
}
-func (p Path) IsFile() bool {
+func (p CurrPath) IsFile() bool {
info, err := p.Lstat()
return err == nil && info.Mode().IsRegular()
}
-func (p Path) IsDir() bool {
+func (p CurrPath) IsDir() bool {
info, err := p.Lstat()
return err == nil && info.IsDir()
}
-func (p Path) Chmod(mode os.FileMode) error {
+func (p CurrPath) Chmod(mode os.FileMode) error {
return os.Chmod(string(p), mode)
}
-func (p Path) ReadDir() ([]os.FileInfo, error) {
+func (p CurrPath) ReadDir() ([]os.FileInfo, error) {
return ioutil.ReadDir(string(p))
}
-func (p Path) Open() (*os.File, error) { return os.Open(string(p)) }
+func (p CurrPath) ReadPaths() []CurrPath {
+ infos, err := p.ReadDir()
+ if err != nil {
+ return nil
+ }
+ var filenames []CurrPath
+ for _, info := range infos {
+ if !isIgnoredFilename(info.Name()) {
+ joined := p.JoinNoClean(NewPath(info.Name())).CleanPath()
+ filenames = append(filenames, joined)
+ }
+ }
+ return filenames
+}
-func (p Path) ReadString() (string, error) {
+func (p CurrPath) Open() (*os.File, error) { return os.Open(string(p)) }
+
+func (p CurrPath) ReadString() (string, error) {
bytes, err := ioutil.ReadFile(string(p))
return string(bytes), err
}
-func (p Path) WriteString(s string) error {
+func (p CurrPath) WriteString(s string) error {
return ioutil.WriteFile(string(p), []byte(s), 0666)
}
+
+// PkgsrcPath is a path relative to the pkgsrc root.
+type PkgsrcPath string
+
+func NewPkgsrcPath(p Path) PkgsrcPath { return PkgsrcPath(p) }
+
+func (p PkgsrcPath) String() string { return string(p) }
+
+func (p PkgsrcPath) AsPath() Path { return NewPath(string(p)) }
+
+func (p PkgsrcPath) DirClean() PkgsrcPath {
+ return NewPkgsrcPath(p.AsPath().DirClean())
+}
+
+func (p PkgsrcPath) DirNoClean() PkgsrcPath {
+ return NewPkgsrcPath(p.AsPath().DirNoClean())
+}
+
+func (p PkgsrcPath) Base() string { return p.AsPath().Base() }
+
+func (p PkgsrcPath) Count() int { return p.AsPath().Count() }
+
+func (p PkgsrcPath) HasPrefixPath(prefix Path) bool {
+ return p.AsPath().HasPrefixPath(prefix)
+}
+
+func (p PkgsrcPath) JoinNoClean(other Path) PkgsrcPath {
+ return NewPkgsrcPath(p.AsPath().JoinNoClean(other))
+}
+
+func (p PkgsrcPath) JoinRel(other RelPath) PkgsrcPath {
+ return p.JoinNoClean(other.AsPath())
+}
+
+// PackagePath is a path relative to the package directory. It is used
+// for the PATCHDIR and PKGDIR variables, as well as dependencies and
+// conflicts on other packages.
+type PackagePath string
+
+func NewPackagePath(p Path) PackagePath { return PackagePath(p) }
+
+func (p PackagePath) AsPath() Path { return Path(p) }
+
+func (p PackagePath) String() string { return p.AsPath().String() }
+
+// TODO: try RelPath instead of Path
+func (p PackagePath) JoinNoClean(other Path) PackagePath {
+ return NewPackagePath(p.AsPath().JoinNoClean(other))
+}
+
+func (p PackagePath) IsEmpty() bool { return p.AsPath().IsEmpty() }
+
+// RelPath is a path that is relative to some base directory that is not
+// further specified.
+type RelPath string
+
+func NewRelPath(p Path) RelPath { return RelPath(p) }
+
+func NewRelPathString(p string) RelPath { return RelPath(p) }
+
+func (p RelPath) AsPath() Path { return NewPath(string(p)) }
+
+func (p RelPath) String() string { return p.AsPath().String() }
+
+func (p RelPath) DirClean() RelPath { return RelPath(p.AsPath().DirClean()) }
+
+func (p RelPath) DirNoClean() RelPath {
+ return RelPath(p.AsPath().DirNoClean())
+}
+
+func (p RelPath) Base() string { return p.AsPath().Base() }
+
+func (p RelPath) HasBase(base string) bool { return p.AsPath().HasBase(base) }
+
+func (p RelPath) Parts() []string { return p.AsPath().Parts() }
+
+func (p RelPath) Count() int { return p.AsPath().Count() }
+
+func (p RelPath) Clean() RelPath { return NewRelPath(p.AsPath().Clean()) }
+
+func (p RelPath) CleanPath() RelPath {
+ return RelPath(p.AsPath().CleanPath())
+}
+
+func (p RelPath) JoinNoClean(other Path) RelPath {
+ return RelPath(p.AsPath().JoinNoClean(other))
+}
+
+func (p RelPath) Replace(from string, to string) RelPath {
+ return RelPath(p.AsPath().Replace(from, to))
+}
+
+func (p RelPath) HasPrefixPath(prefix Path) bool {
+ return p.AsPath().HasPrefixPath(prefix)
+}
+
+func (p RelPath) ContainsPath(sub Path) bool {
+ return p.AsPath().ContainsPath(sub)
+}
+
+func (p RelPath) ContainsText(text string) bool {
+ return p.AsPath().ContainsText(text)
+}
+
+func (p RelPath) HasSuffixPath(suffix Path) bool {
+ return p.AsPath().HasSuffixPath(suffix)
+}
Index: pkgsrc/pkgtools/pkglint/files/path_test.go
diff -u pkgsrc/pkgtools/pkglint/files/path_test.go:1.3 pkgsrc/pkgtools/pkglint/files/path_test.go:1.4
--- pkgsrc/pkgtools/pkglint/files/path_test.go:1.3 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/path_test.go Mon Dec 2 23:32:09 2019
@@ -16,17 +16,6 @@ func (s *Suite) Test_NewPath(c *check.C)
c.Check(NewPath("\\"), check.Not(check.Equals), NewPath("/"))
}
-func (s *Suite) Test_NewPathSlash(c *check.C) {
- t := s.Init(c)
-
- t.CheckEquals(NewPathSlash("filename"), NewPathSlash("filename"))
- t.CheckEquals(NewPathSlash("\\"), NewPathSlash("\\"))
-
- t.CheckEquals(
- NewPathSlash("\\"),
- NewPathSlash(condStr(runtime.GOOS == "windows", "/", "\\")))
-}
-
func (s *Suite) Test_Path_String(c *check.C) {
t := s.Init(c)
@@ -60,11 +49,29 @@ func (s *Suite) Test_Path_IsEmpty(c *che
test("/", false)
}
-func (s *Suite) Test_Path_Dir(c *check.C) {
+func (s *Suite) Test_Path_DirClean(c *check.C) {
t := s.Init(c)
test := func(p, dir Path) {
- t.CheckEquals(p.Dir(), dir)
+ t.CheckEquals(p.DirClean(), dir)
+ }
+
+ test("", ".")
+ test("././././", ".")
+ test("/root", "/")
+ test("filename", ".")
+ test("dir/filename", "dir")
+ test("dir/filename\\with\\backslash", "dir")
+
+ // TODO: I didn't expect that Dir would return the cleaned path.
+ test("././././dir/filename", "dir")
+}
+
+func (s *Suite) Test_Path_DirNoClean(c *check.C) {
+ t := s.Init(c)
+
+ test := func(p, dir Path) {
+ t.CheckEquals(p.DirNoClean(), dir)
}
test("", ".")
@@ -294,32 +301,6 @@ func (s *Suite) Test_Path_ContainsPath(c
test("aa/bb/cc", "c", false)
}
-func (s *Suite) Test_Path_ContainsPathCanonical(c *check.C) {
- t := s.Init(c)
-
- test := func(p, sub Path, contains bool) {
- t.CheckEquals(p.ContainsPathCanonical(sub), contains)
- }
-
- test("", "", false)
- test(".", "", false)
- test("filename", "", false)
- test("filename", "filename", true)
- test("a/b/c", "a", true)
- test("a/b/c", "b", true)
- test("a/b/c", "c", true)
- test("a/b/c", "a/b", true)
- test("a/b/c", "b/c", true)
- test("a/b/c", "a/b/c", true)
- test("aa/b/c", "a", false)
- test("a/bb/c", "b", false)
- test("a/bb/c", "b/c", false)
- test("mk/fetch/fetch.mk", "mk", true)
- test("category/package/../../wip/mk", "mk", true)
- test("category/package/../../wip/mk/..", "mk", true) // FIXME
- test("category/package/../../wip/mk/../..", "mk", false)
-}
-
func (s *Suite) Test_Path_HasSuffixText(c *check.C) {
t := s.Init(c)
@@ -444,6 +425,61 @@ func (s *Suite) Test_Path_CleanDot(c *ch
test("/absolute", "/absolute")
test("/usr/pkgsrc/wip/package", "/usr/pkgsrc/wip/package")
test("/usr/pkgsrc/wip/package/../mk/git-package.mk", "/usr/pkgsrc/wip/package/../mk/git-package.mk")
+ test("a//b", "a/b")
+}
+
+func (s *Suite) Test_Path_CleanPath(c *check.C) {
+ t := s.Init(c)
+
+ test := func(from, to Path) {
+ t.CheckEquals(from.CleanPath(), to)
+ }
+
+ test("simple/path", "simple/path")
+ test("/absolute/path", "/absolute/path")
+
+ // Single dot components are removed, unless it's the only component of the path.
+ test("./././.", ".")
+ test("./././", ".")
+ test("dir/multi/././/file", "dir/multi/file")
+ test("dir/", "dir")
+
+ test("dir/", "dir")
+
+ // Components like aa/bb/../.. are removed, but not in the initial part of the path,
+ // and only if they are not followed by another "..".
+ test("dir/../dir/../dir/../dir/subdir/../../Makefile", "dir/../dir/../dir/../Makefile")
+ test("111/222/../../333/444/../../555/666/../../777/888/9", "111/222/../../777/888/9")
+ test("1/2/3/../../4/5/6/../../7/8/9/../../../../10", "1/2/3/../../4/7/8/9/../../../../10")
+ test("cat/pkg.v1/../../cat/pkg.v2/Makefile", "cat/pkg.v1/../../cat/pkg.v2/Makefile")
+ test("aa/../../../../../a/b/c/d", "aa/../../../../../a/b/c/d")
+ test("aa/bb/../../../../a/b/c/d", "aa/bb/../../../../a/b/c/d")
+ test("aa/bb/cc/../../../a/b/c/d", "aa/bb/cc/../../../a/b/c/d")
+ test("aa/bb/cc/dd/../../a/b/c/d", "aa/bb/a/b/c/d")
+ test("aa/bb/cc/dd/ee/../a/b/c/d", "aa/bb/cc/dd/ee/../a/b/c/d")
+ test("../../../../../a/b/c/d", "../../../../../a/b/c/d")
+ test("aa/../../../../a/b/c/d", "aa/../../../../a/b/c/d")
+ test("aa/bb/../../../a/b/c/d", "aa/bb/../../../a/b/c/d")
+ test("aa/bb/cc/../../a/b/c/d", "aa/bb/cc/../../a/b/c/d")
+ test("aa/bb/cc/dd/../a/b/c/d", "aa/bb/cc/dd/../a/b/c/d")
+ test("aa/../cc/../../a/b/c/d", "aa/../cc/../../a/b/c/d")
+
+ // The initial 2 components of the path are typically category/package, when
+ // pkglint is called from the pkgsrc top-level directory.
+ // This path serves as the context and therefore is always kept.
+ test("aa/bb/../../cc/dd/../../ee/ff", "aa/bb/../../ee/ff")
+ test("aa/bb/../../cc/dd/../..", "aa/bb/../..")
+ test("aa/bb/cc/dd/../..", "aa/bb")
+ test("aa/bb/../../cc/dd/../../ee/ff/buildlink3.mk", "aa/bb/../../ee/ff/buildlink3.mk")
+ test("./aa/bb/../../cc/dd/../../ee/ff/buildlink3.mk", "aa/bb/../../ee/ff/buildlink3.mk")
+
+ test("../.", "..")
+ test("../././././././.", "..")
+ test(".././././././././", "..")
+
+ test(
+ "x11/kde-runtime4/../../misc/kdepimlibs4/../../databases/openldap-client/buildlink3.mk",
+ "x11/kde-runtime4/../../databases/openldap-client/buildlink3.mk")
}
func (s *Suite) Test_Path_IsAbs(c *check.C) {
@@ -473,13 +509,332 @@ func (s *Suite) Test_Path_Rel(c *check.C
t.CheckEquals(abc.Rel(base), NewPath("../../../."))
}
-func (s *Suite) Test_Path_Rename(c *check.C) {
+func (s *Suite) Test_NewCurrPath(c *check.C) {
+ t := s.Init(c)
+
+ curr := NewCurrPath("dir/.///file")
+
+ t.CheckEquals(curr.String(), "dir/.///file")
+}
+
+func (s *Suite) Test_NewCurrPathString(c *check.C) {
+ t := s.Init(c)
+
+ curr := NewCurrPathString("dir/.///file")
+
+ t.CheckEquals(curr.String(), "dir/.///file")
+}
+
+func (s *Suite) Test_NewCurrPathSlash(c *check.C) {
+ t := s.Init(c)
+
+ test := func(path, curr string) {
+ t.CheckEquals(NewCurrPathSlash(path).String(), curr)
+ }
+ testWindows := func(path, currWindows, currOther string) {
+ t.CheckEquals(
+ NewCurrPathSlash(path).String(),
+ condStr(runtime.GOOS == "windows", currWindows, currOther))
+ }
+
+ test("filename", "filename")
+ test("dir/.///file", "dir/.///file")
+
+ testWindows("\\", "/", "\\")
+}
+
+func (s *Suite) Test_NewCurrPathSlash__windows(c *check.C) {
+ t := s.Init(c)
+
+ if runtime.GOOS != "windows" {
+ return
+ }
+
+ curr := NewCurrPathSlash("dir\\.\\\\\\file")
+
+ t.CheckEquals(curr.String(), "dir/.///file")
+}
+
+func (s *Suite) Test_CurrPath_GoString(c *check.C) {
+ t := s.Init(c)
+
+ // Tabs in filenames are rare, probably typos.
+ curr := NewCurrPath("dir/file\t")
+
+ t.CheckEquals(curr.GoString(), "\"dir/file\\t\"")
+}
+
+func (s *Suite) Test_CurrPath_String(c *check.C) {
+ t := s.Init(c)
+
+ // Tabs in filenames are rare, probably typos.
+ curr := NewCurrPath("dir/file\t")
+
+ t.CheckEquals(curr.String(), "dir/file\t")
+}
+
+func (s *Suite) Test_CurrPath_AsPath(c *check.C) {
+ t := s.Init(c)
+
+ // Tabs in filenames are rare, probably typos.
+ curr := NewCurrPath("dir/file\t")
+
+ t.CheckEquals(curr.AsPath(), NewPath("dir/file\t"))
+}
+
+func (s *Suite) Test_CurrPath_IsEmpty(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, isEmpty bool) {
+ t.CheckEquals(curr.IsEmpty(), isEmpty)
+ }
+
+ test("", true)
+ test(".", false)
+ test("/", false)
+}
+
+func (s *Suite) Test_CurrPath_DirClean(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr, dir CurrPath) {
+ t.CheckEquals(curr.DirClean(), dir)
+ }
+
+ test("./dir/../dir///./file", "dir")
+}
+
+func (s *Suite) Test_CurrPath_DirNoClean(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr, dir CurrPath) {
+ t.CheckEquals(curr.DirNoClean(), dir)
+ }
+
+ test("./dir/../dir///./file", "./dir/../dir")
+}
+
+func (s *Suite) Test_CurrPath_Base(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, base string) {
+ t.CheckEquals(curr.Base(), base)
+ }
+
+ test("dir/file", "file")
+}
+
+func (s *Suite) Test_CurrPath_Split(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr, dir CurrPath, base string) {
+ actualDir, actualBase := curr.Split()
+ t.CheckEquals(actualDir, dir)
+ t.CheckEquals(actualBase, base)
+ }
+
+ test("dir/file", "dir/", "file")
+}
+
+func (s *Suite) Test_CurrPath_Parts(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, parts ...string) {
+ t.CheckDeepEquals(curr.Parts(), parts)
+ }
+
+ test("dir/file", "dir", "file")
+}
+
+func (s *Suite) Test_CurrPath_IsAbs(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, isAbs bool) {
+ t.CheckDeepEquals(curr.IsAbs(), isAbs)
+ }
+
+ test("/", true)
+ test("./", false)
+ test("C:/", runtime.GOOS == "windows")
+}
+
+func (s *Suite) Test_CurrPath_HasPrefixPath(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr, prefix CurrPath, hasPrefix bool) {
+ t.CheckEquals(curr.HasPrefixPath(prefix), hasPrefix)
+ }
+
+ test("dir/file", "dir", true)
+ test("dir/file", "file", false)
+ test("dir", ".", true)
+}
+
+func (s *Suite) Test_CurrPath_ContainsPath(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, sub Path, hasPrefix bool) {
+ t.CheckEquals(curr.ContainsPath(sub), hasPrefix)
+ }
+
+ test("dir/file", "dir", true)
+ test("dir/file", "file", true)
+ test("dir/file", "fi", false)
+ test("dir", ".", true)
+}
+
+func (s *Suite) Test_CurrPath_ContainsText(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, sub string, hasPrefix bool) {
+ t.CheckEquals(curr.ContainsText(sub), hasPrefix)
+ }
+
+ test("dir/file", "dir", true)
+ test("dir/file", "r/f", true)
+}
+
+func (s *Suite) Test_CurrPath_HasSuffixPath(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, suffix Path, hasPrefix bool) {
+ t.CheckEquals(curr.HasSuffixPath(suffix), hasPrefix)
+ }
+
+ test("dir/file", "dir", false)
+ test("dir/file", "file", true)
+ test("dir/file", "le", false)
+
+ // In contrast to HasPrefixPath, it doesn't really make sense to
+ // ask whether a path ends with the current directory.
+ test("dir", ".", false)
+}
+
+func (s *Suite) Test_CurrPath_HasSuffixText(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, suffix string, hasPrefix bool) {
+ t.CheckEquals(curr.HasSuffixText(suffix), hasPrefix)
+ }
+
+ test("dir/file", "dir", false)
+ test("dir/file", "file", true)
+ test("dir/file", "le", true)
+}
+
+func (s *Suite) Test_CurrPath_HasBase(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, base string, hasPrefix bool) {
+ t.CheckEquals(curr.HasBase(base), hasPrefix)
+ }
+
+ test("dir/file", "dir", false)
+ test("dir/file", "file", true)
+ test("dir/file", "le", false)
+}
+
+func (s *Suite) Test_CurrPath_TrimSuffix(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, suffix string, trimmed CurrPath) {
+ t.CheckEquals(curr.TrimSuffix(suffix), trimmed)
+ }
+
+ test("dir/file", "dir", "dir/file")
+ test("dir/file", "file", "dir/")
+ test("dir/file", "le", "dir/fi")
+}
+
+func (s *Suite) Test_CurrPath_ReplaceSuffix(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, from, to string, replaced CurrPath) {
+ t.CheckEquals(curr.ReplaceSuffix(from, to), replaced)
+ }
+
+ test("dir/file", "file", "subdir", "dir/subdir")
+
+ // The path must actually end with the suffix, otherwise there is
+ // the risk of creating unintended paths.
+ t.ExpectAssert(
+ func() { test("dir/file", "no-match", "anything", "dir/file") })
+}
+
+func (s *Suite) Test_CurrPath_Clean(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr, cleaned CurrPath) {
+ t.CheckEquals(curr.Clean(), cleaned)
+ }
+
+ test("dir/file", "dir/file")
+ test("dir/.////../file", "file")
+}
+
+func (s *Suite) Test_CurrPath_CleanDot(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr, cleaned CurrPath) {
+ t.CheckEquals(curr.CleanDot(), cleaned)
+ }
+
+ test("dir/file", "dir/file")
+ test("dir/.////../file", "dir/../file")
+}
+
+func (s *Suite) Test_CurrPath_CleanPath(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr, cleaned CurrPath) {
+ t.CheckEquals(curr.CleanPath(), cleaned)
+ }
+
+ test("a/b/../../c/d/../../e/../f", "a/b/../../e/../f")
+}
+
+func (s *Suite) Test_CurrPath_JoinNoClean(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, other Path, joined CurrPath) {
+ t.CheckEquals(curr.JoinNoClean(other), joined)
+ }
+
+ test("", "", "/")
+ test(".", "file", "./file")
+ test("dir", "subdir/file", "dir/subdir/file")
+}
+
+func (s *Suite) Test_CurrPath_JoinClean(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr CurrPath, other Path, joined CurrPath) {
+ t.CheckEquals(curr.JoinClean(other), joined)
+ }
+
+ test("", "", "")
+ test(".", "./////file", "file")
+ test("dir/./.", "../subdir/file", "subdir/file")
+}
+
+func (s *Suite) Test_CurrPath_Rel(c *check.C) {
+ t := s.Init(c)
+
+ test := func(curr, suffix CurrPath, rel Path) {
+ t.CheckEquals(curr.Rel(suffix), rel)
+ }
+
+ test("dir/subdir", "dir", "..")
+ test("dir/subdir", "file", "../../file")
+}
+
+func (s *Suite) Test_CurrPath_Rename(c *check.C) {
t := s.Init(c)
f := t.CreateFileLines("filename.old",
"line 1")
t.CheckEquals(f.IsFile(), true)
- dst := NewPath(f.TrimSuffix(".old").String() + ".new")
+ dst := f.ReplaceSuffix(".old", ".new")
err := f.Rename(dst)
@@ -489,10 +844,10 @@ func (s *Suite) Test_Path_Rename(c *chec
"line 1")
}
-func (s *Suite) Test_Path_Lstat(c *check.C) {
+func (s *Suite) Test_CurrPath_Lstat(c *check.C) {
t := s.Init(c)
- testDir := func(f Path, isDir bool) {
+ testDir := func(f CurrPath, isDir bool) {
st, err := f.Lstat()
assertNil(err, "Lstat")
t.CheckEquals(st.Mode()&os.ModeDir != 0, isDir)
@@ -505,10 +860,10 @@ func (s *Suite) Test_Path_Lstat(c *check
testDir(t.File("file"), false)
}
-func (s *Suite) Test_Path_Stat(c *check.C) {
+func (s *Suite) Test_CurrPath_Stat(c *check.C) {
t := s.Init(c)
- testDir := func(f Path, isDir bool) {
+ testDir := func(f CurrPath, isDir bool) {
st, err := f.Stat()
assertNil(err, "Stat")
t.CheckEquals(st.Mode()&os.ModeDir != 0, isDir)
@@ -521,10 +876,10 @@ func (s *Suite) Test_Path_Stat(c *check.
testDir(t.File("file"), false)
}
-func (s *Suite) Test_Path_Exists(c *check.C) {
+func (s *Suite) Test_CurrPath_Exists(c *check.C) {
t := s.Init(c)
- test := func(f Path, exists bool) {
+ test := func(f CurrPath, exists bool) {
t.CheckEquals(f.Exists(), exists)
}
@@ -536,7 +891,7 @@ func (s *Suite) Test_Path_Exists(c *chec
test(t.File("enoent"), false)
}
-func (s *Suite) Test_Path_IsFile(c *check.C) {
+func (s *Suite) Test_CurrPath_IsFile(c *check.C) {
t := s.Init(c)
t.CreateFileLines("dir/file")
@@ -547,7 +902,7 @@ func (s *Suite) Test_Path_IsFile(c *chec
t.CheckEquals(t.File("dir/file").IsFile(), true)
}
-func (s *Suite) Test_Path_IsDir(c *check.C) {
+func (s *Suite) Test_CurrPath_IsDir(c *check.C) {
t := s.Init(c)
t.CreateFileLines("dir/file")
@@ -558,10 +913,10 @@ func (s *Suite) Test_Path_IsDir(c *check
t.CheckEquals(t.File("dir/file").IsDir(), false)
}
-func (s *Suite) Test_Path_Chmod(c *check.C) {
+func (s *Suite) Test_CurrPath_Chmod(c *check.C) {
t := s.Init(c)
- testWritable := func(f Path, writable bool) {
+ testWritable := func(f CurrPath, writable bool) {
lstat, err := f.Lstat()
assertNil(err, "Lstat")
t.CheckEquals(lstat.Mode().Perm()&0200 != 0, writable)
@@ -576,7 +931,7 @@ func (s *Suite) Test_Path_Chmod(c *check
testWritable(f, false)
}
-func (s *Suite) Test_Path_ReadDir(c *check.C) {
+func (s *Suite) Test_CurrPath_ReadDir(c *check.C) {
t := s.Init(c)
t.CreateFileLines("subdir/file")
@@ -595,7 +950,23 @@ func (s *Suite) Test_Path_ReadDir(c *che
t.CheckDeepEquals(names, []string{".git", "CVS", "file", "subdir"})
}
-func (s *Suite) Test_Path_Open(c *check.C) {
+func (s *Suite) Test_CurrPath_ReadPaths(c *check.C) {
+ t := s.Init(c)
+
+ t.CreateFileLines("dir/subdir/file")
+ t.CreateFileLines("dir/CVS/Entries")
+ t.CreateFileLines("dir/file")
+
+ p := t.File("dir")
+
+ paths := p.ReadPaths()
+
+ t.CheckDeepEquals(paths, []CurrPath{
+ t.File("dir/file"),
+ t.File("dir/subdir")})
+}
+
+func (s *Suite) Test_CurrPath_Open(c *check.C) {
t := s.Init(c)
t.CreateFileLines("filename",
@@ -613,7 +984,7 @@ func (s *Suite) Test_Path_Open(c *check.
t.CheckEquals(sb.String(), "line 1\nline 2\n")
}
-func (s *Suite) Test_Path_ReadString(c *check.C) {
+func (s *Suite) Test_CurrPath_ReadString(c *check.C) {
t := s.Init(c)
t.CreateFileLines("filename",
@@ -626,7 +997,7 @@ func (s *Suite) Test_Path_ReadString(c *
t.CheckEquals(text, "line 1\nline 2\n")
}
-func (s *Suite) Test_Path_WriteString(c *check.C) {
+func (s *Suite) Test_CurrPath_WriteString(c *check.C) {
t := s.Init(c)
err := t.File("filename").WriteString("line 1\nline 2\n")
@@ -636,3 +1007,331 @@ func (s *Suite) Test_Path_WriteString(c
"line 1",
"line 2")
}
+
+func (s *Suite) Test_NewPkgsrcPath(c *check.C) {
+ t := s.Init(c)
+
+ p := NewPkgsrcPath("category/package")
+
+ t.CheckEquals(p.AsPath(), NewPath("category/package"))
+}
+
+func (s *Suite) Test_PkgsrcPath_String(c *check.C) {
+ t := s.Init(c)
+
+ p := NewPkgsrcPath("any string..././")
+
+ str := p.String()
+
+ // No normalization takes place because it is typically not needed.
+ t.CheckEquals(str, "any string..././")
+}
+
+func (s *Suite) Test_PkgsrcPath_AsPath(c *check.C) {
+ t := s.Init(c)
+
+ pp := NewPkgsrcPath("./category/package/Makefile")
+
+ p := pp.AsPath()
+
+ t.CheckEquals(p.String(), "./category/package/Makefile")
+}
+
+func (s *Suite) Test_PkgsrcPath_DirClean(c *check.C) {
+ t := s.Init(c)
+
+ pp := NewPkgsrcPath("./dir/../dir/base///.")
+
+ dir := pp.DirClean()
+
+ t.CheckEquals(dir, NewPkgsrcPath("dir/base"))
+}
+
+func (s *Suite) Test_PkgsrcPath_DirNoClean(c *check.C) {
+ t := s.Init(c)
+
+ pp := NewPkgsrcPath("./dir/../dir/base///.")
+
+ dir := pp.DirNoClean()
+
+ t.CheckEquals(dir, NewPkgsrcPath("./dir/../dir/base"))
+}
+
+func (s *Suite) Test_PkgsrcPath_Base(c *check.C) {
+ t := s.Init(c)
+
+ pp := NewPkgsrcPath("dir/base///.")
+
+ base := pp.Base()
+
+ t.CheckEquals(base, ".")
+}
+
+func (s *Suite) Test_PkgsrcPath_Count(c *check.C) {
+ t := s.Init(c)
+
+ pp := NewPkgsrcPath("./...////dir")
+
+ count := pp.Count()
+
+ t.CheckEquals(count, 2)
+}
+
+func (s *Suite) Test_PkgsrcPath_HasPrefixPath(c *check.C) {
+ t := s.Init(c)
+
+ pp := NewPkgsrcPath("./././///prefix/suffix")
+
+ hasPrefixPath := pp.HasPrefixPath("prefix")
+
+ t.CheckEquals(hasPrefixPath, true)
+}
+
+func (s *Suite) Test_PkgsrcPath_JoinNoClean(c *check.C) {
+ t := s.Init(c)
+
+ pp := NewPkgsrcPath("base///.")
+
+ joined := pp.JoinNoClean("./../rel")
+
+ t.CheckEquals(joined, NewPkgsrcPath("base///././../rel"))
+}
+
+func (s *Suite) Test_PkgsrcPath_JoinRel(c *check.C) {
+ t := s.Init(c)
+
+ pp := NewPkgsrcPath("base///.")
+
+ joined := pp.JoinRel("./../rel")
+
+ t.CheckEquals(joined, NewPkgsrcPath("base///././../rel"))
+}
+
+func (s *Suite) Test_NewPackagePath(c *check.C) {
+ t := s.Init(c)
+
+ p := NewPackagePath("../../category/package")
+
+ t.CheckEquals(p.AsPath(), NewPath("../../category/package"))
+}
+
+func (s *Suite) Test_PackagePath_AsPath(c *check.C) {
+ t := s.Init(c)
+
+ pp := NewPackagePath("../../category/package/Makefile")
+
+ p := pp.AsPath()
+
+ t.CheckEquals(p.String(), "../../category/package/Makefile")
+}
+
+func (s *Suite) Test_PackagePath_String(c *check.C) {
+ t := s.Init(c)
+
+ pp := NewPackagePath("../../category/package/Makefile")
+
+ str := pp.String()
+
+ t.CheckEquals(str, "../../category/package/Makefile")
+}
+
+func (s *Suite) Test_PackagePath_JoinNoClean(c *check.C) {
+ t := s.Init(c)
+
+ pp := NewPackagePath("../../category/package/Makefile")
+
+ p := pp.JoinNoClean("patches")
+
+ t.CheckEquals(p.String(), "../../category/package/Makefile/patches")
+}
+
+func (s *Suite) Test_PackagePath_IsEmpty(c *check.C) {
+ t := s.Init(c)
+
+ test := func(p PackagePath, isEmpty bool) {
+ t.CheckEquals(p.IsEmpty(), isEmpty)
+ }
+
+ test("", true)
+ test(".", false)
+}
+
+func (s *Suite) Test_NewRelPath(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("dir/file")
+
+ t.CheckEquals(rel.String(), "dir/file")
+}
+
+func (s *Suite) Test_NewRelPathString(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPathString("dir/file")
+
+ t.CheckEquals(rel.String(), "dir/file")
+}
+
+func (s *Suite) Test_RelPath_AsPath(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("relative")
+
+ path := rel.AsPath()
+
+ t.CheckEquals(path.String(), "relative")
+}
+
+func (s *Suite) Test_RelPath_String(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath(".///rel")
+
+ str := rel.String()
+
+ t.CheckEquals(str, ".///rel")
+}
+
+func (s *Suite) Test_RelPath_DirClean(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("./dir/../dir///./file")
+
+ dir := rel.DirClean()
+
+ t.CheckEquals(dir, NewRelPath("dir"))
+}
+
+func (s *Suite) Test_RelPath_DirNoClean(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("./dir/../dir///./file")
+
+ dir := rel.DirNoClean()
+
+ t.CheckEquals(dir, NewRelPath("./dir/../dir"))
+}
+
+func (s *Suite) Test_RelPath_Base(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("./dir////./file")
+
+ base := rel.Base()
+
+ t.CheckEquals(base, "file")
+}
+
+func (s *Suite) Test_RelPath_HasBase(c *check.C) {
+ t := s.Init(c)
+
+ test := func(rel RelPath, base string, hasBase bool) {
+ t.CheckEquals(rel.HasBase(base), hasBase)
+ }
+
+ test("./dir/Makefile", "Makefile", true)
+ test("./dir/Makefile", "Make", false)
+ test("./dir/Makefile", "file", false)
+ test("./dir/Makefile", "dir/Makefile", false)
+}
+
+func (s *Suite) Test_RelPath_Parts(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("./dir/.///base")
+
+ parts := rel.Parts()
+
+ t.CheckDeepEquals(parts, []string{"dir", "base"})
+}
+
+func (s *Suite) Test_RelPath_Count(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("./dir/.///base")
+
+ count := rel.Count()
+
+ t.CheckDeepEquals(count, 2)
+}
+
+func (s *Suite) Test_RelPath_Clean(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("a/b/../../c/d/../../e/../f")
+
+ cleaned := rel.Clean()
+
+ t.CheckEquals(cleaned, NewRelPath("f"))
+}
+
+func (s *Suite) Test_RelPath_CleanPath(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("a/b/../../c/d/../../e/../f")
+
+ cleaned := rel.CleanPath()
+
+ t.CheckEquals(cleaned, NewRelPath("a/b/../../e/../f"))
+}
+
+func (s *Suite) Test_RelPath_JoinNoClean(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("basedir/.//")
+
+ joined := rel.JoinNoClean("./other")
+
+ t.CheckEquals(joined, NewRelPath("basedir/.///./other"))
+}
+
+func (s *Suite) Test_RelPath_Replace(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("dir/subdir/file")
+
+ replaced := rel.Replace("/", ":")
+
+ t.CheckEquals(replaced, NewRelPath("dir:subdir:file"))
+}
+
+func (s *Suite) Test_RelPath_HasPrefixPath(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("dir/subdir/file")
+
+ t.CheckEquals(rel.HasPrefixPath("dir"), true)
+ t.CheckEquals(rel.HasPrefixPath("dir/sub"), false)
+ t.CheckEquals(rel.HasPrefixPath("subdir"), false)
+}
+
+func (s *Suite) Test_RelPath_ContainsPath(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("dir/subdir/file")
+
+ t.CheckEquals(rel.ContainsPath("dir"), true)
+ t.CheckEquals(rel.ContainsPath("dir/sub"), false)
+ t.CheckEquals(rel.ContainsPath("subdir"), true)
+}
+
+func (s *Suite) Test_RelPath_ContainsText(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("dir/subdir/file")
+
+ t.CheckEquals(rel.ContainsText("dir"), true)
+ t.CheckEquals(rel.ContainsText("dir/sub"), true)
+ t.CheckEquals(rel.ContainsText("subdir"), true)
+ t.CheckEquals(rel.ContainsText("super"), false)
+}
+
+func (s *Suite) Test_RelPath_HasSuffixPath(c *check.C) {
+ t := s.Init(c)
+
+ rel := NewRelPath("dir/subdir/file")
+
+ t.CheckEquals(rel.HasSuffixPath("file"), true)
+ t.CheckEquals(rel.HasSuffixPath("subdir/file"), true)
+ t.CheckEquals(rel.HasSuffixPath("subdir"), false)
+}
Index: pkgsrc/pkgtools/pkglint/files/pkglint.0
diff -u pkgsrc/pkgtools/pkglint/files/pkglint.0:1.41 pkgsrc/pkgtools/pkglint/files/pkglint.0:1.42
--- pkgsrc/pkgtools/pkglint/files/pkglint.0:1.41 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/pkglint.0 Mon Dec 2 23:32:09 2019
@@ -79,8 +79,6 @@ DDEESSCCRRIIPPTTIIOONN
[[nnoo‐‐]]qquuoottiinngg Warn for possibly invalid quoting of make variables
in shell programs and shell variables themselves.
- [[nnoo‐‐]]ssppaaccee Emit notes for inconsistent use of whitespace.
-
OOtthheerr aarrgguummeennttss
_d_i_r _._._. The pkgsrc directories to be checked. If omit‐
ted, the current directory is checked.
Index: pkgsrc/pkgtools/pkglint/files/pkglint.1
diff -u pkgsrc/pkgtools/pkglint/files/pkglint.1:1.58 pkgsrc/pkgtools/pkglint/files/pkglint.1:1.59
--- pkgsrc/pkgtools/pkglint/files/pkglint.1:1.58 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/pkglint.1 Mon Dec 2 23:32:09 2019
@@ -1,4 +1,4 @@
-.\" $NetBSD: pkglint.1,v 1.58 2019/11/30 20:35:11 rillig Exp $
+.\" $NetBSD: pkglint.1,v 1.59 2019/12/02 23:32:09 rillig Exp $
.\" From FreeBSD: portlint.1,v 1.8 1997/11/25 14:53:14 itojun Exp
.\"
.\" Copyright (c) 1997 by Jun-ichiro Itoh <itojun%itojun.org@localhost>.
@@ -105,8 +105,6 @@ Warn if a variable is used or modified o
.It Cm [no-]quoting
Warn for possibly invalid quoting of make variables in shell programs
and shell variables themselves.
-.It Cm [no-]space
-Emit notes for inconsistent use of whitespace.
.El
.\" =======================================================================
.Ss Other arguments
Index: pkgsrc/pkgtools/pkglint/files/shell_test.go
diff -u pkgsrc/pkgtools/pkglint/files/shell_test.go:1.58 pkgsrc/pkgtools/pkglint/files/shell_test.go:1.59
--- pkgsrc/pkgtools/pkglint/files/shell_test.go:1.58 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/shell_test.go Mon Dec 2 23:32:09 2019
@@ -344,55 +344,6 @@ func (s *Suite) Test_SimpleCommandChecke
"WARN: Makefile:4: Please use ${ECHO_N} instead of \"echo -n\".")
}
-func (s *Suite) Test_ShellLineChecker__shell_comment_with_line_continuation(c *check.C) {
- t := s.Init(c)
-
- t.SetUpTool("echo", "", AtRunTime)
-
- test := func(lines ...string) {
- i := 0
- for ; i < len(lines) && hasPrefix(lines[i], "\t"); i++ {
- }
-
- mklines := t.SetUpFileMkLines("Makefile",
- append([]string{MkCvsID, "pre-install:"},
- lines[:i]...)...)
-
- mklines.Check()
-
- t.CheckOutput(lines[i:])
- }
-
- // The comment can start at the beginning of a follow-up line.
- test(
- "\techo first; \\",
- "\t# comment at the beginning of a command \\",
- "\techo \"hello\"",
-
- // TODO: Warn that the "echo hello" is commented out.
- )
-
- // The comment can start at the beginning of a simple command.
- test(
- "\techo first; # comment at the beginning of a command \\",
- "\techo \"hello\"",
-
- // TODO: Warn that the "echo hello" is commented out.
- )
-
- // The comment can start at a word in the middle of a command.
- test(
- // TODO: Warn that the "echo hello" is commented out.
- "\techo # comment starts inside a command \\",
- "\techo \"hello\"")
-
- // If the comment starts in the last line, there's no further
- // line that might be commented out accidentally.
- test(
- "\techo 'first line'; \\",
- "\t# comment in last line")
-}
-
func (s *Suite) Test_ShellLineChecker_checkConditionalCd(c *check.C) {
t := s.Init(c)
@@ -946,6 +897,55 @@ func (s *Suite) Test_ShellLineChecker_Ch
"NOTE: filename.mk:1: Please use the SUBST framework instead of ${SED} and ${MV}.")
}
+func (s *Suite) Test_ShellLineChecker_CheckShellCommandLine__sed_and_mv_explained(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpCommandLine("-Wall", "--explain")
+ t.SetUpVartypes()
+ t.SetUpTool("sed", "SED", AtRunTime)
+ t.SetUpTool("mv", "MV", AtRunTime)
+ ck := t.NewShellLineChecker("\t${RUN} ${SED} 's,#,// comment:,g' filename > filename.tmp; ${MV} filename.tmp filename")
+
+ ck.CheckShellCommandLine(ck.mkline.ShellCommand())
+
+ t.CheckOutputLines(
+ "NOTE: filename.mk:1: Please use the SUBST framework instead of ${SED} and ${MV}.",
+ "",
+ "\tUsing the SUBST framework instead of explicit commands is easier to",
+ "\tunderstand, since all the complexity of using sed and mv is hidden",
+ "\tbehind the scenes.",
+ "",
+ sprintf("\tRun %q for more information.", bmakeHelp("subst")),
+ "",
+ "\tWhen migrating to the SUBST framework, pay attention to \"#\"",
+ "\tcharacters. In shell commands, make(1) does not interpret them as",
+ "\tcomment character, but in variable assignments it does. Therefore,",
+ "\tinstead of the shell command",
+ "",
+ "\t\tsed -e 's,#define foo,,'",
+ "",
+ "\tyou need to write",
+ "",
+ "\t\tSUBST_SED.foo+=\t's,\\#define foo,,'",
+ "")
+}
+
+func (s *Suite) Test_ShellLineChecker_CheckShellCommandLine__sed_and_mv_autofix_explained(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpCommandLine("-Wall", "--explain", "--autofix")
+ t.SetUpVartypes()
+ t.SetUpTool("sed", "SED", AtRunTime)
+ t.SetUpTool("mv", "MV", AtRunTime)
+ ck := t.NewShellLineChecker("\t${RUN} ${SED} 's,#,// comment:,g' filename > filename.tmp; ${MV} filename.tmp filename")
+
+ ck.CheckShellCommandLine(ck.mkline.ShellCommand())
+
+ // Only ever output an explanation if there's a corresponding diagnostic.
+ // Even if Explain is called twice in a row.
+ t.CheckOutputEmpty()
+}
+
func (s *Suite) Test_ShellLineChecker_CheckShellCommandLine__subshell(c *check.C) {
t := s.Init(c)
@@ -1558,6 +1558,74 @@ func (s *Suite) Test_ShellLineChecker_ch
"WARN: filename.mk:1: ${CP} should not be used to install files.")
}
+func (s *Suite) Test_ShellLineChecker_checkMultiLineComment(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpTool("echo", "", AtRunTime)
+ t.SetUpTool("sed", "", AtRunTime)
+ t.SetUpVartypes()
+
+ test := func(lines ...string) {
+ i := 0
+ for ; i < len(lines) && hasPrefix(lines[i], "\t"); i++ {
+ }
+
+ mklines := t.SetUpFileMkLines("Makefile",
+ append([]string{MkCvsID, "pre-build:"},
+ lines[:i]...)...)
+
+ mklines.Check()
+
+ t.CheckOutput(lines[i:])
+ }
+
+ // The comment can start at the beginning of a follow-up line.
+ test(
+ "\techo first; \\",
+ "\t# comment at the beginning of a command \\",
+ "\techo \"hello\"",
+
+ "WARN: ~/Makefile:4: "+
+ "The shell comment does not stop at the end of this line.")
+
+ // The comment can start at the beginning of a simple command.
+ test(
+ "\techo first; # comment at the beginning of a command \\",
+ "\techo \"hello\"",
+
+ "WARN: ~/Makefile:3: "+
+ "The shell comment does not stop at the end of this line.")
+
+ // The comment can start at a word in the middle of a command.
+ test(
+ "\techo # comment starts inside a command \\",
+ "\techo \"hello\"",
+
+ "WARN: ~/Makefile:3: "+
+ "The shell comment does not stop at the end of this line.")
+
+ // If the comment starts in the last line, there's no further
+ // line that might be commented out accidentally.
+ test(
+ "\techo 'first line'; \\",
+ "\t# comment in last line")
+
+ // If there's a shell token that extends over several lines,
+ // that's unusual enough that pkglint refuses to check this.
+ test(
+ "\techo 'before \\",
+ "\t\tafter'; \\",
+ "\t# comment \\",
+ "\techo 'still a comment'")
+
+ test(
+ "\tsed -e s#@PREFIX@#${PREFIX}#g \\",
+ "\tfilename",
+
+ "WARN: ~/Makefile:3--4: Substitution commands like "+
+ "\"s#@PREFIX@#${PREFIX}#g\" should always be quoted.")
+}
+
func (s *Suite) Test_splitIntoShellTokens__line_continuation(c *check.C) {
t := s.Init(c)
@@ -1713,3 +1781,24 @@ func (s *Suite) Test_splitIntoShellToken
">>", "append"})
t.CheckEquals(rest, "")
}
+
+func (s *Suite) Test_splitIntoShellTokens__varuse(c *check.C) {
+ t := s.Init(c)
+
+ test := func(text string, tokens ...string) {
+ line := t.NewLine("filename.mk", 1, "")
+
+ words, rest := splitIntoShellTokens(line, text)
+
+ t.CheckDeepEquals(words, tokens)
+ t.CheckEquals(rest, "")
+ }
+
+ test(
+ "sed -e s#@PREFIX@#${PREFIX}#g filename",
+
+ "sed",
+ "-e",
+ "s#@PREFIX@#${PREFIX}#g",
+ "filename")
+}
Index: pkgsrc/pkgtools/pkglint/files/pkglint.go
diff -u pkgsrc/pkgtools/pkglint/files/pkglint.go:1.67 pkgsrc/pkgtools/pkglint/files/pkglint.go:1.68
--- pkgsrc/pkgtools/pkglint/files/pkglint.go:1.67 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/pkglint.go Mon Dec 2 23:32:09 2019
@@ -25,14 +25,15 @@ type Pkglint struct {
Pkgsrc Pkgsrc // Global data, mostly extracted from mk/*.
Pkg *Package // The package that is currently checked, or nil.
- Todo PathQueue // The files or directories that still need to be checked.
- Wip bool // Is the currently checked file or package from pkgsrc-wip?
- Infrastructure bool // Is the currently checked file from the pkgsrc infrastructure?
- Testing bool // Is pkglint in self-testing mode (only during development)?
- Experimental bool // For experimental features, only enabled individually in tests
- Username string // For checking against OWNER and MAINTAINER
+ Todo CurrPathQueue // The files or directories that still need to be checked.
- cvsEntriesDir Path // Cached to avoid I/O
+ Wip bool // Is the currently checked file or package from pkgsrc-wip?
+ Infrastructure bool // Is the currently checked file from the pkgsrc infrastructure?
+ Testing bool // Is pkglint in self-testing mode (only during development)?
+ Experimental bool // For experimental features, only enabled individually in tests
+ Username string // For checking against OWNER and MAINTAINER
+
+ cvsEntriesDir CurrPath // Cached to avoid I/O
cvsEntries map[string]CvsEntry
Logger Logger
@@ -45,7 +46,7 @@ type Pkglint struct {
// cwd is the absolute path to the current working
// directory. It is used for speeding up Relpath and abspath.
// There is no other use for it.
- cwd Path
+ cwd CurrPath
InterPackage InterPackage
}
@@ -57,7 +58,7 @@ func NewPkglint(stdout io.Writer, stderr
p := Pkglint{
res: regex.NewRegistry(),
fileCache: NewFileCache(200),
- cwd: NewPathSlash(cwd),
+ cwd: NewCurrPathSlash(cwd),
interner: NewStringInterner()}
p.Logger.out = NewSeparatorWriter(stdout)
p.Logger.err = NewSeparatorWriter(stderr)
@@ -71,17 +72,9 @@ func unusablePkglint() Pkglint { return
type CmdOpts struct {
CheckGlobal bool
- // TODO: Are these Warn* options really all necessary?
- //
- // Some of them may have been unreliable in the past when they were new.
- // Instead of these fine-grained options, there is already --only, which
- // could be contrasted by a future --ignore option, in order to suppress
- // individual checks.
-
WarnExtra,
WarnPerm,
- WarnQuoting,
- WarnSpace bool
+ WarnQuoting bool
Profiling,
ShowHelp,
@@ -208,11 +201,12 @@ func (pkglint *Pkglint) setUpProfiling()
func (pkglint *Pkglint) prepareMainLoop() {
firstDir := pkglint.Todo.Front()
if firstDir.IsFile() {
- firstDir = firstDir.Dir()
+ // FIXME: consider DirNoClean
+ firstDir = firstDir.DirClean()
}
relTopdir := findPkgsrcTopdir(firstDir)
- if relTopdir == "" {
+ if relTopdir.IsEmpty() {
// If the first argument to pkglint is not inside a pkgsrc tree,
// pkglint doesn't know where to load the infrastructure files from,
// and these are needed for virtually every single check.
@@ -257,7 +251,6 @@ func (pkglint *Pkglint) ParseCommandLine
warn.AddFlagVar("extra", &gopts.WarnExtra, false, "enable some extra warnings")
warn.AddFlagVar("perm", &gopts.WarnPerm, false, "warn about unforeseen variable definition and use")
warn.AddFlagVar("quoting", &gopts.WarnQuoting, false, "warn about quoting issues")
- warn.AddFlagVar("space", &gopts.WarnSpace, false, "warn about inconsistent use of whitespace")
remainingArgs, err := opts.Parse(args)
if err != nil {
@@ -280,7 +273,7 @@ func (pkglint *Pkglint) ParseCommandLine
}
for _, arg := range pkglint.Opts.args {
- pkglint.Todo.Push(NewPathSlash(arg))
+ pkglint.Todo.Push(NewCurrPathSlash(arg))
}
if pkglint.Todo.IsEmpty() {
pkglint.Todo.Push(".")
@@ -296,7 +289,7 @@ func (pkglint *Pkglint) ParseCommandLine
//
// It sets up all the global state (infrastructure, wip) for accurately
// classifying the entry.
-func (pkglint *Pkglint) Check(dirent Path) {
+func (pkglint *Pkglint) Check(dirent CurrPath) {
if trace.Tracing {
defer trace.Call(dirent)()
}
@@ -310,7 +303,7 @@ func (pkglint *Pkglint) Check(dirent Pat
pkglint.checkMode(dirent, st.Mode())
}
-func (pkglint *Pkglint) checkMode(dirent Path, mode os.FileMode) {
+func (pkglint *Pkglint) checkMode(dirent CurrPath, mode os.FileMode) {
// TODO: merge duplicate code in Package.checkDirent
isDir := mode.IsDir()
isReg := mode.IsRegular()
@@ -321,7 +314,8 @@ func (pkglint *Pkglint) checkMode(dirent
dir := dirent
if !isDir {
- dir = dirent.Dir()
+ // FIXME: consider DirNoClean
+ dir = dirent.DirClean()
}
basename := dirent.Base()
@@ -330,8 +324,8 @@ func (pkglint *Pkglint) checkMode(dirent
pkglint.Wip = pkgsrcRel.HasPrefixPath("wip")
pkglint.Infrastructure = pkgsrcRel.HasPrefixPath("mk")
pkgsrcdir := findPkgsrcTopdir(dir)
- if pkgsrcdir == "" {
- NewLineWhole(dirent).Errorf("Cannot determine the pkgsrc root directory for %q.", cleanpath(dir))
+ if pkgsrcdir.IsEmpty() {
+ NewLineWhole(dirent).Errorf("Cannot determine the pkgsrc root directory for %q.", dir.CleanPath())
return
}
@@ -359,7 +353,7 @@ func (pkglint *Pkglint) checkMode(dirent
// checkdirPackage checks a complete pkgsrc package, including each
// of the files individually, and also when seen in combination.
-func (pkglint *Pkglint) checkdirPackage(dir Path) {
+func (pkglint *Pkglint) checkdirPackage(dir CurrPath) {
if trace.Tracing {
defer trace.Call(dir)()
}
@@ -373,7 +367,7 @@ func (pkglint *Pkglint) checkdirPackage(
}
// Returns the pkgsrc top-level directory, relative to the given directory.
-func findPkgsrcTopdir(dirname Path) Path {
+func findPkgsrcTopdir(dirname CurrPath) Path {
for _, dir := range [...]Path{".", "..", "../..", "../../.."} {
if dirname.JoinNoClean(dir).JoinNoClean("mk/bsd.pkg.mk").IsFile() {
return dir
@@ -423,7 +417,7 @@ func resolveVariableRefs(mklines *MkLine
}
}
-func CheckFileOther(filename Path) {
+func CheckFileOther(filename CurrPath) {
if trace.Tracing {
defer trace.Call(filename)()
}
@@ -526,7 +520,7 @@ func CheckLinesMessage(lines *Lines) {
SaveAutofixChanges(lines)
}
-func CheckFileMk(filename Path) {
+func CheckFileMk(filename CurrPath) {
if trace.Tracing {
defer trace.Call(filename)()
}
@@ -547,7 +541,7 @@ func CheckFileMk(filename Path) {
// checkReg checks the given regular file.
// depth is 3 for files in the package directory, and 4 or more for files
// deeper in the directory hierarchy, such as in files/ or patches/.
-func (pkglint *Pkglint) checkReg(filename Path, basename string, depth int) {
+func (pkglint *Pkglint) checkReg(filename CurrPath, basename string, depth int) {
if depth == 3 && !pkglint.Wip {
// FIXME: There's no good reason for prohibiting a README file.
@@ -607,16 +601,20 @@ func (pkglint *Pkglint) checkReg(filenam
CheckLinesPatch(lines)
}
- case filename.Dir().Base() == "patches" && matches(filename.Base(), `^manual[^/]*$`):
+ // FIXME: consider DirNoClean
+ case filename.DirClean().Base() == "patches" && matches(filename.Base(), `^manual[^/]*$`):
if trace.Tracing {
trace.Stepf("Unchecked file %q.", filename)
}
- case filename.Dir().Base() == "patches":
+ // FIXME: consider DirNoClean
+ case filename.DirClean().Base() == "patches":
NewLineWhole(filename).Warnf("Patch files should be named \"patch-\", followed by letters, '-', '_', '.', and digits only.")
case (hasPrefix(basename, "Makefile") || hasSuffix(basename, ".mk")) &&
- !filename.Dir().ContainsPath("files"): // FIXME: G.Pkgsrc.Rel(filename) instead of filename
+ // FIXME: consider DirNoClean
+ // FIXME: G.Pkgsrc.Rel(filename) instead of filename
+ !filename.DirClean().ContainsPath("files"):
CheckFileMk(filename)
case hasPrefix(basename, "PLIST"):
@@ -628,7 +626,8 @@ func (pkglint *Pkglint) checkReg(filenam
// This only checks the file but doesn't register the changes globally.
_ = pkglint.Pkgsrc.loadDocChangesFromFile(filename)
- case filename.Dir().Base() == "files":
+ // FIXME: consider DirNoClean
+ case filename.DirClean().Base() == "files":
// Skip files directly in the files/ directory, but not those further down.
case basename == "spec":
@@ -653,7 +652,7 @@ func (pkglint *Pkglint) matchesLicenseFi
return basename == path.Base(licenseFile)
}
-func (pkglint *Pkglint) checkExecutable(filename Path, mode os.FileMode) {
+func (pkglint *Pkglint) checkExecutable(filename CurrPath, mode os.FileMode) {
if mode.Perm()&0111 == 0 {
// Not executable at all.
return
@@ -679,7 +678,7 @@ func (pkglint *Pkglint) checkExecutable(
fix.Describef(0, "Clearing executable bits")
if autofix {
if err := filename.Chmod(mode &^ 0111); err != nil {
- G.Logger.TechErrorf(cleanpath(filename), "Cannot clear executable bits: %s", err)
+ G.Logger.TechErrorf(filename.CleanPath(), "Cannot clear executable bits: %s", err)
}
}
})
@@ -733,8 +732,9 @@ func (pkglint *Pkglint) tools(mklines *M
}
}
-func (pkglint *Pkglint) loadCvsEntries(filename Path) map[string]CvsEntry {
- dir := filename.Dir()
+func (pkglint *Pkglint) loadCvsEntries(filename CurrPath) map[string]CvsEntry {
+ // FIXME: consider DirNoClean
+ dir := filename.DirClean()
if dir == pkglint.cvsEntriesDir {
return pkglint.cvsEntries
}
@@ -759,14 +759,14 @@ func (pkglint *Pkglint) loadCvsEntries(f
}
}
- lines := Load(dir+"/CVS/Entries", 0)
+ lines := Load(dir.JoinNoClean("CVS/Entries"), 0)
if lines != nil {
entries = make(map[string]CvsEntry)
for _, line := range lines.Lines {
handle(line, true, line.Text)
}
- logLines := Load(dir+"/CVS/Entries.Log", 0)
+ logLines := Load(dir.JoinNoClean("CVS/Entries.Log"), 0)
if logLines != nil {
for _, line := range logLines.Lines {
text := line.Text
@@ -784,9 +784,9 @@ func (pkglint *Pkglint) loadCvsEntries(f
return entries
}
-func (pkglint *Pkglint) Abs(filename Path) Path {
+func (pkglint *Pkglint) Abs(filename CurrPath) CurrPath {
if !filename.IsAbs() {
- return pkglint.cwd.JoinNoClean(filename).Clean()
+ return pkglint.cwd.JoinNoClean(filename.AsPath()).Clean()
}
return filename.Clean()
}
Index: pkgsrc/pkgtools/pkglint/files/pkgsrc.go
diff -u pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.44 pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.45
--- pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.44 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/pkgsrc.go Mon Dec 2 23:32:09 2019
@@ -17,9 +17,8 @@ import (
// Everything else (distfile hashes, package names) is recorded in the Pkglint
// type instead.
type Pkgsrc struct {
- // The top directory (PKGSRCDIR), either absolute or relative to
- // the current working directory.
- topdir Path
+ // The top directory (PKGSRCDIR).
+ topdir CurrPath
// The set of user-defined variables that are added to BUILD_DEFS
// within the bsd.pkg.mk file.
@@ -35,7 +34,7 @@ type Pkgsrc struct {
suggestedUpdates []SuggestedUpdate
suggestedWipUpdates []SuggestedUpdate
- LastChange map[Path]*Change
+ LastChange map[PkgsrcPath]*Change
LastFreezeStart string // e.g. "2018-01-01", or ""
LastFreezeEnd string // e.g. "2018-01-01", or ""
@@ -52,7 +51,7 @@ type Pkgsrc struct {
vartypes VarTypeRegistry
}
-func NewPkgsrc(dir Path) Pkgsrc {
+func NewPkgsrc(dir CurrPath) Pkgsrc {
return Pkgsrc{
dir,
make(map[string]bool),
@@ -62,7 +61,7 @@ func NewPkgsrc(dir Path) Pkgsrc {
make(map[string]string),
nil,
nil,
- make(map[Path]*Change),
+ make(map[PkgsrcPath]*Change),
"",
"",
make(map[string][]string),
@@ -156,7 +155,7 @@ func (src *Pkgsrc) loadDocChanges() {
}
}
- src.LastChange = make(map[Path]*Change)
+ src.LastChange = make(map[PkgsrcPath]*Change)
for _, filename := range filenames {
changes := src.loadDocChangesFromFile(docDir.JoinNoClean(filename))
for _, change := range changes {
@@ -170,7 +169,7 @@ func (src *Pkgsrc) loadDocChanges() {
src.checkRemovedAfterLastFreeze()
}
-func (src *Pkgsrc) loadDocChangesFromFile(filename Path) []*Change {
+func (src *Pkgsrc) loadDocChangesFromFile(filename CurrPath) []*Change {
warn := G.Opts.CheckGlobal && !G.Wip
@@ -312,7 +311,7 @@ func (*Pkgsrc) parseDocChange(line *Line
return &Change{
Location: line.Location,
Action: action,
- Pkgpath: NewPath(intern(pkgpath)),
+ Pkgpath: NewPkgsrcPath(NewPath(intern(pkgpath))),
target: intern(condStr(n == 6, f[3], "")),
Author: intern(author),
Date: intern(date),
@@ -405,7 +404,7 @@ func (src *Pkgsrc) loadUserDefinedVars()
func (src *Pkgsrc) loadTools() {
tools := src.Tools
- toolFiles := []Path{"defaults.mk"}
+ toolFiles := []RelPath{"defaults.mk"}
{
toc := src.File("mk/tools/bsd.tools.mk")
mklines := LoadMk(toc, MustSucceed|NotEmpty)
@@ -413,7 +412,7 @@ func (src *Pkgsrc) loadTools() {
if mkline.IsInclude() {
includedFile := mkline.IncludedFile()
if !includedFile.ContainsText("/") {
- toolFiles = append(toolFiles, includedFile)
+ toolFiles = append(toolFiles, NewRelPath(includedFile))
}
}
}
@@ -430,13 +429,13 @@ func (src *Pkgsrc) loadTools() {
tools.def("true", "TRUE", true, AfterPrefsMk, nil)
for _, basename := range toolFiles {
- mklines := src.LoadMk("mk/tools/"+basename, MustSucceed|NotEmpty)
+ mklines := src.LoadMk(NewPkgsrcPath("mk/tools").JoinRel(basename), MustSucceed|NotEmpty)
mklines.ForEach(func(mkline *MkLine) {
tools.ParseToolLine(mklines, mkline, true, !mklines.indentation.IsConditional())
})
}
- for _, relativeName := range [...]Path{"mk/bsd.prefs.mk", "mk/bsd.pkg.mk"} {
+ for _, relativeName := range [...]PkgsrcPath{"mk/bsd.prefs.mk", "mk/bsd.pkg.mk"} {
mklines := src.LoadMk(relativeName, MustSucceed|NotEmpty)
mklines.ForEach(func(mkline *MkLine) {
@@ -670,7 +669,7 @@ func (src *Pkgsrc) loadUntypedVars() {
}
}
- handleMkFile := func(path Path) {
+ handleMkFile := func(path CurrPath) {
mklines := LoadMk(path, MustSucceed)
mklines.collectVariables()
mklines.collectUsedVariables()
@@ -686,7 +685,7 @@ func (src *Pkgsrc) loadUntypedVars() {
assertNil(err, "handleFile %q", pathName)
baseName := info.Name()
if info.Mode().IsRegular() && (hasSuffix(baseName, ".mk") || baseName == "mk.conf") {
- handleMkFile(NewPath(filepath.ToSlash(pathName))) // FIXME: This is too deep to handle os-specific paths
+ handleMkFile(NewCurrPathSlash(pathName)) // FIXME: This is too deep to handle os-specific paths
}
return nil
}
@@ -775,7 +774,7 @@ func (src *Pkgsrc) loadDefaultBuildDefs(
// Example:
// Latest("lang", `^php[0-9]+$`, "../../lang/$0")
// => "../../lang/php72"
-func (src *Pkgsrc) Latest(category Path, re regex.Pattern, repl string) string {
+func (src *Pkgsrc) Latest(category PkgsrcPath, re regex.Pattern, repl string) string {
versions := src.ListVersions(category, re, repl, true)
if len(versions) > 0 {
@@ -791,7 +790,7 @@ func (src *Pkgsrc) Latest(category Path,
// Example:
// ListVersions("lang", `^php[0-9]+$`, "php-$0")
// => {"php-53", "php-56", "php-73"}
-func (src *Pkgsrc) ListVersions(category Path, re regex.Pattern, repl string, errorIfEmpty bool) []string {
+func (src *Pkgsrc) ListVersions(category PkgsrcPath, re regex.Pattern, repl string, errorIfEmpty bool) []string {
if G.Testing {
// Regular expression must be anchored at both ends, to avoid typos.
assert(hasPrefix(string(re), "^"))
@@ -995,7 +994,7 @@ func (src *Pkgsrc) IsBuildDef(varname st
// ReadDir lists the files and subdirectories from the given directory
// (relative to the pkgsrc root), filtering out any ignored files (CVS/*)
// and empty directories.
-func (src *Pkgsrc) ReadDir(dirName Path) []os.FileInfo {
+func (src *Pkgsrc) ReadDir(dirName PkgsrcPath) []os.FileInfo {
dir := src.File(dirName)
files, err := dir.ReadDir()
if err != nil {
@@ -1017,7 +1016,7 @@ func (src *Pkgsrc) ReadDir(dirName Path)
//
// During pkglint testing, these files often don't exist, as they are
// emulated by setting their data structures manually.
-func (src *Pkgsrc) LoadMkExisting(filename Path) *MkLines {
+func (src *Pkgsrc) LoadMkExisting(filename PkgsrcPath) *MkLines {
options := NotEmpty
if !G.Testing {
options |= MustSucceed
@@ -1026,12 +1025,12 @@ func (src *Pkgsrc) LoadMkExisting(filena
}
// LoadMk loads the Makefile relative to the pkgsrc top directory.
-func (src *Pkgsrc) LoadMk(filename Path, options LoadOptions) *MkLines {
+func (src *Pkgsrc) LoadMk(filename PkgsrcPath, options LoadOptions) *MkLines {
return LoadMk(src.File(filename), options)
}
// Load loads the file relative to the pkgsrc top directory.
-func (src *Pkgsrc) Load(filename Path, options LoadOptions) *Lines {
+func (src *Pkgsrc) Load(filename PkgsrcPath, options LoadOptions) *Lines {
return Load(src.File(filename), options)
}
@@ -1042,9 +1041,6 @@ func (src *Pkgsrc) Load(filename Path, o
// pkgsrc root and from there to the "to" filename. This produces the form
// "../../category/package" that is found in DEPENDS and .include lines.
//
-// Both from and to are interpreted relative to the current working directory,
-// unless they are absolute paths.
-//
// This function should only be used if the relative path from one file to
// another cannot be computed in another way. The preferred way is to take
// the relative filenames directly from the .include or exists() where they
@@ -1052,7 +1048,7 @@ func (src *Pkgsrc) Load(filename Path, o
//
// TODO: Invent data types for all kinds of relative paths that occur in pkgsrc
// and pkglint. Make sure that these paths cannot be accidentally mixed.
-func (src *Pkgsrc) Relpath(from, to Path) (result Path) {
+func (src *Pkgsrc) Relpath(from, to CurrPath) Path {
cfrom := from.Clean()
cto := to.Clean()
@@ -1062,23 +1058,20 @@ func (src *Pkgsrc) Relpath(from, to Path
// Take a shortcut for the common case from "dir" to "dir/subdir/...".
if cto.HasPrefixPath(cfrom) {
- rel := cfrom.Rel(cto)
- if !rel.HasPrefixPath("..") {
- return rel
- }
+ return cfrom.Rel(cto)
}
// Take a shortcut for the common case from "category/package" to ".".
// This is the most common variant in a complete pkgsrc scan.
if cto == "." {
fromParts := cfrom.Parts()
- if len(fromParts) == 2 && fromParts[0] != ".." && fromParts[1] != ".." {
+ if len(fromParts) == 2 && fromParts[0] != ".." {
return "../.."
}
}
if cfrom == "." && !cto.IsAbs() {
- return cto.Clean()
+ return cto.Clean().AsPath()
}
absFrom := G.Abs(cfrom)
@@ -1098,7 +1091,7 @@ func (src *Pkgsrc) Relpath(from, to Path
if len(fromParts) >= 2 && len(toParts) >= 2 {
if fromParts[0] == toParts[0] && fromParts[1] == toParts[1] {
var relParts []string
- for _ = range fromParts[2:] {
+ for range fromParts[2:] {
relParts = append(relParts, "..")
}
relParts = append(relParts, toParts[2:]...)
@@ -1106,16 +1099,15 @@ func (src *Pkgsrc) Relpath(from, to Path
}
}
- result = up.JoinNoClean(down).CleanDot()
- return
+ return up.JoinNoClean(down).CleanDot()
}
// File resolves a filename relative to the pkgsrc top directory.
//
// Example:
// NewPkgsrc("/usr/pkgsrc").File("distfiles") => "/usr/pkgsrc/distfiles"
-func (src *Pkgsrc) File(relativeName Path) Path {
- cleaned := relativeName.Clean()
+func (src *Pkgsrc) File(relativeName PkgsrcPath) CurrPath {
+ cleaned := relativeName.AsPath().Clean()
if cleaned == "." {
return src.topdir.CleanDot()
}
@@ -1127,23 +1119,23 @@ func (src *Pkgsrc) File(relativeName Pat
//
// Example:
// NewPkgsrc("/usr/pkgsrc").ToRel("/usr/pkgsrc/distfiles") => "distfiles"
-func (src *Pkgsrc) ToRel(filename Path) Path {
- return src.Relpath(src.topdir, filename)
+func (src *Pkgsrc) ToRel(filename CurrPath) PkgsrcPath {
+ return NewPkgsrcPath(src.Relpath(src.topdir, filename))
}
-// IsInfra returns whether the given filename (relative to the current
-// working directory) is part of the pkgsrc infrastructure.
-func (src *Pkgsrc) IsInfra(filename Path) bool {
+// IsInfra returns whether the given filename is part of the pkgsrc
+// infrastructure.
+func (src *Pkgsrc) IsInfra(filename CurrPath) bool {
rel := src.ToRel(filename)
return rel.HasPrefixPath("mk") || rel.HasPrefixPath("wip/mk")
}
-func (src *Pkgsrc) IsInfraMain(filename Path) bool {
+func (src *Pkgsrc) IsInfraMain(filename CurrPath) bool {
rel := src.ToRel(filename)
return rel.HasPrefixPath("mk")
}
-func (src *Pkgsrc) IsWip(filename Path) bool {
+func (src *Pkgsrc) IsWip(filename CurrPath) bool {
rel := src.ToRel(filename)
return rel.HasPrefixPath("wip")
}
@@ -1152,7 +1144,7 @@ func (src *Pkgsrc) IsWip(filename Path)
type Change struct {
Location Location
Action ChangeAction // Added, Updated, Downgraded, Renamed, Moved, Removed
- Pkgpath Path // For renamed or moved packages, the previous PKGPATH
+ Pkgpath PkgsrcPath // For renamed or moved packages, the previous PKGPATH
target string // The path or version number, depending on the action
Author string
Date string
@@ -1165,9 +1157,9 @@ func (ch *Change) Version() string {
}
// Target returns the target PKGPATH for a Renamed or Moved package.
-func (ch *Change) Target() Path {
+func (ch *Change) Target() PkgsrcPath {
assert(ch.Action == Renamed || ch.Action == Moved)
- return NewPath(ch.target)
+ return NewPkgsrcPath(NewPath(ch.target))
}
// Successor returns the successor for a Removed package.
Index: pkgsrc/pkgtools/pkglint/files/plist.go
diff -u pkgsrc/pkgtools/pkglint/files/plist.go:1.45 pkgsrc/pkgtools/pkglint/files/plist.go:1.46
--- pkgsrc/pkgtools/pkglint/files/plist.go:1.45 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/plist.go Mon Dec 2 23:32:09 2019
@@ -111,12 +111,15 @@ func (ck *PlistChecker) collectFilesAndD
if prev := ck.allFiles[path]; prev == nil || stringSliceLess(pline.conditions, prev.conditions) {
ck.allFiles[path] = pline
}
- for dir := path.Dir(); dir != "."; dir = dir.Dir() {
+ // FIXME: consider DirNoClean
+ // FIXME: consider DirNoClean
+ for dir := path.DirClean(); dir != "."; dir = dir.DirClean() {
ck.allDirs[dir] = pline
}
case first == '@':
if m, dirname := match1(text, `^@exec \$\{MKDIR\} %D/(.*)$`); m {
- for dir := NewPath(dirname); dir != "."; dir = dir.Dir() {
+ // FIXME: consider DirNoClean
+ for dir := NewPath(dirname); dir != "."; dir = dir.DirClean() {
ck.allDirs[dir] = pline
}
}
@@ -560,8 +563,8 @@ func (s *plistLineSorter) Sort() {
mi := s.middle[i]
mj := s.middle[j]
less := mi.text < mj.text ||
- (mi.text == mj.text && stringSliceLess(mi.conditions, mj.conditions))
- if (i < j) != less {
+ mi.text == mj.text && stringSliceLess(mi.conditions, mj.conditions)
+ if i < j != less {
s.changed = true
}
return less
Index: pkgsrc/pkgtools/pkglint/files/redundantscope.go
diff -u pkgsrc/pkgtools/pkglint/files/redundantscope.go:1.8 pkgsrc/pkgtools/pkglint/files/redundantscope.go:1.9
--- pkgsrc/pkgtools/pkglint/files/redundantscope.go:1.8 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/redundantscope.go Mon Dec 2 23:32:09 2019
@@ -223,14 +223,14 @@ func (s *RedundantScope) onOverwrite(ove
// one of two variable assignments is redundant. Two assignments can
// only be redundant if one location includes the other.
type includePath struct {
- files []Path
+ files []CurrPath
}
-func (p *includePath) push(filename Path) {
+func (p *includePath) push(filename CurrPath) {
p.files = append(p.files, filename)
}
-func (p *includePath) popUntil(filename Path) {
+func (p *includePath) popUntil(filename CurrPath) {
for p.files[len(p.files)-1] != filename {
p.files = p.files[:len(p.files)-1]
}
@@ -276,5 +276,5 @@ func (p *includePath) equals(other inclu
}
func (p *includePath) copy() includePath {
- return includePath{append([]Path(nil), p.files...)}
+ return includePath{append([]CurrPath(nil), p.files...)}
}
Index: pkgsrc/pkgtools/pkglint/files/redundantscope_test.go
diff -u pkgsrc/pkgtools/pkglint/files/redundantscope_test.go:1.8 pkgsrc/pkgtools/pkglint/files/redundantscope_test.go:1.9
--- pkgsrc/pkgtools/pkglint/files/redundantscope_test.go:1.8 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/redundantscope_test.go Mon Dec 2 23:32:09 2019
@@ -1525,7 +1525,7 @@ func (s *Suite) Test_RedundantScope_hand
func (s *Suite) Test_includePath_includes(c *check.C) {
t := s.Init(c)
- path := func(locations ...Path) includePath {
+ path := func(locations ...CurrPath) includePath {
return includePath{locations}
}
@@ -1550,7 +1550,7 @@ func (s *Suite) Test_includePath_include
func (s *Suite) Test_includePath_equals(c *check.C) {
t := s.Init(c)
- path := func(locations ...Path) includePath {
+ path := func(locations ...CurrPath) includePath {
return includePath{locations}
}
Index: pkgsrc/pkgtools/pkglint/files/substcontext_test.go
diff -u pkgsrc/pkgtools/pkglint/files/substcontext_test.go:1.30 pkgsrc/pkgtools/pkglint/files/substcontext_test.go:1.31
--- pkgsrc/pkgtools/pkglint/files/substcontext_test.go:1.30 Sun Nov 17 01:26:25 2019
+++ pkgsrc/pkgtools/pkglint/files/substcontext_test.go Mon Dec 2 23:32:09 2019
@@ -301,16 +301,16 @@ func (s *Suite) Test_SubstContext__neste
func (s *Suite) Test_SubstContext__pre_patch(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wextra,no-space", "--show-autofix")
+ t.SetUpCommandLine("-Wextra", "--show-autofix")
t.SetUpVartypes()
mklines := t.NewMkLines("os.mk",
MkCvsID,
"",
- "SUBST_CLASSES+= os",
- "SUBST_STAGE.os= pre-patch",
- "SUBST_FILES.os= guess-os.h",
- "SUBST_SED.os= -e s,@OPSYS@,Darwin,")
+ "SUBST_CLASSES+=\tos",
+ "SUBST_STAGE.os=\tpre-patch",
+ "SUBST_FILES.os=\tguess-os.h",
+ "SUBST_SED.os=\t-e s,@OPSYS@,Darwin,")
mklines.Check()
@@ -322,16 +322,16 @@ func (s *Suite) Test_SubstContext__pre_p
func (s *Suite) Test_SubstContext__post_patch(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wextra,no-space", "--show-autofix")
+ t.SetUpCommandLine("-Wextra", "--show-autofix")
t.SetUpVartypes()
mklines := t.NewMkLines("os.mk",
MkCvsID,
"",
- "SUBST_CLASSES+= os",
- "SUBST_STAGE.os= post-patch",
- "SUBST_FILES.os= guess-os.h",
- "SUBST_SED.os= -e s,@OPSYS@,Darwin,")
+ "SUBST_CLASSES+=\tos",
+ "SUBST_STAGE.os=\tpost-patch",
+ "SUBST_FILES.os=\tguess-os.h",
+ "SUBST_SED.os=\t-e s,@OPSYS@,Darwin,")
mklines.Check()
@@ -343,24 +343,23 @@ func (s *Suite) Test_SubstContext__post_
func (s *Suite) Test_SubstContext__with_NO_CONFIGURE(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
pkg := t.SetUpPackage("category/package",
- "SUBST_CLASSES+= pre",
- "SUBST_STAGE.pre= pre-configure",
- "SUBST_FILES.pre= guess-os.h",
- "SUBST_SED.pre= -e s,@OPSYS@,Darwin,",
- "",
- "SUBST_CLASSES+= post",
- "SUBST_STAGE.post= post-configure",
- "SUBST_FILES.post= guess-os.h",
- "SUBST_SED.post= -e s,@OPSYS@,Darwin,",
- "",
- "SUBST_CLASSES+= e",
- "SUBST_STAGE.e= post-extract",
- "SUBST_FILES.e= guess-os.h",
- "SUBST_SED.e= -e s,@OPSYS@,Darwin,",
+ "SUBST_CLASSES+=\t\tpre",
+ "SUBST_STAGE.pre=\tpre-configure",
+ "SUBST_FILES.pre=\tguess-os.h",
+ "SUBST_SED.pre=\t\t-e s,@OPSYS@,Darwin,",
+ "",
+ "SUBST_CLASSES+=\t\tpost",
+ "SUBST_STAGE.post=\tpost-configure",
+ "SUBST_FILES.post=\tguess-os.h",
+ "SUBST_SED.post=\t\t-e s,@OPSYS@,Darwin,",
+ "",
+ "SUBST_CLASSES+=\te",
+ "SUBST_STAGE.e=\tpost-extract",
+ "SUBST_FILES.e=\tguess-os.h",
+ "SUBST_SED.e=\t-e s,@OPSYS@,Darwin,",
"",
- "NO_CONFIGURE= yes")
+ "NO_CONFIGURE=\tyes")
t.FinishSetUp()
G.Check(pkg)
@@ -375,12 +374,11 @@ func (s *Suite) Test_SubstContext__with_
func (s *Suite) Test_SubstContext__without_NO_CONFIGURE(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wall,no-space")
pkg := t.SetUpPackage("category/package",
- "SUBST_CLASSES+= pre",
- "SUBST_STAGE.pre= pre-configure",
- "SUBST_FILES.pre= guess-os.h",
- "SUBST_SED.pre= -e s,@OPSYS@,Darwin,")
+ "SUBST_CLASSES+=\t\tpre",
+ "SUBST_STAGE.pre=\tpre-configure",
+ "SUBST_FILES.pre=\tguess-os.h",
+ "SUBST_SED.pre=\t\t-e s,@OPSYS@,Darwin,")
t.FinishSetUp()
G.Check(pkg)
@@ -397,15 +395,15 @@ func (s *Suite) Test_SubstContext__adjac
mklines := t.NewMkLines("os.mk",
MkCvsID,
"",
- "SUBST_CLASSES+= 1",
- "SUBST_STAGE.1= pre-configure",
- "SUBST_FILES.1= file1",
- "SUBST_SED.1= -e s,subst1,repl1,",
- "SUBST_CLASSES+= 2",
- "SUBST_SED.1+= -e s,subst1b,repl1b,", // Misplaced
- "SUBST_STAGE.2= pre-configure",
- "SUBST_FILES.2= file2",
- "SUBST_SED.2= -e s,subst2,repl2,")
+ "SUBST_CLASSES+=\t1",
+ "SUBST_STAGE.1=\tpre-configure",
+ "SUBST_FILES.1=\tfile1",
+ "SUBST_SED.1=\t-e s,subst1,repl1,",
+ "SUBST_CLASSES+=\t2",
+ "SUBST_SED.1+=\t-e s,subst1b,repl1b,", // Misplaced
+ "SUBST_STAGE.2=\tpre-configure",
+ "SUBST_FILES.2=\tfile2",
+ "SUBST_SED.2=\t-e s,subst2,repl2,")
mklines.Check()
@@ -416,16 +414,15 @@ func (s *Suite) Test_SubstContext__adjac
func (s *Suite) Test_SubstContext__do_patch(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wextra,no-space")
t.SetUpVartypes()
mklines := t.NewMkLines("os.mk",
MkCvsID,
"",
- "SUBST_CLASSES+= os",
- "SUBST_STAGE.os= do-patch",
- "SUBST_FILES.os= guess-os.h",
- "SUBST_SED.os= -e s,@OPSYS@,Darwin,")
+ "SUBST_CLASSES+=\tos",
+ "SUBST_STAGE.os=\tdo-patch",
+ "SUBST_FILES.os=\tguess-os.h",
+ "SUBST_SED.os=\t-e s,@OPSYS@,Darwin,")
mklines.Check()
@@ -439,18 +436,17 @@ func (s *Suite) Test_SubstContext__do_pa
func (s *Suite) Test_SubstContext__SUBST_VARS_defined_in_block(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wextra,no-space")
t.SetUpVartypes()
mklines := t.NewMkLines("os.mk",
MkCvsID,
"",
- "SUBST_CLASSES+= os",
- "SUBST_STAGE.os= pre-configure",
- "SUBST_FILES.os= guess-os.h",
- "SUBST_VARS.os= TODAY1",
- "TODAY1!= date",
- "TODAY2!= date")
+ "SUBST_CLASSES+=\tos",
+ "SUBST_STAGE.os=\tpre-configure",
+ "SUBST_FILES.os=\tguess-os.h",
+ "SUBST_VARS.os=\tTODAY1",
+ "TODAY1!=\tdate",
+ "TODAY2!=\tdate")
mklines.Check()
@@ -464,19 +460,18 @@ func (s *Suite) Test_SubstContext__SUBST
func (s *Suite) Test_SubstContext__SUBST_VARS_in_next_paragraph(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wextra,no-space")
t.SetUpVartypes()
mklines := t.NewMkLines("os.mk",
MkCvsID,
"",
- "SUBST_CLASSES+= os",
- "SUBST_STAGE.os= pre-configure",
- "SUBST_FILES.os= guess-os.h",
- "SUBST_VARS.os= TODAY1",
+ "SUBST_CLASSES+=\tos",
+ "SUBST_STAGE.os=\tpre-configure",
+ "SUBST_FILES.os=\tguess-os.h",
+ "SUBST_VARS.os=\tTODAY1",
"",
- "TODAY1!= date",
- "TODAY2!= date")
+ "TODAY1!=\tdate",
+ "TODAY2!=\tdate")
mklines.Check()
@@ -487,16 +482,16 @@ func (s *Suite) Test_SubstContext__SUBST
func (s *Suite) Test_SubstContext__multiple_SUBST_VARS(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wextra,no-space")
+ t.SetUpCommandLine("-Wextra")
t.SetUpVartypes()
mklines := t.NewMkLines("os.mk",
MkCvsID,
"",
- "SUBST_CLASSES+= os",
- "SUBST_STAGE.os= pre-configure",
- "SUBST_FILES.os= guess-os.h",
- "SUBST_VARS.os= PREFIX VARBASE")
+ "SUBST_CLASSES+=\tos",
+ "SUBST_STAGE.os=\tpre-configure",
+ "SUBST_FILES.os=\tguess-os.h",
+ "SUBST_VARS.os=\tPREFIX VARBASE")
mklines.Check()
@@ -530,7 +525,6 @@ func (s *Suite) Test_SubstContext__unusu
func (s *Suite) Test_SubstContext_Directive__before_SUBST_CLASSES(c *check.C) {
t := s.Init(c)
- t.SetUpCommandLine("-Wextra,no-space")
t.SetUpVartypes()
t.DisableTracing() // Just for branch coverage.
@@ -539,7 +533,7 @@ func (s *Suite) Test_SubstContext_Direct
"",
".if 0",
".endif",
- "SUBST_CLASSES+= os",
+ "SUBST_CLASSES+=\tos",
".elif 0") // Just for branch coverage.
mklines.Check()
Index: pkgsrc/pkgtools/pkglint/files/tools_test.go
diff -u pkgsrc/pkgtools/pkglint/files/tools_test.go:1.22 pkgsrc/pkgtools/pkglint/files/tools_test.go:1.23
--- pkgsrc/pkgtools/pkglint/files/tools_test.go:1.22 Sat Nov 23 23:35:56 2019
+++ pkgsrc/pkgtools/pkglint/files/tools_test.go Mon Dec 2 23:32:09 2019
@@ -207,7 +207,6 @@ func (s *Suite) Test_Tools__builtin_mk(c
t := s.Init(c)
t.SetUpPkgsrc()
- t.SetUpCommandLine("-Wall,no-space")
t.CreateFileLines("mk/tools/defaults.mk",
"TOOLS_CREATE+= load",
"TOOLS_CREATE+= run",
@@ -228,19 +227,19 @@ func (s *Suite) Test_Tools__builtin_mk(c
mklines := t.SetUpFileMkLines("category/package/builtin.mk",
MkCvsID,
"",
- "VAR!= ${ECHO} 'too early'",
- "VAR!= ${LOAD} 'too early'",
- "VAR!= ${RUN_CMD} 'never allowed'",
- "VAR!= ${NOWHERE} 'never allowed'",
+ "VAR!=\t${ECHO} 'too early'",
+ "VAR!=\t${LOAD} 'too early'",
+ "VAR!=\t${RUN_CMD} 'never allowed'",
+ "VAR!=\t${NOWHERE} 'never allowed'",
"",
".include \"../../mk/buildlink3/bsd.builtin.mk\"",
"",
- "VAR!= ${ECHO} 'valid'",
- "VAR!= ${LOAD} 'valid'",
- "VAR!= ${RUN_CMD} 'never allowed'",
- "VAR!= ${NOWHERE} 'never allowed'",
+ "VAR!=\t${ECHO} 'valid'",
+ "VAR!=\t${LOAD} 'valid'",
+ "VAR!=\t${RUN_CMD} 'never allowed'",
+ "VAR!=\t${NOWHERE} 'never allowed'",
"",
- "VAR!= ${VAR}")
+ "VAR!=\t${VAR}")
mklines.Check()
@@ -257,7 +256,6 @@ func (s *Suite) Test_Tools__implicit_def
t := s.Init(c)
t.SetUpPkgsrc()
- t.SetUpCommandLine("-Wall,no-space")
t.CreateFileLines("mk/tools/defaults.mk",
MkCvsID) // None
t.CreateFileLines("mk/bsd.prefs.mk",
@@ -278,7 +276,6 @@ func (s *Suite) Test_Tools__both_prefs_a
t := s.Init(c)
t.SetUpPkgsrc()
- t.SetUpCommandLine("-Wall,no-space")
t.CreateFileLines("mk/tools/defaults.mk",
MkCvsID)
t.CreateFileLines("mk/bsd.prefs.mk",
@@ -297,7 +294,6 @@ func (s *Suite) Test_Tools__tools_having
t := s.Init(c)
t.SetUpPkgsrc()
- t.SetUpCommandLine("-Wall,no-space")
t.CreateFileLines("mk/tools/defaults.mk",
"_TOOLS_VARNAME.awk= AWK",
"_TOOLS_VARNAME.gawk= AWK",
Index: pkgsrc/pkgtools/pkglint/files/toplevel.go
diff -u pkgsrc/pkgtools/pkglint/files/toplevel.go:1.25 pkgsrc/pkgtools/pkglint/files/toplevel.go:1.26
--- pkgsrc/pkgtools/pkglint/files/toplevel.go:1.25 Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/toplevel.go Mon Dec 2 23:32:09 2019
@@ -1,18 +1,18 @@
package pkglint
type Toplevel struct {
- dir Path
+ dir CurrPath
previousSubdir Path
- subdirs []Path
+ subdirs []CurrPath
}
-func CheckdirToplevel(dir Path) {
+func CheckdirToplevel(dir CurrPath) {
if trace.Tracing {
defer trace.Call(dir)()
}
ctx := Toplevel{dir, "", nil}
- filename := dir + "/Makefile"
+ filename := dir.JoinNoClean("Makefile")
mklines := LoadMk(filename, NotEmpty|LogErrors)
if mklines == nil {
Index: pkgsrc/pkgtools/pkglint/files/vardefs_test.go
diff -u pkgsrc/pkgtools/pkglint/files/vardefs_test.go:1.25 pkgsrc/pkgtools/pkglint/files/vardefs_test.go:1.26
--- pkgsrc/pkgtools/pkglint/files/vardefs_test.go:1.25 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/vardefs_test.go Mon Dec 2 23:32:09 2019
@@ -148,7 +148,7 @@ func (s *Suite) Test_VarTypeRegistry_enu
G.Pkgsrc.vartypes.enumFromDirs(
&G.Pkgsrc, "category", `^pack.*`, "$0", "default")
},
- "FATAL: category: Must contain at least 1 "+
+ "FATAL: ~/category: Must contain at least 1 "+
"subdirectory matching \"^pack.*\".")
}
@@ -177,10 +177,10 @@ func (s *Suite) Test_VarTypeRegistry_enu
t.ExpectFatal(
func() {
- G.Pkgsrc.vartypes.enumFromFiles(
+ G.Pkgsrc.vartypes.enumFromFiles(&G.Pkgsrc,
"mk/platform", `^(\w+)\.mk$`, "$1", "default")
},
- "FATAL: mk/platform: Must contain at least 1 "+
+ "FATAL: ~/mk/platform: Must contain at least 1 "+
"file matching \"^(\\\\w+)\\\\.mk$\".")
}
Index: pkgsrc/pkgtools/pkglint/files/varalignblock.go
diff -u pkgsrc/pkgtools/pkglint/files/varalignblock.go:1.9 pkgsrc/pkgtools/pkglint/files/varalignblock.go:1.10
--- pkgsrc/pkgtools/pkglint/files/varalignblock.go:1.9 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/varalignblock.go Mon Dec 2 23:32:09 2019
@@ -169,8 +169,6 @@ type varalignLine struct {
func (va *VaralignBlock) Process(mkline *MkLine) {
switch {
- case !G.Opts.WarnSpace:
-
case mkline.IsEmpty():
va.Finish()
@@ -299,7 +297,7 @@ func (*VaralignBlock) rightMargin(infos
}
}
}
- return (min & -8) + 8
+ return min&-8 + 8
}
// optimalWidth computes the desired screen width for the variable assignment
@@ -333,7 +331,7 @@ func (*VaralignBlock) optimalWidth(infos
// Widths of the current indentation (including whitespace)
var spaceWidths mklineInts
for _, info := range infos {
- if info.multiEmpty || info.rawIndex > 0 || (outlier > 0 && info.varnameOpWidth() == outlier) {
+ if info.multiEmpty || info.rawIndex > 0 || outlier > 0 && info.varnameOpWidth() == outlier {
continue
}
spaceWidths.append(info.mkline, info.varnameOpSpaceWidth())
@@ -362,7 +360,7 @@ func (*VaralignBlock) optimalWidth(infos
return 0
}
- return (minVarnameOpWidth & -8) + 8
+ return minVarnameOpWidth&-8 + 8
}
// adjustLong allows any follow-up line to start either in column 8 or at
@@ -464,7 +462,7 @@ func (*VaralignBlock) realignMultiEmptyI
if hasSpace && column != oldColumn {
fix.Notef("This variable value should be aligned with tabs, not spaces, to column %d.", column+1)
} else if column != oldColumn {
- fix.Notef("This variable value should be aligned to column %d.", column+1)
+ fix.Notef("This variable value should be aligned to column %d.", column+1) // TODO: to column %d instead of %d.
} else {
fix.Notef("Variable values should be aligned with tabs, not spaces.")
}
Index: pkgsrc/pkgtools/pkglint/files/vardefs.go
diff -u pkgsrc/pkgtools/pkglint/files/vardefs.go:1.79 pkgsrc/pkgtools/pkglint/files/vardefs.go:1.80
--- pkgsrc/pkgtools/pkglint/files/vardefs.go:1.79 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/vardefs.go Mon Dec 2 23:32:09 2019
@@ -335,6 +335,7 @@ func (reg *VarTypeRegistry) compilerLang
languages := make(map[string]bool)
if mklines != nil {
for _, mkline := range mklines.mklines {
+
if mkline.IsVarassign() && mkline.Varname() == "_CXX_STD_VERSIONS" {
words := mkline.ValueFields(mkline.Value())
for _, word := range words {
@@ -368,10 +369,13 @@ func (reg *VarTypeRegistry) compilerLang
// and for all variables matching one of the varcanons, all values
// are added as allowed values.
//
-// If the file cannot be found, the allowed values are taken from
-// defval. This is mostly useful when testing pkglint.
-func (reg *VarTypeRegistry) enumFrom(pkgsrc *Pkgsrc, filename Path, defval string, varcanons ...string) *BasicType {
- mklines := pkgsrc.LoadMkExisting(filename)
+// If the file is not found, the allowed values are taken from
+// defval. This is only done in the pkglint tests.
+func (reg *VarTypeRegistry) enumFrom(
+ src *Pkgsrc, filename PkgsrcPath, defval string,
+ varcanons ...string) *BasicType {
+
+ mklines := src.LoadMkExisting(filename)
if mklines == nil {
return enum(defval)
}
@@ -422,13 +426,16 @@ func (reg *VarTypeRegistry) enumFrom(pkg
// that have a single number in them (such as php72) and ranks them
// from earliest to latest.
//
-// If the directories cannot be found, the allowed values are taken
-// from defval. This is mostly useful when testing pkglint.
-func (reg *VarTypeRegistry) enumFromDirs(pkgsrc *Pkgsrc, category Path, re regex.Pattern, repl string, defval string) *BasicType {
- versions := pkgsrc.ListVersions(category, re, repl, false)
+// If no directories are found, the allowed values are taken
+// from defval. This is only done in the pkglint tests.
+func (reg *VarTypeRegistry) enumFromDirs(
+ src *Pkgsrc, category PkgsrcPath, re regex.Pattern, repl string,
+ defval string) *BasicType {
+
+ versions := src.ListVersions(category, re, repl, false)
if len(versions) == 0 {
if !G.Testing {
- NewLineWhole(category).Fatalf(
+ NewLineWhole(src.File(category)).Fatalf(
"Must contain at least 1 subdirectory matching %q.", re)
}
return enum(defval)
@@ -441,10 +448,13 @@ func (reg *VarTypeRegistry) enumFromDirs
// filtering it through the regular expression and the replacement.
//
// If no files are found, the allowed values are taken
-// from defval. This should only happen in the pkglint tests.
-func (reg *VarTypeRegistry) enumFromFiles(basedir Path, re regex.Pattern, repl string, defval string) *BasicType {
+// from defval. This is only done in the pkglint tests.
+func (reg *VarTypeRegistry) enumFromFiles(
+ src *Pkgsrc, basedir PkgsrcPath, re regex.Pattern, repl string,
+ defval string) *BasicType {
+
var relevant []string
- for _, filename := range dirglob(G.Pkgsrc.File(basedir)) {
+ for _, filename := range src.File(basedir).ReadPaths() {
basename := filename.Base()
if matches(basename, re) {
relevant = append(relevant, replaceAll(basename, re, repl))
@@ -452,7 +462,7 @@ func (reg *VarTypeRegistry) enumFromFile
}
if len(relevant) == 0 {
if !G.Testing {
- NewLineWhole(basedir).Fatalf(
+ NewLineWhole(src.File(basedir)).Fatalf(
"Must contain at least 1 file matching %q.", re)
}
return enum(defval)
@@ -492,6 +502,11 @@ func (reg *VarTypeRegistry) Init(src *Pk
"openjdk8 oracle-jdk8 openjdk7 sun-jdk7 jdk16 jdk15 kaffe",
"_PKG_JVMS.*")
+ platforms := reg.enumFromFiles(src,
+ "mk/platform",
+ `(.*)\.mk$`, "$1",
+ "Cygwin DragonFly FreeBSD Linux NetBSD SunOS")
+
// Last synced with mk/defaults/mk.conf revision 1.300 (fe3d998769f).
reg.usr("USE_CWRAPPERS", enum("yes no auto"))
reg.usr("ALLOW_VULNERABLE_PACKAGES", BtYes)
@@ -1264,7 +1279,7 @@ func (reg *VarTypeRegistry) Init(src *Pk
reg.sys("MANOWN", BtUserGroupName)
reg.pkglist("MASTER_SITES", BtFetchURL)
- for _, filename := range []Path{"mk/fetch/sites.mk", "mk/fetch/fetch.mk"} {
+ for _, filename := range []PkgsrcPath{"mk/fetch/sites.mk", "mk/fetch/fetch.mk"} {
sitesMk := src.LoadMkExisting(filename)
if sitesMk != nil {
sitesMk.ForEach(func(mkline *MkLine) {
@@ -1307,8 +1322,7 @@ func (reg *VarTypeRegistry) Init(src *Pk
reg.pkglistrat("ONLY_FOR_COMPILER", compilers)
reg.pkglistrat("ONLY_FOR_PLATFORM", BtMachinePlatformPattern)
reg.pkgrat("ONLY_FOR_UNPRIVILEGED", BtYesNo)
- reg.sysload("OPSYS", reg.enumFromFiles("mk/platform", `(.*)\.mk$`, "$1",
- "Cygwin DragonFly FreeBSD Linux NetBSD SunOS"))
+ reg.sysload("OPSYS", platforms)
reg.pkglistbl3("OPSYSVARS", BtVariableName)
reg.pkg("OSVERSION_SPECIFIC", BtYes)
reg.sysload("OS_VERSION", BtVersion)
Index: pkgsrc/pkgtools/pkglint/files/vartype.go
diff -u pkgsrc/pkgtools/pkglint/files/vartype.go:1.39 pkgsrc/pkgtools/pkglint/files/vartype.go:1.40
--- pkgsrc/pkgtools/pkglint/files/vartype.go:1.39 Sun Nov 17 01:26:25 2019
+++ pkgsrc/pkgtools/pkglint/files/vartype.go Mon Dec 2 23:32:09 2019
@@ -349,9 +349,9 @@ var (
BtRelativePkgPath = &BasicType{"RelativePkgPath", (*VartypeCheck).RelativePkgPath}
BtRestricted = &BasicType{"Restricted", (*VartypeCheck).Restricted}
BtSedCommands = &BasicType{"SedCommands", (*VartypeCheck).SedCommands}
- BtShellCommand = &BasicType{"ShellCommand", nil}
- BtShellCommands = &BasicType{"ShellCommands", nil}
- BtShellWord = &BasicType{"ShellWord", nil}
+ BtShellCommand = &BasicType{"ShellCommand", nil} // see func init below
+ BtShellCommands = &BasicType{"ShellCommands", nil} // see func init below
+ BtShellWord = &BasicType{"ShellWord", nil} // see func init below
BtStage = &BasicType{"Stage", (*VartypeCheck).Stage}
BtTool = &BasicType{"Tool", (*VartypeCheck).Tool}
BtUnknown = &BasicType{"Unknown", (*VartypeCheck).Unknown}
Index: pkgsrc/pkgtools/pkglint/files/vartypecheck.go
diff -u pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.68 pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.69
--- pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.68 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/vartypecheck.go Mon Dec 2 23:32:09 2019
@@ -225,18 +225,18 @@ func (cv *VartypeCheck) BuildlinkDepmeth
}
func (cv *VartypeCheck) Category() {
- if cv.Value != "wip" && G.Pkgsrc.File(NewPath(cv.Value).JoinNoClean("Makefile")).IsFile() {
+ if cv.Value != "wip" && G.Pkgsrc.File(NewPkgsrcPath(NewPath(cv.Value)).JoinNoClean("Makefile")).IsFile() {
return
}
switch cv.Value {
case
- "chinese", "crosspkgtools",
+ "chinese",
"gnome", "gnustep",
"japanese", "java",
"kde", "korean",
"linux", "local",
- "packages", "perl5", "plan9", "python",
+ "perl5", "plan9", "python",
"R", "ruby",
"scm",
"tcl", "tk",
@@ -442,17 +442,17 @@ func (cv *VartypeCheck) DependencyWithPa
parts := cv.MkLine.ValueSplit(value, ":")
if len(parts) == 2 {
pattern := parts[0]
- relpath := parts[1]
- pathParts := cv.MkLine.ValueSplit(relpath, "/")
+ relpath := NewRelPathString(parts[1])
+ pathParts := relpath.Parts()
pkg := pathParts[len(pathParts)-1]
- if matches(relpath, `^\.\./[^.]`) {
+ if len(pathParts) >= 2 && pathParts[0] == ".." && pathParts[1] != ".." {
cv.Warnf("Dependency paths should have the form \"../../category/package\".")
cv.MkLine.ExplainRelativeDirs()
}
- if !containsVarRef(relpath) {
- MkLineChecker{cv.MkLines, cv.MkLine}.CheckRelativePkgdir(NewPath(relpath))
+ if !containsVarRef(relpath.String()) {
+ MkLineChecker{cv.MkLines, cv.MkLine}.CheckRelativePkgdir(relpath)
}
switch pkg {
@@ -1076,7 +1076,7 @@ func (cv *VartypeCheck) Pkgpath() {
return
}
- pkgpath := NewPath(value)
+ pkgpath := NewPkgsrcPath(NewPath(value))
if !G.Wip && pkgpath.HasPrefixPath("wip") {
cv.MkLine.Errorf("A main pkgsrc package must not depend on a pkgsrc-wip package.")
}
@@ -1164,7 +1164,7 @@ func (cv *VartypeCheck) RPkgVer() {
// RelativePkgDir refers to a package directory, e.g. ../../category/pkgbase.
func (cv *VartypeCheck) RelativePkgDir() {
- MkLineChecker{cv.MkLines, cv.MkLine}.CheckRelativePkgdir(NewPath(cv.Value))
+ MkLineChecker{cv.MkLines, cv.MkLine}.CheckRelativePkgdir(NewRelPathString(cv.Value))
}
// RelativePkgPath refers to a file or directory, e.g. ../../category/pkgbase,
@@ -1172,7 +1172,7 @@ func (cv *VartypeCheck) RelativePkgDir()
//
// See RelativePkgDir, which requires a directory, not a file.
func (cv *VartypeCheck) RelativePkgPath() {
- MkLineChecker{cv.MkLines, cv.MkLine}.CheckRelativePath(NewPath(cv.Value), true)
+ MkLineChecker{cv.MkLines, cv.MkLine}.CheckRelativePath(NewRelPathString(cv.Value), true)
}
func (cv *VartypeCheck) Restricted() {
Index: pkgsrc/pkgtools/pkglint/files/histogram/histogram.go
diff -u pkgsrc/pkgtools/pkglint/files/histogram/histogram.go:1.4 pkgsrc/pkgtools/pkglint/files/histogram/histogram.go:1.5
--- pkgsrc/pkgtools/pkglint/files/histogram/histogram.go:1.4 Wed Nov 7 20:58:23 2018
+++ pkgsrc/pkgtools/pkglint/files/histogram/histogram.go Mon Dec 2 23:32:09 2019
@@ -35,7 +35,7 @@ func (h *Histogram) PrintStats(out io.Wr
sort.SliceStable(entries, func(i, j int) bool {
ei := entries[i]
ej := entries[j]
- return ej.count < ei.count || (ei.count == ej.count && ei.s < ej.s)
+ return ej.count < ei.count || ei.count == ej.count && ei.s < ej.s
})
for i, entry := range entries {
Index: pkgsrc/pkgtools/pkglint/files/intqa/qa.go
diff -u pkgsrc/pkgtools/pkglint/files/intqa/qa.go:1.1 pkgsrc/pkgtools/pkglint/files/intqa/qa.go:1.2
--- pkgsrc/pkgtools/pkglint/files/intqa/qa.go:1.1 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/intqa/qa.go Mon Dec 2 23:32:10 2019
@@ -43,7 +43,9 @@ const (
EMethodsSameFile
)
-// QAChecker ensures that all test names follow a common naming scheme:
+// QAChecker analyzes Go source code for consistency.
+//
+// Among others, it enforces a strict naming scheme for test methods:
// Test_${Type}_${Method}__${description_using_underscores}
// Each of the variable parts may be omitted.
type QAChecker struct {
@@ -90,8 +92,9 @@ func (ck *QAChecker) Configure(filenames
func (ck *QAChecker) Check() {
ck.load(".")
- ck.checkTestees()
+ ck.checkTesteesTest()
ck.checkTests()
+ ck.checkMethodsSameFile()
ck.checkOrder()
ck.print()
}
@@ -306,11 +309,6 @@ func (ck *QAChecker) checkTestDescr(test
test.fullName(), test.descr)
}
-func (ck *QAChecker) checkTestees() {
- ck.checkTesteesTest()
- ck.checkTesteesMethodsSameFile()
-}
-
// checkTesteesTest ensures that each testee has a corresponding unit test.
func (ck *QAChecker) checkTesteesTest() {
tested := make(map[*testee]bool)
@@ -334,20 +332,24 @@ func (ck *QAChecker) checkTesteesTest()
// checkTesteesMethodsSameFile ensures that all methods of a type are
// defined in the same file or in the corresponding test file.
-func (ck *QAChecker) checkTesteesMethodsSameFile() {
- types := map[string]*testee{}
+func (ck *QAChecker) checkMethodsSameFile() {
+ types := map[string]*code{}
+ var methods []*code
+
for _, testee := range ck.testees {
if testee.isType() {
- types[testee.Type] = testee
+ types[testee.Type] = &testee.code
+ } else if testee.isMethod() {
+ methods = append(methods, &testee.code)
}
}
-
- for _, testee := range ck.testees {
- if !testee.isMethod() {
- continue
+ for _, test := range ck.tests {
+ if test.isMethod() {
+ methods = append(methods, &test.code)
}
- method := testee
+ }
+ for _, method := range methods {
typ := types[method.Type]
if typ == nil || method.file == typ.file {
continue
@@ -356,9 +358,9 @@ func (ck *QAChecker) checkTesteesMethods
if method.isTestScope() == typ.isTestScope() {
ck.addError(
EMethodsSameFile,
- testee.code,
+ *method,
"Method %s must be in %s, like its type.",
- testee.fullName(), typ.file)
+ method.fullName(), typ.file)
continue
}
@@ -369,9 +371,9 @@ func (ck *QAChecker) checkTesteesMethods
ck.addError(
EMethodsSameFile,
- testee.code,
+ *method,
"Method %s must be in %s, corresponding to its type.",
- testee.fullName(), correctFile)
+ method.fullName(), correctFile)
}
}
Index: pkgsrc/pkgtools/pkglint/files/intqa/qa_test.go
diff -u pkgsrc/pkgtools/pkglint/files/intqa/qa_test.go:1.1 pkgsrc/pkgtools/pkglint/files/intqa/qa_test.go:1.2
--- pkgsrc/pkgtools/pkglint/files/intqa/qa_test.go:1.1 Wed Nov 27 22:10:07 2019
+++ pkgsrc/pkgtools/pkglint/files/intqa/qa_test.go Mon Dec 2 23:32:10 2019
@@ -293,6 +293,15 @@ func (s *Suite) Test_QAChecker_isTest(c
testFunc("f_test.go", "func Test_Type_Method(t *testing.T) {}", true)
testFunc("f_test.go", "func Test_Type_Method(X) {}", false)
testFunc("f_test.go", "func Test_Type_Method(int) {}", false)
+
+ // Having such a method in a test suite is unlikely since check.v1
+ // checks the number of parameters.
+ testFunc("f_test.go", "func Test_Type_Method() {}", false)
+ testFunc("f_test.go", "func (s *Suite) Test(int, int) {}", false)
+
+ // In a test helper type, it is reasonable that some of the method
+ // names start with "Test". This doesn't make them tests though.
+ testFunc("f_test.go", "func (h *Helper) TestEqInt(int, int) {}", false)
}
func (s *Suite) Test_QAChecker_addTestee(c *check.C) {
@@ -437,18 +446,6 @@ func (s *Suite) Test_QAChecker_checkTest
"must not use CamelCase in the first word.")
}
-func (s *Suite) Test_QAChecker_checkTestees(c *check.C) {
- ck := s.Init(c)
-
- ck.testees = []*testee{s.newTestee("s.go", "", "Func", 0)}
- ck.tests = nil // force an error
-
- ck.checkTestees()
-
- s.CheckErrors(
- "Missing unit test \"Test_Func\" for \"Func\".")
-}
-
func (s *Suite) Test_QAChecker_checkTesteesTest(c *check.C) {
ck := s.Init(c)
@@ -471,7 +468,7 @@ func (s *Suite) Test_QAChecker_checkTest
"Missing unit test \"Test_Type_Method\" for \"Type.Method\".")
}
-func (s *Suite) Test_QAChecker_checkTesteesMethodsSameFile(c *check.C) {
+func (s *Suite) Test_QAChecker_checkMethodsSameFile(c *check.C) {
ck := s.Init(c)
ck.addTestee(code{"main.go", "Main", "", 0})
@@ -482,14 +479,17 @@ func (s *Suite) Test_QAChecker_checkTest
ck.addTestee(code{"main_test.go", "T", "", 100})
ck.addTestee(code{"main_test.go", "T", "MethodOk", 101})
ck.addTestee(code{"other_test.go", "T", "MethodWrong", 102})
+ ck.addTest(code{"main_test.go", "T", "Test_MethodOk", 101})
+ ck.addTest(code{"other_test.go", "T", "Test_MethodWrong", 102})
- ck.checkTesteesMethodsSameFile()
+ ck.checkMethodsSameFile()
s.CheckErrors(
"Method Main.MethodWrong must be in main.go, like its type.",
"Method Main.MethodWrongTest must be in main_test.go, "+
"corresponding to its type.",
- "Method T.MethodWrong must be in main_test.go, like its type.")
+ "Method T.MethodWrong must be in main_test.go, like its type.",
+ "Method T.Test_MethodWrong must be in main_test.go, like its type.")
}
func (s *Suite) Test_QAChecker_errorsMask(c *check.C) {
Index: pkgsrc/pkgtools/pkglint/files/textproc/lexer_bench_test.go
diff -u pkgsrc/pkgtools/pkglint/files/textproc/lexer_bench_test.go:1.1 pkgsrc/pkgtools/pkglint/files/textproc/lexer_bench_test.go:1.2
--- pkgsrc/pkgtools/pkglint/files/textproc/lexer_bench_test.go:1.1 Sun Dec 2 01:57:48 2018
+++ pkgsrc/pkgtools/pkglint/files/textproc/lexer_bench_test.go Mon Dec 2 23:32:10 2019
@@ -181,7 +181,7 @@ func Benchmark_Direct_Compare_fold_case(
var sum int
for i := 0; i < b.N; i++ {
i := byte(i)
- if 'A' <= (i&^0x20) && (i&^0x20) <= 'Z' || '0' <= i && i <= '9' || i == '_' {
+ if 'A' <= i&^0x20 && i&^0x20 <= 'Z' || '0' <= i && i <= '9' || i == '_' {
sum++
}
}
Index: pkgsrc/pkgtools/pkglint/files/trace/tracing_test.go
diff -u pkgsrc/pkgtools/pkglint/files/trace/tracing_test.go:1.6 pkgsrc/pkgtools/pkglint/files/trace/tracing_test.go:1.7
--- pkgsrc/pkgtools/pkglint/files/trace/tracing_test.go:1.6 Wed Nov 27 22:10:08 2019
+++ pkgsrc/pkgtools/pkglint/files/trace/tracing_test.go Mon Dec 2 23:32:10 2019
@@ -93,16 +93,28 @@ func (s *Suite) Test__fixed_argument_var
"TRACE: - netbsd.org/pkglint/trace.(*Suite).Test__fixed_argument_variants.func1()\n")
}
-func (s *Suite) Test__stringer_arg(c *check.C) {
+func (s *Suite) Test_Tracer_Call__Stringer_arg(c *check.C) {
tracer := &s.Tracer
output := s.captureTracingOutput(func() {
- defer tracer.Call(str{}, &str{})()
+ defer tracer.Call(stringer{}, &stringer{})()
})
c.Check(output, check.Equals, ""+
- "TRACE: + netbsd.org/pkglint/trace.(*Suite).Test__stringer_arg.func1(It's a string, It's a string)\n"+
- "TRACE: - netbsd.org/pkglint/trace.(*Suite).Test__stringer_arg.func1(It's a string, It's a string)\n")
+ "TRACE: + netbsd.org/pkglint/trace.(*Suite).Test_Tracer_Call__Stringer_arg.func1(It's a string, It's a string)\n"+
+ "TRACE: - netbsd.org/pkglint/trace.(*Suite).Test_Tracer_Call__Stringer_arg.func1(It's a string, It's a string)\n")
+}
+
+func (s *Suite) Test_Tracer_Call__GoStringer_arg(c *check.C) {
+ tracer := &s.Tracer
+
+ output := s.captureTracingOutput(func() {
+ defer tracer.Call(goStringer{}, &goStringer{})()
+ })
+
+ c.Check(output, check.Equals, ""+
+ "TRACE: + netbsd.org/pkglint/trace.(*Suite).Test_Tracer_Call__GoStringer_arg.func1(\"It's a string\", \"It's a string\")\n"+
+ "TRACE: - netbsd.org/pkglint/trace.(*Suite).Test_Tracer_Call__GoStringer_arg.func1(\"It's a string\", \"It's a string\")\n")
}
func (s *Suite) Test_Tracer_traceCall__panic(c *check.C) {
@@ -137,14 +149,16 @@ func (s *Suite) captureTracingOutput(act
return out.String()
}
-type str struct{}
+type stringer struct{}
-func (str) String() string {
- return "It's a string"
-}
+func (stringer) String() string { return "It's a string" }
+
+type goStringer struct{}
+
+func (goStringer) GoString() string { return "\"It's a string\"" }
-func (s *Suite) Test__qa(c *check.C) {
- ck := intqa.NewQAChecker(c.Errorf)
+func Test__qa(t *testing.T) {
+ ck := intqa.NewQAChecker(t.Errorf)
ck.Configure("*", "*", "*", -intqa.EMissingTest)
ck.Check()
}
Home |
Main Index |
Thread Index |
Old Index