From 712de1c63d9db97c81af68cd0dc4372c53d2e57a Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 15 Sep 2020 18:05:35 +0200 Subject: vendor/github.com/golangci/golangci-lint: update to v1.31 --- vendor/github.com/daixiang0/gci/LICENSE | 29 ++ vendor/github.com/daixiang0/gci/pkg/gci/gci.go | 366 +++++++++++++++++++++++++ 2 files changed, 395 insertions(+) create mode 100644 vendor/github.com/daixiang0/gci/LICENSE create mode 100644 vendor/github.com/daixiang0/gci/pkg/gci/gci.go (limited to 'vendor/github.com/daixiang0') diff --git a/vendor/github.com/daixiang0/gci/LICENSE b/vendor/github.com/daixiang0/gci/LICENSE new file mode 100644 index 000000000..e1292f738 --- /dev/null +++ b/vendor/github.com/daixiang0/gci/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2020, Xiang Dai +All rights reserved. + +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/daixiang0/gci/pkg/gci/gci.go b/vendor/github.com/daixiang0/gci/pkg/gci/gci.go new file mode 100644 index 000000000..f91d9b373 --- /dev/null +++ b/vendor/github.com/daixiang0/gci/pkg/gci/gci.go @@ -0,0 +1,366 @@ +package gci + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "sort" + "strings" +) + +const ( + // pkg type: standard, remote, local + standard int = iota + // 3rd-party packages + remote + local + + commentFlag = "//" +) + +var ( + importStartFlag = []byte(` +import ( +`) + + importEndFlag = []byte(` +) +`) +) + +type FlagSet struct { + LocalFlag string + DoWrite, DoDiff *bool +} + +type pkg struct { + list map[int][]string + comment map[string]string + alias map[string]string +} + +func newPkg(data [][]byte, localFlag string) *pkg { + listMap := make(map[int][]string) + commentMap := make(map[string]string) + aliasMap := make(map[string]string) + p := &pkg{ + list: listMap, + comment: commentMap, + alias: aliasMap, + } + + formatData := make([]string, 0) + // remove all empty lines + for _, v := range data { + if len(v) > 0 { + formatData = append(formatData, strings.TrimSpace(string(v))) + } + } + + n := len(formatData) + for i := n - 1; i >= 0; i-- { + line := formatData[i] + + // check commentFlag: + // 1. one line commentFlag + // 2. commentFlag after import path + commentIndex := strings.Index(line, commentFlag) + if commentIndex == 0 { + // comment in the last line is useless, ignore it + if i+1 >= n { + continue + } + pkg, _, _ := getPkgInfo(formatData[i+1], strings.Index(formatData[i+1], commentFlag) >= 0) + p.comment[pkg] = line + continue + } else if commentIndex > 0 { + pkg, alias, comment := getPkgInfo(line, true) + if alias != "" { + p.alias[pkg] = alias + } + + p.comment[pkg] = comment + pkgType := getPkgType(pkg, localFlag) + p.list[pkgType] = append(p.list[pkgType], pkg) + continue + } + + pkg, alias, _ := getPkgInfo(line, false) + + if alias != "" { + p.alias[pkg] = alias + } + + pkgType := getPkgType(pkg, localFlag) + p.list[pkgType] = append(p.list[pkgType], pkg) + } + + return p +} + +// fmt format import pkgs as expected +func (p *pkg) fmt() []byte { + ret := make([]string, 0, 100) + + for pkgType := range []int{standard, remote, local} { + sort.Strings(p.list[pkgType]) + for _, s := range p.list[pkgType] { + if p.comment[s] != "" { + l := fmt.Sprintf("%s%s%s%s", linebreak, indent, p.comment[s], linebreak) + ret = append(ret, l) + } + + if p.alias[s] != "" { + s = fmt.Sprintf("%s%s%s%s%s", indent, p.alias[s], blank, s, linebreak) + } else { + s = fmt.Sprintf("%s%s%s", indent, s, linebreak) + } + + ret = append(ret, s) + } + + if len(p.list[pkgType]) > 0 { + ret = append(ret, linebreak) + } + } + if ret[len(ret)-1] == linebreak { + ret = ret[:len(ret)-1] + } + + // remove duplicate empty lines + s1 := fmt.Sprintf("%s%s%s%s", linebreak, linebreak, linebreak, indent) + s2 := fmt.Sprintf("%s%s%s", linebreak, linebreak, indent) + return []byte(strings.ReplaceAll(strings.Join(ret, ""), s1, s2)) +} + +// getPkgInfo assume line is a import path, and return (path, alias, comment) +func getPkgInfo(line string, comment bool) (string, string, string) { + if comment { + s := strings.Split(line, commentFlag) + pkgArray := strings.Split(s[0], blank) + if len(pkgArray) > 1 { + return pkgArray[1], pkgArray[0], fmt.Sprintf("%s%s%s", commentFlag, blank, strings.TrimSpace(s[1])) + } else { + return strings.TrimSpace(pkgArray[0]), "", fmt.Sprintf("%s%s%s", commentFlag, blank, strings.TrimSpace(s[1])) + } + } else { + pkgArray := strings.Split(line, blank) + if len(pkgArray) > 1 { + return pkgArray[1], pkgArray[0], "" + } else { + return pkgArray[0], "", "" + } + } +} + +func getPkgType(line, localFlag string) int { + if !strings.Contains(line, dot) { + return standard + } else if strings.Contains(line, localFlag) { + return local + } else { + return remote + } +} + +const ( + dot = "." + blank = " " + indent = "\t" + linebreak = "\n" +) + +func diff(b1, b2 []byte, filename string) (data []byte, err error) { + f1, err := writeTempFile("", "gci", b1) + if err != nil { + return + } + defer os.Remove(f1) + + f2, err := writeTempFile("", "gci", b2) + if err != nil { + return + } + defer os.Remove(f2) + + cmd := "diff" + + data, err = exec.Command(cmd, "-u", f1, f2).CombinedOutput() + if len(data) > 0 { + // diff exits with a non-zero status when the files don't match. + // Ignore that failure as long as we get output. + return replaceTempFilename(data, filename) + } + return +} + +func writeTempFile(dir, prefix string, data []byte) (string, error) { + file, err := ioutil.TempFile(dir, prefix) + if err != nil { + return "", err + } + _, err = file.Write(data) + if err1 := file.Close(); err == nil { + err = err1 + } + if err != nil { + os.Remove(file.Name()) + return "", err + } + return file.Name(), nil +} + +// replaceTempFilename replaces temporary filenames in diff with actual one. +// +// --- /tmp/gofmt316145376 2017-02-03 19:13:00.280468375 -0500 +// +++ /tmp/gofmt617882815 2017-02-03 19:13:00.280468375 -0500 +// ... +// -> +// --- path/to/file.go.orig 2017-02-03 19:13:00.280468375 -0500 +// +++ path/to/file.go 2017-02-03 19:13:00.280468375 -0500 +// ... +func replaceTempFilename(diff []byte, filename string) ([]byte, error) { + bs := bytes.SplitN(diff, []byte{'\n'}, 3) + if len(bs) < 3 { + return nil, fmt.Errorf("got unexpected diff for %s", filename) + } + // Preserve timestamps. + var t0, t1 []byte + if i := bytes.LastIndexByte(bs[0], '\t'); i != -1 { + t0 = bs[0][i:] + } + if i := bytes.LastIndexByte(bs[1], '\t'); i != -1 { + t1 = bs[1][i:] + } + // Always print filepath with slash separator. + f := filepath.ToSlash(filename) + bs[0] = []byte(fmt.Sprintf("--- %s%s", f+".orig", t0)) + bs[1] = []byte(fmt.Sprintf("+++ %s%s", f, t1)) + return bytes.Join(bs, []byte{'\n'}), nil +} + +func visitFile(set *FlagSet) filepath.WalkFunc { + return func(path string, f os.FileInfo, err error) error { + if err == nil && isGoFile(f) { + err = processFile(path, os.Stdout, set) + } + return err + } +} + +func WalkDir(path string, set *FlagSet) error { + return filepath.Walk(path, visitFile(set)) +} + +func isGoFile(f os.FileInfo) bool { + // ignore non-Go files + name := f.Name() + return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") +} + +func ProcessFile(filename string, out io.Writer, set *FlagSet) error { + return processFile(filename, out, set) +} + +func processFile(filename string, out io.Writer, set *FlagSet) error { + var err error + + f, err := os.Open(filename) + if err != nil { + return err + } + defer f.Close() + + src, err := ioutil.ReadAll(f) + if err != nil { + return err + } + + ori := make([]byte, len(src)) + copy(ori, src) + start := bytes.Index(src, importStartFlag) + // in case no importStartFlag or importStartFlag exist in the commentFlag + if start < 0 { + fmt.Printf("skip file %s since no import\n", filename) + return nil + } + end := bytes.Index(src[start:], importEndFlag) + start + + ret := bytes.Split(src[start+len(importStartFlag):end], []byte(linebreak)) + + p := newPkg(ret, set.LocalFlag) + + res := append(src[:start+len(importStartFlag)], append(p.fmt(), src[end+1:]...)...) + + if !bytes.Equal(ori, res) { + if *set.DoWrite { + // On Windows, we need to re-set the permissions from the file. See golang/go#38225. + var perms os.FileMode + if fi, err := os.Stat(filename); err == nil { + perms = fi.Mode() & os.ModePerm + } + err = ioutil.WriteFile(filename, res, perms) + if err != nil { + return err + } + } + if *set.DoDiff { + data, err := diff(ori, res, filename) + if err != nil { + return fmt.Errorf("failed to diff: %v", err) + } + fmt.Printf("diff -u %s %s\n", filepath.ToSlash(filename+".orig"), filepath.ToSlash(filename)) + if _, err := out.Write(data); err != nil { + return fmt.Errorf("failed to write: %v", err) + } + } + } + if !*set.DoWrite && !*set.DoDiff { + if _, err = out.Write(res); err != nil { + return fmt.Errorf("failed to write: %v", err) + } + } + + return err +} + +// Run return source and result in []byte if succeed +func Run(filename string, set *FlagSet) ([]byte, []byte, error) { + var err error + + f, err := os.Open(filename) + if err != nil { + return nil, nil, err + } + defer f.Close() + + src, err := ioutil.ReadAll(f) + if err != nil { + return nil, nil, err + } + + ori := make([]byte, len(src)) + copy(ori, src) + start := bytes.Index(src, importStartFlag) + // in case no importStartFlag or importStartFlag exist in the commentFlag + if start < 0 { + return nil, nil, nil + } + end := bytes.Index(src[start:], importEndFlag) + start + + ret := bytes.Split(src[start+len(importStartFlag):end], []byte(linebreak)) + + p := newPkg(ret, set.LocalFlag) + + res := append(src[:start+len(importStartFlag)], append(p.fmt(), src[end+1:]...)...) + + if bytes.Equal(ori, res) { + return ori, nil, nil + } + + return ori, res, nil +} -- cgit mrf-deployment