From e51ad2c3d0c68e1f9662e9f5444ba4f079cc0c74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 07:25:33 +0100 Subject: [PATCH] Bump mvdan.cc/sh/v3 from 3.8.0 to 3.9.0 (#1505) Bumps [mvdan.cc/sh/v3](https://github.com/mvdan/sh) from 3.8.0 to 3.9.0. - [Release notes](https://github.com/mvdan/sh/releases) - [Changelog](https://github.com/mvdan/sh/blob/master/CHANGELOG.md) - [Commits](https://github.com/mvdan/sh/compare/v3.8.0...v3.9.0) --- updated-dependencies: - dependency-name: mvdan.cc/sh/v3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 5 +- go.sum | 11 +- vendor/github.com/pkg/diff/LICENSE | 11 - vendor/github.com/pkg/diff/ctxt/size.go | 92 ----- vendor/github.com/pkg/diff/ctxt/todo.go | 6 - vendor/github.com/pkg/diff/diff.go | 138 -------- vendor/github.com/pkg/diff/edit/edit.go | 118 ------- vendor/github.com/pkg/diff/edit/op_string.go | 26 -- vendor/github.com/pkg/diff/fuzz.go | 47 --- vendor/github.com/pkg/diff/intern/intern.go | 25 -- vendor/github.com/pkg/diff/myers/myers.go | 184 ---------- vendor/github.com/pkg/diff/readme.md | 29 -- vendor/github.com/pkg/diff/todo.go | 43 --- vendor/github.com/pkg/diff/write/option.go | 39 --- vendor/github.com/pkg/diff/write/todo.go | 7 - vendor/github.com/pkg/diff/write/unified.go | 176 ---------- .../rogpeppe/go-internal/diff/diff.go | 261 ++++++++++++++ vendor/modules.txt | 17 +- vendor/mvdan.cc/sh/v3/cmd/shfmt/Dockerfile | 2 +- vendor/mvdan.cc/sh/v3/cmd/shfmt/main.go | 66 ++-- vendor/mvdan.cc/sh/v3/cmd/shfmt/shfmt.1.scd | 9 +- vendor/mvdan.cc/sh/v3/syntax/lexer.go | 31 +- vendor/mvdan.cc/sh/v3/syntax/nodes.go | 10 +- vendor/mvdan.cc/sh/v3/syntax/parser.go | 93 ++--- vendor/mvdan.cc/sh/v3/syntax/parser_arithm.go | 6 +- vendor/mvdan.cc/sh/v3/syntax/printer.go | 330 +++++++++--------- vendor/mvdan.cc/sh/v3/syntax/simplify.go | 62 ++-- vendor/mvdan.cc/sh/v3/syntax/walk.go | 197 ++++++----- 28 files changed, 679 insertions(+), 1362 deletions(-) delete mode 100644 vendor/github.com/pkg/diff/LICENSE delete mode 100644 vendor/github.com/pkg/diff/ctxt/size.go delete mode 100644 vendor/github.com/pkg/diff/ctxt/todo.go delete mode 100644 vendor/github.com/pkg/diff/diff.go delete mode 100644 vendor/github.com/pkg/diff/edit/edit.go delete mode 100644 vendor/github.com/pkg/diff/edit/op_string.go delete mode 100644 vendor/github.com/pkg/diff/fuzz.go delete mode 100644 vendor/github.com/pkg/diff/intern/intern.go delete mode 100644 vendor/github.com/pkg/diff/myers/myers.go delete mode 100644 vendor/github.com/pkg/diff/readme.md delete mode 100644 vendor/github.com/pkg/diff/todo.go delete mode 100644 vendor/github.com/pkg/diff/write/option.go delete mode 100644 vendor/github.com/pkg/diff/write/todo.go delete mode 100644 vendor/github.com/pkg/diff/write/unified.go create mode 100644 vendor/github.com/rogpeppe/go-internal/diff/diff.go diff --git a/go.mod b/go.mod index c5f77064a..c0fb4c21e 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( k8s.io/code-generator v0.30.3 k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 - mvdan.cc/sh/v3 v3.8.0 + mvdan.cc/sh/v3 v3.9.0 sigs.k8s.io/controller-runtime v0.18.5 sigs.k8s.io/controller-tools v0.15.0 sigs.k8s.io/yaml v1.4.0 @@ -245,7 +245,6 @@ require ( github.com/oklog/ulid v1.3.1 // indirect github.com/pelletier/go-toml/v2 v2.2.0 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect - github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polyfloyd/go-errorlint v1.4.8 // indirect @@ -344,7 +343,7 @@ require ( honnef.co/go/tools v0.4.7 // indirect k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect k8s.io/klog/v2 v2.130.1 // indirect - mvdan.cc/editorconfig v0.2.1-0.20231228180347-1925077f8eb2 // indirect + mvdan.cc/editorconfig v0.3.0 // indirect mvdan.cc/gofumpt v0.6.0 // indirect mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect diff --git a/go.sum b/go.sum index 8169a410c..e554951ec 100644 --- a/go.sum +++ b/go.sum @@ -458,6 +458,8 @@ github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9F github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= +github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-swagger/go-swagger v0.30.5 h1:SQ2+xSonWjjoEMOV5tcOnZJVlfyUfCBhGQGArS1b9+U= github.com/go-swagger/go-swagger v0.30.5/go.mod h1:cWUhSyCNqV7J1wkkxfr5QmbcnCewetCdvEXqgPvbc/Q= @@ -923,7 +925,6 @@ github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeB github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1868,12 +1869,12 @@ k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f h1:2sXuKesAYbRHxL3aE2PN6z k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -mvdan.cc/editorconfig v0.2.1-0.20231228180347-1925077f8eb2 h1:8nmqQGVnHUtHuT+yvuA49lQK0y5il5IOr2PtCBkDI2M= -mvdan.cc/editorconfig v0.2.1-0.20231228180347-1925077f8eb2/go.mod h1:r8RiQJRtzrPrZdcdEs5VCMqvRxAzYDUu9a4S9z7fKh8= +mvdan.cc/editorconfig v0.3.0 h1:D1D2wLYEYGpawWT5SpM5pRivgEgXjtEXwC9MWhEY0gQ= +mvdan.cc/editorconfig v0.3.0/go.mod h1:NcJHuDtNOTEJ6251indKiWuzK6+VcrMuLzGMLKBFupQ= mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo= mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA= -mvdan.cc/sh/v3 v3.8.0 h1:ZxuJipLZwr/HLbASonmXtcvvC9HXY9d2lXZHnKGjFc8= -mvdan.cc/sh/v3 v3.8.0/go.mod h1:w04623xkgBVo7/IUK89E0g8hBykgEpN0vgOj3RJr6MY= +mvdan.cc/sh/v3 v3.9.0 h1:it14fyjCdQUk4jf/aYxLO3FG8jFarR9GzMCtnlvvD7c= +mvdan.cc/sh/v3 v3.9.0/go.mod h1:cdBk8bgoiBI7lSZqK5JhUuq7OB64VQ7fgm85xelw3Nk= mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 h1:zCr3iRRgdk5eIikZNDphGcM6KGVTx3Yu+/Uu9Es254w= mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14/go.mod h1:ZzZjEpJDOmx8TdVU6umamY3Xy0UAQUI2DHbf05USVbI= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/vendor/github.com/pkg/diff/LICENSE b/vendor/github.com/pkg/diff/LICENSE deleted file mode 100644 index 89fd92855..000000000 --- a/vendor/github.com/pkg/diff/LICENSE +++ /dev/null @@ -1,11 +0,0 @@ -Copyright 2018 Joshua Bleecher Snyder - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pkg/diff/ctxt/size.go b/vendor/github.com/pkg/diff/ctxt/size.go deleted file mode 100644 index 67a657ec0..000000000 --- a/vendor/github.com/pkg/diff/ctxt/size.go +++ /dev/null @@ -1,92 +0,0 @@ -// Package ctxt provides routines to reduce the amount of context in an edit script. -package ctxt - -import ( - "github.com/pkg/diff/edit" -) - -// Size returns an edit script preserving only n common elements of context for changes. -// The returned edit script may alias the input. -// If n is negative, Size panics. -func Size(e edit.Script, n int) edit.Script { - if n < 0 { - panic("ctxt.Size called with negative n") - } - - // Handle small scripts. - switch len(e.Ranges) { - case 0: - return edit.Script{} - case 1: - if e.Ranges[0].IsEqual() { - // Entirely identical contents. - // Unclear what to do here. For now, just bail. - // TODO: something else? what does command line diff do? - return edit.Script{} - } - return edit.NewScript(e.Ranges[0]) - } - - out := make([]edit.Range, 0, len(e.Ranges)) - for i, seg := range e.Ranges { - if !seg.IsEqual() { - out = append(out, seg) - continue - } - if i == 0 { - // Leading Range. Keep only the final n entries. - if seg.Len() > n { - seg = rangeLastN(seg, n) - } - out = append(out, seg) - continue - } - if i == len(e.Ranges)-1 { - // Trailing Range. Keep only the first n entries. - if seg.Len() > n { - seg = rangeFirstN(seg, n) - } - out = append(out, seg) - continue - } - if seg.Len() <= n*2 { - // Small middle Range. Keep unchanged. - out = append(out, seg) - continue - } - // Large middle Range. Break into two disjoint parts. - out = append(out, rangeFirstN(seg, n), rangeLastN(seg, n)) - } - - // TODO: Stock macOS diff also trims common blank lines - // from the beginning/end of eq IndexRangess. - // Perhaps we should do that here too. - // Or perhaps that should be a separate, composable function? - return edit.Script{Ranges: out} -} - -func rangeFirstN(seg edit.Range, n int) edit.Range { - if !seg.IsEqual() { - panic("rangeFirstN bad op") - } - if seg.Len() < n { - panic("rangeFirstN bad Len") - } - return edit.Range{ - LowA: seg.LowA, HighA: seg.LowA + n, - LowB: seg.LowB, HighB: seg.LowB + n, - } -} - -func rangeLastN(seg edit.Range, n int) edit.Range { - if !seg.IsEqual() { - panic("rangeLastN bad op") - } - if seg.Len() < n { - panic("rangeLastN bad Len") - } - return edit.Range{ - LowA: seg.HighA - n, HighA: seg.HighA, - LowB: seg.HighB - n, HighB: seg.HighB, - } -} diff --git a/vendor/github.com/pkg/diff/ctxt/todo.go b/vendor/github.com/pkg/diff/ctxt/todo.go deleted file mode 100644 index dd03ba6bb..000000000 --- a/vendor/github.com/pkg/diff/ctxt/todo.go +++ /dev/null @@ -1,6 +0,0 @@ -package ctxt - -// TODO: the standard way to reduce context is to a fixed number of lines around changes. -// But it would be better to be more flexible, to try to match human needs. -// For example, if I deleted the first line of a function, I don't need three full lines of "before" context; -// it should truncate at the function declaration. diff --git a/vendor/github.com/pkg/diff/diff.go b/vendor/github.com/pkg/diff/diff.go deleted file mode 100644 index 263842bcc..000000000 --- a/vendor/github.com/pkg/diff/diff.go +++ /dev/null @@ -1,138 +0,0 @@ -// Package diff contains high level routines that generate a textual diff. -// -// It is implemented in terms of the other packages in this module. -// If you want fine-grained control, -// want to inspect a diff programmatically, -// want to provide a context for cancellation, -// need to diff gigantic files that don't fit in memory, -// or want to diff unusual things, -// use the lower level packages. -package diff - -import ( - "bufio" - "bytes" - "context" - "fmt" - "io" - "os" - "reflect" - "strings" - - "github.com/pkg/diff/ctxt" - "github.com/pkg/diff/intern" - "github.com/pkg/diff/myers" - "github.com/pkg/diff/write" -) - -// lines returns the lines contained in text/filename. -// text and filename are interpreted as described in the docs for Text. -func lines(m intern.Strings, filename string, text interface{}) ([]*string, error) { - var r io.Reader - switch text := text.(type) { - case nil: - f, err := os.Open(filename) - if err != nil { - return nil, err - } - defer f.Close() - r = f - case string: - r = strings.NewReader(text) - case []byte: - r = bytes.NewReader(text) - case io.Reader: - r = text - default: - return nil, fmt.Errorf("unexpected type %T, want string, []byte, io.Reader, or nil", text) - } - var x []*string - scan := bufio.NewScanner(r) - for scan.Scan() { - x = append(x, m.FromBytes(scan.Bytes())) - } - return x, scan.Err() -} - -// addNames adds a Names write.Option using aName and bName, -// taking care to put it at the end, -// so as not to overwrite any competing option. -func addNames(aName, bName string, options []write.Option) []write.Option { - opts := make([]write.Option, len(options)+1) - opts[0] = write.Names(aName, bName) - copy(opts[1:], options) - return opts -} - -// Text diffs a and b and writes the result to w. -// It treats a and b as text, and splits their contents -// into lines using bufio.ScanLines. -// aFile and bFile are filenames to use in the output. -// -// a and b each may be nil or may have type string, []byte, or io.Reader. -// If nil, the text is read from the filename. -func Text(aFile, bFile string, a, b interface{}, w io.Writer, options ...write.Option) error { - m := make(intern.Strings) - aLines, err := lines(m, aFile, a) - if err != nil { - return err - } - bLines, err := lines(m, bFile, b) - if err != nil { - return err - } - ab := &diffStrings{a: aLines, b: bLines} - s := myers.Diff(context.Background(), ab) - s = ctxt.Size(s, 3) - opts := addNames(aFile, bFile, options) - err = write.Unified(s, w, ab, opts...) - return err -} - -type diffStrings struct { - a, b []*string -} - -func (ab *diffStrings) LenA() int { return len(ab.a) } -func (ab *diffStrings) LenB() int { return len(ab.b) } -func (ab *diffStrings) Equal(ai, bi int) bool { return ab.a[ai] == ab.b[bi] } -func (ab *diffStrings) WriteATo(w io.Writer, i int) (int, error) { return io.WriteString(w, *ab.a[i]) } -func (ab *diffStrings) WriteBTo(w io.Writer, i int) (int, error) { return io.WriteString(w, *ab.b[i]) } - -// Slices diffs slices a and b and writes the result to w. -// It uses fmt.Print to print the elements of a and b. -// It uses reflect.DeepEqual to compare elements of a and b. -// It uses aName and bName as the names of a and b in the output. -func Slices(aName, bName string, a, b interface{}, w io.Writer, options ...write.Option) error { - ab := &diffSlices{a: reflect.ValueOf(a), b: reflect.ValueOf(b)} - if err := ab.validateTypes(); err != nil { - return err - } - s := myers.Diff(context.Background(), ab) - s = ctxt.Size(s, 3) - opts := addNames(aName, bName, options) - err := write.Unified(s, w, ab, opts...) - return err -} - -type diffSlices struct { - a, b reflect.Value -} - -func (ab *diffSlices) LenA() int { return ab.a.Len() } -func (ab *diffSlices) LenB() int { return ab.b.Len() } -func (ab *diffSlices) atA(i int) interface{} { return ab.a.Index(i).Interface() } -func (ab *diffSlices) atB(i int) interface{} { return ab.b.Index(i).Interface() } -func (ab *diffSlices) Equal(ai, bi int) bool { return reflect.DeepEqual(ab.atA(ai), ab.atB(bi)) } -func (ab *diffSlices) WriteATo(w io.Writer, i int) (int, error) { return fmt.Fprint(w, ab.atA(i)) } -func (ab *diffSlices) WriteBTo(w io.Writer, i int) (int, error) { return fmt.Fprint(w, ab.atB(i)) } - -func (ab *diffSlices) validateTypes() error { - if t := ab.a.Type(); t.Kind() != reflect.Slice { - return fmt.Errorf("a has type %v, must be a slice", t) - } - if t := ab.b.Type(); t.Kind() != reflect.Slice { - return fmt.Errorf("b has type %v, must be a slice", t) - } - return nil -} diff --git a/vendor/github.com/pkg/diff/edit/edit.go b/vendor/github.com/pkg/diff/edit/edit.go deleted file mode 100644 index 7aab1733d..000000000 --- a/vendor/github.com/pkg/diff/edit/edit.go +++ /dev/null @@ -1,118 +0,0 @@ -// Package edit provides edit scripts. -// Edit scripts are a core notion for diffs. -// They represent a way to go from A to B by a sequence -// of insertions, deletions, and equal elements. -package edit - -import ( - "fmt" - "strings" -) - -// A Script is an edit script to alter A into B. -type Script struct { - Ranges []Range -} - -// NewScript returns a Script containing the ranges r. -// It is only a convenience wrapper used to reduce line noise. -func NewScript(r ...Range) Script { - return Script{Ranges: r} -} - -// IsIdentity reports whether s is the identity edit script, -// that is, whether A and B are identical. -func (s *Script) IsIdentity() bool { - for _, r := range s.Ranges { - if !r.IsEqual() { - return false - } - } - return true -} - -// Stat reports the total number of insertions and deletions in s. -func (s *Script) Stat() (ins, del int) { - for _, r := range s.Ranges { - switch { - case r.IsDelete(): - del += r.HighA - r.LowA - case r.IsInsert(): - ins += r.HighB - r.LowB - } - } - return ins, del -} - -// dump formats s for debugging. -func (s *Script) dump() string { - buf := new(strings.Builder) - for _, r := range s.Ranges { - fmt.Fprintln(buf, r) - } - return buf.String() -} - -// A Range is a pair of clopen index ranges. -// It represents the elements A[LowA:HighA] and B[LowB:HighB]. -type Range struct { - LowA, HighA int - LowB, HighB int -} - -// IsInsert reports whether r represents an insertion in a Script. -// If so, the inserted elements are B[LowB:HighB]. -func (r *Range) IsInsert() bool { - return r.LowA == r.HighA -} - -// IsDelete reports whether r represents a deletion in a Script. -// If so, the deleted elements are A[LowA:HighA]. -func (r *Range) IsDelete() bool { - return r.LowB == r.HighB -} - -// IsEqual reports whether r represents a series of equal elements in a Script. -// If so, the elements A[LowA:HighA] are equal to the elements B[LowB:HighB]. -func (r *Range) IsEqual() bool { - return r.HighB-r.LowB == r.HighA-r.LowA -} - -// An Op is a edit operation in a Script. -type Op int8 - -//go:generate stringer -type Op - -const ( - Del Op = -1 // delete - Eq Op = 0 // equal - Ins Op = 1 // insert -) - -// Op reports what kind of operation r represents. -// This can also be determined by calling r.IsInsert, -// r.IsDelete, and r.IsEqual, -// but this form is sometimes more convenient to use. -func (r *Range) Op() Op { - if r.IsInsert() { - return Ins - } - if r.IsDelete() { - return Del - } - if r.IsEqual() { - return Eq - } - panic("malformed Range") -} - -// Len reports the number of elements in r. -// In a deletion, it is the number of deleted elements. -// In an insertion, it is the number of inserted elements. -// For equal elements, it is the number of equal elements. -func (r *Range) Len() int { - if r.LowA == r.HighA { - return r.HighB - r.LowB - } - return r.HighA - r.LowA -} diff --git a/vendor/github.com/pkg/diff/edit/op_string.go b/vendor/github.com/pkg/diff/edit/op_string.go deleted file mode 100644 index 9560eaa7e..000000000 --- a/vendor/github.com/pkg/diff/edit/op_string.go +++ /dev/null @@ -1,26 +0,0 @@ -// Code generated by "stringer -type Op"; DO NOT EDIT. - -package edit - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[Del - -1] - _ = x[Eq-0] - _ = x[Ins-1] -} - -const _Op_name = "DelEqIns" - -var _Op_index = [...]uint8{0, 3, 5, 8} - -func (i Op) String() string { - i -= -1 - if i < 0 || i >= Op(len(_Op_index)-1) { - return "Op(" + strconv.FormatInt(int64(i+-1), 10) + ")" - } - return _Op_name[_Op_index[i]:_Op_index[i+1]] -} diff --git a/vendor/github.com/pkg/diff/fuzz.go b/vendor/github.com/pkg/diff/fuzz.go deleted file mode 100644 index 2d54e67f9..000000000 --- a/vendor/github.com/pkg/diff/fuzz.go +++ /dev/null @@ -1,47 +0,0 @@ -// +build gofuzz - -package diff - -import ( - "bytes" - "context" - "io" - "io/ioutil" - - "github.com/pkg/diff/ctxt" - "github.com/pkg/diff/myers" - "github.com/pkg/diff/write" -) - -func Fuzz(data []byte) int { - if len(data) < 2 { - return -1 - } - sz := int(data[0]) - data = data[1:] - - nul := bytes.IndexByte(data, 0) - if nul == -1 { - nul = len(data) - 1 - } - a := data[:nul] - b := data[nul:] - ab := &IndividualBytes{a: a, b: b} - s := myers.Diff(context.Background(), ab) - s = ctxt.Size(s, sz) - err := write.Unified(s, ioutil.Discard, ab) - if err != nil { - panic(err) - } - return 0 -} - -type IndividualBytes struct { - a, b []byte -} - -func (ab *IndividualBytes) LenA() int { return len(ab.a) } -func (ab *IndividualBytes) LenB() int { return len(ab.b) } -func (ab *IndividualBytes) Equal(ai, bi int) bool { return ab.a[ai] == ab.b[bi] } -func (ab *IndividualBytes) WriteATo(w io.Writer, i int) (int, error) { return w.Write([]byte{ab.a[i]}) } -func (ab *IndividualBytes) WriteBTo(w io.Writer, i int) (int, error) { return w.Write([]byte{ab.b[i]}) } diff --git a/vendor/github.com/pkg/diff/intern/intern.go b/vendor/github.com/pkg/diff/intern/intern.go deleted file mode 100644 index 0f2f7a2b8..000000000 --- a/vendor/github.com/pkg/diff/intern/intern.go +++ /dev/null @@ -1,25 +0,0 @@ -// Package intern provides string interning. -// -// Unlike much string interning, the routines in this package -// return *string instead of string. This enables extremely -// cheap (compare only a pointer) comparisons of any strings -// interned by this package. Since diff algorithms involve -// many string comparisons, this often ends up paying for the -// cost of the interning. Also, in the typical case, -// diffs involve lots of repeated lines (most of the file -// contents are typically unchanged, so any give line -// appears at least twice), so string interning saves memory. -package intern - -type Strings map[string]*string - -func (m Strings) FromBytes(b []byte) *string { - p, ok := m[string(b)] - if ok { - return p - } - s := string(b) - p = &s - m[s] = p - return p -} diff --git a/vendor/github.com/pkg/diff/myers/myers.go b/vendor/github.com/pkg/diff/myers/myers.go deleted file mode 100644 index de75336de..000000000 --- a/vendor/github.com/pkg/diff/myers/myers.go +++ /dev/null @@ -1,184 +0,0 @@ -// Package myers implements the Myers diff algorithm. -package myers - -import ( - "context" - "fmt" - - "github.com/pkg/diff/edit" -) - -// A Pair is two things that can be diffed using the Myers diff algorithm. -// A is the initial state; B is the final state. -type Pair interface { - // LenA returns the number of initial elements. - LenA() int - // LenB returns the number of final elements. - LenB() int - // Equal reports whether the aᵢ'th element of A is equal to the bᵢ'th element of B. - Equal(ai, bi int) bool -} - -// Diff calculates an edit.Script for ab using the Myers diff algorithm. -// This implementation uses the algorithm described in the first half -// of Myers' paper, which requires quadratric space. -// (An implementation of the linear space version is forthcoming.) -// -// Because diff calculation can be expensive, Myers supports cancellation via ctx. -func Diff(ctx context.Context, ab Pair) edit.Script { - aLen := ab.LenA() - bLen := ab.LenB() - if aLen == 0 { - return edit.NewScript(edit.Range{HighB: bLen}) - } - if bLen == 0 { - return edit.NewScript(edit.Range{HighA: aLen}) - } - - max := aLen + bLen - if max < 0 { - panic("overflow in myers.Diff") - } - // v has indices -max .. 0 .. max - // access to elements of v have the form max + actual offset - v := make([]int, 2*max+1) - - var trace [][]int -search: - for d := 0; d < max; d++ { - // Only check context every 16th iteration to reduce overhead. - if ctx != nil && uint(d)%16 == 0 && ctx.Err() != nil { - return edit.Script{} - } - - // append the middle (populated) elements of v to trace - middle := v[max-d : max+d+1] - vcopy := make([]int, len(middle)) - copy(vcopy, middle) - trace = append(trace, vcopy) - - for k := -d; k <= d; k += 2 { - var x int - if k == -d || (k != d && v[max+k-1] < v[max+k+1]) { - x = v[max+k+1] - } else { - x = v[max+k-1] + 1 - } - - y := x - k - for x < aLen && y < bLen && ab.Equal(x, y) { - x++ - y++ - } - v[max+k] = x - - if x == aLen && y == bLen { - break search - } - } - } - - if len(trace) == max { - // No commonality at all, delete everything and then insert everything. - // This is handled as a special case to avoid complicating the logic below. - return edit.NewScript(edit.Range{HighA: aLen}, edit.Range{HighB: bLen}) - } - - // Create reversed edit script. - x := aLen - y := bLen - var e edit.Script - for d := len(trace) - 1; d >= 0; d-- { - // v has indices -d .. 0 .. d - // access to elements of v have the form d + actual offset - v := trace[d] - k := x - y - var prevk int - if k == -d || (k != d && v[d+k-1] < v[d+k+1]) { - prevk = k + 1 - } else { - prevk = k - 1 - } - var prevx int - if idx := d + prevk; 0 <= idx && idx < len(v) { - prevx = v[idx] - } - prevy := prevx - prevk - for x > prevx && y > prevy { - appendToReversed(&e, edit.Range{LowA: x - 1, LowB: y - 1, HighA: x, HighB: y}) - x-- - y-- - } - if d > 0 { - appendToReversed(&e, edit.Range{LowA: prevx, LowB: prevy, HighA: x, HighB: y}) - } - x, y = prevx, prevy - } - - // Reverse reversed edit script, to return to natural order. - reverse(e) - - // Sanity check - for i := 1; i < len(e.Ranges); i++ { - prevop := e.Ranges[i-1].Op() - currop := e.Ranges[i].Op() - if (prevop == currop) || (prevop == edit.Ins && currop != edit.Eq) || (currop == edit.Del && prevop != edit.Eq) { - panic(fmt.Errorf("bad script: %v -> %v", prevop, currop)) - } - } - - return e -} - -func reverse(e edit.Script) { - for i := 0; i < len(e.Ranges)/2; i++ { - j := len(e.Ranges) - i - 1 - e.Ranges[i], e.Ranges[j] = e.Ranges[j], e.Ranges[i] - } -} - -func appendToReversed(e *edit.Script, seg edit.Range) { - if len(e.Ranges) == 0 { - e.Ranges = append(e.Ranges, seg) - return - } - u, ok := combineRanges(seg, e.Ranges[len(e.Ranges)-1]) - if !ok { - e.Ranges = append(e.Ranges, seg) - return - } - e.Ranges[len(e.Ranges)-1] = u - return -} - -// combineRanges combines s and t into a single edit.Range if possible -// and reports whether it succeeded. -func combineRanges(s, t edit.Range) (u edit.Range, ok bool) { - if t.Len() == 0 { - return s, true - } - if s.Len() == 0 { - return t, true - } - if s.Op() != t.Op() { - return edit.Range{LowA: -1, HighA: -1, LowB: -1, HighB: -1}, false - } - switch s.Op() { - case edit.Ins: - s.HighB = t.HighB - case edit.Del: - s.HighA = t.HighA - case edit.Eq: - s.HighA = t.HighA - s.HighB = t.HighB - default: - panic("bad op") - } - return s, true -} - -func rangeString(r edit.Range) string { - // This output is helpful when hacking on a Myers diff. - // In other contexts it is usually more natural to group LowA, HighA and LowB, HighB. - return fmt.Sprintf("(%d, %d) -- %s %d --> (%d, %d)", r.LowA, r.LowB, r.Op(), r.Len(), r.HighA, r.HighB) -} diff --git a/vendor/github.com/pkg/diff/readme.md b/vendor/github.com/pkg/diff/readme.md deleted file mode 100644 index 7c031f889..000000000 --- a/vendor/github.com/pkg/diff/readme.md +++ /dev/null @@ -1,29 +0,0 @@ -# diff [![GoDoc](https://godoc.org/github.com/pkg/diff?status.svg)](http://godoc.org/github.com/pkg/diff) - -Module github.com/pkg/diff can be used to create, modify, and print diffs. - -The top level package, `diff`, contains convenience functions for the most common uses. - -The subpackages provide very fine-grained control over every aspect: - -* `myers` creates diffs using the Myers diff algorithm. -* `edit` contains the core diff data types. -* `ctxt` provides tools to reduce the amount of context in a diff. -* `write` provides routines to write diffs in standard formats. - -License: BSD 3-Clause. - -### Contributing - -Contributions are welcome. However, I am not always fast to respond. -I apologize for any sadness or frustration that that causes. - -Useful background reading about diffs: - -* [Neil Fraser's website](https://neil.fraser.name/writing/diff) -* [Myers diff paper](http://www.xmailserver.org/diff2.pdf) -* [Guido Van Rossum's reverse engineering of the unified diff format](https://www.artima.com/weblogs/viewpost.jsp?thread=164293) -* [The If Works](https://blog.jcoglan.com/) blog entries about diff algorithms and implementations - -This module has not yet reached v1.0; -the API is not yet settled (issue #18). diff --git a/vendor/github.com/pkg/diff/todo.go b/vendor/github.com/pkg/diff/todo.go deleted file mode 100644 index acffdf473..000000000 --- a/vendor/github.com/pkg/diff/todo.go +++ /dev/null @@ -1,43 +0,0 @@ -package diff - -// TODO: add a package for diffing gigantic files. -// Instead of reading the entire thing into memory, we could -// scan through the file once, storing the location of all newlines in each file. -// Then Seek/ReadAt to read each line lazily as needed, -// relying on the OS page cache for performance. -// This will allow diffing giant files with low memory use, -// albeit at a some time cost. -// An alternative is to mmap the files, -// although this is OS-specific and can be fiddly. - -// TODO: add a package providing a StringIntern type, something like: -// -// type StringIntern struct { -// s map[string]*string -// } -// -// func (i *StringIntern) Bytes(b []byte) *string -// func (i *StringIntern) String(s string) *string -// -// And document what it is and why to use it. -// And consider adding helper functions to Strings and Bytes to use it. -// The reason to use it is that a lot of the execution time in diffing -// (which is an expensive operation) is taken up doing string comparisons. -// If you have paid the O(n) cost to intern all strings involved in both A and B, -// then string comparisons are reduced to cheap pointer comparisons. - -// TODO: consider adding an "it just works" test helper that accepts two slices (via interface{}), -// diffs them using Strings or Bytes or Slices (using reflect.DeepEqual) as appropriate, -// and calls t.Errorf with a generated diff if they're not equal. - -// TODO: add support for hunk/section/function headers. -// This will probably take the form of a write option -// providing access to the necessary data, -// and a package that helps calculate the necessary data. -// There are several ways to do that calculation... - -// TODO: add copyright headers at top of all files - -// TODO: hook up some CI - -// TODO: add more badges? see github.com/pkg/errors for some likely candidates. diff --git a/vendor/github.com/pkg/diff/write/option.go b/vendor/github.com/pkg/diff/write/option.go deleted file mode 100644 index 9e22b1a98..000000000 --- a/vendor/github.com/pkg/diff/write/option.go +++ /dev/null @@ -1,39 +0,0 @@ -// Package write provides routines for writing diffs. -package write - -// An Option modifies behavior when writing a diff. -type Option interface { - isOption() -} - -// Names provides the before/after names for writing a diff. -// They are traditionally filenames. -func Names(a, b string) Option { - return names{a, b} -} - -type names struct { - a, b string -} - -func (names) isOption() {} - -// TerminalColor specifies that a diff intended -// for a terminal should be written using colors. -// -// Do not use TerminalColor if TERM=dumb is set in the environment. -func TerminalColor() Option { - return colorOpt(true) -} - -type colorOpt bool - -func (colorOpt) isOption() {} - -const ( - ansiBold = "\u001b[1m" - ansiFgRed = "\u001b[31m" - ansiFgGreen = "\u001b[32m" - ansiFgBlue = "\u001b[36m" - ansiReset = "\u001b[0m" -) diff --git a/vendor/github.com/pkg/diff/write/todo.go b/vendor/github.com/pkg/diff/write/todo.go deleted file mode 100644 index eb6c42bdd..000000000 --- a/vendor/github.com/pkg/diff/write/todo.go +++ /dev/null @@ -1,7 +0,0 @@ -package write - -// TODO: add diff writing that uses < and > (don't know what that is called) -// TODO: add side by side diffs -// TODO: add html diffs (?) -// TODO: add intraline highlighting? -// TODO: a way to specify alternative colors, like a ColorScheme write option diff --git a/vendor/github.com/pkg/diff/write/unified.go b/vendor/github.com/pkg/diff/write/unified.go deleted file mode 100644 index ab6403bb2..000000000 --- a/vendor/github.com/pkg/diff/write/unified.go +++ /dev/null @@ -1,176 +0,0 @@ -package write - -import ( - "bufio" - "fmt" - "io" - - "github.com/pkg/diff/edit" -) - -// A Pair supports writing a unified diff, element by element. -// A is the initial state; B is the final state. -type Pair interface { - // WriteATo writes the element a[aᵢ] to w. - WriteATo(w io.Writer, ai int) (int, error) - // WriteBTo writes the element b[bᵢ] to w. - WriteBTo(w io.Writer, bi int) (int, error) -} - -// Unified writes e to w using unified diff format. -// ab writes the individual elements. Opts are optional write arguments. -// Unified returns the number of bytes written and the first error (if any) encountered. -// Before writing, edit scripts usually have their context reduced, -// such as by a call to ctxt.Size. -func Unified(e edit.Script, w io.Writer, ab Pair, opts ...Option) error { - // read opts - nameA := "a" - nameB := "b" - color := false - for _, opt := range opts { - switch opt := opt.(type) { - case names: - nameA = opt.a - nameB = opt.b - case colorOpt: - color = true - // TODO: add date/time/timezone WriteOpts - default: - panic(fmt.Sprintf("unrecognized WriteOpt type %T", opt)) - } - } - - bw := bufio.NewWriter(w) - - needsColorReset := false - - // per-file header - if color { - bw.WriteString(ansiBold) - needsColorReset = true - } - fmt.Fprintf(bw, "--- %s\n", nameA) - fmt.Fprintf(bw, "+++ %s\n", nameB) - - for i := 0; i < len(e.Ranges); { - // Peek into the future to learn the line ranges for this chunk of output. - // A chunk of output ends when there's a discontiguity in the edit script. - var ar, br lineRange - var started [2]bool - var j int - for j = i; j < len(e.Ranges); j++ { - curr := e.Ranges[j] - if !curr.IsInsert() { - if !started[0] { - ar.first = curr.LowA - started[0] = true - } - ar.last = curr.HighA - } - if !curr.IsDelete() { - if !started[1] { - br.first = curr.LowB - started[1] = true - } - br.last = curr.HighB - } - if j+1 >= len(e.Ranges) { - // end of script - break - } - if next := e.Ranges[j+1]; curr.HighA != next.LowA || curr.HighB != next.LowB { - // discontiguous edit script - break - } - } - - // Print chunk header. - // TODO: add per-chunk context, like what function we're in - // But how do we get this? need to add PairWriter methods? - // Maybe it should be stored in the EditScript, - // and we can have EditScript methods to populate it somehow? - if color { - if needsColorReset { - bw.WriteString(ansiReset) - } - bw.WriteString(ansiFgBlue) - needsColorReset = true - } - fmt.Fprintf(bw, "@@ -%s +%s @@\n", ar, br) - - // Print prefixed lines. - for k := i; k <= j; k++ { - seg := e.Ranges[k] - switch seg.Op() { - case edit.Eq: - if needsColorReset { - bw.WriteString(ansiReset) - } - for m := seg.LowA; m < seg.HighA; m++ { - // " a[m]\n" - bw.WriteByte(' ') - ab.WriteATo(bw, m) - bw.WriteByte('\n') - } - case edit.Del: - if color { - bw.WriteString(ansiFgRed) - needsColorReset = true - } - for m := seg.LowA; m < seg.HighA; m++ { - // "-a[m]\n" - bw.WriteByte('-') - ab.WriteATo(bw, m) - bw.WriteByte('\n') - } - case edit.Ins: - if color { - bw.WriteString(ansiFgGreen) - needsColorReset = true - } - for m := seg.LowB; m < seg.HighB; m++ { - // "+b[m]\n" - bw.WriteByte('+') - ab.WriteBTo(bw, m) - bw.WriteByte('\n') - } - } - } - - // Advance to next chunk. - i = j + 1 - - // TODO: break if error detected? - } - - // Always finish the output with no color, to prevent "leaking" the - // color into any output that follows a diff. - if needsColorReset { - bw.WriteString(ansiReset) - } - - // TODO: - // If the last line of a file doesn't end in a newline character, - // it is displayed with a newline character, - // and the following line in the chunk has the literal text (starting in the first column): - // '\ No newline at end of file' - - return bw.Flush() -} - -type lineRange struct { - first, last int -} - -func (r lineRange) String() string { - len := r.last - r.first - r.first++ // 1-based index, safe to modify r directly because it is a value - if len <= 0 { - r.first-- // for no obvious reason, empty ranges are "before" the range - } - return fmt.Sprintf("%d,%d", r.first, len) -} - -func (r lineRange) GoString() string { - return fmt.Sprintf("(%d, %d)", r.first, r.last) -} diff --git a/vendor/github.com/rogpeppe/go-internal/diff/diff.go b/vendor/github.com/rogpeppe/go-internal/diff/diff.go new file mode 100644 index 000000000..47b285671 --- /dev/null +++ b/vendor/github.com/rogpeppe/go-internal/diff/diff.go @@ -0,0 +1,261 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package diff + +import ( + "bytes" + "fmt" + "sort" + "strings" +) + +// A pair is a pair of values tracked for both the x and y side of a diff. +// It is typically a pair of line indexes. +type pair struct{ x, y int } + +// Diff returns an anchored diff of the two texts old and new +// in the “unified diff” format. If old and new are identical, +// Diff returns a nil slice (no output). +// +// Unix diff implementations typically look for a diff with +// the smallest number of lines inserted and removed, +// which can in the worst case take time quadratic in the +// number of lines in the texts. As a result, many implementations +// either can be made to run for a long time or cut off the search +// after a predetermined amount of work. +// +// In contrast, this implementation looks for a diff with the +// smallest number of “unique” lines inserted and removed, +// where unique means a line that appears just once in both old and new. +// We call this an “anchored diff” because the unique lines anchor +// the chosen matching regions. An anchored diff is usually clearer +// than a standard diff, because the algorithm does not try to +// reuse unrelated blank lines or closing braces. +// The algorithm also guarantees to run in O(n log n) time +// instead of the standard O(n²) time. +// +// Some systems call this approach a “patience diff,” named for +// the “patience sorting” algorithm, itself named for a solitaire card game. +// We avoid that name for two reasons. First, the name has been used +// for a few different variants of the algorithm, so it is imprecise. +// Second, the name is frequently interpreted as meaning that you have +// to wait longer (to be patient) for the diff, meaning that it is a slower algorithm, +// when in fact the algorithm is faster than the standard one. +func Diff(oldName string, old []byte, newName string, new []byte) []byte { + if bytes.Equal(old, new) { + return nil + } + x := lines(old) + y := lines(new) + + // Print diff header. + var out bytes.Buffer + fmt.Fprintf(&out, "diff %s %s\n", oldName, newName) + fmt.Fprintf(&out, "--- %s\n", oldName) + fmt.Fprintf(&out, "+++ %s\n", newName) + + // Loop over matches to consider, + // expanding each match to include surrounding lines, + // and then printing diff chunks. + // To avoid setup/teardown cases outside the loop, + // tgs returns a leading {0,0} and trailing {len(x), len(y)} pair + // in the sequence of matches. + var ( + done pair // printed up to x[:done.x] and y[:done.y] + chunk pair // start lines of current chunk + count pair // number of lines from each side in current chunk + ctext []string // lines for current chunk + ) + for _, m := range tgs(x, y) { + if m.x < done.x { + // Already handled scanning forward from earlier match. + continue + } + + // Expand matching lines as far possible, + // establishing that x[start.x:end.x] == y[start.y:end.y]. + // Note that on the first (or last) iteration we may (or definitey do) + // have an empty match: start.x==end.x and start.y==end.y. + start := m + for start.x > done.x && start.y > done.y && x[start.x-1] == y[start.y-1] { + start.x-- + start.y-- + } + end := m + for end.x < len(x) && end.y < len(y) && x[end.x] == y[end.y] { + end.x++ + end.y++ + } + + // Emit the mismatched lines before start into this chunk. + // (No effect on first sentinel iteration, when start = {0,0}.) + for _, s := range x[done.x:start.x] { + ctext = append(ctext, "-"+s) + count.x++ + } + for _, s := range y[done.y:start.y] { + ctext = append(ctext, "+"+s) + count.y++ + } + + // If we're not at EOF and have too few common lines, + // the chunk includes all the common lines and continues. + const C = 3 // number of context lines + if (end.x < len(x) || end.y < len(y)) && + (end.x-start.x < C || (len(ctext) > 0 && end.x-start.x < 2*C)) { + for _, s := range x[start.x:end.x] { + ctext = append(ctext, " "+s) + count.x++ + count.y++ + } + done = end + continue + } + + // End chunk with common lines for context. + if len(ctext) > 0 { + n := end.x - start.x + if n > C { + n = C + } + for _, s := range x[start.x : start.x+n] { + ctext = append(ctext, " "+s) + count.x++ + count.y++ + } + done = pair{start.x + n, start.y + n} + + // Format and emit chunk. + // Convert line numbers to 1-indexed. + // Special case: empty file shows up as 0,0 not 1,0. + if count.x > 0 { + chunk.x++ + } + if count.y > 0 { + chunk.y++ + } + fmt.Fprintf(&out, "@@ -%d,%d +%d,%d @@\n", chunk.x, count.x, chunk.y, count.y) + for _, s := range ctext { + out.WriteString(s) + } + count.x = 0 + count.y = 0 + ctext = ctext[:0] + } + + // If we reached EOF, we're done. + if end.x >= len(x) && end.y >= len(y) { + break + } + + // Otherwise start a new chunk. + chunk = pair{end.x - C, end.y - C} + for _, s := range x[chunk.x:end.x] { + ctext = append(ctext, " "+s) + count.x++ + count.y++ + } + done = end + } + + return out.Bytes() +} + +// lines returns the lines in the file x, including newlines. +// If the file does not end in a newline, one is supplied +// along with a warning about the missing newline. +func lines(x []byte) []string { + l := strings.SplitAfter(string(x), "\n") + if l[len(l)-1] == "" { + l = l[:len(l)-1] + } else { + // Treat last line as having a message about the missing newline attached, + // using the same text as BSD/GNU diff (including the leading backslash). + l[len(l)-1] += "\n\\ No newline at end of file\n" + } + return l +} + +// tgs returns the pairs of indexes of the longest common subsequence +// of unique lines in x and y, where a unique line is one that appears +// once in x and once in y. +// +// The longest common subsequence algorithm is as described in +// Thomas G. Szymanski, “A Special Case of the Maximal Common +// Subsequence Problem,” Princeton TR #170 (January 1975), +// available at https://research.swtch.com/tgs170.pdf. +func tgs(x, y []string) []pair { + // Count the number of times each string appears in a and b. + // We only care about 0, 1, many, counted as 0, -1, -2 + // for the x side and 0, -4, -8 for the y side. + // Using negative numbers now lets us distinguish positive line numbers later. + m := make(map[string]int) + for _, s := range x { + if c := m[s]; c > -2 { + m[s] = c - 1 + } + } + for _, s := range y { + if c := m[s]; c > -8 { + m[s] = c - 4 + } + } + + // Now unique strings can be identified by m[s] = -1+-4. + // + // Gather the indexes of those strings in x and y, building: + // xi[i] = increasing indexes of unique strings in x. + // yi[i] = increasing indexes of unique strings in y. + // inv[i] = index j such that x[xi[i]] = y[yi[j]]. + var xi, yi, inv []int + for i, s := range y { + if m[s] == -1+-4 { + m[s] = len(yi) + yi = append(yi, i) + } + } + for i, s := range x { + if j, ok := m[s]; ok && j >= 0 { + xi = append(xi, i) + inv = append(inv, j) + } + } + + // Apply Algorithm A from Szymanski's paper. + // In those terms, A = J = inv and B = [0, n). + // We add sentinel pairs {0,0}, and {len(x),len(y)} + // to the returned sequence, to help the processing loop. + J := inv + n := len(xi) + T := make([]int, n) + L := make([]int, n) + for i := range T { + T[i] = n + 1 + } + for i := 0; i < n; i++ { + k := sort.Search(n, func(k int) bool { + return T[k] >= J[i] + }) + T[k] = J[i] + L[i] = k + 1 + } + k := 0 + for _, v := range L { + if k < v { + k = v + } + } + seq := make([]pair, 2+k) + seq[1+k] = pair{len(x), len(y)} // sentinel at end + lastj := n + for i := n - 1; i >= 0; i-- { + if L[i] == k && J[i] < lastj { + seq[k] = pair{xi[i], yi[J[i]]} + k-- + } + } + seq[0] = pair{0, 0} // sentinel at start + return seq +} diff --git a/vendor/modules.txt b/vendor/modules.txt index ce91181c3..017cc90ff 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -949,14 +949,6 @@ github.com/pelletier/go-toml/v2/unstable # github.com/peterbourgon/diskv v2.0.1+incompatible ## explicit github.com/peterbourgon/diskv -# github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e -## explicit; go 1.15 -github.com/pkg/diff -github.com/pkg/diff/ctxt -github.com/pkg/diff/edit -github.com/pkg/diff/intern -github.com/pkg/diff/myers -github.com/pkg/diff/write # github.com/pkg/errors v0.9.1 ## explicit github.com/pkg/errors @@ -1024,6 +1016,7 @@ github.com/rivo/uniseg github.com/rodaine/hclencoder # github.com/rogpeppe/go-internal v1.12.0 ## explicit; go 1.20 +github.com/rogpeppe/go-internal/diff github.com/rogpeppe/go-internal/fmtsort # github.com/russross/blackfriday/v2 v2.1.0 ## explicit @@ -2222,8 +2215,8 @@ k8s.io/utils/pointer k8s.io/utils/ptr k8s.io/utils/strings/slices k8s.io/utils/trace -# mvdan.cc/editorconfig v0.2.1-0.20231228180347-1925077f8eb2 -## explicit; go 1.20 +# mvdan.cc/editorconfig v0.3.0 +## explicit; go 1.21 mvdan.cc/editorconfig # mvdan.cc/gofumpt v0.6.0 ## explicit; go 1.20 @@ -2232,8 +2225,8 @@ mvdan.cc/gofumpt/internal/govendor/go/doc/comment mvdan.cc/gofumpt/internal/govendor/go/format mvdan.cc/gofumpt/internal/govendor/go/printer mvdan.cc/gofumpt/internal/version -# mvdan.cc/sh/v3 v3.8.0 -## explicit; go 1.21 +# mvdan.cc/sh/v3 v3.9.0 +## explicit; go 1.22 mvdan.cc/sh/v3/cmd/shfmt mvdan.cc/sh/v3/fileutil mvdan.cc/sh/v3/syntax diff --git a/vendor/mvdan.cc/sh/v3/cmd/shfmt/Dockerfile b/vendor/mvdan.cc/sh/v3/cmd/shfmt/Dockerfile index bf5084dc3..604bab48f 100644 --- a/vendor/mvdan.cc/sh/v3/cmd/shfmt/Dockerfile +++ b/vendor/mvdan.cc/sh/v3/cmd/shfmt/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.22.0-alpine AS build +FROM golang:1.23.0-alpine AS build WORKDIR /src RUN apk add --no-cache git diff --git a/vendor/mvdan.cc/sh/v3/cmd/shfmt/main.go b/vendor/mvdan.cc/sh/v3/cmd/shfmt/main.go index 51fcbbc0f..78a6b35ca 100644 --- a/vendor/mvdan.cc/sh/v3/cmd/shfmt/main.go +++ b/vendor/mvdan.cc/sh/v3/cmd/shfmt/main.go @@ -18,8 +18,7 @@ import ( "strings" maybeio "github.com/google/renameio/v2/maybe" - diffpkg "github.com/pkg/diff" - diffwrite "github.com/pkg/diff/write" + diffpkg "github.com/rogpeppe/go-internal/diff" "golang.org/x/term" "mvdan.cc/editorconfig" @@ -64,13 +63,10 @@ var ( parser *syntax.Parser printer *syntax.Printer readBuf, writeBuf bytes.Buffer + color bool copyBuf = make([]byte, 32*1024) - in io.Reader = os.Stdin - out io.Writer = os.Stdout - color bool - version = "(devel)" // to match the default from runtime/debug allFlags = []any{ @@ -186,10 +182,6 @@ For more information, see 'man shfmt' and https://github.com/mvdan/sh. if minify.val { simplify.val = true } - // TODO(mvdan): remove sometime in 2024. - if os.Getenv("SHFMT_NO_EDITORCONFIG") == "true" { - fmt.Fprintln(os.Stderr, "SHFMT_NO_EDITORCONFIG was always undocumented; use any parser or printer flag to disable editorconfig support") - } flag.Visit(func(f *flag.Flag) { switch f.Name { case lang.short, lang.long, @@ -225,7 +217,7 @@ For more information, see 'man shfmt' and https://github.com/mvdan/sh. if os.Getenv("FORCE_COLOR") != "" { color = true } else if os.Getenv("NO_COLOR") != "" || os.Getenv("TERM") == "dumb" { - } else if f, ok := out.(*os.File); ok && term.IsTerminal(int(f.Fd())) { + } else if term.IsTerminal(int(os.Stdout.Fd())) { color = true } if flag.NArg() == 0 || (flag.NArg() == 1 && flag.Arg(0) == "-") { @@ -307,7 +299,7 @@ func formatStdin(name string) error { return nil } } - src, err := io.ReadAll(in) + src, err := io.ReadAll(os.Stdin) if err != nil { return err } @@ -429,7 +421,7 @@ func formatPath(path string, checkShebang bool) error { readBuf.Write(copyBuf[:n]) } if find.val { - fmt.Fprintln(out, path) + fmt.Println(path) return nil } if _, err := io.CopyBuffer(&readBuf, f, copyBuf); err != nil { @@ -486,16 +478,14 @@ func formatBytes(src []byte, path string, fileLang syntax.LangVariant) error { // must be standard input; fine to return // TODO: change the default behavior to be compact, // and allow using --to-json=pretty or --to-json=indent. - return typedjson.EncodeOptions{Indent: "\t"}.Encode(out, node) + return typedjson.EncodeOptions{Indent: "\t"}.Encode(os.Stdout, node) } writeBuf.Reset() printer.Print(&writeBuf, node) res := writeBuf.Bytes() if !bytes.Equal(src, res) { if list.val { - if _, err := fmt.Fprintln(out, path); err != nil { - return err - } + fmt.Println(path) } if write.val { info, err := os.Lstat(path) @@ -509,20 +499,46 @@ func formatBytes(src []byte, path string, fileLang syntax.LangVariant) error { } } if diff.val { - opts := []diffwrite.Option{} - if color { - opts = append(opts, diffwrite.TerminalColor()) + diffBytes := diffpkg.Diff(path+".orig", src, path, res) + if !color { + os.Stdout.Write(diffBytes) + return errChangedWithDiff } - if err := diffpkg.Text(path+".orig", path, src, res, out, opts...); err != nil { - return fmt.Errorf("computing diff: %s", err) + // The first three lines are the header with the filenames, including --- and +++, + // and are marked in bold. + current := terminalBold + os.Stdout.WriteString(current) + for i, line := range bytes.SplitAfter(diffBytes, []byte("\n")) { + last := current + switch { + case i < 3: // the first three lines are bold + case bytes.HasPrefix(line, []byte("@@")): + current = terminalCyan + case bytes.HasPrefix(line, []byte("-")): + current = terminalRed + case bytes.HasPrefix(line, []byte("+")): + current = terminalGreen + default: + current = terminalReset + } + if current != last { + os.Stdout.WriteString(current) + } + os.Stdout.Write(line) } return errChangedWithDiff } } if !list.val && !write.val && !diff.val { - if _, err := out.Write(res); err != nil { - return err - } + os.Stdout.Write(res) } return nil } + +const ( + terminalGreen = "\u001b[32m" + terminalRed = "\u001b[31m" + terminalCyan = "\u001b[36m" + terminalReset = "\u001b[0m" + terminalBold = "\u001b[1m" +) diff --git a/vendor/mvdan.cc/sh/v3/cmd/shfmt/shfmt.1.scd b/vendor/mvdan.cc/sh/v3/cmd/shfmt/shfmt.1.scd index 84dd2dec0..e47790e94 100644 --- a/vendor/mvdan.cc/sh/v3/cmd/shfmt/shfmt.1.scd +++ b/vendor/mvdan.cc/sh/v3/cmd/shfmt/shfmt.1.scd @@ -25,7 +25,7 @@ predictable. Some aspects of the format can be configured via printer flags. ## Generic flags -*-version* +*--version* Show version and exit. *-l*, *--list* @@ -65,14 +65,17 @@ predictable. Some aspects of the format can be configured via printer flags. If neither come up with a result, *bash* is used as a fallback. The filename extension *.sh* is a special case: it implies *posix*, - but may be overriden by a valid shell shebang. + but may be overridden by a valid shell shebang. *-p*, *--posix* Shorthand for *-ln=posix*. -*-filename* str +*--filename* str Provide a name for the standard input file. + Use of this flag is necessary for EditorConfig support to work with stdin, + since EditorConfig files are found relative to the location of a script. + ## Printer flags *-i*, *--indent* diff --git a/vendor/mvdan.cc/sh/v3/syntax/lexer.go b/vendor/mvdan.cc/sh/v3/syntax/lexer.go index 588ab061d..28f96df62 100644 --- a/vendor/mvdan.cc/sh/v3/syntax/lexer.go +++ b/vendor/mvdan.cc/sh/v3/syntax/lexer.go @@ -61,18 +61,13 @@ func (p *Parser) rune() rune { if p.r == '\n' || p.r == escNewl { // p.r instead of b so that newline // character positions don't have col 0. - if p.line++; p.line > lineMax { - p.lineOverflow = true - } + p.line++ p.col = 0 - p.colOverflow = false - } - if p.col += p.w; p.col > colMax { - p.colOverflow = true } + p.col += int64(p.w) bquotes := 0 retry: - if p.bsp < len(p.bs) { + if p.bsp < uint(len(p.bs)) { if b := p.bs[p.bsp]; b < utf8.RuneSelf { p.bsp++ if b == '\x00' { @@ -91,7 +86,7 @@ retry: return escNewl } if p.openBquotes > 0 && bquotes < p.openBquotes && - p.bsp < len(p.bs) && bquoteEscaped(p.bs[p.bsp]) { + p.bsp < uint(len(p.bs)) && bquoteEscaped(p.bs[p.bsp]) { // We turn backquote command substitutions into $(), // so we remove the extra backslashes needed by the backquotes. // For good position information, we still include them in p.w. @@ -115,9 +110,9 @@ retry: var w int p.r, w = utf8.DecodeRune(p.bs[p.bsp:]) if p.litBs != nil { - p.litBs = append(p.litBs, p.bs[p.bsp:p.bsp+w]...) + p.litBs = append(p.litBs, p.bs[p.bsp:p.bsp+uint(w)]...) } - p.bsp += w + p.bsp += uint(w) if p.r == utf8.RuneError && w == 1 { p.posErr(p.nextPos(), "invalid UTF-8 encoding") } @@ -139,8 +134,8 @@ retry: // had not yet been used at the end of the buffer are slid into the // beginning of the buffer. func (p *Parser) fill() { - p.offs += p.bsp - left := len(p.bs) - p.bsp + p.offs += int64(p.bsp) + left := len(p.bs) - int(p.bsp) copy(p.readBuf[:left], p.readBuf[p.bsp:]) readAgain: n, err := 0, p.readErr @@ -259,7 +254,7 @@ skipSpace: } if p.stopAt != nil && (p.spaced || p.tok == illegalTok || p.stopToken()) { w := utf8.RuneLen(r) - if bytes.HasPrefix(p.bs[p.bsp-w:], p.stopAt) { + if bytes.HasPrefix(p.bs[p.bsp-uint(w):], p.stopAt) { p.r = utf8.RuneSelf p.w = 1 p.tok = _EOF @@ -393,7 +388,7 @@ func (p *Parser) extendedGlob() bool { } func (p *Parser) peekBytes(s string) bool { - peekEnd := p.bsp + len(s) + peekEnd := int(p.bsp) + len(s) // TODO: This should loop for slow readers, e.g. those providing one byte at // a time. Use a loop and test it with testing/iotest.OneByteReader. if peekEnd > len(p.bs) { @@ -403,10 +398,10 @@ func (p *Parser) peekBytes(s string) bool { } func (p *Parser) peekByte(b byte) bool { - if p.bsp == len(p.bs) { + if p.bsp == uint(len(p.bs)) { p.fill() } - return p.bsp < len(p.bs) && p.bs[p.bsp] == b + return p.bsp < uint(len(p.bs)) && p.bs[p.bsp] == b } func (p *Parser) regToken(r rune) token { @@ -814,7 +809,7 @@ func (p *Parser) newLit(r rune) { p.litBs[0] = byte(r) case r > escNewl: w := utf8.RuneLen(r) - p.litBs = append(p.litBuf[:0], p.bs[p.bsp-w:p.bsp]...) + p.litBs = append(p.litBuf[:0], p.bs[p.bsp-uint(w):p.bsp]...) default: // don't let r == utf8.RuneSelf go to the second case as RuneLen // would return -1 diff --git a/vendor/mvdan.cc/sh/v3/syntax/nodes.go b/vendor/mvdan.cc/sh/v3/syntax/nodes.go index 88eb7feab..8424545ca 100644 --- a/vendor/mvdan.cc/sh/v3/syntax/nodes.go +++ b/vendor/mvdan.cc/sh/v3/syntax/nodes.go @@ -4,6 +4,7 @@ package syntax import ( + "math" "strconv" "strings" ) @@ -72,6 +73,8 @@ type Pos struct { // We used to split line and column numbers evenly in 16 bits, but line numbers // are significantly more important in practice. Use more bits for them. const ( + offsetMax = math.MaxUint32 + lineBitSize = 18 lineMax = (1 << lineBitSize) - 1 @@ -90,6 +93,9 @@ const ( // Note that Pos uses a limited number of bits to store these numbers. // If line or column overflow their allocated space, they are replaced with 0. func NewPos(offset, line, column uint) Pos { + // Basic protection against offset overflow; + // note that an offset of 0 is valid, so we leave the maximum. + offset = min(offset, offsetMax) if line > lineMax { line = 0 // protect against overflows; rendered as "?" } @@ -105,8 +111,8 @@ func NewPos(offset, line, column uint) Pos { // Offset returns the byte offset of the position in the original source file. // Byte offsets start at 0. // -// Note that Offset is not protected against overflows; -// if an input is larger than 4GiB, the offset will wrap around to 0. +// Offset has basic protection against overflows; if an input is too large, +// offset numbers will stop increasing past a very large number. func (p Pos) Offset() uint { return uint(p.offs) } // Line returns the line number of the position, starting at 1. diff --git a/vendor/mvdan.cc/sh/v3/syntax/parser.go b/vendor/mvdan.cc/sh/v3/syntax/parser.go index b675de3d0..580dab713 100644 --- a/vendor/mvdan.cc/sh/v3/syntax/parser.go +++ b/vendor/mvdan.cc/sh/v3/syntax/parser.go @@ -196,7 +196,7 @@ type wrappedReader struct { *Parser io.Reader - lastLine int + lastLine int64 accumulated []*Stmt fn func([]*Stmt) bool } @@ -338,7 +338,7 @@ func (p *Parser) Arithmetic(r io.Reader) (ArithmExpr, error) { type Parser struct { src io.Reader bs []byte // current chunk of read bytes - bsp int // pos within chunk for the rune after r + bsp uint // pos within chunk for the rune after r; uint helps eliminate bounds checks r rune // next rune w int // width of r @@ -353,15 +353,10 @@ type Parser struct { val string // current value (valid if tok is _Lit*) // position of r, to be converted to Parser.pos later - offs, line, col int + offs, line, col int64 pos Pos // position of tok - // TODO: Guard against offset overflow too. Less likely as it's 32-bit, - // whereas line and col are 16-bit. - lineOverflow bool - colOverflow bool - quote quoteState // current lexer state eqlOffs int // position of '=' in val (a literal) @@ -398,8 +393,6 @@ type Parser struct { litBatch []Lit wordBatch []wordAlloc - stmtBatch []Stmt - callBatch []callAlloc readBuf [bufSize]byte litBuf [bufSize]byte @@ -431,30 +424,33 @@ func (p *Parser) reset() { p.quote, p.forbidNested = noState, false p.openStmts = 0 p.heredocs, p.buriedHdocs = p.heredocs[:0], 0 + p.hdocStops = nil p.parsingDoc = false p.openBquotes = 0 + p.accComs = nil p.accComs, p.curComs = nil, &p.accComs p.litBatch = nil p.wordBatch = nil - p.stmtBatch = nil - p.callBatch = nil + p.litBs = nil } func (p *Parser) nextPos() Pos { - // TODO: detect offset overflow while lexing as well. + // Basic protection against offset overflow; + // note that an offset of 0 is valid, so we leave the maximum. + offset := min(p.offs+int64(p.bsp)-int64(p.w), offsetMax) var line, col uint - if !p.lineOverflow { + if p.line <= lineMax { line = uint(p.line) } - if !p.colOverflow { + if p.col <= colMax { col = uint(p.col) } - return NewPos(uint(p.offs+p.bsp-p.w), line, col) + return NewPos(uint(offset), line, col) } func (p *Parser) lit(pos Pos, val string) *Lit { if len(p.litBatch) == 0 { - p.litBatch = make([]Lit, 64) + p.litBatch = make([]Lit, 32) } l := &p.litBatch[0] p.litBatch = p.litBatch[1:] @@ -492,27 +488,11 @@ func (p *Parser) wordOne(part WordPart) *Word { return w } -func (p *Parser) stmt(pos Pos) *Stmt { - if len(p.stmtBatch) == 0 { - p.stmtBatch = make([]Stmt, 32) - } - s := &p.stmtBatch[0] - p.stmtBatch = p.stmtBatch[1:] - s.Position = pos - return s -} - -type callAlloc struct { - ce CallExpr - ws [4]*Word -} - func (p *Parser) call(w *Word) *CallExpr { - if len(p.callBatch) == 0 { - p.callBatch = make([]callAlloc, 32) + var alloc struct { + ce CallExpr + ws [4]*Word } - alloc := &p.callBatch[0] - p.callBatch = p.callBatch[1:] ce := &alloc.ce ce.Args = alloc.ws[:1] ce.Args[0] = w @@ -579,12 +559,12 @@ func (p *Parser) unquotedWordBytes(w *Word) ([]byte, bool) { } func (p *Parser) unquotedWordPart(buf []byte, wp WordPart, quotes bool) (_ []byte, quoted bool) { - switch x := wp.(type) { + switch wp := wp.(type) { case *Lit: - for i := 0; i < len(x.Value); i++ { - if b := x.Value[i]; b == '\\' && !quotes { - if i++; i < len(x.Value) { - buf = append(buf, x.Value[i]) + for i := 0; i < len(wp.Value); i++ { + if b := wp.Value[i]; b == '\\' && !quotes { + if i++; i < len(wp.Value) { + buf = append(buf, wp.Value[i]) } quoted = true } else { @@ -592,10 +572,10 @@ func (p *Parser) unquotedWordPart(buf []byte, wp WordPart, quotes bool) (_ []byt } } case *SglQuoted: - buf = append(buf, []byte(x.Value)...) + buf = append(buf, []byte(wp.Value)...) quoted = true case *DblQuoted: - for _, wp2 := range x.Parts { + for _, wp2 := range wp.Parts { buf, _ = p.unquotedWordPart(buf, wp2, true) } quoted = true @@ -633,7 +613,7 @@ func (p *Parser) doHeredocs() { r.Hdoc = p.getWord() } if r.Hdoc != nil { - lastLine = int(r.Hdoc.End().Line()) + lastLine = int64(r.Hdoc.End().Line()) } if lastLine < p.line { // TODO: It seems like this triggers more often than it @@ -750,7 +730,7 @@ func (p *Parser) matched(lpos Pos, left, right token) Pos { func (p *Parser) errPass(err error) { if p.err == nil { p.err = err - p.bsp = len(p.bs) + 1 + p.bsp = uint(len(p.bs)) + 1 p.r = utf8.RuneSelf p.w = 1 p.tok = _EOF @@ -1376,8 +1356,7 @@ func (p *Parser) paramExp() *ParamExp { p.curErr("not a valid parameter expansion operator: %v", p.tok) } p.quote = old - pe.Rbrace = p.pos - p.matched(pe.Dollar, dollBrace, rightBrace) + pe.Rbrace = p.matched(pe.Dollar, dollBrace, rightBrace) return pe } @@ -1392,7 +1371,7 @@ func (p *Parser) paramExpExp() *Expansion { p.curErr("@ expansion operator requires a literal") } switch p.val { - case "a", "u", "A", "E", "K", "L", "P", "U": + case "a", "k", "u", "A", "E", "K", "L", "P", "U": if !p.lang.isBash() { p.langErr(p.pos, "this expansion operator", LangBash) } @@ -1402,7 +1381,7 @@ func (p *Parser) paramExpExp() *Expansion { } case "Q": default: - p.curErr("invalid @ expansion operator") + p.curErr("invalid @ expansion operator %q", p.val) } } return &Expansion{Op: op, Word: p.getWord()} @@ -1654,7 +1633,7 @@ func (p *Parser) doRedirect(s *Stmt) { func (p *Parser) getStmt(readEnd, binCmd, fnBody bool) *Stmt { pos, ok := p.gotRsrv("!") - s := p.stmt(pos) + s := &Stmt{Position: pos} if ok { s.Negated = true if p.stopToken() { @@ -1686,7 +1665,7 @@ func (p *Parser) getStmt(readEnd, binCmd, fnBody bool) *Stmt { p.followErr(b.OpPos, b.Op.String(), "a statement") return nil } - s = p.stmt(s.Position) + s = &Stmt{Position: s.Position} s.Cmd = b s.Comments, b.X.Comments = b.X.Comments, nil } @@ -1855,11 +1834,11 @@ func (p *Parser) gotStmtPipe(s *Stmt, binCmd bool) *Stmt { b := &BinaryCmd{OpPos: p.pos, Op: BinCmdOperator(p.tok), X: s} p.next() p.got(_Newl) - if b.Y = p.gotStmtPipe(p.stmt(p.pos), true); b.Y == nil || p.err != nil { + if b.Y = p.gotStmtPipe(&Stmt{Position: p.pos}, true); b.Y == nil || p.err != nil { p.followErr(b.OpPos, b.Op.String(), "a statement") break } - s = p.stmt(s.Position) + s = &Stmt{Position: s.Position} s.Cmd = b s.Comments, b.X.Comments = b.X.Comments, nil // in "! x | y", the bang applies to the entire pipeline @@ -2319,7 +2298,7 @@ func (p *Parser) timeClause(s *Stmt) { if _, ok := p.gotRsrv("-p"); ok { tc.PosixFormat = true } - tc.Stmt = p.gotStmtPipe(p.stmt(p.pos), false) + tc.Stmt = p.gotStmtPipe(&Stmt{Position: p.pos}, false) s.Cmd = tc } @@ -2327,19 +2306,19 @@ func (p *Parser) coprocClause(s *Stmt) { cc := &CoprocClause{Coproc: p.pos} if p.next(); isBashCompoundCommand(p.tok, p.val) { // has no name - cc.Stmt = p.gotStmtPipe(p.stmt(p.pos), false) + cc.Stmt = p.gotStmtPipe(&Stmt{Position: p.pos}, false) s.Cmd = cc return } cc.Name = p.getWord() - cc.Stmt = p.gotStmtPipe(p.stmt(p.pos), false) + cc.Stmt = p.gotStmtPipe(&Stmt{Position: p.pos}, false) if cc.Stmt == nil { if cc.Name == nil { p.posErr(cc.Coproc, "coproc clause requires a command") return } // name was in fact the stmt - cc.Stmt = p.stmt(cc.Name.Pos()) + cc.Stmt = &Stmt{Position: cc.Name.Pos()} cc.Stmt.Cmd = p.call(cc.Name) cc.Name = nil } else if cc.Name != nil { diff --git a/vendor/mvdan.cc/sh/v3/syntax/parser_arithm.go b/vendor/mvdan.cc/sh/v3/syntax/parser_arithm.go index a6d6a951f..c8567b529 100644 --- a/vendor/mvdan.cc/sh/v3/syntax/parser_arithm.go +++ b/vendor/mvdan.cc/sh/v3/syntax/parser_arithm.go @@ -295,11 +295,11 @@ func isArithName(left ArithmExpr) bool { if !ok || len(w.Parts) != 1 { return false } - switch x := w.Parts[0].(type) { + switch wp := w.Parts[0].(type) { case *Lit: - return ValidName(x.Value) + return ValidName(wp.Value) case *ParamExp: - return x.nakedIndex() + return wp.nakedIndex() default: return false } diff --git a/vendor/mvdan.cc/sh/v3/syntax/printer.go b/vendor/mvdan.cc/sh/v3/syntax/printer.go index 7c3ff9e6e..55cf69fc8 100644 --- a/vendor/mvdan.cc/sh/v3/syntax/printer.go +++ b/vendor/mvdan.cc/sh/v3/syntax/printer.go @@ -134,25 +134,25 @@ func (p *Printer) Print(w io.Writer, node Node) error { w = p.tabWriter p.bufWriter.Reset(w) - switch x := node.(type) { + switch node := node.(type) { case *File: - p.stmtList(x.Stmts, x.Last) + p.stmtList(node.Stmts, node.Last) p.newline(Pos{}) case *Stmt: - p.stmtList([]*Stmt{x}, nil) + p.stmtList([]*Stmt{node}, nil) case Command: - p.command(x, nil) + p.command(node, nil) case *Word: - p.line = x.Pos().Line() - p.word(x) + p.line = node.Pos().Line() + p.word(node) case WordPart: - p.line = x.Pos().Line() - p.wordPart(x, nil) + p.line = node.Pos().Line() + p.wordPart(node, nil) case *Assign: - p.line = x.Pos().Line() - p.assigns([]*Assign{x}) + p.line = node.Pos().Line() + p.assigns([]*Assign{node}) default: - return fmt.Errorf("unsupported node type: %T", x) + return fmt.Errorf("unsupported node type: %T", node) } p.flushHeredocs() p.flushComments() @@ -635,88 +635,88 @@ func (p *Printer) wordParts(wps []WordPart, quoted bool) { } func (p *Printer) wordPart(wp, next WordPart) { - switch x := wp.(type) { + switch wp := wp.(type) { case *Lit: - p.writeLit(x.Value) + p.writeLit(wp.Value) case *SglQuoted: - if x.Dollar { + if wp.Dollar { p.WriteByte('$') } p.WriteByte('\'') - p.writeLit(x.Value) + p.writeLit(wp.Value) p.WriteByte('\'') - p.advanceLine(x.End().Line()) + p.advanceLine(wp.End().Line()) case *DblQuoted: - p.dblQuoted(x) + p.dblQuoted(wp) case *CmdSubst: - p.advanceLine(x.Pos().Line()) + p.advanceLine(wp.Pos().Line()) switch { - case x.TempFile: + case wp.TempFile: p.WriteString("${") p.wantSpace = spaceRequired - p.nestedStmts(x.Stmts, x.Last, x.Right) + p.nestedStmts(wp.Stmts, wp.Last, wp.Right) p.wantSpace = spaceNotRequired - p.semiRsrv("}", x.Right) - case x.ReplyVar: + p.semiRsrv("}", wp.Right) + case wp.ReplyVar: p.WriteString("${|") - p.nestedStmts(x.Stmts, x.Last, x.Right) + p.nestedStmts(wp.Stmts, wp.Last, wp.Right) p.wantSpace = spaceNotRequired - p.semiRsrv("}", x.Right) + p.semiRsrv("}", wp.Right) // Special case: `# inline comment` - case x.Backquotes && len(x.Stmts) == 0 && - len(x.Last) == 1 && x.Right.Line() == p.line: + case wp.Backquotes && len(wp.Stmts) == 0 && + len(wp.Last) == 1 && wp.Right.Line() == p.line: p.WriteString("`#") - p.WriteString(x.Last[0].Text) + p.WriteString(wp.Last[0].Text) p.WriteString("`") default: p.WriteString("$(") - if len(x.Stmts) > 0 && startsWithLparen(x.Stmts[0]) { + if len(wp.Stmts) > 0 && startsWithLparen(wp.Stmts[0]) { p.wantSpace = spaceRequired } else { p.wantSpace = spaceNotRequired } - p.nestedStmts(x.Stmts, x.Last, x.Right) - p.rightParen(x.Right) + p.nestedStmts(wp.Stmts, wp.Last, wp.Right) + p.rightParen(wp.Right) } case *ParamExp: litCont := ";" if nextLit, ok := next.(*Lit); ok && nextLit.Value != "" { litCont = nextLit.Value[:1] } - name := x.Param.Value + name := wp.Param.Value switch { case !p.minify: - case x.Excl, x.Length, x.Width: - case x.Index != nil, x.Slice != nil: - case x.Repl != nil, x.Exp != nil: + case wp.Excl, wp.Length, wp.Width: + case wp.Index != nil, wp.Slice != nil: + case wp.Repl != nil, wp.Exp != nil: case len(name) > 1 && !ValidName(name): // ${10} case ValidName(name + litCont): // ${var}cont default: - x2 := *x + x2 := *wp x2.Short = true p.paramExp(&x2) return } - p.paramExp(x) + p.paramExp(wp) case *ArithmExp: p.WriteString("$((") - if x.Unsigned { + if wp.Unsigned { p.WriteString("# ") } - p.arithmExpr(x.X, false, false) + p.arithmExpr(wp.X, false, false) p.WriteString("))") case *ExtGlob: - p.WriteString(x.Op.String()) - p.writeLit(x.Pattern.Value) + p.WriteString(wp.Op.String()) + p.writeLit(wp.Pattern.Value) p.WriteByte(')') case *ProcSubst: // avoid conflict with << and others if p.wantSpace == spaceRequired { p.space() } - p.WriteString(x.Op.String()) - p.nestedStmts(x.Stmts, x.Last, x.Rparen) - p.rightParen(x.Rparen) + p.WriteString(wp.Op.String()) + p.nestedStmts(wp.Stmts, wp.Last, wp.Rparen) + p.rightParen(wp.Rparen) } } @@ -801,23 +801,23 @@ func (p *Printer) paramExp(pe *ParamExp) { } func (p *Printer) loop(loop Loop) { - switch x := loop.(type) { + switch loop := loop.(type) { case *WordIter: - p.writeLit(x.Name.Value) - if x.InPos.IsValid() { + p.writeLit(loop.Name.Value) + if loop.InPos.IsValid() { p.spacedString(" in", Pos{}) - p.wordJoin(x.Items) + p.wordJoin(loop.Items) } case *CStyleLoop: p.WriteString("((") - if x.Init == nil { + if loop.Init == nil { p.space() } - p.arithmExpr(x.Init, false, false) + p.arithmExpr(loop.Init, false, false) p.WriteString("; ") - p.arithmExpr(x.Cond, false, false) + p.arithmExpr(loop.Cond, false, false) p.WriteString("; ") - p.arithmExpr(x.Post, false, false) + p.arithmExpr(loop.Post, false, false) p.WriteString("))") } } @@ -826,40 +826,40 @@ func (p *Printer) arithmExpr(expr ArithmExpr, compact, spacePlusMinus bool) { if p.minify { compact = true } - switch x := expr.(type) { + switch expr := expr.(type) { case *Word: - p.word(x) + p.word(expr) case *BinaryArithm: if compact { - p.arithmExpr(x.X, compact, spacePlusMinus) - p.WriteString(x.Op.String()) - p.arithmExpr(x.Y, compact, false) + p.arithmExpr(expr.X, compact, spacePlusMinus) + p.WriteString(expr.Op.String()) + p.arithmExpr(expr.Y, compact, false) } else { - p.arithmExpr(x.X, compact, spacePlusMinus) - if x.Op != Comma { + p.arithmExpr(expr.X, compact, spacePlusMinus) + if expr.Op != Comma { p.space() } - p.WriteString(x.Op.String()) + p.WriteString(expr.Op.String()) p.space() - p.arithmExpr(x.Y, compact, false) + p.arithmExpr(expr.Y, compact, false) } case *UnaryArithm: - if x.Post { - p.arithmExpr(x.X, compact, spacePlusMinus) - p.WriteString(x.Op.String()) + if expr.Post { + p.arithmExpr(expr.X, compact, spacePlusMinus) + p.WriteString(expr.Op.String()) } else { if spacePlusMinus { - switch x.Op { + switch expr.Op { case Plus, Minus: p.space() } } - p.WriteString(x.Op.String()) - p.arithmExpr(x.X, compact, false) + p.WriteString(expr.Op.String()) + p.arithmExpr(expr.X, compact, false) } case *ParenArithm: p.WriteByte('(') - p.arithmExpr(x.X, false, false) + p.arithmExpr(expr.X, false, false) p.WriteByte(')') } } @@ -877,33 +877,33 @@ func (p *Printer) testExpr(expr TestExpr) { func (p *Printer) testExprSameLine(expr TestExpr) { p.advanceLine(expr.Pos().Line()) - switch x := expr.(type) { + switch expr := expr.(type) { case *Word: - p.word(x) + p.word(expr) case *BinaryTest: - p.testExprSameLine(x.X) + p.testExprSameLine(expr.X) p.space() - p.WriteString(x.Op.String()) - switch x.Op { + p.WriteString(expr.Op.String()) + switch expr.Op { case AndTest, OrTest: p.wantSpace = spaceRequired - p.testExpr(x.Y) + p.testExpr(expr.Y) default: p.space() - p.testExprSameLine(x.Y) + p.testExprSameLine(expr.Y) } case *UnaryTest: - p.WriteString(x.Op.String()) + p.WriteString(expr.Op.String()) p.space() - p.testExprSameLine(x.X) + p.testExprSameLine(expr.X) case *ParenTest: p.WriteByte('(') - if startsWithLparen(x.X) { + if startsWithLparen(expr.X) { p.wantSpace = spaceRequired } else { p.wantSpace = spaceNotRequired } - p.testExpr(x.X) + p.testExpr(expr.X) p.WriteByte(')') } } @@ -915,16 +915,16 @@ func (p *Printer) word(w *Word) { func (p *Printer) unquotedWord(w *Word) { for _, wp := range w.Parts { - switch x := wp.(type) { + switch wp := wp.(type) { case *SglQuoted: - p.writeLit(x.Value) + p.writeLit(wp.Value) case *DblQuoted: - p.wordParts(x.Parts, true) + p.wordParts(wp.Parts, true) case *Lit: - for i := 0; i < len(x.Value); i++ { - if b := x.Value[i]; b == '\\' { - if i++; i < len(x.Value) { - p.WriteByte(x.Value[i]) + for i := 0; i < len(wp.Value); i++ { + if b := wp.Value[i]; b == '\\' { + if i++; i < len(wp.Value) { + p.WriteByte(wp.Value[i]) } } else { p.WriteByte(b) @@ -1084,36 +1084,36 @@ func (p *Printer) printRedirsUntil(redirs []*Redirect, startRedirs int, pos Pos) func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) { p.advanceLine(cmd.Pos().Line()) p.spacePad(cmd.Pos()) - switch x := cmd.(type) { + switch cmd := cmd.(type) { case *CallExpr: - p.assigns(x.Assigns) - if len(x.Args) > 0 { - startRedirs = p.printRedirsUntil(redirs, startRedirs, x.Args[0].Pos()) + p.assigns(cmd.Assigns) + if len(cmd.Args) > 0 { + startRedirs = p.printRedirsUntil(redirs, startRedirs, cmd.Args[0].Pos()) } - if len(x.Args) <= 1 { - p.wordJoin(x.Args) + if len(cmd.Args) <= 1 { + p.wordJoin(cmd.Args) return startRedirs } - p.wordJoin(x.Args[:1]) - startRedirs = p.printRedirsUntil(redirs, startRedirs, x.Args[1].Pos()) - p.wordJoin(x.Args[1:]) + p.wordJoin(cmd.Args[:1]) + startRedirs = p.printRedirsUntil(redirs, startRedirs, cmd.Args[1].Pos()) + p.wordJoin(cmd.Args[1:]) case *Block: p.WriteByte('{') p.wantSpace = spaceRequired // Forbid "foo()\n{ bar; }" p.wantNewline = p.wantNewline || p.funcNextLine - p.nestedStmts(x.Stmts, x.Last, x.Rbrace) - p.semiRsrv("}", x.Rbrace) + p.nestedStmts(cmd.Stmts, cmd.Last, cmd.Rbrace) + p.semiRsrv("}", cmd.Rbrace) case *IfClause: - p.ifClause(x, false) + p.ifClause(cmd, false) case *Subshell: p.WriteByte('(') - stmts := x.Stmts + stmts := cmd.Stmts if len(stmts) > 0 && startsWithLparen(stmts[0]) { p.wantSpace = spaceRequired // Add a space between nested parentheses if we're printing them in a single line, // to avoid the ambiguity between `((` and `( (`. - if (x.Lparen.Line() != stmts[0].Pos().Line() || len(stmts) > 1) && !p.singleLine { + if (cmd.Lparen.Line() != stmts[0].Pos().Line() || len(stmts) > 1) && !p.singleLine { p.wantSpace = spaceNotRequired if p.minify { @@ -1124,38 +1124,38 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) { p.wantSpace = spaceNotRequired } - p.spacePad(stmtsPos(x.Stmts, x.Last)) - p.nestedStmts(x.Stmts, x.Last, x.Rparen) + p.spacePad(stmtsPos(cmd.Stmts, cmd.Last)) + p.nestedStmts(cmd.Stmts, cmd.Last, cmd.Rparen) p.wantSpace = spaceNotRequired - p.spacePad(x.Rparen) - p.rightParen(x.Rparen) + p.spacePad(cmd.Rparen) + p.rightParen(cmd.Rparen) case *WhileClause: - if x.Until { - p.spacedString("until", x.Pos()) + if cmd.Until { + p.spacedString("until", cmd.Pos()) } else { - p.spacedString("while", x.Pos()) + p.spacedString("while", cmd.Pos()) } - p.nestedStmts(x.Cond, x.CondLast, Pos{}) - p.semiOrNewl("do", x.DoPos) - p.nestedStmts(x.Do, x.DoLast, x.DonePos) - p.semiRsrv("done", x.DonePos) + p.nestedStmts(cmd.Cond, cmd.CondLast, Pos{}) + p.semiOrNewl("do", cmd.DoPos) + p.nestedStmts(cmd.Do, cmd.DoLast, cmd.DonePos) + p.semiRsrv("done", cmd.DonePos) case *ForClause: - if x.Select { + if cmd.Select { p.WriteString("select ") } else { p.WriteString("for ") } - p.loop(x.Loop) - p.semiOrNewl("do", x.DoPos) - p.nestedStmts(x.Do, x.DoLast, x.DonePos) - p.semiRsrv("done", x.DonePos) + p.loop(cmd.Loop) + p.semiOrNewl("do", cmd.DoPos) + p.nestedStmts(cmd.Do, cmd.DoLast, cmd.DonePos) + p.semiRsrv("done", cmd.DonePos) case *BinaryCmd: - p.stmt(x.X) - if p.minify || p.singleLine || x.Y.Pos().Line() <= p.line { + p.stmt(cmd.X) + if p.minify || p.singleLine || cmd.Y.Pos().Line() <= p.line { // leave p.nestedBinary untouched - p.spacedToken(x.Op.String(), x.OpPos) - p.advanceLine(x.Y.Pos().Line()) - p.stmt(x.Y) + p.spacedToken(cmd.Op.String(), cmd.OpPos) + p.advanceLine(cmd.Y.Pos().Line()) + p.stmt(cmd.Y) break } indent := !p.nestedBinary @@ -1166,60 +1166,60 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) { if len(p.pendingHdocs) == 0 { p.bslashNewl() } - p.spacedToken(x.Op.String(), x.OpPos) - if len(x.Y.Comments) > 0 { + p.spacedToken(cmd.Op.String(), cmd.OpPos) + if len(cmd.Y.Comments) > 0 { p.wantSpace = spaceNotRequired - p.newline(x.Y.Pos()) + p.newline(cmd.Y.Pos()) p.indent() - p.comments(x.Y.Comments...) + p.comments(cmd.Y.Comments...) p.newline(Pos{}) p.indent() } } else { - p.spacedToken(x.Op.String(), x.OpPos) - p.advanceLine(x.OpPos.Line()) - p.comments(x.Y.Comments...) + p.spacedToken(cmd.Op.String(), cmd.OpPos) + p.advanceLine(cmd.OpPos.Line()) + p.comments(cmd.Y.Comments...) p.newline(Pos{}) p.indent() } - p.advanceLine(x.Y.Pos().Line()) - _, p.nestedBinary = x.Y.Cmd.(*BinaryCmd) - p.stmt(x.Y) + p.advanceLine(cmd.Y.Pos().Line()) + _, p.nestedBinary = cmd.Y.Cmd.(*BinaryCmd) + p.stmt(cmd.Y) if indent { p.decLevel() } p.nestedBinary = false case *FuncDecl: - if x.RsrvWord { + if cmd.RsrvWord { p.WriteString("function ") } - p.writeLit(x.Name.Value) - if !x.RsrvWord || x.Parens { + p.writeLit(cmd.Name.Value) + if !cmd.RsrvWord || cmd.Parens { p.WriteString("()") } if p.funcNextLine { p.newline(Pos{}) p.indent() - } else if !x.Parens || !p.minify { + } else if !cmd.Parens || !p.minify { p.space() } - p.advanceLine(x.Body.Pos().Line()) - p.comments(x.Body.Comments...) - p.stmt(x.Body) + p.advanceLine(cmd.Body.Pos().Line()) + p.comments(cmd.Body.Comments...) + p.stmt(cmd.Body) case *CaseClause: p.WriteString("case ") - p.word(x.Word) + p.word(cmd.Word) p.WriteString(" in") - p.advanceLine(x.In.Line()) + p.advanceLine(cmd.In.Line()) p.wantSpace = spaceRequired if p.swtCaseIndent { p.incLevel() } - if len(x.Items) == 0 { + if len(cmd.Items) == 0 { // Apparently "case x in; esac" is invalid shell. p.mustNewline = true } - for i, ci := range x.Items { + for i, ci := range cmd.Items { var last []Comment for i, c := range ci.Comments { if c.Pos().After(ci.Pos()) { @@ -1244,7 +1244,7 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) { (bodyEnd.IsValid() && ci.OpPos.Line() > bodyEnd.Line()) p.nestedStmts(ci.Stmts, ci.Last, ci.OpPos) p.level++ - if !p.minify || i != len(x.Items)-1 { + if !p.minify || i != len(cmd.Items)-1 { if sep { p.newlines(ci.OpPos) p.wantNewline = true @@ -1258,58 +1258,58 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) { p.flushComments() p.level-- } - p.comments(x.Last...) + p.comments(cmd.Last...) if p.swtCaseIndent { p.flushComments() p.decLevel() } - p.semiRsrv("esac", x.Esac) + p.semiRsrv("esac", cmd.Esac) case *ArithmCmd: p.WriteString("((") - if x.Unsigned { + if cmd.Unsigned { p.WriteString("# ") } - p.arithmExpr(x.X, false, false) + p.arithmExpr(cmd.X, false, false) p.WriteString("))") case *TestClause: p.WriteString("[[ ") p.incLevel() - p.testExpr(x.X) + p.testExpr(cmd.X) p.decLevel() - p.spacedString("]]", x.Right) + p.spacedString("]]", cmd.Right) case *DeclClause: - p.spacedString(x.Variant.Value, x.Pos()) - p.assigns(x.Args) + p.spacedString(cmd.Variant.Value, cmd.Pos()) + p.assigns(cmd.Args) case *TimeClause: - p.spacedString("time", x.Pos()) - if x.PosixFormat { - p.spacedString("-p", x.Pos()) + p.spacedString("time", cmd.Pos()) + if cmd.PosixFormat { + p.spacedString("-p", cmd.Pos()) } - if x.Stmt != nil { - p.stmt(x.Stmt) + if cmd.Stmt != nil { + p.stmt(cmd.Stmt) } case *CoprocClause: - p.spacedString("coproc", x.Pos()) - if x.Name != nil { + p.spacedString("coproc", cmd.Pos()) + if cmd.Name != nil { p.space() - p.word(x.Name) + p.word(cmd.Name) } p.space() - p.stmt(x.Stmt) + p.stmt(cmd.Stmt) case *LetClause: - p.spacedString("let", x.Pos()) - for _, n := range x.Exprs { + p.spacedString("let", cmd.Pos()) + for _, n := range cmd.Exprs { p.space() p.arithmExpr(n, true, false) } case *TestDecl: - p.spacedString("@test", x.Pos()) + p.spacedString("@test", cmd.Pos()) p.space() - p.word(x.Description) + p.word(cmd.Description) p.space() - p.stmt(x.Body) + p.stmt(cmd.Body) default: - panic(fmt.Sprintf("syntax.Printer: unexpected node type %T", x)) + panic(fmt.Sprintf("syntax.Printer: unexpected node type %T", cmd)) } return startRedirs } diff --git a/vendor/mvdan.cc/sh/v3/syntax/simplify.go b/vendor/mvdan.cc/sh/v3/syntax/simplify.go index e82fd55af..34059c629 100644 --- a/vendor/mvdan.cc/sh/v3/syntax/simplify.go +++ b/vendor/mvdan.cc/sh/v3/syntax/simplify.go @@ -27,63 +27,63 @@ type simplifier struct { } func (s *simplifier) visit(node Node) bool { - switch x := node.(type) { + switch node := node.(type) { case *Assign: - x.Index = s.removeParensArithm(x.Index) + node.Index = s.removeParensArithm(node.Index) // Don't inline params, as x[i] and x[$i] mean // different things when x is an associative // array; the first means "i", the second "$i". case *ParamExp: - x.Index = s.removeParensArithm(x.Index) + node.Index = s.removeParensArithm(node.Index) // don't inline params - same as above. - if x.Slice == nil { + if node.Slice == nil { break } - x.Slice.Offset = s.removeParensArithm(x.Slice.Offset) - x.Slice.Offset = s.inlineSimpleParams(x.Slice.Offset) - x.Slice.Length = s.removeParensArithm(x.Slice.Length) - x.Slice.Length = s.inlineSimpleParams(x.Slice.Length) + node.Slice.Offset = s.removeParensArithm(node.Slice.Offset) + node.Slice.Offset = s.inlineSimpleParams(node.Slice.Offset) + node.Slice.Length = s.removeParensArithm(node.Slice.Length) + node.Slice.Length = s.inlineSimpleParams(node.Slice.Length) case *ArithmExp: - x.X = s.removeParensArithm(x.X) - x.X = s.inlineSimpleParams(x.X) + node.X = s.removeParensArithm(node.X) + node.X = s.inlineSimpleParams(node.X) case *ArithmCmd: - x.X = s.removeParensArithm(x.X) - x.X = s.inlineSimpleParams(x.X) + node.X = s.removeParensArithm(node.X) + node.X = s.inlineSimpleParams(node.X) case *ParenArithm: - x.X = s.removeParensArithm(x.X) - x.X = s.inlineSimpleParams(x.X) + node.X = s.removeParensArithm(node.X) + node.X = s.inlineSimpleParams(node.X) case *BinaryArithm: - x.X = s.inlineSimpleParams(x.X) - x.Y = s.inlineSimpleParams(x.Y) + node.X = s.inlineSimpleParams(node.X) + node.Y = s.inlineSimpleParams(node.Y) case *CmdSubst: - x.Stmts = s.inlineSubshell(x.Stmts) + node.Stmts = s.inlineSubshell(node.Stmts) case *Subshell: - x.Stmts = s.inlineSubshell(x.Stmts) + node.Stmts = s.inlineSubshell(node.Stmts) case *Word: - x.Parts = s.simplifyWord(x.Parts) + node.Parts = s.simplifyWord(node.Parts) case *TestClause: - x.X = s.removeParensTest(x.X) - x.X = s.removeNegateTest(x.X) + node.X = s.removeParensTest(node.X) + node.X = s.removeNegateTest(node.X) case *ParenTest: - x.X = s.removeParensTest(x.X) - x.X = s.removeNegateTest(x.X) + node.X = s.removeParensTest(node.X) + node.X = s.removeNegateTest(node.X) case *BinaryTest: - x.X = s.unquoteParams(x.X) - x.X = s.removeNegateTest(x.X) - if x.Op == TsMatchShort { + node.X = s.unquoteParams(node.X) + node.X = s.removeNegateTest(node.X) + if node.Op == TsMatchShort { s.modified = true - x.Op = TsMatch + node.Op = TsMatch } - switch x.Op { + switch node.Op { case TsMatch, TsNoMatch: // unquoting enables globbing default: - x.Y = s.unquoteParams(x.Y) + node.Y = s.unquoteParams(node.Y) } - x.Y = s.removeNegateTest(x.Y) + node.Y = s.removeNegateTest(node.Y) case *UnaryTest: - x.X = s.unquoteParams(x.X) + node.X = s.unquoteParams(node.X) } return true } diff --git a/vendor/mvdan.cc/sh/v3/syntax/walk.go b/vendor/mvdan.cc/sh/v3/syntax/walk.go index 5be8f9c6a..85d669243 100644 --- a/vendor/mvdan.cc/sh/v3/syntax/walk.go +++ b/vendor/mvdan.cc/sh/v3/syntax/walk.go @@ -33,198 +33,198 @@ func Walk(node Node, f func(Node) bool) { return } - switch x := node.(type) { + switch node := node.(type) { case *File: - walkStmts(x.Stmts, x.Last, f) + walkStmts(node.Stmts, node.Last, f) case *Comment: case *Stmt: - for _, c := range x.Comments { - if !x.End().After(c.Pos()) { + for _, c := range node.Comments { + if !node.End().After(c.Pos()) { defer Walk(&c, f) break } Walk(&c, f) } - if x.Cmd != nil { - Walk(x.Cmd, f) + if node.Cmd != nil { + Walk(node.Cmd, f) } - for _, r := range x.Redirs { + for _, r := range node.Redirs { Walk(r, f) } case *Assign: - if x.Name != nil { - Walk(x.Name, f) + if node.Name != nil { + Walk(node.Name, f) } - if x.Value != nil { - Walk(x.Value, f) + if node.Value != nil { + Walk(node.Value, f) } - if x.Index != nil { - Walk(x.Index, f) + if node.Index != nil { + Walk(node.Index, f) } - if x.Array != nil { - Walk(x.Array, f) + if node.Array != nil { + Walk(node.Array, f) } case *Redirect: - if x.N != nil { - Walk(x.N, f) + if node.N != nil { + Walk(node.N, f) } - Walk(x.Word, f) - if x.Hdoc != nil { - Walk(x.Hdoc, f) + Walk(node.Word, f) + if node.Hdoc != nil { + Walk(node.Hdoc, f) } case *CallExpr: - for _, a := range x.Assigns { + for _, a := range node.Assigns { Walk(a, f) } - walkWords(x.Args, f) + walkWords(node.Args, f) case *Subshell: - walkStmts(x.Stmts, x.Last, f) + walkStmts(node.Stmts, node.Last, f) case *Block: - walkStmts(x.Stmts, x.Last, f) + walkStmts(node.Stmts, node.Last, f) case *IfClause: - walkStmts(x.Cond, x.CondLast, f) - walkStmts(x.Then, x.ThenLast, f) - if x.Else != nil { - Walk(x.Else, f) + walkStmts(node.Cond, node.CondLast, f) + walkStmts(node.Then, node.ThenLast, f) + if node.Else != nil { + Walk(node.Else, f) } case *WhileClause: - walkStmts(x.Cond, x.CondLast, f) - walkStmts(x.Do, x.DoLast, f) + walkStmts(node.Cond, node.CondLast, f) + walkStmts(node.Do, node.DoLast, f) case *ForClause: - Walk(x.Loop, f) - walkStmts(x.Do, x.DoLast, f) + Walk(node.Loop, f) + walkStmts(node.Do, node.DoLast, f) case *WordIter: - Walk(x.Name, f) - walkWords(x.Items, f) + Walk(node.Name, f) + walkWords(node.Items, f) case *CStyleLoop: - if x.Init != nil { - Walk(x.Init, f) + if node.Init != nil { + Walk(node.Init, f) } - if x.Cond != nil { - Walk(x.Cond, f) + if node.Cond != nil { + Walk(node.Cond, f) } - if x.Post != nil { - Walk(x.Post, f) + if node.Post != nil { + Walk(node.Post, f) } case *BinaryCmd: - Walk(x.X, f) - Walk(x.Y, f) + Walk(node.X, f) + Walk(node.Y, f) case *FuncDecl: - Walk(x.Name, f) - Walk(x.Body, f) + Walk(node.Name, f) + Walk(node.Body, f) case *Word: - for _, wp := range x.Parts { + for _, wp := range node.Parts { Walk(wp, f) } case *Lit: case *SglQuoted: case *DblQuoted: - for _, wp := range x.Parts { + for _, wp := range node.Parts { Walk(wp, f) } case *CmdSubst: - walkStmts(x.Stmts, x.Last, f) + walkStmts(node.Stmts, node.Last, f) case *ParamExp: - Walk(x.Param, f) - if x.Index != nil { - Walk(x.Index, f) + Walk(node.Param, f) + if node.Index != nil { + Walk(node.Index, f) } - if x.Repl != nil { - if x.Repl.Orig != nil { - Walk(x.Repl.Orig, f) + if node.Repl != nil { + if node.Repl.Orig != nil { + Walk(node.Repl.Orig, f) } - if x.Repl.With != nil { - Walk(x.Repl.With, f) + if node.Repl.With != nil { + Walk(node.Repl.With, f) } } - if x.Exp != nil && x.Exp.Word != nil { - Walk(x.Exp.Word, f) + if node.Exp != nil && node.Exp.Word != nil { + Walk(node.Exp.Word, f) } case *ArithmExp: - Walk(x.X, f) + Walk(node.X, f) case *ArithmCmd: - Walk(x.X, f) + Walk(node.X, f) case *BinaryArithm: - Walk(x.X, f) - Walk(x.Y, f) + Walk(node.X, f) + Walk(node.Y, f) case *BinaryTest: - Walk(x.X, f) - Walk(x.Y, f) + Walk(node.X, f) + Walk(node.Y, f) case *UnaryArithm: - Walk(x.X, f) + Walk(node.X, f) case *UnaryTest: - Walk(x.X, f) + Walk(node.X, f) case *ParenArithm: - Walk(x.X, f) + Walk(node.X, f) case *ParenTest: - Walk(x.X, f) + Walk(node.X, f) case *CaseClause: - Walk(x.Word, f) - for _, ci := range x.Items { + Walk(node.Word, f) + for _, ci := range node.Items { Walk(ci, f) } - for _, c := range x.Last { + for _, c := range node.Last { Walk(&c, f) } case *CaseItem: - for _, c := range x.Comments { - if c.Pos().After(x.Pos()) { + for _, c := range node.Comments { + if c.Pos().After(node.Pos()) { defer Walk(&c, f) break } Walk(&c, f) } - walkWords(x.Patterns, f) - walkStmts(x.Stmts, x.Last, f) + walkWords(node.Patterns, f) + walkStmts(node.Stmts, node.Last, f) case *TestClause: - Walk(x.X, f) + Walk(node.X, f) case *DeclClause: - for _, a := range x.Args { + for _, a := range node.Args { Walk(a, f) } case *ArrayExpr: - for _, el := range x.Elems { + for _, el := range node.Elems { Walk(el, f) } - for _, c := range x.Last { + for _, c := range node.Last { Walk(&c, f) } case *ArrayElem: - for _, c := range x.Comments { - if c.Pos().After(x.Pos()) { + for _, c := range node.Comments { + if c.Pos().After(node.Pos()) { defer Walk(&c, f) break } Walk(&c, f) } - if x.Index != nil { - Walk(x.Index, f) + if node.Index != nil { + Walk(node.Index, f) } - if x.Value != nil { - Walk(x.Value, f) + if node.Value != nil { + Walk(node.Value, f) } case *ExtGlob: - Walk(x.Pattern, f) + Walk(node.Pattern, f) case *ProcSubst: - walkStmts(x.Stmts, x.Last, f) + walkStmts(node.Stmts, node.Last, f) case *TimeClause: - if x.Stmt != nil { - Walk(x.Stmt, f) + if node.Stmt != nil { + Walk(node.Stmt, f) } case *CoprocClause: - if x.Name != nil { - Walk(x.Name, f) + if node.Name != nil { + Walk(node.Name, f) } - Walk(x.Stmt, f) + Walk(node.Stmt, f) case *LetClause: - for _, expr := range x.Exprs { + for _, expr := range node.Exprs { Walk(expr, f) } case *TestDecl: - Walk(x.Description, f) - Walk(x.Body, f) + Walk(node.Description, f) + Walk(node.Body, f) default: - panic(fmt.Sprintf("syntax.Walk: unexpected node type %T", x)) + panic(fmt.Sprintf("syntax.Walk: unexpected node type %T", node)) } f(nil) @@ -235,6 +235,7 @@ func Walk(node Node, f func(Node) bool) { func DebugPrint(w io.Writer, node Node) error { p := debugPrinter{out: w} p.print(reflect.ValueOf(node)) + p.printf("\n") return p.err } @@ -308,6 +309,10 @@ func (p *debugPrinter) print(x reflect.Value) { } p.printf("}") default: - p.printf("%#v", x.Interface()) + if s, ok := x.Interface().(fmt.Stringer); ok && !x.IsZero() { + p.printf("%#v (%s)", x.Interface(), s) + } else { + p.printf("%#v", x.Interface()) + } } }