summaryrefslogtreecommitdiff
path: root/pkgtools/pkglint/files
diff options
context:
space:
mode:
authorrillig <rillig@pkgsrc.org>2019-10-11 23:30:02 +0000
committerrillig <rillig@pkgsrc.org>2019-10-11 23:30:02 +0000
commit2a28b9e77e403bd660aaddfe3dea82e97ebce454 (patch)
tree03901c64a755987afeafa9511a21eb8d03c22539 /pkgtools/pkglint/files
parent48fc847f144f16508925c278730e668f02b58904 (diff)
downloadpkgsrc-2a28b9e77e403bd660aaddfe3dea82e97ebce454.tar.gz
pkgtools/pkglint: update to 19.3.1
Changes since 19.3.0: * In buildlink3.mk files, the package identifier doesn't have to match the PKGBASE from the package Makefile exactly. The PKGBASE may have a leading "lib" (for libiconv and libgettext), as well as a trailing number (for emacs20 and netatalk22). * GITHUB_RELEASE is added to the variables that should appear in a fixed order in the package Makefile. * In the MASTER_SITE URLs, the transport protocol is irrelevant for matching direct URLs to the predefined MASTER_SITE_* variables.
Diffstat (limited to 'pkgtools/pkglint/files')
-rw-r--r--pkgtools/pkglint/files/buildlink3.go29
-rw-r--r--pkgtools/pkglint/files/buildlink3_test.go65
-rw-r--r--pkgtools/pkglint/files/mkshparser_test.go112
-rw-r--r--pkgtools/pkglint/files/package.go2
-rw-r--r--pkgtools/pkglint/files/pkgsrc.go4
-rw-r--r--pkgtools/pkglint/files/pkgsrc_test.go10
-rw-r--r--pkgtools/pkglint/files/shell.y2
-rw-r--r--pkgtools/pkglint/files/vartypecheck.go28
-rw-r--r--pkgtools/pkglint/files/vartypecheck_test.go24
9 files changed, 242 insertions, 34 deletions
diff --git a/pkgtools/pkglint/files/buildlink3.go b/pkgtools/pkglint/files/buildlink3.go
index 7125f2683c4..c8ee205dd27 100644
--- a/pkgtools/pkglint/files/buildlink3.go
+++ b/pkgtools/pkglint/files/buildlink3.go
@@ -119,8 +119,6 @@ func (ck *Buildlink3Checker) checkUniquePkgbase(pkgbase string, mkline *MkLine)
// introduces the uppercase package identifier.
func (ck *Buildlink3Checker) checkSecondParagraph(mlex *MkLinesLexer) bool {
pkgbase := ck.pkgbase
- pkgbaseLine := ck.pkgbaseLine
-
m := mlex.NextRegexp(`^\.if !defined\(([^\t ]+)_BUILDLINK3_MK\)$`)
if m == nil {
return false
@@ -136,18 +134,31 @@ func (ck *Buildlink3Checker) checkSecondParagraph(mlex *MkLinesLexer) bool {
ucPkgbase := strings.ToUpper(strings.Replace(pkgbase, "-", "_", -1))
if ucPkgbase != pkgupper && !containsVarRef(pkgbase) {
pkgupperLine.Errorf("Package name mismatch between multiple-inclusion guard %q (expected %q) and package name %q (from %s).",
- pkgupper, ucPkgbase, pkgbase, pkgupperLine.RefTo(pkgbaseLine))
- }
- if G.Pkg != nil {
- if mkbase := G.Pkg.EffectivePkgbase; mkbase != "" && mkbase != pkgbase {
- pkgbaseLine.Errorf("Package name mismatch between %q in this file and %q from %s.",
- pkgbase, mkbase, pkgbaseLine.RefTo(G.Pkg.EffectivePkgnameLine))
- }
+ pkgupper, ucPkgbase, pkgbase, pkgupperLine.RefTo(ck.pkgbaseLine))
}
+ ck.checkPkgbaseMismatch(pkgbase)
return true
}
+func (ck *Buildlink3Checker) checkPkgbaseMismatch(bl3base string) {
+ if G.Pkg == nil {
+ return
+ }
+
+ mkbase := G.Pkg.EffectivePkgbase
+ if mkbase == "" || mkbase == bl3base || strings.TrimPrefix(mkbase, "lib") == bl3base {
+ return
+ }
+
+ if hasPrefix(mkbase, bl3base) && matches(mkbase[len(bl3base):], `^\d+$`) {
+ return
+ }
+
+ ck.pkgbaseLine.Errorf("Package name mismatch between %q in this file and %q from %s.",
+ bl3base, mkbase, ck.pkgbaseLine.RefTo(G.Pkg.EffectivePkgnameLine))
+}
+
// Third paragraph: Package information.
func (ck *Buildlink3Checker) checkMainPart(mlex *MkLinesLexer) bool {
pkgbase := ck.pkgbase
diff --git a/pkgtools/pkglint/files/buildlink3_test.go b/pkgtools/pkglint/files/buildlink3_test.go
index 17d7d86cce8..c2e50d5e122 100644
--- a/pkgtools/pkglint/files/buildlink3_test.go
+++ b/pkgtools/pkglint/files/buildlink3_test.go
@@ -164,6 +164,71 @@ func (s *Suite) Test_CheckLinesBuildlink3Mk__name_mismatch__Perl(c *check.C) {
t.CheckOutputEmpty()
}
+func (s *Suite) Test_CheckLinesBuildlink3Mk__name_mismatch__lib(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("converters/libiconv")
+ t.CreateFileLines("converters/libiconv/buildlink3.mk",
+ MkCvsID,
+ "",
+ "BUILDLINK_TREE+=\ticonv",
+ "",
+ ".if !defined(ICONV_BUILDLINK3_MK)",
+ "ICONV_BUILDLINK3_MK:=",
+ "",
+ "BUILDLINK_API_DEPENDS.iconv+=\tlibiconv>=1.0",
+ "BUILDLINK_ABI_DEPENDS.iconv+=\tlibiconv>=1.0",
+ "",
+ ".endif\t# ICONV_BUILDLINK3_MK",
+ "",
+ "BUILDLINK_TREE+=\t-iconv")
+ t.FinishSetUp()
+
+ G.Check(t.File("converters/libiconv"))
+
+ // Up to 2019-10-12, pkglint complained about a mismatch
+ // between the package name from buildlink3.mk (iconv) and the
+ // one from the package Makefile (libiconv).
+ //
+ // This mismatch is not important enough to warrant a global
+ // renaming of the buildlink3 identifier, therefore the warning
+ // is suppressed in cases like this.
+ t.CheckOutputEmpty()
+}
+
+func (s *Suite) Test_CheckLinesBuildlink3Mk__name_mismatch__version(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpPackage("editors/emacs22",
+ "PKGNAME=\temacs22-22.0")
+ t.CreateFileLines("editors/emacs22/buildlink3.mk",
+ MkCvsID,
+ "",
+ "BUILDLINK_TREE+=\temacs",
+ "",
+ ".if !defined(EMACS_BUILDLINK3_MK)",
+ "EMACS_BUILDLINK3_MK:=",
+ "",
+ "BUILDLINK_API_DEPENDS.emacs+=\temacs22>=1.0",
+ "BUILDLINK_ABI_DEPENDS.emacs+=\temacs22>=1.0",
+ "",
+ ".endif\t# EMACS_BUILDLINK3_MK",
+ "",
+ "BUILDLINK_TREE+=\t-emacs")
+ t.FinishSetUp()
+
+ G.Check(t.File("editors/emacs22"))
+
+ // Up to 2019-10-12, pkglint complained about a mismatch
+ // between the package name from buildlink3.mk (emacs) and the
+ // one from the package Makefile (emacs22).
+ //
+ // This mismatch is not important enough to warrant a global
+ // renaming of the buildlink3 identifier, therefore the warning
+ // is suppressed in cases like this.
+ t.CheckOutputEmpty()
+}
+
func (s *Suite) Test_CheckLinesBuildlink3Mk__name_mismatch_multiple_inclusion(c *check.C) {
t := s.Init(c)
diff --git a/pkgtools/pkglint/files/mkshparser_test.go b/pkgtools/pkglint/files/mkshparser_test.go
index be937ab42b7..3c36762250a 100644
--- a/pkgtools/pkglint/files/mkshparser_test.go
+++ b/pkgtools/pkglint/files/mkshparser_test.go
@@ -331,12 +331,24 @@ func (s *ShSuite) Test_ShellParser__for_clause(c *check.C) {
b.Words("a", "b", "c"),
b.List().AddCommand(b.SimpleCommand("echo", "$var")).AddSemicolon())))
+ s.test("for var \n in ; do echo $var ; done",
+ b.List().AddCommand(b.For(
+ "var",
+ nil,
+ b.List().AddCommand(b.SimpleCommand("echo", "$var")).AddSemicolon())))
+
s.test("for var in in esac ; do echo $var ; done",
b.List().AddCommand(b.For(
"var",
b.Words("in", "esac"),
b.List().AddCommand(b.SimpleCommand("echo", "$var")).AddSemicolon())))
+ s.test("for var in \n do : ; done",
+ b.List().AddCommand(b.For(
+ "var",
+ nil,
+ b.List().AddCommand(b.SimpleCommand(":")).AddSemicolon())))
+
// No semicolon necessary between the two "done".
s.test("for i in 1; do for j in 1; do echo $$i$$j; done done",
b.List().AddCommand(b.For(
@@ -385,6 +397,20 @@ func (s *ShSuite) Test_ShellParser__case_clause(c *check.C) {
b.Words("pattern"),
b.List().AddCommand(b.SimpleCommand("case-item-action")), sepNone))))
+ s.test("case selector in pattern) \n case-item-action ; esac",
+ b.List().AddCommand(b.Case(
+ b.Token("selector"),
+ b.CaseItem(
+ b.Words("pattern"),
+ b.List().AddCommand(b.SimpleCommand("case-item-action")), sepSemicolon))))
+
+ s.test("case selector in pattern) action \n esac",
+ b.List().AddCommand(b.Case(
+ b.Token("selector"),
+ b.CaseItem(
+ b.Words("pattern"),
+ b.List().AddCommand(b.SimpleCommand("action")), sepNone))))
+
s.test("case $$expr in (if|then|else) ;; esac",
b.List().AddCommand(b.Case(
b.Token("$$expr"),
@@ -433,6 +459,14 @@ func (s *ShSuite) Test_ShellParser__if_clause(c *check.C) {
b.List().AddCommand(b.If(
b.List().AddCommand(b.SimpleCommand("cond2")).AddSemicolon(),
b.List().AddCommand(b.SimpleCommand("action")).AddSemicolon())))))
+
+ s.test("if cond1; then action1; elif cond2; then action2; else action3; fi",
+ b.List().AddCommand(b.If(
+ b.List().AddCommand(b.SimpleCommand("cond1")).AddSemicolon(),
+ b.List().AddCommand(b.SimpleCommand("action1")).AddSemicolon(),
+ b.List().AddCommand(b.SimpleCommand("cond2")).AddSemicolon(),
+ b.List().AddCommand(b.SimpleCommand("action2")).AddSemicolon(),
+ b.List().AddCommand(b.SimpleCommand("action3")).AddSemicolon())))
}
func (s *ShSuite) Test_ShellParser__while_clause(c *check.C) {
@@ -526,7 +560,7 @@ func (s *ShSuite) Test_ShellParser__io_redirect(c *check.C) {
s.test("echo >> ${PLIST_SRC}",
b.List().AddCommand(b.SimpleCommand("echo", ">>${PLIST_SRC}")))
- s.test("echo 1>output 2>>append 3>|clobber 4>&5 6<input >>append",
+ s.test("echo 1>output 2>>append 3>|clobber 4>&5 6<input >>append <&input <>diamond <<-here",
b.List().AddCommand(&MkShCommand{Simple: &MkShSimpleCommand{
Assignments: nil,
Name: b.Token("echo"),
@@ -537,9 +571,12 @@ func (s *ShSuite) Test_ShellParser__io_redirect(c *check.C) {
{3, ">|", b.Token("clobber")},
{4, ">&", b.Token("5")},
{6, "<", b.Token("input")},
- {-1, ">>", b.Token("append")}}}}))
+ {-1, ">>", b.Token("append")},
+ {-1, "<&", b.Token("input")},
+ {-1, "<>", b.Token("diamond")},
+ {-1, "<<-", b.Token("here")}}}}))
- s.test("echo 1> output 2>> append 3>| clobber 4>& 5 6< input >> append",
+ s.test("echo 1> output 2>> append 3>| clobber 4>& 5 6< input >> append <& input <> diamond <<- here",
b.List().AddCommand(&MkShCommand{Simple: &MkShSimpleCommand{
Assignments: nil,
Name: b.Token("echo"),
@@ -550,7 +587,10 @@ func (s *ShSuite) Test_ShellParser__io_redirect(c *check.C) {
{3, ">|", b.Token("clobber")},
{4, ">&", b.Token("5")},
{6, "<", b.Token("input")},
- {-1, ">>", b.Token("append")}}}}))
+ {-1, ">>", b.Token("append")},
+ {-1, "<&", b.Token("input")},
+ {-1, "<>", b.Token("diamond")},
+ {-1, "<<-", b.Token("here")}}}}))
s.test("${MAKE} print-summary-data 2>&1 > /dev/stderr",
b.List().AddCommand(&MkShCommand{Simple: &MkShSimpleCommand{
@@ -560,11 +600,60 @@ func (s *ShSuite) Test_ShellParser__io_redirect(c *check.C) {
Redirections: []*MkShRedirection{
{2, ">&", b.Token("1")},
{-1, ">", b.Token("/dev/stderr")}}}}))
+
+ s.test("1> output command",
+ b.List().AddCommand(&MkShCommand{Simple: &MkShSimpleCommand{
+ Name: b.Token("command"),
+ Redirections: []*MkShRedirection{
+ {1, ">", b.Token("output")}}}}))
+
+ s.test("ENV=value 1> output command",
+ b.List().AddCommand(&MkShCommand{Simple: &MkShSimpleCommand{
+ Assignments: []*ShToken{b.Token("ENV=value")},
+ Name: b.Token("command"),
+ Redirections: []*MkShRedirection{
+ {1, ">", b.Token("output")}}}}))
+}
+
+func (s *ShSuite) Test_ShellParser__redirect_list(c *check.C) {
+ b := s.init(c)
+
+ s.test("(:) 1>out",
+ b.List().AddCommand(
+ b.Redirected(
+ b.Subshell(b.List().AddCommand(b.SimpleCommand(":"))),
+ b.Redirection(1, ">", "out"))))
+
+ s.test("(:) 1>out 2>out",
+ b.List().AddCommand(
+ b.Redirected(
+ b.Subshell(b.List().AddCommand(b.SimpleCommand(":"))),
+ b.Redirection(1, ">", "out"),
+ b.Redirection(2, ">", "out"))))
}
func (s *ShSuite) Test_ShellParser__io_here(c *check.C) {
- // In pkgsrc Makefiles, the IO here-documents cannot be used since all the text
- // is joined into a single line. Therefore there are no tests here.
+ // In pkgsrc Makefiles, the IO here-documents cannot be used since
+ // all the text is joined into a single line. Therefore these test
+ // cases only show that pkglint can indeed not parse <<EOF
+ // redirections.
+ b := s.init(c)
+
+ s.test("<<EOF\ntext\nEOF",
+ b.List().
+ AddCommand(b.SimpleCommand("<<EOF")).
+ AddNewline().
+ AddCommand(b.SimpleCommand("text")). // This is wrong.
+ AddNewline().
+ AddCommand(b.SimpleCommand("EOF"))) // This is wrong.
+
+ s.test("1<<EOF\ntext\nEOF",
+ b.List().
+ AddCommand(b.SimpleCommand("1<<EOF")).
+ AddNewline().
+ AddCommand(b.SimpleCommand("text")). // This is wrong.
+ AddNewline().
+ AddCommand(b.SimpleCommand("EOF"))) // This is wrong.
}
func (s *ShSuite) init(c *check.C) *MkShBuilder {
@@ -766,6 +855,9 @@ func (b *MkShBuilder) Pipeline(negated bool, cmds ...*MkShCommand) *MkShPipeline
return NewMkShPipeline(negated, cmds)
}
+// SimpleCommand classifies the given arguments into variable assignments
+// (only at the beginning of the command), the command name, arguments and
+// redirections. It is not intended to cover any edge cases.
func (b *MkShBuilder) SimpleCommand(words ...string) *MkShCommand {
cmd := MkShSimpleCommand{}
assignments := true
@@ -787,6 +879,9 @@ func (b *MkShBuilder) SimpleCommand(words ...string) *MkShCommand {
return &MkShCommand{Simple: &cmd}
}
+// If creates an if-then-elif-then-else sequence.
+// The first arguments are pairs of conditions and actions.
+// The remaining argument, if any, is the else action.
func (b *MkShBuilder) If(condActionElse ...*MkShList) *MkShCommand {
ifClause := MkShIf{}
for i, part := range condActionElse {
@@ -846,6 +941,11 @@ func (b *MkShBuilder) Subshell(list *MkShList) *MkShCommand {
return &MkShCommand{Compound: &MkShCompoundCommand{Subshell: list}}
}
+func (b *MkShBuilder) Redirected(cmd *MkShCommand, redirects ...*MkShRedirection) *MkShCommand {
+ cmd.Redirects = redirects
+ return cmd
+}
+
func (b *MkShBuilder) Token(mktext string) *ShToken {
tokenizer := NewShTokenizer(dummyLine, mktext, false)
token := tokenizer.ShToken()
diff --git a/pkgtools/pkglint/files/package.go b/pkgtools/pkglint/files/package.go
index 70591500be4..452ef1e26b7 100644
--- a/pkgtools/pkglint/files/package.go
+++ b/pkgtools/pkglint/files/package.go
@@ -980,6 +980,7 @@ func (pkg *Package) CheckVarorder(mklines *MkLines) {
var variables = []Variable{
{"GITHUB_PROJECT", optional}, // either here or below MASTER_SITES
{"GITHUB_TAG", optional},
+ {"GITHUB_RELEASE", optional},
{"DISTNAME", optional},
{"PKGNAME", optional},
{"R_PKGNAME", optional},
@@ -989,6 +990,7 @@ func (pkg *Package) CheckVarorder(mklines *MkLines) {
{"MASTER_SITES", many},
{"GITHUB_PROJECT", optional}, // either here or at the very top
{"GITHUB_TAG", optional},
+ {"GITHUB_RELEASE", optional},
{"DIST_SUBDIR", optional},
{"EXTRACT_SUFX", optional},
{"DISTFILES", many},
diff --git a/pkgtools/pkglint/files/pkgsrc.go b/pkgtools/pkglint/files/pkgsrc.go
index fc3e9781f5a..afad3c26b7a 100644
--- a/pkgtools/pkglint/files/pkgsrc.go
+++ b/pkgtools/pkglint/files/pkgsrc.go
@@ -28,7 +28,7 @@ type Pkgsrc struct {
Tools *Tools
- MasterSiteURLToVar map[string]string // "https://github.com/" => "MASTER_SITE_GITHUB"
+ MasterSiteURLToVar map[string]string // "github.com/" => "MASTER_SITE_GITHUB"
MasterSiteVarToURL map[string]string // "MASTER_SITE_GITHUB" => "https://github.com/"
PkgOptions map[string]string // "x11" => "Provides X11 support"
@@ -921,7 +921,7 @@ func (src *Pkgsrc) registerMasterSite(varname, url string) {
if nameToURL[varname] == "" {
nameToURL[varname] = url
}
- urlToName[url] = varname
+ urlToName[replaceAll(url, `^\w+://`, "")] = varname
}
func (src *Pkgsrc) loadPkgOptions() {
diff --git a/pkgtools/pkglint/files/pkgsrc_test.go b/pkgtools/pkglint/files/pkgsrc_test.go
index 34858f0f6e5..3de9622a31e 100644
--- a/pkgtools/pkglint/files/pkgsrc_test.go
+++ b/pkgtools/pkglint/files/pkgsrc_test.go
@@ -24,16 +24,16 @@ func (s *Suite) Test_Pkgsrc_loadMasterSites(c *check.C) {
G.Pkgsrc.loadMasterSites()
- t.CheckEquals(G.Pkgsrc.MasterSiteURLToVar["https://example.org/distfiles/"], "MASTER_SITE_A")
- t.CheckEquals(G.Pkgsrc.MasterSiteURLToVar["https://b.example.org/distfiles/"], "MASTER_SITE_B")
- t.CheckEquals(G.Pkgsrc.MasterSiteURLToVar["https://b2.example.org/distfiles/"], "MASTER_SITE_B")
- t.CheckEquals(G.Pkgsrc.MasterSiteURLToVar["https://a.example.org/distfiles/"], "MASTER_SITE_A")
+ t.CheckEquals(G.Pkgsrc.MasterSiteURLToVar["example.org/distfiles/"], "MASTER_SITE_A")
+ t.CheckEquals(G.Pkgsrc.MasterSiteURLToVar["b.example.org/distfiles/"], "MASTER_SITE_B")
+ t.CheckEquals(G.Pkgsrc.MasterSiteURLToVar["b2.example.org/distfiles/"], "MASTER_SITE_B")
+ t.CheckEquals(G.Pkgsrc.MasterSiteURLToVar["a.example.org/distfiles/"], "MASTER_SITE_A")
t.CheckEquals(G.Pkgsrc.MasterSiteVarToURL["MASTER_SITE_A"], "https://example.org/distfiles/")
t.CheckEquals(G.Pkgsrc.MasterSiteVarToURL["MASTER_SITE_B"], "https://b.example.org/distfiles/")
// Ignored entries:
t.CheckEquals(G.Pkgsrc.MasterSiteURLToVar["${other}"], "")
- t.CheckEquals(G.Pkgsrc.MasterSiteURLToVar["https://backup.example.org/"], "")
+ t.CheckEquals(G.Pkgsrc.MasterSiteURLToVar["backup.example.org/"], "")
t.CheckEquals(G.Pkgsrc.MasterSiteVarToURL["MASTER_SITE_BACKUP"], "")
}
diff --git a/pkgtools/pkglint/files/shell.y b/pkgtools/pkglint/files/shell.y
index b10fa5e7a33..c762f8160a7 100644
--- a/pkgtools/pkglint/files/shell.y
+++ b/pkgtools/pkglint/files/shell.y
@@ -61,7 +61,7 @@ start : program {
}
program : compound_list {
- $$ = $1
+ /* empty */
}
program : /* empty */ {
$$ = &MkShList{}
diff --git a/pkgtools/pkglint/files/vartypecheck.go b/pkgtools/pkglint/files/vartypecheck.go
index de022e35fa7..2277473afc8 100644
--- a/pkgtools/pkglint/files/vartypecheck.go
+++ b/pkgtools/pkglint/files/vartypecheck.go
@@ -560,18 +560,24 @@ func (cv *VartypeCheck) FetchURL() {
cv.WithValue(url).URL()
- for siteURL, siteName := range G.Pkgsrc.MasterSiteURLToVar {
- if hasPrefix(url, siteURL) {
- subdir := url[len(siteURL):]
- if hasPrefix(url, "https://github.com/") {
- subdir = strings.SplitAfter(subdir, "/")[0]
- cv.Warnf("Please use ${%s%s:=%s} instead of %q and run %q for further instructions.",
- siteName, hyphenSubst, subdir, hyphen+url[:len(siteURL)+len(subdir)], bmakeHelp("github"))
- } else {
- cv.Warnf("Please use ${%s%s:=%s} instead of %q.", siteName, hyphenSubst, subdir, hyphen+url)
- }
- return
+ trimURL := url[len(url)-len(replaceAll(url, `^\w+://`, "")):]
+ protoLen := len(url) - len(trimURL)
+
+ for trimSiteURL, siteName := range G.Pkgsrc.MasterSiteURLToVar {
+ if !hasPrefix(trimURL, trimSiteURL) {
+ continue
+ }
+
+ subdir := trimURL[len(trimSiteURL):]
+ if hasPrefix(trimURL, "github.com/") {
+ subdir = strings.SplitAfter(subdir, "/")[0]
+ commonPrefix := hyphen + url[:protoLen+len(trimSiteURL)+len(subdir)]
+ cv.Warnf("Please use ${%s%s:=%s} instead of %q and run %q for further instructions.",
+ siteName, hyphenSubst, subdir, commonPrefix, bmakeHelp("github"))
+ } else {
+ cv.Warnf("Please use ${%s%s:=%s} instead of %q.", siteName, hyphenSubst, subdir, hyphen+url)
}
+ return
}
tokens := cv.MkLine.Tokenize(url, false)
diff --git a/pkgtools/pkglint/files/vartypecheck_test.go b/pkgtools/pkglint/files/vartypecheck_test.go
index 6d382ed8a69..a10f2b538fa 100644
--- a/pkgtools/pkglint/files/vartypecheck_test.go
+++ b/pkgtools/pkglint/files/vartypecheck_test.go
@@ -605,6 +605,30 @@ func (s *Suite) Test_VartypeCheck_FetchURL(c *check.C) {
"WARN: filename.mk:71: The fetch URL \"https://example.org/pub\" should end with a slash.",
"WARN: filename.mk:72: \"https://example.org/$@\" is not a valid URL.",
"WARN: filename.mk:75: The fetch URL \"https://example.org/download?\" should end with a slash.")
+
+ // The transport protocol doesn't matter for matching the MASTER_SITEs.
+ // See url2pkg.py, function adjust_site_from_sites_mk.
+ vt.Values(
+ "http://ftp.gnu.org/pub/gnu/bash/",
+ "ftp://ftp.gnu.org/pub/gnu/bash/",
+ "https://ftp.gnu.org/pub/gnu/bash/",
+ "-http://ftp.gnu.org/pub/gnu/bash/bash-5.0.tar.gz",
+ "-ftp://ftp.gnu.org/pub/gnu/bash/bash-5.0.tar.gz",
+ "-https://ftp.gnu.org/pub/gnu/bash/bash-5.0.tar.gz")
+
+ vt.Output(
+ "WARN: filename.mk:81: Please use ${MASTER_SITE_GNU:=bash/} "+
+ "instead of \"http://ftp.gnu.org/pub/gnu/bash/\".",
+ "WARN: filename.mk:82: Please use ${MASTER_SITE_GNU:=bash/} "+
+ "instead of \"ftp://ftp.gnu.org/pub/gnu/bash/\".",
+ "WARN: filename.mk:83: Please use ${MASTER_SITE_GNU:=bash/} "+
+ "instead of \"https://ftp.gnu.org/pub/gnu/bash/\".",
+ "WARN: filename.mk:84: Please use ${MASTER_SITE_GNU:S,^,-,:=bash/bash-5.0.tar.gz} "+
+ "instead of \"-http://ftp.gnu.org/pub/gnu/bash/bash-5.0.tar.gz\".",
+ "WARN: filename.mk:85: Please use ${MASTER_SITE_GNU:S,^,-,:=bash/bash-5.0.tar.gz} "+
+ "instead of \"-ftp://ftp.gnu.org/pub/gnu/bash/bash-5.0.tar.gz\".",
+ "WARN: filename.mk:86: Please use ${MASTER_SITE_GNU:S,^,-,:=bash/bash-5.0.tar.gz} "+
+ "instead of \"-https://ftp.gnu.org/pub/gnu/bash/bash-5.0.tar.gz\".")
}
func (s *Suite) Test_VartypeCheck_FetchURL__without_package(c *check.C) {