1
0
mirror of https://github.com/prometheus-community/postgres_exporter.git synced 2025-08-08 04:42:07 +03:00

Add self-contained gometalinter build tooling.

This commit is contained in:
Will Rouesnel
2017-06-06 21:39:41 +10:00
parent 0de0311c22
commit e2b6c973a1
710 changed files with 277204 additions and 35 deletions

22
tools/vendor/github.com/kisielk/errcheck/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
Copyright (c) 2013 Kamil Kisiel
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

122
tools/vendor/github.com/kisielk/errcheck/README.md generated vendored Normal file
View File

@@ -0,0 +1,122 @@
# errcheck
errcheck is a program for checking for unchecked errors in go programs.
[![Build Status](https://travis-ci.org/kisielk/errcheck.png?branch=master)](https://travis-ci.org/kisielk/errcheck)
## Install
go get -u github.com/kisielk/errcheck
errcheck requires Go 1.6 or newer and depends on the package go/loader from the golang.org/x/tools repository.
## Use
For basic usage, just give the package path of interest as the first argument:
errcheck github.com/kisielk/errcheck/testdata
To check all packages beneath the current directory:
errcheck ./...
Or check all packages in your $GOPATH and $GOROOT:
errcheck all
errcheck also recognizes the following command-line options:
The `-tags` flag takes a space-separated list of build tags, just like `go
build`. If you are using any custom build tags in your code base, you may need
to specify the relevant tags here.
The `-asserts` flag enables checking for ignored type assertion results. It
takes no arguments.
The `-blank` flag enables checking for assignments of errors to the
blank identifier. It takes no arguments.
## Excluding functions
Use the `-exclude` flag to specify a path to a file containing a list of functions to
be excluded.
errcheck -exclude errcheck_excludes.txt path/to/package
The file should contain one function signature per line. The format for function signatures is
`package.FunctionName` while for methods it's `(package.Receiver).MethodName` for value receivers
and `(*package.Receiver).MethodName` for pointer receivers.
An example of an exclude file is:
io/ioutil.ReadFile
(*net/http.Client).Do
The exclude list is combined with an internal list for functions in the Go standard library that
have an error return type but are documented to never return an error.
### The deprecated method
The `-ignore` flag takes a comma-separated list of pairs of the form package:regex.
For each package, the regex describes which functions to ignore within that package.
The package may be omitted to have the regex apply to all packages.
For example, you may wish to ignore common operations like Read and Write:
errcheck -ignore '[rR]ead|[wW]rite' path/to/package
or you may wish to ignore common functions like the `print` variants in `fmt`:
errcheck -ignore 'fmt:[FS]?[Pp]rint*' path/to/package
The `-ignorepkg` flag takes a comma-separated list of package import paths
to ignore:
errcheck -ignorepkg 'fmt,encoding/binary' path/to/package
Note that this is equivalent to:
errcheck -ignore 'fmt:.*,encoding/binary:.*' path/to/package
If a regex is provided for a package `pkg` via `-ignore`, and `pkg` also appears
in the list of packages passed to `-ignorepkg`, the latter takes precedence;
that is, all functions within `pkg` will be ignored.
Note that by default the `fmt` package is ignored entirely, unless a regex is
specified for it. To disable this, specify a regex that matches nothing:
errcheck -ignore 'fmt:a^' path/to/package
The `-ignoretests` flag disables checking of `_test.go` files. It takes
no arguments.
## Cgo
Currently errcheck is unable to check packages that `import "C"` due to limitations
in the importer.
However, you can use errcheck on packages that depend on those which use cgo. In
order for this to work you need to `go install` the cgo dependencies before running
errcheck on the dependant packages.
See https://github.com/kisielk/errcheck/issues/16 for more details.
## Exit Codes
errcheck returns 1 if any problems were found in the checked files.
It returns 2 if there were any other failures.
# Editor Integration
## Emacs
[go-errcheck.el](https://github.com/dominikh/go-errcheck.el)
integrates errcheck with Emacs by providing a `go-errcheck` command
and customizable variables to automatically pass flags to errcheck.
## Vim
[vim-go](https://github.com/fatih/vim-go) can run errcheck via both its `:GoErrCheck`
and `:GoMetaLinter` commands.

View File

@@ -0,0 +1,481 @@
// Package errcheck is the library used to implement the errcheck command-line tool.
//
// Note: The API of this package has not been finalized and may change at any point.
package errcheck
import (
"bufio"
"errors"
"fmt"
"go/ast"
"go/build"
"go/token"
"go/types"
"os"
"regexp"
"sort"
"strings"
"sync"
"golang.org/x/tools/go/loader"
)
var errorType *types.Interface
func init() {
errorType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface)
}
var (
// ErrNoGoFiles is returned when CheckPackage is run on a package with no Go source files
ErrNoGoFiles = errors.New("package contains no go source files")
)
// UncheckedError indicates the position of an unchecked error return.
type UncheckedError struct {
Pos token.Position
Line string
FuncName string
}
// UncheckedErrors is returned from the CheckPackage function if the package contains
// any unchecked errors.
// Errors should be appended using the Append method, which is safe to use concurrently.
type UncheckedErrors struct {
mu sync.Mutex
// Errors is a list of all the unchecked errors in the package.
// Printing an error reports its position within the file and the contents of the line.
Errors []UncheckedError
}
func (e *UncheckedErrors) Append(errors ...UncheckedError) {
e.mu.Lock()
defer e.mu.Unlock()
e.Errors = append(e.Errors, errors...)
}
func (e *UncheckedErrors) Error() string {
return fmt.Sprintf("%d unchecked errors", len(e.Errors))
}
// Len is the number of elements in the collection.
func (e *UncheckedErrors) Len() int { return len(e.Errors) }
// Swap swaps the elements with indexes i and j.
func (e *UncheckedErrors) Swap(i, j int) { e.Errors[i], e.Errors[j] = e.Errors[j], e.Errors[i] }
type byName struct{ *UncheckedErrors }
// Less reports whether the element with index i should sort before the element with index j.
func (e byName) Less(i, j int) bool {
ei, ej := e.Errors[i], e.Errors[j]
pi, pj := ei.Pos, ej.Pos
if pi.Filename != pj.Filename {
return pi.Filename < pj.Filename
}
if pi.Line != pj.Line {
return pi.Line < pj.Line
}
if pi.Column != pj.Column {
return pi.Column < pj.Column
}
return ei.Line < ej.Line
}
type Checker struct {
// ignore is a map of package names to regular expressions. Identifiers from a package are
// checked against its regular expressions and if any of the expressions match the call
// is not checked.
Ignore map[string]*regexp.Regexp
// If blank is true then assignments to the blank identifier are also considered to be
// ignored errors.
Blank bool
// If asserts is true then ignored type assertion results are also checked
Asserts bool
// build tags
Tags []string
Verbose bool
// If true, checking of of _test.go files is disabled
WithoutTests bool
exclude map[string]bool
}
func NewChecker() *Checker {
c := Checker{}
c.SetExclude(map[string]bool{})
return &c
}
func (c *Checker) SetExclude(l map[string]bool) {
// Default exclude for stdlib functions
c.exclude = map[string]bool{
"math/rand.Read": true,
"(*math/rand.Rand).Read": true,
"(*bytes.Buffer).Write": true,
"(*bytes.Buffer).WriteByte": true,
"(*bytes.Buffer).WriteRune": true,
"(*bytes.Buffer).WriteString": true,
}
for k := range l {
c.exclude[k] = true
}
}
func (c *Checker) logf(msg string, args ...interface{}) {
if c.Verbose {
fmt.Fprintf(os.Stderr, msg+"\n", args...)
}
}
func (c *Checker) load(paths ...string) (*loader.Program, error) {
ctx := build.Default
for _, tag := range c.Tags {
ctx.BuildTags = append(ctx.BuildTags, tag)
}
loadcfg := loader.Config{
Build: &ctx,
}
rest, err := loadcfg.FromArgs(paths, !c.WithoutTests)
if err != nil {
return nil, fmt.Errorf("could not parse arguments: %s", err)
}
if len(rest) > 0 {
return nil, fmt.Errorf("unhandled extra arguments: %v", rest)
}
return loadcfg.Load()
}
// CheckPackages checks packages for errors.
func (c *Checker) CheckPackages(paths ...string) error {
program, err := c.load(paths...)
if err != nil {
return fmt.Errorf("could not type check: %s", err)
}
var wg sync.WaitGroup
u := &UncheckedErrors{}
for _, pkgInfo := range program.InitialPackages() {
if pkgInfo.Pkg.Path() == "unsafe" { // not a real package
continue
}
wg.Add(1)
go func(pkgInfo *loader.PackageInfo) {
defer wg.Done()
c.logf("Checking %s", pkgInfo.Pkg.Path())
v := &visitor{
prog: program,
pkg: pkgInfo,
ignore: c.Ignore,
blank: c.Blank,
asserts: c.Asserts,
lines: make(map[string][]string),
exclude: c.exclude,
errors: []UncheckedError{},
}
for _, astFile := range v.pkg.Files {
ast.Walk(v, astFile)
}
u.Append(v.errors...)
}(pkgInfo)
}
wg.Wait()
if u.Len() > 0 {
sort.Sort(byName{u})
return u
}
return nil
}
// visitor implements the errcheck algorithm
type visitor struct {
prog *loader.Program
pkg *loader.PackageInfo
ignore map[string]*regexp.Regexp
blank bool
asserts bool
lines map[string][]string
exclude map[string]bool
errors []UncheckedError
}
func (v *visitor) fullName(call *ast.CallExpr) (string, bool) {
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return "", false
}
fn, ok := v.pkg.ObjectOf(sel.Sel).(*types.Func)
if !ok {
// Shouldn't happen, but be paranoid
return "", false
}
// The name is fully qualified by the import path, possible type,
// function/method name and pointer receiver.
//
// TODO(dh): vendored packages will have /vendor/ in their name,
// thus not matching vendored standard library packages. If we
// want to support vendored stdlib packages, we need to implement
// FullName with our own logic.
return fn.FullName(), true
}
func (v *visitor) excludeCall(call *ast.CallExpr) bool {
if name, ok := v.fullName(call); ok {
return v.exclude[name]
}
return false
}
func (v *visitor) ignoreCall(call *ast.CallExpr) bool {
if v.excludeCall(call) {
return true
}
// Try to get an identifier.
// Currently only supports simple expressions:
// 1. f()
// 2. x.y.f()
var id *ast.Ident
switch exp := call.Fun.(type) {
case (*ast.Ident):
id = exp
case (*ast.SelectorExpr):
id = exp.Sel
default:
// eg: *ast.SliceExpr, *ast.IndexExpr
}
if id == nil {
return false
}
// If we got an identifier for the function, see if it is ignored
if re, ok := v.ignore[""]; ok && re.MatchString(id.Name) {
return true
}
if obj := v.pkg.Uses[id]; obj != nil {
if pkg := obj.Pkg(); pkg != nil {
if re, ok := v.ignore[pkg.Path()]; ok {
return re.MatchString(id.Name)
}
// if current package being considered is vendored, check to see if it should be ignored based
// on the unvendored path.
if nonVendoredPkg, ok := nonVendoredPkgPath(pkg.Path()); ok {
if re, ok := v.ignore[nonVendoredPkg]; ok {
return re.MatchString(id.Name)
}
}
}
}
return false
}
// nonVendoredPkgPath returns the unvendored version of the provided package path (or returns the provided path if it
// does not represent a vendored path). The second return value is true if the provided package was vendored, false
// otherwise.
func nonVendoredPkgPath(pkgPath string) (string, bool) {
lastVendorIndex := strings.LastIndex(pkgPath, "/vendor/")
if lastVendorIndex == -1 {
return pkgPath, false
}
return pkgPath[lastVendorIndex+len("/vendor/"):], true
}
// errorsByArg returns a slice s such that
// len(s) == number of return types of call
// s[i] == true iff return type at position i from left is an error type
func (v *visitor) errorsByArg(call *ast.CallExpr) []bool {
switch t := v.pkg.Types[call].Type.(type) {
case *types.Named:
// Single return
return []bool{isErrorType(t)}
case *types.Pointer:
// Single return via pointer
return []bool{isErrorType(t)}
case *types.Tuple:
// Multiple returns
s := make([]bool, t.Len())
for i := 0; i < t.Len(); i++ {
switch et := t.At(i).Type().(type) {
case *types.Named:
// Single return
s[i] = isErrorType(et)
case *types.Pointer:
// Single return via pointer
s[i] = isErrorType(et)
default:
s[i] = false
}
}
return s
}
return []bool{false}
}
func (v *visitor) callReturnsError(call *ast.CallExpr) bool {
if v.isRecover(call) {
return true
}
for _, isError := range v.errorsByArg(call) {
if isError {
return true
}
}
return false
}
// isRecover returns true if the given CallExpr is a call to the built-in recover() function.
func (v *visitor) isRecover(call *ast.CallExpr) bool {
if fun, ok := call.Fun.(*ast.Ident); ok {
if _, ok := v.pkg.Uses[fun].(*types.Builtin); ok {
return fun.Name == "recover"
}
}
return false
}
func (v *visitor) addErrorAtPosition(position token.Pos, call *ast.CallExpr) {
pos := v.prog.Fset.Position(position)
lines, ok := v.lines[pos.Filename]
if !ok {
lines = readfile(pos.Filename)
v.lines[pos.Filename] = lines
}
line := "??"
if pos.Line-1 < len(lines) {
line = strings.TrimSpace(lines[pos.Line-1])
}
var name string
if call != nil {
name, _ = v.fullName(call)
}
v.errors = append(v.errors, UncheckedError{pos, line, name})
}
func readfile(filename string) []string {
var f, err = os.Open(filename)
if err != nil {
return nil
}
var lines []string
var scanner = bufio.NewScanner(f)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
return lines
}
func (v *visitor) Visit(node ast.Node) ast.Visitor {
switch stmt := node.(type) {
case *ast.ExprStmt:
if call, ok := stmt.X.(*ast.CallExpr); ok {
if !v.ignoreCall(call) && v.callReturnsError(call) {
v.addErrorAtPosition(call.Lparen, call)
}
}
case *ast.GoStmt:
if !v.ignoreCall(stmt.Call) && v.callReturnsError(stmt.Call) {
v.addErrorAtPosition(stmt.Call.Lparen, stmt.Call)
}
case *ast.DeferStmt:
if !v.ignoreCall(stmt.Call) && v.callReturnsError(stmt.Call) {
v.addErrorAtPosition(stmt.Call.Lparen, stmt.Call)
}
case *ast.AssignStmt:
if len(stmt.Rhs) == 1 {
// single value on rhs; check against lhs identifiers
if call, ok := stmt.Rhs[0].(*ast.CallExpr); ok {
if !v.blank {
break
}
if v.ignoreCall(call) {
break
}
isError := v.errorsByArg(call)
for i := 0; i < len(stmt.Lhs); i++ {
if id, ok := stmt.Lhs[i].(*ast.Ident); ok {
// We shortcut calls to recover() because errorsByArg can't
// check its return types for errors since it returns interface{}.
if id.Name == "_" && (v.isRecover(call) || isError[i]) {
v.addErrorAtPosition(id.NamePos, call)
}
}
}
} else if assert, ok := stmt.Rhs[0].(*ast.TypeAssertExpr); ok {
if !v.asserts {
break
}
if assert.Type == nil {
// type switch
break
}
if len(stmt.Lhs) < 2 {
// assertion result not read
v.addErrorAtPosition(stmt.Rhs[0].Pos(), nil)
} else if id, ok := stmt.Lhs[1].(*ast.Ident); ok && v.blank && id.Name == "_" {
// assertion result ignored
v.addErrorAtPosition(id.NamePos, nil)
}
}
} else {
// multiple value on rhs; in this case a call can't return
// multiple values. Assume len(stmt.Lhs) == len(stmt.Rhs)
for i := 0; i < len(stmt.Lhs); i++ {
if id, ok := stmt.Lhs[i].(*ast.Ident); ok {
if call, ok := stmt.Rhs[i].(*ast.CallExpr); ok {
if !v.blank {
continue
}
if v.ignoreCall(call) {
continue
}
if id.Name == "_" && v.callReturnsError(call) {
v.addErrorAtPosition(id.NamePos, call)
}
} else if assert, ok := stmt.Rhs[i].(*ast.TypeAssertExpr); ok {
if !v.asserts {
continue
}
if assert.Type == nil {
// Shouldn't happen anyway, no multi assignment in type switches
continue
}
v.addErrorAtPosition(id.NamePos, nil)
}
}
}
}
default:
}
return v
}
func isErrorType(t types.Type) bool {
return types.Implements(t, errorType)
}

193
tools/vendor/github.com/kisielk/errcheck/main.go generated vendored Normal file
View File

@@ -0,0 +1,193 @@
package main
import (
"bufio"
"flag"
"fmt"
"os"
"path/filepath"
"regexp"
"runtime"
"strings"
"github.com/kisielk/errcheck/internal/errcheck"
"github.com/kisielk/gotool"
)
const (
exitCodeOk int = iota
exitUncheckedError
exitFatalError
)
var abspath bool
type ignoreFlag map[string]*regexp.Regexp
func (f ignoreFlag) String() string {
pairs := make([]string, 0, len(f))
for pkg, re := range f {
prefix := ""
if pkg != "" {
prefix = pkg + ":"
}
pairs = append(pairs, prefix+re.String())
}
return fmt.Sprintf("%q", strings.Join(pairs, ","))
}
func (f ignoreFlag) Set(s string) error {
if s == "" {
return nil
}
for _, pair := range strings.Split(s, ",") {
colonIndex := strings.Index(pair, ":")
var pkg, re string
if colonIndex == -1 {
pkg = ""
re = pair
} else {
pkg = pair[:colonIndex]
re = pair[colonIndex+1:]
}
regex, err := regexp.Compile(re)
if err != nil {
return err
}
f[pkg] = regex
}
return nil
}
type tagsFlag []string
func (f *tagsFlag) String() string {
return fmt.Sprintf("%q", strings.Join(*f, " "))
}
func (f *tagsFlag) Set(s string) error {
if s == "" {
return nil
}
tags := strings.Split(s, " ")
if tags == nil {
return nil
}
for _, tag := range tags {
if tag != "" {
*f = append(*f, tag)
}
}
return nil
}
var dotStar = regexp.MustCompile(".*")
func reportUncheckedErrors(e *errcheck.UncheckedErrors, verbose bool) {
wd, err := os.Getwd()
if err != nil {
wd = ""
}
for _, uncheckedError := range e.Errors {
pos := uncheckedError.Pos.String()
if !abspath {
newPos, err := filepath.Rel(wd, pos)
if err == nil {
pos = newPos
}
}
if verbose && uncheckedError.FuncName != "" {
fmt.Printf("%s:\t%s\t%s\n", pos, uncheckedError.FuncName, uncheckedError.Line)
} else {
fmt.Printf("%s:\t%s\n", pos, uncheckedError.Line)
}
}
}
func mainCmd(args []string) int {
runtime.GOMAXPROCS(runtime.NumCPU())
checker := errcheck.NewChecker()
paths, err := parseFlags(checker, args)
if err != exitCodeOk {
return err
}
if err := checker.CheckPackages(paths...); err != nil {
if e, ok := err.(*errcheck.UncheckedErrors); ok {
reportUncheckedErrors(e, checker.Verbose)
return exitUncheckedError
} else if err == errcheck.ErrNoGoFiles {
fmt.Fprintln(os.Stderr, err)
return exitCodeOk
}
fmt.Fprintf(os.Stderr, "error: failed to check packages: %s\n", err)
return exitFatalError
}
return exitCodeOk
}
func parseFlags(checker *errcheck.Checker, args []string) ([]string, int) {
flags := flag.NewFlagSet(args[0], flag.ContinueOnError)
flags.BoolVar(&checker.Blank, "blank", false, "if true, check for errors assigned to blank identifier")
flags.BoolVar(&checker.Asserts, "asserts", false, "if true, check for ignored type assertion results")
flags.BoolVar(&checker.WithoutTests, "ignoretests", false, "if true, checking of _test.go files is disabled")
flags.BoolVar(&checker.Verbose, "verbose", false, "produce more verbose logging")
flags.BoolVar(&abspath, "abspath", false, "print absolute paths to files")
tags := tagsFlag{}
flags.Var(&tags, "tags", "space-separated list of build tags to include")
ignorePkg := flags.String("ignorepkg", "", "comma-separated list of package paths to ignore")
ignore := ignoreFlag(map[string]*regexp.Regexp{
"fmt": dotStar,
})
flags.Var(ignore, "ignore", "[deprecated] comma-separated list of pairs of the form pkg:regex\n"+
" the regex is used to ignore names within pkg.")
var excludeFile string
flags.StringVar(&excludeFile, "exclude", "", "Path to a file containing a list of functions to exclude from checking")
if err := flags.Parse(args[1:]); err != nil {
return nil, exitFatalError
}
if excludeFile != "" {
exclude := make(map[string]bool)
fh, err := os.Open(excludeFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not read exclude file: %s\n", err)
return nil, exitFatalError
}
scanner := bufio.NewScanner(fh)
for scanner.Scan() {
name := scanner.Text()
exclude[name] = true
if checker.Verbose {
fmt.Printf("Excluding %s\n", name)
}
}
if err := scanner.Err(); err != nil {
fmt.Fprintf(os.Stderr, "Could not read exclude file: %s\n", err)
return nil, exitFatalError
}
checker.SetExclude(exclude)
}
checker.Tags = tags
for _, pkg := range strings.Split(*ignorePkg, ",") {
if pkg != "" {
ignore[pkg] = dotStar
}
}
checker.Ignore = ignore
// ImportPaths normalizes paths and expands '...'
return gotool.ImportPaths(flags.Args()), exitCodeOk
}
func main() {
os.Exit(mainCmd(os.Args))
}

32
tools/vendor/github.com/kisielk/gotool/LEGAL generated vendored Normal file
View File

@@ -0,0 +1,32 @@
All the files in this distribution are covered under either the MIT
license (see the file LICENSE) except some files mentioned below.
match.go, match_test.go:
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of Google Inc. 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
OWNER 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.

20
tools/vendor/github.com/kisielk/gotool/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
Copyright (c) 2013 Kamil Kisiel <kamil@kamilkisiel.net>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

6
tools/vendor/github.com/kisielk/gotool/README.md generated vendored Normal file
View File

@@ -0,0 +1,6 @@
gotool
======
[![GoDoc](https://godoc.org/github.com/kisielk/gotool?status.svg)](https://godoc.org/github.com/kisielk/gotool)
[![Build Status](https://travis-ci.org/kisielk/gotool.svg?branch=master)](https://travis-ci.org/kisielk/gotool)
Package gotool contains utility functions used to implement the standard "cmd/go" tool, provided as a convenience to developers who want to write tools with similar semantics.

15
tools/vendor/github.com/kisielk/gotool/go13.go generated vendored Normal file
View File

@@ -0,0 +1,15 @@
// +build !go1.4
package gotool
import (
"go/build"
"path/filepath"
"runtime"
)
var gorootSrc = filepath.Join(runtime.GOROOT(), "src", "pkg")
func shouldIgnoreImport(p *build.Package) bool {
return true
}

15
tools/vendor/github.com/kisielk/gotool/go14-15.go generated vendored Normal file
View File

@@ -0,0 +1,15 @@
// +build go1.4,!go1.6
package gotool
import (
"go/build"
"path/filepath"
"runtime"
)
var gorootSrc = filepath.Join(runtime.GOROOT(), "src")
func shouldIgnoreImport(p *build.Package) bool {
return true
}

15
tools/vendor/github.com/kisielk/gotool/go16.go generated vendored Normal file
View File

@@ -0,0 +1,15 @@
// +build go1.6
package gotool
import (
"go/build"
"path/filepath"
"runtime"
)
var gorootSrc = filepath.Join(runtime.GOROOT(), "src")
func shouldIgnoreImport(p *build.Package) bool {
return p == nil || len(p.InvalidGoFiles) == 0
}

310
tools/vendor/github.com/kisielk/gotool/match.go generated vendored Normal file
View File

@@ -0,0 +1,310 @@
// Copyright (c) 2009 The Go Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * 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.
// * Neither the name of Google Inc. 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
// OWNER 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.
package gotool
import (
"fmt"
"go/build"
"log"
"os"
"path"
"path/filepath"
"regexp"
"strings"
)
// This file contains code from the Go distribution.
// matchPattern(pattern)(name) reports whether
// name matches pattern. Pattern is a limited glob
// pattern in which '...' means 'any string' and there
// is no other special syntax.
func matchPattern(pattern string) func(name string) bool {
re := regexp.QuoteMeta(pattern)
re = strings.Replace(re, `\.\.\.`, `.*`, -1)
// Special case: foo/... matches foo too.
if strings.HasSuffix(re, `/.*`) {
re = re[:len(re)-len(`/.*`)] + `(/.*)?`
}
reg := regexp.MustCompile(`^` + re + `$`)
return reg.MatchString
}
func (c *Context) matchPackages(pattern string) []string {
match := func(string) bool { return true }
treeCanMatch := func(string) bool { return true }
if !isMetaPackage(pattern) {
match = matchPattern(pattern)
treeCanMatch = treeCanMatchPattern(pattern)
}
have := map[string]bool{
"builtin": true, // ignore pseudo-package that exists only for documentation
}
if !c.BuildContext.CgoEnabled {
have["runtime/cgo"] = true // ignore during walk
}
var pkgs []string
for _, src := range c.BuildContext.SrcDirs() {
if (pattern == "std" || pattern == "cmd") && src != gorootSrc {
continue
}
src = filepath.Clean(src) + string(filepath.Separator)
root := src
if pattern == "cmd" {
root += "cmd" + string(filepath.Separator)
}
filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
if err != nil || !fi.IsDir() || path == src {
return nil
}
// Avoid .foo, _foo, and testdata directory trees.
_, elem := filepath.Split(path)
if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" {
return filepath.SkipDir
}
name := filepath.ToSlash(path[len(src):])
if pattern == "std" && (!isStandardImportPath(name) || name == "cmd") {
// The name "std" is only the standard library.
// If the name is cmd, it's the root of the command tree.
return filepath.SkipDir
}
if !treeCanMatch(name) {
return filepath.SkipDir
}
if have[name] {
return nil
}
have[name] = true
if !match(name) {
return nil
}
_, err = c.BuildContext.ImportDir(path, 0)
if err != nil {
if _, noGo := err.(*build.NoGoError); noGo {
return nil
}
}
pkgs = append(pkgs, name)
return nil
})
}
return pkgs
}
// importPathsNoDotExpansion returns the import paths to use for the given
// command line, but it does no ... expansion.
func (c *Context) importPathsNoDotExpansion(args []string) []string {
if len(args) == 0 {
return []string{"."}
}
var out []string
for _, a := range args {
// Arguments are supposed to be import paths, but
// as a courtesy to Windows developers, rewrite \ to /
// in command-line arguments. Handles .\... and so on.
if filepath.Separator == '\\' {
a = strings.Replace(a, `\`, `/`, -1)
}
// Put argument in canonical form, but preserve leading ./.
if strings.HasPrefix(a, "./") {
a = "./" + path.Clean(a)
if a == "./." {
a = "."
}
} else {
a = path.Clean(a)
}
if isMetaPackage(a) {
out = append(out, c.allPackages(a)...)
continue
}
out = append(out, a)
}
return out
}
// importPaths returns the import paths to use for the given command line.
func (c *Context) importPaths(args []string) []string {
args = c.importPathsNoDotExpansion(args)
var out []string
for _, a := range args {
if strings.Contains(a, "...") {
if build.IsLocalImport(a) {
out = append(out, c.allPackagesInFS(a)...)
} else {
out = append(out, c.allPackages(a)...)
}
continue
}
out = append(out, a)
}
return out
}
// allPackages returns all the packages that can be found
// under the $GOPATH directories and $GOROOT matching pattern.
// The pattern is either "all" (all packages), "std" (standard packages),
// "cmd" (standard commands), or a path including "...".
func (c *Context) allPackages(pattern string) []string {
pkgs := c.matchPackages(pattern)
if len(pkgs) == 0 {
fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
}
return pkgs
}
// allPackagesInFS is like allPackages but is passed a pattern
// beginning ./ or ../, meaning it should scan the tree rooted
// at the given directory. There are ... in the pattern too.
func (c *Context) allPackagesInFS(pattern string) []string {
pkgs := c.matchPackagesInFS(pattern)
if len(pkgs) == 0 {
fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
}
return pkgs
}
func (c *Context) matchPackagesInFS(pattern string) []string {
// Find directory to begin the scan.
// Could be smarter but this one optimization
// is enough for now, since ... is usually at the
// end of a path.
i := strings.Index(pattern, "...")
dir, _ := path.Split(pattern[:i])
// pattern begins with ./ or ../.
// path.Clean will discard the ./ but not the ../.
// We need to preserve the ./ for pattern matching
// and in the returned import paths.
prefix := ""
if strings.HasPrefix(pattern, "./") {
prefix = "./"
}
match := matchPattern(pattern)
var pkgs []string
filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
if err != nil || !fi.IsDir() {
return nil
}
if path == dir {
// filepath.Walk starts at dir and recurses. For the recursive case,
// the path is the result of filepath.Join, which calls filepath.Clean.
// The initial case is not Cleaned, though, so we do this explicitly.
//
// This converts a path like "./io/" to "io". Without this step, running
// "cd $GOROOT/src; go list ./io/..." would incorrectly skip the io
// package, because prepending the prefix "./" to the unclean path would
// result in "././io", and match("././io") returns false.
path = filepath.Clean(path)
}
// Avoid .foo, _foo, and testdata directory trees, but do not avoid "." or "..".
_, elem := filepath.Split(path)
dot := strings.HasPrefix(elem, ".") && elem != "." && elem != ".."
if dot || strings.HasPrefix(elem, "_") || elem == "testdata" {
return filepath.SkipDir
}
name := prefix + filepath.ToSlash(path)
if !match(name) {
return nil
}
// We keep the directory if we can import it, or if we can't import it
// due to invalid Go source files. This means that directories containing
// parse errors will be built (and fail) instead of being silently skipped
// as not matching the pattern. Go 1.5 and earlier skipped, but that
// behavior means people miss serious mistakes.
// See golang.org/issue/11407.
if p, err := c.BuildContext.ImportDir(path, 0); err != nil && shouldIgnoreImport(p) {
if _, noGo := err.(*build.NoGoError); !noGo {
log.Print(err)
}
return nil
}
pkgs = append(pkgs, name)
return nil
})
return pkgs
}
// isMetaPackage checks if name is a reserved package name that expands to multiple packages
func isMetaPackage(name string) bool {
return name == "std" || name == "cmd" || name == "all"
}
// isStandardImportPath reports whether $GOROOT/src/path should be considered
// part of the standard distribution. For historical reasons we allow people to add
// their own code to $GOROOT instead of using $GOPATH, but we assume that
// code will start with a domain name (dot in the first element).
func isStandardImportPath(path string) bool {
i := strings.Index(path, "/")
if i < 0 {
i = len(path)
}
elem := path[:i]
return !strings.Contains(elem, ".")
}
// hasPathPrefix reports whether the path s begins with the
// elements in prefix.
func hasPathPrefix(s, prefix string) bool {
switch {
default:
return false
case len(s) == len(prefix):
return s == prefix
case len(s) > len(prefix):
if prefix != "" && prefix[len(prefix)-1] == '/' {
return strings.HasPrefix(s, prefix)
}
return s[len(prefix)] == '/' && s[:len(prefix)] == prefix
}
}
// treeCanMatchPattern(pattern)(name) reports whether
// name or children of name can possibly match pattern.
// Pattern is the same limited glob accepted by matchPattern.
func treeCanMatchPattern(pattern string) func(name string) bool {
wildCard := false
if i := strings.Index(pattern, "..."); i >= 0 {
wildCard = true
pattern = pattern[:i]
}
return func(name string) bool {
return len(name) <= len(pattern) && hasPathPrefix(pattern, name) ||
wildCard && strings.HasPrefix(name, pattern)
}
}

48
tools/vendor/github.com/kisielk/gotool/tool.go generated vendored Normal file
View File

@@ -0,0 +1,48 @@
// Package gotool contains utility functions used to implement the standard
// "cmd/go" tool, provided as a convenience to developers who want to write
// tools with similar semantics.
package gotool
import "go/build"
// Export functions here to make it easier to keep the implementations up to date with upstream.
// DefaultContext is the default context that uses build.Default.
var DefaultContext = Context{
BuildContext: build.Default,
}
// A Context specifies the supporting context.
type Context struct {
// BuildContext is the build.Context that is used when computing import paths.
BuildContext build.Context
}
// ImportPaths returns the import paths to use for the given command line.
//
// The path "all" is expanded to all packages in $GOPATH and $GOROOT.
// The path "std" is expanded to all packages in the Go standard library.
// The path "cmd" is expanded to all Go standard commands.
// The string "..." is treated as a wildcard within a path.
// When matching recursively, directories are ignored if they are prefixed with
// a dot or an underscore (such as ".foo" or "_foo"), or are named "testdata".
// Relative import paths are not converted to full import paths.
// If args is empty, a single element "." is returned.
func (c *Context) ImportPaths(args []string) []string {
return c.importPaths(args)
}
// ImportPaths returns the import paths to use for the given command line
// using default context.
//
// The path "all" is expanded to all packages in $GOPATH and $GOROOT.
// The path "std" is expanded to all packages in the Go standard library.
// The path "cmd" is expanded to all Go standard commands.
// The string "..." is treated as a wildcard within a path.
// When matching recursively, directories are ignored if they are prefixed with
// a dot or an underscore (such as ".foo" or "_foo"), or are named "testdata".
// Relative import paths are not converted to full import paths.
// If args is empty, a single element "." is returned.
func ImportPaths(args []string) []string {
return DefaultContext.importPaths(args)
}