diff options
author | rillig <rillig> | 2016-07-09 09:43:48 +0000 |
---|---|---|
committer | rillig <rillig> | 2016-07-09 09:43:48 +0000 |
commit | f5618ddc37935500a7c797722b19543138a73a19 (patch) | |
tree | 8d54647d341a1f460fb87227288679799ebc6528 | |
parent | fd61e06be9cdf433371c4600cd5e08b6cdbb7497 (diff) | |
download | pkgsrc-f5618ddc37935500a7c797722b19543138a73a19.tar.gz |
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
45 files changed, 878 insertions, 897 deletions
diff --git a/pkgtools/pkglint/Makefile b/pkgtools/pkglint/Makefile index acf4854aeda..bda48b7aa42 100644 --- a/pkgtools/pkglint/Makefile +++ b/pkgtools/pkglint/Makefile @@ -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 diff --git a/pkgtools/pkglint/files/buildlink3_test.go b/pkgtools/pkglint/files/buildlink3_test.go index 8fca46538a2..edb4d0936e6 100644 --- a/pkgtools/pkglint/files/buildlink3_test.go +++ b/pkgtools/pkglint/files/buildlink3_test.go @@ -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$", diff --git a/pkgtools/pkglint/files/category_test.go b/pkgtools/pkglint/files/category_test.go index 1db1e059cf9..19225cb321c 100644 --- a/pkgtools/pkglint/files/category_test.go +++ b/pkgtools/pkglint/files/category_test.go @@ -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"+ diff --git a/pkgtools/pkglint/files/dir_test.go b/pkgtools/pkglint/files/dir_test.go index 0571449fe62..f721e5224f0 100644 --- a/pkgtools/pkglint/files/dir_test.go +++ b/pkgtools/pkglint/files/dir_test.go @@ -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", "") diff --git a/pkgtools/pkglint/files/distinfo_test.go b/pkgtools/pkglint/files/distinfo_test.go index 97d7a863a52..b667917b842 100644 --- a/pkgtools/pkglint/files/distinfo_test.go +++ b/pkgtools/pkglint/files/distinfo_test.go @@ -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 diff --git a/pkgtools/pkglint/files/expecter.go b/pkgtools/pkglint/files/expecter.go index bf236038d66..8dabbdb7475 100644 --- a/pkgtools/pkglint/files/expecter.go +++ b/pkgtools/pkglint/files/expecter.go @@ -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() { diff --git a/pkgtools/pkglint/files/files_test.go b/pkgtools/pkglint/files/files_test.go index 928c9858dac..da49609c404 100644 --- a/pkgtools/pkglint/files/files_test.go +++ b/pkgtools/pkglint/files/files_test.go @@ -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"+ diff --git a/pkgtools/pkglint/files/getopt_test.go b/pkgtools/pkglint/files/getopt_test.go index 4ccb76179c1..ec91f87d209 100644 --- a/pkgtools/pkglint/files/getopt_test.go +++ b/pkgtools/pkglint/files/getopt_test.go @@ -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, "") diff --git a/pkgtools/pkglint/files/globaldata.go b/pkgtools/pkglint/files/globaldata.go index 3e67fa9fd3a..5e396d302ba 100644 --- a/pkgtools/pkglint/files/globaldata.go +++ b/pkgtools/pkglint/files/globaldata.go @@ -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) diff --git a/pkgtools/pkglint/files/globaldata_test.go b/pkgtools/pkglint/files/globaldata_test.go index 8c4c1d840f6..7e3287b19e0 100644 --- a/pkgtools/pkglint/files/globaldata_test.go +++ b/pkgtools/pkglint/files/globaldata_test.go @@ -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) diff --git a/pkgtools/pkglint/files/licenses_test.go b/pkgtools/pkglint/files/licenses_test.go index 1224b24f66b..ca2f360b477 100644 --- a/pkgtools/pkglint/files/licenses_test.go +++ b/pkgtools/pkglint/files/licenses_test.go @@ -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 diff --git a/pkgtools/pkglint/files/line.go b/pkgtools/pkglint/files/line.go index 836118cab65..b24ab83f2bc 100644 --- a/pkgtools/pkglint/files/line.go +++ b/pkgtools/pkglint/files/line.go @@ -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(?::[^\$]+)?\$$`) { diff --git a/pkgtools/pkglint/files/line_test.go b/pkgtools/pkglint/files/line_test.go index 9a31f1944c9..11548a64f87 100644 --- a/pkgtools/pkglint/files/line_test.go +++ b/pkgtools/pkglint/files/line_test.go @@ -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") +} diff --git a/pkgtools/pkglint/files/main_test.go b/pkgtools/pkglint/files/main_test.go index b33d0c9df4e..48b7408fca2 100644 --- a/pkgtools/pkglint/files/main_test.go +++ b/pkgtools/pkglint/files/main_test.go @@ -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 diff --git a/pkgtools/pkglint/files/mkline.go b/pkgtools/pkglint/files/mkline.go index 10b886d18d5..8b3bb1a8f58 100644 --- a/pkgtools/pkglint/files/mkline.go +++ b/pkgtools/pkglint/files/mkline.go @@ -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 doesn’t 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 { diff --git a/pkgtools/pkglint/files/mkline_test.go b/pkgtools/pkglint/files/mkline_test.go index ccbee10c3bb..31a75a2e264 100644 --- a/pkgtools/pkglint/files/mkline_test.go +++ b/pkgtools/pkglint/files/mkline_test.go @@ -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, "") // Don’t 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, "") // Don’t 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") // Don’t 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, "") // Don’t 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, "") // Don’t 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, "") // Don’t 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, "") // Don’t 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, "") // Don’t 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$", diff --git a/pkgtools/pkglint/files/mklines.go b/pkgtools/pkglint/files/mklines.go index 9735a2a93a7..df2ffbbaf24 100644 --- a/pkgtools/pkglint/files/mklines.go +++ b/pkgtools/pkglint/files/mklines.go @@ -303,6 +303,11 @@ func (va *VaralignBlock) fixalign(mkline *MkLine, prefix, oldalign string) { return } + // Don’t 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 diff --git a/pkgtools/pkglint/files/mklines_test.go b/pkgtools/pkglint/files/mklines_test.go index 22c8ff33613..e86fc71e2fc 100644 --- a/pkgtools/pkglint/files/mklines_test.go +++ b/pkgtools/pkglint/files/mklines_test.go @@ -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) +} diff --git a/pkgtools/pkglint/files/mkparser.go b/pkgtools/pkglint/files/mkparser.go index 3ddce64a869..ba7e141ac44 100644 --- a/pkgtools/pkglint/files/mkparser.go +++ b/pkgtools/pkglint/files/mkparser.go @@ -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) diff --git a/pkgtools/pkglint/files/mkshtypes.go b/pkgtools/pkglint/files/mkshtypes.go index 617ddced691..5349ddeb9fb 100644 --- a/pkgtools/pkglint/files/mkshtypes.go +++ b/pkgtools/pkglint/files/mkshtypes.go @@ -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 diff --git a/pkgtools/pkglint/files/mkshwalker.go b/pkgtools/pkglint/files/mkshwalker.go index 97c79becc0d..0d111c0b7a3 100644 --- a/pkgtools/pkglint/files/mkshwalker.go +++ b/pkgtools/pkglint/files/mkshwalker.go @@ -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 diff --git a/pkgtools/pkglint/files/package.go b/pkgtools/pkglint/files/package.go index bfc6104a42a..3f9204be4dd 100644 --- a/pkgtools/pkglint/files/package.go +++ b/pkgtools/pkglint/files/package.go @@ -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) diff --git a/pkgtools/pkglint/files/package_test.go b/pkgtools/pkglint/files/package_test.go index 6f8b16abd24..a7c77f37126 100644 --- a/pkgtools/pkglint/files/package_test.go +++ b/pkgtools/pkglint/files/package_test.go @@ -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, "") +} diff --git a/pkgtools/pkglint/files/parser_test.go b/pkgtools/pkglint/files/parser_test.go index ddb87dbbf08..f50288e214b 100644 --- a/pkgtools/pkglint/files/parser_test.go +++ b/pkgtools/pkglint/files/parser_test.go @@ -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,"))))) - -} diff --git a/pkgtools/pkglint/files/patches.go b/pkgtools/pkglint/files/patches.go index 7277de48d31..48359d17377 100644 --- a/pkgtools/pkglint/files/patches.go +++ b/pkgtools/pkglint/files/patches.go @@ -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 ( diff --git a/pkgtools/pkglint/files/patches_test.go b/pkgtools/pkglint/files/patches_test.go index 6758a09d3fc..935ab745ed4 100644 --- a/pkgtools/pkglint/files/patches_test.go +++ b/pkgtools/pkglint/files/patches_test.go @@ -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 doesn’t 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$", "", diff --git a/pkgtools/pkglint/files/pkglint.go b/pkgtools/pkglint/files/pkglint.go index e89aff7085c..4a1d643fe6e 100644 --- a/pkgtools/pkglint/files/pkglint.go +++ b/pkgtools/pkglint/files/pkglint.go @@ -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])) diff --git a/pkgtools/pkglint/files/pkglint_test.go b/pkgtools/pkglint/files/pkglint_test.go index 03a12d3013c..1fd91217441 100644 --- a/pkgtools/pkglint/files/pkglint_test.go +++ b/pkgtools/pkglint/files/pkglint_test.go @@ -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 doesn’t 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 shouldn’t.", 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", diff --git a/pkgtools/pkglint/files/plist_test.go b/pkgtools/pkglint/files/plist_test.go index 086d98311ac..3e295c643a2 100644 --- a/pkgtools/pkglint/files/plist_test.go +++ b/pkgtools/pkglint/files/plist_test.go @@ -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", diff --git a/pkgtools/pkglint/files/shell.go b/pkgtools/pkglint/files/shell.go index 57e4db3d59a..00b9faf8c64 100644 --- a/pkgtools/pkglint/files/shell.go +++ b/pkgtools/pkglint/files/shell.go @@ -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 diff --git a/pkgtools/pkglint/files/shell_test.go b/pkgtools/pkglint/files/shell_test.go index c4993e40940..f34629b460b 100644 --- a/pkgtools/pkglint/files/shell_test.go +++ b/pkgtools/pkglint/files/shell_test.go @@ -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) // Doesn’t 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\\\"`\"" diff --git a/pkgtools/pkglint/files/shtokenizer.go b/pkgtools/pkglint/files/shtokenizer.go index 68ee4557fc6..c585cf32b2e 100644 --- a/pkgtools/pkglint/files/shtokenizer.go +++ b/pkgtools/pkglint/files/shtokenizer.go @@ -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 diff --git a/pkgtools/pkglint/files/shtokenizer_test.go b/pkgtools/pkglint/files/shtokenizer_test.go index c2eef115eb1..1f7d35ce6d1 100644 --- a/pkgtools/pkglint/files/shtokenizer_test.go +++ b/pkgtools/pkglint/files/shtokenizer_test.go @@ -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), diff --git a/pkgtools/pkglint/files/shtypes.go b/pkgtools/pkglint/files/shtypes.go index b276919d434..bbdf2d42750 100644 --- a/pkgtools/pkglint/files/shtypes.go +++ b/pkgtools/pkglint/files/shtypes.go @@ -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 diff --git a/pkgtools/pkglint/files/substcontext_test.go b/pkgtools/pkglint/files/substcontext_test.go index 49654fba5ad..74ddf95adb6 100644 --- a/pkgtools/pkglint/files/substcontext_test.go +++ b/pkgtools/pkglint/files/substcontext_test.go @@ -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) diff --git a/pkgtools/pkglint/files/toplevel_test.go b/pkgtools/pkglint/files/toplevel_test.go index 9160bef32b6..74e14b64251 100644 --- a/pkgtools/pkglint/files/toplevel_test.go +++ b/pkgtools/pkglint/files/toplevel_test.go @@ -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"+ diff --git a/pkgtools/pkglint/files/tree_test.go b/pkgtools/pkglint/files/tree_test.go index d7d8716287a..f8240261b5b 100644 --- a/pkgtools/pkglint/files/tree_test.go +++ b/pkgtools/pkglint/files/tree_test.go @@ -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\"))") } diff --git a/pkgtools/pkglint/files/util.go b/pkgtools/pkglint/files/util.go index 4b8471f60df..347f4f05d6f 100644 --- a/pkgtools/pkglint/files/util.go +++ b/pkgtools/pkglint/files/util.go @@ -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) diff --git a/pkgtools/pkglint/files/util_test.go b/pkgtools/pkglint/files/util_test.go index 2e69b9cb796..9a091441e0e 100644 --- a/pkgtools/pkglint/files/util_test.go +++ b/pkgtools/pkglint/files/util_test.go @@ -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+`) diff --git a/pkgtools/pkglint/files/vardefs.go b/pkgtools/pkglint/files/vardefs.go index 98839ee809d..a1ce2d26f13 100644 --- a/pkgtools/pkglint/files/vardefs.go +++ b/pkgtools/pkglint/files/vardefs.go @@ -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) } }} } diff --git a/pkgtools/pkglint/files/vartype.go b/pkgtools/pkglint/files/vartype.go index bafba977eec..a5f8bd52959 100644 --- a/pkgtools/pkglint/files/vartype.go +++ b/pkgtools/pkglint/files/vartype.go @@ -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} diff --git a/pkgtools/pkglint/files/vartype_test.go b/pkgtools/pkglint/files/vartype_test.go index c4fbf490c7e..027590c2a3d 100644 --- a/pkgtools/pkglint/files/vartype_test.go +++ b/pkgtools/pkglint/files/vartype_test.go @@ -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") diff --git a/pkgtools/pkglint/files/vartypecheck.go b/pkgtools/pkglint/files/vartypecheck.go index 030c9f96a82..413169f9586 100644 --- a/pkgtools/pkglint/files/vartypecheck.go +++ b/pkgtools/pkglint/files/vartypecheck.go @@ -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() } } diff --git a/pkgtools/pkglint/files/vartypecheck_test.go b/pkgtools/pkglint/files/vartypecheck_test.go index 2893ec9fb07..74922a4c815 100644 --- a/pkgtools/pkglint/files/vartypecheck_test.go +++ b/pkgtools/pkglint/files/vartypecheck_test.go @@ -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) } } diff --git a/pkgtools/pkglint/files/vercmp_test.go b/pkgtools/pkglint/files/vercmp_test.go index 11edd40aab9..512fa7ef958 100644 --- a/pkgtools/pkglint/files/vercmp_test.go +++ b/pkgtools/pkglint/files/vercmp_test.go @@ -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"}, |