pkgtools/pkglint: update to 21.1.4
Changes since 21.1.3: Allow slash in Git tags like 'refs/tags/v1.0.0', as well as in make targets like 'subdir/build'.
This commit is contained in:
parent
6c5fbb1ac4
commit
c34b30ef10
11 changed files with 193 additions and 36 deletions
|
@ -1,6 +1,6 @@
|
|||
# $NetBSD: Makefile,v 1.687 2021/06/06 07:41:34 rillig Exp $
|
||||
# $NetBSD: Makefile,v 1.688 2021/06/06 11:46:43 rillig Exp $
|
||||
|
||||
PKGNAME= pkglint-21.1.3
|
||||
PKGNAME= pkglint-21.1.4
|
||||
CATEGORIES= pkgtools
|
||||
DISTNAME= tools
|
||||
MASTER_SITES= ${MASTER_SITE_GITHUB:=golang/}
|
||||
|
|
|
@ -25,7 +25,7 @@ func CheckdirCategory(dir CurrPath) {
|
|||
if mlex.SkipIf(func(mkline *MkLine) bool { return mkline.IsVarassign() && mkline.Varname() == "COMMENT" }) {
|
||||
mkline := mlex.PreviousMkLine()
|
||||
|
||||
valid := textproc.NewByteSet("--- '(),/0-9A-Za-z")
|
||||
valid := textproc.NewByteSet("- '(),/0-9A-Za-z")
|
||||
invalid := invalidCharacters(mkline.Value(), valid)
|
||||
if invalid != "" {
|
||||
mkline.Warnf("%s contains invalid characters (%s).",
|
||||
|
|
|
@ -67,7 +67,7 @@ type licenseLexer struct {
|
|||
error string
|
||||
}
|
||||
|
||||
var licenseNameChars = textproc.NewByteSet("A-Za-z0-9---._")
|
||||
var licenseNameChars = textproc.NewByteSet("A-Za-z0-9-._")
|
||||
|
||||
func (lexer *licenseLexer) Lex(llval *liyySymType) int {
|
||||
lex := lexer.lexer
|
||||
|
|
|
@ -152,11 +152,13 @@ func (ck *MkCondChecker) checkEmptyType(varuse *MkVarUse) {
|
|||
// mkCondStringLiteralUnquoted contains a safe subset of the characters
|
||||
// that may be used without surrounding quotes in a comparison such as
|
||||
// ${PKGPATH} == category/package.
|
||||
var mkCondStringLiteralUnquoted = textproc.NewByteSet("+---./0-9@A-Z_a-z")
|
||||
// TODO: Check whether the ',' really needs to be here.
|
||||
var mkCondStringLiteralUnquoted = textproc.NewByteSet("-+,./0-9@A-Z_a-z")
|
||||
|
||||
// mkCondModifierPatternLiteral contains a safe subset of the characters
|
||||
// that are interpreted literally in the :M and :N modifiers.
|
||||
var mkCondModifierPatternLiteral = textproc.NewByteSet("+---./0-9<=>@A-Z_a-z")
|
||||
// TODO: Check whether the ',' really needs to be here.
|
||||
var mkCondModifierPatternLiteral = textproc.NewByteSet("-+,./0-9<=>@A-Z_a-z")
|
||||
|
||||
// simplify replaces an unnecessarily complex condition with
|
||||
// a simpler condition that's still equivalent.
|
||||
|
|
|
@ -700,7 +700,7 @@ func (mkline *MkLine) RelMkLine(other *MkLine) string {
|
|||
}
|
||||
|
||||
var (
|
||||
LowerDash = textproc.NewByteSet("a-z---")
|
||||
LowerDash = textproc.NewByteSet("a-z-")
|
||||
AlnumDot = textproc.NewByteSet("A-Za-z0-9_.")
|
||||
unescapeMkCommentSafeChars = textproc.NewByteSet("\\#[\n").Inverse()
|
||||
)
|
||||
|
@ -1327,8 +1327,10 @@ func (ind *Indentation) CheckFinish(filename CurrPath) {
|
|||
// TODO: The allowed characters differ between the basename and the parameter
|
||||
// of the variable. The square bracket is only allowed in the parameter part.
|
||||
var (
|
||||
VarbaseBytes = textproc.NewByteSet("A-Za-z_0-9+---")
|
||||
VarparamBytes = textproc.NewByteSet("A-Za-z_0-9#*+---./[")
|
||||
// TODO: remove the ','
|
||||
VarbaseBytes = textproc.NewByteSet("A-Za-z_0-9-+,")
|
||||
// TODO: Check whether the ',' really needs to be here.
|
||||
VarparamBytes = textproc.NewByteSet("A-Za-z_0-9-#*+,./[")
|
||||
)
|
||||
|
||||
func MatchMkInclude(text string) (m bool, indentation, directive string, filename RelPath) {
|
||||
|
|
|
@ -240,8 +240,8 @@ func (l *Lexer) Copy() *Lexer { return &Lexer{l.rest} }
|
|||
func (l *Lexer) Commit(other *Lexer) bool { l.rest = other.rest; return true }
|
||||
|
||||
// NewByteSet creates a bit mask out of a string like "0-9A-Za-z_".
|
||||
// To add an actual hyphen to the bit mask, write it as "---"
|
||||
// (a range from hyphen to hyphen).
|
||||
// To add an actual hyphen to the bit mask, write it either at the beginning
|
||||
// or at the end of the string, or directly after a range like "a-z".
|
||||
//
|
||||
// The bit mask can be used with Lexer.NextBytesSet.
|
||||
func NewByteSet(chars string) *ByteSet {
|
||||
|
|
|
@ -359,18 +359,81 @@ func (s *Suite) Test_NewByteSet(c *check.C) {
|
|||
}
|
||||
|
||||
// Demonstrates how to specify a byte set that includes a hyphen,
|
||||
// since that is also used for byte ranges.
|
||||
// The hyphen must be written as ---, which is a range from hyphen to hyphen.
|
||||
func (s *Suite) Test_NewByteSet__range_hyphen(c *check.C) {
|
||||
// since that character is also used for byte ranges.
|
||||
// The hyphen is written as ---, which is a range from hyphen to hyphen.
|
||||
func (s *Suite) Test_NewByteSet__range_hyphen_beginning(c *check.C) {
|
||||
set := NewByteSet("---a-z")
|
||||
|
||||
expected := "abcdefghijklmnopqrstuvwxyz-"
|
||||
var actual strings.Builder
|
||||
for i := 0; i < 256; i++ {
|
||||
c.Check(
|
||||
set.Contains(byte(i)),
|
||||
equals,
|
||||
strings.IndexByte(expected, byte(i)) != -1)
|
||||
if set.Contains(byte(i)) {
|
||||
actual.WriteByte(byte(i))
|
||||
}
|
||||
}
|
||||
|
||||
c.Check(actual.String(), equals, "-abcdefghijklmnopqrstuvwxyz")
|
||||
}
|
||||
|
||||
// The byte set "x---a" is interpreted as 3 parts: "x--", "-", "a".
|
||||
//
|
||||
// The range "x--" is empty since U+0078 'x' comes later in Unicode than
|
||||
// U+002D '-'.
|
||||
func (s *Suite) Test_NewByteSet__range_hyphen_middle(c *check.C) {
|
||||
set := NewByteSet("x---a")
|
||||
|
||||
var actual strings.Builder
|
||||
for i := 0; i < 256; i++ {
|
||||
if set.Contains(byte(i)) {
|
||||
actual.WriteByte(byte(i))
|
||||
}
|
||||
}
|
||||
|
||||
c.Check(actual.String(), equals, "-a")
|
||||
}
|
||||
|
||||
// When a hyphen is listed at the very beginning, it is not considered part
|
||||
// of a byte range but interpreted literally.
|
||||
func (s *Suite) Test_NewByteSet__hyphen_beginning(c *check.C) {
|
||||
set := NewByteSet("-ax")
|
||||
|
||||
var actual strings.Builder
|
||||
for i := 0; i < 256; i++ {
|
||||
if set.Contains(byte(i)) {
|
||||
actual.WriteByte(byte(i))
|
||||
}
|
||||
}
|
||||
|
||||
c.Check(actual.String(), equals, "-ax")
|
||||
}
|
||||
|
||||
// When a hyphen is listed directly after a range ('+-+' in this case),
|
||||
// it is interpreted literally.
|
||||
func (s *Suite) Test_NewByteSet__hyphen_after_range(c *check.C) {
|
||||
set := NewByteSet("+-+-")
|
||||
|
||||
var actual strings.Builder
|
||||
for i := 0; i < 256; i++ {
|
||||
if set.Contains(byte(i)) {
|
||||
actual.WriteByte(byte(i))
|
||||
}
|
||||
}
|
||||
|
||||
c.Check(actual.String(), equals, "+-")
|
||||
}
|
||||
|
||||
// When a hyphen is listed at the very end, it is not considered part
|
||||
// of a byte range but interpreted literally.
|
||||
func (s *Suite) Test_NewByteSet__hyphen_end(c *check.C) {
|
||||
set := NewByteSet("ax-")
|
||||
|
||||
var actual strings.Builder
|
||||
for i := 0; i < 256; i++ {
|
||||
if set.Contains(byte(i)) {
|
||||
actual.WriteByte(byte(i))
|
||||
}
|
||||
}
|
||||
|
||||
c.Check(actual.String(), equals, "-ax")
|
||||
}
|
||||
|
||||
func (s *Suite) Test_ByteSet_Inverse(c *check.C) {
|
||||
|
|
|
@ -1032,8 +1032,8 @@ func (reg *VarTypeRegistry) Init(src *Pkgsrc) {
|
|||
reg.pkglist("BUILD_ENV", BtShellWord)
|
||||
reg.sys("BUILD_MAKE_CMD", BtShellCommand)
|
||||
reg.pkglist("BUILD_MAKE_FLAGS", BtShellWord)
|
||||
reg.pkglist("BUILD_TARGET", BtIdentifierIndirect)
|
||||
reg.pkglist("BUILD_TARGET.*", BtIdentifierIndirect)
|
||||
reg.pkglist("BUILD_TARGET", BtMakeTarget)
|
||||
reg.pkglist("BUILD_TARGET.*", BtMakeTarget)
|
||||
reg.pkg("BUILD_USES_MSGFMT", BtYes)
|
||||
reg.acl("BUILTIN_PKG", BtIdentifierDirect,
|
||||
PackageSettable,
|
||||
|
@ -1143,12 +1143,12 @@ func (reg *VarTypeRegistry) Init(src *Pkgsrc) {
|
|||
reg.pkg("DISTNAME", BtFilename)
|
||||
reg.pkg("DIST_SUBDIR", BtPathname)
|
||||
reg.pkglist("DJB_BUILD_ARGS", BtShellWord)
|
||||
reg.pkglist("DJB_BUILD_TARGETS", BtIdentifierIndirect)
|
||||
reg.pkglist("DJB_BUILD_TARGETS", BtMakeTarget)
|
||||
reg.pkgappend("DJB_CONFIG_CMDS", BtShellCommands)
|
||||
reg.pkglist("DJB_CONFIG_DIRS", BtWrksrcSubdirectory)
|
||||
reg.pkg("DJB_CONFIG_HOME", BtFilename)
|
||||
reg.pkg("DJB_CONFIG_PREFIX", BtPathname)
|
||||
reg.pkglist("DJB_INSTALL_TARGETS", BtIdentifierIndirect)
|
||||
reg.pkglist("DJB_INSTALL_TARGETS", BtMakeTarget)
|
||||
reg.pkg("DJB_MAKE_TARGETS", BtYesNo)
|
||||
reg.pkg("DJB_RESTRICTED", BtYesNo)
|
||||
reg.pkg("DJB_SLASHPACKAGE", BtYesNo)
|
||||
|
@ -1230,7 +1230,7 @@ func (reg *VarTypeRegistry) Init(src *Pkgsrc) {
|
|||
reg.pkglistbl3rat("GCC_REQD", BtGccReqd)
|
||||
reg.pkgappend("GENERATE_PLIST", BtShellCommands)
|
||||
reg.pkg("GITHUB_PROJECT", BtIdentifierIndirect)
|
||||
reg.pkg("GITHUB_TAG", BtIdentifierIndirect)
|
||||
reg.pkg("GITHUB_TAG", BtGitTag)
|
||||
reg.pkg("GITHUB_RELEASE", BtFilename)
|
||||
reg.pkg("GITHUB_TYPE", enum("tag release"))
|
||||
reg.pkgrat("GMAKE_REQD", BtVersion)
|
||||
|
@ -1282,7 +1282,7 @@ func (reg *VarTypeRegistry) Init(src *Pkgsrc) {
|
|||
reg.syslist("INSTALL_SCRIPTS_ENV", BtShellWord)
|
||||
reg.sys("INSTALL_SCRIPT_DIR", BtShellCommand)
|
||||
reg.pkglist("INSTALL_SRC", BtPathname)
|
||||
reg.pkglist("INSTALL_TARGET", BtIdentifierIndirect)
|
||||
reg.pkglist("INSTALL_TARGET", BtMakeTarget)
|
||||
reg.pkglist("INSTALL_TEMPLATES", BtPathname)
|
||||
reg.pkgload("INSTALL_UNSTRIPPED", BtYesNo)
|
||||
reg.pkglist("INTERACTIVE_STAGE", enum("fetch extract configure build test install"))
|
||||
|
@ -1729,7 +1729,7 @@ func (reg *VarTypeRegistry) Init(src *Pkgsrc) {
|
|||
reg.pkglist("TEST_DEPENDS", BtDependencyWithPath)
|
||||
reg.pkglist("TEST_DIRS", BtWrksrcSubdirectory)
|
||||
reg.pkglist("TEST_ENV", BtShellWord)
|
||||
reg.pkglist("TEST_TARGET", BtIdentifierIndirect)
|
||||
reg.pkglist("TEST_TARGET", BtMakeTarget)
|
||||
reg.pkglistrat("TEXINFO_REQD", BtVersion)
|
||||
reg.pkglistbl3("TOOL_DEPENDS", BtDependencyWithPath)
|
||||
reg.syslist("TOOLS_ALIASES", BtFilename)
|
||||
|
|
|
@ -358,6 +358,7 @@ func (bt *BasicType) NeedsQ() bool {
|
|||
BtEmulPlatform,
|
||||
BtFileMode,
|
||||
BtFilename,
|
||||
BtGitTag,
|
||||
BtIdentifierDirect,
|
||||
BtIdentifierIndirect,
|
||||
BtInteger,
|
||||
|
@ -428,6 +429,7 @@ var (
|
|||
BtFilePattern = &BasicType{"FilePattern", (*VartypeCheck).FilePattern}
|
||||
BtFileMode = &BasicType{"FileMode", (*VartypeCheck).FileMode}
|
||||
BtGccReqd = &BasicType{"GccReqd", (*VartypeCheck).GccReqd}
|
||||
BtGitTag = &BasicType{"GitTag", (*VartypeCheck).GitTag}
|
||||
BtHomepage = &BasicType{"Homepage", (*VartypeCheck).Homepage}
|
||||
BtIdentifierDirect = &BasicType{"Identifier", (*VartypeCheck).IdentifierDirect}
|
||||
BtIdentifierIndirect = &BasicType{"Identifier", (*VartypeCheck).IdentifierIndirect}
|
||||
|
@ -438,6 +440,7 @@ var (
|
|||
BtMachinePlatform = &BasicType{"MachinePlatform", (*VartypeCheck).MachinePlatform}
|
||||
BtMachinePlatformPattern = &BasicType{"MachinePlatformPattern", (*VartypeCheck).MachinePlatformPattern}
|
||||
BtMailAddress = &BasicType{"MailAddress", (*VartypeCheck).MailAddress}
|
||||
BtMakeTarget = &BasicType{"MakeTarget", (*VartypeCheck).MakeTarget}
|
||||
BtMessage = &BasicType{"Message", (*VartypeCheck).Message}
|
||||
BtOption = &BasicType{"Option", (*VartypeCheck).Option}
|
||||
BtPathlist = &BasicType{"Pathlist", (*VartypeCheck).Pathlist}
|
||||
|
|
|
@ -21,7 +21,7 @@ type VartypeCheck struct {
|
|||
Varname string
|
||||
Op MkOperator
|
||||
Value string
|
||||
ValueNoVar string
|
||||
ValueNoVar string // The Value with all expressions removed.
|
||||
MkComment string // The comment including the "#".
|
||||
Guessed bool // Whether the type definition is guessed (based on the variable name) or explicitly defined (see vardefs.go).
|
||||
}
|
||||
|
@ -676,6 +676,29 @@ func (cv *VartypeCheck) GccReqd() {
|
|||
}
|
||||
}
|
||||
|
||||
// GitTag checks for a fixed reference to a Git commit.
|
||||
//
|
||||
// https://git-scm.com/docs/gitrevisions
|
||||
func (cv *VartypeCheck) GitTag() {
|
||||
tag := cv.ValueNoVar
|
||||
|
||||
valid := textproc.NewByteSet("0-9A-Za-z-+._/")
|
||||
invalid := invalidCharacters(tag, valid)
|
||||
if invalid != "" {
|
||||
cv.Warnf("Invalid characters %q in Git tag.", invalid)
|
||||
return
|
||||
}
|
||||
|
||||
if tag == "master" || hasPrefix(tag, "refs/heads/") {
|
||||
cv.Warnf("The Git tag %q refers to a moving target.", tag)
|
||||
return
|
||||
}
|
||||
|
||||
if len(tag) < 7 && matches(tag, `^[A-Fa-f0-9]+$`) {
|
||||
cv.Warnf("The git commit name %q is too short to be reliable.", tag)
|
||||
}
|
||||
}
|
||||
|
||||
func (cv *VartypeCheck) Homepage() {
|
||||
cv.URL()
|
||||
|
||||
|
@ -683,8 +706,8 @@ func (cv *VartypeCheck) Homepage() {
|
|||
ck.Check()
|
||||
}
|
||||
|
||||
// Identifier checks for valid identifiers in various contexts, limiting the
|
||||
// valid characters to A-Za-z0-9_.
|
||||
// IdentifierDirect checks for valid identifiers in various contexts,
|
||||
// limiting the valid characters to A-Za-z0-9_.
|
||||
func (cv *VartypeCheck) IdentifierDirect() {
|
||||
if cv.Op == opUseMatch {
|
||||
if cv.Value == cv.ValueNoVar && !matches(cv.Value, `^[\w*\-?\[\]]+$`) {
|
||||
|
@ -703,8 +726,8 @@ func (cv *VartypeCheck) IdentifierDirect() {
|
|||
}
|
||||
}
|
||||
|
||||
// Identifier checks for valid identifiers in various contexts, limiting the
|
||||
// valid characters to A-Za-z0-9_.
|
||||
// IdentifierIndirect checks for valid identifiers in various contexts,
|
||||
// limiting the valid characters to A-Za-z0-9_.
|
||||
func (cv *VartypeCheck) IdentifierIndirect() {
|
||||
if cv.Value == cv.ValueNoVar {
|
||||
cv.IdentifierDirect()
|
||||
|
@ -847,6 +870,16 @@ func (cv *VartypeCheck) MailAddress() {
|
|||
}
|
||||
}
|
||||
|
||||
func (cv *VartypeCheck) MakeTarget() {
|
||||
if cv.Op == opUseMatch || cv.ValueNoVar != cv.Value {
|
||||
return
|
||||
}
|
||||
|
||||
if !matches(cv.ValueNoVar, `^[+\-.\w/]+$`) {
|
||||
cv.Warnf("Invalid make target %q.", cv.Value)
|
||||
}
|
||||
}
|
||||
|
||||
// Message is a plain string. When defining a message variable, it should
|
||||
// not be enclosed in quotes since that is the job of the code that uses
|
||||
// the message.
|
||||
|
@ -980,8 +1013,9 @@ func (cv *VartypeCheck) Pathname() {
|
|||
invalid)
|
||||
}
|
||||
|
||||
// Like Pathname, but may contain spaces as well.
|
||||
// Because the spaces must be quoted, backslashes and quotes are allowed as well.
|
||||
// PathnameSpace is like Pathname, but may contain spaces as well.
|
||||
// Because the spaces must be quoted, backslashes and quotes are allowed as
|
||||
// well.
|
||||
func (cv *VartypeCheck) PathnameSpace() {
|
||||
valid := regex.Pattern(condStr(
|
||||
cv.Op == opUseMatch,
|
||||
|
@ -1108,7 +1142,7 @@ func (cv *VartypeCheck) PlistIdentifier() {
|
|||
}
|
||||
|
||||
if cv.Op == opUseMatch {
|
||||
invalidPatternChars := textproc.NewByteSet("A-Za-z0-9---_*?[]")
|
||||
invalidPatternChars := textproc.NewByteSet("A-Za-z0-9-_*?[]")
|
||||
invalid := invalidCharacters(cond, invalidPatternChars)
|
||||
if invalid != "" {
|
||||
cv.Warnf("PLIST identifier pattern %q contains invalid characters (%s).",
|
||||
|
@ -1120,7 +1154,7 @@ func (cv *VartypeCheck) PlistIdentifier() {
|
|||
return
|
||||
}
|
||||
|
||||
invalidChars := textproc.NewByteSet("A-Za-z0-9---_")
|
||||
invalidChars := textproc.NewByteSet("A-Za-z0-9-_")
|
||||
invalid := invalidCharacters(cond, invalidChars)
|
||||
if invalid != "" {
|
||||
cv.Errorf("PLIST identifier %q contains invalid characters (%s).",
|
||||
|
@ -1448,7 +1482,7 @@ func (cv *VartypeCheck) UserGroupName() {
|
|||
if value != cv.ValueNoVar {
|
||||
return
|
||||
}
|
||||
invalid := invalidCharacters(value, textproc.NewByteSet("---0-9_a-z"))
|
||||
invalid := invalidCharacters(value, textproc.NewByteSet("-0-9_a-z"))
|
||||
if invalid != "" {
|
||||
cv.Warnf("User or group name %q contains invalid characters: %s",
|
||||
value, invalid)
|
||||
|
|
|
@ -1126,6 +1126,32 @@ func (s *Suite) Test_VartypeCheck_GccReqd(c *check.C) {
|
|||
"WARN: filename.mk:7: GCC version numbers should only contain the major version (7).")
|
||||
}
|
||||
|
||||
func (s *Suite) Test_VartypeCheck_GitTag(c *check.C) {
|
||||
vt := NewVartypeCheckTester(s.Init(c), BtGitTag)
|
||||
|
||||
vt.Varname("GITHUB_TAG")
|
||||
vt.Values(
|
||||
"master", // Bad since it is a moving target.
|
||||
"v1.2.3",
|
||||
"refs/heads/devel", // Bad since it is a moving target.
|
||||
"refs/tags/v1.2.3",
|
||||
"v${PKGVERSION_NOREV}",
|
||||
"1234567812345678123456781234567812345678",
|
||||
"1234567",
|
||||
"123456", // Too short in practice.
|
||||
"${DISTNAME}",
|
||||
"invalid:char", // Bad since ':' is not supported.
|
||||
"invalid:;char", // Bad since neither ':' nor ';' is supported.
|
||||
"jdk-11.0.10+9-1",
|
||||
)
|
||||
vt.Output(
|
||||
"WARN: filename.mk:1: The Git tag \"master\" refers to a moving target.",
|
||||
"WARN: filename.mk:3: The Git tag \"refs/heads/devel\" refers to a moving target.",
|
||||
"WARN: filename.mk:8: The git commit name \"123456\" is too short to be reliable.",
|
||||
"WARN: filename.mk:10: Invalid characters \":\" in Git tag.",
|
||||
"WARN: filename.mk:11: Invalid characters \": ;\" in Git tag.")
|
||||
}
|
||||
|
||||
func (s *Suite) Test_VartypeCheck_Homepage(c *check.C) {
|
||||
t := s.Init(c)
|
||||
vt := NewVartypeCheckTester(t, BtHomepage)
|
||||
|
@ -1448,6 +1474,33 @@ func (s *Suite) Test_VartypeCheck_MailAddress(c *check.C) {
|
|||
"WARN: filename.mk:4: \"user1@example.org,user2@example.org\" is not a valid mail address.")
|
||||
}
|
||||
|
||||
func (s *Suite) Test_VartypeCheck_MakeTarget(c *check.C) {
|
||||
t := s.Init(c)
|
||||
vt := NewVartypeCheckTester(t, BtMakeTarget)
|
||||
|
||||
vt.Varname("BUILD_TARGET")
|
||||
vt.Values(
|
||||
"${OTHER_VAR}",
|
||||
"spaces in target lists are ok",
|
||||
"target/may/contain/slashes",
|
||||
"target:must:not:contain:colons",
|
||||
"id-${OTHER_VAR}",
|
||||
"")
|
||||
|
||||
vt.Output(
|
||||
"WARN: filename.mk:4: Invalid make target " +
|
||||
"\"target:must:not:contain:colons\".")
|
||||
|
||||
vt.Op(opUseMatch)
|
||||
vt.Values(
|
||||
"[A-Z]",
|
||||
"[A-Z.]",
|
||||
"${PKG_OPTIONS:Moption}",
|
||||
"A*B")
|
||||
|
||||
vt.OutputEmpty()
|
||||
}
|
||||
|
||||
func (s *Suite) Test_VartypeCheck_Message(c *check.C) {
|
||||
vt := NewVartypeCheckTester(s.Init(c), BtMessage)
|
||||
|
||||
|
|
Loading…
Reference in a new issue