pkgsrc-ng/pkgtools/pkglint/files/mklines_test.go
2016-11-18 22:39:22 +01:00

416 lines
13 KiB
Go

package main
import (
check "gopkg.in/check.v1"
)
const mkrcsid = "# $" + "NetBSD$"
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,
"# $"+"NetBSD$",
".if defined(A)",
".for a in ${A}",
".if defined(C)",
".endif",
".endfor",
".endif")
mklines.Check()
c.Check(s.Output(), equals, ""+
"AUTOFIX: ~/fname.mk:3: Replacing \".\" with \". \".\n"+
"AUTOFIX: ~/fname.mk:4: Replacing \".\" with \". \".\n"+
"AUTOFIX: ~/fname.mk:5: Replacing \".\" with \". \".\n"+
"AUTOFIX: ~/fname.mk:6: Replacing \".\" with \". \".\n"+
"AUTOFIX: ~/fname.mk: Has been auto-fixed. Please re-run pkglint.\n")
c.Check(s.LoadTmpFile(c, "fname.mk"), equals, ""+
"# $"+"NetBSD$\n"+
".if defined(A)\n"+
". for a in ${A}\n"+
". if defined(C)\n"+
". endif\n"+
". endfor\n"+
".endif\n")
}
func (s *Suite) Test_MkLines_Check__unusual_target(c *check.C) {
mklines := s.NewMkLines("Makefile",
"# $"+"NetBSD$",
"",
"echo: echo.c",
"\tcc -o ${.TARGET} ${.IMPSRC}")
mklines.Check()
c.Check(s.Output(), equals, "WARN: Makefile:3: Unusual target \"echo\".\n")
}
func (s *Suite) Test_MkLine_checklineInclude_Makefile(c *check.C) {
mkline := NewMkLine(NewLine("Makefile", 2, ".include \"../../other/package/Makefile\"", nil))
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) Test_MkLines_quoting_LDFLAGS_for_GNU_configure(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
G.Pkg = NewPackage("category/pkgbase")
mklines := s.NewMkLines("Makefile",
"# $"+"NetBSD$",
"GNU_CONFIGURE=\tyes",
"CONFIGURE_ENV+=\tX_LIBS=${X11_LDFLAGS:Q}")
mklines.Check()
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__variable_alignment_advanced(c *check.C) {
s.UseCommandLine(c, "-Wspace")
fname := s.CreateTmpFileLines(c, "Makefile",
"# $"+"NetBSD$",
"",
"VAR= \\", // In continuation lines, indenting with spaces is ok
"\tvalue",
"",
"VAR= indented with one space", // Exactly one space is ok in general
"VAR= indented with two spaces", // Two spaces are uncommon
"",
"BLOCK=\tindented with tab",
"BLOCK_LONGVAR= indented with space", // This is ok, to prevent the block from being indented further
"",
"BLOCK=\tshort",
"BLOCK_LONGVAR=\tlong",
"",
"GRP_A= avalue", // The values in a block should be aligned
"GRP_AA= value",
"GRP_AAA= value",
"GRP_AAAA= value",
"",
"VAR=\t${VAR}${BLOCK}${BLOCK_LONGVAR} # suppress warnings about unused variables",
"VAR=\t${GRP_A}${GRP_AA}${GRP_AAA}${GRP_AAAA}")
mklines := NewMkLines(LoadExistingLines(fname, true))
mklines.Check()
c.Check(s.Output(), equals, ""+
"NOTE: ~/Makefile:6: This variable value should be aligned with tabs, not spaces, to column 9.\n"+
"NOTE: ~/Makefile:7: This variable value should be aligned with tabs, not spaces, to column 9.\n"+
"NOTE: ~/Makefile:12: This variable value should be aligned to column 17.\n"+
"NOTE: ~/Makefile:15: This variable value should be aligned with tabs, not spaces, to column 17.\n"+
"NOTE: ~/Makefile:16: This variable value should be aligned with tabs, not spaces, to column 17.\n"+
"NOTE: ~/Makefile:17: This variable value should be aligned with tabs, not spaces, to column 17.\n"+
"NOTE: ~/Makefile:18: This variable value should be aligned with tabs, not spaces, to column 17.\n")
s.UseCommandLine(c, "-Wspace", "--autofix")
mklines.Check()
c.Check(s.Output(), equals, ""+
"AUTOFIX: ~/Makefile:6: Replacing \"VAR= \" with \"VAR=\\t\".\n"+
"AUTOFIX: ~/Makefile:7: Replacing \"VAR= \" with \"VAR=\\t\".\n"+
"AUTOFIX: ~/Makefile:12: Replacing \"BLOCK=\\t\" with \"BLOCK=\\t\\t\".\n"+
"AUTOFIX: ~/Makefile:15: Replacing \"GRP_A= \" with \"GRP_A=\\t\\t\".\n"+
"AUTOFIX: ~/Makefile:16: Replacing \"GRP_AA= \" with \"GRP_AA=\\t\\t\".\n"+
"AUTOFIX: ~/Makefile:17: Replacing \"GRP_AAA= \" with \"GRP_AAA=\\t\".\n"+
"AUTOFIX: ~/Makefile:18: Replacing \"GRP_AAAA= \" with \"GRP_AAAA=\\t\".\n"+
"AUTOFIX: ~/Makefile: Has been auto-fixed. Please re-run pkglint.\n")
c.Check(s.LoadTmpFile(c, "Makefile"), equals, ""+
"# $"+"NetBSD$\n"+
"\n"+
"VAR= \\\n"+
"\tvalue\n"+
"\n"+
"VAR=\tindented with one space\n"+
"VAR=\tindented with two spaces\n"+
"\n"+
"BLOCK=\tindented with tab\n"+
"BLOCK_LONGVAR= indented with space\n"+
"\n"+
"BLOCK=\t\tshort\n"+
"BLOCK_LONGVAR=\tlong\n"+
"\n"+
"GRP_A=\t\tavalue\n"+
"GRP_AA=\t\tvalue\n"+
"GRP_AAA=\tvalue\n"+
"GRP_AAAA=\tvalue\n"+
"\n"+
"VAR=\t${VAR}${BLOCK}${BLOCK_LONGVAR} # suppress warnings about unused variables\n"+
"VAR=\t${GRP_A}${GRP_AA}${GRP_AAA}${GRP_AAAA}\n")
}
func (s *Suite) Test_MkLines__variable_alignment_space_and_tab(c *check.C) {
s.UseCommandLine(c, "-Wspace")
mklines := s.NewMkLines("Makefile",
"# $"+"NetBSD$",
"",
"VAR= space",
"VAR=\ttab ${VAR}")
mklines.Check()
c.Check(s.Output(), equals, "NOTE: Makefile:3: Variable values should be aligned with tabs, not spaces.\n")
}
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})
s.RegisterTool(&Tool{Name: "pax", Varname: "PAX", Predefined: true})
mklines := s.NewMkLines("audio/squeezeboxserver/Makefile",
"# $"+"NetBSD$",
"",
".for _list_ _dir_ in ${SBS_COPY}",
"\tcd ${WRKSRC} && ${FIND} ${${_list_}} -type f ! -name '*.orig' 2>/dev/null "+
"| pax -rw -pm ${DESTDIR}${PREFIX}/${${_dir_}}",
".endfor")
mklines.Check()
c.Check(s.Output(), equals, ""+
"WARN: audio/squeezeboxserver/Makefile:3: Variable names starting with an underscore (_list_) are reserved for internal pkgsrc use.\n"+
"WARN: audio/squeezeboxserver/Makefile:3: Variable names starting with an underscore (_dir_) are reserved for internal pkgsrc use.\n"+
"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__comparing_YesNo_variable_to_string(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("databases/gdbm_compat/builtin.mk",
"# $"+"NetBSD$",
".if ${USE_BUILTIN.gdbm} == \"no\"",
".endif")
mklines.Check()
c.Check(s.Output(), equals, "WARN: databases/gdbm_compat/builtin.mk:2: "+
"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) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("lang/qore/module.mk",
"# $"+"NetBSD$",
"qore-version=\tqore --short-version | ${SED} -e s/-.*//",
"PLIST_SUBST+=\tQORE_VERSION=\"${qore-version:sh}\"")
vars2 := mklines.mklines[1].determineUsedVariables()
c.Check(vars2, deepEquals, []string{"SED"})
vars3 := mklines.mklines[2].determineUsedVariables()
c.Check(vars3, deepEquals, []string{"qore-version"})
mklines.Check()
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) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("converters/wv2/Makefile",
"# $"+"NetBSD$",
"CONFIGURE_ARGS+=\t\t${CONFIGURE_ARGS.${ICONV_TYPE}-iconv}",
"CONFIGURE_ARGS.gnu-iconv=\t--with-libiconv=${BUILDLINK_PREFIX.iconv}")
mklines.Check()
c.Check(s.Output(), equals, "") // No warnings about defined but not used or vice versa
}
func (s *Suite) Test_MkLines__loop_modifier(c *check.C) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("chat/xchat/Makefile",
"# $"+"NetBSD$",
"GCONF_SCHEMAS=\tapps_xchat_url_handler.schemas",
"post-install:",
"\t${GCONF_SCHEMAS:@.s.@"+
"${INSTALL_DATA} ${WRKSRC}/src/common/dbus/${.s.} ${DESTDIR}${GCONF_SCHEMAS_DIR}/@}")
mklines.Check()
c.Check(s.Output(), equals, ""+ // No warning about missing @ at the end
"WARN: chat/xchat/Makefile:4: Unknown shell command \"${GCONF_SCHEMAS:@.s.@"+
"${INSTALL_DATA} ${WRKSRC}/src/common/dbus/${.s.} ${DESTDIR}${GCONF_SCHEMAS_DIR}/@}\".\n")
}
// PR 46570
func (s *Suite) Test_MkLines__PKG_SKIP_REASON_depending_on_OPSYS(c *check.C) {
G.globalData.InitVartypes()
mklines := s.NewMkLines("Makefile",
"# $"+"NetBSD$",
"PKG_SKIP_REASON+=\t\"Fails everywhere\"",
".if ${OPSYS} == \"Cygwin\"",
"PKG_SKIP_REASON+=\t\"Fails on Cygwin\"",
".endif")
mklines.Check()
c.Check(s.Output(), equals, "NOTE: Makefile:4: Consider defining NOT_FOR_PLATFORM instead of setting PKG_SKIP_REASON depending on ${OPSYS}.\n")
}
// PR 46570, item "15. net/uucp/Makefile has a make loop"
func (s *Suite) Test_MkLines__indirect_variables(c *check.C) {
s.UseCommandLine(c, "-Wall")
mklines := s.NewMkLines("net/uucp/Makefile",
"# $"+"NetBSD$",
"",
"post-configure:",
".for var in MAIL_PROGRAM CMDPATH",
"\t"+`${RUN} ${ECHO} "#define ${var} \""${UUCP_${var}}"\"`,
".endfor")
mklines.Check()
// No warning about UUCP_${var} being used but not defined.
c.Check(s.Output(), equals, ""+
"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) {
s.UseCommandLine(c, "-Wall")
mklines := s.NewMkLines("converters/chef/Makefile",
mkrcsid,
"\tcd ${WRKSRC} && tr '\\r' '\\n' < ${DISTDIR}/${DIST_SUBDIR}/${DISTFILES} > chef.l")
mklines.Check()
c.Check(s.Output(), equals, ""+
"WARN: converters/chef/Makefile:2: Unknown shell command \"tr\".\n"+
"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) {
s.UseCommandLine(c, "-Wall")
G.globalData.InitVartypes()
mklines := s.NewMkLines("games/heretic2-demo/Makefile",
mkrcsid,
".if ${OPSYS} == \"DragonFly\"",
"TOOLS_PLATFORM.gtar=\t/usr/bin/bsdtar",
".endif",
"TOOLS_PLATFORM.gtar=\t/usr/bin/bsdtar")
mklines.Check()
// No warning about an unknown shell command in line 3,
// since that line depends on OPSYS.
c.Check(s.Output(), equals, ""+
"WARN: games/heretic2-demo/Makefile:3: The variable TOOLS_PLATFORM.gtar may not be set by any package.\n"+
"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)
}
func (s *Suite) Test_MkLines_PrivateTool_Undefined(c *check.C) {
G.globalData.InitVartypes()
s.UseCommandLine(c, "-Wall")
mklines := s.NewMkLines("fname",
mkrcsid,
"",
"\tmd5sum filename")
mklines.Check()
c.Check(s.Output(), equals, "WARN: fname:3: Unknown shell command \"md5sum\".\n")
}
func (s *Suite) Test_MkLines_PrivateTool_Defined(c *check.C) {
G.globalData.InitVartypes()
s.UseCommandLine(c, "-Wall")
mklines := s.NewMkLines("fname",
mkrcsid,
"TOOLS_CREATE+=\tmd5sum",
"",
"\tmd5sum filename")
mklines.Check()
c.Check(s.Output(), equals, "")
}