Vendor godep v79 and use it

pull/6/head
Tim Hockin 2017-09-01 14:37:57 -07:00
parent a29c048e33
commit ac4ffb1e6e
51 changed files with 6228 additions and 13 deletions

19
Godeps/Godeps.json generated
View File

@ -5,6 +5,7 @@
"Packages": [
"github.com/onsi/ginkgo/ginkgo",
"github.com/jteeuwen/go-bindata/go-bindata",
"github.com/tools/godep",
"./..."
],
"Deps": [
@ -1922,11 +1923,20 @@
"ImportPath": "github.com/kr/fs",
"Rev": "2788f0dbd16903de03cb8186e5c7d97b69ad387b"
},
{
"ImportPath": "github.com/kr/pretty",
"Comment": "go.weekly.2011-12-22-24-gf31442d",
"Rev": "f31442d60e51465c69811e2107ae978868dbea5c"
},
{
"ImportPath": "github.com/kr/pty",
"Comment": "release.r56-29-gf7ee69f",
"Rev": "f7ee69f31298ecbe5d2b349c711e2547a617d398"
},
{
"ImportPath": "github.com/kr/text",
"Rev": "6807e777504f54ad073ecef66747de158294b639"
},
{
"ImportPath": "github.com/libopenstorage/openstorage/api",
"Rev": "093a0c3888753c2056e7373183693d670c6bba01"
@ -2519,6 +2529,11 @@
"ImportPath": "github.com/syndtr/gocapability/capability",
"Rev": "e7cb7fa329f456b3855136a2642b197bad7366ba"
},
{
"ImportPath": "github.com/tools/godep",
"Comment": "v79",
"Rev": "f15f6db5da33a4ac48be83e20b9dd838e14f117b"
},
{
"ImportPath": "github.com/ugorji/go/codec",
"Rev": "ded73eae5db7e7a0ef6f55aace87a2873c5d2b74"
@ -2859,6 +2874,10 @@
"ImportPath": "golang.org/x/tools/container/intsets",
"Rev": "2382e3994d48b1d22acc2c86bcad0a2aff028e32"
},
{
"ImportPath": "golang.org/x/tools/go/vcs",
"Rev": "2382e3994d48b1d22acc2c86bcad0a2aff028e32"
},
{
"ImportPath": "google.golang.org/api/cloudkms/v1",
"Rev": "654f863362977d69086620b5f72f13e911da2410"

127
Godeps/LICENSES generated
View File

@ -66824,6 +66824,35 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
================================================================================
= vendor/github.com/kr/pretty licensed under: =
The MIT License (MIT)
Copyright 2012 Keith Rarick
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.
= vendor/github.com/kr/pretty/License 9d305c2010c6891ee4f3cd42a562f78f
================================================================================
================================================================================
= vendor/github.com/kr/pty licensed under: =
@ -66855,6 +66884,33 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================================================
================================================================================
= vendor/github.com/kr/text licensed under: =
Copyright 2012 Keith Rarick
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.
= vendor/github.com/kr/text/License 449bfedd81a372635934cf9ce004c0cf
================================================================================
================================================================================
= vendor/github.com/libopenstorage/openstorage/api licensed under: =
@ -79402,6 +79458,42 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
================================================================================
= vendor/github.com/tools/godep licensed under: =
Copyright © 2013 Keith Rarick.
Portions Copyright (c) 2012 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.
= vendor/github.com/tools/godep/License 71eb66e9b353dd06ca5a81ce0f469e1a
================================================================================
================================================================================
= vendor/github.com/ugorji/go/codec licensed under: =
@ -86286,6 +86378,41 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
================================================================================
= vendor/golang.org/x/tools/go/vcs licensed under: =
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.
= vendor/golang.org/x/tools/LICENSE 5d4950ecb7b26d2c5e4e7b4e0dd74707
================================================================================
================================================================================
= vendor/google.golang.org/api/cloudkms/v1 licensed under: =

View File

@ -58,6 +58,7 @@ fi
REQUIRED_BINS=(
"github.com/onsi/ginkgo/ginkgo"
"github.com/jteeuwen/go-bindata/go-bindata"
"github.com/tools/godep"
"./..."
)

View File

@ -521,20 +521,9 @@ kube::util::ensure_godep_version() {
return
fi
kube::log::status "Getting godep version ${GODEP_VERSION}"
kube::util::ensure-temp-dir
mkdir -p "${KUBE_TEMP}/go/src"
kube::log::status "Installing godep version ${GODEP_VERSION}"
go install ./vendor/github.com/tools/godep/
GP="$(echo $GOPATH | cut -f1 -d:)"
rm -rf "${GP}/src/github.com/tools/godep"
go get -d -u github.com/tools/godep
pushd "${GP}/src/github.com/tools/godep" >/dev/null
git checkout -q "${GODEP_VERSION}"
go install .
popd >/dev/null
hash -r # force bash to clear PATH cache
PATH="${PATH}:${GP}/bin"
if [[ "$(godep version 2>/dev/null)" != *"godep ${GODEP_VERSION}"* ]]; then
kube::log::error "Expected godep ${GODEP_VERSION}, got $(godep version)"
return 1

4
vendor/BUILD vendored
View File

@ -258,7 +258,9 @@ filegroup(
"//vendor/github.com/kardianos/osext:all-srcs",
"//vendor/github.com/karlseguin/ccache:all-srcs",
"//vendor/github.com/kr/fs:all-srcs",
"//vendor/github.com/kr/pretty:all-srcs",
"//vendor/github.com/kr/pty:all-srcs",
"//vendor/github.com/kr/text:all-srcs",
"//vendor/github.com/libopenstorage/openstorage/api:all-srcs",
"//vendor/github.com/libopenstorage/openstorage/pkg/parser:all-srcs",
"//vendor/github.com/libopenstorage/openstorage/pkg/units:all-srcs",
@ -323,6 +325,7 @@ filegroup(
"//vendor/github.com/stretchr/testify/mock:all-srcs",
"//vendor/github.com/stretchr/testify/require:all-srcs",
"//vendor/github.com/syndtr/gocapability/capability:all-srcs",
"//vendor/github.com/tools/godep:all-srcs",
"//vendor/github.com/ugorji/go/codec:all-srcs",
"//vendor/github.com/vishvananda/netlink:all-srcs",
"//vendor/github.com/vishvananda/netns:all-srcs",
@ -368,6 +371,7 @@ filegroup(
"//vendor/golang.org/x/text/width:all-srcs",
"//vendor/golang.org/x/time/rate:all-srcs",
"//vendor/golang.org/x/tools/container/intsets:all-srcs",
"//vendor/golang.org/x/tools/go/vcs:all-srcs",
"//vendor/google.golang.org/api/cloudkms/v1:all-srcs",
"//vendor/google.golang.org/api/cloudmonitoring/v2beta2:all-srcs",
"//vendor/google.golang.org/api/compute/v0.alpha:all-srcs",

4
vendor/github.com/kr/pretty/.gitignore generated vendored Normal file
View File

@ -0,0 +1,4 @@
[568].out
_go*
_test*
_obj

27
vendor/github.com/kr/pretty/BUILD generated vendored Normal file
View File

@ -0,0 +1,27 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"diff.go",
"formatter.go",
"pretty.go",
"zero.go",
],
visibility = ["//visibility:public"],
deps = ["//vendor/github.com/kr/text:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

21
vendor/github.com/kr/pretty/License generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright 2012 Keith Rarick
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.

9
vendor/github.com/kr/pretty/Readme generated vendored Normal file
View File

@ -0,0 +1,9 @@
package pretty
import "github.com/kr/pretty"
Package pretty provides pretty-printing for Go values.
Documentation
http://godoc.org/github.com/kr/pretty

158
vendor/github.com/kr/pretty/diff.go generated vendored Normal file
View File

@ -0,0 +1,158 @@
package pretty
import (
"fmt"
"io"
"reflect"
)
type sbuf []string
func (s *sbuf) Write(b []byte) (int, error) {
*s = append(*s, string(b))
return len(b), nil
}
// Diff returns a slice where each element describes
// a difference between a and b.
func Diff(a, b interface{}) (desc []string) {
Fdiff((*sbuf)(&desc), a, b)
return desc
}
// Fdiff writes to w a description of the differences between a and b.
func Fdiff(w io.Writer, a, b interface{}) {
diffWriter{w: w}.diff(reflect.ValueOf(a), reflect.ValueOf(b))
}
type diffWriter struct {
w io.Writer
l string // label
}
func (w diffWriter) printf(f string, a ...interface{}) {
var l string
if w.l != "" {
l = w.l + ": "
}
fmt.Fprintf(w.w, l+f, a...)
}
func (w diffWriter) diff(av, bv reflect.Value) {
if !av.IsValid() && bv.IsValid() {
w.printf("nil != %#v", bv.Interface())
return
}
if av.IsValid() && !bv.IsValid() {
w.printf("%#v != nil", av.Interface())
return
}
if !av.IsValid() && !bv.IsValid() {
return
}
at := av.Type()
bt := bv.Type()
if at != bt {
w.printf("%v != %v", at, bt)
return
}
// numeric types, including bool
if at.Kind() < reflect.Array {
a, b := av.Interface(), bv.Interface()
if a != b {
w.printf("%#v != %#v", a, b)
}
return
}
switch at.Kind() {
case reflect.String:
a, b := av.Interface(), bv.Interface()
if a != b {
w.printf("%q != %q", a, b)
}
case reflect.Ptr:
switch {
case av.IsNil() && !bv.IsNil():
w.printf("nil != %v", bv.Interface())
case !av.IsNil() && bv.IsNil():
w.printf("%v != nil", av.Interface())
case !av.IsNil() && !bv.IsNil():
w.diff(av.Elem(), bv.Elem())
}
case reflect.Struct:
for i := 0; i < av.NumField(); i++ {
w.relabel(at.Field(i).Name).diff(av.Field(i), bv.Field(i))
}
case reflect.Slice:
lenA := av.Len()
lenB := bv.Len()
if lenA != lenB {
w.printf("%s[%d] != %s[%d]", av.Type(), lenA, bv.Type(), lenB)
break
}
for i := 0; i < lenA; i++ {
w.relabel(fmt.Sprintf("[%d]", i)).diff(av.Index(i), bv.Index(i))
}
case reflect.Map:
ak, both, bk := keyDiff(av.MapKeys(), bv.MapKeys())
for _, k := range ak {
w := w.relabel(fmt.Sprintf("[%#v]", k.Interface()))
w.printf("%q != (missing)", av.MapIndex(k))
}
for _, k := range both {
w := w.relabel(fmt.Sprintf("[%#v]", k.Interface()))
w.diff(av.MapIndex(k), bv.MapIndex(k))
}
for _, k := range bk {
w := w.relabel(fmt.Sprintf("[%#v]", k.Interface()))
w.printf("(missing) != %q", bv.MapIndex(k))
}
case reflect.Interface:
w.diff(reflect.ValueOf(av.Interface()), reflect.ValueOf(bv.Interface()))
default:
if !reflect.DeepEqual(av.Interface(), bv.Interface()) {
w.printf("%# v != %# v", Formatter(av.Interface()), Formatter(bv.Interface()))
}
}
}
func (d diffWriter) relabel(name string) (d1 diffWriter) {
d1 = d
if d.l != "" && name[0] != '[' {
d1.l += "."
}
d1.l += name
return d1
}
func keyDiff(a, b []reflect.Value) (ak, both, bk []reflect.Value) {
for _, av := range a {
inBoth := false
for _, bv := range b {
if reflect.DeepEqual(av.Interface(), bv.Interface()) {
inBoth = true
both = append(both, av)
break
}
}
if !inBoth {
ak = append(ak, av)
}
}
for _, bv := range b {
inBoth := false
for _, av := range a {
if reflect.DeepEqual(av.Interface(), bv.Interface()) {
inBoth = true
break
}
}
if !inBoth {
bk = append(bk, bv)
}
}
return
}

337
vendor/github.com/kr/pretty/formatter.go generated vendored Normal file
View File

@ -0,0 +1,337 @@
package pretty
import (
"fmt"
"io"
"reflect"
"strconv"
"text/tabwriter"
"github.com/kr/text"
)
const (
limit = 50
)
type formatter struct {
x interface{}
force bool
quote bool
}
// Formatter makes a wrapper, f, that will format x as go source with line
// breaks and tabs. Object f responds to the "%v" formatting verb when both the
// "#" and " " (space) flags are set, for example:
//
// fmt.Sprintf("%# v", Formatter(x))
//
// If one of these two flags is not set, or any other verb is used, f will
// format x according to the usual rules of package fmt.
// In particular, if x satisfies fmt.Formatter, then x.Format will be called.
func Formatter(x interface{}) (f fmt.Formatter) {
return formatter{x: x, quote: true}
}
func (fo formatter) String() string {
return fmt.Sprint(fo.x) // unwrap it
}
func (fo formatter) passThrough(f fmt.State, c rune) {
s := "%"
for i := 0; i < 128; i++ {
if f.Flag(i) {
s += string(i)
}
}
if w, ok := f.Width(); ok {
s += fmt.Sprintf("%d", w)
}
if p, ok := f.Precision(); ok {
s += fmt.Sprintf(".%d", p)
}
s += string(c)
fmt.Fprintf(f, s, fo.x)
}
func (fo formatter) Format(f fmt.State, c rune) {
if fo.force || c == 'v' && f.Flag('#') && f.Flag(' ') {
w := tabwriter.NewWriter(f, 4, 4, 1, ' ', 0)
p := &printer{tw: w, Writer: w, visited: make(map[visit]int)}
p.printValue(reflect.ValueOf(fo.x), true, fo.quote)
w.Flush()
return
}
fo.passThrough(f, c)
}
type printer struct {
io.Writer
tw *tabwriter.Writer
visited map[visit]int
depth int
}
func (p *printer) indent() *printer {
q := *p
q.tw = tabwriter.NewWriter(p.Writer, 4, 4, 1, ' ', 0)
q.Writer = text.NewIndentWriter(q.tw, []byte{'\t'})
return &q
}
func (p *printer) printInline(v reflect.Value, x interface{}, showType bool) {
if showType {
io.WriteString(p, v.Type().String())
fmt.Fprintf(p, "(%#v)", x)
} else {
fmt.Fprintf(p, "%#v", x)
}
}
// printValue must keep track of already-printed pointer values to avoid
// infinite recursion.
type visit struct {
v uintptr
typ reflect.Type
}
func (p *printer) printValue(v reflect.Value, showType, quote bool) {
if p.depth > 10 {
io.WriteString(p, "!%v(DEPTH EXCEEDED)")
return
}
switch v.Kind() {
case reflect.Bool:
p.printInline(v, v.Bool(), showType)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p.printInline(v, v.Int(), showType)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
p.printInline(v, v.Uint(), showType)
case reflect.Float32, reflect.Float64:
p.printInline(v, v.Float(), showType)
case reflect.Complex64, reflect.Complex128:
fmt.Fprintf(p, "%#v", v.Complex())
case reflect.String:
p.fmtString(v.String(), quote)
case reflect.Map:
t := v.Type()
if showType {
io.WriteString(p, t.String())
}
writeByte(p, '{')
if nonzero(v) {
expand := !canInline(v.Type())
pp := p
if expand {
writeByte(p, '\n')
pp = p.indent()
}
keys := v.MapKeys()
for i := 0; i < v.Len(); i++ {
showTypeInStruct := true
k := keys[i]
mv := v.MapIndex(k)
pp.printValue(k, false, true)
writeByte(pp, ':')
if expand {
writeByte(pp, '\t')
}
showTypeInStruct = t.Elem().Kind() == reflect.Interface
pp.printValue(mv, showTypeInStruct, true)
if expand {
io.WriteString(pp, ",\n")
} else if i < v.Len()-1 {
io.WriteString(pp, ", ")
}
}
if expand {
pp.tw.Flush()
}
}
writeByte(p, '}')
case reflect.Struct:
t := v.Type()
if v.CanAddr() {
addr := v.UnsafeAddr()
vis := visit{addr, t}
if vd, ok := p.visited[vis]; ok && vd < p.depth {
p.fmtString(t.String()+"{(CYCLIC REFERENCE)}", false)
break // don't print v again
}
p.visited[vis] = p.depth
}
if showType {
io.WriteString(p, t.String())
}
writeByte(p, '{')
if nonzero(v) {
expand := !canInline(v.Type())
pp := p
if expand {
writeByte(p, '\n')
pp = p.indent()
}
for i := 0; i < v.NumField(); i++ {
showTypeInStruct := true
if f := t.Field(i); f.Name != "" {
io.WriteString(pp, f.Name)
writeByte(pp, ':')
if expand {
writeByte(pp, '\t')
}
showTypeInStruct = labelType(f.Type)
}
pp.printValue(getField(v, i), showTypeInStruct, true)
if expand {
io.WriteString(pp, ",\n")
} else if i < v.NumField()-1 {
io.WriteString(pp, ", ")
}
}
if expand {
pp.tw.Flush()
}
}
writeByte(p, '}')
case reflect.Interface:
switch e := v.Elem(); {
case e.Kind() == reflect.Invalid:
io.WriteString(p, "nil")
case e.IsValid():
pp := *p
pp.depth++
pp.printValue(e, showType, true)
default:
io.WriteString(p, v.Type().String())
io.WriteString(p, "(nil)")
}
case reflect.Array, reflect.Slice:
t := v.Type()
if showType {
io.WriteString(p, t.String())
}
if v.Kind() == reflect.Slice && v.IsNil() && showType {
io.WriteString(p, "(nil)")
break
}
if v.Kind() == reflect.Slice && v.IsNil() {
io.WriteString(p, "nil")
break
}
writeByte(p, '{')
expand := !canInline(v.Type())
pp := p
if expand {
writeByte(p, '\n')
pp = p.indent()
}
for i := 0; i < v.Len(); i++ {
showTypeInSlice := t.Elem().Kind() == reflect.Interface
pp.printValue(v.Index(i), showTypeInSlice, true)
if expand {
io.WriteString(pp, ",\n")
} else if i < v.Len()-1 {
io.WriteString(pp, ", ")
}
}
if expand {
pp.tw.Flush()
}
writeByte(p, '}')
case reflect.Ptr:
e := v.Elem()
if !e.IsValid() {
writeByte(p, '(')
io.WriteString(p, v.Type().String())
io.WriteString(p, ")(nil)")
} else {
pp := *p
pp.depth++
writeByte(pp, '&')
pp.printValue(e, true, true)
}
case reflect.Chan:
x := v.Pointer()
if showType {
writeByte(p, '(')
io.WriteString(p, v.Type().String())
fmt.Fprintf(p, ")(%#v)", x)
} else {
fmt.Fprintf(p, "%#v", x)
}
case reflect.Func:
io.WriteString(p, v.Type().String())
io.WriteString(p, " {...}")
case reflect.UnsafePointer:
p.printInline(v, v.Pointer(), showType)
case reflect.Invalid:
io.WriteString(p, "nil")
}
}
func canInline(t reflect.Type) bool {
switch t.Kind() {
case reflect.Map:
return !canExpand(t.Elem())
case reflect.Struct:
for i := 0; i < t.NumField(); i++ {
if canExpand(t.Field(i).Type) {
return false
}
}
return true
case reflect.Interface:
return false
case reflect.Array, reflect.Slice:
return !canExpand(t.Elem())
case reflect.Ptr:
return false
case reflect.Chan, reflect.Func, reflect.UnsafePointer:
return false
}
return true
}
func canExpand(t reflect.Type) bool {
switch t.Kind() {
case reflect.Map, reflect.Struct,
reflect.Interface, reflect.Array, reflect.Slice,
reflect.Ptr:
return true
}
return false
}
func labelType(t reflect.Type) bool {
switch t.Kind() {
case reflect.Interface, reflect.Struct:
return true
}
return false
}
func (p *printer) fmtString(s string, quote bool) {
if quote {
s = strconv.Quote(s)
}
io.WriteString(p, s)
}
func tryDeepEqual(a, b interface{}) bool {
defer func() { recover() }()
return reflect.DeepEqual(a, b)
}
func writeByte(w io.Writer, b byte) {
w.Write([]byte{b})
}
func getField(v reflect.Value, i int) reflect.Value {
val := v.Field(i)
if val.Kind() == reflect.Interface && !val.IsNil() {
val = val.Elem()
}
return val
}

98
vendor/github.com/kr/pretty/pretty.go generated vendored Normal file
View File

@ -0,0 +1,98 @@
// Package pretty provides pretty-printing for Go values. This is
// useful during debugging, to avoid wrapping long output lines in
// the terminal.
//
// It provides a function, Formatter, that can be used with any
// function that accepts a format string. It also provides
// convenience wrappers for functions in packages fmt and log.
package pretty
import (
"fmt"
"io"
"log"
)
// Errorf is a convenience wrapper for fmt.Errorf.
//
// Calling Errorf(f, x, y) is equivalent to
// fmt.Errorf(f, Formatter(x), Formatter(y)).
func Errorf(format string, a ...interface{}) error {
return fmt.Errorf(format, wrap(a, false)...)
}
// Fprintf is a convenience wrapper for fmt.Fprintf.
//
// Calling Fprintf(w, f, x, y) is equivalent to
// fmt.Fprintf(w, f, Formatter(x), Formatter(y)).
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, error error) {
return fmt.Fprintf(w, format, wrap(a, false)...)
}
// Log is a convenience wrapper for log.Printf.
//
// Calling Log(x, y) is equivalent to
// log.Print(Formatter(x), Formatter(y)), but each operand is
// formatted with "%# v".
func Log(a ...interface{}) {
log.Print(wrap(a, true)...)
}
// Logf is a convenience wrapper for log.Printf.
//
// Calling Logf(f, x, y) is equivalent to
// log.Printf(f, Formatter(x), Formatter(y)).
func Logf(format string, a ...interface{}) {
log.Printf(format, wrap(a, false)...)
}
// Logln is a convenience wrapper for log.Printf.
//
// Calling Logln(x, y) is equivalent to
// log.Println(Formatter(x), Formatter(y)), but each operand is
// formatted with "%# v".
func Logln(a ...interface{}) {
log.Println(wrap(a, true)...)
}
// Print pretty-prints its operands and writes to standard output.
//
// Calling Print(x, y) is equivalent to
// fmt.Print(Formatter(x), Formatter(y)), but each operand is
// formatted with "%# v".
func Print(a ...interface{}) (n int, errno error) {
return fmt.Print(wrap(a, true)...)
}
// Printf is a convenience wrapper for fmt.Printf.
//
// Calling Printf(f, x, y) is equivalent to
// fmt.Printf(f, Formatter(x), Formatter(y)).
func Printf(format string, a ...interface{}) (n int, errno error) {
return fmt.Printf(format, wrap(a, false)...)
}
// Println pretty-prints its operands and writes to standard output.
//
// Calling Print(x, y) is equivalent to
// fmt.Println(Formatter(x), Formatter(y)), but each operand is
// formatted with "%# v".
func Println(a ...interface{}) (n int, errno error) {
return fmt.Println(wrap(a, true)...)
}
// Sprintf is a convenience wrapper for fmt.Sprintf.
//
// Calling Sprintf(f, x, y) is equivalent to
// fmt.Sprintf(f, Formatter(x), Formatter(y)).
func Sprintf(format string, a ...interface{}) string {
return fmt.Sprintf(format, wrap(a, false)...)
}
func wrap(a []interface{}, force bool) []interface{} {
w := make([]interface{}, len(a))
for i, x := range a {
w[i] = formatter{x: x, force: force}
}
return w
}

41
vendor/github.com/kr/pretty/zero.go generated vendored Normal file
View File

@ -0,0 +1,41 @@
package pretty
import (
"reflect"
)
func nonzero(v reflect.Value) bool {
switch v.Kind() {
case reflect.Bool:
return v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() != 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() != 0
case reflect.Float32, reflect.Float64:
return v.Float() != 0
case reflect.Complex64, reflect.Complex128:
return v.Complex() != complex(0, 0)
case reflect.String:
return v.String() != ""
case reflect.Struct:
for i := 0; i < v.NumField(); i++ {
if nonzero(getField(v, i)) {
return true
}
}
return false
case reflect.Array:
for i := 0; i < v.Len(); i++ {
if nonzero(v.Index(i)) {
return true
}
}
return false
case reflect.Map, reflect.Interface, reflect.Slice, reflect.Ptr, reflect.Chan, reflect.Func:
return !v.IsNil()
case reflect.UnsafePointer:
return v.Pointer() != 0
}
return true
}

25
vendor/github.com/kr/text/BUILD generated vendored Normal file
View File

@ -0,0 +1,25 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"indent.go",
"wrap.go",
],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

19
vendor/github.com/kr/text/License generated vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright 2012 Keith Rarick
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.

3
vendor/github.com/kr/text/Readme generated vendored Normal file
View File

@ -0,0 +1,3 @@
This is a Go package for manipulating paragraphs of text.
See http://go.pkgdoc.org/github.com/kr/text for full documentation.

3
vendor/github.com/kr/text/doc.go generated vendored Normal file
View File

@ -0,0 +1,3 @@
// Package text provides rudimentary functions for manipulating text in
// paragraphs.
package text

74
vendor/github.com/kr/text/indent.go generated vendored Normal file
View File

@ -0,0 +1,74 @@
package text
import (
"io"
)
// Indent inserts prefix at the beginning of each non-empty line of s. The
// end-of-line marker is NL.
func Indent(s, prefix string) string {
return string(IndentBytes([]byte(s), []byte(prefix)))
}
// IndentBytes inserts prefix at the beginning of each non-empty line of b.
// The end-of-line marker is NL.
func IndentBytes(b, prefix []byte) []byte {
var res []byte
bol := true
for _, c := range b {
if bol && c != '\n' {
res = append(res, prefix...)
}
res = append(res, c)
bol = c == '\n'
}
return res
}
// Writer indents each line of its input.
type indentWriter struct {
w io.Writer
bol bool
pre [][]byte
sel int
off int
}
// NewIndentWriter makes a new write filter that indents the input
// lines. Each line is prefixed in order with the corresponding
// element of pre. If there are more lines than elements, the last
// element of pre is repeated for each subsequent line.
func NewIndentWriter(w io.Writer, pre ...[]byte) io.Writer {
return &indentWriter{
w: w,
pre: pre,
bol: true,
}
}
// The only errors returned are from the underlying indentWriter.
func (w *indentWriter) Write(p []byte) (n int, err error) {
for _, c := range p {
if w.bol {
var i int
i, err = w.w.Write(w.pre[w.sel][w.off:])
w.off += i
if err != nil {
return n, err
}
}
_, err = w.w.Write([]byte{c})
if err != nil {
return n, err
}
n++
w.bol = c == '\n'
if w.bol {
w.off = 0
if w.sel < len(w.pre)-1 {
w.sel++
}
}
}
return n, nil
}

86
vendor/github.com/kr/text/wrap.go generated vendored Executable file
View File

@ -0,0 +1,86 @@
package text
import (
"bytes"
"math"
)
var (
nl = []byte{'\n'}
sp = []byte{' '}
)
const defaultPenalty = 1e5
// Wrap wraps s into a paragraph of lines of length lim, with minimal
// raggedness.
func Wrap(s string, lim int) string {
return string(WrapBytes([]byte(s), lim))
}
// WrapBytes wraps b into a paragraph of lines of length lim, with minimal
// raggedness.
func WrapBytes(b []byte, lim int) []byte {
words := bytes.Split(bytes.Replace(bytes.TrimSpace(b), nl, sp, -1), sp)
var lines [][]byte
for _, line := range WrapWords(words, 1, lim, defaultPenalty) {
lines = append(lines, bytes.Join(line, sp))
}
return bytes.Join(lines, nl)
}
// WrapWords is the low-level line-breaking algorithm, useful if you need more
// control over the details of the text wrapping process. For most uses, either
// Wrap or WrapBytes will be sufficient and more convenient.
//
// WrapWords splits a list of words into lines with minimal "raggedness",
// treating each byte as one unit, accounting for spc units between adjacent
// words on each line, and attempting to limit lines to lim units. Raggedness
// is the total error over all lines, where error is the square of the
// difference of the length of the line and lim. Too-long lines (which only
// happen when a single word is longer than lim units) have pen penalty units
// added to the error.
func WrapWords(words [][]byte, spc, lim, pen int) [][][]byte {
n := len(words)
length := make([][]int, n)
for i := 0; i < n; i++ {
length[i] = make([]int, n)
length[i][i] = len(words[i])
for j := i + 1; j < n; j++ {
length[i][j] = length[i][j-1] + spc + len(words[j])
}
}
nbrk := make([]int, n)
cost := make([]int, n)
for i := range cost {
cost[i] = math.MaxInt32
}
for i := n - 1; i >= 0; i-- {
if length[i][n-1] <= lim {
cost[i] = 0
nbrk[i] = n
} else {
for j := i + 1; j < n; j++ {
d := lim - length[i][j-1]
c := d*d + cost[j]
if length[i][j-1] > lim {
c += pen // too-long lines get a worse penalty
}
if c < cost[i] {
cost[i] = c
nbrk[i] = j
}
}
}
}
var lines [][][]byte
i := 0
for i < n {
lines = append(lines, words[i:nbrk[i]])
i = nbrk[i]
}
return lines
}

1
vendor/github.com/tools/godep/.gitignore generated vendored Normal file
View File

@ -0,0 +1 @@
/godep

34
vendor/github.com/tools/godep/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,34 @@
language: go
sudo: false
go: 1.6
script:
# Godep's unit tests run git, and git complains
# if we don't set these config parameters.
# We put dummy values here because they don't matter.
- git config --global user.email "you@example.com"
- git config --global user.name "Your Name"
- test -z "$(go fmt)"
- go vet
- go test -v
- go test -v -race
- test -z "$(goimports -l .)"
before_install:
- go get golang.org/x/tools/cmd/goimports
before_deploy:
- export OS_TARGETS="linux darwin windows"
- export ARCH_TARGETS="386 amd64"
- go get github.com/mitchellh/gox
- gox -os "$OS_TARGETS" -arch="$ARCH_TARGETS"
deploy:
skip_cleanup: true
provider: releases
api_key:
secure: Q1JP8LziaXMTxFmNXiyC1YhS9e4M4WnI6UDjRTMf6mm1LZeJyUFOCCtXnifL7RyCIR1hpjp6s8M1aWE+NpuweF96IZI3Uk4ASx5C8FePC4qvhsCdtJ2sLD2GTIrp9b0MS9/+ao20AIbpVDSaLaF9IjqXpMxMyM0P8P5coRTkwItlGxmQbVJW3YuiYcPa8UojwM4EyafO2CIoUKapW8lwb9KcimBJV8PfF/XZjPVhMkn2ABhh5Hqbn2zBJtvPYMMzi0CnY50JQF5LwN3vGTMpTsRP+lOLCNbOWfkl+2hgG7VpKrtx+cX62knOodpF457sIJ31KUzmeLUVBejTGb1zuVeTojuyi8Huo8YBIBCcN+p3Dqd+n2ZK45mIrheGiEJIkf/vI4MI6A01Nu/o+xU0IPsVfAL/xU5j5nntEGfFWVoclPrl9qcfqf74xdRcARzcCJVmdc8iw49DBDHJfnPa3zxzVz//00+Rz6mZXmhk+Npk/HLLNW59vmJIjP+8XOtPor7dST9HrS1a9AcnmIjNuw9yfbwK5769SDVxCKgqNwXW/Dy5F39aIH5AL4I4y9hCEeeT8ctvSJHGOyiB9MWU5jnt5tluPtz5opG51tFXnIYP/XaWpTfO+eJ6x55pbwT+n3LfRS5l1POM+jGAFF1MFWwc14RY7qynEIEzm4Wb/UE=
file:
- godep_darwin_amd64
- godep_linux_amd64
- godep_windows_386.exe
- godep_windows_amd64.exe
on:
tags: true
repo: tools/godep

54
vendor/github.com/tools/godep/BUILD generated vendored Normal file
View File

@ -0,0 +1,54 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "go_default_library",
srcs = [
"dep.go",
"diff.go",
"doc.go",
"errors.go",
"get.go",
"go.go",
"godepfile.go",
"license.go",
"list.go",
"main.go",
"msg.go",
"path.go",
"pkg.go",
"restore.go",
"rewrite.go",
"save.go",
"update.go",
"util.go",
"vcs.go",
"version.go",
],
visibility = ["//visibility:private"],
deps = [
"//vendor/github.com/kr/fs:go_default_library",
"//vendor/github.com/kr/pretty:go_default_library",
"//vendor/github.com/pmezard/go-difflib/difflib:go_default_library",
"//vendor/golang.org/x/tools/go/vcs:go_default_library",
],
)
go_binary(
name = "godep",
library = ":go_default_library",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

408
vendor/github.com/tools/godep/Changelog.md generated vendored Normal file
View File

@ -0,0 +1,408 @@
#v79 (2017/02/01)
* Fixes #531: fullPackageInDir didn't capture the error from fillPackage()
#v78 (2017/01/19)
* Don't use build.ImportDir when discovering packages for the package spec. Fixes #529
#v77 (2017/01/13)
* Don't include quotes around hg revisions
#v76 (2017/01/10)
* Default to vendor being on unless older go versions.
#v75 (2016/11/02)
* Add "AUTHORS" and "CONTRIBUTORS" to legal files list: https://github.com/tools/godep/pull/522
#v74 (2016/06/01)
* Enable vendor/ on go1.7
* No longer use a godep workspace, use vendor/ (yay!)
* Notify that support for Godep workspaces will be removed once go1.8 ships
#v73 (2016/05/31)
* Fix permission changes on Windows via @alexbrand. Closes #481.
#v72 (2016/05/27)
* Improve handling of git remote show origin. Should help in cases where remote HEAD is ambiguous.
* Add ISSUE_TEMPLATE
#v71 (2016/05/24)
* Preserve permissions on copied files.
#v70 (2016/05/20)
* Fix the May changelog dates
* No need to call build.Import, we already have the root of the dependency. Fixes an additional comment on #365
#v69 (2016/05/16)
* Make sure `devel-<short sha>` enabled `vendor/` unless there is a classic Godep _workspace already.
#v68 (2016/05/16)
* `devel-<short sha>` is always considered newer than any released go version
#v67 (2016/05/13)
* Attempt to handle missing deps a little better.
#v66 (2016/05/10)
* Use `git remote show origin` to find the default branch when restoring a git based package repository that is in detached head state
#v65 (2016/05/09)
* Rewrite update so that it considers new transitive dependencies, both in the same repo and outside of it.
#v64 (2016/05/09)
* godep update golang.org/x/tools/go/vcs
#v63 (2016/05/03)
* Support recording devel-<short sha> so development versions of Go can be matched
#v62 (2016/04/07)
* Note new go1.6+ behavior of not checking out master in README / restore help text.
#v61 (2016/04/06)
* Obey go version build tags based on recorded major go version. Fixes #448.
#v60 (2016/03/18)
* Make the $GOPATH check a warning.
#v59 (2016/03/18)
* Enforce requirement to be inside of a go src directory. A lot of time is usually spent
tracking down bug reports where people are doign stuff from outside of their $GOPATH. This
should help with that, at least until there it time to properly test godep use outside of a
$GOPATH and fix the issues.
#v58 (2016/03/15)
* Add GodepVersion to Godeps.json file so that as godep changes / adds features / fixes bugs we can know which version of godep most recently wrote out the file.
#v57 (2016/03/07)
* Don't use `git rev-parse --show-toplevel` to determine git repo roots as it resolves symlinks: https://github.com/tools/godep/pull/418
# v56 (2016/02/26)
* replace path comparisons with case insensitive pathEqual()
* add versionString() to debug output
* Send log output to Stderr
# v55 2016/02/22
* re-saved deps to clean out extra stuff (see v54; godep restore; godep save -r=false; rm -rf Godeps; godep save -r). We're still using a workspace with rewrites so users of older go version can still go get this tool.
* Replace simple == with strings.EqualFold in listFiles to avoid problems with case insensitive filesystems ("Code" != "code" when doing a byte by byte comparison)
# v54 2016/02/22
* Update some docs around vendor/
* More precise recording of dependencies. Removed recursive copying of sub directories of a package (precise vendoring). This should allow using `./...` with the go tool for compilation of project using `vendor/`. See https://github.com/tools/godep/pull/415
# v53 2016/02/11
* Disable VendorExperiment if a godep workspace already exists.
# v52 2016/01/27
* Trim 'rc' out of go version strings when determining major version.
# v51 2016/01/21
* Trim 'beta' out of go version strings when determining major version.
# v50 2016/01/19
* More verbose output on save -v.
# v49 2016/01/13
* Add UK spelling license/licence to the pile + fix up a bunch of typos
* Clarify tag handling in docs
# v48 2016/01/13
* Abort restore if there is no $GOPATH set.
# v47 2016/01/12
* Dev versions of go should honor the current meaning of GO15VENDOREXPERIMENT
# v46 2016/01/03
* Record "devel" when the release is a devel release of go (compiled from git).
# v45 2015/12/28
* Upcase windows drive letters before comparing. Fixes #383.
# v44 2015/12/23
* Clean package roots when attempting to find a vendor directory so we don't loop forever.
* Fixes 382
# v43 2015/12/22
* Better error messages when parsing Godeps.json: Fixes #372
# v42 2015/12/22
* Fix a bunch of GO15VENDOREXPERIMENT issues
* Find package directories better. Previously we used build.FindOnly which didn't work the way I expected it to (any dir would work w/o error).
* Set the VendorExperiment bool based on go version as 1.6 defaults to on.
* A bunch of extra debugging for use while sanity checking myself.
* vendor flag for test structs.
* Some tests for vendor/ stuff:
* Basic Test
* Transitive
* Transitive, across GOPATHs + collapse vendor/ directories.
* Should Fix #358
# v41 2015/12/17
* Don't rewrite packages outside of the project. This would happen if you specified
an external package for vendoring when you ran `goodep save -r ./... github.com/some/other/package`
# v40 2015/12/17
* When downloading a dependency, create the base directory if needed.
# v39 2015/12/16
* Record only the major go version (ex. go1.5) instead of the complete string.
# v38 2015/12/16
* Replace `go get`, further fix up restore error handling/reporting.
* Fixes #186
* Don't bother restoring/downloading if already done.
# v37 2015/12/15
* Change up how download/restore works a little
* Try to load the package after downloading/restoring. Previously
that was done too early in the process.
* make previous verbose output debug output
* report a typed error instead of a string from listPackage so it can
be asserted to provide a nicer error.
* Catch go get errors that say there are no go files found. See code
comment as to why.
* do *all* downloading during download phase.
# v36 2015/12/14
* Fixes #358: Using wrong variable. Will add test after release.
# v35 2015/12/11
* Fixes #356: Major performance regressions in v34
* Enable cpu profiling via flag on save.
* Cache packages by dir
* Don't do a full import pass on deps for packages in the GOROOT
* create a bit less garbage at times
* Generalize -v & -d flags
# v34 2015/12/08
* We now use build.Context to help locate packages only and do our own parsing (via go/ast).
* Fixes reported issues caused by v33 (Removal of `go list`):
* #345: Bug in godep restore
* #346: Fix loading a dot package
* #348: Godep save issue when importing lib/pq
* #350: undefined: build.MultiplePackageError
* #351: stow away helper files
* #353: cannot find package "appengine"
* Don't process imports of `.go` files tagged with the `appengine` build tag.
# v33 2015/12/07
* Replace the use of `go list`. This is a large change although all existing tests pass.
* Don't process the imports of `.go` files with the `ignore` build tag.
# v32 2015/12/02
* Eval Symlinks in Contains() check.
# v31 2015/12/02
* In restore, mention which package had the problem -- @shurcool
# v30 2015/11/25
* Add `-t` flag to the `godep get` command.
# v29 2015/11/17
* Temp work around to fix issue with LICENSE files.
# v28 2015/11/09
* Make `version` an actual command.
# v27 2015/11/06
* run command once during restore -v
# v26 2015/11/05
* Better fix for the issue fixed in v25: All update paths are now path.Clean()'d
# v25 2015/11/05
* `godep update package/` == `godep update package`. Fixes #313
# v24 2015/11/05
* Honor -t during update. Fixes #312
# v23 2015/11/05
* Do not use --debug to find full revision name for mercurial repositories
# v22 2015/11/14
* s/GOVENDOREXPERIMENT/GO15VENDOREXPERIMENT :-(
# v21 2015/11/13
* Fix #310: Case insensitive fs issue
# v20 2015/11/13
* Attempt to include license files when vendoring. (@client9)
# v19 2015/11/3
* Fix conflict error message. Revisions were swapped. Also better selection of package that needs update.
# v18 2015/10/16
* Improve error message when trying to save a conflicting revision.
# v17 2015/10/15
* Fix for v16 bug. All vcs list commands now produce paths relative to the root of the vcs.
# v16 2015/10/15
* Determine repo root using vcs commands and use that instead of dep.dir
# v15 2015/10/14
* Update .travis.yml file to do releases to github
# v14 2015/10/08
* Don't print out a workspace path when GO15VENDOREXPERIMENT is active. The vendor/ directory is not a valid workspace, so can't be added to your $GOPATH.
# v13 2015/10/07
* Do restores in 2 separate steps, first download all deps and then check out the recorded revisions.
* Update Changelog date format
# v12 2015/09/22
* Extract errors into separate file.
# v11 2015/08/22
* Amend code to pass golint.
# v10 2015/09/21
* Analyse vendored package test dependencies.
* Update documentation.
# v9 2015/09/17
* Don't save test dependencies by default.
# v8 2015/09/17
* Reorganize code.
# v7 2015/09/09
* Add verbose flag.
* Skip untracked files.
* Add VCS list command.
# v6 2015/09/04
* Revert ignoring testdata directories and instead ignore it while
processing Go files and copy the whole directory unmodified.
# v5 2015/09/04
* Fix vcs selection in restore command to work as go get does
# v4 2015/09/03
* Remove the deprecated copy option.
# v3 2015/08/26
* Ignore testdata directories
# v2 2015/08/11
* Include command line packages in the set to copy
This is a simplification to how we define the behavior
of the save command. Now it has two distinct package
parameters, the "root set" and the "destination", and
they have clearer roles. The packages listed on the
command line form the root set; they and all their
dependencies will be copied into the Godeps directory.
Additionally, the destination (always ".") will form the
initial list of "seen" import paths to exclude from
copying.
In the common case, the root set is equal to the
destination, so the effective behavior doesn't change.
This is primarily just a simpler definition. However, if
the user specifies a package on the command line that
lives outside of . then that package will be copied.
As a side effect, there's a simplification to the way we
add packages to the initial "seen" set. Formerly, to
avoid copying dependencies unnecessarily, we would try
to find the root of the VCS repo for each package in the
root set, and mark the import path of the entire repo as
seen. This meant for a repo at path C, if destination
C/S imports C/T, we would not copy C/T into C/S/Godeps.
Now we don't treat the repo root specially, and as
mentioned above, the destination alone is considered
seen.
This also means we don't require listed packages to be
in VCS unless they're outside of the destination.
# v1 2015/07/20
* godep version command
Output the version as well as some godep runtime information that is
useful for debugging user's issues.
The version const would be bumped each time a PR is merged into master
to ensure that we'll be able to tell which version someone got when they
did a `go get github.com/tools/godep`.
# Older changes
Many and more, see `git log -p`

22
vendor/github.com/tools/godep/FAQ.md generated vendored Normal file
View File

@ -0,0 +1,22 @@
## Why do I need to check in `vendor/`?
godep's primary concern is to allow you to repeatably build your project. Your
dependencies are part of that project. Without them it won't build. Not
committing `vendor/` adds additional external dependencies that are outside of
your control. In Go, fetching packages is tied to multiple external systems
(DNS, web servers, etc). Over time other developers or code hosting sites may
discontinue service, delete code, force push, or take any number of other
actions that may make a package unreachable. Therefore it's the opinion of the
godep authors that `vendor/` should always be checked in.
## Should I use `godep restore`?
Probably not, unless you **need** to. Situations where you would **need** to are:
1. Using older Godep Workspaces (`Godeps/_workspace`) and not using `godep go
<cmd>`.
1. Resetting the state of $GOPATH to what is in your `Godeps.json` file in order
to cleanly re-vendor everything w/o upgrading/changing any deps. This is
useful when [migrating](https://github.com/tools/godep#migrating-to-vendor)
from workspaces to `vendor` or when a bug is fixed in `godep` that cleans up
a previous vendoring error.

28
vendor/github.com/tools/godep/License generated vendored Normal file
View File

@ -0,0 +1,28 @@
Copyright © 2013 Keith Rarick.
Portions Copyright (c) 2012 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.

199
vendor/github.com/tools/godep/Readme.md generated vendored Normal file
View File

@ -0,0 +1,199 @@
## Godep
[![Build Status](https://travis-ci.org/tools/godep.svg)](https://travis-ci.org/tools/godep)
[![GoDoc](https://godoc.org/github.com/tools/godep?status.svg)](https://godoc.org/github.com/tools/godep)
godep helps build packages reproducibly by fixing their dependencies.
This tool assumes you are working in a standard Go workspace, as described in
http://golang.org/doc/code.html. We expect godep to build on Go 1.4* or newer,
but you can use it on any project that works with Go 1 or newer.
Please check the [FAQ](FAQ.md) if you have a question.
## Install
```console
$ go get github.com/tools/godep
```
## How to use godep with a new project
Assuming you've got everything working already, so you can build your project
with `go install` and test it with `go test`, it's one command to start using:
```console
$ godep save
```
This will save a list of dependencies to the file `Godeps/Godeps.json` and copy
their source code into `vendor/` (or `Godeps/_workspace/` when using older
versions of Go). Godep does **not copy**:
- files from source repositories that are not tracked in version control.
- `*_test.go` files.
- `testdata` directories.
- files outside of the go packages.
Godep does not process the imports of `.go` files with either the `ignore`
or `appengine` build tags.
Test files and testdata directories can be saved by adding `-t`.
Read over the contents of `vendor/` and make sure it looks reasonable. Then
commit the `Godeps/` and `vendor/` directories to version control.
## The deprecated `-r` flag
For older versions of Go, the `-r` flag tells save to automatically rewrite
package import paths. This allows your code to refer directly to the copied
dependencies in `Godeps/_workspace`. So, a package C that depends on package
D will actually import `C/Godeps/_workspace/src/D`. This makes C's repo
self-contained and causes `go get` to build C with the right version of all
dependencies.
If you don't use `-r`, when using older version of Go, then in order to use the
fixed dependencies and get reproducible builds, you must make sure that **every
time** you run a Go-related command, you wrap it in one of these two ways:
- If the command you are running is just `go`, run it as `godep go ...`, e.g.
`godep go install -v ./...`
- When using a different command, set your `$GOPATH` using `godep path` as
described below.
`-r` isn't necessary with go1.6+ and isn't allowed.
## Additional Operations
### Restore
The `godep restore` installs the
package versions specified in `Godeps/Godeps.json` to your `$GOPATH`. This
modifies the state of packages in your `$GOPATH`. NOTE: `godep restore` leaves
git repositories in a detached state. `go1.6`+ no longer checks out the master
branch when doing a `go get`, see [here](https://github.com/golang/go/commit/42206598671a44111c8f726ad33dc7b265bdf669).
Please see the [FAQ](https://github.com/tools/godep/blob/master/FAQ.md#should-i-use-godep-restore) section about restore.
### Edit-test Cycle
1. Edit code
1. Run `godep go test`
1. (repeat)
### Add a Dependency
To add a new package foo/bar, do this:
1. Run `go get foo/bar`
1. Edit your code to import foo/bar.
1. Run `godep save` (or `godep save ./...`).
### Update a Dependency
To update a package from your `$GOPATH`, do this:
1. Run `go get -u foo/bar`
1. Run `godep update foo/bar`. (You can use the `...` wildcard, for example
`godep update foo/...`).
Before comitting the change, you'll probably want to inspect the changes to
Godeps, for example with `git diff`, and make sure it looks reasonable.
## Multiple Packages
If your repository has more than one package, you're probably accustomed to
running commands like `go test ./...`, `go install ./...`, and `go fmt ./...`.
Similarly, you should run `godep save ./...` to capture the dependencies of all
packages in your application.
## File Format
Godeps is a json file with the following structure:
```go
type Godeps struct {
ImportPath string
GoVersion string // Abridged output of 'go version'.
GodepVersion string // Abridged output of 'godep version'
Packages []string // Arguments to godep save, if any.
Deps []struct {
ImportPath string
Comment string // Description of commit, if present.
Rev string // VCS-specific commit ID.
}
}
```
Example Godeps:
```json
{
"ImportPath": "github.com/kr/hk",
"GoVersion": "go1.6",
"Deps": [
{
"ImportPath": "code.google.com/p/go-netrc/netrc",
"Rev": "28676070ab99"
},
{
"ImportPath": "github.com/kr/binarydist",
"Rev": "3380ade90f8b0dfa3e363fd7d7e941fa857d0d13"
}
]
}
```
## Migrating to vendor/
Godep supports the Go 1.5+ vendor/
[experiment](https://github.com/golang/go/commit/183cc0cd41f06f83cb7a2490a499e3f9101befff)
utilizing the same environment variable that the go tooling itself supports
(`GO15VENDOREXPERIMENT`).
godep mostly works the same way as the `go` command line tool. If you have go
1.5.X and set `GO15VENDOREXPERIMENT=1` or have go1.6.X (or devel) `vendor/`
is enabled. **Unless** you already have a `Godeps/_workspace`. This is a safety
feature and godep warns you about this.
When `vendor/` is enabled godep will write the vendored code into the top level
`./vendor/` directory. A `./Godeps/Godeps.json` file is created to track
the dependencies and revisions. `vendor/` is not compatible with rewrites.
There is currently no automated migration between the old Godeps workspace and
the vendor directory, but the following steps should work:
```term
# just to be safe
$ unset GO15VENDOREXPERIMENT
# restore currently vendored deps to the $GOPATH
$ godep restore
# The next line is only needed to automatically undo rewritten imports that were
# created with godep save -r.
$ godep save -r=false <pkg spec>
# Remove the old Godeps folder
$ rm -rf Godeps
# If on go1.5.X to enable `vendor/`
$ export GO15VENDOREXPERIMENT=1
# re-analyze deps and save to `vendor/`.
$ godep save <pkg spec>
# Add the changes to your VCS
$ git add -A . ; git commit -am "Godep workspace -> vendor/"
# You should see your Godeps/_workspace/src files "moved" to vendor/.
```
## Releasing
1. Increment the version in `version.go`.
1. Tag the commit with the same version number.
1. Update `Changelog.md`.

128
vendor/github.com/tools/godep/dep.go generated vendored Normal file
View File

@ -0,0 +1,128 @@
package main
import (
"fmt"
"os"
"os/exec"
"sort"
"strings"
)
// A Dependency is a specific revision of a package.
type Dependency struct {
ImportPath string
Comment string `json:",omitempty"` // Description of commit, if present.
Rev string // VCS-specific commit ID.
// used by command save & update
ws string // workspace
root string // import path to repo root
dir string // full path to package
// used by command update
matched bool // selected for update by command line
pkg *Package
missing bool // packages is missing
// used by command go
vcs *VCS
}
func eqDeps(a, b []Dependency) bool {
ok := true
for _, da := range a {
for _, db := range b {
if da.ImportPath == db.ImportPath && da.Rev != db.Rev {
ok = false
}
}
}
return ok
}
// containsPathPrefix returns whether any string in a
// is s or a directory containing s.
// For example, pattern ["a"] matches "a" and "a/b"
// (but not "ab").
func containsPathPrefix(pats []string, s string) bool {
for _, pat := range pats {
if pat == s || strings.HasPrefix(s, pat+"/") {
return true
}
}
return false
}
func uniq(a []string) []string {
var s string
var i int
if !sort.StringsAreSorted(a) {
sort.Strings(a)
}
for _, t := range a {
if t != s {
a[i] = t
i++
s = t
}
}
return a[:i]
}
// trimGoVersion and return the major version
func trimGoVersion(version string) (string, error) {
if version == "devel" {
return "devel", nil
}
if strings.HasPrefix(version, "devel+") || strings.HasPrefix(version, "devel-") {
return strings.Replace(version, "devel+", "devel-", 1), nil
}
p := strings.Split(version, ".")
if len(p) < 2 {
return "", fmt.Errorf("Error determining major go version from: %q", version)
}
var split string
switch {
case strings.Contains(p[1], "beta"):
split = "beta"
case strings.Contains(p[1], "rc"):
split = "rc"
}
if split != "" {
p[1] = strings.Split(p[1], split)[0]
}
return p[0] + "." + p[1], nil
}
var goVersionTestOutput = ""
func getGoVersion() (string, error) {
// For testing purposes only
if goVersionTestOutput != "" {
return goVersionTestOutput, nil
}
// Godep might have been compiled with a different
// version, so we can't just use runtime.Version here.
cmd := exec.Command("go", "version")
cmd.Stderr = os.Stderr
out, err := cmd.Output()
return string(out), err
}
// goVersion returns the major version string of the Go compiler
// currently installed, e.g. "go1.5".
func goVersion() (string, error) {
out, err := getGoVersion()
if err != nil {
return "", err
}
gv := strings.Split(out, " ")
if len(gv) < 4 {
return "", fmt.Errorf("Error splitting output of `go version`: Expected 4 or more elements, but there are < 4: %q", out)
}
if gv[2] == "devel" {
return trimGoVersion(gv[2] + gv[3])
}
return trimGoVersion(gv[2])
}

74
vendor/github.com/tools/godep/diff.go generated vendored Normal file
View File

@ -0,0 +1,74 @@
package main
import (
"bytes"
"fmt"
"log"
"github.com/pmezard/go-difflib/difflib"
)
var cmdDiff = &Command{
Name: "diff",
Short: "shows the diff between current and previously saved set of dependencies",
Long: `
Shows the difference, in a unified diff format, between the
current set of dependencies and those generated on a
previous 'go save' execution.
`,
Run: runDiff,
OnlyInGOPATH: true,
}
func runDiff(cmd *Command, args []string) {
gold, err := loadDefaultGodepsFile()
if err != nil {
log.Fatalln(err)
}
pkgs := []string{"."}
dot, err := LoadPackages(pkgs...)
if err != nil {
log.Fatalln(err)
}
gnew := &Godeps{
ImportPath: dot[0].ImportPath,
GoVersion: gold.GoVersion,
}
err = gnew.fill(dot, dot[0].ImportPath)
if err != nil {
log.Fatalln(err)
}
diff, err := diffStr(&gold, gnew)
if err != nil {
log.Fatalln(err)
}
fmt.Println(diff)
}
// diffStr returns a unified diff string of two Godeps.
func diffStr(a, b *Godeps) (string, error) {
var ab, bb bytes.Buffer
_, err := a.writeTo(&ab)
if err != nil {
log.Fatalln(err)
}
_, err = b.writeTo(&bb)
if err != nil {
log.Fatalln(err)
}
diff := difflib.UnifiedDiff{
A: difflib.SplitLines(ab.String()),
B: difflib.SplitLines(bb.String()),
FromFile: b.file(),
ToFile: "$GOPATH",
Context: 10,
}
return difflib.GetUnifiedDiffString(diff)
}

22
vendor/github.com/tools/godep/doc.go generated vendored Normal file
View File

@ -0,0 +1,22 @@
/*
Command godep helps build packages reproducibly by fixing
their dependencies.
Example Usage
Save currently-used dependencies to file Godeps:
$ godep save
Build project using saved dependencies:
$ godep go install
or
$ GOPATH=`godep path`:$GOPATH
$ go install
*/
package main

18
vendor/github.com/tools/godep/errors.go generated vendored Normal file
View File

@ -0,0 +1,18 @@
package main
import "errors"
var (
errorLoadingDeps = errors.New("error loading dependencies")
errorLoadingPackages = errors.New("error loading packages")
errorCopyingSourceCode = errors.New("error copying source code")
errorNoPackagesUpdatable = errors.New("no packages can be updated")
)
type errPackageNotFound struct {
path string
}
func (e errPackageNotFound) Error() string {
return "Package (" + e.path + ") not found"
}

96
vendor/github.com/tools/godep/get.go generated vendored Normal file
View File

@ -0,0 +1,96 @@
package main
import (
"log"
"os"
"os/exec"
)
var cmdGet = &Command{
Name: "get",
Args: "[-t] [packages]",
Short: "download and install packages with specified dependencies",
Long: `
Get downloads to GOPATH the packages named by the import paths, and installs
them with the dependencies specified in their Godeps files.
If any of the packages do not have Godeps files, those are installed
as if by go get.
If -t is given, dependencies of test files are also downloaded and installed.
For more about specifying packages, see 'go help packages'.
`,
Run: runGet,
OnlyInGOPATH: true,
}
var getT bool
func init() {
cmdGet.Flag.BoolVar(&getT, "t", false, "get test dependencies")
}
func runGet(cmd *Command, args []string) {
if len(args) == 0 {
args = []string{"."}
}
cmdArgs := []interface{}{"get", "-d"}
if verbose {
cmdArgs = append(cmdArgs, "-v")
}
if getT {
cmdArgs = append(cmdArgs, "-t")
}
err := command("go", append(cmdArgs, args)...).Run()
if err != nil {
log.Fatalln(err)
}
// group import paths by Godeps location
groups := make(map[string][]string)
ps, err := LoadPackages(args...)
if err != nil {
log.Fatalln(err)
}
for _, pkg := range ps {
if pkg.Error.Err != "" {
log.Fatalln(pkg.Error.Err)
}
dir, _ := findInParents(pkg.Dir, "Godeps")
groups[dir] = append(groups[dir], pkg.ImportPath)
}
for dir, packages := range groups {
var c *exec.Cmd
if dir == "" {
c = command("go", "install", packages)
} else {
c = command("godep", "go", "install", packages)
c.Dir = dir
}
if err := c.Run(); err != nil {
log.Fatalln(err)
}
}
}
// command is like exec.Command, but the returned
// Cmd inherits stderr from the current process, and
// elements of args may be either string or []string.
func command(name string, args ...interface{}) *exec.Cmd {
var a []string
for _, arg := range args {
switch v := arg.(type) {
case string:
a = append(a, v)
case []string:
a = append(a, v...)
}
}
c := exec.Command(name, a...)
c.Stderr = os.Stderr
return c
}

129
vendor/github.com/tools/godep/go.go generated vendored Normal file
View File

@ -0,0 +1,129 @@
package main
import (
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
)
var cmdGo = &Command{
Name: "go",
Args: "command [arguments]",
Short: "run the go tool with saved dependencies",
Long: `
Go runs the go tool with a modified GOPATH giving access to
dependencies saved in Godeps.
Any go tool command can run this way, but "godep go get"
is unnecessary and has been disabled. Instead, use
"godep go install".
`,
Run: runGo,
OnlyInGOPATH: true,
}
// Find the godep GOPATH for this file tree and run the go tool.
func runGo(cmd *Command, args []string) {
gopath := prepareGopath()
if s := os.Getenv("GOPATH"); s != "" {
gopath += string(os.PathListSeparator) + os.Getenv("GOPATH")
}
if len(args) > 0 && args[0] == "get" {
log.Printf("invalid subcommand: %q", "go get")
fmt.Fprintln(os.Stderr, "Use 'godep go install' instead.")
fmt.Fprintln(os.Stderr, "Run 'godep help go' for usage.")
os.Exit(2)
}
c := exec.Command("go", args...)
c.Env = append(envNoGopath(), "GOPATH="+gopath)
c.Stdin = os.Stdin
c.Stdout = os.Stdout
c.Stderr = os.Stderr
err := c.Run()
if err != nil {
log.Fatalln("go", err)
}
}
// prepareGopath reads dependency information from the filesystem
// entry name, fetches any necessary code, and returns a gopath
// causing the specified dependencies to be used.
func prepareGopath() (gopath string) {
dir, isDir := findGodeps()
if dir == "" {
log.Fatalln("No Godeps found (or in any parent directory)")
}
if !isDir {
log.Fatalln(strings.TrimSpace(needSource))
}
return filepath.Join(dir, "Godeps", "_workspace")
}
// findGodeps looks for a directory entry "Godeps" in the
// current directory or any parent, and returns the containing
// directory and whether the entry itself is a directory.
// If Godeps can't be found, findGodeps returns "".
// For any other error, it exits the program.
func findGodeps() (dir string, isDir bool) {
wd, err := os.Getwd()
if err != nil {
log.Fatalln(err)
}
return findInParents(wd, "Godeps")
}
// isRoot returns true iff a path is a root.
// On Unix: "/".
// On Windows: "C:\", "D:\", ...
func isRoot(p string) bool {
p = filepath.Clean(p)
volume := filepath.VolumeName(p)
p = strings.TrimPrefix(p, volume)
p = filepath.ToSlash(p)
return p == "/"
}
// findInParents returns the path to the directory containing name
// in dir or any ancestor, and whether name itself is a directory.
// If name cannot be found, findInParents returns the empty string.
func findInParents(dir, name string) (container string, isDir bool) {
for {
fi, err := os.Stat(filepath.Join(dir, name))
if os.IsNotExist(err) && isRoot(dir) {
return "", false
}
if os.IsNotExist(err) {
dir = filepath.Dir(dir)
continue
}
if err != nil {
log.Fatalln(err)
}
return dir, fi.IsDir()
}
}
func envNoGopath() (a []string) {
for _, s := range os.Environ() {
if !strings.HasPrefix(s, "GOPATH=") {
a = append(a, s)
}
}
return a
}
const needSource = `
outdated Godeps missing source code
This dependency list was created with an old version of godep.
To work around this, you have two options:
1. Run 'godep restore', and try again.
2. Ask the maintainer to switch to a newer version of godep,
then try again with the updated package.
`

224
vendor/github.com/tools/godep/godepfile.go generated vendored Normal file
View File

@ -0,0 +1,224 @@
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"os"
"path/filepath"
)
var (
godepsFile = filepath.Join("Godeps", "Godeps.json")
oldGodepsFile = filepath.Join("Godeps")
)
// Godeps describes what a package needs to be rebuilt reproducibly.
// It's the same information stored in file Godeps.
type Godeps struct {
ImportPath string
GoVersion string
GodepVersion string
Packages []string `json:",omitempty"` // Arguments to save, if any.
Deps []Dependency
isOldFile bool
}
func createGodepsFile() (*os.File, error) {
return os.Create(godepsFile)
}
func loadGodepsFile(path string) (Godeps, error) {
var g Godeps
f, err := os.Open(path)
if err != nil {
return g, err
}
defer f.Close()
err = json.NewDecoder(f).Decode(&g)
if err != nil {
err = fmt.Errorf("Unable to parse %s: %s", path, err.Error())
}
return g, err
}
func loadDefaultGodepsFile() (Godeps, error) {
var g Godeps
var err error
g, err = loadGodepsFile(godepsFile)
if err != nil {
if os.IsNotExist(err) {
var err1 error
g, err1 = loadGodepsFile(oldGodepsFile)
if err1 != nil {
if os.IsNotExist(err1) {
return g, err
}
return g, err1
}
g.isOldFile = true
return g, nil
}
}
return g, err
}
// pkgs is the list of packages to read dependencies for
func (g *Godeps) fill(pkgs []*Package, destImportPath string) error {
debugln("fill", destImportPath)
ppln(pkgs)
var err1 error
var path, testImports []string
dipp := []string{destImportPath}
for _, p := range pkgs {
if p.Standard {
log.Println("ignoring stdlib package:", p.ImportPath)
continue
}
if p.Error.Err != "" {
log.Println(p.Error.Err)
err1 = errorLoadingPackages
continue
}
path = append(path, p.ImportPath)
path = append(path, p.Deps...)
testImports = append(testImports, p.TestImports...)
testImports = append(testImports, p.XTestImports...)
}
ps, err := LoadPackages(testImports...)
if err != nil {
return err
}
for _, p := range ps {
if p.Standard {
continue
}
if p.Error.Err != "" {
log.Println(p.Error.Err)
err1 = errorLoadingPackages
continue
}
path = append(path, p.ImportPath)
path = append(path, p.Deps...)
}
debugln("path", path)
for i, p := range path {
path[i] = unqualify(p)
}
path = uniq(path)
debugln("uniq, unqualify'd path", path)
ps, err = LoadPackages(path...)
if err != nil {
return err
}
for _, pkg := range ps {
if pkg.Error.Err != "" {
log.Println(pkg.Error.Err)
err1 = errorLoadingDeps
continue
}
if pkg.Standard || containsPathPrefix(dipp, pkg.ImportPath) {
debugln("standard or dest skipping", pkg.ImportPath)
continue
}
vcs, reporoot, err := VCSFromDir(pkg.Dir, filepath.Join(pkg.Root, "src"))
if err != nil {
log.Println(err)
err1 = errorLoadingDeps
continue
}
id, err := vcs.identify(pkg.Dir)
if err != nil {
log.Println(err)
err1 = errorLoadingDeps
continue
}
if vcs.isDirty(pkg.Dir, id) {
log.Println("dirty working tree (please commit changes):", pkg.Dir)
err1 = errorLoadingDeps
continue
}
comment := vcs.describe(pkg.Dir, id)
g.Deps = append(g.Deps, Dependency{
ImportPath: pkg.ImportPath,
Rev: id,
Comment: comment,
dir: pkg.Dir,
ws: pkg.Root,
root: filepath.ToSlash(reporoot),
vcs: vcs,
})
}
return err1
}
func (g *Godeps) copy() *Godeps {
h := *g
h.Deps = make([]Dependency, len(g.Deps))
copy(h.Deps, g.Deps)
return &h
}
func (g *Godeps) file() string {
if g.isOldFile {
return oldGodepsFile
}
return godepsFile
}
func (g *Godeps) save() (int64, error) {
f, err := os.Create(g.file())
if err != nil {
return 0, err
}
defer f.Close()
return g.writeTo(f)
}
func (g *Godeps) writeTo(w io.Writer) (int64, error) {
g.GodepVersion = fmt.Sprintf("v%d", version) // godep always writes its current version.
b, err := json.MarshalIndent(g, "", "\t")
if err != nil {
return 0, err
}
n, err := w.Write(append(b, '\n'))
return int64(n), err
}
func (g *Godeps) addOrUpdateDeps(deps []Dependency) {
var missing []Dependency
for _, d := range deps {
var found bool
for i := range g.Deps {
if g.Deps[i].ImportPath == d.ImportPath {
g.Deps[i] = d
found = true
break
}
}
if !found {
missing = append(missing, d)
}
}
for _, d := range missing {
g.Deps = append(g.Deps, d)
}
}
func (g *Godeps) removeDeps(deps []Dependency) {
var f []Dependency
for i := range g.Deps {
var found bool
for _, d := range deps {
if g.Deps[i].ImportPath == d.ImportPath {
found = true
break
}
}
if !found {
f = append(f, g.Deps[i])
}
}
g.Deps = f
}

59
vendor/github.com/tools/godep/license.go generated vendored Normal file
View File

@ -0,0 +1,59 @@
package main
import (
"strings"
)
// LicenseFilePrefix is a list of filename prefixes that indicate it
// might contain a software license
var LicenseFilePrefix = []string{
"licence", // UK spelling
"license", // US spelling
"copying",
"unlicense",
"copyright",
"copyleft",
"authors",
"contributors",
}
// LegalFileSubstring are substrings that indicate the file is likely
// to contain some type of legal declaration. "legal" is often used
// that it might moved to LicenseFilePrefix
var LegalFileSubstring = []string{
"legal",
"notice",
"disclaimer",
"patent",
"third-party",
"thirdparty",
}
// IsLicenseFile returns true if the filename might be contain a
// software license
func IsLicenseFile(filename string) bool {
lowerfile := strings.ToLower(filename)
for _, prefix := range LicenseFilePrefix {
if strings.HasPrefix(lowerfile, prefix) {
return true
}
}
return false
}
// IsLegalFile returns true if the file is likely to contain some type
// of of legal declaration or licensing information
func IsLegalFile(filename string) bool {
lowerfile := strings.ToLower(filename)
for _, prefix := range LicenseFilePrefix {
if strings.HasPrefix(lowerfile, prefix) {
return true
}
}
for _, substring := range LegalFileSubstring {
if strings.Index(lowerfile, substring) != -1 {
return true
}
}
return false
}

604
vendor/github.com/tools/godep/list.go generated vendored Normal file
View File

@ -0,0 +1,604 @@
package main
import (
"errors"
"fmt"
"go/build"
"go/parser"
"go/token"
"log"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"unicode"
pathpkg "path"
)
var (
gorootSrc = filepath.Join(build.Default.GOROOT, "src")
ignoreTags = []string{"appengine", "ignore"} //TODO: appengine is a special case for now: https://github.com/tools/godep/issues/353
versionMatch = regexp.MustCompile(`\Ago\d+\.\d+\z`)
versionNegativeMatch = regexp.MustCompile(`\A\!go\d+\.\d+\z`)
)
type errorMissingDep struct {
i, dir string // import, dir
}
func (e errorMissingDep) Error() string {
return "Unable to find dependent package " + e.i + " in context of " + e.dir
}
// packageContext is used to track an import and which package imported it.
type packageContext struct {
pkg *build.Package // package that imports the import
imp string // import
}
// depScanner tracks the processed and to be processed packageContexts
type depScanner struct {
processed []packageContext
todo []packageContext
}
// Next package and import to process
func (ds *depScanner) Next() (*build.Package, string) {
c := ds.todo[0]
ds.processed = append(ds.processed, c)
ds.todo = ds.todo[1:]
return c.pkg, c.imp
}
// Continue looping?
func (ds *depScanner) Continue() bool {
if len(ds.todo) > 0 {
return true
}
return false
}
// Add a package and imports to the depScanner. Skips already processed/pending package/import combos
func (ds *depScanner) Add(pkg *build.Package, imports ...string) {
NextImport:
for _, i := range imports {
if i == "C" {
i = "runtime/cgo"
}
for _, epc := range ds.processed {
if pkg.Dir == epc.pkg.Dir && i == epc.imp {
debugln("ctxts epc.pkg.Dir == pkg.Dir && i == epc.imp, skipping", epc.pkg.Dir, i)
continue NextImport
}
}
for _, epc := range ds.todo {
if pkg.Dir == epc.pkg.Dir && i == epc.imp {
debugln("ctxts epc.pkg.Dir == pkg.Dir && i == epc.imp, skipping", epc.pkg.Dir, i)
continue NextImport
}
}
pc := packageContext{pkg, i}
debugln("Adding pc:", pc.pkg.Dir, pc.imp)
ds.todo = append(ds.todo, pc)
}
}
var (
pkgCache = make(map[string]*build.Package) // dir => *build.Package
)
// returns the package in dir either from a cache or by importing it and then caching it
func fullPackageInDir(dir string) (*build.Package, error) {
var err error
pkg, ok := pkgCache[dir]
if !ok {
pkg, err = build.ImportDir(dir, build.FindOnly)
if pkg.Goroot {
pkg, err = build.ImportDir(pkg.Dir, 0)
} else {
err = fillPackage(pkg)
}
if err == nil {
pkgCache[dir] = pkg
}
}
return pkg, err
}
// listPackage specified by path
func listPackage(path string) (*Package, error) {
debugln("listPackage", path)
var lp *build.Package
dir, err := findDirForPath(path, nil)
if err != nil {
return nil, err
}
lp, err = fullPackageInDir(dir)
p := &Package{
Dir: lp.Dir,
Root: lp.Root,
ImportPath: lp.ImportPath,
XTestImports: lp.XTestImports,
TestImports: lp.TestImports,
GoFiles: lp.GoFiles,
CgoFiles: lp.CgoFiles,
TestGoFiles: lp.TestGoFiles,
XTestGoFiles: lp.XTestGoFiles,
IgnoredGoFiles: lp.IgnoredGoFiles,
}
p.Standard = lp.Goroot && lp.ImportPath != "" && !strings.Contains(lp.ImportPath, ".")
if err != nil || p.Standard {
return p, err
}
debugln("Looking For Package:", path, "in", dir)
ppln(lp)
ds := depScanner{}
ds.Add(lp, lp.Imports...)
for ds.Continue() {
ip, i := ds.Next()
debugf("Processing import %s for %s\n", i, ip.Dir)
pdir, err := findDirForPath(i, ip)
if err != nil {
return nil, err
}
dp, err := fullPackageInDir(pdir)
if err != nil { // This really should happen in this context though
ppln(err)
return nil, errorMissingDep{i: i, dir: ip.Dir}
}
ppln(dp)
if !dp.Goroot {
// Don't bother adding packages in GOROOT to the dependency scanner, they don't import things from outside of it.
ds.Add(dp, dp.Imports...)
}
debugln("lp:")
ppln(lp)
debugln("ip:")
ppln(ip)
if lp == ip {
debugln("lp == ip")
p.Imports = append(p.Imports, dp.ImportPath)
}
p.Deps = append(p.Deps, dp.ImportPath)
p.Dependencies = addDependency(p.Dependencies, dp)
}
p.Imports = uniq(p.Imports)
p.Deps = uniq(p.Deps)
debugln("Done Looking For Package:", path, "in", dir)
ppln(p)
return p, nil
}
func addDependency(deps []build.Package, d *build.Package) []build.Package {
for i := range deps {
if deps[i].Dir == d.Dir {
return deps
}
}
return append(deps, *d)
}
// finds the directory for the given import path in the context of the provided build.Package (if provided)
func findDirForPath(path string, ip *build.Package) (string, error) {
debugln("findDirForPath", path, ip)
var search []string
if build.IsLocalImport(path) {
dir := path
if !filepath.IsAbs(dir) {
if abs, err := filepath.Abs(dir); err == nil {
// interpret relative to current directory
dir = abs
}
}
return dir, nil
}
// We need to check to see if the import exists in vendor/ folders up the hierarchy of the importing package
if VendorExperiment && ip != nil {
debugln("resolving vendor posibilities:", ip.Dir, ip.Root)
cr := cleanPath(ip.Root)
for base := cleanPath(ip.Dir); !pathEqual(base, cr); base = cleanPath(filepath.Dir(base)) {
s := filepath.Join(base, "vendor", path)
debugln("Adding search dir:", s)
search = append(search, s)
}
}
for _, base := range build.Default.SrcDirs() {
search = append(search, filepath.Join(base, path))
}
for _, dir := range search {
debugln("searching", dir)
fi, err := stat(dir)
if err == nil && fi.IsDir() {
return dir, nil
}
}
return "", errPackageNotFound{path}
}
type statEntry struct {
fi os.FileInfo
err error
}
var (
statCache = make(map[string]statEntry)
)
func clearStatCache() {
statCache = make(map[string]statEntry)
}
func stat(p string) (os.FileInfo, error) {
if e, ok := statCache[p]; ok {
return e.fi, e.err
}
fi, err := os.Stat(p)
statCache[p] = statEntry{fi, err}
return fi, err
}
// fillPackage full of info. Assumes p.Dir is set at a minimum
func fillPackage(p *build.Package) error {
if p.Goroot {
return nil
}
if p.SrcRoot == "" {
for _, base := range build.Default.SrcDirs() {
if strings.HasPrefix(p.Dir, base) {
p.SrcRoot = base
}
}
}
if p.SrcRoot == "" {
return errors.New("Unable to find SrcRoot for package " + p.ImportPath)
}
if p.Root == "" {
p.Root = filepath.Dir(p.SrcRoot)
}
var buildMatch = "+build "
var buildFieldSplit = func(r rune) bool {
return unicode.IsSpace(r) || r == ','
}
debugln("Filling package:", p.ImportPath, "from", p.Dir)
gofiles, err := filepath.Glob(filepath.Join(p.Dir, "*.go"))
if err != nil {
debugln("Error globbing", err)
return err
}
if len(gofiles) == 0 {
return &build.NoGoError{Dir: p.Dir}
}
var testImports []string
var imports []string
NextFile:
for _, file := range gofiles {
debugln(file)
pf, err := parser.ParseFile(token.NewFileSet(), file, nil, parser.ImportsOnly|parser.ParseComments)
if err != nil {
return err
}
testFile := strings.HasSuffix(file, "_test.go")
fname := filepath.Base(file)
for _, c := range pf.Comments {
ct := c.Text()
if i := strings.Index(ct, buildMatch); i != -1 {
for _, t := range strings.FieldsFunc(ct[i+len(buildMatch):], buildFieldSplit) {
for _, tag := range ignoreTags {
if t == tag {
p.IgnoredGoFiles = append(p.IgnoredGoFiles, fname)
continue NextFile
}
}
if versionMatch.MatchString(t) && !isSameOrNewer(t, majorGoVersion) {
debugln("Adding", fname, "to ignored list because of version tag", t)
p.IgnoredGoFiles = append(p.IgnoredGoFiles, fname)
continue NextFile
}
if versionNegativeMatch.MatchString(t) && isSameOrNewer(t[1:], majorGoVersion) {
debugln("Adding", fname, "to ignored list because of version tag", t)
p.IgnoredGoFiles = append(p.IgnoredGoFiles, fname)
continue NextFile
}
}
}
}
if testFile {
p.TestGoFiles = append(p.TestGoFiles, fname)
} else {
p.GoFiles = append(p.GoFiles, fname)
}
for _, is := range pf.Imports {
name, err := strconv.Unquote(is.Path.Value)
if err != nil {
return err // can't happen?
}
if testFile {
testImports = append(testImports, name)
} else {
imports = append(imports, name)
}
}
}
imports = uniq(imports)
testImports = uniq(testImports)
p.Imports = imports
p.TestImports = testImports
return nil
}
// All of the following functions were vendored from go proper. Locations are noted in comments, but may change in future Go versions.
// importPaths returns the import paths to use for the given command line.
// $GOROOT/src/cmd/main.go:366
func importPaths(args []string) []string {
debugf("importPathsNoDotExpansion(%q) == ", args)
args = importPathsNoDotExpansion(args)
debugf("%q\n", args)
var out []string
for _, a := range args {
if strings.Contains(a, "...") {
if build.IsLocalImport(a) {
debugf("build.IsLocalImport(%q) == true\n", a)
pkgs := allPackagesInFS(a)
debugf("allPackagesInFS(%q) == %q\n", a, pkgs)
out = append(out, pkgs...)
} else {
debugf("build.IsLocalImport(%q) == false\n", a)
pkgs := allPackages(a)
debugf("allPackages(%q) == %q\n", a, pkgs)
out = append(out, allPackages(a)...)
}
continue
}
out = append(out, a)
}
return out
}
// importPathsNoDotExpansion returns the import paths to use for the given
// command line, but it does no ... expansion.
// $GOROOT/src/cmd/main.go:332
func 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 = "./" + pathpkg.Clean(a)
if a == "./." {
a = "."
}
} else {
a = pathpkg.Clean(a)
}
if a == "all" || a == "std" || a == "cmd" {
out = append(out, allPackages(a)...)
continue
}
out = append(out, a)
}
return out
}
// 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.
// $GOROOT/src/cmd/main.go:620
func allPackagesInFS(pattern string) []string {
pkgs := matchPackagesInFS(pattern)
if len(pkgs) == 0 {
fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
}
return pkgs
}
// 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 "...".
// $GOROOT/src/cmd/main.go:542
func allPackages(pattern string) []string {
pkgs := matchPackages(pattern)
if len(pkgs) == 0 {
fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
}
return pkgs
}
// $GOROOT/src/cmd/main.go:554
// This has been changed to not use build.ImportDir
func matchPackages(pattern string) []string {
match := func(string) bool { return true }
treeCanMatch := func(string) bool { return true }
if pattern != "all" && pattern != "std" && pattern != "cmd" {
match = matchPattern(pattern)
treeCanMatch = treeCanMatchPattern(pattern)
}
have := map[string]bool{
"builtin": true, // ignore pseudo-package that exists only for documentation
}
if !build.Default.CgoEnabled {
have["runtime/cgo"] = true // ignore during walk
}
var pkgs []string
for _, src := range build.Default.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" && (strings.Contains(name, ".") || name == "cmd") {
// The name "std" is only the standard library.
// If the name has a dot, assume it's a domain name for go get,
// and 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
}
ap, err := filepath.Abs(path)
if err != nil {
return nil
}
if _, err = fullPackageInDir(ap); err != nil {
debugf("matchPackage(%q) ap=%q Error: %q\n", ap, pattern, err)
if _, noGo := err.(*build.NoGoError); noGo {
return nil
}
}
pkgs = append(pkgs, name)
return nil
})
}
return pkgs
}
// treeCanMatchPattern(pattern)(name) reports whether
// name or children of name can possibly match pattern.
// Pattern is the same limited glob accepted by matchPattern.
// $GOROOT/src/cmd/main.go:527
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)
}
}
// hasPathPrefix reports whether the path s begins with the
// elements in prefix.
// $GOROOT/src/cmd/main.go:489
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
}
}
// $GOROOT/src/cmd/go/main.go:631
// This has been changed to not use build.ImportDir
func 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, _ := pathpkg.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
}
ap, err := filepath.Abs(path)
if err != nil {
return nil
}
if _, err = fullPackageInDir(ap); err != nil {
debugf("matchPackageInFS(%q) ap=%q Error: %q\n", ap, pattern, err)
if _, noGo := err.(*build.NoGoError); !noGo {
log.Print(err)
}
return nil
}
pkgs = append(pkgs, name)
return nil
})
return pkgs
}

255
vendor/github.com/tools/godep/main.go generated vendored Normal file
View File

@ -0,0 +1,255 @@
package main
import (
"flag"
"fmt"
"go/build"
"io"
"log"
"os"
"path/filepath"
"runtime/pprof"
"strings"
"text/template"
)
var (
cpuprofile string
verbose bool // Verbose flag for commands that support it
debug bool // Debug flag for commands that support it
majorGoVersion string
VendorExperiment bool
sep string
)
// Command is an implementation of a godep command
// like godep save or godep go.
type Command struct {
// Run runs the command.
// The args are the arguments after the command name.
Run func(cmd *Command, args []string)
// Name of the command
Name string
// Args the command would expect
Args string
// Short is the short description shown in the 'godep help' output.
Short string
// Long is the long message shown in the
// 'godep help <this-command>' output.
Long string
// Flag is a set of flags specific to this command.
Flag flag.FlagSet
// OnlyInGOPATH limits this command to being run only while inside of a GOPATH
OnlyInGOPATH bool
}
// UsageExit prints usage information and exits.
func (c *Command) UsageExit() {
fmt.Fprintf(os.Stderr, "Args: godep %s [-v] [-d] %s\n\n", c.Name, c.Args)
fmt.Fprintf(os.Stderr, "Run 'godep help %s' for help.\n", c.Name)
os.Exit(2)
}
// Commands lists the available commands and help topics.
// The order here is the order in which they are printed
// by 'godep help'.
var commands = []*Command{
cmdSave,
cmdGo,
cmdGet,
cmdPath,
cmdRestore,
cmdUpdate,
cmdDiff,
cmdVersion,
}
// VendorExperiment is the Go 1.5 vendor directory experiment flag, see
// https://github.com/golang/go/commit/183cc0cd41f06f83cb7a2490a499e3f9101befff
// Honor the env var unless the project already has an old school godep workspace
func determineVendor(v string) bool {
go15ve := os.Getenv("GO15VENDOREXPERIMENT")
var ev bool
switch v {
case "go1", "go1.1", "go1.2", "go1.3", "go1.4":
ev = false
case "go1.5":
ev = go15ve == "1"
case "go1.6":
ev = go15ve != "0"
default: //go1.7+, devel*
ev = true
}
ws := filepath.Join("Godeps", "_workspace")
s, err := os.Stat(ws)
if err == nil && s.IsDir() {
log.Printf("WARNING: Godep workspaces (./Godeps/_workspace) are deprecated and support for them will be removed when go1.8 is released.")
if ev {
log.Printf("WARNING: Go version (%s) & $GO15VENDOREXPERIMENT=%s wants to enable the vendor experiment, but disabling because a Godep workspace (%s) exists\n", v, go15ve, ws)
}
return false
}
return ev
}
func main() {
log.SetFlags(0)
log.SetPrefix("godep: ")
log.SetOutput(os.Stderr)
flag.Usage = usageExit
flag.Parse()
args := flag.Args()
if len(args) < 1 {
usageExit()
}
if args[0] == "help" {
help(args[1:])
return
}
var err error
majorGoVersion, err = goVersion()
if err != nil {
log.Fatal(err)
}
for _, cmd := range commands {
if cmd.Name == args[0] {
if cmd.OnlyInGOPATH {
checkInGOPATH()
}
VendorExperiment = determineVendor(majorGoVersion)
// sep is the signature set of path elements that
// precede the original path of an imported package.
sep = defaultSep(VendorExperiment)
cmd.Flag.BoolVar(&verbose, "v", false, "enable verbose output")
cmd.Flag.BoolVar(&debug, "d", false, "enable debug output")
cmd.Flag.StringVar(&cpuprofile, "cpuprofile", "", "Write cpu profile to this file")
cmd.Flag.Usage = func() { cmd.UsageExit() }
cmd.Flag.Parse(args[1:])
debugln("versionString()", versionString())
debugln("majorGoVersion", majorGoVersion)
debugln("VendorExperiment", VendorExperiment)
debugln("sep", sep)
if cpuprofile != "" {
f, err := os.Create(cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
cmd.Run(cmd, cmd.Flag.Args())
return
}
}
fmt.Fprintf(os.Stderr, "godep: unknown command %q\n", args[0])
fmt.Fprintf(os.Stderr, "Run 'godep help' for usage.\n")
os.Exit(2)
}
func subPath(sub, path string) bool {
ls := strings.ToLower(sub)
lp := strings.ToLower(path)
if ls == lp {
return false
}
return strings.HasPrefix(ls, lp)
}
func checkInGOPATH() {
pwd, err := os.Getwd()
if err != nil {
log.Fatal("Unable to determine current working directory", err)
}
dirs := build.Default.SrcDirs()
for _, p := range dirs {
if ok := subPath(pwd, p); ok {
return
}
}
log.Println("[WARNING]: godep should only be used inside a valid go package directory and")
log.Println("[WARNING]: may not function correctly. You are probably outside of your $GOPATH.")
log.Printf("[WARNING]:\tCurrent Directory: %s\n", pwd)
log.Printf("[WARNING]:\t$GOPATH: %s\n", os.Getenv("GOPATH"))
}
var usageTemplate = `
Godep is a tool for managing Go package dependencies.
Usage:
godep command [arguments]
The commands are:
{{range .}}
{{.Name | printf "%-8s"}} {{.Short}}{{end}}
Use "godep help [command]" for more information about a command.
`
var helpTemplate = `
Args: godep {{.Name}} [-v] [-d] {{.Args}}
{{.Long | trim}}
If -v is given, verbose output is enabled.
If -d is given, debug output is enabled (you probably don't want this, see -v).
`
func help(args []string) {
if len(args) == 0 {
printUsage(os.Stdout)
return
}
if len(args) != 1 {
fmt.Fprintf(os.Stderr, "usage: godep help command\n\n")
fmt.Fprintf(os.Stderr, "Too many arguments given.\n")
os.Exit(2)
}
for _, cmd := range commands {
if cmd.Name == args[0] {
tmpl(os.Stdout, helpTemplate, cmd)
return
}
}
}
func usageExit() {
printUsage(os.Stderr)
os.Exit(2)
}
func printUsage(w io.Writer) {
tmpl(w, usageTemplate, commands)
}
// tmpl executes the given template text on data, writing the result to w.
func tmpl(w io.Writer, text string, data interface{}) {
t := template.New("top")
t.Funcs(template.FuncMap{
"trim": strings.TrimSpace,
})
template.Must(t.Parse(strings.TrimSpace(text) + "\n\n"))
if err := t.Execute(w, data); err != nil {
panic(err)
}
}

55
vendor/github.com/tools/godep/msg.go generated vendored Normal file
View File

@ -0,0 +1,55 @@
package main
import (
"fmt"
"log"
"github.com/kr/pretty"
)
func debugln(a ...interface{}) (int, error) {
if debug {
return fmt.Println(a...)
}
return 0, nil
}
func verboseln(a ...interface{}) {
if verbose {
log.Println(a...)
}
}
func debugf(format string, a ...interface{}) (int, error) {
if debug {
return fmt.Printf(format, a...)
}
return 0, nil
}
func verbosef(format string, a ...interface{}) {
if verbose {
log.Printf(format, a...)
}
}
func pp(a ...interface{}) (int, error) {
if debug {
return pretty.Print(a...)
}
return 0, nil
}
func ppln(a ...interface{}) (int, error) {
if debug {
return pretty.Println(a...)
}
return 0, nil
}
func ppf(format string, a ...interface{}) (int, error) {
if debug {
return pretty.Printf(format, a...)
}
return 0, nil
}

36
vendor/github.com/tools/godep/path.go generated vendored Normal file
View File

@ -0,0 +1,36 @@
package main
import (
"fmt"
"os"
)
var cmdPath = &Command{
Name: "path",
Short: "print GOPATH for dependency code",
Long: `
Command path prints a path for use in env var GOPATH
that makes available the specified version of each dependency.
The printed path does not include any GOPATH value from
the environment.
For more about how GOPATH works, see 'go help gopath'.
`,
Run: runPath,
OnlyInGOPATH: true,
}
// Print the gopath that points to
// the included dependency code.
func runPath(cmd *Command, args []string) {
if len(args) != 0 {
cmd.UsageExit()
}
if VendorExperiment {
fmt.Fprintln(os.Stderr, "Error: GO15VENDOREXPERIMENT is enabled and the vendor/ directory is not a valid Go workspace.")
os.Exit(1)
}
gopath := prepareGopath()
fmt.Println(gopath)
}

81
vendor/github.com/tools/godep/pkg.go generated vendored Normal file
View File

@ -0,0 +1,81 @@
package main
import (
"go/build"
"regexp"
"strings"
)
// Package represents a Go package.
type Package struct {
Dir string
Root string
ImportPath string
Deps []string
Standard bool
Processed bool
GoFiles []string
CgoFiles []string
IgnoredGoFiles []string
TestGoFiles []string
TestImports []string
XTestGoFiles []string
XTestImports []string
Error struct {
Err string
}
// --- New stuff for now
Imports []string
Dependencies []build.Package
}
// LoadPackages loads the named packages
// Unlike the go tool, an empty argument list is treated as an empty list; "."
// must be given explicitly if desired.
// IgnoredGoFiles will be processed and their dependencies resolved recursively
func LoadPackages(names ...string) (a []*Package, err error) {
debugln("LoadPackages", names)
if len(names) == 0 {
return nil, nil
}
for _, i := range importPaths(names) {
p, err := listPackage(i)
if err != nil {
return nil, err
}
a = append(a, p)
}
return a, nil
}
func (p *Package) allGoFiles() []string {
var a []string
a = append(a, p.GoFiles...)
a = append(a, p.CgoFiles...)
a = append(a, p.TestGoFiles...)
a = append(a, p.XTestGoFiles...)
a = append(a, p.IgnoredGoFiles...)
return a
}
// 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.
// Taken from $GOROOT/src/cmd/go/main.go.
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 func(name string) bool {
return reg.MatchString(name)
}
}

195
vendor/github.com/tools/godep/restore.go generated vendored Normal file
View File

@ -0,0 +1,195 @@
package main
import (
"errors"
"go/build"
"log"
"os"
"path/filepath"
"golang.org/x/tools/go/vcs"
)
var cmdRestore = &Command{
Name: "restore",
Short: "check out listed dependency versions in GOPATH",
Long: `
Restore checks out the Godeps-specified version of each package in GOPATH.
NOTE: restore leaves git repositories in a detached state. go1.6+ no longer
checks out the master branch when doing a "go get", see:
https://github.com/golang/go/commit/42206598671a44111c8f726ad33dc7b265bdf669.
`,
Run: runRestore,
OnlyInGOPATH: true,
}
// Three phases:
// 1. Download all deps
// 2. Restore all deps (checkout the recorded rev)
// 3. Attempt to load all deps as a simple consistency check
func runRestore(cmd *Command, args []string) {
if len(build.Default.GOPATH) == 0 {
log.Println("Error restore requires GOPATH but it is empty.")
os.Exit(1)
}
var hadError bool
checkErr := func(s string) {
if hadError {
log.Println(s)
os.Exit(1)
}
}
g, err := loadDefaultGodepsFile()
if err != nil {
log.Fatalln(err)
}
for i, dep := range g.Deps {
verboseln("Downloading dependency (if needed):", dep.ImportPath)
err := download(&dep)
if err != nil {
log.Printf("error downloading dep (%s): %s\n", dep.ImportPath, err)
hadError = true
}
g.Deps[i] = dep
}
checkErr("Error downloading some deps. Aborting restore and check.")
for _, dep := range g.Deps {
verboseln("Restoring dependency (if needed):", dep.ImportPath)
err := restore(dep)
if err != nil {
log.Printf("error restoring dep (%s): %s\n", dep.ImportPath, err)
hadError = true
}
}
checkErr("Error restoring some deps. Aborting check.")
for _, dep := range g.Deps {
verboseln("Checking dependency:", dep.ImportPath)
_, err := LoadPackages(dep.ImportPath)
if err != nil {
log.Printf("Dep (%s) restored, but was unable to load it with error:\n\t%s\n", dep.ImportPath, err)
if me, ok := err.(errorMissingDep); ok {
log.Println("\tThis may be because the dependencies were saved with an older version of godep (< v33).")
log.Printf("\tTry `go get %s`. Then `godep save` to update deps.\n", me.i)
}
hadError = true
}
}
checkErr("Error checking some deps.")
}
var downloaded = make(map[string]bool)
// download the given dependency.
// 2 Passes: 1) go get -d <pkg>, 2) git pull (if necessary)
func download(dep *Dependency) error {
rr, err := vcs.RepoRootForImportPath(dep.ImportPath, debug)
if err != nil {
debugln("Error determining repo root for", dep.ImportPath)
return err
}
ppln("rr", rr)
dep.vcs = cmd[rr.VCS]
// try to find an existing directory in the GOPATHs
for _, gp := range filepath.SplitList(build.Default.GOPATH) {
t := filepath.Join(gp, "src", rr.Root)
fi, err := os.Stat(t)
if err != nil {
continue
}
if fi.IsDir() {
dep.root = t
break
}
}
// If none found, just pick the first GOPATH entry (AFAICT that's what go get does)
if dep.root == "" {
dep.root = filepath.Join(filepath.SplitList(build.Default.GOPATH)[0], "src", rr.Root)
}
ppln("dep", dep)
if downloaded[rr.Repo] {
verboseln("Skipping already downloaded repo", rr.Repo)
return nil
}
fi, err := os.Stat(dep.root)
if err != nil {
if os.IsNotExist(err) {
if err := os.MkdirAll(filepath.Dir(dep.root), os.ModePerm); err != nil {
debugln("Error creating base dir of", dep.root)
return err
}
err := rr.VCS.CreateAtRev(dep.root, rr.Repo, dep.Rev)
debugln("CreatedAtRev", dep.root, rr.Repo, dep.Rev)
if err != nil {
debugln("CreateAtRev error", err)
return err
}
downloaded[rr.Repo] = true
return nil
}
debugln("Error checking repo root for", dep.ImportPath, "at", dep.root, ":", err)
return err
}
if !fi.IsDir() {
return errors.New("repo root src dir exists, but isn't a directory for " + dep.ImportPath + " at " + dep.root)
}
if !dep.vcs.exists(dep.root, dep.Rev) {
debugln("Updating existing", dep.root)
if dep.vcs == vcsGit {
detached, err := gitDetached(dep.root)
if err != nil {
return err
}
if detached {
db, err := gitDefaultBranch(dep.root)
if err != nil {
return err
}
if err := gitCheckout(dep.root, db); err != nil {
return err
}
}
}
dep.vcs.vcs.Download(dep.root)
downloaded[rr.Repo] = true
}
debugln("Nothing to download")
return nil
}
var restored = make(map[string]string) // dep.root -> dep.Rev
// restore checks out the given revision.
func restore(dep Dependency) error {
rev, ok := restored[dep.root]
debugln(rev)
debugln(ok)
debugln(dep.root)
if ok {
if rev != dep.Rev {
return errors.New("Wanted to restore rev " + dep.Rev + ", already restored rev " + rev + " for another package in the repo")
}
verboseln("Skipping already restored repo")
return nil
}
debugln("Restoring:", dep.ImportPath, dep.Rev)
err := dep.vcs.RevSync(dep.root, dep.Rev)
if err == nil {
restored[dep.root] = dep.Rev
}
return err
}

168
vendor/github.com/tools/godep/rewrite.go generated vendored Normal file
View File

@ -0,0 +1,168 @@
package main
import (
"bytes"
"log"
"os"
"path/filepath"
"strconv"
"strings"
"go/ast"
"go/parser"
"go/printer"
"go/token"
"github.com/kr/fs"
)
// rewrite visits the go files in pkgs, plus all go files
// in the directory tree Godeps, rewriting import statements
// according to the rules for func qualify.
func rewrite(pkgs []*Package, qual string, paths []string) error {
for _, path := range pkgFiles(pkgs) {
debugln("rewrite", path)
err := rewriteTree(path, qual, paths)
if err != nil {
return err
}
}
return rewriteTree("Godeps", qual, paths)
}
// pkgFiles returns the full filesystem path to all go files in pkgs.
func pkgFiles(pkgs []*Package) []string {
var a []string
for _, pkg := range pkgs {
for _, s := range pkg.allGoFiles() {
a = append(a, filepath.Join(pkg.Dir, s))
}
}
return a
}
// rewriteTree recursively visits the go files in path, rewriting
// import statements according to the rules for func qualify.
// This function ignores the 'testdata' directory.
func rewriteTree(path, qual string, paths []string) error {
w := fs.Walk(path)
for w.Step() {
if w.Err() != nil {
log.Println("rewrite:", w.Err())
continue
}
s := w.Stat()
if s.IsDir() && s.Name() == "testdata" {
w.SkipDir()
continue
}
if strings.HasSuffix(w.Path(), ".go") {
err := rewriteGoFile(w.Path(), qual, paths)
if err != nil {
return err
}
}
}
return nil
}
// rewriteGoFile rewrites import statements in the named file
// according to the rules for func qualify.
func rewriteGoFile(name, qual string, paths []string) error {
debugln("rewriteGoFile", name, ",", qual, ",", paths)
printerConfig := &printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, name, nil, parser.ParseComments)
if err != nil {
return err
}
var changed bool
for _, s := range f.Imports {
name, err := strconv.Unquote(s.Path.Value)
if err != nil {
return err // can't happen
}
q := qualify(unqualify(name), qual, paths)
if q != name {
s.Path.Value = strconv.Quote(q)
changed = true
}
}
if !changed {
return nil
}
var buffer bytes.Buffer
if err = printerConfig.Fprint(&buffer, fset, f); err != nil {
return err
}
fset = token.NewFileSet()
f, err = parser.ParseFile(fset, name, &buffer, parser.ParseComments)
ast.SortImports(fset, f)
tpath := name + ".temp"
t, err := os.Create(tpath)
if err != nil {
return err
}
if err = printerConfig.Fprint(t, fset, f); err != nil {
return err
}
if err = t.Close(); err != nil {
return err
}
// This is required before the rename on windows.
if err = os.Remove(name); err != nil {
return err
}
return os.Rename(tpath, name)
}
func defaultSep(experiment bool) string {
if experiment {
return "/vendor/"
}
return "/Godeps/_workspace/src/"
}
func relativeVendorTarget(experiment bool) string {
full := defaultSep(experiment)
if full[0] == '/' {
full = full[1:]
}
return filepath.FromSlash(full)
}
// unqualify returns the part of importPath after the last
// occurrence of the signature path elements
// (Godeps/_workspace/src) that always precede imported
// packages in rewritten import paths.
//
// For example,
// unqualify(C) = C
// unqualify(D/Godeps/_workspace/src/C) = C
func unqualify(importPath string) string {
if i := strings.LastIndex(importPath, sep); i != -1 {
importPath = importPath[i+len(sep):]
}
return importPath
}
// qualify qualifies importPath with its corresponding import
// path in the Godeps src copy of package pkg. If importPath
// is a directory lexically contained in a path in paths,
// it will be qualified with package pkg; otherwise, it will
// be returned unchanged.
//
// For example, given paths {D, T} and pkg C,
// importPath returns
// C C
// fmt fmt
// D C/Godeps/_workspace/src/D
// D/P C/Godeps/_workspace/src/D/P
// T C/Godeps/_workspace/src/T
func qualify(importPath, pkg string, paths []string) string {
if containsPathPrefix(paths, importPath) {
return pkg + sep + importPath
}
return importPath
}

612
vendor/github.com/tools/godep/save.go generated vendored Normal file
View File

@ -0,0 +1,612 @@
package main
import (
"bufio"
"bytes"
"errors"
"fmt"
"go/build"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/kr/fs"
)
var cmdSave = &Command{
Name: "save",
Args: "[-r] [-t] [packages]",
Short: "list and copy dependencies into Godeps",
Long: `
Save writes a list of the named packages and their dependencies along
with the exact source control revision of each package, and copies
their source code into a subdirectory. Packages inside "." are excluded
from the list to be copied.
The list is written to Godeps/Godeps.json, and source code for all
dependencies is copied into either Godeps/_workspace or, if the vendor
experiment is turned on, vendor/.
The dependency list is a JSON document with the following structure:
type Godeps struct {
ImportPath string
GoVersion string // Abridged output of 'go version'.
Packages []string // Arguments to godep save, if any.
Deps []struct {
ImportPath string
Comment string // Tag or description of commit.
Rev string // VCS-specific commit ID.
}
}
Any packages already present in the list will be left unchanged.
To update a dependency to a newer revision, use 'godep update'.
If -r is given, import statements will be rewritten to refer directly
to the copied source code. This is not compatible with the vendor
experiment. Note that this will not rewrite the statements in the
files outside the project.
If -t is given, test files (*_test.go files + testdata directories) are
also saved.
For more about specifying packages, see 'go help packages'.
`,
Run: runSave,
OnlyInGOPATH: true,
}
var (
saveR, saveT bool
)
func init() {
cmdSave.Flag.BoolVar(&saveR, "r", false, "rewrite import paths")
cmdSave.Flag.BoolVar(&saveT, "t", false, "save test files")
}
func runSave(cmd *Command, args []string) {
if VendorExperiment && saveR {
log.Println("flag -r is incompatible with the vendoring experiment")
cmd.UsageExit()
}
err := save(args)
if err != nil {
log.Fatalln(err)
}
}
func dotPackage() (*build.Package, error) {
dir, err := filepath.Abs(".")
if err != nil {
return nil, err
}
return build.ImportDir(dir, build.FindOnly)
}
func projectPackages(dDir string, a []*Package) []*Package {
var projPkgs []*Package
dotDir := fmt.Sprintf("%s%c", dDir, filepath.Separator)
for _, p := range a {
pkgDir := fmt.Sprintf("%s%c", p.Dir, filepath.Separator)
if strings.HasPrefix(pkgDir, dotDir) {
projPkgs = append(projPkgs, p)
}
}
return projPkgs
}
func save(pkgs []string) error {
var err error
dp, err := dotPackage()
if err != nil {
return err
}
debugln("dotPackageImportPath:", dp.ImportPath)
debugln("dotPackageDir:", dp.Dir)
cv, err := goVersion()
if err != nil {
return err
}
verboseln("Go Version:", cv)
gold, err := loadDefaultGodepsFile()
if err != nil {
if !os.IsNotExist(err) {
return err
}
verboseln("No old Godeps.json found.")
gold.GoVersion = cv
}
printVersionWarnings(gold.GoVersion)
if len(gold.GoVersion) == 0 {
gold.GoVersion = majorGoVersion
} else {
majorGoVersion, err = trimGoVersion(gold.GoVersion)
if err != nil {
log.Fatalf("Unable to determine go major version from value specified in %s: %s\n", gold.file(), gold.GoVersion)
}
}
gnew := &Godeps{
ImportPath: dp.ImportPath,
GoVersion: gold.GoVersion,
}
switch len(pkgs) {
case 0:
pkgs = []string{"."}
default:
gnew.Packages = pkgs
}
verboseln("Finding dependencies for", pkgs)
a, err := LoadPackages(pkgs...)
if err != nil {
return err
}
for _, p := range a {
verboseln("Found package:", p.ImportPath)
verboseln("\tDeps:", strings.Join(p.Deps, " "))
}
ppln(a)
projA := projectPackages(dp.Dir, a)
debugln("Filtered projectPackages")
ppln(projA)
verboseln("Computing new Godeps.json file")
err = gnew.fill(a, dp.ImportPath)
if err != nil {
return err
}
debugln("New Godeps Filled")
ppln(gnew)
if gnew.Deps == nil {
gnew.Deps = make([]Dependency, 0) // produce json [], not null
}
gdisk := gnew.copy()
err = carryVersions(&gold, gnew)
if err != nil {
return err
}
if gold.isOldFile {
// If we are migrating from an old format file,
// we require that the listed version of every
// dependency must be installed in GOPATH, so it's
// available to copy.
if !eqDeps(gnew.Deps, gdisk.Deps) {
return errors.New(strings.TrimSpace(needRestore))
}
gold = Godeps{}
}
os.Remove("Godeps") // remove regular file if present; ignore error
readme := filepath.Join("Godeps", "Readme")
err = writeFile(readme, strings.TrimSpace(Readme)+"\n")
if err != nil {
log.Println(err)
}
_, err = gnew.save()
if err != nil {
return err
}
verboseln("Computing diff between old and new deps")
// We use a name starting with "_" so the go tool
// ignores this directory when traversing packages
// starting at the project's root. For example,
// godep go list ./...
srcdir := filepath.FromSlash(strings.Trim(sep, "/"))
rem := subDeps(gold.Deps, gnew.Deps)
ppln(rem)
add := subDeps(gnew.Deps, gold.Deps)
ppln(add)
if len(rem) > 0 {
verboseln("Deps to remove:")
for _, r := range rem {
verboseln("\t", r.ImportPath)
}
verboseln("Removing unused dependencies")
err = removeSrc(srcdir, rem)
if err != nil {
return err
}
}
if len(add) > 0 {
verboseln("Deps to add:")
for _, a := range add {
verboseln("\t", a.ImportPath)
}
verboseln("Adding new dependencies")
err = copySrc(srcdir, add)
if err != nil {
return err
}
}
if !VendorExperiment {
f, _ := filepath.Split(srcdir)
writeVCSIgnore(f)
}
var rewritePaths []string
if saveR {
for _, dep := range gnew.Deps {
rewritePaths = append(rewritePaths, dep.ImportPath)
}
}
verboseln("Rewriting paths (if necessary)")
ppln(rewritePaths)
return rewrite(projA, dp.ImportPath, rewritePaths)
}
func printVersionWarnings(ov string) {
var warning bool
cv, err := goVersion()
if err != nil {
return
}
// Trim the old version because we may have saved it w/o trimming it
// cv is already trimmed by goVersion()
tov, err := trimGoVersion(ov)
if err != nil {
return
}
if tov != ov {
log.Printf("WARNING: Recorded go version (%s) with minor version string found.\n", ov)
warning = true
}
if cv != tov {
log.Printf("WARNING: Recorded major go version (%s) and in-use major go version (%s) differ.\n", tov, cv)
warning = true
}
if warning {
log.Println("To record current major go version run `godep update -goversion`.")
}
}
type revError struct {
ImportPath string
WantRev string
HavePath string
HaveRev string
}
func (v *revError) Error() string {
return fmt.Sprintf("cannot save %s at revision %s: already have %s at revision %s.\n"+
"Run `godep update %s' first.", v.ImportPath, v.WantRev, v.HavePath, v.HaveRev, v.HavePath)
}
// carryVersions copies Rev and Comment from a to b for
// each dependency with an identical ImportPath. For any
// dependency in b that appears to be from the same repo
// as one in a (for example, a parent or child directory),
// the Rev must already match - otherwise it is an error.
func carryVersions(a, b *Godeps) error {
for i := range b.Deps {
err := carryVersion(a, &b.Deps[i])
if err != nil {
return err
}
}
return nil
}
func carryVersion(a *Godeps, db *Dependency) error {
// First see if this exact package is already in the list.
for _, da := range a.Deps {
if db.ImportPath == da.ImportPath {
db.Rev = da.Rev
db.Comment = da.Comment
return nil
}
}
// No exact match, check for child or sibling package.
// We can't handle mismatched versions for packages in
// the same repo, so report that as an error.
for _, da := range a.Deps {
if strings.HasPrefix(db.ImportPath, da.ImportPath+"/") ||
strings.HasPrefix(da.ImportPath, db.root+"/") {
if da.Rev != db.Rev {
return &revError{
ImportPath: db.ImportPath,
WantRev: db.Rev,
HavePath: da.ImportPath,
HaveRev: da.Rev,
}
}
}
}
// No related package in the list, must be a new repo.
return nil
}
// subDeps returns a - b, using ImportPath for equality.
func subDeps(a, b []Dependency) (diff []Dependency) {
Diff:
for _, da := range a {
for _, db := range b {
if da.ImportPath == db.ImportPath {
continue Diff
}
}
diff = append(diff, da)
}
return diff
}
func removeSrc(srcdir string, deps []Dependency) error {
for _, dep := range deps {
path := filepath.FromSlash(dep.ImportPath)
err := os.RemoveAll(filepath.Join(srcdir, path))
if err != nil {
return err
}
}
return nil
}
func copySrc(dir string, deps []Dependency) error {
// mapping to see if we visited a parent directory already
visited := make(map[string]bool)
ok := true
for _, dep := range deps {
debugln("copySrc for", dep.ImportPath)
srcdir := filepath.Join(dep.ws, "src")
rel, err := filepath.Rel(srcdir, dep.dir)
debugln("srcdir", srcdir)
debugln("rel", rel)
debugln("err", err)
if err != nil { // this should never happen
return err
}
dstpkgroot := filepath.Join(dir, rel)
err = os.RemoveAll(dstpkgroot)
if err != nil {
log.Println(err)
ok = false
}
// copy actual dependency
vf := dep.vcs.listFiles(dep.dir)
debugln("vf", vf)
w := fs.Walk(dep.dir)
for w.Step() {
err = copyPkgFile(vf, dir, srcdir, w)
if err != nil {
log.Println(err)
ok = false
}
}
// Look for legal files in root
// some packages are imports as a sub-package but license info
// is at root: exampleorg/common has license file in exampleorg
//
if dep.ImportPath == dep.root {
// we are already at root
continue
}
// prevent copying twice This could happen if we have
// two subpackages listed someorg/common and
// someorg/anotherpack which has their license in
// the parent dir of someorg
rootdir := filepath.Join(srcdir, filepath.FromSlash(dep.root))
if visited[rootdir] {
continue
}
visited[rootdir] = true
vf = dep.vcs.listFiles(rootdir)
w = fs.Walk(rootdir)
for w.Step() {
fname := filepath.Base(w.Path())
if IsLegalFile(fname) && !strings.Contains(w.Path(), sep) {
err = copyPkgFile(vf, dir, srcdir, w)
if err != nil {
log.Println(err)
ok = false
}
}
}
}
if !ok {
return errorCopyingSourceCode
}
return nil
}
func copyPkgFile(vf vcsFiles, dstroot, srcroot string, w *fs.Walker) error {
if w.Err() != nil {
return w.Err()
}
name := w.Stat().Name()
if w.Stat().IsDir() {
if name[0] == '.' || name[0] == '_' || (!saveT && name == "testdata") {
// Skip directories starting with '.' or '_' or
// 'testdata' (last is only skipped if saveT is false)
w.SkipDir()
}
return nil
}
rel, err := filepath.Rel(srcroot, w.Path())
if err != nil { // this should never happen
return err
}
if !saveT && strings.HasSuffix(name, "_test.go") {
if verbose {
log.Printf("save: skipping test file: %s", w.Path())
}
return nil
}
if !vf.Contains(w.Path()) {
if verbose {
log.Printf("save: skipping untracked file: %s", w.Path())
}
return nil
}
return copyFile(filepath.Join(dstroot, rel), w.Path())
}
// copyFile copies a regular file from src to dst.
// dst is opened with os.Create.
// If the file name ends with .go,
// copyFile strips canonical import path annotations.
// These are comments of the form:
// package foo // import "bar/foo"
// package foo /* import "bar/foo" */
func copyFile(dst, src string) error {
err := os.MkdirAll(filepath.Dir(dst), 0777)
if err != nil {
return err
}
linkDst, err := os.Readlink(src)
if err == nil {
return os.Symlink(linkDst, dst)
}
si, err := stat(src)
if err != nil {
return err
}
r, err := os.Open(src)
if err != nil {
return err
}
defer r.Close()
w, err := os.Create(dst)
if err != nil {
return err
}
if err := os.Chmod(dst, si.Mode()); err != nil {
return err
}
if strings.HasSuffix(dst, ".go") {
debugln("Copy Without Import Comment", w, r)
err = copyWithoutImportComment(w, r)
} else {
debugln("Copy (plain)", w, r)
_, err = io.Copy(w, r)
}
err1 := w.Close()
if err == nil {
err = err1
}
return err
}
func copyWithoutImportComment(w io.Writer, r io.Reader) error {
b := bufio.NewReader(r)
for {
l, err := b.ReadBytes('\n')
eof := err == io.EOF
if err != nil && err != io.EOF {
return err
}
// If we have data then write it out...
if len(l) > 0 {
// Strip off \n if it exists because stripImportComment
_, err := w.Write(append(stripImportComment(bytes.TrimRight(l, "\n")), '\n'))
if err != nil {
return err
}
}
if eof {
return nil
}
}
}
const (
importAnnotation = `import\s+(?:"[^"]*"|` + "`[^`]*`" + `)`
importComment = `(?://\s*` + importAnnotation + `\s*$|/\*\s*` + importAnnotation + `\s*\*/)`
)
var (
importCommentRE = regexp.MustCompile(`^\s*(package\s+\w+)\s+` + importComment + `(.*)`)
pkgPrefix = []byte("package ")
)
// stripImportComment returns line with its import comment removed.
// If s is not a package statement containing an import comment,
// it is returned unaltered.
// FIXME: expects lines w/o a \n at the end
// See also http://golang.org/s/go14customimport.
func stripImportComment(line []byte) []byte {
if !bytes.HasPrefix(line, pkgPrefix) {
// Fast path; this will skip all but one line in the file.
// This assumes there is no whitespace before the keyword.
return line
}
if m := importCommentRE.FindSubmatch(line); m != nil {
return append(m[1], m[2]...)
}
return line
}
// Func writeVCSIgnore writes "ignore" files inside dir for known VCSs,
// so that dir/pkg and dir/bin don't accidentally get committed.
// It logs any errors it encounters.
func writeVCSIgnore(dir string) {
// Currently git is the only VCS for which we know how to do this.
// Mercurial and Bazaar have similar mechanisms, but they apparently
// require writing files outside of dir.
const ignore = "/pkg\n/bin\n"
name := filepath.Join(dir, ".gitignore")
err := writeFile(name, ignore)
if err != nil {
log.Println(err)
}
}
// writeFile is like ioutil.WriteFile but it creates
// intermediate directories with os.MkdirAll.
func writeFile(name, body string) error {
err := os.MkdirAll(filepath.Dir(name), 0777)
if err != nil {
return err
}
return ioutil.WriteFile(name, []byte(body), 0666)
}
const (
// Readme contains the README text.
Readme = `
This directory tree is generated automatically by godep.
Please do not edit.
See https://github.com/tools/godep for more information.
`
needRestore = `
mismatched versions while migrating
It looks like you are switching from the old Godeps format
(from flag -copy=false). The old format is just a file; it
doesn't contain source code. For this migration, godep needs
the appropriate version of each dependency to be installed in
GOPATH, so that the source code is available to copy.
To fix this, run 'godep restore'.
`
)

292
vendor/github.com/tools/godep/update.go generated vendored Normal file
View File

@ -0,0 +1,292 @@
package main
import (
"go/parser"
"go/token"
"log"
"os"
"path"
"path/filepath"
"strconv"
"strings"
)
var cmdUpdate = &Command{
Name: "update",
Args: "[-goversion] [packages]",
Short: "update selected packages or the go version",
Long: `
Update changes the named dependency packages to use the
revision of each currently installed in GOPATH. New code will
be copied into the Godeps workspace or vendor folder and the
new revision will be written to the manifest.
If -goversion is specified, update the recorded go version.
For more about specifying packages, see 'go help packages'.
`,
Run: runUpdate,
OnlyInGOPATH: true,
}
var (
updateGoVer bool
)
func init() {
cmdUpdate.Flag.BoolVar(&saveT, "t", false, "save test files during update")
cmdUpdate.Flag.BoolVar(&updateGoVer, "goversion", false, "update the recorded go version")
}
func runUpdate(cmd *Command, args []string) {
if updateGoVer {
err := updateGoVersion()
if err != nil {
log.Fatalln(err)
}
}
if len(args) > 0 {
err := update(args)
if err != nil {
log.Fatalln(err)
}
}
}
func updateGoVersion() error {
gold, err := loadDefaultGodepsFile()
if err != nil {
if !os.IsNotExist(err) {
return err
}
}
cv, err := goVersion()
if err != nil {
return err
}
gv := gold.GoVersion
gold.GoVersion = cv
_, err = gold.save()
if err != nil {
return err
}
if gv != cv {
log.Println("Updated major go version to", cv)
}
return nil
}
func update(args []string) error {
if len(args) == 0 {
args = []string{"."}
}
g, err := loadDefaultGodepsFile()
if err != nil {
return err
}
for _, arg := range args {
arg := path.Clean(arg)
any := markMatches(arg, g.Deps)
if !any {
log.Println("not in manifest:", arg)
}
}
deps, rdeps, err := LoadVCSAndUpdate(g.Deps)
if err != nil {
return err
}
if len(deps) == 0 {
return errorNoPackagesUpdatable
}
g.addOrUpdateDeps(deps)
g.removeDeps(rdeps)
if _, err = g.save(); err != nil {
return err
}
srcdir := relativeVendorTarget(VendorExperiment)
if err := removeSrc(filepath.FromSlash(strings.Trim(sep, "/")), rdeps); err != nil {
return err
}
copySrc(srcdir, deps)
ok, err := needRewrite(g.Packages)
if err != nil {
return err
}
var rewritePaths []string
if ok {
for _, dep := range g.Deps {
rewritePaths = append(rewritePaths, dep.ImportPath)
}
}
return rewrite(nil, g.ImportPath, rewritePaths)
}
func needRewrite(importPaths []string) (bool, error) {
if len(importPaths) == 0 {
importPaths = []string{"."}
}
a, err := LoadPackages(importPaths...)
if err != nil {
return false, err
}
for _, p := range a {
for _, name := range p.allGoFiles() {
path := filepath.Join(p.Dir, name)
hasSep, err := hasRewrittenImportStatement(path)
if err != nil {
return false, err
}
if hasSep {
return true, nil
}
}
}
return false, nil
}
func hasRewrittenImportStatement(path string) (bool, error) {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, path, nil, 0)
if err != nil {
return false, err
}
for _, s := range f.Imports {
name, _ := strconv.Unquote(s.Path.Value)
if strings.Contains(name, sep) {
return true, nil
}
}
return false, nil
}
// markMatches marks each entry in deps with an import path that
// matches pat. It returns whether any matches occurred.
func markMatches(pat string, deps []Dependency) (matched bool) {
f := matchPattern(pat)
for i, dep := range deps {
if f(dep.ImportPath) {
deps[i].matched = true
matched = true
}
}
return matched
}
func fillDeps(deps []Dependency) ([]Dependency, error) {
for i := range deps {
if deps[i].pkg != nil {
continue
}
ps, err := LoadPackages(deps[i].ImportPath)
if err != nil {
if _, ok := err.(errPackageNotFound); ok {
deps[i].missing = true
continue
}
return nil, err
}
if len(ps) > 1 {
panic("More than one package found for " + deps[i].ImportPath)
}
p := ps[0]
deps[i].pkg = p
deps[i].dir = p.Dir
deps[i].ws = p.Root
vcs, reporoot, err := VCSFromDir(p.Dir, filepath.Join(p.Root, "src"))
if err != nil {
return nil, errorLoadingDeps
}
deps[i].root = filepath.ToSlash(reporoot)
deps[i].vcs = vcs
}
return deps, nil
}
// LoadVCSAndUpdate loads and updates a set of dependencies.
func LoadVCSAndUpdate(deps []Dependency) ([]Dependency, []Dependency, error) {
var err1 error
deps, err := fillDeps(deps)
if err != nil {
return nil, nil, err
}
repoMask := make(map[string]bool)
for i := range deps {
if !deps[i].matched {
repoMask[deps[i].root] = true
}
}
// Determine if we need any new packages because of new transitive imports
for _, dep := range deps {
if !dep.matched || dep.missing {
continue
}
for _, dp := range dep.pkg.Dependencies {
if dp.Goroot {
continue
}
var have bool
for _, d := range deps {
if d.ImportPath == dp.ImportPath {
have = true
break
}
}
if !have {
deps = append(deps, Dependency{ImportPath: dp.ImportPath, matched: true})
}
}
}
deps, err = fillDeps(deps)
if err != nil {
return nil, nil, err
}
var toUpdate, toRemove []Dependency
for _, d := range deps {
if !d.matched || repoMask[d.root] {
continue
}
if d.missing {
toRemove = append(toRemove, d)
continue
}
toUpdate = append(toUpdate, d)
}
debugln("toUpdate")
ppln(toUpdate)
var toCopy []Dependency
for _, d := range toUpdate {
id, err := d.vcs.identify(d.dir)
if err != nil {
log.Println(err)
err1 = errorLoadingDeps
continue
}
if d.vcs.isDirty(d.dir, id) {
log.Println("dirty working tree (please commit changes):", d.dir)
}
d.Rev = id
d.Comment = d.vcs.describe(d.dir, id)
toCopy = append(toCopy, d)
}
debugln("toCopy")
ppln(toCopy)
if err1 != nil {
return nil, nil, err1
}
return toCopy, toRemove, nil
}

60
vendor/github.com/tools/godep/util.go generated vendored Normal file
View File

@ -0,0 +1,60 @@
package main
import (
"fmt"
"os/exec"
"path/filepath"
"runtime"
"strings"
)
// Runs a command in dir.
// The name and args are as in exec.Command.
// Stdout, stderr, and the environment are inherited
// from the current process.
func runIn(dir, name string, args ...string) error {
_, err := runInWithOutput(dir, name, args...)
return err
}
func runInWithOutput(dir, name string, args ...string) (string, error) {
c := exec.Command(name, args...)
c.Dir = dir
o, err := c.CombinedOutput()
if debug {
fmt.Printf("execute: %+v\n", c)
fmt.Printf(" output: %s\n", string(o))
}
return string(o), err
}
// driveLetterToUpper converts Windows path's drive letters to uppercase. This
// is needed when comparing 2 paths with different drive letter case.
func driveLetterToUpper(path string) string {
if runtime.GOOS != "windows" || path == "" {
return path
}
p := path
// If path's drive letter is lowercase, change it to uppercase.
if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' {
p = string(p[0]+'A'-'a') + p[1:]
}
return p
}
// clean the path and ensure that a drive letter is upper case (if it exists).
func cleanPath(path string) string {
return driveLetterToUpper(filepath.Clean(path))
}
// deal with case insensitive filesystems and other weirdness
func pathEqual(a, b string) bool {
a = cleanPath(a)
b = cleanPath(b)
return strings.EqualFold(a, b)
}

322
vendor/github.com/tools/godep/vcs.go generated vendored Normal file
View File

@ -0,0 +1,322 @@
package main
import (
"bytes"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"golang.org/x/tools/go/vcs"
)
// VCS represents a version control system.
type VCS struct {
vcs *vcs.Cmd
IdentifyCmd string
DescribeCmd string
DiffCmd string
ListCmd string
RootCmd string
// run in sandbox repos
ExistsCmd string
}
var vcsBzr = &VCS{
vcs: vcs.ByCmd("bzr"),
IdentifyCmd: "version-info --custom --template {revision_id}",
DescribeCmd: "revno", // TODO(kr): find tag names if possible
DiffCmd: "diff -r {rev}",
ListCmd: "ls --from-root -R",
RootCmd: "root",
}
var vcsGit = &VCS{
vcs: vcs.ByCmd("git"),
IdentifyCmd: "rev-parse HEAD",
DescribeCmd: "describe --tags",
DiffCmd: "diff {rev}",
ListCmd: "ls-files --full-name",
RootCmd: "rev-parse --show-cdup",
ExistsCmd: "cat-file -e {rev}",
}
var vcsHg = &VCS{
vcs: vcs.ByCmd("hg"),
IdentifyCmd: "parents --template {node}",
DescribeCmd: "log -r . --template {latesttag}-{latesttagdistance}",
DiffCmd: "diff -r {rev}",
ListCmd: "status --all --no-status",
RootCmd: "root",
ExistsCmd: "cat -r {rev} .",
}
var cmd = map[*vcs.Cmd]*VCS{
vcsBzr.vcs: vcsBzr,
vcsGit.vcs: vcsGit,
vcsHg.vcs: vcsHg,
}
// VCSFromDir returns a VCS value from a directory.
func VCSFromDir(dir, srcRoot string) (*VCS, string, error) {
vcscmd, reporoot, err := vcs.FromDir(dir, srcRoot)
if err != nil {
return nil, "", fmt.Errorf("error while inspecting %q: %v", dir, err)
}
vcsext := cmd[vcscmd]
if vcsext == nil {
return nil, "", fmt.Errorf("%s is unsupported: %s", vcscmd.Name, dir)
}
return vcsext, reporoot, nil
}
// VCSForImportPath returns a VCS value for an import path.
func VCSForImportPath(importPath string) (*VCS, error) {
rr, err := vcs.RepoRootForImportPath(importPath, debug)
if err != nil {
return nil, err
}
vcs := cmd[rr.VCS]
if vcs == nil {
return nil, fmt.Errorf("%s is unsupported: %s", rr.VCS.Name, importPath)
}
return vcs, nil
}
func (v *VCS) identify(dir string) (string, error) {
out, err := v.runOutput(dir, v.IdentifyCmd)
return string(bytes.TrimSpace(out)), err
}
func absRoot(dir, out string) string {
if filepath.IsAbs(out) {
return filepath.Clean(out)
}
return filepath.Join(dir, out)
}
func (v *VCS) root(dir string) (string, error) {
out, err := v.runOutput(dir, v.RootCmd)
return absRoot(dir, string(bytes.TrimSpace(out))), err
}
func (v *VCS) describe(dir, rev string) string {
out, err := v.runOutputVerboseOnly(dir, v.DescribeCmd, "rev", rev)
if err != nil {
return ""
}
return string(bytes.TrimSpace(out))
}
func (v *VCS) isDirty(dir, rev string) bool {
out, err := v.runOutput(dir, v.DiffCmd, "rev", rev)
return err != nil || len(out) != 0
}
type vcsFiles map[string]bool
func (vf vcsFiles) Contains(path string) bool {
// Fast path, we have the path
if vf[path] {
return true
}
// Slow path for case insensitive filesystems
// See #310
for f := range vf {
if pathEqual(f, path) {
return true
}
// git's root command (maybe other vcs as well) resolve symlinks, so try that too
// FIXME: rev-parse --show-cdup + extra logic will fix this for git but also need to validate the other vcs commands. This is maybe temporary.
p, err := filepath.EvalSymlinks(path)
if err != nil {
return false
}
if pathEqual(f, p) {
return true
}
}
// No matches by either method
return false
}
// listFiles tracked by the VCS in the repo that contains dir, converted to absolute path.
func (v *VCS) listFiles(dir string) vcsFiles {
root, err := v.root(dir)
debugln("vcs dir", dir)
debugln("vcs root", root)
ppln(v)
if err != nil {
return nil
}
out, err := v.runOutput(dir, v.ListCmd)
if err != nil {
return nil
}
files := make(vcsFiles)
for _, file := range bytes.Split(out, []byte{'\n'}) {
if len(file) > 0 {
path, err := filepath.Abs(filepath.Join(root, string(file)))
if err != nil {
panic(err) // this should not happen
}
if pathEqual(filepath.Dir(path), dir) {
files[path] = true
}
}
}
return files
}
func (v *VCS) exists(dir, rev string) bool {
err := v.runVerboseOnly(dir, v.ExistsCmd, "rev", rev)
return err == nil
}
// RevSync checks out the revision given by rev in dir.
// The dir must exist and rev must be a valid revision.
func (v *VCS) RevSync(dir, rev string) error {
return v.run(dir, v.vcs.TagSyncCmd, "tag", rev)
}
// run runs the command line cmd in the given directory.
// keyval is a list of key, value pairs. run expands
// instances of {key} in cmd into value, but only after
// splitting cmd into individual arguments.
// If an error occurs, run prints the command line and the
// command's combined stdout+stderr to standard error.
// Otherwise run discards the command's output.
func (v *VCS) run(dir string, cmdline string, kv ...string) error {
_, err := v.run1(dir, cmdline, kv, true)
return err
}
// runVerboseOnly is like run but only generates error output to standard error in verbose mode.
func (v *VCS) runVerboseOnly(dir string, cmdline string, kv ...string) error {
_, err := v.run1(dir, cmdline, kv, false)
return err
}
// runOutput is like run but returns the output of the command.
func (v *VCS) runOutput(dir string, cmdline string, kv ...string) ([]byte, error) {
return v.run1(dir, cmdline, kv, true)
}
// runOutputVerboseOnly is like runOutput but only generates error output to standard error in verbose mode.
func (v *VCS) runOutputVerboseOnly(dir string, cmdline string, kv ...string) ([]byte, error) {
return v.run1(dir, cmdline, kv, false)
}
// run1 is the generalized implementation of run and runOutput.
func (v *VCS) run1(dir string, cmdline string, kv []string, verbose bool) ([]byte, error) {
m := make(map[string]string)
for i := 0; i < len(kv); i += 2 {
m[kv[i]] = kv[i+1]
}
args := strings.Fields(cmdline)
for i, arg := range args {
args[i] = expand(m, arg)
}
_, err := exec.LookPath(v.vcs.Cmd)
if err != nil {
fmt.Fprintf(os.Stderr, "godep: missing %s command.\n", v.vcs.Name)
return nil, err
}
cmd := exec.Command(v.vcs.Cmd, args...)
cmd.Dir = dir
var buf bytes.Buffer
cmd.Stdout = &buf
cmd.Stderr = &buf
err = cmd.Run()
out := buf.Bytes()
if err != nil {
if verbose {
fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.vcs.Cmd, strings.Join(args, " "))
os.Stderr.Write(out)
}
return nil, err
}
return out, nil
}
func expand(m map[string]string, s string) string {
for k, v := range m {
s = strings.Replace(s, "{"+k+"}", v, -1)
}
return s
}
// Mercurial has no command equivalent to git remote add.
// We handle it as a special case in process.
func hgLink(dir, remote, url string) error {
hgdir := filepath.Join(dir, ".hg")
if err := os.MkdirAll(hgdir, 0777); err != nil {
return err
}
path := filepath.Join(hgdir, "hgrc")
f, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
return err
}
fmt.Fprintf(f, "[paths]\n%s = %s\n", remote, url)
return f.Close()
}
func gitDetached(r string) (bool, error) {
o, err := vcsGit.runOutput(r, "status")
if err != nil {
return false, errors.New("unable to determine git status " + err.Error())
}
return bytes.Contains(o, []byte("HEAD detached at")), nil
}
func gitDefaultBranch(r string) (string, error) {
o, err := vcsGit.runOutput(r, "remote show origin")
if err != nil {
return "", errors.New("Running git remote show origin errored with: " + err.Error())
}
return gitDetermineDefaultBranch(r, string(o))
}
func gitDetermineDefaultBranch(r, o string) (string, error) {
e := "Unable to determine HEAD branch: "
hb := "HEAD branch:"
lbcfgp := "Local branch configured for 'git pull':"
s := strings.Index(o, hb)
if s < 0 {
b := strings.Index(o, lbcfgp)
if b < 0 {
return "", errors.New(e + "Remote HEAD is ambiguous. Before godep can pull new commits you will need to:" + `
cd ` + r + `
git checkout <a HEAD branch>
Here is what was reported:
` + o)
}
s = b + len(lbcfgp)
} else {
s += len(hb)
}
f := strings.Fields(o[s:])
if len(f) < 3 {
return "", errors.New(e + "git output too short")
}
return f[0], nil
}
func gitCheckout(r, b string) error {
return vcsGit.run(r, "checkout "+b)
}

63
vendor/github.com/tools/godep/version.go generated vendored Normal file
View File

@ -0,0 +1,63 @@
package main
import (
"fmt"
"log"
"runtime"
"strconv"
"strings"
)
const version = 79
var cmdVersion = &Command{
Name: "version",
Short: "show version info",
Long: `
Displays the version of godep as well as the target OS, architecture and go runtime version.
`,
Run: runVersion,
}
func versionString() string {
return fmt.Sprintf("godep v%d (%s/%s/%s)", version, runtime.GOOS, runtime.GOARCH, runtime.Version())
}
func runVersion(cmd *Command, args []string) {
fmt.Printf("%s\n", versionString())
}
func GoVersionFields(c rune) bool {
return c == 'g' || c == 'o' || c == '.'
}
// isSameOrNewer go version (goA.B)
// go1.6 >= go1.6 == true
// go1.5 >= go1.6 == false
func isSameOrNewer(base, check string) bool {
if base == check {
return true
}
if strings.HasPrefix(check, "devel-") {
return true
}
bp := strings.FieldsFunc(base, GoVersionFields)
cp := strings.FieldsFunc(check, GoVersionFields)
if len(bp) < 2 || len(cp) < 2 {
log.Fatalf("Error comparing %s to %s\n", base, check)
}
if bp[0] == cp[0] { // We only have go version 1 right now
bm, err := strconv.Atoi(bp[1])
// These errors are unlikely and there is nothing nice to do here anyway
if err != nil {
panic(err)
}
cm, err := strconv.Atoi(cp[1])
if err != nil {
panic(err)
}
return cm >= bm
}
return false
}

26
vendor/golang.org/x/tools/go/vcs/BUILD generated vendored Normal file
View File

@ -0,0 +1,26 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"discovery.go",
"env.go",
"http.go",
"vcs.go",
],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

76
vendor/golang.org/x/tools/go/vcs/discovery.go generated vendored Normal file
View File

@ -0,0 +1,76 @@
// Copyright 2012 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 vcs
import (
"encoding/xml"
"fmt"
"io"
"strings"
)
// charsetReader returns a reader for the given charset. Currently
// it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful
// error which is printed by go get, so the user can find why the package
// wasn't downloaded if the encoding is not supported. Note that, in
// order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters
// greater than 0x7f are not rejected).
func charsetReader(charset string, input io.Reader) (io.Reader, error) {
switch strings.ToLower(charset) {
case "ascii":
return input, nil
default:
return nil, fmt.Errorf("can't decode XML document using charset %q", charset)
}
}
// parseMetaGoImports returns meta imports from the HTML in r.
// Parsing ends at the end of the <head> section or the beginning of the <body>.
func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
d := xml.NewDecoder(r)
d.CharsetReader = charsetReader
d.Strict = false
var t xml.Token
for {
t, err = d.Token()
if err != nil {
if err == io.EOF || len(imports) > 0 {
err = nil
}
return
}
if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
return
}
if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
return
}
e, ok := t.(xml.StartElement)
if !ok || !strings.EqualFold(e.Name.Local, "meta") {
continue
}
if attrValue(e.Attr, "name") != "go-import" {
continue
}
if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
imports = append(imports, metaImport{
Prefix: f[0],
VCS: f[1],
RepoRoot: f[2],
})
}
}
}
// attrValue returns the attribute value for the case-insensitive key
// `name', or the empty string if nothing is found.
func attrValue(attrs []xml.Attr, name string) string {
for _, a := range attrs {
if strings.EqualFold(a.Name.Local, name) {
return a.Value
}
}
return ""
}

39
vendor/golang.org/x/tools/go/vcs/env.go generated vendored Normal file
View File

@ -0,0 +1,39 @@
// Copyright 2013 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 vcs
import (
"os"
"strings"
)
// envForDir returns a copy of the environment
// suitable for running in the given directory.
// The environment is the current process's environment
// but with an updated $PWD, so that an os.Getwd in the
// child will be faster.
func envForDir(dir string) []string {
env := os.Environ()
// Internally we only use rooted paths, so dir is rooted.
// Even if dir is not rooted, no harm done.
return mergeEnvLists([]string{"PWD=" + dir}, env)
}
// mergeEnvLists merges the two environment lists such that
// variables with the same name in "in" replace those in "out".
func mergeEnvLists(in, out []string) []string {
NextVar:
for _, inkv := range in {
k := strings.SplitAfterN(inkv, "=", 2)[0]
for i, outkv := range out {
if strings.HasPrefix(outkv, k) {
out[i] = inkv
continue NextVar
}
}
out = append(out, inkv)
}
return out
}

80
vendor/golang.org/x/tools/go/vcs/http.go generated vendored Normal file
View File

@ -0,0 +1,80 @@
// Copyright 2012 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 vcs
import (
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"net/url"
)
// httpClient is the default HTTP client, but a variable so it can be
// changed by tests, without modifying http.DefaultClient.
var httpClient = http.DefaultClient
// httpGET returns the data from an HTTP GET request for the given URL.
func httpGET(url string) ([]byte, error) {
resp, err := httpClient.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return nil, fmt.Errorf("%s: %s", url, resp.Status)
}
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("%s: %v", url, err)
}
return b, nil
}
// httpsOrHTTP returns the body of either the importPath's
// https resource or, if unavailable, the http resource.
func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err error) {
fetch := func(scheme string) (urlStr string, res *http.Response, err error) {
u, err := url.Parse(scheme + "://" + importPath)
if err != nil {
return "", nil, err
}
u.RawQuery = "go-get=1"
urlStr = u.String()
if Verbose {
log.Printf("Fetching %s", urlStr)
}
res, err = httpClient.Get(urlStr)
return
}
closeBody := func(res *http.Response) {
if res != nil {
res.Body.Close()
}
}
urlStr, res, err := fetch("https")
if err != nil || res.StatusCode != 200 {
if Verbose {
if err != nil {
log.Printf("https fetch failed.")
} else {
log.Printf("ignoring https fetch with status code %d", res.StatusCode)
}
}
closeBody(res)
urlStr, res, err = fetch("http")
}
if err != nil {
closeBody(res)
return "", nil, err
}
// Note: accepting a non-200 OK here, so people can serve a
// meta import in their http 404 page.
if Verbose {
log.Printf("Parsing meta tags from %s (status code %d)", urlStr, res.StatusCode)
}
return urlStr, res.Body, nil
}

710
vendor/golang.org/x/tools/go/vcs/vcs.go generated vendored Normal file
View File

@ -0,0 +1,710 @@
// Copyright 2012 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 vcs
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
)
// Verbose enables verbose operation logging.
var Verbose bool
// ShowCmd controls whether VCS commands are printed.
var ShowCmd bool
// A Cmd describes how to use a version control system
// like Mercurial, Git, or Subversion.
type Cmd struct {
Name string
Cmd string // name of binary to invoke command
CreateCmd string // command to download a fresh copy of a repository
DownloadCmd string // command to download updates into an existing repository
TagCmd []TagCmd // commands to list tags
TagLookupCmd []TagCmd // commands to lookup tags before running tagSyncCmd
TagSyncCmd string // command to sync to specific tag
TagSyncDefault string // command to sync to default tag
LogCmd string // command to list repository changelogs in an XML format
Scheme []string
PingCmd string
}
// A TagCmd describes a command to list available tags
// that can be passed to Cmd.TagSyncCmd.
type TagCmd struct {
Cmd string // command to list tags
Pattern string // regexp to extract tags from list
}
// vcsList lists the known version control systems
var vcsList = []*Cmd{
vcsHg,
vcsGit,
vcsSvn,
vcsBzr,
}
// ByCmd returns the version control system for the given
// command name (hg, git, svn, bzr).
func ByCmd(cmd string) *Cmd {
for _, vcs := range vcsList {
if vcs.Cmd == cmd {
return vcs
}
}
return nil
}
// vcsHg describes how to use Mercurial.
var vcsHg = &Cmd{
Name: "Mercurial",
Cmd: "hg",
CreateCmd: "clone -U {repo} {dir}",
DownloadCmd: "pull",
// We allow both tag and branch names as 'tags'
// for selecting a version. This lets people have
// a go.release.r60 branch and a go1 branch
// and make changes in both, without constantly
// editing .hgtags.
TagCmd: []TagCmd{
{"tags", `^(\S+)`},
{"branches", `^(\S+)`},
},
TagSyncCmd: "update -r {tag}",
TagSyncDefault: "update default",
LogCmd: "log --encoding=utf-8 --limit={limit} --template={template}",
Scheme: []string{"https", "http", "ssh"},
PingCmd: "identify {scheme}://{repo}",
}
// vcsGit describes how to use Git.
var vcsGit = &Cmd{
Name: "Git",
Cmd: "git",
CreateCmd: "clone {repo} {dir}",
DownloadCmd: "pull --ff-only",
TagCmd: []TagCmd{
// tags/xxx matches a git tag named xxx
// origin/xxx matches a git branch named xxx on the default remote repository
{"show-ref", `(?:tags|origin)/(\S+)$`},
},
TagLookupCmd: []TagCmd{
{"show-ref tags/{tag} origin/{tag}", `((?:tags|origin)/\S+)$`},
},
TagSyncCmd: "checkout {tag}",
TagSyncDefault: "checkout master",
Scheme: []string{"git", "https", "http", "git+ssh"},
PingCmd: "ls-remote {scheme}://{repo}",
}
// vcsBzr describes how to use Bazaar.
var vcsBzr = &Cmd{
Name: "Bazaar",
Cmd: "bzr",
CreateCmd: "branch {repo} {dir}",
// Without --overwrite bzr will not pull tags that changed.
// Replace by --overwrite-tags after http://pad.lv/681792 goes in.
DownloadCmd: "pull --overwrite",
TagCmd: []TagCmd{{"tags", `^(\S+)`}},
TagSyncCmd: "update -r {tag}",
TagSyncDefault: "update -r revno:-1",
Scheme: []string{"https", "http", "bzr", "bzr+ssh"},
PingCmd: "info {scheme}://{repo}",
}
// vcsSvn describes how to use Subversion.
var vcsSvn = &Cmd{
Name: "Subversion",
Cmd: "svn",
CreateCmd: "checkout {repo} {dir}",
DownloadCmd: "update",
// There is no tag command in subversion.
// The branch information is all in the path names.
LogCmd: "log --xml --limit={limit}",
Scheme: []string{"https", "http", "svn", "svn+ssh"},
PingCmd: "info {scheme}://{repo}",
}
func (v *Cmd) String() string {
return v.Name
}
// run runs the command line cmd in the given directory.
// keyval is a list of key, value pairs. run expands
// instances of {key} in cmd into value, but only after
// splitting cmd into individual arguments.
// If an error occurs, run prints the command line and the
// command's combined stdout+stderr to standard error.
// Otherwise run discards the command's output.
func (v *Cmd) run(dir string, cmd string, keyval ...string) error {
_, err := v.run1(dir, cmd, keyval, true)
return err
}
// runVerboseOnly is like run but only generates error output to standard error in verbose mode.
func (v *Cmd) runVerboseOnly(dir string, cmd string, keyval ...string) error {
_, err := v.run1(dir, cmd, keyval, false)
return err
}
// runOutput is like run but returns the output of the command.
func (v *Cmd) runOutput(dir string, cmd string, keyval ...string) ([]byte, error) {
return v.run1(dir, cmd, keyval, true)
}
// run1 is the generalized implementation of run and runOutput.
func (v *Cmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([]byte, error) {
m := make(map[string]string)
for i := 0; i < len(keyval); i += 2 {
m[keyval[i]] = keyval[i+1]
}
args := strings.Fields(cmdline)
for i, arg := range args {
args[i] = expand(m, arg)
}
_, err := exec.LookPath(v.Cmd)
if err != nil {
fmt.Fprintf(os.Stderr,
"go: missing %s command. See http://golang.org/s/gogetcmd\n",
v.Name)
return nil, err
}
cmd := exec.Command(v.Cmd, args...)
cmd.Dir = dir
cmd.Env = envForDir(cmd.Dir)
if ShowCmd {
fmt.Printf("cd %s\n", dir)
fmt.Printf("%s %s\n", v.Cmd, strings.Join(args, " "))
}
var buf bytes.Buffer
cmd.Stdout = &buf
cmd.Stderr = &buf
err = cmd.Run()
out := buf.Bytes()
if err != nil {
if verbose || Verbose {
fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.Cmd, strings.Join(args, " "))
os.Stderr.Write(out)
}
return nil, err
}
return out, nil
}
// Ping pings the repo to determine if scheme used is valid.
// This repo must be pingable with this scheme and VCS.
func (v *Cmd) Ping(scheme, repo string) error {
return v.runVerboseOnly(".", v.PingCmd, "scheme", scheme, "repo", repo)
}
// Create creates a new copy of repo in dir.
// The parent of dir must exist; dir must not.
func (v *Cmd) Create(dir, repo string) error {
return v.run(".", v.CreateCmd, "dir", dir, "repo", repo)
}
// CreateAtRev creates a new copy of repo in dir at revision rev.
// The parent of dir must exist; dir must not.
// rev must be a valid revision in repo.
func (v *Cmd) CreateAtRev(dir, repo, rev string) error {
if err := v.Create(dir, repo); err != nil {
return err
}
return v.run(dir, v.TagSyncCmd, "tag", rev)
}
// Download downloads any new changes for the repo in dir.
// dir must be a valid VCS repo compatible with v.
func (v *Cmd) Download(dir string) error {
return v.run(dir, v.DownloadCmd)
}
// Tags returns the list of available tags for the repo in dir.
// dir must be a valid VCS repo compatible with v.
func (v *Cmd) Tags(dir string) ([]string, error) {
var tags []string
for _, tc := range v.TagCmd {
out, err := v.runOutput(dir, tc.Cmd)
if err != nil {
return nil, err
}
re := regexp.MustCompile(`(?m-s)` + tc.Pattern)
for _, m := range re.FindAllStringSubmatch(string(out), -1) {
tags = append(tags, m[1])
}
}
return tags, nil
}
// TagSync syncs the repo in dir to the named tag, which is either a
// tag returned by Tags or the empty string (the default tag).
// dir must be a valid VCS repo compatible with v and the tag must exist.
func (v *Cmd) TagSync(dir, tag string) error {
if v.TagSyncCmd == "" {
return nil
}
if tag != "" {
for _, tc := range v.TagLookupCmd {
out, err := v.runOutput(dir, tc.Cmd, "tag", tag)
if err != nil {
return err
}
re := regexp.MustCompile(`(?m-s)` + tc.Pattern)
m := re.FindStringSubmatch(string(out))
if len(m) > 1 {
tag = m[1]
break
}
}
}
if tag == "" && v.TagSyncDefault != "" {
return v.run(dir, v.TagSyncDefault)
}
return v.run(dir, v.TagSyncCmd, "tag", tag)
}
// Log logs the changes for the repo in dir.
// dir must be a valid VCS repo compatible with v.
func (v *Cmd) Log(dir, logTemplate string) ([]byte, error) {
if err := v.Download(dir); err != nil {
return []byte{}, err
}
const N = 50 // how many revisions to grab
return v.runOutput(dir, v.LogCmd, "limit", strconv.Itoa(N), "template", logTemplate)
}
// LogAtRev logs the change for repo in dir at the rev revision.
// dir must be a valid VCS repo compatible with v.
// rev must be a valid revision for the repo in dir.
func (v *Cmd) LogAtRev(dir, rev, logTemplate string) ([]byte, error) {
if err := v.Download(dir); err != nil {
return []byte{}, err
}
// Append revision flag to LogCmd.
logAtRevCmd := v.LogCmd + " --rev=" + rev
return v.runOutput(dir, logAtRevCmd, "limit", strconv.Itoa(1), "template", logTemplate)
}
// A vcsPath describes how to convert an import path into a
// version control system and repository name.
type vcsPath struct {
prefix string // prefix this description applies to
re string // pattern for import path
repo string // repository to use (expand with match of re)
vcs string // version control system to use (expand with match of re)
check func(match map[string]string) error // additional checks
ping bool // ping for scheme to use to download repo
regexp *regexp.Regexp // cached compiled form of re
}
// FromDir inspects dir and its parents to determine the
// version control system and code repository to use.
// On return, root is the import path
// corresponding to the root of the repository.
func FromDir(dir, srcRoot string) (vcs *Cmd, root string, err error) {
// Clean and double-check that dir is in (a subdirectory of) srcRoot.
dir = filepath.Clean(dir)
srcRoot = filepath.Clean(srcRoot)
if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
return nil, "", fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
}
origDir := dir
for len(dir) > len(srcRoot) {
for _, vcs := range vcsList {
if _, err := os.Stat(filepath.Join(dir, "."+vcs.Cmd)); err == nil {
return vcs, filepath.ToSlash(dir[len(srcRoot)+1:]), nil
}
}
// Move to parent.
ndir := filepath.Dir(dir)
if len(ndir) >= len(dir) {
// Shouldn't happen, but just in case, stop.
break
}
dir = ndir
}
return nil, "", fmt.Errorf("directory %q is not using a known version control system", origDir)
}
// RepoRoot represents a version control system, a repo, and a root of
// where to put it on disk.
type RepoRoot struct {
VCS *Cmd
// Repo is the repository URL, including scheme.
Repo string
// Root is the import path corresponding to the root of the
// repository.
Root string
}
// RepoRootForImportPath analyzes importPath to determine the
// version control system, and code repository to use.
func RepoRootForImportPath(importPath string, verbose bool) (*RepoRoot, error) {
rr, err := RepoRootForImportPathStatic(importPath, "")
if err == errUnknownSite {
rr, err = RepoRootForImportDynamic(importPath, verbose)
// RepoRootForImportDynamic returns error detail
// that is irrelevant if the user didn't intend to use a
// dynamic import in the first place.
// Squelch it.
if err != nil {
if Verbose {
log.Printf("import %q: %v", importPath, err)
}
err = fmt.Errorf("unrecognized import path %q", importPath)
}
}
if err == nil && strings.Contains(importPath, "...") && strings.Contains(rr.Root, "...") {
// Do not allow wildcards in the repo root.
rr = nil
err = fmt.Errorf("cannot expand ... in %q", importPath)
}
return rr, err
}
var errUnknownSite = errors.New("dynamic lookup required to find mapping")
// RepoRootForImportPathStatic attempts to map importPath to a
// RepoRoot using the commonly-used VCS hosting sites in vcsPaths
// (github.com/user/dir), or from a fully-qualified importPath already
// containing its VCS type (foo.com/repo.git/dir)
//
// If scheme is non-empty, that scheme is forced.
func RepoRootForImportPathStatic(importPath, scheme string) (*RepoRoot, error) {
if strings.Contains(importPath, "://") {
return nil, fmt.Errorf("invalid import path %q", importPath)
}
for _, srv := range vcsPaths {
if !strings.HasPrefix(importPath, srv.prefix) {
continue
}
m := srv.regexp.FindStringSubmatch(importPath)
if m == nil {
if srv.prefix != "" {
return nil, fmt.Errorf("invalid %s import path %q", srv.prefix, importPath)
}
continue
}
// Build map of named subexpression matches for expand.
match := map[string]string{
"prefix": srv.prefix,
"import": importPath,
}
for i, name := range srv.regexp.SubexpNames() {
if name != "" && match[name] == "" {
match[name] = m[i]
}
}
if srv.vcs != "" {
match["vcs"] = expand(match, srv.vcs)
}
if srv.repo != "" {
match["repo"] = expand(match, srv.repo)
}
if srv.check != nil {
if err := srv.check(match); err != nil {
return nil, err
}
}
vcs := ByCmd(match["vcs"])
if vcs == nil {
return nil, fmt.Errorf("unknown version control system %q", match["vcs"])
}
if srv.ping {
if scheme != "" {
match["repo"] = scheme + "://" + match["repo"]
} else {
for _, scheme := range vcs.Scheme {
if vcs.Ping(scheme, match["repo"]) == nil {
match["repo"] = scheme + "://" + match["repo"]
break
}
}
}
}
rr := &RepoRoot{
VCS: vcs,
Repo: match["repo"],
Root: match["root"],
}
return rr, nil
}
return nil, errUnknownSite
}
// RepoRootForImportDynamic finds a *RepoRoot for a custom domain that's not
// statically known by RepoRootForImportPathStatic.
//
// This handles custom import paths like "name.tld/pkg/foo" or just "name.tld".
func RepoRootForImportDynamic(importPath string, verbose bool) (*RepoRoot, error) {
slash := strings.Index(importPath, "/")
if slash < 0 {
slash = len(importPath)
}
host := importPath[:slash]
if !strings.Contains(host, ".") {
return nil, errors.New("import path doesn't contain a hostname")
}
urlStr, body, err := httpsOrHTTP(importPath)
if err != nil {
return nil, fmt.Errorf("http/https fetch: %v", err)
}
defer body.Close()
imports, err := parseMetaGoImports(body)
if err != nil {
return nil, fmt.Errorf("parsing %s: %v", importPath, err)
}
metaImport, err := matchGoImport(imports, importPath)
if err != nil {
if err != errNoMatch {
return nil, fmt.Errorf("parse %s: %v", urlStr, err)
}
return nil, fmt.Errorf("parse %s: no go-import meta tags", urlStr)
}
if verbose {
log.Printf("get %q: found meta tag %#v at %s", importPath, metaImport, urlStr)
}
// If the import was "uni.edu/bob/project", which said the
// prefix was "uni.edu" and the RepoRoot was "evilroot.com",
// make sure we don't trust Bob and check out evilroot.com to
// "uni.edu" yet (possibly overwriting/preempting another
// non-evil student). Instead, first verify the root and see
// if it matches Bob's claim.
if metaImport.Prefix != importPath {
if verbose {
log.Printf("get %q: verifying non-authoritative meta tag", importPath)
}
urlStr0 := urlStr
urlStr, body, err = httpsOrHTTP(metaImport.Prefix)
if err != nil {
return nil, fmt.Errorf("fetch %s: %v", urlStr, err)
}
imports, err := parseMetaGoImports(body)
if err != nil {
return nil, fmt.Errorf("parsing %s: %v", importPath, err)
}
if len(imports) == 0 {
return nil, fmt.Errorf("fetch %s: no go-import meta tag", urlStr)
}
metaImport2, err := matchGoImport(imports, importPath)
if err != nil || metaImport != metaImport2 {
return nil, fmt.Errorf("%s and %s disagree about go-import for %s", urlStr0, urlStr, metaImport.Prefix)
}
}
if !strings.Contains(metaImport.RepoRoot, "://") {
return nil, fmt.Errorf("%s: invalid repo root %q; no scheme", urlStr, metaImport.RepoRoot)
}
rr := &RepoRoot{
VCS: ByCmd(metaImport.VCS),
Repo: metaImport.RepoRoot,
Root: metaImport.Prefix,
}
if rr.VCS == nil {
return nil, fmt.Errorf("%s: unknown vcs %q", urlStr, metaImport.VCS)
}
return rr, nil
}
// metaImport represents the parsed <meta name="go-import"
// content="prefix vcs reporoot" /> tags from HTML files.
type metaImport struct {
Prefix, VCS, RepoRoot string
}
// errNoMatch is returned from matchGoImport when there's no applicable match.
var errNoMatch = errors.New("no import match")
// matchGoImport returns the metaImport from imports matching importPath.
// An error is returned if there are multiple matches.
// errNoMatch is returned if none match.
func matchGoImport(imports []metaImport, importPath string) (_ metaImport, err error) {
match := -1
for i, im := range imports {
if !strings.HasPrefix(importPath, im.Prefix) {
continue
}
if match != -1 {
err = fmt.Errorf("multiple meta tags match import path %q", importPath)
return
}
match = i
}
if match == -1 {
err = errNoMatch
return
}
return imports[match], nil
}
// expand rewrites s to replace {k} with match[k] for each key k in match.
func expand(match map[string]string, s string) string {
for k, v := range match {
s = strings.Replace(s, "{"+k+"}", v, -1)
}
return s
}
// vcsPaths lists the known vcs paths.
var vcsPaths = []*vcsPath{
// go.googlesource.com
{
prefix: "go.googlesource.com",
re: `^(?P<root>go\.googlesource\.com/[A-Za-z0-9_.\-]+/?)$`,
vcs: "git",
repo: "https://{root}",
check: noVCSSuffix,
},
// Github
{
prefix: "github.com/",
re: `^(?P<root>github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[\p{L}0-9_.\-]+)*$`,
vcs: "git",
repo: "https://{root}",
check: noVCSSuffix,
},
// Bitbucket
{
prefix: "bitbucket.org/",
re: `^(?P<root>bitbucket\.org/(?P<bitname>[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
repo: "https://{root}",
check: bitbucketVCS,
},
// Launchpad
{
prefix: "launchpad.net/",
re: `^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
vcs: "bzr",
repo: "https://{root}",
check: launchpadVCS,
},
// Git at OpenStack
{
prefix: "git.openstack.org",
re: `^(?P<root>git\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(\.git)?(/[A-Za-z0-9_.\-]+)*$`,
vcs: "git",
repo: "https://{root}",
check: noVCSSuffix,
},
// General syntax for any server.
{
re: `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/]*?)\.(?P<vcs>bzr|git|hg|svn))(/[A-Za-z0-9_.\-]+)*$`,
ping: true,
},
}
func init() {
// fill in cached regexps.
// Doing this eagerly discovers invalid regexp syntax
// without having to run a command that needs that regexp.
for _, srv := range vcsPaths {
srv.regexp = regexp.MustCompile(srv.re)
}
}
// noVCSSuffix checks that the repository name does not
// end in .foo for any version control system foo.
// The usual culprit is ".git".
func noVCSSuffix(match map[string]string) error {
repo := match["repo"]
for _, vcs := range vcsList {
if strings.HasSuffix(repo, "."+vcs.Cmd) {
return fmt.Errorf("invalid version control suffix in %s path", match["prefix"])
}
}
return nil
}
// bitbucketVCS determines the version control system for a
// Bitbucket repository, by using the Bitbucket API.
func bitbucketVCS(match map[string]string) error {
if err := noVCSSuffix(match); err != nil {
return err
}
var resp struct {
SCM string `json:"scm"`
}
url := expand(match, "https://api.bitbucket.org/1.0/repositories/{bitname}")
data, err := httpGET(url)
if err != nil {
return err
}
if err := json.Unmarshal(data, &resp); err != nil {
return fmt.Errorf("decoding %s: %v", url, err)
}
if ByCmd(resp.SCM) != nil {
match["vcs"] = resp.SCM
if resp.SCM == "git" {
match["repo"] += ".git"
}
return nil
}
return fmt.Errorf("unable to detect version control system for bitbucket.org/ path")
}
// launchpadVCS solves the ambiguity for "lp.net/project/foo". In this case,
// "foo" could be a series name registered in Launchpad with its own branch,
// and it could also be the name of a directory within the main project
// branch one level up.
func launchpadVCS(match map[string]string) error {
if match["project"] == "" || match["series"] == "" {
return nil
}
_, err := httpGET(expand(match, "https://code.launchpad.net/{project}{series}/.bzr/branch-format"))
if err != nil {
match["root"] = expand(match, "launchpad.net/{project}")
match["repo"] = expand(match, "https://{root}")
}
return nil
}