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 5.5.15
details: https://anonhg.NetBSD.org/pkgsrc/rev/02d091c2155d
branches: trunk
changeset: 383350:02d091c2155d
user: rillig <rillig%pkgsrc.org@localhost>
date: Sat Jul 28 18:31:23 2018 +0000
description:
pkgtools/pkglint: update to 5.5.15
Changes since 5.5.14:
* Check that the comments in .endif and .endfor lines match the
corresponding conditions.
* Check for redundant variables (e.g. MASTER_SITES for R packages).
* Check for accidentally overwritten variables.
* Miscellaneous code cleanup and refactoring.
diffstat:
pkgtools/pkglint/Makefile | 4 +-
pkgtools/pkglint/files/check_test.go | 8 +-
pkgtools/pkglint/files/mkline.go | 190 +++++++++++++++++++++------
pkgtools/pkglint/files/mkline_test.go | 16 +-
pkgtools/pkglint/files/mklinechecker.go | 47 ++++--
pkgtools/pkglint/files/mklines.go | 81 ++++++++++-
pkgtools/pkglint/files/mklines_test.go | 71 ++++++++++-
pkgtools/pkglint/files/mkparser.go | 2 +
pkgtools/pkglint/files/mkparser_test.go | 2 +
pkgtools/pkglint/files/package.go | 36 +---
pkgtools/pkglint/files/package_test.go | 45 ++++++-
pkgtools/pkglint/files/patches.go | 17 +-
pkgtools/pkglint/files/patches_test.go | 64 +++++++-
pkgtools/pkglint/files/pkgsrc.go | 2 +-
pkgtools/pkglint/files/shell_test.go | 30 +++-
pkgtools/pkglint/files/util.go | 80 +++++++++++
pkgtools/pkglint/files/vartypecheck.go | 16 +-
pkgtools/pkglint/files/vartypecheck_test.go | 11 +-
18 files changed, 583 insertions(+), 139 deletions(-)
diffs (truncated from 1330 to 300 lines):
diff -r 1e76a73e8567 -r 02d091c2155d pkgtools/pkglint/Makefile
--- a/pkgtools/pkglint/Makefile Sat Jul 28 18:29:38 2018 +0000
+++ b/pkgtools/pkglint/Makefile Sat Jul 28 18:31:23 2018 +0000
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.542 2018/07/19 06:38:15 rillig Exp $
+# $NetBSD: Makefile,v 1.543 2018/07/28 18:31:23 rillig Exp $
-PKGNAME= pkglint-5.5.14
+PKGNAME= pkglint-5.5.15
DISTFILES= # none
CATEGORIES= pkgtools
diff -r 1e76a73e8567 -r 02d091c2155d pkgtools/pkglint/files/check_test.go
--- a/pkgtools/pkglint/files/check_test.go Sat Jul 28 18:29:38 2018 +0000
+++ b/pkgtools/pkglint/files/check_test.go Sat Jul 28 18:31:23 2018 +0000
@@ -3,6 +3,7 @@
import (
"bytes"
"fmt"
+ "io"
"io/ioutil"
"os"
"path"
@@ -296,11 +297,12 @@
t.c().Check(emptyToNil(actualLines), deepEquals, emptyToNil(expectedLines))
}
-// EnableTracing redirects all logging output to stdout instead of
-// the buffer. This is useful when stepping through the code, especially
+// EnableTracing redirects all logging output (which is normally captured
+// in an in-memory buffer) additionally to stdout.
+// This is useful when stepping through the code, especially
// in combination with SetupCommandLine("--debug").
func (t *Tester) EnableTracing() {
- G.logOut = NewSeparatorWriter(os.Stdout)
+ G.logOut = NewSeparatorWriter(io.MultiWriter(os.Stdout, &t.stdout))
trace.Out = os.Stdout
trace.Tracing = true
}
diff -r 1e76a73e8567 -r 02d091c2155d pkgtools/pkglint/files/mkline.go
--- a/pkgtools/pkglint/files/mkline.go Sat Jul 28 18:29:38 2018 +0000
+++ b/pkgtools/pkglint/files/mkline.go Sat Jul 28 18:31:23 2018 +0000
@@ -38,6 +38,7 @@
indent string
directive string
args string
+ comment string
}
type mkLineInclude struct {
mustExist bool
@@ -112,8 +113,8 @@
return &MkLineImpl{line, mkLineEmpty{}}
}
- if m, indent, directive, args := matchMkCond(text); m {
- return &MkLineImpl{line, mkLineConditional{indent, directive, args}}
+ if m, indent, directive, args, comment := matchMkCond(text); m {
+ return &MkLineImpl{line, mkLineConditional{indent, directive, args, comment}}
}
if m, indent, directive, includefile := MatchMkInclude(text); m {
@@ -217,7 +218,8 @@
// Op applies to variable assignments and returns the assignment operator.
func (mkline *MkLineImpl) Op() MkOperator { return mkline.data.(mkLineAssign).op }
-// For a variable assignment, the text up to and including the assignment operator, e.g. VARNAME+=\t
+// ValueAlign applies to variable assignments and returns all the text
+// before the variable value, e.g. "VARNAME+=\t".
func (mkline *MkLineImpl) ValueAlign() string { return mkline.data.(mkLineAssign).valueAlign }
func (mkline *MkLineImpl) Value() string { return mkline.data.(mkLineAssign).value }
@@ -235,14 +237,25 @@
return mkline.data.(mkLineInclude).indent
}
}
-func (mkline *MkLineImpl) Directive() string { return mkline.data.(mkLineConditional).directive }
-func (mkline *MkLineImpl) Args() string { return mkline.data.(mkLineConditional).args }
+
+// Directive returns one of "if", "ifdef", "ifndef", "else", "elif", "endif", "for", "endfor", "undef".
+//
+// See matchMkCond.
+func (mkline *MkLineImpl) Directive() string { return mkline.data.(mkLineConditional).directive }
+func (mkline *MkLineImpl) Args() string { return mkline.data.(mkLineConditional).args }
+
+// CondComment is the trailing end-of-line comment, typically at a deeply nested .endif or .endfor.
+func (mkline *MkLineImpl) CondComment() string { return mkline.data.(mkLineConditional).comment }
+
func (mkline *MkLineImpl) MustExist() bool { return mkline.data.(mkLineInclude).mustExist }
func (mkline *MkLineImpl) IncludeFile() string { return mkline.data.(mkLineInclude).includeFile }
-func (mkline *MkLineImpl) Targets() string { return mkline.data.(mkLineDependency).targets }
-func (mkline *MkLineImpl) Sources() string { return mkline.data.(mkLineDependency).sources }
+
+func (mkline *MkLineImpl) Targets() string { return mkline.data.(mkLineDependency).targets }
+func (mkline *MkLineImpl) Sources() string { return mkline.data.(mkLineDependency).sources }
-// Initialized step by step, when parsing other lines
+// ConditionVars is a space-separated list of those variable names
+// on which the inclusion depends. It is initialized later,
+// step by step, when parsing other lines
func (mkline *MkLineImpl) ConditionVars() string { return mkline.data.(mkLineInclude).conditionVars }
func (mkline *MkLineImpl) SetConditionVars(varnames string) {
include := mkline.data.(mkLineInclude)
@@ -340,7 +353,7 @@
"main pkgsrc repository.")
}
-func matchMkCond(text string) (m bool, indent, directive, args string) {
+func matchMkCond(text string) (m bool, indent, directive, args, comment string) {
i, n := 0, len(text)
if i < n && text[i] == '.' {
i++
@@ -375,6 +388,13 @@
for i < n && (text[i] != '#' || text[i-1] == '\\') {
i++
}
+ commentStart := i
+ if commentStart < n {
+ commentStart++
+ for commentStart < n && (text[commentStart] == ' ' || text[commentStart] == '\t') {
+ commentStart++
+ }
+ }
for i > argsStart && (text[i-1] == ' ' || text[i-1] == '\t') {
i--
}
@@ -383,6 +403,7 @@
m = true
indent = text[indentStart:indentEnd]
args = strings.Replace(text[argsStart:argsEnd], "\\#", "#", -1)
+ comment = text[commentStart:]
return
}
@@ -728,57 +749,66 @@
// An excepting are multiple-inclusion guards, they don't increase the
// indentation.
type Indentation struct {
- depth []int // Number of space characters; always a multiple of 2
- conditionVars [][]string // Variables on which the current path depends
+ levels []indentationLevel
+}
+
+func NewIndentation() *Indentation {
+ ind := &Indentation{}
+ ind.Push(0, "") // Dummy
+ return ind
+}
+
+type indentationLevel struct {
+ depth int // Number of space characters; always a multiple of 2
+ condition string // The corresponding condition from the .if or .elif
+ conditionVars []string // Variables on which the current path depends
// Files whose existence has been checked in a related path.
// The check counts for both the "if" and the "else" branch,
// but that sloppiness will be discovered by functional tests.
- checkedFiles [][]string
+ checkedFiles []string
}
func (ind *Indentation) Len() int {
- return len(ind.depth)
+ return len(ind.levels)
}
+func (ind *Indentation) top() *indentationLevel {
+ return &ind.levels[ind.Len()-1]
+}
+
+// Depth returns the number of space characters by which the directive
+// should be indented.
func (ind *Indentation) Depth(directive string) int {
switch directive {
- case "elif", "else", "endfor", "endif":
- return ind.depth[imax(0, len(ind.depth)-2)]
+ case "if", "elif", "else", "endfor", "endif":
+ return ind.levels[imax(0, ind.Len()-2)].depth
}
- return ind.depth[len(ind.depth)-1]
+ return ind.top().depth
}
func (ind *Indentation) Pop() {
- newlen := ind.Len() - 1
- ind.depth = ind.depth[:newlen]
- ind.conditionVars = ind.conditionVars[:newlen]
- ind.checkedFiles = ind.checkedFiles[:newlen]
+ ind.levels = ind.levels[:ind.Len()-1]
}
-func (ind *Indentation) Push(indent int) {
- ind.depth = append(ind.depth, indent)
- ind.conditionVars = append(ind.conditionVars, nil)
- ind.checkedFiles = append(ind.checkedFiles, nil)
+func (ind *Indentation) Push(indent int, condition string) {
+ ind.levels = append(ind.levels, indentationLevel{indent, condition, nil, nil})
}
func (ind *Indentation) AddVar(varname string) {
- level := ind.Len() - 1
- if hasSuffix(varname, "_MK") {
- return
- }
- for _, existingVarname := range ind.conditionVars[level] {
+ vars := &ind.top().conditionVars
+ for _, existingVarname := range *vars {
if varname == existingVarname {
return
}
}
- ind.conditionVars[level] = append(ind.conditionVars[level], varname)
+ *vars = append(*vars, varname)
}
func (ind *Indentation) DependsOn(varname string) bool {
- for _, levelVarnames := range ind.conditionVars {
- for _, levelVarname := range levelVarnames {
+ for _, level := range ind.levels {
+ for _, levelVarname := range level.conditionVars {
if varname == levelVarname {
return true
}
@@ -788,34 +818,46 @@
}
func (ind *Indentation) IsConditional() bool {
- for _, vars := range ind.conditionVars {
- if len(vars) > 0 {
- return true
+ for _, level := range ind.levels {
+ for _, varname := range level.conditionVars {
+ if !hasSuffix(varname, "_MK") {
+ return true
+ }
}
}
return false
}
+// Varnames returns the list of all variables that are mentioned in any
+// condition or loop surrounding the current line.
+// Variables named *_MK are excluded since they are usually not interesting.
func (ind *Indentation) Varnames() string {
sep := ""
varnames := ""
- for _, levelVarnames := range ind.conditionVars {
- for _, levelVarname := range levelVarnames {
- varnames += sep + levelVarname
- sep = ", "
+ for _, level := range ind.levels {
+ for _, levelVarname := range level.conditionVars {
+ if !hasSuffix(levelVarname, "_MK") {
+ varnames += sep + levelVarname
+ sep = ", "
+ }
}
}
return varnames
}
+// Condition returns the condition for the innermost .if, .elif or .for.
+func (ind *Indentation) Condition() string {
+ return ind.top().condition
+}
+
func (ind *Indentation) AddCheckedFile(filename string) {
- level := ind.Len() - 1
- ind.checkedFiles[level] = append(ind.checkedFiles[level], filename)
+ top := ind.top()
+ top.checkedFiles = append(top.checkedFiles, filename)
}
func (ind *Indentation) IsCheckedFile(filename string) bool {
- for _, levelFilenames := range ind.checkedFiles {
- for _, levelFilename := range levelFilenames {
+ for _, level := range ind.levels {
+ for _, levelFilename := range level.checkedFiles {
if filename == levelFilename {
return true
}
@@ -824,6 +866,68 @@
return false
}
+func (ind *Indentation) TrackBefore(mkline MkLine) {
+ if !mkline.IsCond() {
+ return
+ }
+ if trace.Tracing {
+ trace.Stepf("Indentation before line %s: %+v", mkline.Linenos(), ind.levels)
+ }
+
+ directive := mkline.Directive()
+ args := mkline.Args()
+
+ switch directive {
+ case "for", "if", "ifdef", "ifndef":
+ ind.Push(ind.top().depth, args)
+ }
Home |
Main Index |
Thread Index |
Old Index