mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Vendor godep v79 and use it
This commit is contained in:
		
							
								
								
									
										19
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										19
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							@@ -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
									
									
									
								
							
							
						
						
									
										127
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							@@ -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: =
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -58,6 +58,7 @@ fi
 | 
			
		||||
REQUIRED_BINS=(
 | 
			
		||||
  "github.com/onsi/ginkgo/ginkgo"
 | 
			
		||||
  "github.com/jteeuwen/go-bindata/go-bindata"
 | 
			
		||||
  "github.com/tools/godep"
 | 
			
		||||
  "./..."
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
									
									
								
							
							
						
						
									
										4
									
								
								vendor/BUILD
									
									
									
									
										vendored
									
									
								
							@@ -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
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/kr/pretty/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
[568].out
 | 
			
		||||
_go*
 | 
			
		||||
_test*
 | 
			
		||||
_obj
 | 
			
		||||
							
								
								
									
										27
									
								
								vendor/github.com/kr/pretty/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/kr/pretty/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/kr/pretty/License
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/kr/pretty/Readme
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										158
									
								
								vendor/github.com/kr/pretty/diff.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										337
									
								
								vendor/github.com/kr/pretty/formatter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										98
									
								
								vendor/github.com/kr/pretty/pretty.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										41
									
								
								vendor/github.com/kr/pretty/zero.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/kr/text/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/kr/text/License
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/kr/text/Readme
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/kr/text/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										74
									
								
								vendor/github.com/kr/text/indent.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										86
									
								
								vendor/github.com/kr/text/wrap.go
									
									
									
										generated
									
									
										vendored
									
									
										Executable 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
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/tools/godep/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
/godep
 | 
			
		||||
							
								
								
									
										34
									
								
								vendor/github.com/tools/godep/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/tools/godep/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										54
									
								
								vendor/github.com/tools/godep/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										408
									
								
								vendor/github.com/tools/godep/Changelog.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/tools/godep/FAQ.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/tools/godep/License
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										199
									
								
								vendor/github.com/tools/godep/Readme.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,199 @@
 | 
			
		||||
## Godep
 | 
			
		||||
 | 
			
		||||
[](https://travis-ci.org/tools/godep)
 | 
			
		||||
 | 
			
		||||
[](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
									
								
							
							
						
						
									
										128
									
								
								vendor/github.com/tools/godep/dep.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										74
									
								
								vendor/github.com/tools/godep/diff.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/tools/godep/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/tools/godep/errors.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										96
									
								
								vendor/github.com/tools/godep/get.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										129
									
								
								vendor/github.com/tools/godep/go.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										224
									
								
								vendor/github.com/tools/godep/godepfile.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										59
									
								
								vendor/github.com/tools/godep/license.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										604
									
								
								vendor/github.com/tools/godep/list.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										255
									
								
								vendor/github.com/tools/godep/main.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										55
									
								
								vendor/github.com/tools/godep/msg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/tools/godep/path.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										81
									
								
								vendor/github.com/tools/godep/pkg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										195
									
								
								vendor/github.com/tools/godep/restore.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										168
									
								
								vendor/github.com/tools/godep/rewrite.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										612
									
								
								vendor/github.com/tools/godep/save.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										292
									
								
								vendor/github.com/tools/godep/update.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/tools/godep/util.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										322
									
								
								vendor/github.com/tools/godep/vcs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										63
									
								
								vendor/github.com/tools/godep/version.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										26
									
								
								vendor/golang.org/x/tools/go/vcs/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										76
									
								
								vendor/golang.org/x/tools/go/vcs/discovery.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										39
									
								
								vendor/golang.org/x/tools/go/vcs/env.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										80
									
								
								vendor/golang.org/x/tools/go/vcs/http.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										710
									
								
								vendor/golang.org/x/tools/go/vcs/vcs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user