Updated pkglint to 5.4.4.

Changes since 5.4.3:

* Improved detection for undocumented patches from Git
* Added warning about unnecessary space after variable names
* Lots of internal housekeeping
This commit is contained in:
rillig 2016-07-09 09:43:48 +00:00
parent 68a014ac63
commit bc46f036d4
45 changed files with 878 additions and 897 deletions

View file

@ -1,6 +1,6 @@
# $NetBSD: Makefile,v 1.488 2016/07/07 12:09:26 rillig Exp $
# $NetBSD: Makefile,v 1.489 2016/07/09 09:43:48 rillig Exp $
PKGNAME= pkglint-5.4.3
PKGNAME= pkglint-5.4.4
DISTFILES= # none
CATEGORIES= pkgtools

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestChecklinesBuildlink3(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("buildlink3.mk",
"# $"+"NetBSD$",
@ -37,7 +37,7 @@ func (s *Suite) TestChecklinesBuildlink3(c *check.C) {
// Before version 5.3, pkglint wrongly warned here.
// The mk/haskell.mk file takes care of constructing the correct PKGNAME,
// but pkglint had not looked at that file.
func (s *Suite) TestChecklinesBuildlink3_NameMismatch(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk_name_mismatch(c *check.C) {
G.globalData.InitVartypes()
G.Pkg = NewPackage("x11/hs-X11")
G.Pkg.EffectivePkgbase = "X11"
@ -62,7 +62,7 @@ func (s *Suite) TestChecklinesBuildlink3_NameMismatch(c *check.C) {
c.Check(s.Output(), equals, "ERROR: buildlink3.mk:3: Package name mismatch between \"hs-X11\" in this file and \"X11\" from Makefile:3.\n")
}
func (s *Suite) TestChecklinesBuildlink3_NameMismatchMultipleInclusion(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk_name_mismatch_multiple_inclusion(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("buildlink3.mk",
"# $"+"NetBSD$",
@ -83,7 +83,7 @@ func (s *Suite) TestChecklinesBuildlink3_NameMismatchMultipleInclusion(c *check.
"WARN: buildlink3.mk:9: Definition of BUILDLINK_API_DEPENDS is missing.\n")
}
func (s *Suite) TestChecklinesBuildlink3_NameMismatchAbiApi(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk_name_mismatch_abi_api(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("buildlink3.mk",
"# $"+"NetBSD$",
@ -105,7 +105,7 @@ func (s *Suite) TestChecklinesBuildlink3_NameMismatchAbiApi(c *check.C) {
c.Check(s.Output(), equals, "WARN: buildlink3.mk:9: Package name mismatch between ABI \"hs-X12\" and API \"hs-X11\" (from line 8).\n")
}
func (s *Suite) TestChecklinesBuildlink3_AbiApiVersions(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk_abi_api_versions(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("buildlink3.mk",
"# $"+"NetBSD$",
@ -128,7 +128,7 @@ func (s *Suite) TestChecklinesBuildlink3_AbiApiVersions(c *check.C) {
"WARN: buildlink3.mk:9: ABI version \"1.6.0\" should be at least API version \"1.6.1\" (see line 8).\n")
}
func (s *Suite) TestChecklinesBuildlink3_NoBuildlinkTreeAtBeginning(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk_no_BUILDLINK_TREE_at_beginning(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("buildlink3.mk",
"# $"+"NetBSD$",
@ -149,7 +149,7 @@ func (s *Suite) TestChecklinesBuildlink3_NoBuildlinkTreeAtBeginning(c *check.C)
c.Check(s.Output(), equals, "WARN: buildlink3.mk:3: Expected a BUILDLINK_TREE line.\n")
}
func (s *Suite) TestChecklinesBuildlink3_NoBuildlinkTreeAtEnd(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk_no_BUILDLINK_TREE_at_end(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("buildlink3.mk",
"# $"+"NetBSD$",
@ -176,7 +176,7 @@ func (s *Suite) TestChecklinesBuildlink3_NoBuildlinkTreeAtEnd(c *check.C) {
"WARN: buildlink3.mk:15: This line should contain the following text: BUILDLINK_TREE+=\t-hs-X11\n")
}
func (s *Suite) TestChecklinesBuildlink3_MultipleInclusionWrong(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk_multiple_inclusion_wrong(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("buildlink3.mk",
"# $"+"NetBSD$",
@ -193,7 +193,7 @@ func (s *Suite) TestChecklinesBuildlink3_MultipleInclusionWrong(c *check.C) {
"WARN: buildlink3.mk:6: This line should contain the following text: HS_X11_BUILDLINK3_MK:=\n")
}
func (s *Suite) TestChecklinesBuildlink3_EndIfMissing(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk_missing_endif(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("buildlink3.mk",
"# $"+"NetBSD$",
@ -208,7 +208,7 @@ func (s *Suite) TestChecklinesBuildlink3_EndIfMissing(c *check.C) {
c.Check(s.Output(), equals, "WARN: buildlink3.mk:EOF: Expected .endif\n")
}
func (s *Suite) TestChecklinesBuildlink3_UnknownDependencyPatterns(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk_unknown_dependency_patterns(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("buildlink3.mk",
"# $"+"NetBSD$",
@ -233,7 +233,7 @@ func (s *Suite) TestChecklinesBuildlink3_UnknownDependencyPatterns(c *check.C) {
"WARN: buildlink3.mk:10: Unknown dependency pattern \"hs-X11!=1.6.1.2nb2\".\n")
}
func (s *Suite) TestChecklinesBuildlink3_PkgbaseWithVariable(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk_PKGBASE_with_variable(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("buildlink3.mk",
"# $"+"NetBSD$",
@ -255,7 +255,7 @@ func (s *Suite) TestChecklinesBuildlink3_PkgbaseWithVariable(c *check.C) {
c.Check(s.Output(), equals, "WARN: buildlink3.mk:3: Please use \"py\" instead of \"${PYPKGPREFIX}\".\n")
}
func (s *Suite) TestChecklinesBuildlink3_PkgbaseWithUnknownVariable(c *check.C) {
func (s *Suite) Test_ChecklinesBuildlink3Mk_PKGBASE_with_unknown_variable(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("buildlink3.mk",
"# $"+"NetBSD$",

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestCheckdirCategory_TotallyBroken(c *check.C) {
func (s *Suite) Test_CheckdirCategory_totally_broken(c *check.C) {
G.globalData.InitVartypes()
s.CreateTmpFile(c, "archivers/Makefile", ""+
"# $\n"+
@ -33,7 +33,7 @@ func (s *Suite) TestCheckdirCategory_TotallyBroken(c *check.C) {
"ERROR: ~/archivers/Makefile:4: The file should end here.\n")
}
func (s *Suite) TestCheckdirCategory_InvalidComment(c *check.C) {
func (s *Suite) Test_CheckdirCategory_invalid_comment(c *check.C) {
G.globalData.InitVartypes()
s.CreateTmpFile(c, "archivers/Makefile", ""+
"# $"+"NetBSD$\n"+

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestCheckDirent_outside(c *check.C) {
func (s *Suite) Test_CheckDirent_outside(c *check.C) {
s.CreateTmpFile(c, "empty", "")
CheckDirent(s.tmpdir)
@ -12,7 +12,7 @@ func (s *Suite) TestCheckDirent_outside(c *check.C) {
c.Check(s.Output(), equals, "ERROR: ~: Cannot determine the pkgsrc root directory for \"~\".\n")
}
func (s *Suite) TestCheckDirent(c *check.C) {
func (s *Suite) Test_CheckDirent(c *check.C) {
s.CreateTmpFile(c, "mk/bsd.pkg.mk", "")
s.CreateTmpFile(c, "category/package/Makefile", "")
s.CreateTmpFile(c, "category/Makefile", "")

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestChecklinesDistinfo(c *check.C) {
func (s *Suite) Test_ChecklinesDistinfo(c *check.C) {
s.CreateTmpFile(c, "patches/patch-aa", ""+
"$"+"NetBSD$ line is ignored\n"+
"patch contents\n")
@ -28,7 +28,7 @@ func (s *Suite) TestChecklinesDistinfo(c *check.C) {
"WARN: distinfo:7: Patch file \"patch-nonexistent\" does not exist in directory \"patches\".\n")
}
func (s *Suite) TestChecklinesDistinfo_GlobalHashMismatch(c *check.C) {
func (s *Suite) Test_ChecklinesDistinfo_global_hash_mismatch(c *check.C) {
otherLine := NewLine("other/distinfo", 7, "dummy", nil)
G.Hash = make(map[string]*Hash)
G.Hash["SHA512:pkgname-1.0.tar.gz"] = &Hash{"asdfasdf", otherLine}
@ -43,7 +43,7 @@ func (s *Suite) TestChecklinesDistinfo_GlobalHashMismatch(c *check.C) {
"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) {
func (s *Suite) Test_ChecklinesDistinfo_uncommitted_patch(c *check.C) {
s.CreateTmpFile(c, "patches/patch-aa", ""+
"$"+"NetBSD$\n"+
"\n"+
@ -65,7 +65,7 @@ func (s *Suite) TestChecklinesDistinfo_UncommittedPatch(c *check.C) {
"WARN: ~/distinfo:3: patches/patch-aa is registered in distinfo but not added to CVS.\n")
}
func (s *Suite) TestChecklinesDistinfo_UnrecordedPatches(c *check.C) {
func (s *Suite) Test_ChecklinesDistinfo_unrecorded_patches(c *check.C) {
s.CreateTmpFile(c, "patches/CVS/Entries", "")
s.CreateTmpFile(c, "patches/patch-aa", "")
s.CreateTmpFile(c, "patches/patch-src-Makefile", "")
@ -84,7 +84,7 @@ func (s *Suite) TestChecklinesDistinfo_UnrecordedPatches(c *check.C) {
"ERROR: ~/distinfo: patch \"patches/patch-src-Makefile\" is not recorded. Run \""+confMake+" makepatchsum\".\n")
}
func (s *Suite) TestChecklinesDistinfo_ManualPatches(c *check.C) {
func (s *Suite) Test_ChecklinesDistinfo_manual_patches(c *check.C) {
s.CreateTmpFile(c, "patches/manual-libtool.m4",
"")
G.CurrentDir = s.tmpdir

View file

@ -37,9 +37,9 @@ func (exp *Expecter) StepBack() {
exp.index--
}
func (exp *Expecter) AdvanceIfMatches(re string) bool {
func (exp *Expecter) AdvanceIfMatches(re RegexPattern) bool {
if G.opts.Debug {
defer tracecall2(exp.CurrentLine().Text, re)()
defer tracecall(exp.CurrentLine().Text, re)()
}
if !exp.EOF() {

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestConvertToLogicalLines_nocont(c *check.C) {
func (s *Suite) Test_convertToLogicalLines_no_continuation(c *check.C) {
rawText := "" +
"first line\n" +
"second line\n"
@ -16,7 +16,7 @@ func (s *Suite) TestConvertToLogicalLines_nocont(c *check.C) {
c.Check(lines[1].String(), equals, "fname_nocont:2: second line")
}
func (s *Suite) TestConvertToLogicalLines_cont(c *check.C) {
func (s *Suite) Test_convertToLogicalLines_continuation(c *check.C) {
rawText := "" +
"first line \\\n" +
"second line\n" +
@ -29,7 +29,7 @@ func (s *Suite) TestConvertToLogicalLines_cont(c *check.C) {
c.Check(lines[1].String(), equals, "fname_cont:3: third")
}
func (s *Suite) TestConvertToLogicalLines_contInLastLine(c *check.C) {
func (s *Suite) Test_convertToLogicalLines_continuationInLastLine(c *check.C) {
rawText := "" +
"last line\\"
@ -40,7 +40,7 @@ func (s *Suite) TestConvertToLogicalLines_contInLastLine(c *check.C) {
c.Check(s.Stdout(), equals, "ERROR: fname_contlast:EOF: File must end with a newline.\n")
}
func (s *Suite) TestSplitRawLine(c *check.C) {
func (s *Suite) Test_splitRawLine(c *check.C) {
leadingWhitespace, text, trailingWhitespace, continuation := splitRawLine("\n")
c.Check(leadingWhitespace, equals, "")
@ -56,7 +56,7 @@ func (s *Suite) TestSplitRawLine(c *check.C) {
c.Check(continuation, equals, "\\")
}
func (s *Suite) TestAutofix_show(c *check.C) {
func (s *Suite) Test_show_autofix(c *check.C) {
s.UseCommandLine(c, "--show-autofix")
fname := s.CreateTmpFile(c, "Makefile", ""+
"line1\n"+
@ -76,7 +76,7 @@ func (s *Suite) TestAutofix_show(c *check.C) {
"AUTOFIX: ~/Makefile:2: Replacing regular expression \".\" with \"X\".\n")
}
func (s *Suite) TestAutofix_fix(c *check.C) {
func (s *Suite) Test_autofix(c *check.C) {
s.UseCommandLine(c, "--autofix")
fname := s.CreateTmpFile(c, "Makefile", ""+
"line1\n"+

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestGetopt_Short(c *check.C) {
func (s *Suite) Test_Options_Parse_short(c *check.C) {
opts := NewOptions()
var help bool
opts.AddFlagVar('h', "help", &help, false, "prints a help page")
@ -16,7 +16,7 @@ func (s *Suite) TestGetopt_Short(c *check.C) {
c.Check(help, equals, true)
}
func (s *Suite) TestGetopt_UnknownShort(c *check.C) {
func (s *Suite) Test_Options_Parse_unknown_short(c *check.C) {
opts := NewOptions()
_, err := opts.Parse([]string{"progname", "-z"})
@ -24,7 +24,7 @@ func (s *Suite) TestGetopt_UnknownShort(c *check.C) {
c.Check(err.Error(), equals, "progname: unknown option: -z")
}
func (s *Suite) TestGetopt_UnknownLong(c *check.C) {
func (s *Suite) Test_Options_Parse_unknown_long(c *check.C) {
opts := NewOptions()
_, err := opts.Parse([]string{"progname", "--unknown-long"})
@ -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_UnknownFlagInGroup(c *check.C) {
func (s *Suite) Test_Options_Parse_unknown_flag_in_group(c *check.C) {
opts := NewOptions()
opts.AddFlagGroup('W', "warnings", "", "")
@ -49,7 +49,7 @@ func (s *Suite) TestGetopt_UnknownFlagInGroup(c *check.C) {
c.Check(err.Error(), equals, "progname: option requires an argument: -W")
}
func (s *Suite) TestGetopt_AbbreviatedLong(c *check.C) {
func (s *Suite) Test_Options_Parse_abbreviated_long(c *check.C) {
opts := NewOptions()
var longFlag, longerFlag bool
opts.AddFlagVar('?', "long", &longFlag, false, "")
@ -75,7 +75,7 @@ func (s *Suite) TestGetopt_AbbreviatedLong(c *check.C) {
c.Check(longerFlag, equals, true)
}
func (s *Suite) TestGetopt_MixedArgsAndOptions(c *check.C) {
func (s *Suite) Test_Options_Parse_mixed_args_and_options(c *check.C) {
opts := NewOptions()
var aflag, bflag bool
opts.AddFlagVar('a', "aflag", &aflag, false, "")

View file

@ -70,7 +70,7 @@ func (gd *GlobalData) loadDistSites() {
name2url := make(map[string]string)
url2name := make(map[string]string)
for _, line := range lines {
if m, varname, _, _, urls, _ := MatchVarassign(line.Text); m {
if m, varname, _, _, _, urls, _ := MatchVarassign(line.Text); m {
if hasPrefix(varname, "MASTER_SITE_") && varname != "MASTER_SITE_BACKUP" {
for _, url := range splitOnSpace(urls) {
if matches(url, `^(?:http://|https://|ftp://)`) {
@ -138,7 +138,7 @@ func (gd *GlobalData) loadTools() {
fname := G.globalData.Pkgsrcdir + "/mk/tools/" + basename
lines := LoadExistingLines(fname, true)
for _, line := range lines {
if m, varname, _, _, value, _ := MatchVarassign(line.Text); m {
if m, varname, _, _, _, value, _ := MatchVarassign(line.Text); m {
if varname == "TOOLS_CREATE" && (value == "[" || matches(value, `^?[-\w.]+$`)) {
reg.Register(value)
@ -166,7 +166,7 @@ func (gd *GlobalData) loadTools() {
for _, line := range lines {
text := line.Text
if m, varname, _, _, value, _ := MatchVarassign(text); m {
if m, varname, _, _, _, value, _ := MatchVarassign(text); m {
if varname == "USE_TOOLS" {
if G.opts.Debug {
traceStep("[condDepth=%d] %s", condDepth, value)

View file

@ -4,14 +4,14 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestGlobalDataVartypes(c *check.C) {
func (s *Suite) Test_GlobalData_InitVartypes(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, "YesNoIndirectly")
}
func (s *Suite) TestParselinesSuggestedUpdates(c *check.C) {
func (s *Suite) Test_parselinesSuggestedUpdates(c *check.C) {
lines := s.NewLines("doc/TODO",
"",
"Suggested package updates",
@ -30,7 +30,7 @@ func (s *Suite) TestParselinesSuggestedUpdates(c *check.C) {
{lines[6], "freeciv-client", "2.5.0", "(urgent)"}})
}
func (s *Suite) TestGlobalData_LoadTools(c *check.C) {
func (s *Suite) Test_GlobalData_loadTools(c *check.C) {
s.CreateTmpFileLines(c, "mk/tools/bsd.tools.mk",
".include \"flex.mk\"",
".include \"gettext.mk\"")
@ -74,7 +74,7 @@ func (s *Suite) TestGlobalData_LoadTools(c *check.C) {
"TRACE: - (*ToolRegistry).Trace()\n")
}
func (s *Suite) TestGlobalData_loadDocChanges(c *check.C) {
func (s *Suite) Test_GlobalData_loadDocChangesFromFile(c *check.C) {
s.CreateTmpFile(c, "doc/CHANGES-2015", ""+
"\tAdded category/package version 1.0 [author1 2015-01-01]\n"+
"\tUpdated category/package to 1.5 [author2 2015-01-02]\n"+
@ -96,7 +96,7 @@ func (s *Suite) TestGlobalData_loadDocChanges(c *check.C) {
c.Check(*changes[6], equals, Change{changes[6].Line, "Downgraded", "category/package", "1.2", "author7", "2015-01-07"})
}
func (s *Suite) TestGlobalData_deprecated(c *check.C) {
func (s *Suite) Test_GlobalData_deprecated(c *check.C) {
G.globalData.loadDeprecatedVars()
line := NewLine("Makefile", 5, "USE_PERL5=\tyes", nil)

View file

@ -4,12 +4,12 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestParseLicenses(c *check.C) {
func (s *Suite) Test_parseLicenses(c *check.C) {
c.Check(parseLicenses("gnu-gpl-v2"), check.DeepEquals, []string{"gnu-gpl-v2"})
c.Check(parseLicenses("AND artistic"), check.DeepEquals, []string{"artistic"})
}
func (s *Suite) TestChecklineLicense(c *check.C) {
func (s *Suite) Test_checklineLicense(c *check.C) {
s.CreateTmpFile(c, "licenses/gnu-gpl-v2", "Most software \u2026")
mkline := NewMkLine(NewLine("Makefile", 7, "LICENSE=dummy", nil))
G.globalData.Pkgsrcdir = s.tmpdir

View file

@ -40,7 +40,7 @@ type Line struct {
changed bool
before []string
after []string
autofixMessage *string
autofixMessage string
}
func NewLine(fname string, lineno int, text string, rawLines []*RawLine) *Line {
@ -49,7 +49,7 @@ func NewLine(fname string, lineno int, text string, rawLines []*RawLine) *Line {
// NewLineMulti is for logical Makefile lines that end with backslash.
func NewLineMulti(fname string, firstLine, lastLine int, text string, rawLines []*RawLine) *Line {
return &Line{fname, int32(firstLine), int32(lastLine), text, rawLines, false, nil, nil, nil}
return &Line{fname, int32(firstLine), int32(lastLine), text, rawLines, false, nil, nil, ""}
}
// NewLineEOF creates a dummy line for logging, with the “line number” EOF.
@ -157,9 +157,9 @@ func (line *Line) String() string {
}
func (line *Line) logAutofix() {
if line.autofixMessage != nil {
logs(llAutofix, line.Fname, line.linenos(), "%s", *line.autofixMessage)
line.autofixMessage = nil
if line.autofixMessage != "" {
logs(llAutofix, line.Fname, line.linenos(), "%s", line.autofixMessage)
line.autofixMessage = ""
}
}
@ -200,7 +200,7 @@ func (line *Line) AutofixReplace(from, to string) bool {
return false
}
func (line *Line) AutofixReplaceRegexp(from, to string) bool {
func (line *Line) AutofixReplaceRegexp(from RegexPattern, to string) bool {
for _, rawLine := range line.raw {
if rawLine.Lineno != 0 {
if replaced := regcomp(from).ReplaceAllString(rawLine.textnl, to); replaced != rawLine.textnl {
@ -224,8 +224,7 @@ func (line *Line) RememberAutofix(format string, args ...interface{}) (hasBeenFi
return true
}
if G.opts.PrintAutofix {
msg := fmt.Sprintf(format, args...)
line.autofixMessage = &msg
line.autofixMessage = fmt.Sprintf(format, args...)
}
return false
}
@ -259,7 +258,7 @@ func (line *Line) CheckLength(maxlength int) {
}
}
func (line *Line) CheckValidCharacters(reChar string) {
func (line *Line) CheckValidCharacters(reChar RegexPattern) {
rest := regcomp(reChar).ReplaceAllString(line.Text, "")
if rest != "" {
uni := ""
@ -281,9 +280,9 @@ func (line *Line) CheckTrailingWhitespace() {
}
}
func (line *Line) CheckRcsid(prefixRe, suggestedPrefix string) bool {
func (line *Line) CheckRcsid(prefixRe RegexPattern, suggestedPrefix string) bool {
if G.opts.Debug {
defer tracecall2(prefixRe, suggestedPrefix)()
defer tracecall(prefixRe, suggestedPrefix)()
}
if matches(line.Text, `^`+prefixRe+`\$`+`NetBSD(?::[^\$]+)?\$$`) {

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestLineModify(c *check.C) {
func (s *Suite) Test_Line_modifications(c *check.C) {
s.UseCommandLine(c, "--show-autofix")
line := NewLine("fname", 1, "dummy", s.NewRawLines(1, "original\n"))
@ -53,7 +53,7 @@ func (s *Suite) TestLineModify(c *check.C) {
"after\n"})
}
func (s *Suite) TestLine_CheckAbsolutePathname(c *check.C) {
func (s *Suite) Test_Line_CheckAbsolutePathname(c *check.C) {
line := NewLine("Makefile", 1, "# dummy", nil)
line.CheckAbsolutePathname("bindir=/bin")
@ -62,7 +62,7 @@ func (s *Suite) TestLine_CheckAbsolutePathname(c *check.C) {
c.Check(s.Output(), equals, "WARN: Makefile:1: Found absolute pathname: /bin\n")
}
func (s *Suite) TestShowAutofix_replace(c *check.C) {
func (s *Suite) Test_Line_show_autofix_AutofixReplace(c *check.C) {
s.UseCommandLine(c, "--show-autofix", "--source")
line := NewLineMulti("Makefile", 27, 29, "# old", s.NewRawLines(
27, "before\n",
@ -83,7 +83,7 @@ func (s *Suite) TestShowAutofix_replace(c *check.C) {
"AUTOFIX: Makefile:27--29: Replacing \"old\" with \"new\".\n")
}
func (s *Suite) TestShowAutofix_insert(c *check.C) {
func (s *Suite) Test_Line_show_autofix_AutofixInsertBefore(c *check.C) {
s.UseCommandLine(c, "--show-autofix", "--source")
line := NewLine("Makefile", 30, "original", s.NewRawLines(30, "original\n"))
@ -99,7 +99,7 @@ func (s *Suite) TestShowAutofix_insert(c *check.C) {
"AUTOFIX: Makefile:30: Inserting a line \"inserted\" before this line.\n")
}
func (s *Suite) TestShowAutofix_delete(c *check.C) {
func (s *Suite) Test_Line_show_autofix_AutofixDelete(c *check.C) {
s.UseCommandLine(c, "--show-autofix", "--source")
line := NewLine("Makefile", 30, "to be deleted", s.NewRawLines(30, "to be deleted\n"))
@ -114,10 +114,28 @@ func (s *Suite) TestShowAutofix_delete(c *check.C) {
"AUTOFIX: Makefile:30: Deleting this line.\n")
}
func (s *Suite) TestLine_CheckTrailingWhitespace(c *check.C) {
func (s *Suite) Test_Line_CheckTrailingWhitespace(c *check.C) {
line := NewLine("Makefile", 32, "The line must go on ", nil)
line.CheckTrailingWhitespace()
c.Check(s.Output(), equals, "NOTE: Makefile:32: Trailing white-space.\n")
}
func (s *Suite) Test_Line_CheckRcsid(c *check.C) {
lines := s.NewLines("fname",
"$"+"NetBSD: dummy $",
"$"+"NetBSD$",
"$"+"Id: dummy $",
"$"+"Id$",
"$"+"FreeBSD$")
for _, line := range lines {
line.CheckRcsid(``, "")
}
c.Check(s.Output(), equals, ""+
"ERROR: fname:3: Expected \"$"+"NetBSD$\".\n"+
"ERROR: fname:4: Expected \"$"+"NetBSD$\".\n"+
"ERROR: fname:5: Expected \"$"+"NetBSD$\".\n")
}

View file

@ -6,21 +6,21 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestMainHelp(c *check.C) {
func (s *Suite) Test_Pkglint_Main_help(c *check.C) {
exitcode := new(Pkglint).Main("pkglint", "-h")
c.Check(exitcode, equals, 0)
c.Check(s.Output(), check.Matches, `^\Qusage: pkglint [options] dir...\E\n(?s).+`)
}
func (s *Suite) TestMainVersion(c *check.C) {
func (s *Suite) Test_Pkglint_Main_version(c *check.C) {
exitcode := new(Pkglint).Main("pkglint", "--version")
c.Check(exitcode, equals, 0)
c.Check(s.Output(), equals, confVersion+"\n")
}
func (s *Suite) TestMainNoArgs(c *check.C) {
func (s *Suite) Test_Pkglint_Main_no_args(c *check.C) {
exitcode := new(Pkglint).Main("pkglint")
c.Check(exitcode, equals, 1)
@ -31,7 +31,7 @@ func (s *Suite) TestMainNoArgs(c *check.C) {
// pkgsrcdir=...
// env PKGLINT_TESTCMDLINE="$pkgsrcdir -r" ./pkglint.test -test.coverprofile pkglint.cov -check.f TestRunPkglint
// go tool cover -html=pkglint.cov -o coverage.html
func (s *Suite) TestRunPkglint(c *check.C) {
func (s *Suite) Test_Pkglint_coverage(c *check.C) {
cmdline := os.Getenv("PKGLINT_TESTCMDLINE")
if cmdline != "" {
G.logOut, G.logErr, G.debugOut = os.Stdout, os.Stderr, os.Stdout

View file

@ -44,7 +44,20 @@ func NewMkLine(line *Line) (mkline *MkLine) {
"white-space.")
}
if m, varname, op, valueAlign, value, comment := MatchVarassign(text); m {
if m, varname, spaceAfterVarname, op, valueAlign, value, comment := MatchVarassign(text); m {
if G.opts.WarnSpace && spaceAfterVarname != "" {
switch {
case hasSuffix(varname, "+") && op == "=":
break
case matches(varname, `^[a-z]`) && op == ":=":
break
default:
if !line.AutofixReplace(varname+spaceAfterVarname+op, varname+op) {
line.Warn1("Unnecessary space after variable name %q.", varname)
}
}
}
value = strings.Replace(value, "\\#", "#", -1)
varparam := varnameParam(varname)
@ -243,7 +256,7 @@ func (mkline *MkLine) checkCond(forVars map[string]bool) {
indentation.Push(indentation.Depth() + 2)
}
reDirectivesWithArgs := `^(?:if|ifdef|ifndef|elif|for|undef)$`
const reDirectivesWithArgs = `^(?:if|ifdef|ifndef|elif|for|undef)$`
if matches(directive, reDirectivesWithArgs) && args == "" {
mkline.Error1("\".%s\" requires arguments.", directive)
@ -295,7 +308,7 @@ func (mkline *MkLine) checkCond(forVars map[string]bool) {
}
forLoopType := &Vartype{lkSpace, CheckvarUnchecked, []AclEntry{{"*", aclpAllRead}}, guessed}
forLoopContext := &VarUseContext{forLoopType, vucTimeParse, vucQuotFor, vucExtentWord}
forLoopContext := &VarUseContext{forLoopType, vucTimeParse, vucQuotFor, false}
for _, forLoopVar := range mkline.extractUsedVariables(values) {
mkline.CheckVaruse(&MkVarUse{forLoopVar, nil}, forLoopContext)
}
@ -640,7 +653,7 @@ func (mkline *MkLine) CheckVaruseShellword(varname string, vartype *Vartype, vuc
} else if needsQuoting == nqYes {
correctMod := strippedMod + ifelseStr(needMstar, ":M*:Q", ":Q")
if correctMod == mod+":Q" && vuc.extent == vucExtentWordpart && !vartype.IsShell() {
if correctMod == mod+":Q" && vuc.IsWordPart && !vartype.IsShell() {
mkline.Line.Warnf("The list variable %s should not be embedded in a word.", varname)
Explain(
"When a list variable has multiple elements, this expression expands",
@ -848,12 +861,8 @@ func (mkline *MkLine) checkVarassignVaruseMk(vartype *Vartype, time vucTime) {
if token.Varuse != nil {
spaceLeft := i-1 < 0 || matches(tokens[i-1].Text, `\s$`)
spaceRight := i+1 >= len(tokens) || matches(tokens[i+1].Text, `^\s`)
extent := vucExtentWordpart
if spaceLeft && spaceRight {
extent = vucExtentWord
}
vuc := &VarUseContext{vartype, time, vucQuotPlain, extent}
isWordPart := !(spaceLeft && spaceRight)
vuc := &VarUseContext{vartype, time, vucQuotPlain, isWordPart}
mkline.CheckVaruse(token.Varuse, vuc)
}
}
@ -864,27 +873,21 @@ func (mkline *MkLine) checkVarassignVaruseShell(vartype *Vartype, time vucTime)
defer tracecall(vartype, time)()
}
extent := func(tokens []*ShAtom, i int) vucExtent {
if i-1 >= 0 {
typ := tokens[i-1].Type
if typ != shtSpace && typ != shtSemicolon && typ != shtParenOpen && typ != shtParenClose {
return vucExtentWordpart
}
isWordPart := func(tokens []*ShAtom, i int) bool {
if i-1 >= 0 && tokens[i-1].Type.IsWord() {
return true
}
if i+1 < len(tokens) {
typ := tokens[i+1].Type
if typ != shtSpace && typ != shtSemicolon && typ != shtParenOpen && typ != shtParenClose {
return vucExtentWordpart
}
if i+1 < len(tokens) && tokens[i+1].Type.IsWord() {
return true
}
return vucExtentWord
return false
}
atoms := NewShTokenizer(mkline.Line, mkline.Value(), false).ShAtoms()
for i, atom := range atoms {
if atom.Type == shtVaruse {
extent := extent(atoms, i)
vuc := &VarUseContext{vartype, time, atom.Quoting.ToVarUseContext(), extent}
isWordPart := isWordPart(atoms, i)
vuc := &VarUseContext{vartype, time, atom.Quoting.ToVarUseContext(), isWordPart}
mkline.CheckVaruse(atom.Data.(*MkVarUse), vuc)
}
}
@ -1028,46 +1031,42 @@ func (mkline *MkLine) CheckVartype(varname string, op MkOperator, value, comment
}
case vartype.kindOfList == lkNone:
mkline.CheckVartypePrimitive(varname, vartype.checker, op, value, comment, vartype.IsConsideredList(), vartype.guessed)
mkline.CheckVartypePrimitive(varname, vartype.checker, op, value, comment, vartype.guessed)
case value == "":
break
case vartype.kindOfList == lkSpace:
for _, word := range splitOnSpace(value) {
mkline.CheckVartypePrimitive(varname, vartype.checker, op, word, comment, true, vartype.guessed)
mkline.CheckVartypePrimitive(varname, vartype.checker, op, word, comment, vartype.guessed)
}
case vartype.kindOfList == lkShell:
words, _ := splitIntoMkWords(mkline.Line, value)
for _, word := range words {
mkline.CheckVartypePrimitive(varname, vartype.checker, op, word, comment, true, vartype.guessed)
mkline.CheckVartypePrimitive(varname, vartype.checker, op, word, comment, vartype.guessed)
}
}
}
// For some variables (like `BuildlinkDepth`), `op` influences the valid values.
// The `comment` parameter comes from a variable assignment, when a part of the line is commented out.
func (mkline *MkLine) CheckVartypePrimitive(varname string, checker *VarChecker, op MkOperator, value, comment string, isList bool, guessed bool) {
func (mkline *MkLine) CheckVartypePrimitive(varname string, checker *VarChecker, op MkOperator, value, comment string, guessed bool) {
if G.opts.Debug {
defer tracecall(varname, checker.name, op, value, comment, isList, guessed)()
defer tracecall(varname, checker.name, op, value, comment, guessed)()
}
valueNoVar := mkline.withoutMakeVariables(value, isList)
ctx := &VartypeCheck{mkline, mkline.Line, varname, op, value, valueNoVar, comment, isList, guessed}
valueNoVar := mkline.withoutMakeVariables(value)
ctx := &VartypeCheck{mkline, mkline.Line, varname, op, value, valueNoVar, comment, guessed}
checker.checker(ctx)
}
func (mkline *MkLine) withoutMakeVariables(value string, qModifierAllowed bool) string {
func (mkline *MkLine) withoutMakeVariables(value string) string {
valueNovar := value
for {
var m []string
if m, valueNovar = replaceFirst(valueNovar, `\$\{([^{}]*)\}`, ""); m != nil {
varuse := m[1]
if !qModifierAllowed && hasSuffix(varuse, ":Q") {
mkline.Warn0("The :Q operator should only be used in lists and shell commands.")
}
} else {
m, valueNovar = replaceFirst(valueNovar, `\$\{[^{}]*\}`, "")
if m == nil {
return valueNovar
}
}
@ -1198,7 +1197,7 @@ func (mkline *MkLine) rememberUsedVariables(cond *Tree) {
cond.Visit("compareVarVar", arg2varuse)
}
func (mkline *MkLine) CheckValidCharactersInValue(reValid string) {
func (mkline *MkLine) CheckValidCharactersInValue(reValid RegexPattern) {
rest := regcomp(reValid).ReplaceAllString(mkline.Value(), "")
if rest != "" {
uni := ""
@ -1335,7 +1334,7 @@ func (mkline *MkLine) variableNeedsQuoting(varname string, vartype *Vartype, vuc
if vartype.kindOfList == lkNone {
return nqDoesntMatter
}
if vartype.kindOfList == lkShell && vuc.extent != vucExtentWordpart {
if vartype.kindOfList == lkShell && !vuc.IsWordPart {
return nqNo
}
}
@ -1355,7 +1354,7 @@ func (mkline *MkLine) variableNeedsQuoting(varname string, vartype *Vartype, vuc
}
// A shell word may appear as part of a shell word, for example COMPILER_RPATH_FLAG.
if vuc.extent == vucExtentWordpart && vuc.quoting == vucQuotPlain {
if vuc.IsWordPart && vuc.quoting == vucQuotPlain {
if vartype.kindOfList == lkNone && vartype.checker == CheckvarShellWord {
return nqNo
}
@ -1364,7 +1363,7 @@ func (mkline *MkLine) variableNeedsQuoting(varname string, vartype *Vartype, vuc
// Both of these can be correct, depending on the situation:
// 1. echo ${PERL5:Q}
// 2. xargs ${PERL5}
if vuc.extent == vucExtentWord && vuc.quoting == vucQuotPlain {
if !vuc.IsWordPart && vuc.quoting == vucQuotPlain {
if wantList && haveList {
return nqDontKnow
}
@ -1375,7 +1374,7 @@ func (mkline *MkLine) variableNeedsQuoting(varname string, vartype *Vartype, vuc
if G.globalData.Tools.byVarname[varname] != nil {
switch vuc.quoting {
case vucQuotPlain:
if vuc.extent != vucExtentWordpart {
if !vuc.IsWordPart {
return nqNo
}
case vucQuotBackt:
@ -1389,7 +1388,7 @@ func (mkline *MkLine) variableNeedsQuoting(varname string, vartype *Vartype, vuc
// to be quoted. An exception is in the case of backticks,
// because the whole backticks expression is parsed as a single
// shell word by pkglint.
if vuc.extent == vucExtentWordpart && vuc.vartype != nil && vuc.vartype.IsShell() && vuc.quoting != vucQuotBackt {
if vuc.IsWordPart && vuc.vartype != nil && vuc.vartype.IsShell() && vuc.quoting != vucQuotBackt {
return nqYes
}
@ -1401,7 +1400,7 @@ func (mkline *MkLine) variableNeedsQuoting(varname string, vartype *Vartype, vuc
// Assigning lists to lists does not require any quoting, though
// there may be cases like "CONFIGURE_ARGS+= -libs ${LDFLAGS:Q}"
// where quoting is necessary.
if wantList && haveList && vuc.extent != vucExtentWordpart {
if wantList && haveList && !vuc.IsWordPart {
return nqDoesntMatter
}
@ -1419,7 +1418,7 @@ func (mkline *MkLine) variableNeedsQuoting(varname string, vartype *Vartype, vuc
// Bad: LDADD += -l${LIBS}
// Good: LDADD += ${LIBS:@lib@-l${lib} @}
if wantList && haveList && vuc.extent == vucExtentWordpart {
if wantList && haveList && vuc.IsWordPart {
return nqYes
}
@ -1586,10 +1585,10 @@ func (mkline *MkLine) determineUsedVariables() (varnames []string) {
// checked against the variable type. For example, comparing OPSYS to
// x86_64 doesnt make sense.
type VarUseContext struct {
vartype *Vartype
time vucTime
quoting vucQuoting
extent vucExtent
vartype *Vartype
time vucTime
quoting vucQuoting
IsWordPart bool // Example: echo ${LOCALBASE} LOCALBASE=${LOCALBASE}
}
type vucTime uint8
@ -1633,21 +1632,12 @@ func (q vucQuoting) String() string {
return [...]string{"unknown", "plain", "dquot", "squot", "backt", "mk-for"}[q]
}
type vucExtent uint8
const (
vucExtentWord vucExtent = iota // Example: echo ${LOCALBASE}
vucExtentWordpart // Example: echo LOCALBASE=${LOCALBASE}
)
func (e vucExtent) String() string { return [...]string{"word", "wordpart"}[e] }
func (vuc *VarUseContext) String() string {
typename := "no-type"
if vuc.vartype != nil {
typename = vuc.vartype.String()
}
return fmt.Sprintf("(%s time:%s quoting:%s extent:%s)", typename, vuc.time, vuc.quoting, vuc.extent)
return fmt.Sprintf("(%s time:%s quoting:%s wordpart:%v)", typename, vuc.time, vuc.quoting, vuc.IsWordPart)
}
type Indentation struct {

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestChecklineMkVartype_SimpleType(c *check.C) {
func (s *Suite) Test_MkLine_CheckVartype_simple_type(c *check.C) {
s.UseCommandLine(c, "-Wtypes")
G.globalData.InitVartypes()
mkline := NewMkLine(NewLine("fname", 1, "COMMENT=\tA nice package", nil))
@ -25,14 +25,14 @@ func (s *Suite) TestChecklineMkVartype_SimpleType(c *check.C) {
c.Check(s.Stdout(), equals, "WARN: fname:1: COMMENT should not begin with \"A\".\n")
}
func (s *Suite) TestChecklineMkVartype(c *check.C) {
func (s *Suite) Test_MkLine_CheckVartype(c *check.C) {
G.globalData.InitVartypes()
mkline := NewMkLine(NewLine("fname", 1, "DISTNAME=gcc-${GCC_VERSION}", nil))
mkline.CheckVartype("DISTNAME", opAssign, "gcc-${GCC_VERSION}", "")
}
func (s *Suite) TestMkLine_CheckVaralign_Autofix(c *check.C) {
func (s *Suite) Test_VaralignBlock_Check_autofix(c *check.C) {
s.UseCommandLine(c, "-Wspace", "-f")
lines := s.NewLines("file.mk",
"VAR= value", // Indentation 7, fixed to 8.
@ -49,7 +49,7 @@ func (s *Suite) TestMkLine_CheckVaralign_Autofix(c *check.C) {
"", //
"VAR=\tvalue") // Already aligned with tabs only, left unchanged.
varalign := new(VaralignBlock)
varalign := &VaralignBlock{}
for _, line := range lines {
varalign.Check(NewMkLine(line))
}
@ -84,7 +84,7 @@ func (s *Suite) TestMkLine_CheckVaralign_Autofix(c *check.C) {
"AUTOFIX: file.mk:11: Replacing \"VAR= \\t\" with \"VAR=\\t\".\n")
}
func (s *Suite) TestMkLine_CheckVaralign_ReduceIndentation(c *check.C) {
func (s *Suite) Test_VaralignBlock_Check_reduce_indentation(c *check.C) {
s.UseCommandLine(c, "-Wspace")
mklines := s.NewMkLines("file.mk",
"VAR= \tvalue",
@ -107,7 +107,7 @@ func (s *Suite) TestMkLine_CheckVaralign_ReduceIndentation(c *check.C) {
"NOTE: file.mk:3: This variable value should be aligned to column 9.\n")
}
func (s *Suite) TestMkLine_CheckVaralign_LongestLineEmptyAlignment(c *check.C) {
func (s *Suite) Test_VaralignBlock_Check_longest_line_no_space(c *check.C) {
s.UseCommandLine(c, "-Wspace")
mklines := s.NewMkLines("file.mk",
"SUBST_CLASSES+= aaaaaaaa",
@ -128,7 +128,7 @@ func (s *Suite) TestMkLine_CheckVaralign_LongestLineEmptyAlignment(c *check.C) {
"NOTE: file.mk:4: This variable value should be aligned to column 33.\n")
}
func (s *Suite) TestMkLine_CheckVaralign_OnlySpaces(c *check.C) {
func (s *Suite) Test_VaralignBlock_Check_only_spaces(c *check.C) {
s.UseCommandLine(c, "-Wspace")
mklines := s.NewMkLines("file.mk",
"SUBST_CLASSES+= aaaaaaaa",
@ -149,7 +149,8 @@ func (s *Suite) TestMkLine_CheckVaralign_OnlySpaces(c *check.C) {
"NOTE: file.mk:4: This variable value should be aligned with tabs, not spaces, to column 33.\n")
}
func (s *Suite) TestMkLine_fields(c *check.C) {
func (s *Suite) Test_NewMkLine(c *check.C) {
s.UseCommandLine(c, "-Wspace")
mklines := NewMkLines(s.NewLines("test.mk",
"VARNAME.param?=value # varassign comment",
"\tshell command # shell comment",
@ -208,7 +209,41 @@ func (s *Suite) TestMkLine_fields(c *check.C) {
c.Check(s.Output(), equals, "WARN: test.mk:9: Space before colon in dependency line.\n")
}
func (s *Suite) TestMkLine_checkVarassign(c *check.C) {
func (s *Suite) Test_NewMkLine__autofix_space_after_varname(c *check.C) {
s.UseCommandLine(c, "-Wspace")
fname := s.CreateTmpFileLines(c, "Makefile",
mkrcsid,
"VARNAME +=\t${VARNAME}",
"VARNAME+ =\t${VARNAME+}",
"VARNAME+ +=\t${VARNAME+}",
"pkgbase := pkglint")
CheckfileMk(fname)
c.Check(s.Output(), equals, ""+
"WARN: ~/Makefile:2: Unnecessary space after variable name \"VARNAME\".\n"+
"WARN: ~/Makefile:4: Unnecessary space after variable name \"VARNAME+\".\n")
s.UseCommandLine(c, "-Wspace", "--autofix")
CheckfileMk(fname)
c.Check(s.Output(), equals, ""+
"AUTOFIX: ~/Makefile:2: Replacing \"VARNAME +=\" with \"VARNAME+=\".\n"+
"AUTOFIX: ~/Makefile:4: Replacing \"VARNAME+ +=\" with \"VARNAME++=\".\n"+
"AUTOFIX: ~/Makefile: Has been auto-fixed. Please re-run pkglint.\n"+
"AUTOFIX: ~/Makefile: Has been auto-fixed. Please re-run pkglint.\n")
c.Check(s.LoadTmpFile(c, "Makefile"), equals, ""+
"# $NetBSD: mkline_test.go,v 1.14 2016/07/09 09:43:48 rillig Exp $\n"+
"VARNAME+=\t${VARNAME}\n"+
"VARNAME+ =\t${VARNAME+}\n"+
"VARNAME++=\t${VARNAME+}\n"+
"pkgbase := pkglint\n")
}
// Pkglint once interpreted all lists as consisting of shell tokens,
// splitting this URL at the ampersands.
func (s *Suite) Test_MkLine_checkVarassign_URL_with_shell_special_characters(c *check.C) {
G.Pkg = NewPackage("graphics/gimp-fix-ca")
G.globalData.InitVartypes()
mkline := NewMkLine(NewLine("fname", 10, "MASTER_SITES=http://registry.gimp.org/file/fix-ca.c?action=download&id=9884&file=", nil))
@ -218,7 +253,7 @@ func (s *Suite) TestMkLine_checkVarassign(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestChecklineMkCondition(c *check.C) {
func (s *Suite) Test_MkLine_Check_conditions(c *check.C) {
s.UseCommandLine(c, "-Wtypes")
G.globalData.InitVartypes()
@ -263,7 +298,7 @@ func (s *Suite) TestChecklineMkCondition(c *check.C) {
"WARN: fname:98: The pattern \"x86\" cannot match any of { aarch64 aarch64eb alpha amd64 arc arm arm26 arm32 cobalt coldfire convex dreamcast earm earmeb earmhf earmhfeb earmv4 earmv4eb earmv5 earmv5eb earmv6 earmv6eb earmv6hf earmv6hfeb earmv7 earmv7eb earmv7hf earmv7hfeb evbarm hpcmips hpcsh hppa hppa64 i386 i586 i686 ia64 m68000 m68k m88k mips mips64 mips64eb mips64el mipseb mipsel mipsn32 mlrisc ns32k pc532 pmax powerpc powerpc64 rs6000 s390 sh3eb sh3el sparc sparc64 vax x86_64 } for MACHINE_ARCH.\n")
}
func (s *Suite) TestMkLine_variableNeedsQuoting_Varbase(c *check.C) {
func (s *Suite) Test_MkLine_getVariableType_varparam(c *check.C) {
mkline := NewMkLine(NewLine("fname", 1, "# dummy", nil))
G.globalData.InitVartypes()
@ -278,16 +313,16 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_Varbase(c *check.C) {
c.Check(t2.String(), equals, "ShellList of Pathmask")
}
func (s *Suite) TestVarUseContext_ToString(c *check.C) {
func (s *Suite) Test_VarUseContext_String(c *check.C) {
G.globalData.InitVartypes()
mkline := NewMkLine(NewLine("fname", 1, "# dummy", nil))
vartype := mkline.getVariableType("PKGNAME")
vuc := &VarUseContext{vartype, vucTimeUnknown, vucQuotBackt, vucExtentWord}
vuc := &VarUseContext{vartype, vucTimeUnknown, vucQuotBackt, false}
c.Check(vuc.String(), equals, "(PkgName time:unknown quoting:backt extent:word)")
c.Check(vuc.String(), equals, "(PkgName time:unknown quoting:backt wordpart:false)")
}
func (s *Suite) TestMkLine_(c *check.C) {
func (s *Suite) Test_MkLine_checkVarassign(c *check.C) {
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("Makefile",
@ -302,42 +337,44 @@ func (s *Suite) TestMkLine_(c *check.C) {
// In variable assignments, a plain '#' introduces a line comment, unless
// it is escaped by a backslash. In shell commands, on the other hand, it
// is interpreted literally.
func (s *Suite) TestParselineMk(c *check.C) {
line1 := NewMkLine(NewLine("fname", 1, "SED_CMD=\t's,\\#,hash,g'", nil))
func (s *Suite) Test_NewMkLine_numbersign(c *check.C) {
mklineVarassignEscaped := NewMkLine(NewLine("fname", 1, "SED_CMD=\t's,\\#,hash,g'", nil))
c.Check(line1.Varname(), equals, "SED_CMD")
c.Check(line1.Value(), equals, "'s,#,hash,g'")
c.Check(mklineVarassignEscaped.Varname(), equals, "SED_CMD")
c.Check(mklineVarassignEscaped.Value(), equals, "'s,#,hash,g'")
line2 := NewMkLine(NewLine("fname", 1, "\tsed -e 's,\\#,hash,g'", nil))
mklineCommandEscaped := NewMkLine(NewLine("fname", 1, "\tsed -e 's,\\#,hash,g'", nil))
c.Check(line2.Shellcmd(), equals, "sed -e 's,\\#,hash,g'")
c.Check(mklineCommandEscaped.Shellcmd(), equals, "sed -e 's,\\#,hash,g'")
// From shells/zsh/Makefile.common, rev. 1.78
NewMkLine(NewLine("fname", 1, "\t# $ sha1 patches/patch-ac", nil))
mklineCommandUnescaped := NewMkLine(NewLine("fname", 1, "\t# $ sha1 patches/patch-ac", nil))
c.Check(s.Output(), equals, "")
c.Check(mklineCommandUnescaped.Shellcmd(), equals, "# $ sha1 patches/patch-ac")
c.Check(s.Output(), equals, "") // No warning about parsing the lonely dollar sign.
mklineVarassignUnescaped := NewMkLine(NewLine("fname", 1, "SED_CMD=\t's,#,hash,'", nil))
c.Check(mklineVarassignUnescaped.Value(), equals, "'s,")
}
func (s *Suite) TestMkLine_LeadingSpace(c *check.C) {
func (s *Suite) Test_NewMkLine_leading_space(c *check.C) {
_ = NewMkLine(NewLine("rubyversion.mk", 427, " _RUBYVER=\t2.15", nil))
c.Check(s.Output(), equals, "WARN: rubyversion.mk:427: Makefile lines should not start with space characters.\n")
}
func (s *Suite) TestMkLine_checkVarassignDefPermissions(c *check.C) {
func (s *Suite) Test_MkLine_checkVarassignDefPermissions(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("options.mk",
"# $"+"NetBSD$",
"PKG_DEVELOPER?=\tyes",
"COMMENT=\t${PKG_DEVELOPER}")
mkline := NewMkLine(NewLine("options.mk", 2, "PKG_DEVELOPER?=\tyes", nil))
mklines.Check()
mkline.checkVarassignDefPermissions()
c.Check(s.Output(), equals, "WARN: options.mk:2: The variable PKG_DEVELOPER may not be given a default value by any package.\n")
}
func (s *Suite) TestMkLine_CheckVarusePermissions(c *check.C) {
func (s *Suite) Test_MkLine_CheckVarusePermissions(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("options.mk",
@ -359,7 +396,7 @@ func (s *Suite) TestMkLine_CheckVarusePermissions(c *check.C) {
"NOTE: options.mk:4: This variable value should be aligned to column 17.\n")
}
func (s *Suite) Test_MkLine_CheckVarusePermissions_LoadTime(c *check.C) {
func (s *Suite) Test_MkLine_CheckVarusePermissions__load_time(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("options.mk",
@ -371,7 +408,7 @@ func (s *Suite) Test_MkLine_CheckVarusePermissions_LoadTime(c *check.C) {
c.Check(s.Output(), equals, "") // Dont warn that “.CURDIR should not be evaluated at load time.”
}
func (s *Suite) TestMkLine_WarnVaruseLocalbase(c *check.C) {
func (s *Suite) Test_MkLine_WarnVaruseLocalbase(c *check.C) {
mkline := NewMkLine(NewLine("options.mk", 56, "PKGNAME=${LOCALBASE}", nil))
mkline.WarnVaruseLocalbase()
@ -379,7 +416,7 @@ func (s *Suite) TestMkLine_WarnVaruseLocalbase(c *check.C) {
c.Check(s.Output(), equals, "WARN: options.mk:56: The LOCALBASE variable should not be used by packages.\n")
}
func (s *Suite) TestMkLine_Misc(c *check.C) {
func (s *Suite) Test_MkLines_Check__extra(c *check.C) {
s.UseCommandLine(c, "-Wextra")
G.globalData.InitVartypes()
G.Pkg = NewPackage("category/pkgbase")
@ -406,7 +443,7 @@ func (s *Suite) TestMkLine_Misc(c *check.C) {
"NOTE: options.mk:10: You can use \"../build\" instead of \"${WRKSRC}/../build\".\n")
}
func (s *Suite) TestMkLine_CheckRelativePkgdir(c *check.C) {
func (s *Suite) Test_MkLine_CheckRelativePkgdir(c *check.C) {
mkline := NewMkLine(NewLine("Makefile", 46, "# dummy", nil))
mkline.CheckRelativePkgdir("../pkgbase")
@ -417,7 +454,7 @@ func (s *Suite) TestMkLine_CheckRelativePkgdir(c *check.C) {
}
// PR pkg/46570, item 2
func (s *Suite) TestMkLine_UnfinishedVaruse(c *check.C) {
func (s *Suite) Test_MkLine__unclosed_varuse(c *check.C) {
mkline := NewMkLine(NewLine("Makefile", 93, "EGDIRS=${EGDIR/apparmor.d ${EGDIR/dbus-1/system.d ${EGDIR/pam.d", nil))
mkline.checkVarassign()
@ -428,23 +465,23 @@ func (s *Suite) TestMkLine_UnfinishedVaruse(c *check.C) {
"WARN: Makefile:93: EGDIRS is defined but not used. Spelling mistake?\n")
}
func (s *Suite) TestMkLine_variableNeedsQuoting_1(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__unknown_rhs(c *check.C) {
mkline := NewMkLine(NewLine("fname", 1, "PKGNAME := ${UNKNOWN}", nil))
G.globalData.InitVartypes()
vuc := &VarUseContext{G.globalData.vartypes["PKGNAME"], vucTimeParse, vucQuotUnknown, vucExtentWord}
vuc := &VarUseContext{G.globalData.vartypes["PKGNAME"], vucTimeParse, vucQuotUnknown, false}
nq := mkline.variableNeedsQuoting("UNKNOWN", nil, vuc)
c.Check(nq, equals, nqDontKnow)
}
func (s *Suite) TestMkLine_variableNeedsQuoting_2(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__append_URL_to_list_of_URLs(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
s.RegisterMasterSite("MASTER_SITE_SOURCEFORGE", "http://downloads.sourceforge.net/sourceforge/")
mkline := NewMkLine(NewLine("Makefile", 95, "MASTER_SITES=\t${HOMEPAGE}", nil))
vuc := &VarUseContext{G.globalData.vartypes["MASTER_SITES"], vucTimeRun, vucQuotPlain, vucExtentWord}
vuc := &VarUseContext{G.globalData.vartypes["MASTER_SITES"], vucTimeRun, vucQuotPlain, false}
nq := mkline.variableNeedsQuoting("HOMEPAGE", G.globalData.vartypes["HOMEPAGE"], vuc)
c.Check(nq, equals, nqNo)
@ -455,7 +492,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_2(c *check.C) {
}
// Assigning lists to lists is ok.
func (s *Suite) TestMkLine_variableNeedsQuoting_3(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__append_list_to_list(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
s.RegisterMasterSite("MASTER_SITE_SOURCEFORGE", "http://downloads.sourceforge.net/sourceforge/")
@ -466,7 +503,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_3(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestMkLine_variableNeedsQuoting_4(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__eval_shell(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mkline := NewMkLine(NewLine("builtin.mk", 3, "USE_BUILTIN.Xfixes!=\t${PKG_ADMIN} pmatch 'pkg-[0-9]*' ${BUILTIN_PKG.Xfixes:Q}", nil))
@ -478,7 +515,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_4(c *check.C) {
"NOTE: builtin.mk:3: The :Q operator isn't necessary for ${BUILTIN_PKG.Xfixes} here.\n")
}
func (s *Suite) TestMkLine_variableNeedsQuoting_5(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__command_in_single_quotes(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mkline := NewMkLine(NewLine("Makefile", 3, "SUBST_SED.hpath=\t-e 's|^\\(INSTALL[\t:]*=\\).*|\\1${INSTALL}|'", nil))
@ -488,7 +525,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_5(c *check.C) {
c.Check(s.Output(), equals, "WARN: Makefile:3: Please use ${INSTALL:Q} instead of ${INSTALL} and make sure the variable appears outside of any quoting characters.\n")
}
func (s *Suite) TestMkLine_variableNeedsQuoting_6(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__command_in_command(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
s.RegisterTool(&Tool{Name: "find", Varname: "FIND", Predefined: true})
@ -505,7 +542,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_6(c *check.C) {
"WARN: Makefile:2: The exitcode of the left-hand-side command of the pipe operator is ignored.\n")
}
func (s *Suite) TestMkLine_variableNeedsQuoting_7(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__word_as_part_of_word(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("Makefile",
@ -517,8 +554,13 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_7(c *check.C) {
c.Check(s.Output(), equals, "")
}
// As an argument to ${ECHO}, the :Q modifier should be used, but pkglint
// currently does not know all shell commands and how they handle their
// arguments. As an argument to xargs(1), the :Q modifier would be misplaced,
// therefore no warning is issued.
//
// Based on graphics/circos/Makefile.
func (s *Suite) TestMkLine_variableNeedsQuoting_8(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__command_as_command_argument(c *check.C) {
s.UseCommandLine(c, "-Wall")
s.RegisterTool(&Tool{Name: "perl", Varname: "PERL5", Predefined: true})
s.RegisterTool(&Tool{Name: "bash", Varname: "BASH", Predefined: true})
@ -537,7 +579,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_8(c *check.C) {
}
// Based on mail/mailfront/Makefile.
func (s *Suite) TestMkLine_variableNeedsQuoting_9(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__URL_as_part_of_word_in_list(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("Makefile",
@ -549,8 +591,12 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_9(c *check.C) {
c.Check(s.Output(), equals, "") // Dont suggest to use ${HOMEPAGE:Q}.
}
// Pkglint currently does not parse $$(subshell) commands very well. As
// a side effect, it sometimes issues wrong warnings about the :Q
// modifier.
//
// Based on www/firefox31/xpi.mk.
func (s *Suite) TestMkLine_variableNeedsQuoting_10(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__command_in_subshell(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
s.RegisterTool(&Tool{Name: "awk", Varname: "AWK", Predefined: true})
@ -566,7 +612,10 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_10(c *check.C) {
c.Check(s.Output(), equals, "WARN: xpi.mk:2: Invoking subshells via $(...) is not portable enough.\n") // Dont suggest to use ${AWK:Q}.
}
func (s *Suite) TestMkLine_variableNeedsQuoting_11(c *check.C) {
// LDFLAGS (and even more so CPPFLAGS and CFLAGS) may contain special
// shell characters like quotes or backslashes. Therefore, quoting them
// correctly is more tricky than with other variables.
func (s *Suite) Test_MkLine_variableNeedsQuoting__LDFLAGS_in_single_quotes(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("x11/mlterm/Makefile",
@ -580,7 +629,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_11(c *check.C) {
c.Check(s.Output(), equals, "WARN: x11/mlterm/Makefile:2: Please move ${LDFLAGS:M*:Q} outside of any quoting characters.\n")
}
func (s *Suite) TestMkLine_variableNeedsQuoting_12(c *check.C) {
func (s *Suite) Test_MkLines_Check__MASTER_SITE_in_HOMEPAGE(c *check.C) {
s.UseCommandLine(c, "-Wall")
s.RegisterMasterSite("MASTER_SITE_GITHUB", "https://github.com/")
G.globalData.InitVartypes()
@ -600,9 +649,10 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_12(c *check.C) {
"WARN: devel/catch/Makefile:5: HOMEPAGE should not be defined in terms of MASTER_SITEs.\n")
}
func (s *Suite) TestMkLine_variableNeedsQuoting_13(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__tool_in_quotes_in_subshell_in_shellwords(c *check.C) {
s.UseCommandLine(c, "-Wall")
s.RegisterTool(&Tool{Varname: "SH", Predefined: true})
s.RegisterTool(&Tool{Name: "echo", Varname: "ECHO", Predefined: true})
s.RegisterTool(&Tool{Name: "sh", Varname: "SH", Predefined: true})
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("x11/labltk/Makefile",
"# $"+"NetBSD$",
@ -613,7 +663,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_13(c *check.C) {
c.Check(s.Output(), equals, "") // Dont suggest ${ECHO:Q} here.
}
func (s *Suite) TestMkLine_variableNeedsQuoting_14(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting__LDADD_in_BUILDLINK_TRANSFORM(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("x11/qt5-qtbase/Makefile.common",
@ -625,7 +675,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_14(c *check.C) {
c.Check(s.Output(), equals, "WARN: x11/qt5-qtbase/Makefile.common:1: Please use ${BUILDLINK_LDADD.dl:Q} instead of ${BUILDLINK_LDADD.dl:M*}.\n")
}
func (s *Suite) TestMkLine_variableNeedsQuoting_15(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting_command_in_message(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("benchmarks/iozone/Makefile",
@ -636,7 +686,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_15(c *check.C) {
c.Check(s.Output(), equals, "") // Dont suggest ${REPLACE_PERL:Q}.
}
func (s *Suite) TestMkLine_variableNeedsQuoting_16(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting_guessed_list_variable_in_quotes(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("audio/jack-rack/Makefile",
@ -649,7 +699,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_16(c *check.C) {
c.Check(s.Output(), equals, "WARN: audio/jack-rack/Makefile:3: The list variable LADSPA_PLUGIN_PATH should not be embedded in a word.\n")
}
func (s *Suite) TestMkLine_variableNeedsQuoting_17(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting_list_in_list(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("x11/eterm/Makefile",
@ -661,7 +711,7 @@ func (s *Suite) TestMkLine_variableNeedsQuoting_17(c *check.C) {
c.Check(s.Output(), equals, "") // Dont warn about missing :Q operators.
}
func (s *Suite) TestMkLine_variableNeedsQuoting_18(c *check.C) {
func (s *Suite) Test_MkLine_variableNeedsQuoting_PKGNAME_and_URL_list_in_URL_list(c *check.C) {
s.UseCommandLine(c, "-Wall")
s.RegisterMasterSite("MASTER_SITE_GNOME", "http://ftp.gnome.org/")
G.globalData.InitVartypes()
@ -703,7 +753,7 @@ func (s *Suite) Test_MkLine_Varuse_Modifier_L(c *check.C) {
c.Check(s.Output(), equals, "") // Dont warn that ${XKBBASE}/xkbcomp is used but not defined.
}
func (s *Suite) Test_MkLine_Cond_ShellCommand(c *check.C) {
func (s *Suite) Test_MkLine_CheckCond_comparison_with_shell_command(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("security/openssl/Makefile",
@ -716,7 +766,7 @@ func (s *Suite) Test_MkLine_Cond_ShellCommand(c *check.C) {
c.Check(s.Output(), equals, "") // Dont warn about unknown shell command "cc".
}
func (s *Suite) disabledTest_MkLine_Pkgmandir(c *check.C) {
func (s *Suite) disabled_Test_MkLine_Pkgmandir(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("chat/ircII/Makefile",
@ -729,7 +779,7 @@ func (s *Suite) disabledTest_MkLine_Pkgmandir(c *check.C) {
c.Check(s.Output(), equals, "WARN: chat/ircII/Makefile:2: Please use ${PKGMANDIR} instead of \"man\".\n")
}
func (s *Suite) Test_MkLine_Check_Cflags_Backticks(c *check.C) {
func (s *Suite) Test_MkLine_Check_CFLAGS_with_backticks(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("chat/pidgin-icb/Makefile",
@ -747,7 +797,7 @@ func (s *Suite) Test_MkLine_Check_Cflags_Backticks(c *check.C) {
c.Check(s.Output(), equals, "") // No warning about "`pkg-config" being an unknown CFlag.
}
func (s *Suite) Test_MkLine_MasterSites_WordPart(c *check.C) {
func (s *Suite) Test_MkLine_Check_VERSION_as_wordpart_in_MASTER_SITES(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("geography/viking/Makefile",
@ -760,7 +810,7 @@ func (s *Suite) Test_MkLine_MasterSites_WordPart(c *check.C) {
"The list variable MASTER_SITE_SOURCEFORGE should not be embedded in a word.\n")
}
func (s *Suite) Test_MkLine_ShellCommand_WordPart(c *check.C) {
func (s *Suite) Test_MkLine_Check_shell_command_as_wordpart_in_ENV_list(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("x11/lablgtk1/Makefile",
@ -769,7 +819,9 @@ func (s *Suite) Test_MkLine_ShellCommand_WordPart(c *check.C) {
mklines.Check()
c.Check(s.Output(), equals, "WARN: x11/lablgtk1/Makefile:2: Please use ${CC:Q} instead of ${CC}.\n")
c.Check(s.Output(), equals, ""+
"WARN: x11/lablgtk1/Makefile:2: Please use ${CC:Q} instead of ${CC}.\n"+
"WARN: x11/lablgtk1/Makefile:2: Please use ${CC:Q} instead of ${CC}.\n")
}
func (s *Suite) Test_MkLine_shell_varuse_in_backt_dquot(c *check.C) {
@ -795,9 +847,9 @@ func (s *Suite) Test_MkLine_getVariableType(c *check.C) {
}
// See PR 46570, Ctrl+F "4. Shell quoting".
// Pkglint is correct, since this definition for CPPFLAGS should be
// seen by the shell as three words, not one word.
func (s *Suite) Test_MkLine_Cflags(c *check.C) {
// Pkglint is correct, since the shell sees this definition for
// CPPFLAGS as three words, not one word.
func (s *Suite) Test_MkLine_CheckVartype_CFLAGS(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("Makefile",
"# $"+"NetBSD$",

View file

@ -303,6 +303,11 @@ func (va *VaralignBlock) fixalign(mkline *MkLine, prefix, oldalign string) {
return
}
// Dont warn about procedure parameters
if mkline.Op() == opAssignEval && matches(mkline.Varname(), `^[a-z]`) {
return
}
goodWidth := va.maxTabWidth
if goodWidth == 0 && va.differ {
goodWidth = va.maxSpaceWidth

View file

@ -6,7 +6,7 @@ import (
const mkrcsid = "# $" + "NetBSD$"
func (s *Suite) TestMkLines_AutofixConditionalIndentation(c *check.C) {
func (s *Suite) Test_MkLines_Check__autofix_conditional_indentation(c *check.C) {
s.UseCommandLine(c, "--autofix", "-Wspace")
tmpfile := s.CreateTmpFile(c, "fname.mk", "")
mklines := s.NewMkLines(tmpfile,
@ -36,7 +36,7 @@ func (s *Suite) TestMkLines_AutofixConditionalIndentation(c *check.C) {
".endif\n")
}
func (s *Suite) TestMkLines_UnusualTarget(c *check.C) {
func (s *Suite) Test_MkLines_Check__unusual_target(c *check.C) {
mklines := s.NewMkLines("Makefile",
"# $"+"NetBSD$",
"",
@ -48,19 +48,17 @@ func (s *Suite) TestMkLines_UnusualTarget(c *check.C) {
c.Check(s.Output(), equals, "WARN: Makefile:3: Unusual target \"echo\".\n")
}
func (s *Suite) TestMkLines_checklineInclude_Makefile(c *check.C) {
mklines := s.NewMkLines("Makefile",
"# $"+"NetBSD$",
".include \"../../other/package/Makefile\"")
func (s *Suite) Test_MkLine_checklineInclude_Makefile(c *check.C) {
mkline := NewMkLine(NewLine("Makefile", 2, ".include \"../../other/package/Makefile\"", nil))
mklines.Check()
mkline.checkInclude()
c.Check(s.Output(), equals, ""+
"ERROR: Makefile:2: \"/other/package/Makefile\" does not exist.\n"+
"ERROR: Makefile:2: Other Makefiles must not be included directly.\n")
}
func (s *Suite) TestMkLines_Quoting(c *check.C) {
func (s *Suite) Test_MkLines_quoting_LDFLAGS_for_GNU_configure(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Pkg = NewPackage("category/pkgbase")
@ -71,10 +69,12 @@ func (s *Suite) TestMkLines_Quoting(c *check.C) {
mklines.Check()
c.Check(s.Output(), equals, "WARN: Makefile:3: Please use ${X11_LDFLAGS:M*:Q} instead of ${X11_LDFLAGS:Q}.\n")
c.Check(s.Output(), equals, ""+
"WARN: Makefile:3: Please use ${X11_LDFLAGS:M*:Q} instead of ${X11_LDFLAGS:Q}.\n"+
"WARN: Makefile:3: Please use ${X11_LDFLAGS:M*:Q} instead of ${X11_LDFLAGS:Q}.\n")
}
func (s *Suite) Test_MkLines_Varalign_Advanced(c *check.C) {
func (s *Suite) Test_MkLines__variable_alignment_advanced(c *check.C) {
s.UseCommandLine(c, "-Wspace")
fname := s.CreateTmpFileLines(c, "Makefile",
"# $"+"NetBSD$",
@ -148,7 +148,7 @@ func (s *Suite) Test_MkLines_Varalign_Advanced(c *check.C) {
"VAR=\t${GRP_A}${GRP_AA}${GRP_AAA}${GRP_AAAA}\n")
}
func (s *Suite) Test_MkLines_Varalign_Misc(c *check.C) {
func (s *Suite) Test_MkLines__variable_alignment_space_and_tab(c *check.C) {
s.UseCommandLine(c, "-Wspace")
mklines := s.NewMkLines("Makefile",
"# $"+"NetBSD$",
@ -161,7 +161,7 @@ func (s *Suite) Test_MkLines_Varalign_Misc(c *check.C) {
c.Check(s.Output(), equals, "NOTE: Makefile:3: Variable values should be aligned with tabs, not spaces.\n")
}
func (s *Suite) Test_MkLines_ForLoop_Multivar(c *check.C) {
func (s *Suite) Test_MkLines__for_loop_multiple_variables(c *check.C) {
s.UseCommandLine(c, "-Wall")
s.RegisterTool(&Tool{Name: "echo", Varname: "ECHO", Predefined: true})
s.RegisterTool(&Tool{Name: "find", Varname: "FIND", Predefined: true})
@ -182,7 +182,7 @@ func (s *Suite) Test_MkLines_ForLoop_Multivar(c *check.C) {
"WARN: audio/squeezeboxserver/Makefile:4: The exitcode of the left-hand-side command of the pipe operator is ignored.\n")
}
func (s *Suite) Test_MkLines_Cond_Compare_YesNo(c *check.C) {
func (s *Suite) Test_MkLines__comparing_YesNo_variable_to_string(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("databases/gdbm_compat/builtin.mk",
@ -196,7 +196,7 @@ func (s *Suite) Test_MkLines_Cond_Compare_YesNo(c *check.C) {
"USE_BUILTIN.gdbm should be matched against \"[yY][eE][sS]\" or \"[nN][oO]\", not compared with \"no\".\n")
}
func (s *Suite) Test_MkLines_Varuse_sh_Modifier(c *check.C) {
func (s *Suite) Test_MkLines__varuse_sh_modifier(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("lang/qore/module.mk",
@ -217,7 +217,7 @@ func (s *Suite) Test_MkLines_Varuse_sh_Modifier(c *check.C) {
c.Check(s.Output(), equals, "") // No warnings about defined but not used or vice versa
}
func (s *Suite) Test_MkLines_Varuse_parameterized(c *check.C) {
func (s *Suite) Test_MkLines__varuse_parameterized(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("converters/wv2/Makefile",
@ -230,7 +230,7 @@ func (s *Suite) Test_MkLines_Varuse_parameterized(c *check.C) {
c.Check(s.Output(), equals, "") // No warnings about defined but not used or vice versa
}
func (s *Suite) Test_MkLines_LoopModifier(c *check.C) {
func (s *Suite) Test_MkLines__loop_modifier(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("chat/xchat/Makefile",
@ -247,7 +247,8 @@ func (s *Suite) Test_MkLines_LoopModifier(c *check.C) {
"${INSTALL_DATA} ${WRKSRC}/src/common/dbus/${.s.} ${DESTDIR}${GCONF_SCHEMAS_DIR}/@}\".\n")
}
func (s *Suite) Test_MkLines_Indentation_DependsOn(c *check.C) {
// PR 46570
func (s *Suite) Test_MkLines__PKG_SKIP_REASON_depending_on_OPSYS(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("Makefile",
"# $"+"NetBSD$",
@ -262,7 +263,7 @@ func (s *Suite) Test_MkLines_Indentation_DependsOn(c *check.C) {
}
// PR 46570, item "15. net/uucp/Makefile has a make loop"
func (s *Suite) Test_MkLines_indirect_variables(c *check.C) {
func (s *Suite) Test_MkLines__indirect_variables(c *check.C) {
s.UseCommandLine(c, "-Wall")
mklines := s.NewMkLines("net/uucp/Makefile",
"# $"+"NetBSD$",
@ -279,7 +280,7 @@ func (s *Suite) Test_MkLines_indirect_variables(c *check.C) {
"WARN: net/uucp/Makefile:5: Unknown shell command \"${ECHO}\".\n")
}
func (s *Suite) Test_MkLines_Check_list_variable_as_part_of_word(c *check.C) {
func (s *Suite) Test_MkLines_Check__list_variable_as_part_of_word(c *check.C) {
s.UseCommandLine(c, "-Wall")
mklines := s.NewMkLines("converters/chef/Makefile",
mkrcsid,
@ -292,7 +293,7 @@ func (s *Suite) Test_MkLines_Check_list_variable_as_part_of_word(c *check.C) {
"WARN: converters/chef/Makefile:2: The list variable DISTFILES should not be embedded in a word.\n")
}
func (s *Suite) Test_MkLines_Check_absolute_pathname_depending_on_OPSYS(c *check.C) {
func (s *Suite) Test_MkLines_Check__absolute_pathname_depending_on_OPSYS(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("games/heretic2-demo/Makefile",
@ -311,3 +312,77 @@ func (s *Suite) Test_MkLines_Check_absolute_pathname_depending_on_OPSYS(c *check
"WARN: games/heretic2-demo/Makefile:5: The variable TOOLS_PLATFORM.gtar may not be set by any package.\n"+
"WARN: games/heretic2-demo/Makefile:5: Unknown shell command \"/usr/bin/bsdtar\".\n")
}
func (s *Suite) Test_MkLines_checkForUsedComment(c *check.C) {
s.UseCommandLine(c, "--show-autofix")
s.NewMkLines("Makefile.common",
"# $"+"NetBSD$",
"",
"# used by sysutils/mc",
).checkForUsedComment("sysutils/mc")
c.Check(s.Output(), equals, "")
s.NewMkLines("Makefile.common").checkForUsedComment("category/package")
c.Check(s.Output(), equals, "")
s.NewMkLines("Makefile.common",
"# $"+"NetBSD$",
).checkForUsedComment("category/package")
c.Check(s.Output(), equals, "")
s.NewMkLines("Makefile.common",
"# $"+"NetBSD$",
"",
).checkForUsedComment("category/package")
c.Check(s.Output(), equals, "")
s.NewMkLines("Makefile.common",
"# $"+"NetBSD$",
"",
"VARNAME=\tvalue",
).checkForUsedComment("category/package")
c.Check(s.Output(), equals, ""+
"WARN: Makefile.common:2: Please add a line \"# used by category/package\" here.\n"+
"AUTOFIX: Makefile.common:2: Inserting a line \"# used by category/package\" before this line.\n")
s.NewMkLines("Makefile.common",
"# $"+"NetBSD$",
"#",
"#",
).checkForUsedComment("category/package")
c.Check(s.Output(), equals, ""+
"WARN: Makefile.common:3: Please add a line \"# used by category/package\" here.\n"+
"AUTOFIX: Makefile.common:3: Inserting a line \"# used by category/package\" before this line.\n")
}
func (s *Suite) Test_MkLines_DetermineUsedVariables__simple(c *check.C) {
mklines := s.NewMkLines("fname",
"\t${VAR}")
mkline := mklines.mklines[0]
G.Mk = mklines
mklines.DetermineUsedVariables()
c.Check(len(mklines.varuse), equals, 1)
c.Check(mklines.varuse["VAR"], equals, mkline)
}
func (s *Suite) Test_MkLines_DetermineUsedVariables__nested(c *check.C) {
mklines := s.NewMkLines("fname",
"\t${outer.${inner}}")
mkline := mklines.mklines[0]
G.Mk = mklines
mklines.DetermineUsedVariables()
c.Check(len(mklines.varuse), equals, 3)
c.Check(mklines.varuse["inner"], equals, mkline)
c.Check(mklines.varuse["outer."], equals, mkline)
c.Check(mklines.varuse["outer.*"], equals, mkline)
}

View file

@ -67,7 +67,7 @@ func (p *MkParser) VarUse() *MkVarUse {
}
}
for p.VarUse() != nil || repl.AdvanceRegexp(`^([^$:`+closing+`]|\$\$)+`) {
for p.VarUse() != nil || repl.AdvanceRegexp(RegexPattern(`^([^$:`+closing+`]|\$\$)+`)) {
}
rest := p.Rest()
if hasPrefix(rest, ":L") || hasPrefix(rest, ":?") {
@ -126,7 +126,7 @@ func (p *MkParser) VarUseModifiers(varname, closing string) []string {
case '=', 'D', 'M', 'N', 'U':
if repl.AdvanceRegexp(`^[=DMNU]`) {
for p.VarUse() != nil || repl.AdvanceRegexp(`^([^$:`+closing+`]|\$\$)+`) {
for p.VarUse() != nil || repl.AdvanceRegexp(RegexPattern(`^([^$:`+closing+`]|\$\$)+`)) {
}
modifiers = append(modifiers, repl.Since(modifierMark))
continue
@ -136,7 +136,7 @@ func (p *MkParser) VarUseModifiers(varname, closing string) []string {
if repl.AdvanceRegexp(`^[CS]([%,/:;@^|])`) {
separator := repl.m[1]
repl.AdvanceStr("^")
re := `^([^\` + separator + `$` + closing + `\\]|\$\$|\\.)+`
re := RegexPattern(`^([^\` + separator + `$` + closing + `\\]|\$\$|\\.)+`)
for p.VarUse() != nil || repl.AdvanceRegexp(re) {
}
repl.AdvanceStr("$")
@ -155,7 +155,7 @@ func (p *MkParser) VarUseModifiers(varname, closing string) []string {
case '@':
if repl.AdvanceRegexp(`^@([\w.]+)@`) {
loopvar := repl.m[1]
for p.VarUse() != nil || repl.AdvanceRegexp(`^([^$:@`+closing+`\\]|\$\$|\\.)+`) {
for p.VarUse() != nil || repl.AdvanceRegexp(RegexPattern(`^([^$:@`+closing+`\\]|\$\$|\\.)+`)) {
}
if !repl.AdvanceStr("@") && p.EmitWarnings {
p.Line.Warn2("Modifier ${%s:@%s@...@} is missing the final \"@\".", varname, loopvar)
@ -172,7 +172,7 @@ func (p *MkParser) VarUseModifiers(varname, closing string) []string {
case '?':
repl.AdvanceStr("?")
re := `^([^$:` + closing + `]|\$\$)+`
re := RegexPattern(`^([^$:` + closing + `]|\$\$)+`)
for p.VarUse() != nil || repl.AdvanceRegexp(re) {
}
if repl.AdvanceStr(":") {
@ -184,7 +184,7 @@ func (p *MkParser) VarUseModifiers(varname, closing string) []string {
}
repl.Reset(modifierMark)
for p.VarUse() != nil || repl.AdvanceRegexp(`^([^:$`+closing+`]|\$\$)+`) {
for p.VarUse() != nil || repl.AdvanceRegexp(RegexPattern(`^([^:$`+closing+`]|\$\$)+`)) {
}
if suffixSubst := repl.Since(modifierMark); contains(suffixSubst, "=") {
modifiers = append(modifiers, suffixSubst)

View file

@ -144,7 +144,7 @@ func (c *StrCommand) HasOption(opt string) bool {
return false
}
func (c *StrCommand) AnyArgMatches(pattern string) bool {
func (c *StrCommand) AnyArgMatches(pattern RegexPattern) bool {
for _, arg := range c.Args {
if matches(arg, pattern) {
return true

View file

@ -9,7 +9,7 @@ func (w *MkShWalker) Walk(list *MkShList, callback func(node interface{})) {
}
}
func (w *MkShWalker) iterate(list *MkShList) chan interface{} {
func (w *MkShWalker) iterate(list *MkShList) <-chan interface{} {
elements := make(chan interface{})
go func() {
@ -20,7 +20,7 @@ func (w *MkShWalker) iterate(list *MkShList) chan interface{} {
return elements
}
func (w *MkShWalker) walkList(list *MkShList, collector chan interface{}) {
func (w *MkShWalker) walkList(list *MkShList, collector chan<- interface{}) {
collector <- list
for _, andor := range list.AndOrs {
@ -28,7 +28,7 @@ func (w *MkShWalker) walkList(list *MkShList, collector chan interface{}) {
}
}
func (w *MkShWalker) walkAndOr(andor *MkShAndOr, collector chan interface{}) {
func (w *MkShWalker) walkAndOr(andor *MkShAndOr, collector chan<- interface{}) {
collector <- andor
for _, pipeline := range andor.Pipes {
@ -36,7 +36,7 @@ func (w *MkShWalker) walkAndOr(andor *MkShAndOr, collector chan interface{}) {
}
}
func (w *MkShWalker) walkPipeline(pipeline *MkShPipeline, collector chan interface{}) {
func (w *MkShWalker) walkPipeline(pipeline *MkShPipeline, collector chan<- interface{}) {
collector <- pipeline
for _, command := range pipeline.Cmds {
@ -44,7 +44,7 @@ func (w *MkShWalker) walkPipeline(pipeline *MkShPipeline, collector chan interfa
}
}
func (w *MkShWalker) walkCommand(command *MkShCommand, collector chan interface{}) {
func (w *MkShWalker) walkCommand(command *MkShCommand, collector chan<- interface{}) {
collector <- command
switch {
@ -59,7 +59,7 @@ func (w *MkShWalker) walkCommand(command *MkShCommand, collector chan interface{
}
}
func (w *MkShWalker) walkSimpleCommand(command *MkShSimpleCommand, collector chan interface{}) {
func (w *MkShWalker) walkSimpleCommand(command *MkShSimpleCommand, collector chan<- interface{}) {
collector <- command
w.walkWords(command.Assignments, collector)
@ -70,7 +70,7 @@ func (w *MkShWalker) walkSimpleCommand(command *MkShSimpleCommand, collector cha
w.walkRedirects(command.Redirections, collector)
}
func (w *MkShWalker) walkCompoundCommand(command *MkShCompoundCommand, collector chan interface{}) {
func (w *MkShWalker) walkCompoundCommand(command *MkShCompoundCommand, collector chan<- interface{}) {
collector <- command
switch {
@ -89,7 +89,7 @@ func (w *MkShWalker) walkCompoundCommand(command *MkShCompoundCommand, collector
}
}
func (w *MkShWalker) walkCase(caseClause *MkShCaseClause, collector chan interface{}) {
func (w *MkShWalker) walkCase(caseClause *MkShCaseClause, collector chan<- interface{}) {
collector <- caseClause
w.walkWord(caseClause.Word, collector)
@ -100,13 +100,13 @@ func (w *MkShWalker) walkCase(caseClause *MkShCaseClause, collector chan interfa
}
}
func (w *MkShWalker) walkFunctionDefinition(funcdef *MkShFunctionDefinition, collector chan interface{}) {
func (w *MkShWalker) walkFunctionDefinition(funcdef *MkShFunctionDefinition, collector chan<- interface{}) {
collector <- funcdef
w.walkCompoundCommand(funcdef.Body, collector)
}
func (w *MkShWalker) walkIf(ifClause *MkShIfClause, collector chan interface{}) {
func (w *MkShWalker) walkIf(ifClause *MkShIfClause, collector chan<- interface{}) {
collector <- ifClause
for i, cond := range ifClause.Conds {
w.walkList(cond, collector)
@ -117,13 +117,13 @@ func (w *MkShWalker) walkIf(ifClause *MkShIfClause, collector chan interface{})
}
}
func (w *MkShWalker) walkLoop(loop *MkShLoopClause, collector chan interface{}) {
func (w *MkShWalker) walkLoop(loop *MkShLoopClause, collector chan<- interface{}) {
collector <- loop
w.walkList(loop.Cond, collector)
w.walkList(loop.Action, collector)
}
func (w *MkShWalker) walkWords(words []*ShToken, collector chan interface{}) {
func (w *MkShWalker) walkWords(words []*ShToken, collector chan<- interface{}) {
collector <- words
for _, word := range words {
@ -131,11 +131,11 @@ func (w *MkShWalker) walkWords(words []*ShToken, collector chan interface{}) {
}
}
func (w *MkShWalker) walkWord(word *ShToken, collector chan interface{}) {
func (w *MkShWalker) walkWord(word *ShToken, collector chan<- interface{}) {
collector <- word
}
func (w *MkShWalker) walkRedirects(redirects []*MkShRedirection, collector chan interface{}) {
func (w *MkShWalker) walkRedirects(redirects []*MkShRedirection, collector chan<- interface{}) {
collector <- redirects
for _, redirect := range redirects {
@ -144,7 +144,7 @@ func (w *MkShWalker) walkRedirects(redirects []*MkShRedirection, collector chan
}
}
func (w *MkShWalker) walkFor(forClause *MkShForClause, collector chan interface{}) {
func (w *MkShWalker) walkFor(forClause *MkShForClause, collector chan<- interface{}) {
collector <- forClause
collector <- forClause.Varname

View file

@ -493,7 +493,7 @@ func (pkg *Package) pkgnameFromDistname(pkgname, distname string) string {
defer tracecall(str, smod, ref(result))()
}
qsep := regexp.QuoteMeta(smod[1:2])
if m, left, from, right, to, flags := match5(smod, `^S`+qsep+`(\^?)([^:]*?)(\$?)`+qsep+`([^:]*)`+qsep+`([1g]*)$`); m {
if m, left, from, right, to, flags := match5(smod, RegexPattern(`^S`+qsep+`(\^?)([^:]*?)(\$?)`+qsep+`([^:]*)`+qsep+`([1g]*)$`)); m {
result := mkopSubst(str, left != "", from, right != "", to, flags)
if G.opts.Debug {
traceStep("subst %q %q => %q", str, smod, result)

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestPkgnameFromDistname(c *check.C) {
func (s *Suite) Test_Package_pkgnameFromDistname(c *check.C) {
pkg := NewPackage("dummy")
pkg.vardef["PKGNAME"] = NewMkLine(NewLine("Makefile", 5, "PKGNAME=dummy", nil))
@ -21,7 +21,7 @@ func (s *Suite) TestPkgnameFromDistname(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestChecklinesPackageMakefileVarorder(c *check.C) {
func (s *Suite) Test_Package_ChecklinesPackageMakefileVarorder(c *check.C) {
s.UseCommandLine(c, "-Worder")
pkg := NewPackage("x11/9term")
@ -46,7 +46,7 @@ func (s *Suite) TestChecklinesPackageMakefileVarorder(c *check.C) {
"WARN: Makefile:6: The canonical position for the required variable LICENSE is here.\n")
}
func (s *Suite) TestGetNbpart(c *check.C) {
func (s *Suite) Test_Package_getNbpart(c *check.C) {
pkg := NewPackage("category/pkgbase")
pkg.vardef["PKGREVISION"] = NewMkLine(NewLine("Makefile", 1, "PKGREVISION=14", nil))
@ -57,55 +57,7 @@ func (s *Suite) TestGetNbpart(c *check.C) {
c.Check(pkg.getNbpart(), equals, "")
}
func (s *Suite) TestMkLines_CheckForUsedComment(c *check.C) {
s.UseCommandLine(c, "--show-autofix")
s.NewMkLines("Makefile.common",
"# $"+"NetBSD$",
"",
"# used by sysutils/mc",
).checkForUsedComment("sysutils/mc")
c.Check(s.Output(), equals, "")
s.NewMkLines("Makefile.common").checkForUsedComment("category/package")
c.Check(s.Output(), equals, "")
s.NewMkLines("Makefile.common",
"# $"+"NetBSD$",
).checkForUsedComment("category/package")
c.Check(s.Output(), equals, "")
s.NewMkLines("Makefile.common",
"# $"+"NetBSD$",
"",
).checkForUsedComment("category/package")
c.Check(s.Output(), equals, "")
s.NewMkLines("Makefile.common",
"# $"+"NetBSD$",
"",
"VARNAME=\tvalue",
).checkForUsedComment("category/package")
c.Check(s.Output(), equals, ""+
"WARN: Makefile.common:2: Please add a line \"# used by category/package\" here.\n"+
"AUTOFIX: Makefile.common:2: Inserting a line \"# used by category/package\" before this line.\n")
s.NewMkLines("Makefile.common",
"# $"+"NetBSD$",
"#",
"#",
).checkForUsedComment("category/package")
c.Check(s.Output(), equals, ""+
"WARN: Makefile.common:3: Please add a line \"# used by category/package\" here.\n"+
"AUTOFIX: Makefile.common:3: Inserting a line \"# used by category/package\" before this line.\n")
}
func (s *Suite) TestPackage_DetermineEffectivePkgVars_Precedence(c *check.C) {
func (s *Suite) Test_Package_determineEffectivePkgVars__precedence(c *check.C) {
pkg := NewPackage("category/pkgbase")
pkgnameLine := NewMkLine(NewLine("Makefile", 3, "PKGNAME=pkgname-1.0", nil))
distnameLine := NewMkLine(NewLine("Makefile", 4, "DISTNAME=distname-1.0", nil))
@ -122,7 +74,7 @@ func (s *Suite) TestPackage_DetermineEffectivePkgVars_Precedence(c *check.C) {
c.Check(pkg.EffectivePkgversion, equals, "1.0")
}
func (s *Suite) TestPackage_CheckPossibleDowngrade(c *check.C) {
func (s *Suite) Test_Package_checkPossibleDowngrade(c *check.C) {
G.Pkg = NewPackage("category/pkgbase")
G.CurPkgsrcdir = "../.."
G.Pkg.EffectivePkgname = "package-1.0nb15"
@ -146,7 +98,7 @@ func (s *Suite) TestPackage_CheckPossibleDowngrade(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestCheckdirPackage(c *check.C) {
func (s *Suite) Test_checkdirPackage(c *check.C) {
s.CreateTmpFile(c, "Makefile", ""+
"# $"+"NetBSD$\n")
G.CurrentDir = s.tmpdir
@ -160,7 +112,7 @@ func (s *Suite) TestCheckdirPackage(c *check.C) {
"WARN: ~/Makefile: No COMMENT given.\n")
}
func (s *Suite) Test_Package_Meta_package_License(c *check.C) {
func (s *Suite) Test_checkdirPackage__meta_package_without_license(c *check.C) {
s.CreateTmpFileLines(c, "Makefile",
"# $"+"NetBSD$",
"",
@ -173,7 +125,7 @@ func (s *Suite) Test_Package_Meta_package_License(c *check.C) {
c.Check(s.Output(), equals, "WARN: ~/Makefile: No COMMENT given.\n") // No error about missing LICENSE.
}
func (s *Suite) Test_Package_Varuse_LoadTime(c *check.C) {
func (s *Suite) Test_Package__varuse_at_load_time(c *check.C) {
s.CreateTmpFileLines(c, "doc/CHANGES-2016",
"# dummy")
s.CreateTmpFileLines(c, "doc/TODO",
@ -234,3 +186,20 @@ func (s *Suite) Test_Package_Varuse_LoadTime(c *check.C) {
"WARN: ~/category/pkgbase/Makefile:10: To use the tool \"TRUE\" at load time, bsd.prefs.mk has to be included before.\n"+
"WARN: ~/category/pkgbase/Makefile:16: To use the tool \"NICE\" at load time, it has to be added to USE_TOOLS before including bsd.prefs.mk.\n")
}
func (s *Suite) Test_Package_loadPackageMakefile(c *check.C) {
makefile := s.CreateTmpFile(c, "category/package/Makefile", ""+
"# $"+"NetBSD$\n"+
"\n"+
"PKGNAME=pkgname-1.67\n"+
"DISTNAME=distfile_1_67\n"+
".include \"../../category/package/Makefile\"\n")
pkg := NewPackage("category/package")
G.CurrentDir = s.tmpdir + "/category/package"
G.CurPkgsrcdir = "../.."
G.Pkg = pkg
pkg.loadPackageMakefile(makefile)
c.Check(s.Output(), equals, "")
}

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestParser_PkgbasePattern(c *check.C) {
func (s *Suite) Test_Parser_PkgbasePattern(c *check.C) {
checkRest := func(pattern, expected, rest string) {
parser := NewParser(dummyLine, pattern, false)
actual := parser.PkgbasePattern()
@ -19,7 +19,7 @@ func (s *Suite) TestParser_PkgbasePattern(c *check.C) {
checkRest("${PYPKGPREFIX}-metakit-[0-9]*", "${PYPKGPREFIX}-metakit", "-[0-9]*")
}
func (s *Suite) TestParser_Dependency(c *check.C) {
func (s *Suite) Test_Parser_Dependency(c *check.C) {
checkRest := func(pattern string, expected DependencyPattern, rest string) {
parser := NewParser(dummyLine, pattern, false)
@ -50,26 +50,3 @@ func (s *Suite) TestParser_Dependency(c *check.C) {
checkRest("gnome-control-center>=2.20.1{,nb*}", DependencyPattern{"gnome-control-center", ">=", "2.20.1", "", "", ""}, "{,nb*}")
// "{ssh{,6}-[0-9]*,openssh-[0-9]*}" is not representable using the current data structure
}
// @Beta
func (s *Suite) Test_Parser_ShAst(c *check.C) {
f := func(args ...interface{}) interface{} { return nil }
Commands := f
Command := f
Arg := f
Varuse := f
Varassign := f
Subshell := f
Pipe := f
_ = "cd ${WRKSRC}/doc/man/man3; PAGES=\"`ls -1 | ${SED} -e 's,3qt$$,3,'`\";"
Commands(
Command("cd",
Arg(Varuse("WRKSRC"), "/doc/man/man3")),
Varassign("PAGES", Subshell(
Pipe(
Command("ls", "-1"),
Command(Varuse("SED"), "-e", "s,3qt$,3,")))))
}

View file

@ -76,7 +76,7 @@ func (ck *PatchChecker) Check() {
}
ck.exp.Advance()
ck.previousLineEmpty = line.Text == "" || hasPrefix(line.Text, "diff ") || hasPrefix(line.Text, "=============")
ck.previousLineEmpty = ck.isEmptyLine(line.Text)
if !ck.previousLineEmpty {
ck.seenDocumentation = true
}
@ -143,7 +143,7 @@ func (ck *PatchChecker) checkUnifiedDiff(patchedFile string) {
}
if !ck.exp.EOF() {
line := ck.exp.CurrentLine()
if line.Text != "" && !matches(line.Text, rePatchUniFileDel) && !hasPrefix(line.Text, "Index:") && !hasPrefix(line.Text, "diff ") {
if !ck.isEmptyLine(line.Text) && !matches(line.Text, rePatchUniFileDel) {
line.Warn0("Empty line or end of file expected.")
Explain3(
"This empty line makes the end of the patch clearly visible.",
@ -249,6 +249,14 @@ func (ck *PatchChecker) checktextRcsid(text string) {
}
}
func (ck *PatchChecker) isEmptyLine(text string) bool {
return text == "" ||
hasPrefix(text, "index ") ||
hasPrefix(text, "Index: ") ||
hasPrefix(text, "diff ") ||
hasPrefix(text, "=============")
}
type FileType uint8
const (

View file

@ -5,7 +5,7 @@ import (
"io/ioutil"
)
func (s *Suite) TestChecklinesPatch_WithComment(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__with_comment(c *check.C) {
s.UseCommandLine(c, "-Wall")
lines := s.NewLines("patch-WithComment",
"$"+"NetBSD$",
@ -26,7 +26,7 @@ func (s *Suite) TestChecklinesPatch_WithComment(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestChecklinesPatch_WithoutEmptyLine(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__without_empty_line(c *check.C) {
fname := s.CreateTmpFile(c, "patch-WithoutEmptyLines", "dummy")
s.UseCommandLine(c, "-Wall", "--autofix")
lines := s.NewLines(fname,
@ -63,7 +63,7 @@ func (s *Suite) TestChecklinesPatch_WithoutEmptyLine(c *check.C) {
" context after\n")
}
func (s *Suite) TestChecklinesPatch_WithoutComment(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__without_comment(c *check.C) {
s.UseCommandLine(c, "-Wall")
lines := s.NewLines("patch-WithoutComment",
"$"+"NetBSD$",
@ -81,7 +81,25 @@ func (s *Suite) TestChecklinesPatch_WithoutComment(c *check.C) {
c.Check(s.Output(), equals, "ERROR: patch-WithoutComment:3: Each patch must be documented.\n")
}
func (s *Suite) TestChecklineOtherAbsolutePathname(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__git_without_comment(c *check.C) {
s.UseCommandLine(c, "-Wall")
lines := s.NewLines("patch-aa",
"$"+"NetBSD$",
"",
"diff --git a/aa b/aa",
"index 1234567..1234567 100644",
"--- a/aa",
"+++ b/aa",
"@@ -1,1 +1,1 @@",
"-old",
"+new")
ChecklinesPatch(lines)
c.Check(s.Output(), equals, "ERROR: patch-aa:5: Each patch must be documented.\n")
}
func (s *Suite) Test_checklineOtherAbsolutePathname(c *check.C) {
line := NewLine("patch-ag", 1, "+$install -s -c ./bin/rosegarden ${DESTDIR}$BINDIR", nil)
checklineOtherAbsolutePathname(line, line.Text)
@ -89,7 +107,7 @@ func (s *Suite) TestChecklineOtherAbsolutePathname(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestChecklinesPatch_ErrorCode(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__error_code(c *check.C) {
s.UseCommandLine(c, "-Wall")
lines := s.NewLines("patch-ErrorCode",
"$"+"NetBSD$",
@ -109,7 +127,7 @@ func (s *Suite) TestChecklinesPatch_ErrorCode(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestChecklinesPatch_WrongOrder(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__wrong_header_order(c *check.C) {
s.UseCommandLine(c, "-Wall")
lines := s.NewLines("patch-WrongOrder",
"$"+"NetBSD$",
@ -130,7 +148,7 @@ func (s *Suite) TestChecklinesPatch_WrongOrder(c *check.C) {
c.Check(s.Output(), equals, "WARN: patch-WrongOrder:7: Unified diff headers should be first ---, then +++.\n")
}
func (s *Suite) TestChecklinesPatch_ContextDiff(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__context_diff(c *check.C) {
s.UseCommandLine(c, "-Wall")
lines := s.NewLines("patch-ctx",
"$"+"NetBSD$",
@ -146,7 +164,7 @@ func (s *Suite) TestChecklinesPatch_ContextDiff(c *check.C) {
"WARN: patch-ctx:4: Please use unified diffs (diff -u) for patches.\n")
}
func (s *Suite) TestChecklinesPatch_NoPatch(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__no_patch(c *check.C) {
lines := s.NewLines("patch-aa",
"$"+"NetBSD$",
"",
@ -158,7 +176,7 @@ func (s *Suite) TestChecklinesPatch_NoPatch(c *check.C) {
c.Check(s.Output(), equals, "ERROR: patch-aa: Contains no patch.\n")
}
func (s *Suite) TestChecklinesPatch_TwoPatches(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__two_patched_files(c *check.C) {
lines := s.NewLines("patch-aa",
"$"+"NetBSD$",
"",
@ -180,7 +198,7 @@ func (s *Suite) TestChecklinesPatch_TwoPatches(c *check.C) {
"WARN: patch-aa: Contains patches for 2 files, should be only one.\n")
}
func (s *Suite) TestChecklinesPatch_PatchlikeDocumentation(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__documentation_that_looks_like_patch_lines(c *check.C) {
lines := s.NewLines("patch-aa",
"$"+"NetBSD$",
"",
@ -195,7 +213,7 @@ func (s *Suite) TestChecklinesPatch_PatchlikeDocumentation(c *check.C) {
c.Check(s.Output(), equals, "ERROR: patch-aa: Contains no patch.\n")
}
func (s *Suite) TestChecklinesPatch_OnlyUnifiedHeader(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__only_unified_header_but_no_content(c *check.C) {
lines := s.NewLines("patch-unified",
"$"+"NetBSD$",
"",
@ -209,7 +227,7 @@ func (s *Suite) TestChecklinesPatch_OnlyUnifiedHeader(c *check.C) {
c.Check(s.Output(), equals, "ERROR: patch-unified:EOF: No patch hunks for \"file\".\n")
}
func (s *Suite) TestChecklinesPatch_OnlyContextHeader(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__only_context_header_but_no_content(c *check.C) {
lines := s.NewLines("patch-context",
"$"+"NetBSD$",
"",
@ -220,10 +238,12 @@ func (s *Suite) TestChecklinesPatch_OnlyContextHeader(c *check.C) {
ChecklinesPatch(lines)
// Context diffs are deprecated, therefore it is not worth
// adding extra code for checking them thoroughly.
c.Check(s.Output(), equals, "WARN: patch-context:5: Please use unified diffs (diff -u) for patches.\n")
}
func (s *Suite) TestChecklinesPatch_Makefile(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__Makefile_with_absolute_pathnames(c *check.C) {
lines := s.NewLines("patch-unified",
"$"+"NetBSD$",
"",
@ -258,7 +278,7 @@ func (s *Suite) TestChecklinesPatch_Makefile(c *check.C) {
"WARN: patch-unified:15: Found absolute pathname: /bin/cp\n")
}
func (s *Suite) TestChecklinesPatch_NoNewline_withFollowingText(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__no_newline_with_text_following(c *check.C) {
lines := s.NewLines("patch-aa",
"$"+"NetBSD$",
"",
@ -278,7 +298,7 @@ func (s *Suite) TestChecklinesPatch_NoNewline_withFollowingText(c *check.C) {
c.Check(s.Output(), equals, "WARN: patch-aa:12: Empty line or end of file expected.\n")
}
func (s *Suite) TestChecklinesPatch_NoNewline(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__no_newline(c *check.C) {
lines := s.NewLines("patch-aa",
"$"+"NetBSD$",
"",
@ -297,7 +317,7 @@ func (s *Suite) TestChecklinesPatch_NoNewline(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestChecklinesPatch_ShortAtEof(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__empty_lines_left_out_at_eof(c *check.C) {
lines := s.NewLines("patch-aa",
"$"+"NetBSD$",
"",
@ -320,7 +340,7 @@ func (s *Suite) TestChecklinesPatch_ShortAtEof(c *check.C) {
// In some context lines, the leading space character is missing.
// Since this is no problem for patch(1), pkglint also doesnt complain.
func (s *Suite) TestChecklinesPatch_AddTab(c *check.C) {
func (s *Suite) Test_ChecklinesPatch__context_lines_with_tab_instead_of_space(c *check.C) {
lines := s.NewLines("patch-aa",
"$"+"NetBSD$",
"",

View file

@ -306,7 +306,7 @@ func ChecklinesTrailingEmptyLines(lines []*Line) {
}
}
func MatchVarassign(text string) (m bool, varname, op, valueAlign, value, comment string) {
func MatchVarassign(text string) (m bool, varname, spaceAfterVarname, op, valueAlign, value, comment string) {
i, n := 0, len(text)
for i < n && text[i] == ' ' {
@ -379,6 +379,7 @@ func MatchVarassign(text string) (m bool, varname, op, valueAlign, value, commen
m = true
varname = text[varnameStart:varnameEnd]
spaceAfterVarname = text[varnameEnd:opStart]
op = text[opStart:opEnd]
valueAlign = text[0:valueStart]
value = strings.TrimSpace(string(valuebuf[:j]))

View file

@ -6,33 +6,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestDetermineUsedVariables_simple(c *check.C) {
mklines := s.NewMkLines("fname",
"\t${VAR}")
mkline := mklines.mklines[0]
G.Mk = mklines
mklines.DetermineUsedVariables()
c.Check(len(mklines.varuse), equals, 1)
c.Check(mklines.varuse["VAR"], equals, mkline)
}
func (s *Suite) TestDetermineUsedVariables_nested(c *check.C) {
mklines := s.NewMkLines("fname",
"\t${outer.${inner}}")
mkline := mklines.mklines[0]
G.Mk = mklines
mklines.DetermineUsedVariables()
c.Check(len(mklines.varuse), equals, 3)
c.Check(mklines.varuse["inner"], equals, mkline)
c.Check(mklines.varuse["outer."], equals, mkline)
c.Check(mklines.varuse["outer.*"], equals, mkline)
}
func (s *Suite) TestResolveVariableRefs_CircularReference(c *check.C) {
func (s *Suite) Test_resolveVariableRefs__circular_reference(c *check.C) {
mkline := NewMkLine(NewLine("fname", 1, "GCC_VERSION=${GCC_VERSION}", nil))
G.Pkg = NewPackage(".")
G.Pkg.vardef["GCC_VERSION"] = mkline
@ -42,7 +16,7 @@ func (s *Suite) TestResolveVariableRefs_CircularReference(c *check.C) {
c.Check(resolved, equals, "gcc-${GCC_VERSION}")
}
func (s *Suite) TestResolveVariableRefs_Multilevel(c *check.C) {
func (s *Suite) Test_resolveVariableRefs__multilevel(c *check.C) {
mkline1 := NewMkLine(NewLine("fname", 10, "_=${SECOND}", nil))
mkline2 := NewMkLine(NewLine("fname", 11, "_=${THIRD}", nil))
mkline3 := NewMkLine(NewLine("fname", 12, "_=got it", nil))
@ -56,7 +30,7 @@ func (s *Suite) TestResolveVariableRefs_Multilevel(c *check.C) {
c.Check(resolved, equals, "you got it")
}
func (s *Suite) TestResolveVariableRefs_SpecialChars(c *check.C) {
func (s *Suite) Test_resolveVariableRefs__special_chars(c *check.C) {
mkline := NewMkLine(NewLine("fname", 10, "_=x11", nil))
G.Pkg = NewPackage("category/pkg")
G.Pkg.vardef["GST_PLUGINS0.10_TYPE"] = mkline
@ -66,76 +40,41 @@ func (s *Suite) TestResolveVariableRefs_SpecialChars(c *check.C) {
c.Check(resolved, equals, "gst-plugins0.10-x11/distinfo")
}
func (s *Suite) TestChecklineRcsid(c *check.C) {
lines := s.NewLines("fname",
"$"+"NetBSD: dummy $",
"$"+"NetBSD$",
"$"+"Id: dummy $",
"$"+"Id$",
"$"+"FreeBSD$")
for _, line := range lines {
line.CheckRcsid(``, "")
}
c.Check(s.Output(), equals, ""+
"ERROR: fname:3: Expected \"$"+"NetBSD$\".\n"+
"ERROR: fname:4: Expected \"$"+"NetBSD$\".\n"+
"ERROR: fname:5: Expected \"$"+"NetBSD$\".\n")
}
func (s *Suite) TestMatchVarassign(c *check.C) {
checkVarassign := func(text string, ck check.Checker, varname, op, align, value, comment string) {
func (s *Suite) Test_MatchVarassign(c *check.C) {
checkVarassign := func(text string, ck check.Checker, varname, spaceAfterVarname, op, align, value, comment string) {
type va struct {
varname, op, align, value, comment string
varname, spaceAfterVarname, op, align, value, comment string
}
expected := va{varname, op, align, value, comment}
am, avarname, aop, aalign, avalue, acomment := MatchVarassign(text)
expected := va{varname, spaceAfterVarname, op, align, value, comment}
am, avarname, aspaceAfterVarname, aop, aalign, avalue, acomment := MatchVarassign(text)
if !am {
c.Errorf("Text %q doesnt match variable assignment", text)
return
}
actual := va{avarname, aop, aalign, avalue, acomment}
actual := va{avarname, aspaceAfterVarname, aop, aalign, avalue, acomment}
c.Check(actual, ck, expected)
}
checkNotVarassign := func(text string) {
m, _, _, _, _, _ := MatchVarassign(text)
m, _, _, _, _, _, _ := MatchVarassign(text)
if m {
c.Errorf("Text %q matches variable assignment, but shouldnt.", text)
}
}
checkVarassign("C++=c11", equals, "C+", "+=", "C++=", "c11", "")
checkVarassign("V=v", equals, "V", "=", "V=", "v", "")
checkVarassign("VAR=#comment", equals, "VAR", "=", "VAR=", "", "#comment")
checkVarassign("VAR=\\#comment", equals, "VAR", "=", "VAR=", "#comment", "")
checkVarassign("VAR=\\\\\\##comment", equals, "VAR", "=", "VAR=", "\\\\#", "#comment")
checkVarassign("VAR=\\", equals, "VAR", "=", "VAR=", "\\", "")
checkVarassign("VAR += value", equals, "VAR", "+=", "VAR += ", "value", "")
checkVarassign(" VAR=value", equals, "VAR", "=", " VAR=", "value", "")
checkVarassign("C++=c11", equals, "C+", "", "+=", "C++=", "c11", "")
checkVarassign("V=v", equals, "V", "", "=", "V=", "v", "")
checkVarassign("VAR=#comment", equals, "VAR", "", "=", "VAR=", "", "#comment")
checkVarassign("VAR=\\#comment", equals, "VAR", "", "=", "VAR=", "#comment", "")
checkVarassign("VAR=\\\\\\##comment", equals, "VAR", "", "=", "VAR=", "\\\\#", "#comment")
checkVarassign("VAR=\\", equals, "VAR", "", "=", "VAR=", "\\", "")
checkVarassign("VAR += value", equals, "VAR", " ", "+=", "VAR += ", "value", "")
checkVarassign(" VAR=value", equals, "VAR", "", "=", " VAR=", "value", "")
checkNotVarassign("\tVAR=value")
checkNotVarassign("?=value")
checkNotVarassign("<=value")
}
func (s *Suite) TestPackage_LoadPackageMakefile(c *check.C) {
makefile := s.CreateTmpFile(c, "category/package/Makefile", ""+
"# $"+"NetBSD$\n"+
"\n"+
"PKGNAME=pkgname-1.67\n"+
"DISTNAME=distfile_1_67\n"+
".include \"../../category/package/Makefile\"\n")
pkg := NewPackage("category/package")
G.CurrentDir = s.tmpdir + "/category/package"
G.CurPkgsrcdir = "../.."
G.Pkg = pkg
pkg.loadPackageMakefile(makefile)
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestChecklinesDescr(c *check.C) {
func (s *Suite) Test_ChecklinesDescr(c *check.C) {
lines := s.NewLines("DESCR",
strings.Repeat("X", 90),
"", "", "", "", "", "", "", "", "10",
@ -151,7 +90,7 @@ func (s *Suite) TestChecklinesDescr(c *check.C) {
"WARN: DESCR:25: File too long (should be no more than 24 lines).\n")
}
func (s *Suite) TestChecklinesMessage_short(c *check.C) {
func (s *Suite) Test_ChecklinesMessage__short(c *check.C) {
lines := s.NewLines("MESSAGE",
"one line")
@ -160,7 +99,7 @@ func (s *Suite) TestChecklinesMessage_short(c *check.C) {
c.Check(s.Output(), equals, "WARN: MESSAGE:1: File too short.\n")
}
func (s *Suite) TestChecklinesMessage_malformed(c *check.C) {
func (s *Suite) Test_ChecklinesMessage__malformed(c *check.C) {
lines := s.NewLines("MESSAGE",
"1",
"2",

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestChecklinesPlist(c *check.C) {
func (s *Suite) Test_ChecklinesPlist(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.Pkg = NewPackage("category/pkgbase")
lines := s.NewLines("PLIST",
@ -46,7 +46,7 @@ func (s *Suite) TestChecklinesPlist(c *check.C) {
"ERROR: PLIST:16: Duplicate filename \"share/tzinfo\", already appeared in line 15.\n")
}
func (s *Suite) TestChecklinesPlist_empty(c *check.C) {
func (s *Suite) Test_ChecklinesPlist__empty(c *check.C) {
lines := s.NewLines("PLIST",
"@comment $"+"NetBSD$")
@ -55,7 +55,7 @@ func (s *Suite) TestChecklinesPlist_empty(c *check.C) {
c.Check(s.Output(), equals, "WARN: PLIST:1: PLIST files shouldn't be empty.\n")
}
func (s *Suite) TestChecklinesPlist_commonEnd(c *check.C) {
func (s *Suite) Test_ChecklinesPlist__commonEnd(c *check.C) {
s.CreateTmpFile(c, "PLIST.common", ""+
"@comment $"+"NetBSD$\n"+
"bin/common\n")
@ -68,7 +68,7 @@ func (s *Suite) TestChecklinesPlist_commonEnd(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestChecklinesPlist_conditional(c *check.C) {
func (s *Suite) Test_ChecklinesPlist__conditional(c *check.C) {
G.Pkg = NewPackage("category/pkgbase")
G.Pkg.plistSubstCond["PLIST.bincmds"] = true
lines := s.NewLines("PLIST",
@ -80,7 +80,7 @@ func (s *Suite) TestChecklinesPlist_conditional(c *check.C) {
c.Check(s.Output(), equals, "WARN: PLIST:2: The bin/ directory should not have subdirectories.\n")
}
func (s *Suite) TestChecklinesPlist_sorting(c *check.C) {
func (s *Suite) Test_ChecklinesPlist__sorting(c *check.C) {
s.UseCommandLine(c, "-Wplist-sort")
lines := s.NewLines("PLIST",
"@comment $"+"NetBSD$",
@ -97,7 +97,7 @@ func (s *Suite) TestChecklinesPlist_sorting(c *check.C) {
"WARN: PLIST:6: \"bin/cat\" should be sorted before \"bin/otherprogram\".\n")
}
func (s *Suite) TestPlistChecker_sort(c *check.C) {
func (s *Suite) Test_PlistLineSorter_Sort(c *check.C) {
s.UseCommandLine(c, "--autofix")
tmpfile := s.CreateTmpFile(c, "PLIST", "dummy\n")
ck := &PlistChecker{nil, nil, ""}
@ -144,7 +144,7 @@ func (s *Suite) TestPlistChecker_sort(c *check.C) {
"sbin/program\n")
}
func (s *Suite) TestPlistChecker_checkpathShare_Desktop(c *check.C) {
func (s *Suite) Test_PlistChecker_checkpathShare_Desktop(c *check.C) {
// Disabled due to PR 46570, item "10. It should stop".
return
@ -158,7 +158,7 @@ func (s *Suite) TestPlistChecker_checkpathShare_Desktop(c *check.C) {
c.Check(s.Output(), equals, "WARN: PLIST:2: Packages that install a .desktop entry should .include \"../../sysutils/desktop-file-utils/desktopdb.mk\".\n")
}
func (s *Suite) TestPlistChecker_checkpathMan_gz(c *check.C) {
func (s *Suite) Test_PlistChecker_checkpathMan_gz(c *check.C) {
G.Pkg = NewPackage("category/pkgbase")
ChecklinesPlist(s.NewLines("PLIST",

View file

@ -25,7 +25,7 @@ func NewShellLine(mkline *MkLine) *ShellLine {
}
var shellcommandsContextType = &Vartype{lkNone, CheckvarShellCommands, []AclEntry{{"*", aclpAllRuntime}}, false}
var shellwordVuc = &VarUseContext{shellcommandsContextType, vucTimeUnknown, vucQuotPlain, vucExtentWord}
var shellwordVuc = &VarUseContext{shellcommandsContextType, vucTimeUnknown, vucQuotPlain, false}
func (shline *ShellLine) CheckWord(token string, checkQuoting bool) {
if G.opts.Debug {
@ -207,7 +207,7 @@ func (shline *ShellLine) checkVaruseToken(parser *MkParser, quoting ShQuoting) b
if varname != "@" {
vucstate := quoting.ToVarUseContext()
vuc := &VarUseContext{shellcommandsContextType, vucTimeUnknown, vucstate, vucExtentWordpart}
vuc := &VarUseContext{shellcommandsContextType, vucTimeUnknown, vucstate, true}
shline.mkline.CheckVaruse(varuse, vuc)
}
return true

View file

@ -6,7 +6,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) Test_SplitIntoShellTokens_LineContinuation(c *check.C) {
func (s *Suite) Test_splitIntoShellTokens__line_continuation(c *check.C) {
words, rest := splitIntoShellTokens(dummyLine, "if true; then \\")
c.Check(words, check.DeepEquals, []string{"if", "true", ";", "then"})
@ -15,28 +15,28 @@ func (s *Suite) Test_SplitIntoShellTokens_LineContinuation(c *check.C) {
c.Check(s.Output(), equals, "WARN: Pkglint parse error in ShTokenizer.ShAtom at \"\\\\\" (quoting=plain)\n")
}
func (s *Suite) Test_SplitIntoShellTokens_DollarSlash(c *check.C) {
func (s *Suite) Test_splitIntoShellTokens__dollar_slash(c *check.C) {
words, rest := splitIntoShellTokens(dummyLine, "pax -s /.*~$$//g")
c.Check(words, check.DeepEquals, []string{"pax", "-s", "/.*~$$//g"})
c.Check(rest, equals, "")
}
func (s *Suite) Test_SplitIntoShellTokens_DollarSubshell(c *check.C) {
func (s *Suite) Test_splitIntoShellTokens__dollar_subshell(c *check.C) {
words, rest := splitIntoShellTokens(dummyLine, "id=$$(${AWK} '{print}' < ${WRKSRC}/idfile) && echo \"$$id\"")
c.Check(words, deepEquals, []string{"id=", "$$(", "${AWK}", "'{print}'", "<", "${WRKSRC}/idfile", ")", "&&", "echo", "\"$$id\""})
c.Check(rest, equals, "")
}
func (s *Suite) Test_SplitIntoShellTokens_Semicolons(c *check.C) {
func (s *Suite) Test_splitIntoShellTokens__semicolons(c *check.C) {
words, rest := splitIntoShellTokens(dummyLine, "word1 word2;;;")
c.Check(words, deepEquals, []string{"word1", "word2", ";;", ";"})
c.Check(rest, equals, "")
}
func (s *Suite) Test_SplitIntoShellTokens_Whitespace(c *check.C) {
func (s *Suite) Test_splitIntoShellTokens__whitespace(c *check.C) {
text := "\t${RUN} cd ${WRKSRC}&&(${ECHO} ${PERL5:Q};${ECHO})|${BASH} ./install"
words, rest := splitIntoShellTokens(dummyLine, text)
@ -48,7 +48,7 @@ func (s *Suite) Test_SplitIntoShellTokens_Whitespace(c *check.C) {
c.Check(rest, equals, "")
}
func (s *Suite) Test_SplitIntoShellTokens_MkVarUse(c *check.C) {
func (s *Suite) Test_splitIntoShellTokens__varuse_with_embedded_space_and_other_vars(c *check.C) {
varuseWord := "${GCONF_SCHEMAS:@.s.@${INSTALL_DATA} ${WRKSRC}/src/common/dbus/${.s.} ${DESTDIR}${GCONF_SCHEMAS_DIR}/@}"
words, rest := splitIntoShellTokens(dummyLine, varuseWord)
@ -56,28 +56,28 @@ func (s *Suite) Test_SplitIntoShellTokens_MkVarUse(c *check.C) {
c.Check(rest, equals, "")
}
func (s *Suite) Test_SplitIntoMkWords_Semicolons(c *check.C) {
func (s *Suite) Test_splitIntoMkWords__semicolons(c *check.C) {
words, rest := splitIntoMkWords(dummyLine, "word1 word2;;;")
c.Check(words, deepEquals, []string{"word1", "word2;;;"})
c.Check(rest, equals, "")
}
func (s *Suite) Test_SplitIntoShellTokens_VaruseSpace(c *check.C) {
func (s *Suite) Test_splitIntoShellTokens__varuse_with_embedded_space(c *check.C) {
words, rest := splitIntoShellTokens(dummyLine, "${VAR:S/ /_/g}")
c.Check(words, deepEquals, []string{"${VAR:S/ /_/g}"})
c.Check(rest, equals, "")
}
func (s *Suite) Test_SplitIntoMkWords_VaruseSpace(c *check.C) {
func (s *Suite) Test_splitIntoMkWords__varuse_with_embedded_space(c *check.C) {
words, rest := splitIntoMkWords(dummyLine, "${VAR:S/ /_/g}")
c.Check(words, deepEquals, []string{"${VAR:S/ /_/g}"})
c.Check(rest, equals, "")
}
func (s *Suite) Test_splitIntoShellTokens_Redirect(c *check.C) {
func (s *Suite) Test_splitIntoShellTokens__redirect(c *check.C) {
words, rest := splitIntoShellTokens(dummyLine, "echo 1>output 2>>append 3>|clobber 4>&5 6<input >>append")
c.Check(words, deepEquals, []string{
@ -103,7 +103,7 @@ func (s *Suite) Test_splitIntoShellTokens_Redirect(c *check.C) {
c.Check(rest, equals, "")
}
func (s *Suite) TestChecklineMkShellCommandLine(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShellCommandLine(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.Mk = s.NewMkLines("fname",
"# dummy")
@ -229,7 +229,7 @@ func (s *Suite) TestChecklineMkShellCommandLine(c *check.C) {
c.Check(s.Output(), equals, "") // No warning about missing error checking.
}
func (s *Suite) TestShellLine_CheckShelltext_nofix(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShellCommandLine__nofix(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
s.RegisterTool(&Tool{Name: "echo", Predefined: true})
@ -246,7 +246,7 @@ func (s *Suite) TestShellLine_CheckShelltext_nofix(c *check.C) {
"NOTE: Makefile:1: The :Q operator isn't necessary for ${PKGNAME} here.\n")
}
func (s *Suite) TestShellLine_CheckShelltext_showAutofix(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShellCommandLine__show_autofix(c *check.C) {
s.UseCommandLine(c, "-Wall", "--show-autofix")
G.globalData.InitVartypes()
s.RegisterTool(&Tool{Name: "echo", Predefined: true})
@ -261,7 +261,7 @@ func (s *Suite) TestShellLine_CheckShelltext_showAutofix(c *check.C) {
"AUTOFIX: Makefile:1: Replacing \"${PKGNAME:Q}\" with \"${PKGNAME}\".\n")
}
func (s *Suite) TestShellLine_CheckShelltext_autofix(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShellCommandLine__autofix(c *check.C) {
s.UseCommandLine(c, "-Wall", "--autofix")
G.globalData.InitVartypes()
s.RegisterTool(&Tool{Name: "echo", Predefined: true})
@ -275,7 +275,7 @@ func (s *Suite) TestShellLine_CheckShelltext_autofix(c *check.C) {
"AUTOFIX: Makefile:1: Replacing \"${PKGNAME:Q}\" with \"${PKGNAME}\".\n")
}
func (s *Suite) TestShellLine_CheckShelltext_InternalError1(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShellCommandLine__implementation(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("fname",
@ -300,7 +300,7 @@ func (s *Suite) TestShellLine_CheckShelltext_InternalError1(c *check.C) {
"WARN: fname:1: Unknown shell command \"echo\".\n")
}
func (s *Suite) TestShellLine_CheckShelltext_DollarWithoutVariable(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShelltext__dollar_without_variable(c *check.C) {
G.globalData.InitVartypes()
G.Mk = s.NewMkLines("fname",
"# dummy")
@ -355,7 +355,7 @@ func (s *Suite) Test_ShellLine_CheckWord(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) Test_ShellLine_CheckWord_DollarWithoutVariable(c *check.C) {
func (s *Suite) Test_ShellLine_CheckWord__dollar_without_variable(c *check.C) {
shline := NewShellLine(NewMkLine(NewLine("fname", 1, "# dummy", nil)))
shline.CheckWord("/.*~$$//g", false) // Typical argument to pax(1).
@ -363,7 +363,7 @@ func (s *Suite) Test_ShellLine_CheckWord_DollarWithoutVariable(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestShelltextContext_CheckCommandStart(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShellCommandLine__echo(c *check.C) {
s.UseCommandLine(c, "-Wall")
s.RegisterTool(&Tool{Name: "echo", Varname: "ECHO", MustUseVarForm: true, Predefined: true})
G.Mk = s.NewMkLines("fname",
@ -380,7 +380,7 @@ func (s *Suite) TestShelltextContext_CheckCommandStart(c *check.C) {
"WARN: fname:3: Please use \"${ECHO}\" instead of \"echo\".\n")
}
func (s *Suite) TestShellLine_checklineMkShelltext(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShellCommandLine__shell_variables(c *check.C) {
text := "\tfor f in *.pl; do ${SED} s,@PREFIX@,${PREFIX}, < $f > $f.tmp && ${MV} $f.tmp $f; done"
shline := NewShellLine(NewMkLine(NewLine("Makefile", 3, text, nil)))
@ -402,7 +402,7 @@ func (s *Suite) TestShellLine_checklineMkShelltext(c *check.C) {
c.Check(s.Output(), equals, "WARN: Makefile:3: Please use the RCD_SCRIPTS mechanism to install rc.d scripts automatically to ${RCD_SCRIPTS_EXAMPLEDIR}.\n")
}
func (s *Suite) TestShellLine_checkCommandUse(c *check.C) {
func (s *Suite) Test_ShellLine_checkCommandUse(c *check.C) {
G.Mk = s.NewMkLines("fname",
"# dummy")
G.Mk.target = "do-install"
@ -418,7 +418,7 @@ func (s *Suite) TestShellLine_checkCommandUse(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:1: ${CP} should not be used to install files.\n")
}
func (s *Suite) TestSplitIntoMkWords(c *check.C) {
func (s *Suite) Test_splitIntoMkWords(c *check.C) {
url := "http://registry.gimp.org/file/fix-ca.c?action=download&id=9884&file="
words, rest := splitIntoShellTokens(dummyLine, url) // Doesnt really make sense
@ -437,7 +437,7 @@ func (s *Suite) TestSplitIntoMkWords(c *check.C) {
c.Check(rest, equals, "'rest")
}
func (s *Suite) TestShellLine_CheckShellCommandLine_SedMv(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShellCommandLine__sed_and_mv(c *check.C) {
shline := NewShellLine(NewMkLine(NewLine("Makefile", 85, "\t${RUN} ${SED} 's,#,// comment:,g' fname > fname.tmp; ${MV} fname.tmp fname", nil)))
shline.CheckShellCommandLine(shline.mkline.Shellcmd())
@ -445,7 +445,7 @@ func (s *Suite) TestShellLine_CheckShellCommandLine_SedMv(c *check.C) {
c.Check(s.Output(), equals, "NOTE: Makefile:85: Please use the SUBST framework instead of ${SED} and ${MV}.\n")
}
func (s *Suite) TestShellLine_CheckShellCommandLine_Subshell(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShellCommandLine__subshell(c *check.C) {
shline := NewShellLine(NewMkLine(NewLine("Makefile", 85, "\t${RUN} uname=$$(uname)", nil)))
shline.CheckShellCommandLine(shline.mkline.Shellcmd())
@ -453,7 +453,7 @@ func (s *Suite) TestShellLine_CheckShellCommandLine_Subshell(c *check.C) {
c.Check(s.Output(), equals, "WARN: Makefile:85: Invoking subshells via $(...) is not portable enough.\n")
}
func (s *Suite) TestShellLine_CheckShellCommandLine_InstallDirs(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShellCommandLine__install_dir(c *check.C) {
shline := NewShellLine(NewMkLine(NewLine("Makefile", 85, "\t${RUN} ${INSTALL_DATA_DIR} ${DESTDIR}${PREFIX}/dir1 ${DESTDIR}${PREFIX}/dir2", nil)))
shline.CheckShellCommandLine(shline.mkline.Shellcmd())
@ -477,7 +477,7 @@ func (s *Suite) TestShellLine_CheckShellCommandLine_InstallDirs(c *check.C) {
"WARN: Makefile:85: The INSTALL_*_DIR commands can only handle one directory at a time.\n")
}
func (s *Suite) TestShellLine_CheckShellCommandLine_InstallD(c *check.C) {
func (s *Suite) Test_ShellLine_CheckShellCommandLine__install_option_d(c *check.C) {
shline := NewShellLine(NewMkLine(NewLine("Makefile", 85, "\t${RUN} ${INSTALL} -d ${DESTDIR}${PREFIX}/dir1 ${DESTDIR}${PREFIX}/dir2", nil)))
shline.CheckShellCommandLine(shline.mkline.Shellcmd())
@ -487,7 +487,7 @@ func (s *Suite) TestShellLine_CheckShellCommandLine_InstallD(c *check.C) {
"NOTE: Makefile:85: You can use AUTO_MKDIRS=yes or \"INSTALLATION_DIRS+= dir2\" instead of \"${INSTALL} -d\".\n")
}
func (s *Suite) TestShellLine_(c *check.C) {
func (s *Suite) Test_ShellLine__shell_comment_with_line_continuation(c *check.C) {
tmpfile := s.CreateTmpFile(c, "Makefile", ""+
"# $"+"NetBSD$\n"+
"pre-install:\n"+
@ -518,7 +518,7 @@ func (s *Suite) Test_ShQuote(c *check.C) {
c.Check(traceQuoting("x`x\\\"x\\'x\\`x\\\\"), equals, "[plain]`[b]\\\"[b]\\'[b]\\`[b]\\\\[b]")
}
func (s *Suite) Test_unescapeBackticks(c *check.C) {
func (s *Suite) Test_ShellLine_unescapeBackticks(c *check.C) {
shline := NewShellLine(NewMkLine(dummyLine))
// foobar="`echo \"foo bar\"`"
text := "foobar=\"`echo \\\"foo bar\\\"`\""

View file

@ -58,37 +58,20 @@ func (p *ShTokenizer) ShAtom(quoting ShQuoting) *ShAtom {
}
func (p *ShTokenizer) shAtomPlain() *ShAtom {
q := shqPlain
const q = shqPlain
if op := p.shOperator(q); op != nil {
return op
}
repl := p.parser.repl
switch {
case repl.AdvanceHspace():
return &ShAtom{shtSpace, repl.s, q, nil}
case repl.AdvanceStr("\n"):
return &ShAtom{shtNewline, repl.s, q, nil}
case repl.AdvanceStr(";;"):
return &ShAtom{shtCaseSeparator, repl.s, q, nil}
case repl.AdvanceStr(";"):
return &ShAtom{shtSemicolon, repl.s, q, nil}
case repl.AdvanceStr("("):
return &ShAtom{shtParenOpen, repl.s, q, nil}
case repl.AdvanceStr(")"):
return &ShAtom{shtParenClose, repl.s, q, nil}
case repl.AdvanceStr("||"):
return &ShAtom{shtOr, repl.s, q, nil}
case repl.AdvanceStr("&&"):
return &ShAtom{shtAnd, repl.s, q, nil}
case repl.AdvanceStr("|"):
return &ShAtom{shtPipe, repl.s, q, nil}
case repl.AdvanceStr("&"):
return &ShAtom{shtBackground, repl.s, q, nil}
case repl.AdvanceStr("\""):
return &ShAtom{shtWord, repl.s, shqDquot, nil}
case repl.AdvanceStr("'"):
return &ShAtom{shtWord, repl.s, shqSquot, nil}
case repl.AdvanceStr("`"):
return &ShAtom{shtWord, repl.s, shqBackt, nil}
case repl.AdvanceRegexp(`^\d*(?:<<-|<<|<&|<>|>>|>&|>\||<|>)`):
return &ShAtom{shtRedirect, repl.m[0], q, nil}
case repl.AdvanceRegexp(`^#.*`):
return &ShAtom{shtComment, repl.m[0], q, nil}
case repl.AdvanceStr("$$("):
@ -125,6 +108,9 @@ func (p *ShTokenizer) shAtomSquot() *ShAtom {
func (p *ShTokenizer) shAtomBackt() *ShAtom {
const q = shqBackt
if op := p.shOperator(q); op != nil {
return op
}
repl := p.parser.repl
switch {
case repl.AdvanceStr("\""):
@ -135,24 +121,6 @@ func (p *ShTokenizer) shAtomBackt() *ShAtom {
return &ShAtom{shtWord, repl.s, shqBacktSquot, nil}
case repl.AdvanceHspace():
return &ShAtom{shtSpace, repl.s, q, nil}
case repl.AdvanceStr(";;"):
return &ShAtom{shtCaseSeparator, repl.s, q, nil}
case repl.AdvanceStr(";"):
return &ShAtom{shtSemicolon, repl.s, q, nil}
case repl.AdvanceStr("("):
return &ShAtom{shtParenOpen, repl.s, q, nil}
case repl.AdvanceStr(")"):
return &ShAtom{shtParenClose, repl.s, q, nil}
case repl.AdvanceStr("||"):
return &ShAtom{shtOr, repl.s, q, nil}
case repl.AdvanceStr("&&"):
return &ShAtom{shtAnd, repl.s, q, nil}
case repl.AdvanceStr("|"):
return &ShAtom{shtPipe, repl.s, q, nil}
case repl.AdvanceStr("&"):
return &ShAtom{shtBackground, repl.s, q, nil}
case repl.AdvanceRegexp(`^(?:<|<<|>|>>|>&)`):
return &ShAtom{shtRedirect, repl.s, q, nil}
case repl.AdvanceRegexp("^#[^`]*"):
return &ShAtom{shtComment, repl.s, q, nil}
case repl.AdvanceRegexp(`^(?:[!#%*+,\-./0-9:=?@A-Z\[\]_a-z~]+|\\[^$]|` + reShDollar + `)+`):
@ -163,6 +131,9 @@ func (p *ShTokenizer) shAtomBackt() *ShAtom {
func (p *ShTokenizer) shAtomSub() *ShAtom {
const q = shqSubsh
if op := p.shOperator(q); op != nil {
return op
}
repl := p.parser.repl
mark := repl.Mark()
atom := func(typ ShAtomType) *ShAtom {
@ -171,26 +142,12 @@ func (p *ShTokenizer) shAtomSub() *ShAtom {
switch {
case repl.AdvanceHspace():
return atom(shtSpace)
case repl.AdvanceStr(";;"):
return atom(shtCaseSeparator)
case repl.AdvanceStr(";"):
return atom(shtSemicolon)
case repl.AdvanceStr("||"):
return atom(shtOr)
case repl.AdvanceStr("&&"):
return atom(shtAnd)
case repl.AdvanceStr("|"):
return atom(shtPipe)
case repl.AdvanceStr("&"):
return atom(shtBackground)
case repl.AdvanceStr("\""):
//return &ShAtom{shtWord, repl.s, shqDquot, nil}
case repl.AdvanceStr("'"):
return &ShAtom{shtWord, repl.s, shqSubshSquot, nil}
case repl.AdvanceStr("`"):
//return &ShAtom{shtWord, repl.s, shqBackt, nil}
case repl.AdvanceRegexp(`^\d*(?:<<-|<<|<&|<>|>>|>&|>\||<|>)`):
return &ShAtom{shtRedirect, repl.m[0], q, nil}
case repl.AdvanceRegexp(`^#.*`):
return &ShAtom{shtComment, repl.m[0], q, nil}
case repl.AdvanceStr(")"):
@ -203,6 +160,9 @@ func (p *ShTokenizer) shAtomSub() *ShAtom {
func (p *ShTokenizer) shAtomDquotBackt() *ShAtom {
const q = shqDquotBackt
if op := p.shOperator(q); op != nil {
return op
}
repl := p.parser.repl
switch {
case repl.AdvanceStr("`"):
@ -213,24 +173,6 @@ func (p *ShTokenizer) shAtomDquotBackt() *ShAtom {
return &ShAtom{shtWord, repl.s, shqDquotBacktSquot, nil}
case repl.AdvanceRegexp("^#[^`]*"):
return &ShAtom{shtComment, repl.s, q, nil}
case repl.AdvanceStr(";;"):
return &ShAtom{shtCaseSeparator, repl.s, q, nil}
case repl.AdvanceStr(";"):
return &ShAtom{shtSemicolon, repl.s, q, nil}
case repl.AdvanceStr("("):
return &ShAtom{shtParenOpen, repl.s, q, nil}
case repl.AdvanceStr(")"):
return &ShAtom{shtParenClose, repl.s, q, nil}
case repl.AdvanceStr("||"):
return &ShAtom{shtOr, repl.s, q, nil}
case repl.AdvanceStr("&&"):
return &ShAtom{shtAnd, repl.s, q, nil}
case repl.AdvanceStr("|"):
return &ShAtom{shtPipe, repl.s, q, nil}
case repl.AdvanceStr("&"):
return &ShAtom{shtBackground, repl.s, q, nil}
case repl.AdvanceRegexp(`^(?:<|<<|>|>>|>&)`):
return &ShAtom{shtRedirect, repl.s, q, nil}
case repl.AdvanceRegexp(`^(?:[!#%*+,\-./0-9:=?@A-Z\[\]_a-z~]+|\\[^$]|` + reShDollar + `)+`):
return &ShAtom{shtWord, repl.s, q, nil}
case repl.AdvanceHspace():
@ -297,6 +239,25 @@ func (p *ShTokenizer) shAtomDquotBacktSquot() *ShAtom {
return nil
}
func (p *ShTokenizer) shOperator(q ShQuoting) *ShAtom {
repl := p.parser.repl
switch {
case repl.AdvanceStr("||"),
repl.AdvanceStr("&&"),
repl.AdvanceStr(";;"),
repl.AdvanceStr("\n"),
repl.AdvanceStr(";"),
repl.AdvanceStr("("),
repl.AdvanceStr(")"),
repl.AdvanceStr("|"),
repl.AdvanceStr("&"):
return &ShAtom{shtOperator, repl.s, q, nil}
case repl.AdvanceRegexp(`^\d*(?:<<-|<<|<&|<>|>>|>&|>\||<|>)`):
return &ShAtom{shtOperator, repl.m[0], q, nil}
}
return nil
}
func (p *ShTokenizer) ShAtoms() []*ShAtom {
var atoms []*ShAtom
q := shqPlain

View file

@ -4,7 +4,6 @@ import (
check "gopkg.in/check.v1"
)
// @Beta
func (s *Suite) Test_ShTokenizer_ShAtom(c *check.C) {
checkRest := func(s string, expected ...*ShAtom) string {
p := NewShTokenizer(dummyLine, s, false)
@ -28,6 +27,7 @@ func (s *Suite) Test_ShTokenizer_ShAtom(c *check.C) {
dquot := func(s string) *ShAtom { return token(shtWord, s, shqDquot) }
squot := func(s string) *ShAtom { return token(shtWord, s, shqSquot) }
backt := func(s string) *ShAtom { return token(shtWord, s, shqBackt) }
operator := func(s string) *ShAtom { return token(shtOperator, s, shqPlain) }
varuse := func(varname string, modifiers ...string) *ShAtom {
text := "${" + varname
for _, modifier := range modifiers {
@ -42,8 +42,8 @@ func (s *Suite) Test_ShTokenizer_ShAtom(c *check.C) {
}
whitespace := func(s string) *ShAtom { return token(shtSpace, s, shqPlain) }
space := token(shtSpace, " ", shqPlain)
semicolon := token(shtSemicolon, ";", shqPlain)
pipe := token(shtPipe, "|", shqPlain)
semicolon := operator(";")
pipe := operator("|")
check("" /* none */)
@ -55,7 +55,7 @@ func (s *Suite) Test_ShTokenizer_ShAtom(c *check.C) {
check("$$var;;",
word("$$var"),
token(shtCaseSeparator, ";;", shqPlain))
operator(";;"))
check("'single-quoted'",
q(shqSquot, word("'")),
@ -116,7 +116,7 @@ func (s *Suite) Test_ShTokenizer_ShAtom(c *check.C) {
q(shqDquotBackt, space),
q(shqDquotBackt, word("-1")),
q(shqDquotBackt, space),
token(shtPipe, "|", shqDquotBackt),
q(shqDquotBackt, operator("|")),
q(shqDquotBackt, space),
q(shqDquotBackt, varuse("SED")),
q(shqDquotBackt, space),
@ -136,7 +136,7 @@ func (s *Suite) Test_ShTokenizer_ShAtom(c *check.C) {
squot("'"), squot("s,3qt$$,3,"), word("'"))
check("(for PAGE in $$PAGES; do ",
&ShAtom{shtParenOpen, "(", shqPlain, nil},
&ShAtom{shtOperator, "(", shqPlain, nil},
word("for"),
space,
word("PAGE"),
@ -212,7 +212,7 @@ func (s *Suite) Test_ShTokenizer_ShAtom(c *check.C) {
check("cat<file",
word("cat"),
token(shtRedirect, "<", shqPlain),
operator("<"),
word("file"))
check("-e \"s,\\$$sysconfdir/jabberd,\\$$sysconfdir,g\"",
@ -243,15 +243,15 @@ func (s *Suite) Test_ShTokenizer_ShAtom(c *check.C) {
q(shqBackt, word("echo")),
q(shqBackt, semicolon),
q(shqBackt, word("echo")),
q(shqBackt, token(shtPipe, "|", shqBackt)),
q(shqBackt, operator("|")),
q(shqBackt, word("echo")),
q(shqBackt, token(shtBackground, "&", shqBackt)),
q(shqBackt, operator("&")),
q(shqBackt, word("echo")),
q(shqBackt, token(shtOr, "||", shqBackt)),
q(shqBackt, operator("||")),
q(shqBackt, word("echo")),
q(shqBackt, token(shtAnd, "&&", shqBackt)),
q(shqBackt, operator("&&")),
q(shqBackt, word("echo")),
q(shqBackt, token(shtRedirect, ">", shqBackt)),
q(shqBackt, operator(">")),
q(shqBackt, word("echo")),
q(shqPlain, word("`")))
@ -321,7 +321,7 @@ func (s *Suite) Test_ShTokenizer_ShAtom(c *check.C) {
}
}
func (s *Suite) Test_Shtokenizer_ShAtom_Quoting(c *check.C) {
func (s *Suite) Test_Shtokenizer_ShAtom__quoting(c *check.C) {
checkQuotingChange := func(input, expectedOutput string) {
p := NewShTokenizer(dummyLine, input, false)
q := shqPlain
@ -389,7 +389,7 @@ func (s *Suite) Test_ShTokenizer_ShToken(c *check.C) {
NewShAtom(shtSpace, " ", shqDquotBackt),
NewShAtom(shtWord, "-1", shqDquotBackt),
NewShAtom(shtSpace, " ", shqDquotBackt),
NewShAtom(shtPipe, "|", shqDquotBackt),
NewShAtom(shtOperator, "|", shqDquotBackt),
NewShAtom(shtSpace, " ", shqDquotBackt),
NewShAtomVaruse("${SED}", shqDquotBackt, "SED"),
NewShAtom(shtSpace, " ", shqDquotBackt),
@ -412,19 +412,19 @@ func (s *Suite) Test_ShTokenizer_ShToken(c *check.C) {
check("if cond1; then action1; elif cond2; then action2; else action3; fi",
NewShToken("if", NewShAtom(shtWord, "if", shqPlain)),
NewShToken("cond1", NewShAtom(shtWord, "cond1", shqPlain)),
NewShToken(";", NewShAtom(shtSemicolon, ";", shqPlain)),
NewShToken(";", NewShAtom(shtOperator, ";", shqPlain)),
NewShToken("then", NewShAtom(shtWord, "then", shqPlain)),
NewShToken("action1", NewShAtom(shtWord, "action1", shqPlain)),
NewShToken(";", NewShAtom(shtSemicolon, ";", shqPlain)),
NewShToken(";", NewShAtom(shtOperator, ";", shqPlain)),
NewShToken("elif", NewShAtom(shtWord, "elif", shqPlain)),
NewShToken("cond2", NewShAtom(shtWord, "cond2", shqPlain)),
NewShToken(";", NewShAtom(shtSemicolon, ";", shqPlain)),
NewShToken(";", NewShAtom(shtOperator, ";", shqPlain)),
NewShToken("then", NewShAtom(shtWord, "then", shqPlain)),
NewShToken("action2", NewShAtom(shtWord, "action2", shqPlain)),
NewShToken(";", NewShAtom(shtSemicolon, ";", shqPlain)),
NewShToken(";", NewShAtom(shtOperator, ";", shqPlain)),
NewShToken("else", NewShAtom(shtWord, "else", shqPlain)),
NewShToken("action3", NewShAtom(shtWord, "action3", shqPlain)),
NewShToken(";", NewShAtom(shtSemicolon, ";", shqPlain)),
NewShToken(";", NewShAtom(shtOperator, ";", shqPlain)),
NewShToken("fi", NewShAtom(shtWord, "fi", shqPlain)))
check("PATH=/nonexistent env PATH=${PATH:Q} true",
@ -452,7 +452,7 @@ func (s *Suite) Test_ShTokenizer_ShToken(c *check.C) {
NewShAtom(shtWord, "{print}", shqBacktSquot),
NewShAtom(shtWord, "'", shqBackt),
NewShAtom(shtSpace, " ", shqBackt),
NewShAtom(shtRedirect, "<", shqBackt),
NewShAtom(shtOperator, "<", shqBackt),
NewShAtom(shtSpace, " ", shqBackt),
NewShAtomVaruse("${WRKSRC}", shqBackt, "WRKSRC"),
NewShAtom(shtWord, "/idfile", shqBackt),

View file

@ -9,21 +9,12 @@ import (
type ShAtomType uint8
const (
shtSpace ShAtomType = iota
shtVaruse // ${PREFIX}
shtWord //
shtSemicolon // ;
shtCaseSeparator // ;;
shtParenOpen // (
shtParenClose // )
shtPipe // |
shtBackground // &
shtOr // ||
shtAnd // &&
shtRedirect // >, <, >>
shtComment // # ...
shtSubshell // $$(
shtNewline // \n
shtSpace ShAtomType = iota
shtVaruse // ${PREFIX}
shtWord //
shtOperator
shtComment // # ...
shtSubshell // $$(
)
func (t ShAtomType) String() string {
@ -31,28 +22,15 @@ func (t ShAtomType) String() string {
"space",
"varuse",
"word",
"semicolon",
"caseSeparator",
"parenOpen", "parenClose",
"pipe", "background",
"or", "and",
"redirect",
"operator",
"comment",
"newline",
"subshell",
}[t]
}
func (t ShAtomType) IsWord() bool {
switch t {
case shtVaruse, shtWord, shtRedirect:
return true
}
return false
}
func (t ShAtomType) IsCommandDelimiter() bool {
switch t {
case shtSemicolon, shtNewline, shtPipe, shtBackground, shtAnd, shtOr, shtCaseSeparator:
case shtVaruse, shtWord:
return true
}
return false

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestSubstContext_Incomplete(c *check.C) {
func (s *Suite) Test_SubstContext__incomplete(c *check.C) {
G.opts.WarnExtra = true
ctx := new(SubstContext)
@ -29,7 +29,7 @@ func (s *Suite) TestSubstContext_Incomplete(c *check.C) {
c.Check(s.Output(), equals, "WARN: Makefile:14: Incomplete SUBST block: SUBST_STAGE.interp missing.\n")
}
func (s *Suite) TestSubstContext_Complete(c *check.C) {
func (s *Suite) Test_SubstContext__complete(c *check.C) {
G.opts.WarnExtra = true
ctx := new(SubstContext)
@ -49,7 +49,7 @@ func (s *Suite) TestSubstContext_Complete(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) Test_SubstContext_OPSYSVARS(c *check.C) {
func (s *Suite) Test_SubstContext__OPSYSVARS(c *check.C) {
G.opts.WarnExtra = true
ctx := new(SubstContext)
@ -66,7 +66,7 @@ func (s *Suite) Test_SubstContext_OPSYSVARS(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestSubstContext_NoClass(c *check.C) {
func (s *Suite) Test_SubstContext__no_class(c *check.C) {
s.UseCommandLine(c, "-Wextra")
ctx := new(SubstContext)

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestCheckdirToplevel(c *check.C) {
func (s *Suite) Test_CheckdirToplevel(c *check.C) {
s.CreateTmpFile(c, "Makefile", ""+
"# $"+"NetBSD$\n"+
"\n"+

View file

@ -4,6 +4,6 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestTreeString(c *check.C) {
func (s *Suite) Test_Tree_String(c *check.C) {
c.Check(NewTree("not", NewTree("empty", "varname")).String(), equals, "(not (empty \"varname\"))")
}

View file

@ -28,7 +28,7 @@ func ifelseStr(cond bool, a, b string) string {
return b
}
func mustMatch(s, re string) []string {
func mustMatch(s string, re RegexPattern) []string {
if m := match(s, re); m != nil {
return m
}
@ -192,18 +192,20 @@ func dirExists(fname string) bool {
return err == nil && st.Mode().IsDir()
}
var res = make(map[string]*regexp.Regexp)
type RegexPattern string
func regcomp(re string) *regexp.Regexp {
var res = make(map[RegexPattern]*regexp.Regexp)
func regcomp(re RegexPattern) *regexp.Regexp {
cre := res[re]
if cre == nil {
cre = regexp.MustCompile(re)
cre = regexp.MustCompile(string(re))
res[re] = cre
}
return cre
}
func match(s, re string) []string {
func match(s string, re RegexPattern) []string {
if !G.opts.Profiling {
return regcomp(re).FindStringSubmatch(s)
}
@ -216,28 +218,28 @@ func match(s, re string) []string {
delay := immediatelyBefore.UnixNano() - before.UnixNano()
timeTaken := after.UnixNano() - immediatelyBefore.UnixNano() - delay
G.retime.Add(re, int(timeTaken))
G.retime.Add(string(re), int(timeTaken))
if m != nil {
G.rematch.Add(re, 1)
G.rematch.Add(string(re), 1)
} else {
G.renomatch.Add(re, 1)
G.renomatch.Add(string(re), 1)
}
return m
}
func matches(s, re string) bool {
func matches(s string, re RegexPattern) bool {
matches := regcomp(re).MatchString(s)
if G.opts.Profiling {
if matches {
G.rematch.Add(re, 1)
G.rematch.Add(string(re), 1)
} else {
G.renomatch.Add(re, 1)
G.renomatch.Add(string(re), 1)
}
}
return matches
}
func matchn(s, re string, n int) []string {
func matchn(s string, re RegexPattern, n int) []string {
if m := match(s, re); m != nil {
if len(m) != 1+n {
panic(fmt.Sprintf("expected match%d, got match%d for %q", len(m)-1, n, re))
@ -247,38 +249,38 @@ func matchn(s, re string, n int) []string {
return nil
}
func match1(s, re string) (matched bool, m1 string) {
func match1(s string, re RegexPattern) (matched bool, m1 string) {
if m := matchn(s, re, 1); m != nil {
return true, m[1]
}
return
}
func match2(s, re string) (matched bool, m1, m2 string) {
func match2(s string, re RegexPattern) (matched bool, m1, m2 string) {
if m := matchn(s, re, 2); m != nil {
return true, m[1], m[2]
}
return
}
func match3(s, re string) (matched bool, m1, m2, m3 string) {
func match3(s string, re RegexPattern) (matched bool, m1, m2, m3 string) {
if m := matchn(s, re, 3); m != nil {
return true, m[1], m[2], m[3]
}
return
}
func match4(s, re string) (matched bool, m1, m2, m3, m4 string) {
func match4(s string, re RegexPattern) (matched bool, m1, m2, m3, m4 string) {
if m := matchn(s, re, 4); m != nil {
return true, m[1], m[2], m[3], m[4]
}
return
}
func match5(s, re string) (matched bool, m1, m2, m3, m4, m5 string) {
func match5(s string, re RegexPattern) (matched bool, m1, m2, m3, m4, m5 string) {
if m := matchn(s, re, 5); m != nil {
return true, m[1], m[2], m[3], m[4], m[5]
}
return
}
func replaceFirst(s, re, replacement string) ([]string, string) {
func replaceFirst(s string, re RegexPattern, replacement string) ([]string, string) {
if G.opts.Debug {
defer tracecall(s, re, replacement)()
}
@ -347,10 +349,10 @@ func (pr *PrefixReplacer) AdvanceHspace() bool {
return false
}
func (pr *PrefixReplacer) AdvanceRegexp(re string) bool {
func (pr *PrefixReplacer) AdvanceRegexp(re RegexPattern) bool {
pr.m = nil
pr.s = ""
if !hasPrefix(re, "^") {
if !hasPrefix(string(re), "^") {
panic(fmt.Sprintf("PrefixReplacer.AdvanceRegexp: regular expression %q must have prefix %q.", re, "^"))
}
if G.Testing && matches("", re) {
@ -530,7 +532,7 @@ func mkopSubst(s string, left bool, from string, right bool, to string, flags st
if G.opts.Debug {
defer tracecall(s, left, from, right, to, flags)()
}
re := ifelseStr(left, "^", "") + regexp.QuoteMeta(from) + ifelseStr(right, "$", "")
re := RegexPattern(ifelseStr(left, "^", "") + regexp.QuoteMeta(from) + ifelseStr(right, "$", ""))
done := false
gflag := contains(flags, "g")
return regcomp(re).ReplaceAllStringFunc(s, func(match string) string {
@ -587,7 +589,7 @@ func containsVarRef(s string) bool {
return contains(s, "${")
}
func reReplaceRepeatedly(from string, re string, to string) string {
func reReplaceRepeatedly(from string, re RegexPattern, to string) string {
replaced := regcomp(re).ReplaceAllString(from, to)
if replaced != from {
return reReplaceRepeatedly(replaced, re, to)

View file

@ -4,34 +4,34 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestMkopSubst_middle(c *check.C) {
func (s *Suite) Test_MkopSubst__middle(c *check.C) {
c.Check(mkopSubst("pkgname", false, "kgna", false, "ri", ""), equals, "prime")
c.Check(mkopSubst("pkgname", false, "pkgname", false, "replacement", ""), equals, "replacement")
}
func (s *Suite) TestMkopSubst_left(c *check.C) {
func (s *Suite) Test_MkopSubst__left(c *check.C) {
c.Check(mkopSubst("pkgname", true, "kgna", false, "ri", ""), equals, "pkgname")
c.Check(mkopSubst("pkgname", true, "pkgname", false, "replacement", ""), equals, "replacement")
}
func (s *Suite) TestMkopSubst_right(c *check.C) {
func (s *Suite) Test_MkopSubst__right(c *check.C) {
c.Check(mkopSubst("pkgname", false, "kgna", true, "ri", ""), equals, "pkgname")
c.Check(mkopSubst("pkgname", false, "pkgname", true, "replacement", ""), equals, "replacement")
}
func (s *Suite) TestMkopSubst_leftRight(c *check.C) {
func (s *Suite) Test_MkopSubst__leftRight(c *check.C) {
c.Check(mkopSubst("pkgname", true, "kgna", true, "ri", ""), equals, "pkgname")
c.Check(mkopSubst("pkgname", false, "pkgname", false, "replacement", ""), equals, "replacement")
}
func (s *Suite) TestMkopSubst_gflag(c *check.C) {
func (s *Suite) Test_MkopSubst__gflag(c *check.C) {
c.Check(mkopSubst("aaaaa", false, "a", false, "b", "g"), equals, "bbbbb")
c.Check(mkopSubst("aaaaa", true, "a", false, "b", "g"), equals, "baaaa")
c.Check(mkopSubst("aaaaa", false, "a", true, "b", "g"), equals, "aaaab")
c.Check(mkopSubst("aaaaa", true, "a", true, "b", "g"), equals, "aaaaa")
}
func (s *Suite) TestReplaceFirst(c *check.C) {
func (s *Suite) Test_replaceFirst(c *check.C) {
m, rest := replaceFirst("a+b+c+d", `(\w)(.)(\w)`, "X")
c.Assert(m, check.NotNil)
@ -39,7 +39,7 @@ func (s *Suite) TestReplaceFirst(c *check.C) {
c.Check(rest, equals, "X+c+d")
}
func (s *Suite) TestTabLength(c *check.C) {
func (s *Suite) Test_tabLength(c *check.C) {
c.Check(tabLength("12345"), equals, 5)
c.Check(tabLength("\t"), equals, 8)
c.Check(tabLength("123\t"), equals, 8)
@ -47,7 +47,7 @@ func (s *Suite) TestTabLength(c *check.C) {
c.Check(tabLength("12345678\t"), equals, 16)
}
func (s *Suite) TestCleanpath(c *check.C) {
func (s *Suite) Test_cleanpath(c *check.C) {
c.Check(cleanpath("simple/path"), equals, "simple/path")
c.Check(cleanpath("/absolute/path"), equals, "/absolute/path")
c.Check(cleanpath("./././."), equals, ".")
@ -59,7 +59,7 @@ func (s *Suite) TestCleanpath(c *check.C) {
c.Check(cleanpath("dir/"), equals, "dir")
}
func (s *Suite) TestIsEmptyDirAndGetSubdirs(c *check.C) {
func (s *Suite) Test_isEmptyDir_and_getSubdirs(c *check.C) {
s.CreateTmpFile(c, "CVS/Entries", "dummy\n")
c.Check(isEmptyDir(s.tmpdir), equals, true)
@ -80,7 +80,7 @@ func (s *Suite) TestIsEmptyDirAndGetSubdirs(c *check.C) {
}
}
func (s *Suite) TestPrefixReplacer_Since(c *check.C) {
func (s *Suite) Test_PrefixReplacer_Since(c *check.C) {
repl := NewPrefixReplacer("hello, world")
mark := repl.Mark()
repl.AdvanceRegexp(`^\w+`)

View file

@ -151,7 +151,7 @@ func (gd *GlobalData) InitVartypes() {
acl("BUILDLINK_TRANSFORM", lkShell, CheckvarWrapperTransform, "*: append")
acl("BUILDLINK_TRANSFORM.*", lkShell, CheckvarWrapperTransform, "*: append")
acl("BUILDLINK_TREE", lkShell, CheckvarIdentifier, "buildlink3.mk: append")
acl("BUILD_DEFS", lkShell, CheckvarVarname, "Makefile, Makefile.common, options.mk: append")
acl("BUILD_DEFS", lkShell, CheckvarVariableName, "Makefile, Makefile.common, options.mk: append")
acl("BUILD_DEPENDS", lkSpace, CheckvarDependencyWithPath, "Makefile, Makefile.common, *.mk: append")
pkglist("BUILD_DIRS", lkShell, CheckvarWrksrcSubdirectory)
pkglist("BUILD_ENV", lkShell, CheckvarShellWord)
@ -162,10 +162,10 @@ func (gd *GlobalData) InitVartypes() {
pkg("BUILD_USES_MSGFMT", lkNone, CheckvarYes)
acl("BUILTIN_PKG", lkNone, CheckvarIdentifier, "builtin.mk: set, use-loadtime, use")
acl("BUILTIN_PKG.*", lkNone, CheckvarPkgName, "builtin.mk: set, use-loadtime, use")
acl("BUILTIN_FIND_FILES_VAR", lkShell, CheckvarVarname, "builtin.mk: set")
acl("BUILTIN_FIND_FILES_VAR", lkShell, CheckvarVariableName, "builtin.mk: set")
acl("BUILTIN_FIND_FILES.*", lkShell, CheckvarPathname, "builtin.mk: set")
acl("BUILTIN_FIND_GREP.*", lkNone, CheckvarString, "builtin.mk: set")
acl("BUILTIN_FIND_HEADERS_VAR", lkShell, CheckvarVarname, "builtin.mk: set")
acl("BUILTIN_FIND_HEADERS_VAR", lkShell, CheckvarVariableName, "builtin.mk: set")
acl("BUILTIN_FIND_HEADERS.*", lkShell, CheckvarPathname, "builtin.mk: set")
acl("BUILTIN_FIND_LIBS", lkShell, CheckvarPathname, "builtin.mk: set")
acl("BUILTIN_IMAKE_CHECK", lkShell, CheckvarUnchecked, "builtin.mk: set")
@ -232,7 +232,7 @@ func (gd *GlobalData) InitVartypes() {
usr("DEPENDS_TARGET", lkShell, CheckvarIdentifier)
acl("DESCR_SRC", lkShell, CheckvarPathname, "Makefile: set, append; Makefile.common: default, set")
sys("DESTDIR", lkNone, CheckvarPathname)
acl("DESTDIR_VARNAME", lkNone, CheckvarVarname, "Makefile, Makefile.common: set")
acl("DESTDIR_VARNAME", lkNone, CheckvarVariableName, "Makefile, Makefile.common: set")
sys("DEVOSSAUDIO", lkNone, CheckvarPathname)
sys("DEVOSSSOUND", lkNone, CheckvarPathname)
pkglist("DISTFILES", lkShell, CheckvarFilename)
@ -320,7 +320,7 @@ func (gd *GlobalData) InitVartypes() {
pkg("FILESDIR", lkNone, CheckvarRelativePkgPath)
pkglist("FILES_SUBST", lkShell, CheckvarShellWord)
acl("FILES_SUBST_SED", lkShell, CheckvarShellWord, "")
pkglist("FIX_RPATH", lkShell, CheckvarVarname)
pkglist("FIX_RPATH", lkShell, CheckvarVariableName)
pkglist("FLEX_REQD", lkShell, CheckvarVersion)
acl("FONTS_DIRS.*", lkShell, CheckvarPathname, "Makefile: set, append, use; Makefile.common: append, use")
sys("GAMEDATAMODE", lkNone, CheckvarFileMode)
@ -410,7 +410,7 @@ func (gd *GlobalData) InitVartypes() {
acl("MAINTAINER", lkNone, CheckvarMailAddress, "Makefile: set; Makefile.common: default")
sys("MAKE", lkNone, CheckvarShellCommand)
pkglist("MAKEFLAGS", lkShell, CheckvarShellWord)
acl("MAKEVARS", lkShell, CheckvarVarname, "buildlink3.mk, builtin.mk, hacks.mk: append")
acl("MAKEVARS", lkShell, CheckvarVariableName, "buildlink3.mk, builtin.mk, hacks.mk: append")
pkglist("MAKE_DIRS", lkShell, CheckvarPathname)
pkglist("MAKE_DIRS_PERMS", lkShell, CheckvarPerms)
acl("MAKE_ENV", lkShell, CheckvarShellWord, "Makefile, Makefile.common: append, set, use; buildlink3.mk, builtin.mk: append; *.mk: append, use")
@ -484,7 +484,7 @@ func (gd *GlobalData) InitVartypes() {
pkglist("ONLY_FOR_PLATFORM", lkSpace, CheckvarMachinePlatformPattern)
pkg("ONLY_FOR_UNPRIVILEGED", lkNone, CheckvarYesNo)
sys("OPSYS", lkNone, CheckvarIdentifier)
acl("OPSYSVARS", lkShell, CheckvarVarname, "Makefile, Makefile.common: append")
acl("OPSYSVARS", lkShell, CheckvarVariableName, "Makefile, Makefile.common: append")
acl("OSVERSION_SPECIFIC", lkNone, CheckvarYes, "Makefile, Makefile.common: set")
sys("OS_VERSION", lkNone, CheckvarVersion)
pkg("OVERRIDE_DIRDEPTH*", lkNone, CheckvarInteger)
@ -548,7 +548,7 @@ func (gd *GlobalData) InitVartypes() {
acl("PKG_GECOS.*", lkNone, CheckvarMessage, "Makefile: set")
acl("PKG_GID.*", lkNone, CheckvarInteger, "Makefile: set")
acl("PKG_GROUPS", lkShell, CheckvarShellWord, "Makefile: set, append")
pkglist("PKG_GROUPS_VARS", lkShell, CheckvarVarname)
pkglist("PKG_GROUPS_VARS", lkShell, CheckvarVariableName)
acl("PKG_HOME.*", lkNone, CheckvarPathname, "Makefile: set")
acl("PKG_HACKS", lkShell, CheckvarIdentifier, "hacks.mk: append")
sys("PKG_INFO", lkNone, CheckvarShellCommand)
@ -584,7 +584,7 @@ func (gd *GlobalData) InitVartypes() {
acl("PKG_SYSCONFVAR", lkNone, CheckvarIdentifier, "") // FIXME: name/type mismatch.
acl("PKG_UID", lkNone, CheckvarInteger, "Makefile: set")
acl("PKG_USERS", lkShell, CheckvarShellWord, "Makefile: set, append")
pkg("PKG_USERS_VARS", lkShell, CheckvarVarname)
pkg("PKG_USERS_VARS", lkShell, CheckvarVariableName)
acl("PKG_USE_KERBEROS", lkNone, CheckvarYes, "Makefile, Makefile.common: set")
// PLIST.* has special handling code
pkglist("PLIST_VARS", lkShell, CheckvarIdentifier)
@ -658,7 +658,7 @@ func (gd *GlobalData) InitVartypes() {
acl("SUBST_MESSAGE.*", lkNone, CheckvarMessage, "Makefile, Makefile.*, *.mk: set")
acl("SUBST_SED.*", lkNone, CheckvarSedCommands, "Makefile, Makefile.*, *.mk: set, append")
pkg("SUBST_STAGE.*", lkNone, CheckvarStage)
pkglist("SUBST_VARS.*", lkShell, CheckvarVarname)
pkglist("SUBST_VARS.*", lkShell, CheckvarVariableName)
pkglist("SUPERSEDES", lkSpace, CheckvarDependency)
pkglist("TEST_DIRS", lkShell, CheckvarWrksrcSubdirectory)
pkglist("TEST_ENV", lkShell, CheckvarShellWord)
@ -724,25 +724,25 @@ func enum(values string) *VarChecker {
}
name := "enum: " + values + " " // See IsEnum
return &VarChecker{name, func(cv *VartypeCheck) {
if cv.op == opUseMatch {
if !vmap[cv.value] && cv.value == cv.valueNovar {
if cv.Op == opUseMatch {
if !vmap[cv.Value] && cv.Value == cv.ValueNoVar {
canMatch := false
for value := range vmap {
if ok, err := path.Match(cv.value, value); err != nil {
cv.line.Warnf("Invalid match pattern %q.", cv.value)
if ok, err := path.Match(cv.Value, value); err != nil {
cv.Line.Warnf("Invalid match pattern %q.", cv.Value)
} else if ok {
canMatch = true
}
}
if !canMatch {
cv.line.Warnf("The pattern %q cannot match any of { %s } for %s.", cv.value, values, cv.varname)
cv.Line.Warnf("The pattern %q cannot match any of { %s } for %s.", cv.Value, values, cv.Varname)
}
}
return
}
if cv.value == cv.valueNovar && !vmap[cv.value] {
cv.line.Warnf("%q is not valid for %s. Use one of { %s } instead.", cv.value, cv.varname, values)
if cv.Value == cv.ValueNoVar && !vmap[cv.Value] {
cv.Line.Warnf("%q is not valid for %s. Use one of { %s } instead.", cv.Value, cv.Varname, values)
}
}}
}

View file

@ -257,7 +257,7 @@ var (
CheckvarUnchecked = &VarChecker{"Unchecked", (*VartypeCheck).Unchecked}
CheckvarURL = &VarChecker{"URL", (*VartypeCheck).URL}
CheckvarUserGroupName = &VarChecker{"UserGroupName", (*VartypeCheck).UserGroupName}
CheckvarVarname = &VarChecker{"Varname", (*VartypeCheck).Varname}
CheckvarVariableName = &VarChecker{"VariableName", (*VartypeCheck).VariableName}
CheckvarVersion = &VarChecker{"Version", (*VartypeCheck).Version}
CheckvarWrapperReorder = &VarChecker{"WrapperReorder", (*VartypeCheck).WrapperReorder}
CheckvarWrapperTransform = &VarChecker{"WrapperTransform", (*VartypeCheck).WrapperTransform}

View file

@ -4,20 +4,16 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestVartypeEffectivePermissions(c *check.C) {
func (s *Suite) Test_Vartype_EffectivePermissions(c *check.C) {
G.globalData.InitVartypes()
{
t := G.globalData.vartypes["PREFIX"]
if t := G.globalData.vartypes["PREFIX"]; c.Check(t, check.NotNil) {
c.Check(t.checker.name, equals, "Pathname")
c.Check(t.aclEntries, check.DeepEquals, []AclEntry{{glob: "*", permissions: aclpUse}})
c.Check(t.EffectivePermissions("Makefile"), equals, aclpUse)
}
{
t := G.globalData.vartypes["EXTRACT_OPTS"]
if t := G.globalData.vartypes["EXTRACT_OPTS"]; c.Check(t, check.NotNil) {
c.Check(t.checker.name, equals, "ShellWord")
c.Check(t.EffectivePermissions("Makefile"), equals, aclpAppend|aclpSet)
c.Check(t.EffectivePermissions("../Makefile"), equals, aclpAppend|aclpSet)
@ -25,7 +21,7 @@ func (s *Suite) TestVartypeEffectivePermissions(c *check.C) {
}
}
func (s *Suite) TestVarCheckerHasEnum(c *check.C) {
func (s *Suite) Test_VarChecker_HasEnum(c *check.C) {
vc := enum("catinstall middle maninstall")
c.Check(vc.HasEnum("catinstall"), equals, true)
@ -33,7 +29,7 @@ func (s *Suite) TestVarCheckerHasEnum(c *check.C) {
c.Check(vc.HasEnum("maninstall"), equals, true)
}
func (s *Suite) TestAclPermissions_contains(c *check.C) {
func (s *Suite) Test_AclPermissions_Contains(c *check.C) {
perms := aclpAllRuntime
c.Check(perms.Contains(aclpAllRuntime), equals, true)
@ -41,7 +37,7 @@ func (s *Suite) TestAclPermissions_contains(c *check.C) {
c.Check(perms.Contains(aclpUseLoadtime), equals, false)
}
func (s *Suite) TestAclPermissions_String(c *check.C) {
func (s *Suite) Test_AclPermissions_String(c *check.C) {
c.Check(AclPermissions(0).String(), equals, "none")
c.Check(aclpAll.String(), equals, "set, set-default, append, use-loadtime, use")
c.Check(aclpUnknown.String(), equals, "unknown")

View file

@ -7,15 +7,14 @@ import (
)
type VartypeCheck struct {
mkline *MkLine
line *Line
varname string
op MkOperator
value string
valueNovar string
comment string
listContext bool
guessed bool // Whether the type definition is guessed (based on the variable name) or explicitly defined (see vardefs.go).
MkLine *MkLine
Line *Line
Varname string
Op MkOperator
Value string
ValueNoVar string
MkComment string
Guessed bool // Whether the type definition is guessed (based on the variable name) or explicitly defined (see vardefs.go).
}
type MkOperator uint8
@ -109,27 +108,27 @@ var (
func (cv *VartypeCheck) AwkCommand() {
if G.opts.Debug {
traceStep1("Unchecked AWK command: %q", cv.value)
traceStep1("Unchecked AWK command: %q", cv.Value)
}
}
func (cv *VartypeCheck) BasicRegularExpression() {
if G.opts.Debug {
traceStep1("Unchecked basic regular expression: %q", cv.value)
traceStep1("Unchecked basic regular expression: %q", cv.Value)
}
}
func (cv *VartypeCheck) BuildlinkDepmethod() {
if !containsVarRef(cv.value) && cv.value != "build" && cv.value != "full" {
cv.line.Warn1("Invalid dependency method %q. Valid methods are \"build\" or \"full\".", cv.value)
if !containsVarRef(cv.Value) && cv.Value != "build" && cv.Value != "full" {
cv.Line.Warn1("Invalid dependency method %q. Valid methods are \"build\" or \"full\".", cv.Value)
}
}
func (cv *VartypeCheck) Category() {
if cv.value != "wip" && fileExists(G.CurrentDir+"/"+G.CurPkgsrcdir+"/"+cv.value+"/Makefile") {
if cv.Value != "wip" && fileExists(G.CurrentDir+"/"+G.CurPkgsrcdir+"/"+cv.Value+"/Makefile") {
return
}
switch cv.value {
switch cv.Value {
case
"chinese", "crosspkgtools",
"gnome", "gnustep",
@ -143,16 +142,16 @@ func (cv *VartypeCheck) Category() {
"windowmaker",
"xmms":
default:
cv.line.Error1("Invalid category %q.", cv.value)
cv.Line.Error1("Invalid category %q.", cv.Value)
}
}
// A single option to the C/C++ compiler.
func (cv *VartypeCheck) CFlag() {
if cv.op == opUseMatch {
if cv.Op == opUseMatch {
return
}
cflag := cv.value
cflag := cv.Value
switch {
case matches(cflag, `^-[DILOUWfgm]`),
hasPrefix(cflag, "-std="),
@ -164,15 +163,15 @@ func (cv *VartypeCheck) CFlag() {
containsVarRef(cflag):
return
case hasPrefix(cflag, "-"):
cv.line.Warn1("Unknown compiler flag %q.", cflag)
cv.Line.Warn1("Unknown compiler flag %q.", cflag)
default:
cv.line.Warn1("Compiler flag %q should start with a hyphen.", cflag)
cv.Line.Warn1("Compiler flag %q should start with a hyphen.", cflag)
}
}
// The single-line description of the package.
func (cv *VartypeCheck) Comment() {
line, value := cv.line, cv.value
line, value := cv.Line, cv.Value
if value == "TODO: Short description of the package" { // See pkgtools/url2pkg/files/url2pkg.pl, keyword "COMMENT".
line.Error0("COMMENT must be set.")
@ -192,7 +191,7 @@ func (cv *VartypeCheck) Comment() {
}
func (cv *VartypeCheck) Dependency() {
line, value := cv.line, cv.value
line, value := cv.Line, cv.Value
parser := NewParser(line, value, false)
deppat := parser.Dependency()
@ -258,13 +257,13 @@ func (cv *VartypeCheck) Dependency() {
}
func (cv *VartypeCheck) DependencyWithPath() {
line, value := cv.line, cv.value
if value != cv.valueNovar {
line, value := cv.Line, cv.Value
if value != cv.ValueNoVar {
return // It's probably not worth checking this.
}
if m, pattern, relpath, pkg := match3(value, `(.*):(\.\./\.\./[^/]+/([^/]+))$`); m {
cv.mkline.CheckRelativePkgdir(relpath)
cv.MkLine.CheckRelativePkgdir(relpath)
switch pkg {
case "msgfmt", "gettext":
@ -275,13 +274,13 @@ func (cv *VartypeCheck) DependencyWithPath() {
line.Warn0("Please use USE_TOOLS+=gmake instead of this dependency.")
}
cv.mkline.CheckVartypePrimitive(cv.varname, CheckvarDependency, cv.op, pattern, cv.comment, cv.listContext, cv.guessed)
cv.MkLine.CheckVartypePrimitive(cv.Varname, CheckvarDependency, cv.Op, pattern, cv.MkComment, cv.Guessed)
return
}
if matches(value, `:\.\./[^/]+$`) {
line.Warn0("Dependencies should have the form \"../../category/package\".")
cv.mkline.explainRelativeDirs()
cv.MkLine.explainRelativeDirs()
return
}
@ -294,42 +293,40 @@ func (cv *VartypeCheck) DependencyWithPath() {
}
func (cv *VartypeCheck) DistSuffix() {
if cv.value == ".tar.gz" {
cv.line.Note1("%s is \".tar.gz\" by default, so this definition may be redundant.", cv.varname)
if cv.Value == ".tar.gz" {
cv.Line.Note1("%s is \".tar.gz\" by default, so this definition may be redundant.", cv.Varname)
}
}
func (cv *VartypeCheck) EmulPlatform() {
const rePart = `(?:\[[^\]]+\]|[^-\[])+`
const rePair = `^(` + rePart + `)-(` + rePart + `)$`
if m, opsysPattern, archPattern := match2(cv.value, rePair); m {
if m, opsysPattern, archPattern := match2(cv.Value, rePair); m {
opsysCv := &VartypeCheck{
cv.mkline,
cv.line,
"the operating system part of " + cv.varname,
cv.op,
cv.MkLine,
cv.Line,
"the operating system part of " + cv.Varname,
cv.Op,
opsysPattern,
opsysPattern,
cv.comment,
cv.listContext,
cv.guessed}
cv.MkComment,
cv.Guessed}
enumEmulOpsys.checker(opsysCv)
// no check for os_version
archCv := &VartypeCheck{
cv.mkline,
cv.line,
"the hardware architecture part of " + cv.varname,
cv.op,
cv.MkLine,
cv.Line,
"the hardware architecture part of " + cv.Varname,
cv.Op,
archPattern,
archPattern,
cv.comment,
cv.listContext,
cv.guessed}
cv.MkComment,
cv.Guessed}
enumEmulArch.checker(archCv)
} else {
cv.line.Warn1("%q is not a valid emulation platform.", cv.value)
cv.Line.Warn1("%q is not a valid emulation platform.", cv.Value)
Explain(
"An emulation platform has the form <OPSYS>-<MACHINE_ARCH>.",
"OPSYS is the lower-case name of the operating system, and",
@ -342,28 +339,28 @@ func (cv *VartypeCheck) EmulPlatform() {
}
func (cv *VartypeCheck) FetchURL() {
cv.mkline.CheckVartypePrimitive(cv.varname, CheckvarURL, cv.op, cv.value, cv.comment, cv.listContext, cv.guessed)
cv.MkLine.CheckVartypePrimitive(cv.Varname, CheckvarURL, cv.Op, cv.Value, cv.MkComment, cv.Guessed)
for siteURL, siteName := range G.globalData.MasterSiteURLToVar {
if hasPrefix(cv.value, siteURL) {
subdir := cv.value[len(siteURL):]
if hasPrefix(cv.value, "https://github.com/") {
if hasPrefix(cv.Value, siteURL) {
subdir := cv.Value[len(siteURL):]
if hasPrefix(cv.Value, "https://github.com/") {
subdir = strings.SplitAfter(subdir, "/")[0]
cv.line.Warnf("Please use ${%s:=%s} instead of %q and run \"%s help topic=github\" for further tips.",
siteName, subdir, cv.value, confMake)
cv.Line.Warnf("Please use ${%s:=%s} instead of %q and run \"%s help topic=github\" for further tips.",
siteName, subdir, cv.Value, confMake)
} else {
cv.line.Warnf("Please use ${%s:=%s} instead of %q.", siteName, subdir, cv.value)
cv.Line.Warnf("Please use ${%s:=%s} instead of %q.", siteName, subdir, cv.Value)
}
return
}
}
if m, name, subdir := match2(cv.value, `\$\{(MASTER_SITE_[^:]*).*:=(.*)\}$`); m {
if m, name, subdir := match2(cv.Value, `\$\{(MASTER_SITE_[^:]*).*:=(.*)\}$`); m {
if G.globalData.MasterSiteVarToURL[name] == "" {
cv.line.Error1("The site %s does not exist.", name)
cv.Line.Error1("The site %s does not exist.", name)
}
if !hasSuffix(subdir, "/") {
cv.line.Error1("The subdirectory in %s must end with a slash.", name)
cv.Line.Error1("The subdirectory in %s must end with a slash.", name)
}
}
}
@ -372,39 +369,39 @@ func (cv *VartypeCheck) FetchURL() {
// See http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_169
func (cv *VartypeCheck) Filename() {
switch {
case cv.op == opUseMatch:
case cv.Op == opUseMatch:
break
case contains(cv.valueNovar, "/"):
cv.line.Warn0("A filename should not contain a slash.")
case !matches(cv.valueNovar, `^[-0-9@A-Za-z.,_~+%]*$`):
cv.line.Warn1("%q is not a valid filename.", cv.value)
case contains(cv.ValueNoVar, "/"):
cv.Line.Warn0("A filename should not contain a slash.")
case !matches(cv.ValueNoVar, `^[-0-9@A-Za-z.,_~+%]*$`):
cv.Line.Warn1("%q is not a valid filename.", cv.Value)
}
}
func (cv *VartypeCheck) Filemask() {
if cv.op == opUseMatch {
if cv.Op == opUseMatch {
return
}
if !matches(cv.valueNovar, `^[-0-9A-Za-z._~+%*?]*$`) {
cv.line.Warn1("%q is not a valid filename mask.", cv.value)
if !matches(cv.ValueNoVar, `^[-0-9A-Za-z._~+%*?]*$`) {
cv.Line.Warn1("%q is not a valid filename mask.", cv.Value)
}
}
func (cv *VartypeCheck) FileMode() {
switch {
case cv.value != "" && cv.valueNovar == "":
case cv.Value != "" && cv.ValueNoVar == "":
// Fine.
case matches(cv.value, `^[0-7]{3,4}`):
case matches(cv.Value, `^[0-7]{3,4}`):
// Fine.
default:
cv.line.Warn1("Invalid file mode %q.", cv.value)
cv.Line.Warn1("Invalid file mode %q.", cv.Value)
}
}
func (cv *VartypeCheck) Homepage() {
cv.mkline.CheckVartypePrimitive(cv.varname, CheckvarURL, cv.op, cv.value, cv.comment, cv.listContext, cv.guessed)
cv.MkLine.CheckVartypePrimitive(cv.Varname, CheckvarURL, cv.Op, cv.Value, cv.MkComment, cv.Guessed)
if m, wrong, sitename, subdir := match3(cv.value, `^(\$\{(MASTER_SITE\w+)(?::=([\w\-/]+))?\})`); m {
if m, wrong, sitename, subdir := match3(cv.Value, `^(\$\{(MASTER_SITE\w+)(?::=([\w\-/]+))?\})`); m {
baseURL := G.globalData.MasterSiteVarToURL[sitename]
if sitename == "MASTER_SITES" && G.Pkg != nil {
masterSites, _ := G.Pkg.varValue("MASTER_SITES")
@ -415,12 +412,12 @@ func (cv *VartypeCheck) Homepage() {
fixedURL := baseURL + subdir
explain := false
if baseURL != "" {
if !cv.line.AutofixReplace(wrong, fixedURL) {
cv.line.Warn1("HOMEPAGE should not be defined in terms of MASTER_SITEs. Use %s directly.", fixedURL)
if !cv.Line.AutofixReplace(wrong, fixedURL) {
cv.Line.Warn1("HOMEPAGE should not be defined in terms of MASTER_SITEs. Use %s directly.", fixedURL)
explain = true
}
} else {
cv.line.Warn0("HOMEPAGE should not be defined in terms of MASTER_SITEs.")
cv.Line.Warn0("HOMEPAGE should not be defined in terms of MASTER_SITEs.")
explain = true
}
if explain {
@ -436,38 +433,38 @@ func (cv *VartypeCheck) Homepage() {
}
func (cv *VartypeCheck) Identifier() {
if cv.op == opUseMatch {
if cv.value == cv.valueNovar && !matches(cv.value, `^[\w*?]`) {
cv.line.Warn2("Invalid identifier pattern %q for %s.", cv.value, cv.varname)
if cv.Op == opUseMatch {
if cv.Value == cv.ValueNoVar && !matches(cv.Value, `^[\w*?]`) {
cv.Line.Warn2("Invalid identifier pattern %q for %s.", cv.Value, cv.Varname)
}
return
}
if cv.value != cv.valueNovar {
if cv.Value != cv.ValueNoVar {
//line.logWarning("Identifiers should be given directly.")
}
switch {
case matches(cv.valueNovar, `^[+\-.0-9A-Z_a-z]+$`):
case matches(cv.ValueNoVar, `^[+\-.0-9A-Z_a-z]+$`):
// Fine.
case cv.value != "" && cv.valueNovar == "":
case cv.Value != "" && cv.ValueNoVar == "":
// Don't warn here.
default:
cv.line.Warn1("Invalid identifier %q.", cv.value)
cv.Line.Warn1("Invalid identifier %q.", cv.Value)
}
}
func (cv *VartypeCheck) Integer() {
if !matches(cv.value, `^\d+$`) {
cv.line.Warn1("Invalid integer %q.", cv.value)
if !matches(cv.Value, `^\d+$`) {
cv.Line.Warn1("Invalid integer %q.", cv.Value)
}
}
func (cv *VartypeCheck) LdFlag() {
if cv.op == opUseMatch {
if cv.Op == opUseMatch {
return
}
ldflag := cv.value
ldflag := cv.Value
if m, rpathFlag := match1(ldflag, `^(-Wl,(?:-R|-rpath|--rpath))`); m {
cv.line.Warn1("Please use \"${COMPILER_RPATH_FLAG}\" instead of %q.", rpathFlag)
cv.Line.Warn1("Please use \"${COMPILER_RPATH_FLAG}\" instead of %q.", rpathFlag)
return
}
@ -479,21 +476,21 @@ func (cv *VartypeCheck) LdFlag() {
hasPrefix(ldflag, "-static-"),
hasPrefix(ldflag, "-Wl,-"),
hasPrefix(ldflag, "`") && hasSuffix(ldflag, "`"),
ldflag != cv.valueNovar:
ldflag != cv.ValueNoVar:
return
case hasPrefix(ldflag, "-"):
cv.line.Warn1("Unknown linker flag %q.", cv.value)
cv.Line.Warn1("Unknown linker flag %q.", cv.Value)
default:
cv.line.Warn1("Linker flag %q should start with a hypen.", cv.value)
cv.Line.Warn1("Linker flag %q should start with a hypen.", cv.Value)
}
}
func (cv *VartypeCheck) License() {
checklineLicense(cv.mkline, cv.value)
checklineLicense(cv.MkLine, cv.Value)
}
func (cv *VartypeCheck) MachineGnuPlatform() {
if cv.value != cv.valueNovar {
if cv.Value != cv.ValueNoVar {
return
}
@ -501,40 +498,38 @@ func (cv *VartypeCheck) MachineGnuPlatform() {
const rePair = `^(` + rePart + `)-(` + rePart + `)$`
const reTriple = `^(` + rePart + `)-(` + rePart + `)-(` + rePart + `)$`
pattern := cv.value
pattern := cv.Value
if matches(pattern, rePair) && hasSuffix(pattern, "*") {
pattern += "-*"
}
if m, archPattern, vendorPattern, opsysPattern := match3(pattern, reTriple); m {
archCv := &VartypeCheck{
cv.mkline,
cv.line,
"the hardware architecture part of " + cv.varname,
cv.MkLine,
cv.Line,
"the hardware architecture part of " + cv.Varname,
opUseMatch, // Always allow patterns, since this is a PlatformPattern.
archPattern,
archPattern,
cv.comment,
cv.listContext,
cv.guessed}
cv.MkComment,
cv.Guessed}
enumMachineGnuArch.checker(archCv)
_ = vendorPattern
opsysCv := &VartypeCheck{
cv.mkline,
cv.line,
"the operating system part of " + cv.varname,
cv.MkLine,
cv.Line,
"the operating system part of " + cv.Varname,
opUseMatch, // Always allow patterns, since this is a PlatformPattern.
opsysPattern,
opsysPattern,
cv.comment,
cv.listContext,
cv.guessed}
cv.MkComment,
cv.Guessed}
enumMachineGnuPlatformOpsys.checker(opsysCv)
} else {
cv.line.Warn1("%q is not a valid platform pattern.", cv.value)
cv.Line.Warn1("%q is not a valid platform pattern.", cv.Value)
Explain(
"A platform pattern has the form <OPSYS>-<OS_VERSION>-<MACHINE_ARCH>.",
"Each of these components may be a shell globbing expression.",
@ -547,7 +542,7 @@ func (cv *VartypeCheck) MachineGnuPlatform() {
}
func (cv *VartypeCheck) MailAddress() {
line, value := cv.line, cv.value
line, value := cv.Line, cv.Value
if m, _, domain := match2(value, `^([+\-.0-9A-Z_a-z]+)@([-\w\d.]+)$`); m {
if strings.EqualFold(domain, "NetBSD.org") && domain != "NetBSD.org" {
@ -564,7 +559,7 @@ func (cv *VartypeCheck) MailAddress() {
// See ${STEP_MSG}, ${PKG_FAIL_REASON}
func (cv *VartypeCheck) Message() {
line, varname, value := cv.line, cv.varname, cv.value
line, varname, value := cv.Line, cv.Varname, cv.Value
if matches(value, `^[\"'].*[\"']$`) {
line.Warn1("%s should not be quoted.", varname)
@ -581,7 +576,7 @@ func (cv *VartypeCheck) Message() {
// A package option from options.mk
func (cv *VartypeCheck) Option() {
line, value, valueNovar := cv.line, cv.value, cv.valueNovar
line, value, valueNovar := cv.Line, cv.Value, cv.ValueNoVar
if value != valueNovar {
if G.opts.Debug {
@ -612,22 +607,22 @@ func (cv *VartypeCheck) Option() {
// The PATH environment variable
func (cv *VartypeCheck) Pathlist() {
if !contains(cv.value, ":") && cv.guessed {
cv.mkline.CheckVartypePrimitive(cv.varname, CheckvarPathname, cv.op, cv.value, cv.comment, cv.listContext, cv.guessed)
if !contains(cv.Value, ":") && cv.Guessed {
cv.MkLine.CheckVartypePrimitive(cv.Varname, CheckvarPathname, cv.Op, cv.Value, cv.MkComment, cv.Guessed)
return
}
for _, path := range strings.Split(cv.value, ":") {
for _, path := range strings.Split(cv.Value, ":") {
if contains(path, "${") {
continue
}
if !matches(path, `^[-0-9A-Za-z._~+%/]*$`) {
cv.line.Warn1("%q is not a valid pathname.", path)
cv.Line.Warn1("%q is not a valid pathname.", path)
}
if !hasPrefix(path, "/") {
cv.line.Warn2("All components of %s (in this case %q) should be absolute paths.", cv.varname, path)
cv.Line.Warn2("All components of %s (in this case %q) should be absolute paths.", cv.Varname, path)
}
}
}
@ -635,50 +630,50 @@ func (cv *VartypeCheck) Pathlist() {
// Shell globbing including slashes.
// See Filemask
func (cv *VartypeCheck) Pathmask() {
if cv.op == opUseMatch {
if cv.Op == opUseMatch {
return
}
if !matches(cv.valueNovar, `^[#\-0-9A-Za-z._~+%*?/\[\]]*`) {
cv.line.Warn1("%q is not a valid pathname mask.", cv.value)
if !matches(cv.ValueNoVar, `^[#\-0-9A-Za-z._~+%*?/\[\]]*`) {
cv.Line.Warn1("%q is not a valid pathname mask.", cv.Value)
}
cv.line.CheckAbsolutePathname(cv.value)
cv.Line.CheckAbsolutePathname(cv.Value)
}
// Like Filename, but including slashes
// See http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_266
func (cv *VartypeCheck) Pathname() {
if cv.op == opUseMatch {
if cv.Op == opUseMatch {
return
}
if !matches(cv.valueNovar, `^[#\-0-9A-Za-z._~+%/]*$`) {
cv.line.Warn1("%q is not a valid pathname.", cv.value)
if !matches(cv.ValueNoVar, `^[#\-0-9A-Za-z._~+%/]*$`) {
cv.Line.Warn1("%q is not a valid pathname.", cv.Value)
}
cv.line.CheckAbsolutePathname(cv.value)
cv.Line.CheckAbsolutePathname(cv.Value)
}
func (cv *VartypeCheck) Perl5Packlist() {
if cv.value != cv.valueNovar {
cv.line.Warn1("%s should not depend on other variables.", cv.varname)
if cv.Value != cv.ValueNoVar {
cv.Line.Warn1("%s should not depend on other variables.", cv.Varname)
}
}
func (cv *VartypeCheck) Perms() {
if cv.value == "${ROOT_USER}" || cv.value == "${ROOT_GROUP}" {
valuename := cv.value[2 : len(cv.value)-1]
cv.line.Error1("%s must not be used in permission definitions. Use REAL_%[1]s instead.", valuename)
if cv.Value == "${ROOT_USER}" || cv.Value == "${ROOT_GROUP}" {
valuename := cv.Value[2 : len(cv.Value)-1]
cv.Line.Error1("%s must not be used in permission definitions. Use REAL_%[1]s instead.", valuename)
}
}
func (cv *VartypeCheck) PkgName() {
if cv.op != opUseMatch && cv.value == cv.valueNovar && !matches(cv.value, rePkgname) {
cv.line.Warn1("%q is not a valid package name. A valid package name has the form packagename-version, where version consists only of digits, letters and dots.", cv.value)
if cv.Op != opUseMatch && cv.Value == cv.ValueNoVar && !matches(cv.Value, rePkgname) {
cv.Line.Warn1("%q is not a valid package name. A valid package name has the form packagename-version, where version consists only of digits, letters and dots.", cv.Value)
}
}
func (cv *VartypeCheck) PkgOptionsVar() {
cv.mkline.CheckVartypePrimitive(cv.varname, CheckvarVarname, cv.op, cv.value, cv.comment, false, cv.guessed)
if matches(cv.value, `\$\{PKGBASE[:\}]`) {
cv.line.Error0("PKGBASE must not be used in PKG_OPTIONS_VAR.")
cv.MkLine.CheckVartypePrimitive(cv.Varname, CheckvarVariableName, cv.Op, cv.Value, cv.MkComment, cv.Guessed)
if matches(cv.Value, `\$\{PKGBASE[:\}]`) {
cv.Line.Error0("PKGBASE must not be used in PKG_OPTIONS_VAR.")
Explain3(
"PKGBASE is defined in bsd.pkg.mk, which is included as the",
"very last file, but PKG_OPTIONS_VAR is evaluated earlier.",
@ -686,23 +681,23 @@ func (cv *VartypeCheck) PkgOptionsVar() {
}
// PR 46570, item "6. It should complain in PKG_OPTIONS_VAR is wrong"
if !hasPrefix(cv.value, "PKG_OPTIONS.") {
cv.line.Error2("PKG_OPTIONS_VAR must be of the form %q, not %q.", "PKG_OPTIONS.*", cv.value)
if !hasPrefix(cv.Value, "PKG_OPTIONS.") {
cv.Line.Error2("PKG_OPTIONS_VAR must be of the form %q, not %q.", "PKG_OPTIONS.*", cv.Value)
}
}
// A directory name relative to the top-level pkgsrc directory.
// Despite its name, it is more similar to RelativePkgDir than to RelativePkgPath.
func (cv *VartypeCheck) PkgPath() {
cv.mkline.CheckRelativePkgdir(G.CurPkgsrcdir + "/" + cv.value)
cv.MkLine.CheckRelativePkgdir(G.CurPkgsrcdir + "/" + cv.Value)
}
func (cv *VartypeCheck) PkgRevision() {
if !matches(cv.value, `^[1-9]\d*$`) {
cv.line.Warn1("%s must be a positive integer number.", cv.varname)
if !matches(cv.Value, `^[1-9]\d*$`) {
cv.Line.Warn1("%s must be a positive integer number.", cv.Varname)
}
if path.Base(cv.line.Fname) != "Makefile" {
cv.line.Error1("%s only makes sense directly in the package Makefile.", cv.varname)
if path.Base(cv.Line.Fname) != "Makefile" {
cv.Line.Error1("%s only makes sense directly in the package Makefile.", cv.Varname)
Explain(
"Usually, different packages using the same Makefile.common have",
"different dependencies and will be bumped at different times (e.g.",
@ -717,7 +712,7 @@ func (cv *VartypeCheck) MachinePlatform() {
}
func (cv *VartypeCheck) MachinePlatformPattern() {
if cv.value != cv.valueNovar {
if cv.Value != cv.ValueNoVar {
return
}
@ -725,40 +720,38 @@ func (cv *VartypeCheck) MachinePlatformPattern() {
const rePair = `^(` + rePart + `)-(` + rePart + `)$`
const reTriple = `^(` + rePart + `)-(` + rePart + `)-(` + rePart + `)$`
pattern := cv.value
pattern := cv.Value
if matches(pattern, rePair) && hasSuffix(pattern, "*") {
pattern += "-*"
}
if m, opsysPattern, _, archPattern := match3(pattern, reTriple); m {
opsysCv := &VartypeCheck{
cv.mkline,
cv.line,
"the operating system part of " + cv.varname,
cv.MkLine,
cv.Line,
"the operating system part of " + cv.Varname,
opUseMatch, // Always allow patterns, since this is a PlatformPattern.
opsysPattern,
opsysPattern,
cv.comment,
cv.listContext,
cv.guessed}
cv.MkComment,
cv.Guessed}
enumMachineOpsys.checker(opsysCv)
// no check for os_version
archCv := &VartypeCheck{
cv.mkline,
cv.line,
"the hardware architecture part of " + cv.varname,
cv.MkLine,
cv.Line,
"the hardware architecture part of " + cv.Varname,
opUseMatch, // Always allow patterns, since this is a PlatformPattern.
archPattern,
archPattern,
cv.comment,
cv.listContext,
cv.guessed}
cv.MkComment,
cv.Guessed}
enumMachineArch.checker(archCv)
} else {
cv.line.Warn1("%q is not a valid platform pattern.", cv.value)
cv.Line.Warn1("%q is not a valid platform pattern.", cv.Value)
Explain(
"A platform pattern has the form <OPSYS>-<OS_VERSION>-<MACHINE_ARCH>.",
"Each of these components may be a shell globbing expression.",
@ -772,16 +765,16 @@ func (cv *VartypeCheck) MachinePlatformPattern() {
// A pathname relative to ${PREFIX}.
func (cv *VartypeCheck) PrefixPathname() {
if m, mansubdir := match1(cv.value, `^man/(.+)`); m {
cv.line.Warn2("Please use \"${PKGMANDIR}/%s\" instead of %q.", mansubdir, cv.value)
if m, mansubdir := match1(cv.Value, `^man/(.+)`); m {
cv.Line.Warn2("Please use \"${PKGMANDIR}/%s\" instead of %q.", mansubdir, cv.Value)
}
}
func (cv *VartypeCheck) PythonDependency() {
if cv.value != cv.valueNovar {
cv.line.Warn0("Python dependencies should not contain variables.")
} else if !matches(cv.valueNovar, `^[+\-.0-9A-Z_a-z]+(?:|:link|:build)$`) {
cv.line.Warn1("Invalid Python dependency %q.", cv.value)
if cv.Value != cv.ValueNoVar {
cv.Line.Warn0("Python dependencies should not contain variables.")
} else if !matches(cv.ValueNoVar, `^[+\-.0-9A-Z_a-z]+(?:|:link|:build)$`) {
cv.Line.Warn1("Invalid Python dependency %q.", cv.Value)
Explain4(
"Python dependencies must be an identifier for a package, as",
"specified in lang/python/versioned_dependencies.mk. This",
@ -792,17 +785,17 @@ func (cv *VartypeCheck) PythonDependency() {
// Refers to a package directory, e.g. ../../category/pkgbase.
func (cv *VartypeCheck) RelativePkgDir() {
cv.mkline.CheckRelativePkgdir(cv.value)
cv.MkLine.CheckRelativePkgdir(cv.Value)
}
// Refers to a file or directory, e.g. ../../category/pkgbase, ../../category/pkgbase/Makefile.
func (cv *VartypeCheck) RelativePkgPath() {
cv.mkline.CheckRelativePath(cv.value, true)
cv.MkLine.CheckRelativePath(cv.Value, true)
}
func (cv *VartypeCheck) Restricted() {
if cv.value != "${RESTRICTED}" {
cv.line.Warn1("The only valid value for %s is ${RESTRICTED}.", cv.varname)
if cv.Value != "${RESTRICTED}" {
cv.Line.Warn1("The only valid value for %s is ${RESTRICTED}.", cv.Varname)
Explain3(
"These variables are used to control which files may be mirrored on",
"FTP servers or CD-ROM collections. They are not intended to mark",
@ -814,10 +807,10 @@ func (cv *VartypeCheck) SedCommand() {
}
func (cv *VartypeCheck) SedCommands() {
line := cv.line
mkline := cv.mkline
line := cv.Line
mkline := cv.MkLine
tokens, rest := splitIntoShellTokens(line, cv.value)
tokens, rest := splitIntoShellTokens(line, cv.Value)
if rest != "" {
if strings.Contains(line.Text, "#") {
line.Error1("Invalid shell words %q in sed commands.", rest)
@ -853,7 +846,7 @@ func (cv *VartypeCheck) SedCommands() {
"",
"This way, short sed commands cannot be hidden at the end of a line.")
}
mkline.CheckVartypePrimitive(cv.varname, CheckvarSedCommand, cv.op, tokens[i], cv.comment, cv.listContext, cv.guessed)
mkline.CheckVartypePrimitive(cv.Varname, CheckvarSedCommand, cv.Op, tokens[i], cv.MkComment, cv.Guessed)
} else {
line.Error0("The -e option to sed requires an argument.")
}
@ -873,27 +866,25 @@ func (cv *VartypeCheck) SedCommands() {
}
func (cv *VartypeCheck) ShellCommand() {
if cv.op == opUseMatch || cv.op == opUse {
if cv.Op == opUseMatch || cv.Op == opUse {
return
}
setE := true
NewShellLine(cv.mkline).CheckShellCommand(cv.value, &setE)
NewShellLine(cv.MkLine).CheckShellCommand(cv.Value, &setE)
}
// Zero or more shell commands, each terminated with a semicolon.
func (cv *VartypeCheck) ShellCommands() {
NewShellLine(cv.mkline).CheckShellCommands(cv.value)
NewShellLine(cv.MkLine).CheckShellCommands(cv.Value)
}
func (cv *VartypeCheck) ShellWord() {
if !cv.listContext {
NewShellLine(cv.mkline).CheckWord(cv.value, true)
}
NewShellLine(cv.MkLine).CheckWord(cv.Value, true)
}
func (cv *VartypeCheck) Stage() {
if !matches(cv.value, `^(?:pre|do|post)-(?:extract|patch|configure|build|test|install)`) {
cv.line.Warn1("Invalid stage name %q. Use one of {pre,do,post}-{extract,patch,configure,build,test,install}.", cv.value)
if !matches(cv.Value, `^(?:pre|do|post)-(?:extract|patch|configure|build|test|install)`) {
cv.Line.Warn1("Invalid stage name %q. Use one of {pre,do,post}-{extract,patch,configure,build,test,install}.", cv.Value)
}
}
@ -902,20 +893,20 @@ func (cv *VartypeCheck) String() {
}
func (cv *VartypeCheck) Tool() {
if cv.varname == "TOOLS_NOOP" && cv.op == opAssignAppend {
if cv.Varname == "TOOLS_NOOP" && cv.Op == opAssignAppend {
// no warning for package-defined tool definitions
} else if m, toolname, tooldep := match2(cv.value, `^([-\w]+|\[)(?::(\w+))?$`); m {
} else if m, toolname, tooldep := match2(cv.Value, `^([-\w]+|\[)(?::(\w+))?$`); m {
if G.globalData.Tools.byName[toolname] == nil {
cv.line.Error1("Unknown tool %q.", toolname)
cv.Line.Error1("Unknown tool %q.", toolname)
}
switch tooldep {
case "", "bootstrap", "build", "pkgsrc", "run":
default:
cv.line.Error1("Unknown tool dependency %q. Use one of \"build\", \"pkgsrc\" or \"run\".", tooldep)
cv.Line.Error1("Unknown tool dependency %q. Use one of \"build\", \"pkgsrc\" or \"run\".", tooldep)
}
} else if cv.op != opUseMatch {
cv.line.Error1("Invalid tool syntax: %q.", cv.value)
} else if cv.Op != opUseMatch {
cv.Line.Error1("Invalid tool syntax: %q.", cv.Value)
}
}
@ -924,9 +915,9 @@ func (cv *VartypeCheck) Unchecked() {
}
func (cv *VartypeCheck) URL() {
line, value := cv.line, cv.value
line, value := cv.Line, cv.Value
if value == "" && hasPrefix(cv.comment, "#") {
if value == "" && hasPrefix(cv.MkComment, "#") {
// Ok
} else if containsVarRef(value) {
@ -955,14 +946,14 @@ func (cv *VartypeCheck) URL() {
}
func (cv *VartypeCheck) UserGroupName() {
if cv.value == cv.valueNovar && !matches(cv.value, `^[0-9_a-z]+$`) {
cv.line.Warn1("Invalid user or group name %q.", cv.value)
if cv.Value == cv.ValueNoVar && !matches(cv.Value, `^[0-9_a-z]+$`) {
cv.Line.Warn1("Invalid user or group name %q.", cv.Value)
}
}
func (cv *VartypeCheck) Varname() {
if cv.value == cv.valueNovar && !matches(cv.value, `^[A-Z_][0-9A-Z_]*(?:[.].*)?$`) {
cv.line.Warn1("%q is not a valid variable name.", cv.value)
func (cv *VartypeCheck) VariableName() {
if cv.Value == cv.ValueNoVar && !matches(cv.Value, `^[A-Z_][0-9A-Z_]*(?:[.].*)?$`) {
cv.Line.Warn1("%q is not a valid variable name.", cv.Value)
Explain(
"Variable names are restricted to only uppercase letters and the",
"underscore in the basename, and arbitrary characters in the",
@ -975,23 +966,23 @@ func (cv *VartypeCheck) Varname() {
}
func (cv *VartypeCheck) Version() {
if cv.op == opUseMatch {
if !matches(cv.value, `^[\d?\[][\w\-.*?\[\]]+$`) {
cv.line.Warn1("Invalid version number pattern %q.", cv.value)
if cv.Op == opUseMatch {
if !matches(cv.Value, `^[\d?\[][\w\-.*?\[\]]+$`) {
cv.Line.Warn1("Invalid version number pattern %q.", cv.Value)
}
} else if cv.value == cv.valueNovar && !matches(cv.value, `^\d[\w.]+$`) {
cv.line.Warn1("Invalid version number %q.", cv.value)
} else if cv.Value == cv.ValueNoVar && !matches(cv.Value, `^\d[\w.]+$`) {
cv.Line.Warn1("Invalid version number %q.", cv.Value)
}
}
func (cv *VartypeCheck) WrapperReorder() {
if !matches(cv.value, `^reorder:l:([\w\-]+):([\w\-]+)$`) {
cv.line.Warn1("Unknown wrapper reorder command %q.", cv.value)
if !matches(cv.Value, `^reorder:l:([\w\-]+):([\w\-]+)$`) {
cv.Line.Warn1("Unknown wrapper reorder command %q.", cv.Value)
}
}
func (cv *VartypeCheck) WrapperTransform() {
cmd := cv.value
cmd := cv.Value
if hasPrefix(cmd, "rm:-") ||
matches(cmd, `^(R|l|rpath):([^:]+):(.+)$`) ||
matches(cmd, `^'?(opt|rename|rm-optarg|rmdir):.*$`) ||
@ -999,35 +990,35 @@ func (cv *VartypeCheck) WrapperTransform() {
matches(cmd, `^["']?s[|:,]`) {
return
}
cv.line.Warn1("Unknown wrapper transform command %q.", cmd)
cv.Line.Warn1("Unknown wrapper transform command %q.", cmd)
}
func (cv *VartypeCheck) WrkdirSubdirectory() {
cv.mkline.CheckVartypePrimitive(cv.varname, CheckvarPathname, cv.op, cv.value, cv.comment, cv.listContext, cv.guessed)
cv.MkLine.CheckVartypePrimitive(cv.Varname, CheckvarPathname, cv.Op, cv.Value, cv.MkComment, cv.Guessed)
}
// A directory relative to ${WRKSRC}, for use in CONFIGURE_DIRS and similar variables.
func (cv *VartypeCheck) WrksrcSubdirectory() {
if m, _, rest := match2(cv.value, `^(\$\{WRKSRC\})(?:/(.*))?`); m {
if m, _, rest := match2(cv.Value, `^(\$\{WRKSRC\})(?:/(.*))?`); m {
if rest == "" {
rest = "."
}
cv.line.Note2("You can use %q instead of %q.", rest, cv.value)
cv.Line.Note2("You can use %q instead of %q.", rest, cv.Value)
Explain1(
"These directories are interpreted relative to ${WRKSRC}.")
} else if cv.value != "" && cv.valueNovar == "" {
} else if cv.Value != "" && cv.ValueNoVar == "" {
// The value of another variable
} else if !matches(cv.valueNovar, `^(?:\.|[0-9A-Za-z_@][-0-9A-Za-z_@./+]*)$`) {
cv.line.Warn1("%q is not a valid subdirectory of ${WRKSRC}.", cv.value)
} else if !matches(cv.ValueNoVar, `^(?:\.|[0-9A-Za-z_@][-0-9A-Za-z_@./+]*)$`) {
cv.Line.Warn1("%q is not a valid subdirectory of ${WRKSRC}.", cv.Value)
}
}
func (cv *VartypeCheck) Yes() {
switch cv.op {
switch cv.Op {
case opUseMatch:
cv.line.Warn1("%s should only be used in a \".if defined(...)\" conditional.", cv.varname)
cv.Line.Warn1("%s should only be used in a \".if defined(...)\" conditional.", cv.Varname)
Explain(
"This variable can have only two values: defined or undefined.",
"When it is defined, it means \"yes\", even when its value is",
@ -1037,8 +1028,8 @@ func (cv *VartypeCheck) Yes() {
"but using \".if defined(VARNAME)\" alone.")
default:
if !matches(cv.value, `^(?:YES|yes)(?:\s+#.*)?$`) {
cv.line.Warn1("%s should be set to YES or yes.", cv.varname)
if !matches(cv.Value, `^(?:YES|yes)(?:\s+#.*)?$`) {
cv.Line.Warn1("%s should be set to YES or yes.", cv.Varname)
Explain4(
"This variable means \"yes\" if it is defined, and \"no\" if it is",
"undefined. Even when it has the value \"no\", this means \"yes\".",
@ -1055,25 +1046,25 @@ func (cv *VartypeCheck) YesNo() {
no1 = "[nN][oO]"
no2 = "[Nn][Oo]"
)
if cv.op == opUseMatch {
switch cv.value {
if cv.Op == opUseMatch {
switch cv.Value {
case yes1, yes2, no1, no2:
default:
cv.line.Warnf("%s should be matched against %q or %q, not %q.", cv.varname, yes1, no1, cv.value)
cv.Line.Warnf("%s should be matched against %q or %q, not %q.", cv.Varname, yes1, no1, cv.Value)
}
} else if cv.op == opUse {
cv.line.Warnf("%s should be matched against %q or %q, not compared with %q.", cv.varname, yes1, no1, cv.value)
} else if cv.Op == opUse {
cv.Line.Warnf("%s should be matched against %q or %q, not compared with %q.", cv.Varname, yes1, no1, cv.Value)
Explain(
"The yes/no value can be written in either upper or lower case, and",
"both forms are actually used. As long as this is the case, when",
"checking the variable value, both must be accepted.")
} else if !matches(cv.value, `^(?:YES|yes|NO|no)(?:\s+#.*)?$`) {
cv.line.Warn1("%s should be set to YES, yes, NO, or no.", cv.varname)
} else if !matches(cv.Value, `^(?:YES|yes|NO|no)(?:\s+#.*)?$`) {
cv.Line.Warn1("%s should be set to YES, yes, NO, or no.", cv.Varname)
}
}
func (cv *VartypeCheck) YesNoIndirectly() {
if cv.valueNovar != "" {
if cv.ValueNoVar != "" {
cv.YesNo()
}
}

View file

@ -6,7 +6,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestVartypeCheck_AwkCommand(c *check.C) {
func (s *Suite) Test_VartypeCheck_AwkCommand(c *check.C) {
runVartypeChecks("PLIST_AWK", opAssignAppend, (*VartypeCheck).AwkCommand,
"{print $0}",
"{print $$0}")
@ -14,7 +14,7 @@ func (s *Suite) TestVartypeCheck_AwkCommand(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:1: $0 is ambiguous. Use ${0} if you mean a Makefile variable or $$0 if you mean a shell variable.\n")
}
func (s *Suite) TestVartypeCheck_BasicRegularExpression(c *check.C) {
func (s *Suite) Test_VartypeCheck_BasicRegularExpression(c *check.C) {
runVartypeChecks("REPLACE_FILES.pl", opAssign, (*VartypeCheck).BasicRegularExpression,
".*\\.pl$",
".*\\.pl$$")
@ -22,7 +22,7 @@ func (s *Suite) TestVartypeCheck_BasicRegularExpression(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:1: Pkglint parse error in MkLine.Tokenize at \"$\".\n")
}
func (s *Suite) TestVartypeCheck_BuildlinkDepmethod(c *check.C) {
func (s *Suite) Test_VartypeCheck_BuildlinkDepmethod(c *check.C) {
runVartypeChecks("BUILDLINK_DEPMETHOD.libc", opAssignDefault, (*VartypeCheck).BuildlinkDepmethod,
"full",
"unknown")
@ -30,7 +30,7 @@ func (s *Suite) TestVartypeCheck_BuildlinkDepmethod(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:2: Invalid dependency method \"unknown\". Valid methods are \"build\" or \"full\".\n")
}
func (s *Suite) TestVartypeCheck_Category(c *check.C) {
func (s *Suite) Test_VartypeCheck_Category(c *check.C) {
s.CreateTmpFile(c, "filesyscategory/Makefile", "# empty\n")
s.CreateTmpFile(c, "wip/Makefile", "# empty\n")
G.CurrentDir = s.tmpdir
@ -47,7 +47,7 @@ func (s *Suite) TestVartypeCheck_Category(c *check.C) {
"ERROR: fname:4: Invalid category \"wip\".\n")
}
func (s *Suite) TestVartypeCheck_CFlag(c *check.C) {
func (s *Suite) Test_VartypeCheck_CFlag(c *check.C) {
runVartypeChecks("CFLAGS", opAssignAppend, (*VartypeCheck).CFlag,
"-Wall",
"/W3",
@ -62,7 +62,7 @@ func (s *Suite) TestVartypeCheck_CFlag(c *check.C) {
"WARN: fname:5: Unknown compiler flag \"-XX:+PrintClassHistogramAfterFullGC\".\n")
}
func (s *Suite) TestVartypeCheck_Comment(c *check.C) {
func (s *Suite) Test_VartypeCheck_Comment(c *check.C) {
runVartypeChecks("COMMENT", opAssign, (*VartypeCheck).Comment,
"Versatile Programming Language",
"TODO: Short description of the package",
@ -77,7 +77,7 @@ func (s *Suite) TestVartypeCheck_Comment(c *check.C) {
"WARN: fname:4: COMMENT should not be longer than 70 characters.\n")
}
func (s *Suite) TestVartypeCheck_Dependency(c *check.C) {
func (s *Suite) Test_VartypeCheck_Dependency(c *check.C) {
runVartypeChecks("CONFLICTS", opAssignAppend, (*VartypeCheck).Dependency,
"Perl",
"perl5>=5.22",
@ -114,7 +114,7 @@ func (s *Suite) TestVartypeCheck_Dependency(c *check.C) {
"WARN: fname:21: Dependency patterns of the form pkgbase>=1.0 don't need the \"{,nb*}\" extension.\n")
}
func (s *Suite) TestVartypeCheck_DependencyWithPath(c *check.C) {
func (s *Suite) Test_VartypeCheck_DependencyWithPath(c *check.C) {
s.CreateTmpFile(c, "x11/alacarte/Makefile", "# empty\n")
s.CreateTmpFile(c, "category/package/Makefile", "# empty\n")
G.globalData.Pkgsrcdir = s.tmpdir
@ -151,7 +151,7 @@ func (s *Suite) TestVartypeCheck_DependencyWithPath(c *check.C) {
"WARN: fname:11: Unknown dependency pattern \"broken>\".\n")
}
func (s *Suite) TestVartypeCheck_DistSuffix(c *check.C) {
func (s *Suite) Test_VartypeCheck_DistSuffix(c *check.C) {
runVartypeChecks("EXTRACT_SUFX", opAssign, (*VartypeCheck).DistSuffix,
".tar.gz",
".tar.bz2")
@ -159,7 +159,7 @@ func (s *Suite) TestVartypeCheck_DistSuffix(c *check.C) {
c.Check(s.Output(), equals, "NOTE: fname:1: EXTRACT_SUFX is \".tar.gz\" by default, so this definition may be redundant.\n")
}
func (s *Suite) TestVartypeCheck_EmulPlatform(c *check.C) {
func (s *Suite) Test_VartypeCheck_EmulPlatform(c *check.C) {
runVartypeChecks("EMUL_PLATFORM", opAssign, (*VartypeCheck).EmulPlatform,
"linux-i386",
"nextbsd-8087",
@ -171,7 +171,7 @@ func (s *Suite) TestVartypeCheck_EmulPlatform(c *check.C) {
"WARN: fname:3: \"${LINUX}\" is not a valid emulation platform.\n")
}
func (s *Suite) TestVartypeCheck_Enum(c *check.C) {
func (s *Suite) Test_VartypeCheck_Enum(c *check.C) {
runVartypeMatchChecks("JDK", enum("jdk1 jdk2 jdk4").checker,
"*",
"jdk*",
@ -181,7 +181,7 @@ func (s *Suite) TestVartypeCheck_Enum(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:3: The pattern \"sun-jdk*\" cannot match any of { jdk1 jdk2 jdk4 } for JDK.\n")
}
func (s *Suite) TestVartypeCheck_FetchURL(c *check.C) {
func (s *Suite) Test_VartypeCheck_FetchURL(c *check.C) {
s.RegisterMasterSite("MASTER_SITE_GNU", "http://ftp.gnu.org/pub/gnu/")
s.RegisterMasterSite("MASTER_SITE_GITHUB", "https://github.com/")
@ -211,7 +211,7 @@ func (s *Suite) TestVartypeCheck_FetchURL(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:3: \"http://example.org/download?fname=<distfile>;version=<version>\" is not a valid URL.\n")
}
func (s *Suite) TestVartypeCheck_Filename(c *check.C) {
func (s *Suite) Test_VartypeCheck_Filename(c *check.C) {
runVartypeChecks("FNAME", opAssign, (*VartypeCheck).Filename,
"Filename with spaces.docx",
"OS/2-manual.txt")
@ -221,7 +221,7 @@ func (s *Suite) TestVartypeCheck_Filename(c *check.C) {
"WARN: fname:2: A filename should not contain a slash.\n")
}
func (s *Suite) TestVartypeCheck_LdFlag(c *check.C) {
func (s *Suite) Test_VartypeCheck_LdFlag(c *check.C) {
runVartypeChecks("LDFLAGS", opAssignAppend, (*VartypeCheck).LdFlag,
"-lc",
"-L/usr/lib64",
@ -231,7 +231,7 @@ func (s *Suite) TestVartypeCheck_LdFlag(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:4: Unknown linker flag \"-unknown\".\n")
}
func (s *Suite) TestVartypeCheck_MachineGnuPlatform(c *check.C) {
func (s *Suite) Test_VartypeCheck_MachineGnuPlatform(c *check.C) {
runVartypeMatchChecks("MACHINE_GNU_PLATFORM", (*VartypeCheck).MachineGnuPlatform,
"x86_64-pc-cygwin",
"Cygwin-*-amd64")
@ -241,14 +241,14 @@ func (s *Suite) TestVartypeCheck_MachineGnuPlatform(c *check.C) {
"WARN: fname:2: The pattern \"amd64\" cannot match any of { bitrig bsdos cygwin darwin dragonfly freebsd haiku hpux interix irix linux mirbsd netbsd openbsd osf1 solaris sunos } for the operating system part of MACHINE_GNU_PLATFORM.\n")
}
func (s *Suite) TestVartypeCheck_MailAddress(c *check.C) {
func (s *Suite) Test_VartypeCheck_MailAddress(c *check.C) {
runVartypeChecks("MAINTAINER", opAssign, (*VartypeCheck).MailAddress,
"pkgsrc-users@netbsd.org")
c.Check(s.Output(), equals, "WARN: fname:1: Please write \"NetBSD.org\" instead of \"netbsd.org\".\n")
}
func (s *Suite) TestVartypeCheck_Message(c *check.C) {
func (s *Suite) Test_VartypeCheck_Message(c *check.C) {
runVartypeChecks("SUBST_MESSAGE.id", opAssign, (*VartypeCheck).Message,
"\"Correct paths\"",
"Correct paths")
@ -256,7 +256,7 @@ func (s *Suite) TestVartypeCheck_Message(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:1: SUBST_MESSAGE.id should not be quoted.\n")
}
func (s *Suite) TestVartypeCheck_Option(c *check.C) {
func (s *Suite) Test_VartypeCheck_Option(c *check.C) {
G.globalData.PkgOptions = map[string]string{
"documented": "Option description",
"undocumented": "",
@ -270,7 +270,7 @@ func (s *Suite) TestVartypeCheck_Option(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:3: Unknown option \"unknown\".\n")
}
func (s *Suite) TestVartypeCheck_Pathlist(c *check.C) {
func (s *Suite) Test_VartypeCheck_Pathlist(c *check.C) {
runVartypeChecks("PATH", opAssign, (*VartypeCheck).Pathlist,
"/usr/bin:/usr/sbin:.:${LOCALBASE}/bin")
@ -287,7 +287,7 @@ func (s *Suite) Test_VartypeCheck_Perms(c *check.C) {
c.Check(s.Output(), equals, "ERROR: fname:2: ROOT_USER must not be used in permission definitions. Use REAL_ROOT_USER instead.\n")
}
func (s *Suite) TestVartypeCheck_PkgOptionsVar(c *check.C) {
func (s *Suite) Test_VartypeCheck_PkgOptionsVar(c *check.C) {
runVartypeChecks("PKG_OPTIONS_VAR.screen", opAssign, (*VartypeCheck).PkgOptionsVar,
"PKG_OPTIONS.${PKGBASE}",
"PKG_OPTIONS.anypkgbase")
@ -296,7 +296,7 @@ func (s *Suite) TestVartypeCheck_PkgOptionsVar(c *check.C) {
"ERROR: fname:1: PKGBASE must not be used in PKG_OPTIONS_VAR.\n")
}
func (s *Suite) TestVartypeCheck_PkgRevision(c *check.C) {
func (s *Suite) Test_VartypeCheck_PkgRevision(c *check.C) {
runVartypeChecks("PKGREVISION", opAssign, (*VartypeCheck).PkgRevision,
"3a")
@ -310,7 +310,7 @@ func (s *Suite) TestVartypeCheck_PkgRevision(c *check.C) {
c.Check(s.Output(), equals, "")
}
func (s *Suite) TestVartypeCheck_MachinePlatformPattern(c *check.C) {
func (s *Suite) Test_VartypeCheck_MachinePlatformPattern(c *check.C) {
runVartypeMatchChecks("ONLY_FOR_PLATFORM", (*VartypeCheck).MachinePlatformPattern,
"linux-i386",
"nextbsd-5.0-8087",
@ -329,7 +329,7 @@ func (s *Suite) TestVartypeCheck_MachinePlatformPattern(c *check.C) {
"WARN: fname:5: \"FreeBSD*\" is not a valid platform pattern.\n")
}
func (s *Suite) TestVartypeCheck_PythonDependency(c *check.C) {
func (s *Suite) Test_VartypeCheck_PythonDependency(c *check.C) {
runVartypeChecks("PYTHON_VERSIONED_DEPENDENCIES", opAssign, (*VartypeCheck).PythonDependency,
"cairo",
"${PYDEP}",
@ -340,14 +340,14 @@ func (s *Suite) TestVartypeCheck_PythonDependency(c *check.C) {
"WARN: fname:3: Invalid Python dependency \"cairo,X\".\n")
}
func (s *Suite) TestVartypeCheck_Restricted(c *check.C) {
func (s *Suite) Test_VartypeCheck_Restricted(c *check.C) {
runVartypeChecks("NO_BIN_ON_CDROM", opAssign, (*VartypeCheck).Restricted,
"May only be distributed free of charge")
c.Check(s.Output(), equals, "WARN: fname:1: The only valid value for NO_BIN_ON_CDROM is ${RESTRICTED}.\n")
}
func (s *Suite) TestVartypeCheck_SedCommands(c *check.C) {
func (s *Suite) Test_VartypeCheck_SedCommands(c *check.C) {
runVartypeChecks("SUBST_SED.dummy", opAssign, (*VartypeCheck).SedCommands,
"s,@COMPILER@,gcc,g",
"-e s,a,b, -e a,b,c,",
@ -359,7 +359,7 @@ func (s *Suite) TestVartypeCheck_SedCommands(c *check.C) {
"NOTE: fname:2: Each sed command should appear in an assignment of its own.\n")
}
func (s *Suite) TestVartypeCheck_ShellCommands(c *check.C) {
func (s *Suite) Test_VartypeCheck_ShellCommands(c *check.C) {
runVartypeChecks("GENERATE_PLIST", opAssign, (*VartypeCheck).ShellCommands,
"echo bin/program",
"echo bin/program;")
@ -367,7 +367,7 @@ func (s *Suite) TestVartypeCheck_ShellCommands(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:1: This shell command list should end with a semicolon.\n")
}
func (s *Suite) TestVartypeCheck_Stage(c *check.C) {
func (s *Suite) Test_VartypeCheck_Stage(c *check.C) {
runVartypeChecks("SUBST_STAGE.dummy", opAssign, (*VartypeCheck).Stage,
"post-patch",
"post-modern",
@ -376,8 +376,8 @@ func (s *Suite) TestVartypeCheck_Stage(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:2: Invalid stage name \"post-modern\". Use one of {pre,do,post}-{extract,patch,configure,build,test,install}.\n")
}
func (s *Suite) TestVartypeCheck_Varname(c *check.C) {
runVartypeChecks("BUILD_DEFS", opAssign, (*VartypeCheck).Varname,
func (s *Suite) Test_VartypeCheck_VariableName(c *check.C) {
runVartypeChecks("BUILD_DEFS", opAssign, (*VartypeCheck).VariableName,
"VARBASE",
"VarBase",
"PKG_OPTIONS_VAR.pkgbase",
@ -386,7 +386,7 @@ func (s *Suite) TestVartypeCheck_Varname(c *check.C) {
c.Check(s.Output(), equals, "WARN: fname:2: \"VarBase\" is not a valid variable name.\n")
}
func (s *Suite) TestVartypeCheck_Yes(c *check.C) {
func (s *Suite) Test_VartypeCheck_Yes(c *check.C) {
runVartypeChecks("APACHE_MODULE", opAssign, (*VartypeCheck).Yes,
"yes",
"no",
@ -407,7 +407,7 @@ func (s *Suite) TestVartypeCheck_Yes(c *check.C) {
"WARN: fname:3: PKG_DEVELOPER should only be used in a \".if defined(...)\" conditional.\n")
}
func (s *Suite) TestVartypeCheck_YesNo(c *check.C) {
func (s *Suite) Test_VartypeCheck_YesNo(c *check.C) {
runVartypeChecks("GNU_CONFIGURE", opAssign, (*VartypeCheck).YesNo,
"yes",
"no",
@ -419,7 +419,7 @@ func (s *Suite) TestVartypeCheck_YesNo(c *check.C) {
"WARN: fname:4: GNU_CONFIGURE should be set to YES, yes, NO, or no.\n")
}
func (s *Suite) TestVartypeCheck_YesNoIndirectly(c *check.C) {
func (s *Suite) Test_VartypeCheck_YesNoIndirectly(c *check.C) {
runVartypeChecks("GNU_CONFIGURE", opAssign, (*VartypeCheck).YesNoIndirectly,
"yes",
"no",
@ -436,8 +436,8 @@ func runVartypeChecks(varname string, op MkOperator, checker func(*VartypeCheck)
}
for i, value := range values {
mkline := NewMkLine(NewLine("fname", i+1, varname+op.String()+value, nil))
valueNovar := mkline.withoutMakeVariables(mkline.Value(), true)
vc := &VartypeCheck{mkline, mkline.Line, mkline.Varname(), mkline.Op(), mkline.Value(), valueNovar, "", true, false}
valueNovar := mkline.withoutMakeVariables(mkline.Value())
vc := &VartypeCheck{mkline, mkline.Line, mkline.Varname(), mkline.Op(), mkline.Value(), valueNovar, "", false}
checker(vc)
}
}
@ -446,8 +446,8 @@ func runVartypeMatchChecks(varname string, checker func(*VartypeCheck), values .
for i, value := range values {
text := fmt.Sprintf(".if ${%s:M%s} == \"\"", varname, value)
mkline := NewMkLine(NewLine("fname", i+1, text, nil))
valueNovar := mkline.withoutMakeVariables(value, true)
vc := &VartypeCheck{mkline, mkline.Line, varname, opUseMatch, value, valueNovar, "", true, false}
valueNovar := mkline.withoutMakeVariables(value)
vc := &VartypeCheck{mkline, mkline.Line, varname, opUseMatch, value, valueNovar, "", false}
checker(vc)
}
}
@ -455,8 +455,8 @@ func runVartypeMatchChecks(varname string, checker func(*VartypeCheck), values .
func runVartypeChecksFname(fname, varname string, op MkOperator, checker func(*VartypeCheck), values ...string) {
for i, value := range values {
mkline := NewMkLine(NewLine(fname, i+1, varname+op.String()+value, nil))
valueNovar := mkline.withoutMakeVariables(value, true)
vc := &VartypeCheck{mkline, mkline.Line, varname, op, value, valueNovar, "", true, false}
valueNovar := mkline.withoutMakeVariables(value)
vc := &VartypeCheck{mkline, mkline.Line, varname, op, value, valueNovar, "", false}
checker(vc)
}
}

View file

@ -4,7 +4,7 @@ import (
check "gopkg.in/check.v1"
)
func (s *Suite) TestMkversion(c *check.C) {
func (s *Suite) Test_newVersion(c *check.C) {
c.Check(newVersion("5.0"), check.DeepEquals, &version{[]int{5, 0, 0}, 0})
c.Check(newVersion("5.0nb5"), check.DeepEquals, &version{[]int{5, 0, 0}, 5})
c.Check(newVersion("0.0.1-SNAPSHOT"), check.DeepEquals, &version{[]int{0, 0, 0, 0, 1, 19, 14, 1, 16, 19, 8, 15, 20}, 0})
@ -18,7 +18,7 @@ func (s *Suite) TestMkversion(c *check.C) {
c.Check(newVersion("0pre20160620"), deepEquals, &version{[]int{0, -1, 20160620}, 0})
}
func (s *Suite) TestPkgverCmp(c *check.C) {
func (s *Suite) Test_pkgverCmp(c *check.C) {
var versions = [][]string{
{"0pre20160620"},
{"0"},