pkgsrc-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[pkgsrc/trunk]: pkgsrc/pkgtools/pkglint pkgtools/pkglint: Update to 22.3.1
details: https://anonhg.NetBSD.org/pkgsrc/rev/1c9fc4906abe
branches: trunk
changeset: 388411:1c9fc4906abe
user: rillig <rillig%pkgsrc.org@localhost>
date: Sat Nov 19 10:51:07 2022 +0000
description:
pkgtools/pkglint: Update to 22.3.1
Changes since 22.3.0:
In doc/CHANGES files, check for typos in month and day of the dates.
In conditions for YesNo variables, suggest to replace the modifier
':M[yY][eE][sS]' with a simpler comparison.
https://mail-index.netbsd.org/tech-pkg/2022/11/16/msg026992.html
diffstat:
pkgtools/pkglint/Makefile | 9 +-
pkgtools/pkglint/files/mkcondchecker_test.go | 6 +-
pkgtools/pkglint/files/mkcondsimplifier.go | 115 +++-
pkgtools/pkglint/files/mkcondsimplifier_test.go | 757 +++++++++++++----------
pkgtools/pkglint/files/mktypes.go | 25 +-
pkgtools/pkglint/files/mktypes_test.go | 4 +-
pkgtools/pkglint/files/pkgsrc.go | 71 +-
pkgtools/pkglint/files/pkgsrc_test.go | 40 +
8 files changed, 644 insertions(+), 383 deletions(-)
diffs (truncated from 1352 to 300 lines):
diff -r 61cbe667533e -r 1c9fc4906abe pkgtools/pkglint/Makefile
--- a/pkgtools/pkglint/Makefile Sat Nov 19 10:43:21 2022 +0000
+++ b/pkgtools/pkglint/Makefile Sat Nov 19 10:51:07 2022 +0000
@@ -1,7 +1,6 @@
-# $NetBSD: Makefile,v 1.733 2022/11/02 19:39:53 bsiegert Exp $
+# $NetBSD: Makefile,v 1.734 2022/11/19 10:51:07 rillig Exp $
-PKGNAME= pkglint-22.3.0
-PKGREVISION= 2
+PKGNAME= pkglint-22.3.1
CATEGORIES= pkgtools
MAINTAINER= rillig%NetBSD.org@localhost
@@ -16,7 +15,7 @@
SUBST_CLASSES+= pkglint
SUBST_STAGE.pkglint= post-configure
-SUBST_FILES.pkglint+= ${WRKSRC}/pkglint.go
+SUBST_FILES.pkglint+= pkglint.go
SUBST_SED.pkglint+= -e s\|@VERSION@\|${PKGVERSION}\|g
SUBST_SED.pkglint+= -e s\|@BMAKE@\|${MAKE:T:Q}\|g
@@ -46,7 +45,7 @@
PLIST_VARS+= catinstall0 catinstall maninstall
.if ${MANINSTALL:Mcatinstall}
INSTALLATION_DIRS+= man/cat1
-. if ${CATMAN_SECTION_SUFFIX:M[Yy][Ee][Ss]}
+. if ${CATMAN_SECTION_SUFFIX:U:tl} == yes
PLIST.catinstall= yes
. else
PLIST.catinstall0= yes
diff -r 61cbe667533e -r 1c9fc4906abe pkgtools/pkglint/files/mkcondchecker_test.go
--- a/pkgtools/pkglint/files/mkcondchecker_test.go Sat Nov 19 10:43:21 2022 +0000
+++ b/pkgtools/pkglint/files/mkcondchecker_test.go Sat Nov 19 10:51:07 2022 +0000
@@ -51,7 +51,11 @@
"WARN: filename.mk:4: PKGSRC_RUN_TEST should be matched "+
"against \"[yY][eE][sS]\" or \"[nN][oO]\", not \"[Y][eE][sS]\".")
- test(".if !empty(IS_BUILTIN.Xfixes:M[yY][eE][sS])")
+ test(".if !empty(IS_BUILTIN.Xfixes:M[yY][eE][sS])",
+ "NOTE: filename.mk:4: "+
+ "\"!empty(IS_BUILTIN.Xfixes:M[yY][eE][sS])\" "+
+ "can be simplified to "+
+ "\"${IS_BUILTIN.Xfixes:U:tl} == yes\".")
test(".if !empty(${IS_BUILTIN.Xfixes:M[yY][eE][sS]})",
"WARN: filename.mk:4: The empty() function takes a variable name as parameter, "+
diff -r 61cbe667533e -r 1c9fc4906abe pkgtools/pkglint/files/mkcondsimplifier.go
--- a/pkgtools/pkglint/files/mkcondsimplifier.go Sat Nov 19 10:43:21 2022 +0000
+++ b/pkgtools/pkglint/files/mkcondsimplifier.go Sat Nov 19 10:51:07 2022 +0000
@@ -1,6 +1,9 @@
package pkglint
-import "netbsd.org/pkglint/textproc"
+import (
+ "netbsd.org/pkglint/textproc"
+ "strings"
+)
// MkCondSimplifier replaces unnecessarily complex conditions with simpler yet
// equivalent conditions.
@@ -16,6 +19,9 @@
//
// * neg is true for the form !empty(VAR...), and false for empty(VAR...).
func (s *MkCondSimplifier) SimplifyVarUse(varuse *MkVarUse, fromEmpty bool, neg bool) {
+ if s.simplifyYesNo(varuse, fromEmpty, neg) {
+ return
+ }
s.simplifyMatch(varuse, fromEmpty, neg)
s.simplifyWord(varuse, fromEmpty, neg)
}
@@ -33,6 +39,9 @@
}
modsExceptLast := NewMkVarUse("", modifiers[:n-1]...).Mod()
vartype := G.Pkgsrc.VariableType(s.MkLines, varname)
+ if vartype == nil || vartype.IsList() {
+ return
+ }
// replace constructs the state before and after the autofix.
// The before state is constructed to ensure that only very simple
@@ -82,12 +91,10 @@
if !ok || !positive && n != 1 {
return
}
-
- switch {
- case !exact,
- vartype == nil,
- vartype.IsList(),
- textproc.NewLexer(pattern).NextBytesSet(mkCondModifierPatternLiteral) != pattern:
+ if !exact {
+ return
+ }
+ if textproc.NewLexer(pattern).NextBytesSet(mkCondModifierPatternLiteral) != pattern {
return
}
@@ -112,6 +119,100 @@
fix.Apply()
}
+// simplifyYesNo replaces conditions of the form '${VAR:M[yY][eE][sS]}' with
+// the equivalent ${VAR:tl} == yes.
+func (s *MkCondSimplifier) simplifyYesNo(varuse *MkVarUse, fromEmpty bool, neg bool) (done bool) {
+
+ // TODO: Merge the common code from simplifyWord and simplifyYesNo.
+ // Even better would be to manipulate the conditions in an AST
+ // instead of working directly with strings, but as of November 2022,
+ // that is not implemented yet.
+ // .
+ // Another useful feature would be to chain multiple autofixes
+ // together, but to do that, pkglint needs to be able to convert an
+ // AST back into the source code form.
+
+ toLower := func(p string) string {
+ var sb strings.Builder
+ upper := textproc.Upper
+ lower := textproc.Lower
+ for ; len(p) >= 4 && p[0] == '[' && p[3] == ']'; p = p[4:] {
+ if upper.Contains(p[1]) && p[2] == p[1]-'A'+'a' {
+ sb.WriteByte(p[2])
+ } else if lower.Contains(p[1]) && p[2] == p[1]-'a'+'A' {
+ sb.WriteByte(p[1])
+ } else {
+ return ""
+ }
+ }
+ if p != "" {
+ return ""
+ }
+ return sb.String()
+ }
+
+ varname := varuse.varname
+ modifiers := varuse.modifiers
+
+ n := len(modifiers)
+ if n == 0 {
+ return
+ }
+ modsExceptLast := NewMkVarUse("", modifiers[:n-1]...).Mod()
+ vartype := G.Pkgsrc.VariableType(s.MkLines, varname)
+ if vartype == nil || vartype.IsList() {
+ return
+ }
+
+ // replace constructs the state before and after the autofix.
+ replace := func(positive bool, pattern, lower string) (bool, string, string) {
+ defined := s.isDefined(varname, vartype)
+ if !defined && !positive {
+ // Too many negations; maybe handle this case later.
+ return false, "", ""
+ }
+ uMod := condStr(!defined && !varuse.HasModifier("U"), ":U", "")
+
+ op := condStr(neg == positive, "==", "!=")
+
+ from := sprintf("%s%s%s%s%s%s%s",
+ condStr(neg != fromEmpty, "", "!"),
+ condStr(fromEmpty, "empty(", "${"),
+ varname,
+ modsExceptLast,
+ condStr(positive, ":M", ":N"),
+ pattern,
+ condStr(fromEmpty, ")", "}"))
+
+ to := sprintf(
+ "${%s%s%s:tl} %s %s",
+ varname, uMod, modsExceptLast, op, lower)
+
+ return true, from, to
+ }
+
+ modifier := modifiers[n-1]
+ ok, positive, pattern, exact := modifier.MatchMatch()
+ if !ok || !positive && n != 1 || exact {
+ return
+ }
+ lower := toLower(pattern)
+ if lower == "" {
+ return
+ }
+
+ ok, from, to := replace(positive, pattern, lower)
+ if !ok {
+ return
+ }
+
+ fix := s.MkLine.Autofix()
+ fix.Notef("\"%s\" can be simplified to \"%s\".", from, to)
+ fix.Replace(from, to)
+ fix.Apply()
+ return true
+}
+
// simplifyMatch replaces:
// !empty(VAR:M*.c) with ${VAR:M*.c}
// empty(VAR:M*.c) with !${VAR:M*.c}
diff -r 61cbe667533e -r 1c9fc4906abe pkgtools/pkglint/files/mkcondsimplifier_test.go
--- a/pkgtools/pkglint/files/mkcondsimplifier_test.go Sat Nov 19 10:43:21 2022 +0000
+++ b/pkgtools/pkglint/files/mkcondsimplifier_test.go Sat Nov 19 10:51:07 2022 +0000
@@ -2,11 +2,21 @@
import (
"gopkg.in/check.v1"
+ "netbsd.org/pkglint/regex"
)
type MkCondSimplifierTester struct {
c *check.C
*Tester
+ allowedVariableNames regex.Pattern
+}
+
+func NewMkCondSimplifierTester(c *check.C, s *Suite) *MkCondSimplifierTester {
+ return &MkCondSimplifierTester{
+ c,
+ s.Init(c),
+ `IN_SCOPE|PREFS|LATER|UNDEFINED`,
+ }
}
func (t *MkCondSimplifierTester) setUp() {
@@ -37,6 +47,10 @@
// Even when they are in scope, some variables such as PKGREVISION
// or MAKE_JOBS may be undefined.
+ // TODO: Test list variables; they differ in that a ':M' modifier
+ // cannot be replaced with '==', as the variable may contain
+ // multiple words.
+
t.SetUpVarType("IN_SCOPE_DEFINED", btAnything, AlwaysInScope|DefinedIfInScope,
"*.mk: use, use-loadtime")
t.SetUpVarType("IN_SCOPE", btAnything, AlwaysInScope,
@@ -69,8 +83,10 @@
// before: the directive before the condition is simplified
// after: the directive after the condition is simplified
func (t *MkCondSimplifierTester) doTest(prefs bool, before, after string, diagnostics ...string) {
- if !matches(before, `IN_SCOPE|PREFS|LATER|UNDEFINED`) {
- t.c.Errorf("Condition %q must include one of the above variable names.", before)
+ if !matches(before, t.allowedVariableNames) {
+ // Prevent typos in the variable names used in the test.
+ t.c.Errorf("Condition %q must include one of the variable names %q.",
+ before, t.allowedVariableNames)
}
mklines := t.SetUpFileMkLines("filename.mk",
MkCvsID,
@@ -104,33 +120,7 @@
}
func (s *Suite) Test_MkCondSimplifier_SimplifyVarUse(c *check.C) {
- t := MkCondSimplifierTester{c, s.Init(c)}
-
- t.setUp()
-
- t.testBeforeAndAfterPrefs(
- ".if ${IN_SCOPE_DEFINED:Mpattern}",
- ".if ${IN_SCOPE_DEFINED} == pattern",
-
- "NOTE: filename.mk:6: IN_SCOPE_DEFINED can be "+
- "compared using the simpler \"${IN_SCOPE_DEFINED} == pattern\" "+
- "instead of matching against \":Mpattern\".",
- "AUTOFIX: filename.mk:6: Replacing \"${IN_SCOPE_DEFINED:Mpattern}\" "+
- "with \"${IN_SCOPE_DEFINED} == pattern\".")
-
- t.testBeforeAndAfterPrefs(
- ".if !empty(IN_SCOPE_DEFINED:M[Nn][Oo])",
- ".if ${IN_SCOPE_DEFINED:M[Nn][Oo]}",
-
- "NOTE: filename.mk:6: \"!empty(IN_SCOPE_DEFINED:M[Nn][Oo])\" "+
- "can be simplified to \"${IN_SCOPE_DEFINED:M[Nn][Oo]}\".",
- "AUTOFIX: filename.mk:6: "+
- "Replacing \"!empty(IN_SCOPE_DEFINED:M[Nn][Oo])\" "+
- "with \"${IN_SCOPE_DEFINED:M[Nn][Oo]}\".")
-}
-
-func (s *Suite) Test_MkCondSimplifier_simplifyWord(c *check.C) {
- t := MkCondSimplifierTester{c, s.Init(c)}
+ t := NewMkCondSimplifierTester(c, s)
t.setUp()
@@ -144,6 +134,43 @@
"AUTOFIX: filename.mk:6: Replacing \"${IN_SCOPE_DEFINED:Mpattern}\" "+
"with \"${IN_SCOPE_DEFINED} == pattern\".")
+ // From simplifyYesNo.
+ t.testBeforeAndAfterPrefs(
+ ".if !empty(IN_SCOPE_DEFINED:M[Nn][Oo])",
+ ".if ${IN_SCOPE_DEFINED:tl} == no",
+
+ "NOTE: filename.mk:6: \"!empty(IN_SCOPE_DEFINED:M[Nn][Oo])\" "+
+ "can be simplified to \"${IN_SCOPE_DEFINED:tl} == no\".",
+ "AUTOFIX: filename.mk:6: "+
+ "Replacing \"!empty(IN_SCOPE_DEFINED:M[Nn][Oo])\" "+
+ "with \"${IN_SCOPE_DEFINED:tl} == no\".")
+}
+
+// Show in which cases the ':U' modifier is needed, and how including
Home |
Main Index |
Thread Index |
Old Index