summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrillig <rillig@pkgsrc.org>2015-12-05 08:54:08 +0000
committerrillig <rillig@pkgsrc.org>2015-12-05 08:54:08 +0000
commit0877f14540c0accf4deb3c2926ecc4f349f2fe27 (patch)
tree3aaae751b6594fe02578755ccff8cb1406827bb8
parent8ad1bbc2c95ff3b9469edde34991ce31bfeb47ef (diff)
downloadpkgsrc-0877f14540c0accf4deb3c2926ecc4f349f2fe27.tar.gz
Updated pkglint to 5.2.
Changes since 5.1: * Fixed distinfo check for unrecorded patch files (thanks, wiz) * Command line options parser accepts abbreviations (--a instead of --autofix) * Realistic unit tests using temporary files * General code cleanup (using gometalinter)
-rw-r--r--pkgtools/pkglint/Makefile4
-rw-r--r--pkgtools/pkglint/files/category.go86
-rw-r--r--pkgtools/pkglint/files/check_test.go17
-rw-r--r--pkgtools/pkglint/files/deprecated.go3
-rw-r--r--pkgtools/pkglint/files/deprecated_test.go14
-rw-r--r--pkgtools/pkglint/files/distinfo.go67
-rw-r--r--pkgtools/pkglint/files/distinfo_test.go83
-rw-r--r--pkgtools/pkglint/files/getopt.go154
-rw-r--r--pkgtools/pkglint/files/getopt_test.go28
-rw-r--r--pkgtools/pkglint/files/globaldata.go60
-rw-r--r--pkgtools/pkglint/files/globaldata_test.go2
-rw-r--r--pkgtools/pkglint/files/line.go74
-rw-r--r--pkgtools/pkglint/files/main.go2
-rw-r--r--pkgtools/pkglint/files/makefiles.go2
-rw-r--r--pkgtools/pkglint/files/mkcond.go2
-rw-r--r--pkgtools/pkglint/files/mkcond_test.go6
-rw-r--r--pkgtools/pkglint/files/patches.go1
-rw-r--r--pkgtools/pkglint/files/pkglint.go1
-rw-r--r--pkgtools/pkglint/files/pkglint_test.go9
-rw-r--r--pkgtools/pkglint/files/plist_test.go2
-rw-r--r--pkgtools/pkglint/files/shell_test.go96
-rw-r--r--pkgtools/pkglint/files/substcontext.go64
-rw-r--r--pkgtools/pkglint/files/toplevel.go5
-rw-r--r--pkgtools/pkglint/files/toplevel_test.go32
-rw-r--r--pkgtools/pkglint/files/util.go22
-rw-r--r--pkgtools/pkglint/files/util_test.go20
-rw-r--r--pkgtools/pkglint/files/vardefs.go4
-rw-r--r--pkgtools/pkglint/files/vars.go6
-rw-r--r--pkgtools/pkglint/files/vars_test.go17
-rw-r--r--pkgtools/pkglint/files/vartype.go34
-rw-r--r--pkgtools/pkglint/files/vartypecheck.go2
-rw-r--r--pkgtools/pkglint/files/varusecontext.go12
32 files changed, 583 insertions, 348 deletions
diff --git a/pkgtools/pkglint/Makefile b/pkgtools/pkglint/Makefile
index af8628fb171..0f70a880576 100644
--- a/pkgtools/pkglint/Makefile
+++ b/pkgtools/pkglint/Makefile
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.469 2015/12/02 21:46:46 rillig Exp $
+# $NetBSD: Makefile,v 1.470 2015/12/05 08:54:08 rillig Exp $
-PKGNAME= pkglint-5.1
+PKGNAME= pkglint-5.2
DISTFILES= # none
CATEGORIES= pkgtools
diff --git a/pkgtools/pkglint/files/category.go b/pkgtools/pkglint/files/category.go
index a6b5db21fce..06dd0acd10f 100644
--- a/pkgtools/pkglint/files/category.go
+++ b/pkgtools/pkglint/files/category.go
@@ -4,8 +4,8 @@ import (
"sort"
)
-type Subdir struct {
- subdir string
+type subdir struct {
+ name string
line *Line
active bool
}
@@ -42,33 +42,33 @@ func checkdirCategory() {
fSubdirs := getSubdirs(G.currentDir)
sort.Sort(sort.StringSlice(fSubdirs))
- var mSubdirs []Subdir
+ var mSubdirs []subdir
prevSubdir := ""
for !exp.eof() {
line := exp.currentLine()
text := line.text
- if m, commentFlag, indentation, subdir, comment := match4(text, `^(#?)SUBDIR\+=(\s*)(\S+)\s*(?:#\s*(.*?)\s*|)$`); m {
+ if m, commentFlag, indentation, name, comment := match4(text, `^(#?)SUBDIR\+=(\s*)(\S+)\s*(?:#\s*(.*?)\s*|)$`); m {
commentedOut := commentFlag == "#"
if commentedOut && comment == "" {
- line.warnf("%q commented out without giving a reason.", subdir)
+ line.warnf("%q commented out without giving a reason.", name)
}
if indentation != "\t" {
line.warnf("Indentation should be a single tab character.")
}
- if subdir == prevSubdir {
- line.errorf("%q must only appear once.", subdir)
- } else if subdir < prevSubdir {
- line.warnf("%q should come before %q.", subdir, prevSubdir)
+ if name == prevSubdir {
+ line.errorf("%q must only appear once.", name)
+ } else if name < prevSubdir {
+ line.warnf("%q should come before %q.", name, prevSubdir)
} else {
// correctly ordered
}
- mSubdirs = append(mSubdirs, Subdir{subdir, line, !commentedOut})
- prevSubdir = subdir
+ mSubdirs = append(mSubdirs, subdir{name, line, !commentedOut})
+ prevSubdir = name
exp.advance()
} else {
@@ -88,62 +88,62 @@ func checkdirCategory() {
fCheck[fsub] = true
}
for _, msub := range mSubdirs {
- mCheck[msub.subdir] = true
+ mCheck[msub.name] = true
}
- f_index, f_atend, f_neednext, f_current := 0, false, true, ""
- m_index, m_atend, m_neednext, m_current := 0, false, true, ""
+ fIndex, fAtend, fNeednext, fCurrent := 0, false, true, ""
+ mIndex, mAtend, mNeednext, mCurrent := 0, false, true, ""
var subdirs []string
var line *Line
- m_active := false
+ mActive := false
- for !(m_atend && f_atend) {
- if !m_atend && m_neednext {
- m_neednext = false
- if m_index >= len(mSubdirs) {
- m_atend = true
+ for !(mAtend && fAtend) {
+ if !mAtend && mNeednext {
+ mNeednext = false
+ if mIndex >= len(mSubdirs) {
+ mAtend = true
line = exp.currentLine()
continue
} else {
- m_current = mSubdirs[m_index].subdir
- line = mSubdirs[m_index].line
- m_active = mSubdirs[m_index].active
- m_index++
+ mCurrent = mSubdirs[mIndex].name
+ line = mSubdirs[mIndex].line
+ mActive = mSubdirs[mIndex].active
+ mIndex++
}
}
- if !f_atend && f_neednext {
- f_neednext = false
- if f_index >= len(fSubdirs) {
- f_atend = true
+ if !fAtend && fNeednext {
+ fNeednext = false
+ if fIndex >= len(fSubdirs) {
+ fAtend = true
continue
} else {
- f_current = fSubdirs[f_index]
- f_index++
+ fCurrent = fSubdirs[fIndex]
+ fIndex++
}
}
- if !f_atend && (m_atend || f_current < m_current) {
- if !mCheck[f_current] {
- line.errorf("%q exists in the file system, but not in the Makefile.", f_current)
- line.insertBefore("SUBDIR+=\t" + f_current)
+ if !fAtend && (mAtend || fCurrent < mCurrent) {
+ if !mCheck[fCurrent] {
+ line.errorf("%q exists in the file system, but not in the Makefile.", fCurrent)
+ line.insertBefore("SUBDIR+=\t" + fCurrent)
}
- f_neednext = true
+ fNeednext = true
- } else if !m_atend && (f_atend || m_current < f_current) {
- if !fCheck[m_current] {
- line.errorf("%q exists in the Makefile, but not in the file system.", m_current)
+ } else if !mAtend && (fAtend || mCurrent < fCurrent) {
+ if !fCheck[mCurrent] {
+ line.errorf("%q exists in the Makefile, but not in the file system.", mCurrent)
line.delete()
}
- m_neednext = true
+ mNeednext = true
} else { // f_current == m_current
- f_neednext = true
- m_neednext = true
- if m_active {
- subdirs = append(subdirs, G.currentDir+"/"+m_current)
+ fNeednext = true
+ mNeednext = true
+ if mActive {
+ subdirs = append(subdirs, G.currentDir+"/"+mCurrent)
}
}
}
diff --git a/pkgtools/pkglint/files/check_test.go b/pkgtools/pkglint/files/check_test.go
index 3f0e53ce0ff..25b10d644a6 100644
--- a/pkgtools/pkglint/files/check_test.go
+++ b/pkgtools/pkglint/files/check_test.go
@@ -2,6 +2,10 @@ package main
import (
"bytes"
+ "io/ioutil"
+ "os"
+ "path"
+ "path/filepath"
"testing"
check "gopkg.in/check.v1"
@@ -13,6 +17,7 @@ var deepEquals = check.DeepEquals
type Suite struct {
stdout bytes.Buffer
stderr bytes.Buffer
+ tmpdir string
}
func (s *Suite) Stdout() string {
@@ -49,6 +54,17 @@ func (s *Suite) DummyLine() *Line {
return NewLine("fname", "1", "dummy", nil)
}
+func (s *Suite) CreateTmpFile(c *check.C, fname, content string) {
+ if s.tmpdir == "" {
+ s.tmpdir = filepath.ToSlash(c.MkDir())
+ }
+ err := os.MkdirAll(s.tmpdir+"/"+path.Dir(fname), 0777)
+ c.Check(err, check.IsNil)
+
+ err = ioutil.WriteFile(s.tmpdir+"/"+fname, []byte(content), 0666)
+ c.Check(err, check.IsNil)
+}
+
func (s *Suite) ExpectFatalError(action func()) {
if r := recover(); r != nil {
if _, ok := r.(pkglintFatal); ok {
@@ -69,6 +85,7 @@ func (s *Suite) TearDownTest(c *check.C) {
if out := s.Output(); out != "" {
c.Logf("Unchecked output; check with: c.Check(s.Output(), equals, %q)", out)
}
+ s.tmpdir = ""
}
var _ = check.Suite(new(Suite))
diff --git a/pkgtools/pkglint/files/deprecated.go b/pkgtools/pkglint/files/deprecated.go
index feb2c1d70eb..e286b9a1475 100644
--- a/pkgtools/pkglint/files/deprecated.go
+++ b/pkgtools/pkglint/files/deprecated.go
@@ -137,9 +137,6 @@ func getDeprecatedVars() map[string]string {
"_PKG_SILENT": "Use RUN (with more error checking) instead.",
"_PKG_DEBUG": "Use RUN (with more error checking) instead.",
"LICENCE": "Use LICENSE instead.",
- // The following variable is not yet deprecated, as there has been
- // a large disagreement on the proper spelling.
- //ACCEPTABLE_LICENCES Use ACCEPTABLE_LICENSES instead.
// November 2007
//USE_NCURSES Include "../../devel/ncurses/buildlink3.mk" instead.
diff --git a/pkgtools/pkglint/files/deprecated_test.go b/pkgtools/pkglint/files/deprecated_test.go
new file mode 100644
index 00000000000..37687c31624
--- /dev/null
+++ b/pkgtools/pkglint/files/deprecated_test.go
@@ -0,0 +1,14 @@
+package main
+
+import (
+ check "gopkg.in/check.v1"
+)
+
+func (s *Suite) TestDeprecated(c *check.C) {
+ G.globalData.deprecated = getDeprecatedVars()
+
+ line := NewLine("Makefile", "5", "dummy", nil)
+ checklineMkVarassign(line, "USE_PERL5", "=", "yes", "")
+
+ c.Check(s.Output(), equals, "WARN: Makefile:5: Definition of USE_PERL5 is deprecated. Use USE_TOOLS+=perl or USE_TOOLS+=perl:run instead.\n")
+}
diff --git a/pkgtools/pkglint/files/distinfo.go b/pkgtools/pkglint/files/distinfo.go
index 5d5e561aeca..e76d7e624c0 100644
--- a/pkgtools/pkglint/files/distinfo.go
+++ b/pkgtools/pkglint/files/distinfo.go
@@ -29,11 +29,11 @@ func checklinesDistinfo(lines []*Line) {
}
type distinfoLinesChecker struct {
- fname string
- patchdir string // Relative to G.currentDir
- isCommitted bool
+ distinfoFilename string
+ patchdir string // Relative to G.currentDir
+ distinfoIsCommitted bool
- patches map[string]bool
+ patches map[string]bool // "patch-aa" => true
previousFilename string
isPatch bool
algorithms []string
@@ -49,28 +49,28 @@ func (ck *distinfoLinesChecker) checkLines(lines []*Line) {
if i < 2 {
continue
}
- m, alg, fname, hash := match3(line.text, `^(\w+) \((\w[^)]*)\) = (.*)(?: bytes)?$`)
+ m, alg, filename, hash := match3(line.text, `^(\w+) \((\w[^)]*)\) = (.*)(?: bytes)?$`)
if !m {
line.errorf("Invalid line.")
continue
}
- if fname != ck.previousFilename {
- ck.onFilenameChange(line, fname)
+ if filename != ck.previousFilename {
+ ck.onFilenameChange(line, filename)
}
ck.algorithms = append(ck.algorithms, alg)
- ck.checkGlobalMismatch(line, fname, alg, hash)
- ck.checkUncommittedPatch(line, fname, hash)
+ ck.checkGlobalMismatch(line, filename, alg, hash)
+ ck.checkUncommittedPatch(line, filename, hash)
}
- ck.onFilenameChange(NewLine(ck.fname, "EOF", "", nil), "")
+ ck.onFilenameChange(NewLine(ck.distinfoFilename, "EOF", "", nil), "")
}
-func (ctx *distinfoLinesChecker) onFilenameChange(line *Line, nextFname string) {
- prevFname := ctx.previousFilename
+func (ck *distinfoLinesChecker) onFilenameChange(line *Line, nextFname string) {
+ prevFname := ck.previousFilename
if prevFname != "" {
- algorithms := strings.Join(ctx.algorithms, ", ")
- if ctx.isPatch {
+ algorithms := strings.Join(ck.algorithms, ", ")
+ if ck.isPatch {
if algorithms != "SHA1" {
line.errorf("Expected SHA1 hash for %s, got %s.", prevFname, algorithms)
}
@@ -81,15 +81,15 @@ func (ctx *distinfoLinesChecker) onFilenameChange(line *Line, nextFname string)
}
}
- ctx.isPatch = matches(nextFname, `^patch-.+$`) && fileExists(G.currentDir+"/"+ctx.patchdir+"/"+nextFname)
- ctx.previousFilename = nextFname
- ctx.algorithms = nil
+ ck.isPatch = matches(nextFname, `^patch-.+$`) && fileExists(G.currentDir+"/"+ck.patchdir+"/"+nextFname)
+ ck.previousFilename = nextFname
+ ck.algorithms = nil
}
-func (ctx *distinfoLinesChecker) checkPatchSha1(line *Line, fname, distinfoSha1Hex string) {
- patchBytes, err := ioutil.ReadFile(fname)
+func (ck *distinfoLinesChecker) checkPatchSha1(line *Line, patchFname, distinfoSha1Hex string) {
+ patchBytes, err := ioutil.ReadFile(G.currentDir + "/" + patchFname)
if err != nil {
- line.errorf("%s does not exist.", fname)
+ line.errorf("%s does not exist.", patchFname)
return
}
@@ -102,18 +102,21 @@ func (ctx *distinfoLinesChecker) checkPatchSha1(line *Line, fname, distinfoSha1H
}
fileSha1Hex := sprintf("%x", h.Sum(nil))
if distinfoSha1Hex != fileSha1Hex {
- line.errorf("%s hash of %s differs (distinfo has %s, patch file has %s). Run \"%s makepatchsum\".", "SHA1", fname, distinfoSha1Hex, fileSha1Hex, confMake)
+ line.errorf("%s hash of %s differs (distinfo has %s, patch file has %s). Run \"%s makepatchsum\".", "SHA1", patchFname, distinfoSha1Hex, fileSha1Hex, confMake)
}
}
func (ck *distinfoLinesChecker) checkUnrecordedPatches() {
files, err := ioutil.ReadDir(G.currentDir + "/" + ck.patchdir)
if err != nil {
- for _, file := range files {
- patch := file.Name()
- if !ck.patches[patch] {
- errorf(ck.fname, NO_LINES, "patch is not recorded. Run \"%s makepatchsum\".", confMake)
- }
+ _ = G.opts.DebugUnchecked && debugf(ck.distinfoFilename, NO_LINES, "Cannot read patchesDir %q: %s", ck.patchdir, err)
+ return
+ }
+
+ for _, file := range files {
+ patch := file.Name()
+ if !ck.patches[patch] {
+ errorf(ck.distinfoFilename, NO_LINES, "patch %q is not recorded. Run \"%s makepatchsum\".", ck.patchdir+"/"+patch, confMake)
}
}
}
@@ -134,13 +137,13 @@ func (ck *distinfoLinesChecker) checkGlobalMismatch(line *Line, fname, alg, hash
}
}
-func (ck *distinfoLinesChecker) checkUncommittedPatch(line *Line, fname, sha1Hash string) {
+func (ck *distinfoLinesChecker) checkUncommittedPatch(line *Line, patchName, sha1Hash string) {
if ck.isPatch {
- fname := G.currentDir + "/" + ck.patchdir + "/" + fname
- if ck.isCommitted && !isCommitted(fname) {
- line.warnf("%s/%s is registered in distinfo but not added to CVS.", ck.patchdir, fname)
+ patchFname := ck.patchdir + "/" + patchName
+ if ck.distinfoIsCommitted && !isCommitted(G.currentDir+"/"+patchFname) {
+ line.warnf("%s is registered in distinfo but not added to CVS.", patchFname)
}
- ck.checkPatchSha1(line, fname, sha1Hash)
- ck.patches[fname] = true
+ ck.checkPatchSha1(line, patchFname, sha1Hash)
+ ck.patches[patchName] = true
}
}
diff --git a/pkgtools/pkglint/files/distinfo_test.go b/pkgtools/pkglint/files/distinfo_test.go
index 653142c3146..8b55439d188 100644
--- a/pkgtools/pkglint/files/distinfo_test.go
+++ b/pkgtools/pkglint/files/distinfo_test.go
@@ -2,36 +2,79 @@ package main
import (
check "gopkg.in/check.v1"
- "io/ioutil"
- "os"
- "path/filepath"
)
func (s *Suite) TestChecklinesDistinfo(c *check.C) {
- tmpdir := c.MkDir()
- patchesdir := tmpdir + "/patches"
- patchAa := patchesdir + "/patch-aa"
- patchContents := "" +
- "$" + "NetBSD$ line is ignored\n" +
- "patch contents\n"
-
- os.Mkdir(patchesdir, 0777)
- if err := ioutil.WriteFile(patchAa, []byte(patchContents), 0666); err != nil {
- c.Fatal(err)
- }
- G.currentDir = filepath.ToSlash(tmpdir)
-
- lines := s.NewLines("distinfo",
+ s.CreateTmpFile(c, "patches/patch-aa", ""+
+ "$"+"NetBSD$ line is ignored\n"+
+ "patch contents\n")
+ G.currentDir = s.tmpdir
+
+ checklinesDistinfo(s.NewLines("distinfo",
"should be the RCS ID",
"should be empty",
"MD5 (distfile.tar.gz) = 12345678901234567890123456789012",
"SHA1 (distfile.tar.gz) = 1234567890123456789012345678901234567890",
- "SHA1 (patch-aa) = 6b98dd609f85a9eb9c4c1e4e7055a6aaa62b7cc7")
-
- checklinesDistinfo(lines)
+ "SHA1 (patch-aa) = 6b98dd609f85a9eb9c4c1e4e7055a6aaa62b7cc7"))
c.Check(s.Output(), equals, ""+
"ERROR: distinfo:1: Expected \"$"+"NetBSD$\".\n"+
"NOTE: distinfo:2: Empty line expected.\n"+
"ERROR: distinfo:5: Expected SHA1, RMD160, SHA512, Size checksums for \"distfile.tar.gz\", got MD5, SHA1.\n")
}
+
+func (s *Suite) TestChecklinesDistinfo_GlobalHashMismatch(c *check.C) {
+ otherLine := NewLine("other/distinfo", "7", "dummy", nil)
+ G.ipcDistinfo = make(map[string]*Hash)
+ G.ipcDistinfo["SHA512:pkgname-1.0.tar.gz"] = &Hash{"asdfasdf", otherLine}
+
+ checklinesDistinfo(s.NewLines("distinfo",
+ "$"+"NetBSD$",
+ "",
+ "SHA512 (pkgname-1.0.tar.gz) = 12341234"))
+
+ c.Check(s.Output(), equals, ""+
+ "ERROR: distinfo:3: The hash SHA512 for pkgname-1.0.tar.gz is 12341234, ...\n"+
+ "ERROR: other/distinfo:7: ... which differs from asdfasdf.\n"+
+ "ERROR: distinfo:EOF: Expected SHA1, RMD160, SHA512, Size checksums for \"pkgname-1.0.tar.gz\", got SHA512.\n")
+}
+
+func (s *Suite) TestChecklinesDistinfo_UncommittedPatch(c *check.C) {
+ s.CreateTmpFile(c, "patches/patch-aa", ""+
+ "$"+"NetBSD$\n"+
+ "\n"+
+ "--- oldfile\n"+
+ "+++ newfile\n"+
+ "@@ -1,1 +1,1 @@\n"+
+ "-old\n"+
+ "+new\n")
+ s.CreateTmpFile(c, "CVS/Entries",
+ "/distinfo/...\n")
+ G.currentDir = s.tmpdir
+
+ checklinesDistinfo(s.NewLines(s.tmpdir+"/distinfo",
+ "$"+"NetBSD$",
+ "",
+ "SHA1 (patch-aa) = 5ad1fb9b3c328fff5caa1a23e8f330e707dd50c0"))
+
+ c.Check(s.Output(), equals, "WARN: "+s.tmpdir+"/distinfo:3: patches/patch-aa is registered in distinfo but not added to CVS.\n")
+}
+
+func (s *Suite) TestChecklinesDistinfo_UnrecordedPatches(c *check.C) {
+ s.CreateTmpFile(c, "patches/patch-aa", "")
+ s.CreateTmpFile(c, "patches/patch-src-Makefile", "")
+ G.currentDir = s.tmpdir
+
+ checklinesDistinfo(s.NewLines(s.tmpdir+"/distinfo",
+ "$"+"NetBSD$",
+ "",
+ "SHA1 (distfile.tar.gz) = ...",
+ "RMD160 (distfile.tar.gz) = ...",
+ "SHA512 (distfile.tar.gz) = ...",
+ "Size (distfile.tar.gz) = 1024 bytes"))
+
+ c.Check(s.Output(), equals, sprintf(""+
+ "ERROR: %[1]s: patch \"patches/patch-aa\" is not recorded. Run \"%s makepatchsum\".\n"+
+ "ERROR: %[1]s: patch \"patches/patch-src-Makefile\" is not recorded. Run \"%s makepatchsum\".\n",
+ s.tmpdir+"/distinfo", confMake))
+}
diff --git a/pkgtools/pkglint/files/getopt.go b/pkgtools/pkglint/files/getopt.go
index a07cd41f09c..6cea5d037c9 100644
--- a/pkgtools/pkglint/files/getopt.go
+++ b/pkgtools/pkglint/files/getopt.go
@@ -11,54 +11,50 @@ import (
)
type Options struct {
- options []*Option
+ options []*option
}
func NewOptions() *Options {
return new(Options)
}
-func (self *Options) AddFlagGroup(shortName rune, longName, argDescription, description string) *FlagGroup {
+func (o *Options) AddFlagGroup(shortName rune, longName, argDescription, description string) *FlagGroup {
grp := new(FlagGroup)
- opt := &Option{shortName, longName, argDescription, description, grp}
- self.options = append(self.options, opt)
+ opt := &option{shortName, longName, argDescription, description, grp}
+ o.options = append(o.options, opt)
return grp
}
-func (self *Options) AddFlagVar(shortName rune, longName string, pflag *bool, defval bool, description string) {
+func (o *Options) AddFlagVar(shortName rune, longName string, pflag *bool, defval bool, description string) {
*pflag = defval
- opt := &Option{shortName, longName, "", description, pflag}
- self.options = append(self.options, opt)
+ opt := &option{shortName, longName, "", description, pflag}
+ o.options = append(o.options, opt)
}
-func (self *Options) Parse(args []string) (remainingArgs []string, err error) {
- defer func() {
- if r := recover(); r != nil {
- if rerr, ok := r.(OptErr); ok {
- err = OptErr(args[0] + ": " + string(rerr))
- } else {
- panic(r)
- }
- }
- }()
-
- for i := 1; i < len(args); i++ {
+func (o *Options) Parse(args []string) (remainingArgs []string, err error) {
+ var skip int
+ for i := 1; i < len(args) && err == nil; i++ {
arg := args[i]
switch {
case arg == "--":
- return append(remainingArgs, args[i+1:]...), nil
+ return append(remainingArgs, args[i+1:]...), err
case hasPrefix(arg, "--"):
- i += self.parseLongOption(args, i, arg[2:])
+ skip, err = o.parseLongOption(args, i, arg[2:])
+ i += skip
case hasPrefix(arg, "-"):
- i += self.parseShortOptions(args, i, arg[1:])
+ skip, err = o.parseShortOptions(args, i, arg[1:])
+ i += skip
default:
remainingArgs = append(remainingArgs, arg)
}
}
+ if err != nil {
+ err = optErr(args[0] + ": " + err.Error())
+ }
return
}
-func (self *Options) parseLongOption(args []string, i int, argRest string) int {
+func (o *Options) parseLongOption(args []string, i int, argRest string) (skip int, err error) {
parts := strings.SplitN(argRest, "=", 2)
argname := parts[0]
var argval *string
@@ -66,41 +62,58 @@ func (self *Options) parseLongOption(args []string, i int, argRest string) int {
argval = &parts[1]
}
- for _, opt := range self.options {
+ for _, opt := range o.options {
if argname == opt.longName {
- switch data := opt.data.(type) {
- case *bool:
- if argval == nil {
- *data = true
- } else {
- switch *argval {
- case "true", "on", "enabled", "1":
- *data = true
- case "false", "off", "disabled", "0":
- *data = false
- default:
- panic(OptErr("invalid argument for option --" + opt.longName))
- }
- }
- return 0
- case *FlagGroup:
- if argval == nil {
- data.parse("--"+opt.longName+"=", args[i+1])
- return 1
- } else {
- data.parse("--"+opt.longName+"=", *argval)
- return 0
- }
+ return o.handleLongOption(args, i, opt, argval)
+ }
+ }
+
+ var prefixOpt *option
+ for _, opt := range o.options {
+ if strings.HasPrefix(opt.longName, argname) {
+ if prefixOpt == nil {
+ prefixOpt = opt
+ } else {
+ return 0, optErr(fmt.Sprintf("ambiguous option: --%s could mean --%s or --%s", argRest, prefixOpt.longName, opt.longName))
}
}
}
- panic(OptErr("unknown option: --" + argRest))
+ if prefixOpt != nil {
+ return o.handleLongOption(args, i, prefixOpt, argval)
+ }
+ return 0, optErr("unknown option: --" + argRest)
+}
+
+func (o *Options) handleLongOption(args []string, i int, opt *option, argval *string) (skip int, err error) {
+ switch data := opt.data.(type) {
+ case *bool:
+ if argval == nil {
+ *data = true
+ } else {
+ switch *argval {
+ case "true", "on", "enabled", "1":
+ *data = true
+ case "false", "off", "disabled", "0":
+ *data = false
+ default:
+ return 0, optErr("invalid argument for option --" + opt.longName)
+ }
+ }
+ return 0, nil
+ case *FlagGroup:
+ if argval == nil {
+ return 1, data.parse("--"+opt.longName+"=", args[i+1])
+ } else {
+ return 0, data.parse("--"+opt.longName+"=", *argval)
+ }
+ }
+ panic("getopt: unknown option type")
}
-func (self *Options) parseShortOptions(args []string, i int, optchars string) int {
+func (o *Options) parseShortOptions(args []string, i int, optchars string) (skip int, err error) {
optchar:
for ai, optchar := range optchars {
- for _, opt := range self.options {
+ for _, opt := range o.options {
if optchar == opt.shortName {
switch data := opt.data.(type) {
case *bool:
@@ -109,28 +122,26 @@ optchar:
case *FlagGroup:
argarg := optchars[ai+utf8.RuneLen(optchar):]
if argarg != "" {
- data.parse(sprintf("-%c", optchar), argarg)
- return 0
+ return 0, data.parse(sprintf("-%c", optchar), argarg)
} else {
- data.parse(sprintf("-%c", optchar), args[i+1])
- return 1
+ return 1, data.parse(sprintf("-%c", optchar), args[i+1])
}
}
}
}
- panic(OptErr(sprintf("unknown option: -%c", optchar)))
+ return 0, optErr(sprintf("unknown option: -%c", optchar))
}
- return 0
+ return 0, nil
}
-func (self *Options) Help(out io.Writer, generalUsage string) {
+func (o *Options) Help(out io.Writer, generalUsage string) {
wr := tabwriter.NewWriter(out, 1, 0, 2, ' ', tabwriter.TabIndent)
fmt.Fprintf(wr, "usage: %s\n", generalUsage)
fmt.Fprintln(wr)
wr.Flush()
- for _, opt := range self.options {
+ for _, opt := range o.options {
if opt.argDescription == "" {
fmt.Fprintf(wr, " -%c, --%s\t %s\n",
opt.shortName, opt.longName, opt.description)
@@ -142,7 +153,7 @@ func (self *Options) Help(out io.Writer, generalUsage string) {
wr.Flush()
hasFlagGroups := false
- for _, opt := range self.options {
+ for _, opt := range o.options {
switch flagGroup := opt.data.(type) {
case *FlagGroup:
hasFlagGroups = true
@@ -163,7 +174,7 @@ func (self *Options) Help(out io.Writer, generalUsage string) {
}
}
-type Option struct {
+type option struct {
shortName rune
longName string
argDescription string
@@ -172,25 +183,25 @@ type Option struct {
}
type FlagGroup struct {
- flags []*GroupFlag
+ flags []*groupFlag
}
-func (self *FlagGroup) AddFlagVar(name string, flag *bool, defval bool, help string) {
- opt := &GroupFlag{name, flag, help}
- self.flags = append(self.flags, opt)
+func (fg *FlagGroup) AddFlagVar(name string, flag *bool, defval bool, help string) {
+ opt := &groupFlag{name, flag, help}
+ fg.flags = append(fg.flags, opt)
*flag = defval
}
-func (self *FlagGroup) parse(optionPrefix, arg string) {
+func (fg *FlagGroup) parse(optionPrefix, arg string) (err error) {
argopt:
for _, argopt := range strings.Split(arg, ",") {
if argopt == "none" || argopt == "all" {
- for _, opt := range self.flags {
+ for _, opt := range fg.flags {
*opt.value = argopt == "all"
}
continue argopt
}
- for _, opt := range self.flags {
+ for _, opt := range fg.flags {
if argopt == opt.name {
*opt.value = true
continue argopt
@@ -200,18 +211,19 @@ argopt:
continue argopt
}
}
- panic(OptErr("unknown option: " + optionPrefix + argopt))
+ return optErr("unknown option: " + optionPrefix + argopt)
}
+ return nil
}
-type GroupFlag struct {
+type groupFlag struct {
name string
value *bool
help string
}
-type OptErr string
+type optErr string
-func (err OptErr) Error() string {
+func (err optErr) Error() string {
return string(err)
}
diff --git a/pkgtools/pkglint/files/getopt_test.go b/pkgtools/pkglint/files/getopt_test.go
index ca8e569c834..52e7f7fceeb 100644
--- a/pkgtools/pkglint/files/getopt_test.go
+++ b/pkgtools/pkglint/files/getopt_test.go
@@ -32,7 +32,7 @@ func (s *Suite) TestGetopt_UnknownLong(c *check.C) {
c.Check(err.Error(), equals, "progname: unknown option: --unknown-long")
}
-func (s *Suite) TestGetopt_UnknownFlag(c *check.C) {
+func (s *Suite) TestGetopt_UnknownFlagInGroup(c *check.C) {
opts := NewOptions()
opts.AddFlagGroup('W', "warnings", "", "")
@@ -45,6 +45,32 @@ func (s *Suite) TestGetopt_UnknownFlag(c *check.C) {
c.Check(err.Error(), equals, "progname: unknown option: --warnings=no-error")
}
+func (s *Suite) TestGetopt_AbbreviatedLong(c *check.C) {
+ opts := NewOptions()
+ var longFlag, longerFlag bool
+ opts.AddFlagVar('?', "long", &longFlag, false, "")
+ opts.AddFlagVar('?', "longer", &longerFlag, false, "")
+
+ _, err := opts.Parse([]string{"progname", "--lo"})
+
+ c.Check(err.Error(), equals, "progname: ambiguous option: --lo could mean --long or --longer")
+
+ args, err := opts.Parse([]string{"progname", "--long"})
+
+ c.Assert(err, check.IsNil)
+ c.Check(args, check.IsNil)
+ c.Check(longFlag, equals, true)
+ c.Check(longerFlag, equals, false)
+
+ longFlag = false
+ args, err = opts.Parse([]string{"progname", "--longe"})
+
+ c.Assert(err, check.IsNil)
+ c.Check(args, check.IsNil)
+ c.Check(longFlag, equals, false)
+ c.Check(longerFlag, equals, true)
+}
+
func (s *Suite) TestGetopt_MixedArgsAndOptions(c *check.C) {
opts := NewOptions()
var aflag, bflag bool
diff --git a/pkgtools/pkglint/files/globaldata.go b/pkgtools/pkglint/files/globaldata.go
index a050bae3fc9..f3557bc5c75 100644
--- a/pkgtools/pkglint/files/globaldata.go
+++ b/pkgtools/pkglint/files/globaldata.go
@@ -67,8 +67,8 @@ func (gd *GlobalData) Initialize() {
gd.deprecated = getDeprecatedVars()
}
-func (self *GlobalData) loadDistSites() {
- fname := self.pkgsrcdir + "/mk/fetch/sites.mk"
+func (gd *GlobalData) loadDistSites() {
+ fname := gd.pkgsrcdir + "/mk/fetch/sites.mk"
lines := LoadExistingLines(fname, true)
names := make(map[string]bool)
@@ -91,25 +91,25 @@ func (self *GlobalData) loadDistSites() {
names["MASTER_SITE_LOCAL"] = true
_ = G.opts.DebugMisc && debugf(fname, NO_LINES, "Loaded %d MASTER_SITE_* URLs.", len(url2name))
- self.masterSiteUrls = url2name
- self.masterSiteVars = names
+ gd.masterSiteUrls = url2name
+ gd.masterSiteVars = names
}
-func (self *GlobalData) loadPkgOptions() {
- fname := self.pkgsrcdir + "/mk/defaults/options.description"
+func (gd *GlobalData) loadPkgOptions() {
+ fname := gd.pkgsrcdir + "/mk/defaults/options.description"
lines := LoadExistingLines(fname, false)
- self.pkgOptions = make(map[string]string)
+ gd.pkgOptions = make(map[string]string)
for _, line := range lines {
if m, optname, optdescr := match2(line.text, `^([-0-9a-z_+]+)(?:\s+(.*))?$`); m {
- self.pkgOptions[optname] = optdescr
+ gd.pkgOptions[optname] = optdescr
} else {
line.fatalf("Unknown line format.")
}
}
}
-func (self *GlobalData) loadTools() {
+func (gd *GlobalData) loadTools() {
toolFiles := []string{"defaults.mk"}
{
fname := G.globalData.pkgsrcdir + "/mk/tools/bsd.tools.mk"
@@ -221,19 +221,19 @@ func (self *GlobalData) loadTools() {
systemBuildDefs["GAMEOWN"] = true
systemBuildDefs["GAMEGRP"] = true
- self.tools = tools
- self.vartools = vartools
- self.predefinedTools = predefinedTools
- self.varnameToToolname = varnameToToolname
- self.systemBuildDefs = systemBuildDefs
- self.toolvarsVarRequired = map[string]bool{
+ gd.tools = tools
+ gd.vartools = vartools
+ gd.predefinedTools = predefinedTools
+ gd.varnameToToolname = varnameToToolname
+ gd.systemBuildDefs = systemBuildDefs
+ gd.toolvarsVarRequired = map[string]bool{
"ECHO": true,
"ECHO_N": true,
"FALSE": true,
"TEST": true,
"TRUE": true,
}
- self.toolsVarRequired = map[string]bool{
+ gd.toolsVarRequired = map[string]bool{
"echo": true,
"false": true,
"test": true,
@@ -277,14 +277,14 @@ func parselinesSuggestedUpdates(lines []*Line) []SuggestedUpdate {
return updates
}
-func (self *GlobalData) loadSuggestedUpdates() {
- self.suggestedUpdates = loadSuggestedUpdates(G.globalData.pkgsrcdir + "/doc/TODO")
+func (gd *GlobalData) loadSuggestedUpdates() {
+ gd.suggestedUpdates = loadSuggestedUpdates(G.globalData.pkgsrcdir + "/doc/TODO")
if wipFilename := G.globalData.pkgsrcdir + "/wip/TODO"; fileExists(wipFilename) {
- self.suggestedWipUpdates = loadSuggestedUpdates(wipFilename)
+ gd.suggestedWipUpdates = loadSuggestedUpdates(wipFilename)
}
}
-func (self *GlobalData) loadDocChangesFromFile(fname string) []Change {
+func (gd *GlobalData) loadDocChangesFromFile(fname string) []Change {
lines := LoadExistingLines(fname, false)
var changes []Change
@@ -317,15 +317,15 @@ func (self *GlobalData) loadDocChangesFromFile(fname string) []Change {
return changes
}
-func (self *GlobalData) getSuggestedPackageUpdates() []SuggestedUpdate {
+func (gd *GlobalData) getSuggestedPackageUpdates() []SuggestedUpdate {
if G.isWip {
- return self.suggestedWipUpdates
+ return gd.suggestedWipUpdates
} else {
- return self.suggestedUpdates
+ return gd.suggestedUpdates
}
}
-func (self *GlobalData) loadDocChanges() {
+func (gd *GlobalData) loadDocChanges() {
docdir := G.globalData.pkgsrcdir + "/doc"
files, err := ioutil.ReadDir(docdir)
if err != nil {
@@ -341,24 +341,24 @@ func (self *GlobalData) loadDocChanges() {
}
sort.Strings(fnames)
- self.lastChange = make(map[string]*Change)
+ gd.lastChange = make(map[string]*Change)
for _, fname := range fnames {
- changes := self.loadDocChangesFromFile(docdir + "/" + fname)
+ changes := gd.loadDocChangesFromFile(docdir + "/" + fname)
for _, change := range changes {
c := change
- self.lastChange[change.pkgpath] = &c
+ gd.lastChange[change.pkgpath] = &c
}
}
}
-func (self *GlobalData) loadUserDefinedVars() {
+func (gd *GlobalData) loadUserDefinedVars() {
lines := LoadExistingLines(G.globalData.pkgsrcdir+"/mk/defaults/mk.conf", true)
- self.userDefinedVars = make(map[string]*Line)
+ gd.userDefinedVars = make(map[string]*Line)
for _, line := range lines {
parselineMk(line)
if m, varname, _, _, _ := matchVarassign(line.text); m {
- self.userDefinedVars[varname] = line
+ gd.userDefinedVars[varname] = line
}
}
}
diff --git a/pkgtools/pkglint/files/globaldata_test.go b/pkgtools/pkglint/files/globaldata_test.go
index 27c384c3bee..bc8cf695246 100644
--- a/pkgtools/pkglint/files/globaldata_test.go
+++ b/pkgtools/pkglint/files/globaldata_test.go
@@ -8,7 +8,7 @@ func (s *Suite) TestGlobalDataVartypes(c *check.C) {
G.globalData.InitVartypes()
c.Check(G.globalData.vartypes["BSD_MAKE_ENV"].checker.name, equals, "ShellWord")
- c.Check(G.globalData.vartypes["USE_BUILTIN.*"].checker.name, equals, "YesNo_Indirectly")
+ c.Check(G.globalData.vartypes["USE_BUILTIN.*"].checker.name, equals, "YesNoIndirectly")
}
func (s *Suite) TestParselinesSuggestedUpdates(c *check.C) {
diff --git a/pkgtools/pkglint/files/line.go b/pkgtools/pkglint/files/line.go
index 66515957241..ba256fbdc05 100644
--- a/pkgtools/pkglint/files/line.go
+++ b/pkgtools/pkglint/files/line.go
@@ -43,41 +43,41 @@ func NewLine(fname, linenos, text string, rawLines []*RawLine) *Line {
return &Line{fname, linenos, text, rawLines, false, nil, nil, make(map[string]interface{})}
}
-func (self *Line) rawLines() []*RawLine {
- return append(self.before, append(self.raw, self.after...)...)
+func (ln *Line) rawLines() []*RawLine {
+ return append(ln.before, append(ln.raw, ln.after...)...)
}
-func (self *Line) printSource(out io.Writer) {
+func (ln *Line) printSource(out io.Writer) {
if G.opts.PrintSource {
io.WriteString(out, "\n")
- for _, rawLine := range self.rawLines() {
+ for _, rawLine := range ln.rawLines() {
fmt.Fprintf(out, "> %s", rawLine.textnl)
}
}
}
-func (self *Line) fatalf(format string, args ...interface{}) bool {
- self.printSource(G.logErr)
- return fatalf(self.fname, self.lines, format, args...)
+func (ln *Line) fatalf(format string, args ...interface{}) bool {
+ ln.printSource(G.logErr)
+ return fatalf(ln.fname, ln.lines, format, args...)
}
-func (self *Line) errorf(format string, args ...interface{}) bool {
- self.printSource(G.logOut)
- return errorf(self.fname, self.lines, format, args...)
+func (ln *Line) errorf(format string, args ...interface{}) bool {
+ ln.printSource(G.logOut)
+ return errorf(ln.fname, ln.lines, format, args...)
}
-func (self *Line) warnf(format string, args ...interface{}) bool {
- self.printSource(G.logOut)
- return warnf(self.fname, self.lines, format, args...)
+func (ln *Line) warnf(format string, args ...interface{}) bool {
+ ln.printSource(G.logOut)
+ return warnf(ln.fname, ln.lines, format, args...)
}
-func (self *Line) notef(format string, args ...interface{}) bool {
- self.printSource(G.logOut)
- return notef(self.fname, self.lines, format, args...)
+func (ln *Line) notef(format string, args ...interface{}) bool {
+ ln.printSource(G.logOut)
+ return notef(ln.fname, ln.lines, format, args...)
}
-func (self *Line) debugf(format string, args ...interface{}) bool {
- self.printSource(G.logOut)
- return debugf(self.fname, self.lines, format, args...)
+func (ln *Line) debugf(format string, args ...interface{}) bool {
+ ln.printSource(G.logOut)
+ return debugf(ln.fname, ln.lines, format, args...)
}
-func (self *Line) explain(explanation ...string) {
+func (ln *Line) explain(explanation ...string) {
if G.opts.Explain {
complete := strings.Join(explanation, "\n")
if G.explanationsGiven[complete] {
@@ -97,41 +97,41 @@ func (self *Line) explain(explanation ...string) {
G.explanationsAvailable = true
}
-func (self *Line) String() string {
- return self.fname + ":" + self.lines + ": " + self.text
+func (ln *Line) String() string {
+ return ln.fname + ":" + ln.lines + ": " + ln.text
}
-func (self *Line) insertBefore(line string) {
- self.before = append(self.before, &RawLine{0, line + "\n"})
- self.noteAutofix("Autofix: inserting a line %q before this line.", line)
+func (ln *Line) insertBefore(line string) {
+ ln.before = append(ln.before, &RawLine{0, line + "\n"})
+ ln.noteAutofix("Autofix: inserting a line %q before this line.", line)
}
-func (self *Line) insertAfter(line string) {
- self.after = append(self.after, &RawLine{0, line + "\n"})
- self.noteAutofix("Autofix: inserting a line %q after this line.", line)
+func (ln *Line) insertAfter(line string) {
+ ln.after = append(ln.after, &RawLine{0, line + "\n"})
+ ln.noteAutofix("Autofix: inserting a line %q after this line.", line)
}
-func (self *Line) delete() {
- self.raw = nil
- self.changed = true
+func (ln *Line) delete() {
+ ln.raw = nil
+ ln.changed = true
}
-func (self *Line) replace(from, to string) {
- for _, rawLine := range self.raw {
+func (ln *Line) replace(from, to string) {
+ for _, rawLine := range ln.raw {
if rawLine.lineno != 0 {
if replaced := strings.Replace(rawLine.textnl, from, to, 1); replaced != rawLine.textnl {
rawLine.textnl = replaced
- self.noteAutofix("Autofix: replacing %q with %q.", from, to)
+ ln.noteAutofix("Autofix: replacing %q with %q.", from, to)
}
}
}
}
-func (self *Line) replaceRegex(from, to string) {
- for _, rawLine := range self.raw {
+func (ln *Line) replaceRegex(from, to string) {
+ for _, rawLine := range ln.raw {
if rawLine.lineno != 0 {
if replaced := regcomp(from).ReplaceAllString(rawLine.textnl, to); replaced != rawLine.textnl {
rawLine.textnl = replaced
- self.noteAutofix("Autofix: replacing regular expression %q with %q.", from, to)
+ ln.noteAutofix("Autofix: replacing regular expression %q with %q.", from, to)
}
}
}
diff --git a/pkgtools/pkglint/files/main.go b/pkgtools/pkglint/files/main.go
index 9df44e6c91f..28005ae658c 100644
--- a/pkgtools/pkglint/files/main.go
+++ b/pkgtools/pkglint/files/main.go
@@ -42,7 +42,7 @@ func (p *Pkglint) Main(args ...string) (exitcode int) {
if G.opts.Profiling {
f, err := os.Create("pkglint.pprof")
if err != nil {
- fatalf(NO_FILE, NO_LINES, "Cannot create profiling file: %s", err)
+ dummyLine.fatalf("Cannot create profiling file: %s", err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
diff --git a/pkgtools/pkglint/files/makefiles.go b/pkgtools/pkglint/files/makefiles.go
index 1327d53523a..49c991fd03d 100644
--- a/pkgtools/pkglint/files/makefiles.go
+++ b/pkgtools/pkglint/files/makefiles.go
@@ -450,7 +450,7 @@ func ChecklinesMk(lines []*Line) {
}
} else if directive == "if" || directive == "elif" {
- checklineMkCondition(line, args)
+ checklineMkIf(line, args)
} else if directive == "ifdef" || directive == "ifndef" {
if matches(args, `\s`) {
diff --git a/pkgtools/pkglint/files/mkcond.go b/pkgtools/pkglint/files/mkcond.go
index 6e4b28b7e60..4d4b869c196 100644
--- a/pkgtools/pkglint/files/mkcond.go
+++ b/pkgtools/pkglint/files/mkcond.go
@@ -29,7 +29,7 @@ func parseMkCond(line *Line, cond string) *Tree {
return NewTree("unknown", cond)
}
-func checklineMkCondition(line *Line, condition string) {
+func checklineMkIf(line *Line, condition string) {
defer tracecall("checklineMkCond", condition)()
tree := parseMkCond(line, condition)
diff --git a/pkgtools/pkglint/files/mkcond_test.go b/pkgtools/pkglint/files/mkcond_test.go
index 7741e7c6fee..1af382a7b26 100644
--- a/pkgtools/pkglint/files/mkcond_test.go
+++ b/pkgtools/pkglint/files/mkcond_test.go
@@ -25,17 +25,17 @@ func (s *Suite) TestChecklineMkCondition(c *check.C) {
G.globalData.InitVartypes()
line := NewLine("fname", "1", "", nil)
- checklineMkCondition(line, "!empty(PKGSRC_COMPILER:Mmycc)")
+ checklineMkIf(line, "!empty(PKGSRC_COMPILER:Mmycc)")
c.Check(s.Stdout(), equals, "WARN: fname:1: Invalid :M value \"mycc\". "+
"Only { ccache ccc clang distcc f2c gcc hp icc ido gcc mipspro "+
"mipspro-ucode pcc sunpro xlc } are allowed.\n")
- checklineMkCondition(line, "${A} != ${B}")
+ checklineMkIf(line, "${A} != ${B}")
c.Check(s.Stdout(), equals, "") // Unknown condition types are silently ignored
- checklineMkCondition(line, "${HOMEPAGE} == \"mailto:someone@example.org\"")
+ checklineMkIf(line, "${HOMEPAGE} == \"mailto:someone@example.org\"")
c.Check(s.Output(), equals, "WARN: fname:1: \"mailto:someone@example.org\" is not a valid URL.\n")
}
diff --git a/pkgtools/pkglint/files/patches.go b/pkgtools/pkglint/files/patches.go
index b081ab871fd..86f454256a8 100644
--- a/pkgtools/pkglint/files/patches.go
+++ b/pkgtools/pkglint/files/patches.go
@@ -111,7 +111,6 @@ func checklineOtherAbsolutePathname(line *Line, text string) {
}
const (
- rePatchRcsid = `^\$.*\$$`
rePatchNonempty = `^(.+)$`
rePatchEmpty = `^$`
rePatchTextError = `\*\*\* Error code`
diff --git a/pkgtools/pkglint/files/pkglint.go b/pkgtools/pkglint/files/pkglint.go
index bdee9038c5c..b188e129472 100644
--- a/pkgtools/pkglint/files/pkglint.go
+++ b/pkgtools/pkglint/files/pkglint.go
@@ -15,7 +15,6 @@ const (
reMkCond = `^\.(\s*)(if|ifdef|ifndef|else|elif|endif|for|endfor|undef)(?:\s+([^\s#][^#]*?))?\s*(?:#.*)?$`
reMkInclude = `^\.\s*(s?include)\s+\"([^\"]+)\"\s*(?:#.*)?$`
reVarassign = `^ *([-*+A-Z_a-z0-9.${}\[]+?)\s*([!+:?]?=)\s*((?:\\#|[^#])*?)(?:\s*(#.*))?$`
- reVarname = `(?:[-*+.0-9A-Z_a-z{}\[]+|\$\{[\w_]+\})+`
rePkgname = `^([\w\-.+]+)-(\d(?:\w|\.\d)*)$`
rePkgbase = `(?:[+.\w]|-[A-Z_a-z])+`
rePkgversion = `\d(?:\w|\.\d)*`
diff --git a/pkgtools/pkglint/files/pkglint_test.go b/pkgtools/pkglint/files/pkglint_test.go
index 7d48cfef671..84f24727f86 100644
--- a/pkgtools/pkglint/files/pkglint_test.go
+++ b/pkgtools/pkglint/files/pkglint_test.go
@@ -83,15 +83,6 @@ func (s *Suite) TestResolveVariableRefs_SpecialChars(c *check.C) {
c.Check(resolved, equals, "gst-plugins0.10-x11/distinfo")
}
-func (s *Suite) TestReVarname(c *check.C) {
- re := `^(?:` + reVarname + `)$`
-
- c.Check(matches("", re), equals, false)
- c.Check(matches("VARNAME", re), equals, true)
- c.Check(matches("0FLAGS", re), equals, true)
- c.Check(matches("CFLAGS.${prog}.DEBUG", re), equals, true)
-}
-
func (s *Suite) TestChecklineRcsid(c *check.C) {
lines := s.NewLines("fname",
"$"+"NetBSD: dummy $",
diff --git a/pkgtools/pkglint/files/plist_test.go b/pkgtools/pkglint/files/plist_test.go
index 7c2bfee093e..a910a8fd1a9 100644
--- a/pkgtools/pkglint/files/plist_test.go
+++ b/pkgtools/pkglint/files/plist_test.go
@@ -15,7 +15,7 @@ func (s *Suite) TestChecklinesPlist(c *check.C) {
checklinesPlist(lines)
c.Check(s.Output(), equals, ""+
- "ERROR: PLIST:1: Expected \"@comment $NetBSD: plist_test.go,v 1.2 2015/12/02 21:46:46 rillig Exp $\".\n"+
+ "ERROR: PLIST:1: Expected \"@comment $"+"NetBSD$\".\n"+
"WARN: PLIST:1: The bin/ directory should not have subdirectories.\n"+
"WARN: PLIST:5: Please remove this line. It is no longer necessary.\n")
}
diff --git a/pkgtools/pkglint/files/shell_test.go b/pkgtools/pkglint/files/shell_test.go
index 1db763e070c..8b47bdfd9fe 100644
--- a/pkgtools/pkglint/files/shell_test.go
+++ b/pkgtools/pkglint/files/shell_test.go
@@ -19,10 +19,69 @@ func (s *Suite) TestSplitIntoShellwords_LineContinuation(c *check.C) {
}
func (s *Suite) TestChecklineMkShelltext(c *check.C) {
+ s.UseCommandLine(c, "-Wall")
G.mkContext = newMkContext()
- line := NewLine("fname", "1", "dummy", nil)
+ msline := NewMkShellLine(NewLine("fname", "1", "dummy", nil))
+
+ msline.checklineMkShelltext("@# Comment")
+
+ c.Check(s.Output(), equals, "")
+
+ msline.checklineMkShelltext("uname=`uname`; echo $$uname")
+
+ c.Check(s.Output(), equals, ""+
+ "WARN: fname:1: Unknown shell command \"uname\".\n"+
+ "WARN: fname:1: Please switch to \"set -e\" mode before using a semicolon to separate commands.\n"+
+ "WARN: fname:1: Unknown shell command \"echo\".\n"+
+ "WARN: fname:1: Unquoted shell variable \"uname\".\n")
+
+ // The following test case goes beyond the limits of the current shell parser.
+
+ // foobar="`echo \"foo bar\"`"
+ msline.checklineMkShelltext("foobar=\"`echo \\\"foo bar\\\"`\"")
+
+ c.Check(s.Output(), equals, ""+
+ "WARN: fname:1: Backslashes should be doubled inside backticks.\n"+
+ "WARN: fname:1: Double quotes inside backticks inside double quotes are error prone.\n"+
+ "WARN: fname:1: Backslashes should be doubled inside backticks.\n"+
+ "WARN: fname:1: Double quotes inside backticks inside double quotes are error prone.\n"+
+ "WARN: fname:1: Unknown shell command \"echo\".\n"+
+ "ERROR: fname:1: Internal pkglint error: checklineMkShellword state=plain, rest=\"\\\\foo\", shellword=\"\\\\foo\"\n"+
+ "ERROR: fname:1: Internal pkglint error: checklineMkShelltext state=continuation rest=\"\\\\\" shellword=\"echo \\\\foo bar\\\\\"\n")
+
+ G.globalData.tools = map[string]bool{"echo": true}
+ G.globalData.predefinedTools = map[string]bool{"echo": true}
+ G.mkContext = newMkContext()
+ G.globalData.InitVartypes()
+
+ msline.checklineMkShelltext("echo ${PKGNAME:Q}") // VUC_SHW_PLAIN
+
+ c.Check(s.Output(), equals, ""+
+ "WARN: fname:1: PKGNAME may not be used in this file.\n"+
+ "NOTE: fname:1: The :Q operator isn't necessary for ${PKGNAME} here.\n")
- NewMkShellLine(line).checklineMkShelltext("@# Comment")
+ msline.checklineMkShelltext("echo \"${CFLAGS:Q}\"") // VUC_SHW_DQUOT
+
+ c.Check(s.Output(), equals, ""+
+ "WARN: fname:1: Please don't use the :Q operator in double quotes.\n"+
+ "WARN: fname:1: CFLAGS may not be used in this file.\n"+
+ "WARN: fname:1: Please use ${CFLAGS:M*:Q} instead of ${CFLAGS:Q} and make sure the variable appears outside of any quoting characters.\n")
+
+ msline.checklineMkShelltext("echo '${COMMENT:Q}'") // VUC_SHW_SQUOT
+
+ c.Check(s.Output(), equals, "WARN: fname:1: COMMENT may not be used in this file.\n")
+
+ msline.checklineMkShelltext("echo $$@")
+
+ c.Check(s.Output(), equals, "WARN: fname:1: The $@ shell variable should only be used in double quotes.\n")
+
+ msline.checklineMkShelltext("echo \"$$\"") // As seen by make(1); the shell sees: echo $
+
+ c.Check(s.Output(), equals, "WARN: fname:1: Unquoted $ or strange shell variable found.\n")
+
+ msline.checklineMkShelltext("echo \"\\n\"") // As seen by make(1); the shell sees: echo "\n"
+
+ c.Check(s.Output(), equals, "WARN: fname:1: Please use \"\\\\n\" instead of \"\\n\".\n")
}
func (s *Suite) TestChecklineMkShellword(c *check.C) {
@@ -30,7 +89,6 @@ func (s *Suite) TestChecklineMkShellword(c *check.C) {
G.globalData.InitVartypes()
line := NewLine("fname", "1", "dummy", nil)
- c.Check(matches("${list}", `^`+reVarname+`$`), equals, true)
c.Check(matches("${list}", `^`+reVarnameDirect+`$`), equals, false)
checklineMkShellword(line, "${${list}}", false)
@@ -56,3 +114,35 @@ func (s *Suite) TestShelltextContext_CheckCommandStart(c *check.C) {
"WARN: fname:3: The \"echo\" tool is used but not added to USE_TOOLS.\n"+
"WARN: fname:3: Please use \"${ECHO}\" instead of \"echo\".\n")
}
+
+func (s *Suite) TestMkShellLine_checklineMkShelltext(c *check.C) {
+
+ shline := NewMkShellLine(s.DummyLine())
+
+ shline.checklineMkShelltext("for f in *.pl; do ${SED} s,@PREFIX@,${PREFIX}, < $f > $f.tmp && ${MV} $f.tmp $f; done")
+
+ c.Check(s.Output(), equals, "NOTE: fname:1: Please use the SUBST framework instead of ${SED} and ${MV}.\n")
+
+ shline.checklineMkShelltext("install -c manpage.1 ${PREFIX}/man/man1/manpage.1")
+
+ c.Check(s.Output(), equals, "WARN: fname:1: Please use ${PKGMANDIR} instead of \"man\".\n")
+
+ shline.checklineMkShelltext("cp init-script ${PREFIX}/etc/rc.d/service")
+
+ c.Check(s.Output(), equals, "WARN: fname:1: Please use the RCD_SCRIPTS mechanism to install rc.d scripts automatically to ${RCD_SCRIPTS_EXAMPLEDIR}.\n")
+}
+
+func (s *Suite) TestMkShellLine_checkCommandUse(c *check.C) {
+ G.mkContext = newMkContext()
+ G.mkContext.target = "do-install"
+
+ shline := NewMkShellLine(s.DummyLine())
+
+ shline.checkCommandUse("sed")
+
+ c.Check(s.Output(), equals, "WARN: fname:1: The shell command \"sed\" should not be used in the install phase.\n")
+
+ shline.checkCommandUse("cp")
+
+ c.Check(s.Output(), equals, "WARN: fname:1: ${CP} should not be used to install files.\n")
+}
diff --git a/pkgtools/pkglint/files/substcontext.go b/pkgtools/pkglint/files/substcontext.go
index cdeef42819c..d442ec5ca82 100644
--- a/pkgtools/pkglint/files/substcontext.go
+++ b/pkgtools/pkglint/files/substcontext.go
@@ -12,7 +12,7 @@ type SubstContext struct {
filterCmd string
}
-func (self *SubstContext) Varassign(line *Line, varname, op, value string) {
+func (ctx *SubstContext) Varassign(line *Line, varname, op, value string) {
if !G.opts.WarnExtra {
return
}
@@ -22,54 +22,54 @@ func (self *SubstContext) Varassign(line *Line, varname, op, value string) {
if len(classes) > 1 {
line.warnf("Please add only one class at a time to SUBST_CLASSES.")
}
- if self.id != "" {
+ if ctx.id != "" {
line.warnf("SUBST_CLASSES should only appear once in a SUBST block.")
}
- self.id = classes[0]
+ ctx.id = classes[0]
return
}
m, varbase, varparam := match2(varname, `^(SUBST_(?:STAGE|MESSAGE|FILES|SED|VARS|FILTER_CMD))\.([\-\w_]+)$`)
if !m {
- if self.id != "" {
+ if ctx.id != "" {
line.warnf("Foreign variable %q in SUBST block.", varname)
}
return
}
- if self.id == "" {
+ if ctx.id == "" {
line.warnf("SUBST_CLASSES should come before the definition of %q.", varname)
- self.id = varparam
+ ctx.id = varparam
}
- if varparam != self.id {
- if self.IsComplete() {
+ if varparam != ctx.id {
+ if ctx.IsComplete() {
// XXX: This code sometimes produces weird warnings. See
// meta-pkgs/xorg/Makefile.common 1.41 for an example.
- self.Finish(line)
+ ctx.Finish(line)
// The following assignment prevents an additional warning,
// but from a technically viewpoint, it is incorrect.
- self.id = varparam
+ ctx.id = varparam
} else {
- line.warnf("Variable %q does not match SUBST class %q.", varname, self.id)
+ line.warnf("Variable %q does not match SUBST class %q.", varname, ctx.id)
}
return
}
switch varbase {
case "SUBST_STAGE":
- self.dup(line, &self.stage, varname, value)
+ ctx.dup(line, &ctx.stage, varname, value)
case "SUBST_MESSAGE":
- self.dup(line, &self.message, varname, value)
+ ctx.dup(line, &ctx.message, varname, value)
case "SUBST_FILES":
- self.duplist(line, &self.files, varname, op, value)
+ ctx.duplist(line, &ctx.files, varname, op, value)
case "SUBST_SED":
- self.duplist(line, &self.sed, varname, op, value)
+ ctx.duplist(line, &ctx.sed, varname, op, value)
case "SUBST_FILTER_CMD":
- self.dup(line, &self.filterCmd, varname, value)
+ ctx.dup(line, &ctx.filterCmd, varname, value)
case "SUBST_VARS":
- self.duplist(line, &self.vars, varname, op, value)
+ ctx.duplist(line, &ctx.vars, varname, op, value)
default:
line.warnf("Foreign variable %q in SUBST block.", varname)
}
@@ -82,27 +82,27 @@ func (ctx *SubstContext) IsComplete() bool {
(len(ctx.sed) != 0 || len(ctx.vars) != 0 || ctx.filterCmd != "")
}
-func (self *SubstContext) Finish(line *Line) {
- if self.id == "" || !G.opts.WarnExtra {
+func (ctx *SubstContext) Finish(line *Line) {
+ if ctx.id == "" || !G.opts.WarnExtra {
return
}
- if self.stage == "" {
- line.warnf("Incomplete SUBST block: %s missing.", self.varname("SUBST_STAGE"))
+ if ctx.stage == "" {
+ line.warnf("Incomplete SUBST block: %s missing.", ctx.varname("SUBST_STAGE"))
}
- if len(self.files) == 0 {
- line.warnf("Incomplete SUBST block: %s missing.", self.varname("SUBST_FILES"))
+ if len(ctx.files) == 0 {
+ line.warnf("Incomplete SUBST block: %s missing.", ctx.varname("SUBST_FILES"))
}
- if len(self.sed) == 0 && len(self.vars) == 0 && self.filterCmd == "" {
+ if len(ctx.sed) == 0 && len(ctx.vars) == 0 && ctx.filterCmd == "" {
line.warnf("Incomplete SUBST block: %s, %s or %s missing.",
- self.varname("SUBST_SED"), self.varname("SUBST_VARS"), self.varname("SUBST_FILTER_CMD"))
+ ctx.varname("SUBST_SED"), ctx.varname("SUBST_VARS"), ctx.varname("SUBST_FILTER_CMD"))
}
- self.id = ""
- self.stage = ""
- self.message = ""
- self.files = nil
- self.sed = nil
- self.vars = nil
- self.filterCmd = ""
+ ctx.id = ""
+ ctx.stage = ""
+ ctx.message = ""
+ ctx.files = nil
+ ctx.sed = nil
+ ctx.vars = nil
+ ctx.filterCmd = ""
}
func (ctx *SubstContext) varname(varbase string) string {
diff --git a/pkgtools/pkglint/files/toplevel.go b/pkgtools/pkglint/files/toplevel.go
index dd481c7ac53..de34c1c76a3 100644
--- a/pkgtools/pkglint/files/toplevel.go
+++ b/pkgtools/pkglint/files/toplevel.go
@@ -18,9 +18,6 @@ func checkdirToplevel() {
}
ParselinesMk(lines)
- if 0 < len(lines) {
- checklineRcsid(lines[0], `#\s+`, "# ")
- }
for _, line := range lines {
if m, commentedOut, indentation, subdir, comment := match4(line.text, `^(#?)SUBDIR\s*\+=(\s*)(\S+)\s*(?:#\s*(.*?)\s*|)$`); m {
@@ -40,7 +37,7 @@ func checkdirToplevel() {
func (ctx *Toplevel) checkSubdir(line *Line, commentedOut bool, indentation, subdir, comment string) {
if commentedOut && comment == "" {
- line.warnf("%s commented out without giving a reason.", subdir)
+ line.warnf("%q commented out without giving a reason.", subdir)
}
if indentation != "\t" {
diff --git a/pkgtools/pkglint/files/toplevel_test.go b/pkgtools/pkglint/files/toplevel_test.go
new file mode 100644
index 00000000000..f232369fcd2
--- /dev/null
+++ b/pkgtools/pkglint/files/toplevel_test.go
@@ -0,0 +1,32 @@
+package main
+
+import (
+ check "gopkg.in/check.v1"
+)
+
+func (s *Suite) TestCheckdirToplevel(c *check.C) {
+ s.CreateTmpFile(c, "Makefile", ""+
+ "# $"+"NetBSD$\n"+
+ "\n"+
+ "SUBDIR+= x11\n"+
+ "SUBDIR+=\tarchivers\n"+
+ "SUBDIR+=\tccc\n"+
+ "SUBDIR+=\tccc\n"+
+ "#SUBDIR+=\tignoreme\n"+
+ "SUBDIR+=\tnonexisting\n"+ // This just doesn’t happen in practice.
+ "SUBDIR+=\tbbb\n")
+ s.CreateTmpFile(c, "archivers/Makefile", "")
+ s.CreateTmpFile(c, "bbb/Makefile", "")
+ s.CreateTmpFile(c, "ccc/Makefile", "")
+ s.CreateTmpFile(c, "x11/Makefile", "")
+ G.globalData.InitVartypes()
+ G.currentDir = s.tmpdir
+
+ checkdirToplevel()
+
+ c.Check(s.Output(), equals, ""+
+ "WARN: "+s.tmpdir+"/Makefile:3: Indentation should be a single tab character.\n"+
+ "ERROR: "+s.tmpdir+"/Makefile:6: Each subdir must only appear once.\n"+
+ "WARN: "+s.tmpdir+"/Makefile:7: \"ignoreme\" commented out without giving a reason.\n"+
+ "WARN: "+s.tmpdir+"/Makefile:9: bbb should come before ccc\n")
+}
diff --git a/pkgtools/pkglint/files/util.go b/pkgtools/pkglint/files/util.go
index f608d880b20..bd11f08ca96 100644
--- a/pkgtools/pkglint/files/util.go
+++ b/pkgtools/pkglint/files/util.go
@@ -21,13 +21,6 @@ var (
hasSuffix = strings.HasSuffix
)
-func intMax(a, b int) int {
- if a > b {
- return a
- }
- return b
-}
-
func ifelseStr(cond bool, a, b string) string {
if cond {
return a
@@ -175,14 +168,6 @@ func dirExists(fname string) bool {
return err == nil && st.Mode().IsDir()
}
-func stringset(s string) map[string]bool {
- result := make(map[string]bool)
- for _, m := range splitOnSpace(strings.TrimSpace(s)) {
- result[m] = true
- }
- return result
-}
-
var res = make(map[string]*regexp.Regexp)
func regcomp(re string) *regexp.Regexp {
@@ -282,13 +267,6 @@ func replacePrefix(ps *string, pm *[]string, re string) bool {
return false
}
-func nilToZero(pi *int) int {
- if pi != nil {
- return *pi
- }
- return 0
-}
-
// Useful in combination with regex.Find*Index
func negToZero(i int) int {
if i >= 0 {
diff --git a/pkgtools/pkglint/files/util_test.go b/pkgtools/pkglint/files/util_test.go
index f279a4c5ea8..ec857f1e0f1 100644
--- a/pkgtools/pkglint/files/util_test.go
+++ b/pkgtools/pkglint/files/util_test.go
@@ -58,3 +58,23 @@ func (s *Suite) TestCleanpath(c *check.C) {
c.Check(cleanpath("cat/pkg.v1/../../cat/pkg.v2/Makefile"), equals, "cat/pkg.v1/../../cat/pkg.v2/Makefile")
c.Check(cleanpath("dir/"), equals, "dir")
}
+
+func (s *Suite) TestIsEmptyDirAndGetSubdirs(c *check.C) {
+ s.CreateTmpFile(c, "CVS/Entries", "dummy\n")
+
+ c.Check(isEmptyDir(s.tmpdir), equals, true)
+ c.Check(getSubdirs(s.tmpdir), check.DeepEquals, []string(nil))
+
+ s.CreateTmpFile(c, "somedir/file", "")
+
+ c.Check(isEmptyDir(s.tmpdir), equals, false)
+ c.Check(getSubdirs(s.tmpdir), check.DeepEquals, []string{"somedir"})
+
+ if nodir := s.tmpdir + "/nonexistent"; true {
+ c.Check(isEmptyDir(nodir), equals, true) // Counts as empty.
+ defer s.ExpectFatalError(func() {
+ c.Check(s.Output(), equals, "FATAL: "+nodir+": Cannot be read: open "+nodir+": The system cannot find the file specified.\n")
+ })
+ c.Check(getSubdirs(nodir), check.DeepEquals, []string(nil))
+ }
+}
diff --git a/pkgtools/pkglint/files/vardefs.go b/pkgtools/pkglint/files/vardefs.go
index e0300ecdd4e..ac2eaa4b538 100644
--- a/pkgtools/pkglint/files/vardefs.go
+++ b/pkgtools/pkglint/files/vardefs.go
@@ -357,7 +357,7 @@ func (gd *GlobalData) InitVartypes() {
acl("INSTALL_TEMPLATES", LK_SHELL, CheckvarPathname, "Makefile:as", "Makefile.common:ads")
acl("INSTALL_UNSTRIPPED", LK_NONE, CheckvarYesNo, "Makefile:s", "Makefile.common:s")
pkg("INTERACTIVE_STAGE", LK_SHELL, enum("fetch extract configure build install"))
- acl("IS_BUILTIN.*", LK_NONE, CheckvarYesNo_Indirectly, "builtin.mk:psu")
+ acl("IS_BUILTIN.*", LK_NONE, CheckvarYesNoIndirectly, "builtin.mk:psu")
sys("JAVA_BINPREFIX", LK_NONE, CheckvarPathname)
pkg("JAVA_CLASSPATH", LK_NONE, CheckvarShellWord)
pkg("JAVA_HOME", LK_NONE, CheckvarPathname)
@@ -658,7 +658,7 @@ func (gd *GlobalData) InitVartypes() {
pkglist("UNWRAP_FILES", LK_SHELL, CheckvarPathmask)
usr("UPDATE_TARGET", LK_SHELL, CheckvarIdentifier)
pkg("USE_BSD_MAKEFILE", LK_NONE, CheckvarYes)
- acl("USE_BUILTIN.*", LK_NONE, CheckvarYesNo_Indirectly, "builtin.mk:s")
+ acl("USE_BUILTIN.*", LK_NONE, CheckvarYesNoIndirectly, "builtin.mk:s")
pkg("USE_CMAKE", LK_NONE, CheckvarYes)
acl("USE_CROSSBASE", LK_NONE, CheckvarYes, "Makefile:s")
pkg("USE_FEATURES", LK_SHELL, CheckvarIdentifier)
diff --git a/pkgtools/pkglint/files/vars.go b/pkgtools/pkglint/files/vars.go
index cd58ef77ca7..0829e461247 100644
--- a/pkgtools/pkglint/files/vars.go
+++ b/pkgtools/pkglint/files/vars.go
@@ -17,7 +17,7 @@ func variableNeedsQuoting(line *Line, varname string, vuc *VarUseContext) NeedsQ
return NQ_DONT_KNOW
}
- cond := vartype.checker.IsEnum()
+ isPlainWord := vartype.checker.IsEnum()
switch vartype.checker.name {
case "DistSuffix",
"FileMode", "Filename",
@@ -28,9 +28,9 @@ func variableNeedsQuoting(line *Line, varname string, vuc *VarUseContext) NeedsQ
"UserGroupName",
"Varname", "Version",
"WrkdirSubdirectory":
- cond = true
+ isPlainWord = true
}
- if cond {
+ if isPlainWord {
if vartype.kindOfList == LK_NONE {
return NQ_DOESNT_MATTER
}
diff --git a/pkgtools/pkglint/files/vars_test.go b/pkgtools/pkglint/files/vars_test.go
new file mode 100644
index 00000000000..c98bfbb9366
--- /dev/null
+++ b/pkgtools/pkglint/files/vars_test.go
@@ -0,0 +1,17 @@
+package main
+
+import (
+ check "gopkg.in/check.v1"
+)
+
+func (s *Suite) TestVariableNeedsQuoting(c *check.C) {
+ line := s.DummyLine()
+ G.globalData.InitVartypes()
+ pkgnameType := G.globalData.vartypes["PKGNAME"]
+
+ // In Makefile: PKGNAME := ${UNKNOWN}
+ vuc := &VarUseContext{VUC_TIME_LOAD, pkgnameType, VUC_SHW_UNKNOWN, VUC_EXTENT_UNKNOWN}
+ nq := variableNeedsQuoting(line, "UNKNOWN", vuc)
+
+ c.Check(nq, equals, NQ_DONT_KNOW)
+}
diff --git a/pkgtools/pkglint/files/vartype.go b/pkgtools/pkglint/files/vartype.go
index 3ddb1708f81..1b22c897d8e 100644
--- a/pkgtools/pkglint/files/vartype.go
+++ b/pkgtools/pkglint/files/vartype.go
@@ -35,8 +35,8 @@ const (
)
// The allowed actions in this file, or "?" if unknown.
-func (self *Vartype) effectivePermissions(fname string) string {
- for _, aclEntry := range self.aclEntries {
+func (vt *Vartype) effectivePermissions(fname string) string {
+ for _, aclEntry := range vt.aclEntries {
if m, _ := path.Match(aclEntry.glob, path.Base(fname)); m {
return aclEntry.permissions
}
@@ -68,9 +68,9 @@ func ReadableVartypePermissions(perms string) string {
// Returns the union of all possible permissions. This can be used to
// check whether a variable may be defined or used at all, or if it is
// read-only.
-func (self *Vartype) union() string {
+func (vt *Vartype) union() string {
var permissions string
- for _, aclEntry := range self.aclEntries {
+ for _, aclEntry := range vt.aclEntries {
permissions += aclEntry.permissions
}
return permissions
@@ -79,34 +79,34 @@ func (self *Vartype) union() string {
// Returns whether the type is considered a shell list.
// This distinction between “real lists” and “considered a list” makes
// the implementation of checklineMkVartype easier.
-func (self *Vartype) isConsideredList() bool {
- switch self.kindOfList {
+func (vt *Vartype) isConsideredList() bool {
+ switch vt.kindOfList {
case LK_SHELL:
return true
case LK_SPACE:
return false
}
- switch self.checker {
+ switch vt.checker {
case CheckvarSedCommands, CheckvarShellCommand:
return true
}
return false
}
-func (self *Vartype) mayBeAppendedTo() bool {
- return self.kindOfList != LK_NONE ||
- self.checker == CheckvarAwkCommand ||
- self.checker == CheckvarSedCommands
+func (vt *Vartype) mayBeAppendedTo() bool {
+ return vt.kindOfList != LK_NONE ||
+ vt.checker == CheckvarAwkCommand ||
+ vt.checker == CheckvarSedCommands
}
-func (self *Vartype) String() string {
- switch self.kindOfList {
+func (vt *Vartype) String() string {
+ switch vt.kindOfList {
case LK_NONE:
- return self.checker.name
+ return vt.checker.name
case LK_SPACE:
- return "SpaceList of " + self.checker.name
+ return "SpaceList of " + vt.checker.name
case LK_SHELL:
- return "ShellList of " + self.checker.name
+ return "ShellList of " + vt.checker.name
default:
panic("Unknown list type")
}
@@ -181,7 +181,7 @@ var (
CheckvarWrksrcSubdirectory = &VarChecker{"WrksrcSubdirectory", (*VartypeCheck).WrksrcSubdirectory}
CheckvarYes = &VarChecker{"Yes", (*VartypeCheck).Yes}
CheckvarYesNo = &VarChecker{"YesNo", (*VartypeCheck).YesNo}
- CheckvarYesNo_Indirectly = &VarChecker{"YesNo_Indirectly", (*VartypeCheck).YesNo_Indirectly}
+ CheckvarYesNoIndirectly = &VarChecker{"YesNoIndirectly", (*VartypeCheck).YesNoIndirectly}
)
func init() { // Necessary due to circular dependency
diff --git a/pkgtools/pkglint/files/vartypecheck.go b/pkgtools/pkglint/files/vartypecheck.go
index 603d130d9fb..3d85d645161 100644
--- a/pkgtools/pkglint/files/vartypecheck.go
+++ b/pkgtools/pkglint/files/vartypecheck.go
@@ -740,7 +740,7 @@ func (cv *VartypeCheck) YesNo() {
// Like YesNo, but the value may be produced by a shell command using the
// != operator.
-func (cv *VartypeCheck) YesNo_Indirectly() {
+func (cv *VartypeCheck) YesNoIndirectly() {
if cv.valueNovar != "" && !matches(cv.value, `^(?:YES|yes|NO|no)(?:\s+#.*)?$`) {
cv.line.warnf("%s should be set to YES, yes, NO, or no.", cv.varname)
}
diff --git a/pkgtools/pkglint/files/varusecontext.go b/pkgtools/pkglint/files/varusecontext.go
index 0a49d74b9f5..f45fd68db2a 100644
--- a/pkgtools/pkglint/files/varusecontext.go
+++ b/pkgtools/pkglint/files/varusecontext.go
@@ -55,14 +55,14 @@ const (
VUC_EXT_WORDPART // Example: echo LOCALBASE=${LOCALBASE}
)
-func (self *VarUseContext) String() string {
+func (vuc *VarUseContext) String() string {
typename := "no-type"
- if self.vartype != nil {
- typename = self.vartype.String()
+ if vuc.vartype != nil {
+ typename = vuc.vartype.String()
}
return sprintf("(%s %s %s %s)",
- []string{"unknown", "load-time", "run-time"}[self.time],
+ []string{"unknown", "load-time", "run-time"}[vuc.time],
typename,
- []string{"unknown", "plain", "dquot", "squot", "backt", "for"}[self.shellword],
- []string{"unknown", "word", "word-part"}[self.extent])
+ []string{"unknown", "plain", "dquot", "squot", "backt", "for"}[vuc.shellword],
+ []string{"unknown", "word", "word-part"}[vuc.extent])
}