Add self-contained gometalinter build tooling.
This commit is contained in:
27
tools/vendor/github.com/kardianos/govendor/LICENSE
generated
vendored
Normal file
27
tools/vendor/github.com/kardianos/govendor/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2015 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.
|
||||
182
tools/vendor/github.com/kardianos/govendor/README.md
generated
vendored
Normal file
182
tools/vendor/github.com/kardianos/govendor/README.md
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
# The Vendor Tool for Go
|
||||
`go get -u github.com/kardianos/govendor`
|
||||
|
||||
New users please read the [FAQ](doc/faq.md)
|
||||
|
||||
Package developers should read the [developer guide](doc/dev-guide.md).
|
||||
|
||||
For a high level overview read the [whitepaper](doc/whitepaper.md)
|
||||
|
||||
Uses the go1.5+ vendor folder. Multiple workflows supported, single tool.
|
||||
|
||||
[](https://travis-ci.org/kardianos/govendor)
|
||||
[](https://ci.appveyor.com/project/kardianos/govendor/branch/master)
|
||||
[](https://godoc.org/github.com/kardianos/govendor)
|
||||
|
||||
* Copy existing dependencies from $GOPATH with `govendor add/update`.
|
||||
* If you ignore `vendor/*/`, restore dependencies with `govendor sync`.
|
||||
* Pull in new dependencies or update existing dependencies directly from
|
||||
remotes with `govendor fetch`.
|
||||
* Migrate from legacy systems with `govendor migrate`.
|
||||
* Supports Linux, OS X, Windows, probably all others.
|
||||
* Supports git, hg, svn, bzr (must be installed an on the PATH).
|
||||
|
||||
## Notes
|
||||
|
||||
* The project must be within a $GOPATH/src.
|
||||
* If using go1.5, ensure you `set GO15VENDOREXPERIMENT=1`.
|
||||
|
||||
### Quick Start, also see the [FAQ](doc/faq.md)
|
||||
```
|
||||
# Setup your project.
|
||||
cd "my project in GOPATH"
|
||||
govendor init
|
||||
|
||||
# Add existing GOPATH files to vendor.
|
||||
govendor add +external
|
||||
|
||||
# View your work.
|
||||
govendor list
|
||||
|
||||
# Look at what is using a package
|
||||
govendor list -v fmt
|
||||
|
||||
# Specify a specific version or revision to fetch
|
||||
govendor fetch golang.org/x/net/context@a4bbce9fcae005b22ae5443f6af064d80a6f5a55
|
||||
govendor fetch golang.org/x/net/context@v1 # Get latest v1.*.* tag or branch.
|
||||
govendor fetch golang.org/x/net/context@=v1 # Get the tag or branch named "v1".
|
||||
|
||||
# Update a package to latest, given any prior version constraint
|
||||
govendor fetch golang.org/x/net/context
|
||||
|
||||
# Format your repository only
|
||||
govendor fmt +local
|
||||
|
||||
# Build everything in your repository only
|
||||
govendor install +local
|
||||
|
||||
# Test your repository only
|
||||
govendor test +local
|
||||
|
||||
```
|
||||
|
||||
## Sub-commands
|
||||
```
|
||||
init Create the "vendor" folder and the "vendor.json" file.
|
||||
list List and filter existing dependencies and packages.
|
||||
add Add packages from $GOPATH.
|
||||
update Update packages from $GOPATH.
|
||||
remove Remove packages from the vendor folder.
|
||||
status Lists any packages missing, out-of-date, or modified locally.
|
||||
fetch Add new or update vendor folder packages from remote repository.
|
||||
sync Pull packages into vendor folder from remote repository with revisions
|
||||
from vendor.json file.
|
||||
migrate Move packages from a legacy tool to the vendor folder with metadata.
|
||||
get Like "go get" but copies dependencies into a "vendor" folder.
|
||||
license List discovered licenses for the given status or import paths.
|
||||
shell Run a "shell" to make multiple sub-commands more efficient for large
|
||||
projects.
|
||||
|
||||
go tool commands that are wrapped:
|
||||
`+<status>` package selection may be used with them
|
||||
fmt, build, install, clean, test, vet, generate, tool
|
||||
```
|
||||
|
||||
## Status
|
||||
|
||||
Packages can be specified by their "status".
|
||||
```
|
||||
+local (l) packages in your project
|
||||
+external (e) referenced packages in GOPATH but not in current project
|
||||
+vendor (v) packages in the vendor folder
|
||||
+std (s) packages in the standard library
|
||||
|
||||
+excluded (x) external packages explicitly excluded from vendoring
|
||||
+unused (u) packages in the vendor folder, but unused
|
||||
+missing (m) referenced packages but not found
|
||||
|
||||
+program (p) package is a main package
|
||||
|
||||
+outside +external +missing
|
||||
+all +all packages
|
||||
```
|
||||
|
||||
Status can be referenced by their initial letters.
|
||||
|
||||
* `+std` same as `+s`
|
||||
* `+external` same as `+ext` same as `+e`
|
||||
* `+excluded` same as `+exc` same as `+x`
|
||||
|
||||
Status can be logically composed:
|
||||
|
||||
* `+local,program` (local AND program) local packages that are also programs
|
||||
* `+local +vendor` (local OR vendor) local packages or vendor packages
|
||||
* `+vendor,program +std` ((vendor AND program) OR std) vendor packages that are also programs
|
||||
or std library packages
|
||||
* `+vendor,^program` (vendor AND NOT program) vendor package that are not "main" packages.
|
||||
|
||||
## Package specifier
|
||||
|
||||
The full package-spec is:
|
||||
`<path>[::<origin>][{/...|/^}][@[<version-spec>]]`
|
||||
|
||||
Some examples:
|
||||
|
||||
* `github.com/kardianos/govendor` specifies a single package and single folder.
|
||||
* `github.com/kardianos/govendor/...` specifies `govendor` and all referenced
|
||||
packages under that path.
|
||||
* `github.com/kardianos/govendor/^` specifies the `govendor` folder and all
|
||||
sub-folders. Useful for resources or if you don't want a partial repository.
|
||||
* `github.com/kardianos/govendor/^::github.com/myself/govendor` same as above
|
||||
but fetch from user "myself".
|
||||
* `github.com/kardianos/govendor/...@abc12032` all referenced packages at
|
||||
revision `abc12032`.
|
||||
* `github.com/kardianos/govendor/...@v1` same as above, but get the most recent
|
||||
"v1" tag, such as "v1.4.3".
|
||||
* `github.com/kardianos/govendor/...@=v1` get the exact version "v1".
|
||||
|
||||
## Packages and Status
|
||||
|
||||
You may specify multiple package-specs and multiple status in a single command.
|
||||
Commands that accept status and package-spec:
|
||||
|
||||
* list
|
||||
* add
|
||||
* update
|
||||
* remove
|
||||
* fetch
|
||||
|
||||
You may pass arguments to govendor through stdin if the last argument is a "-".
|
||||
For example `echo +vendor | govendor list -` will list all vendor packages.
|
||||
|
||||
## Ignoring build tags and excluding packages
|
||||
Ignoring build tags is opt-out and is designed to be the opposite of the build
|
||||
file directives which are opt-in when specified. Typically a developer will
|
||||
want to support cross platform builds, but selectively opt out of tags, tests,
|
||||
and architectures as desired.
|
||||
|
||||
To ignore additional tags edit the "vendor.json" file and add tag to the vendor
|
||||
"ignore" file field. The field uses spaces to separate tags to ignore.
|
||||
For example the following will ignore both test and appengine files.
|
||||
```
|
||||
{
|
||||
"ignore": "test appengine",
|
||||
}
|
||||
```
|
||||
|
||||
Similarly, some specific packages can be excluded from the vendoring process.
|
||||
These packages will be listed as `excluded` (`x`), and will not be copied to the
|
||||
"vendor" folder when running `govendor add|fetch|update`.
|
||||
|
||||
Any sub-package `foo/bar` of an excluded package `foo` is also excluded (but
|
||||
package `bar/foo` is not). The import dependencies of excluded packages are not
|
||||
listed, and thus not vendored.
|
||||
|
||||
To exclude packages, also use the "ignore" field of the "vendor.json" file.
|
||||
Packages are identified by their name, they should contain a "/" character
|
||||
(possibly at the end):
|
||||
```
|
||||
{
|
||||
"ignore": "test appengine foo/",
|
||||
}
|
||||
```
|
||||
24
tools/vendor/github.com/kardianos/govendor/appveyor.yml
generated
vendored
Normal file
24
tools/vendor/github.com/kardianos/govendor/appveyor.yml
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
version: "{build}"
|
||||
|
||||
os: Windows Server 2012 R2
|
||||
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
GOVERSION: 1.7
|
||||
|
||||
clone_folder: c:\gopath\src\github.com\kardianos\govendor
|
||||
|
||||
install:
|
||||
- mkdir c:\tmp
|
||||
- set TMP=C:\tmp
|
||||
- go version
|
||||
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
|
||||
- rmdir c:\go /s /q
|
||||
- appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-amd64.zip
|
||||
- 7z x go%GOVERSION%.windows-amd64.zip -y -oC:\ > NUL
|
||||
- go version
|
||||
- go env
|
||||
|
||||
build_script:
|
||||
- go test -i ./...
|
||||
- go test ./...
|
||||
154
tools/vendor/github.com/kardianos/govendor/cliprompt/cliPrompt.go
generated
vendored
Normal file
154
tools/vendor/github.com/kardianos/govendor/cliprompt/cliPrompt.go
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
// Copyright 2016 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 cliprompt uses the CLI to prompt for user feedback.
|
||||
package cliprompt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/kardianos/govendor/prompt"
|
||||
|
||||
cp "github.com/Bowery/prompt"
|
||||
)
|
||||
|
||||
type Prompt struct{}
|
||||
|
||||
// Ask the user a question based on the CLI.
|
||||
// TODO (DT): Currently can't handle fetching empty responses do to cancel method.
|
||||
func (p *Prompt) Ask(q *prompt.Question) (prompt.Response, error) {
|
||||
term, err := cp.NewTerminal()
|
||||
if err != nil {
|
||||
return prompt.RespCancel, err
|
||||
}
|
||||
|
||||
if len(q.Error) > 0 {
|
||||
fmt.Fprintf(term.Out, "%s\n\n", q.Error)
|
||||
}
|
||||
|
||||
switch q.Type {
|
||||
default:
|
||||
panic("Unknown question type")
|
||||
case prompt.TypeSelectMultiple:
|
||||
return prompt.RespCancel, fmt.Errorf("Selecting multiple isn't currently supported")
|
||||
case prompt.TypeSelectOne:
|
||||
return getSingle(term, q)
|
||||
}
|
||||
}
|
||||
|
||||
func getSingle(term *cp.Terminal, q *prompt.Question) (prompt.Response, error) {
|
||||
if len(q.Options) == 1 && q.Options[0].Other() {
|
||||
opt := &q.Options[0]
|
||||
opt.Choosen = true
|
||||
return setOther(term, q, opt)
|
||||
}
|
||||
|
||||
choosen := q.AnswerSingle(false)
|
||||
if choosen == nil {
|
||||
return setOption(term, q)
|
||||
}
|
||||
resp, err := setOther(term, q, choosen)
|
||||
if err != nil {
|
||||
return prompt.RespCancel, err
|
||||
}
|
||||
if resp == prompt.RespCancel {
|
||||
choosen.Choosen = false
|
||||
return setOption(term, q)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func setOther(term *cp.Terminal, q *prompt.Question, opt *prompt.Option) (prompt.Response, error) {
|
||||
var blankCount = 0
|
||||
var internalMessage = ""
|
||||
for {
|
||||
// Write out messages
|
||||
if len(internalMessage) > 0 {
|
||||
fmt.Fprintf(term.Out, "%s\n\n", internalMessage)
|
||||
}
|
||||
if len(q.Prompt) > 0 {
|
||||
fmt.Fprintf(term.Out, "%s\n", q.Prompt)
|
||||
}
|
||||
if len(opt.Validation()) > 0 {
|
||||
fmt.Fprintf(term.Out, " ** %s\n", opt.Validation())
|
||||
}
|
||||
// Reset message.
|
||||
internalMessage = ""
|
||||
ln, err := term.Basic(" > ", false)
|
||||
if err != nil {
|
||||
return prompt.RespCancel, err
|
||||
}
|
||||
if len(ln) == 0 && blankCount > 0 {
|
||||
return prompt.RespCancel, nil
|
||||
}
|
||||
if len(ln) == 0 {
|
||||
internalMessage = "Press enter again to cancel"
|
||||
blankCount++
|
||||
continue
|
||||
}
|
||||
blankCount = 0
|
||||
opt.Value = strings.TrimSpace(ln)
|
||||
return prompt.RespAnswer, nil
|
||||
}
|
||||
}
|
||||
|
||||
func setOption(term *cp.Terminal, q *prompt.Question) (prompt.Response, error) {
|
||||
var blankCount = 0
|
||||
var internalMessage = ""
|
||||
for {
|
||||
// Write out messages
|
||||
if len(internalMessage) > 0 {
|
||||
fmt.Fprintf(term.Out, "%s\n\n", internalMessage)
|
||||
}
|
||||
if len(q.Prompt) > 0 {
|
||||
fmt.Fprintf(term.Out, "%s\n", q.Prompt)
|
||||
}
|
||||
for index, opt := range q.Options {
|
||||
fmt.Fprintf(term.Out, " (%d) %s\n", index+1, opt.Prompt())
|
||||
if len(opt.Validation()) > 0 {
|
||||
fmt.Fprintf(term.Out, " ** %s\n", opt.Validation())
|
||||
}
|
||||
}
|
||||
// Reset message.
|
||||
internalMessage = ""
|
||||
ln, err := term.Basic(" # ", false)
|
||||
if err != nil {
|
||||
return prompt.RespCancel, err
|
||||
}
|
||||
if len(ln) == 0 && blankCount > 0 {
|
||||
return prompt.RespCancel, nil
|
||||
}
|
||||
if len(ln) == 0 {
|
||||
internalMessage = "Press enter again to cancel"
|
||||
blankCount++
|
||||
continue
|
||||
}
|
||||
blankCount = 0
|
||||
choice, err := strconv.ParseInt(ln, 10, 32)
|
||||
if err != nil {
|
||||
internalMessage = "Not a valid number"
|
||||
continue
|
||||
}
|
||||
index := int(choice - 1)
|
||||
if index < 0 || index >= len(q.Options) {
|
||||
internalMessage = "Not a valid choice."
|
||||
continue
|
||||
}
|
||||
opt := &q.Options[index]
|
||||
opt.Choosen = true
|
||||
if opt.Other() {
|
||||
res, err := setOther(term, q, opt)
|
||||
if err != nil {
|
||||
return prompt.RespCancel, err
|
||||
}
|
||||
if res == prompt.RespCancel {
|
||||
opt.Choosen = false
|
||||
continue
|
||||
}
|
||||
}
|
||||
return prompt.RespAnswer, nil
|
||||
}
|
||||
}
|
||||
403
tools/vendor/github.com/kardianos/govendor/context/context.go
generated
vendored
Normal file
403
tools/vendor/github.com/kardianos/govendor/context/context.go
generated
vendored
Normal file
@@ -0,0 +1,403 @@
|
||||
// Copyright 2015 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 context gathers the status of packages and stores it in Context.
|
||||
// A new Context needs to be pointed to the root of the project and any
|
||||
// project owned vendor file.
|
||||
package context
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/kardianos/govendor/internal/pathos"
|
||||
os "github.com/kardianos/govendor/internal/vos"
|
||||
"github.com/kardianos/govendor/pkgspec"
|
||||
"github.com/kardianos/govendor/vendorfile"
|
||||
)
|
||||
|
||||
const (
|
||||
debug = false
|
||||
looplimit = 10000
|
||||
|
||||
vendorFilename = "vendor.json"
|
||||
)
|
||||
|
||||
func dprintf(f string, v ...interface{}) {
|
||||
if debug {
|
||||
fmt.Printf(f, v...)
|
||||
}
|
||||
}
|
||||
|
||||
// Context represents the current project context.
|
||||
type Context struct {
|
||||
Logger io.Writer // Write to the verbose log.
|
||||
Insecure bool // Allow insecure network operations
|
||||
|
||||
GopathList []string // List of GOPATHs in environment. Includes "src" dir.
|
||||
Goroot string // The path to the standard library.
|
||||
|
||||
RootDir string // Full path to the project root.
|
||||
RootGopath string // The GOPATH the project is in.
|
||||
RootImportPath string // The import path to the project.
|
||||
|
||||
VendorFile *vendorfile.File
|
||||
VendorFilePath string // File path to vendor file.
|
||||
VendorFolder string // Store vendor packages in this folder.
|
||||
RootToVendorFile string // The relative path from the project root to the vendor file directory.
|
||||
|
||||
VendorDiscoverFolder string // Normally auto-set to "vendor"
|
||||
|
||||
// Package is a map where the import path is the key.
|
||||
// Populated with LoadPackage.
|
||||
Package map[string]*Package
|
||||
// Change to unkown structure (rename). Maybe...
|
||||
|
||||
// MoveRule provides the translation from origional import path to new import path.
|
||||
RewriteRule map[string]string // map[from]to
|
||||
|
||||
Operation []*Operation
|
||||
|
||||
loaded, dirty bool
|
||||
rewriteImports bool
|
||||
|
||||
ignoreTag []string // list of tags to ignore
|
||||
excludePackage []string // list of package prefixes to exclude
|
||||
|
||||
statusCache []StatusItem
|
||||
added map[string]bool
|
||||
}
|
||||
|
||||
// Package maintains information pertaining to a package.
|
||||
type Package struct {
|
||||
OriginDir string // Origin directory
|
||||
Dir string // Physical directory path of the package.
|
||||
|
||||
Status Status // Status and location of the package.
|
||||
*pkgspec.Pkg
|
||||
Local string // Current location of a package relative to $GOPATH/src.
|
||||
Gopath string // Includes trailing "src".
|
||||
Files []*File
|
||||
|
||||
inVendor bool // Different then Status.Location, this is in *any* vendor tree.
|
||||
inTree bool
|
||||
|
||||
ignoreFile []string
|
||||
|
||||
// used in resolveUnknown function. Not persisted.
|
||||
referenced map[string]*Package
|
||||
}
|
||||
|
||||
// File holds a reference to the imports in a file and the file locaiton.
|
||||
type File struct {
|
||||
Package *Package
|
||||
Path string
|
||||
Imports []string
|
||||
|
||||
ImportComment string
|
||||
}
|
||||
|
||||
type RootType byte
|
||||
|
||||
const (
|
||||
RootVendor RootType = iota
|
||||
RootWD
|
||||
RootVendorOrWD
|
||||
)
|
||||
|
||||
func (pkg *Package) String() string {
|
||||
return pkg.Local
|
||||
}
|
||||
|
||||
type packageList []*Package
|
||||
|
||||
func (li packageList) Len() int { return len(li) }
|
||||
func (li packageList) Swap(i, j int) { li[i], li[j] = li[j], li[i] }
|
||||
func (li packageList) Less(i, j int) bool {
|
||||
if li[i].Path != li[j].Path {
|
||||
return li[i].Path < li[j].Path
|
||||
}
|
||||
return li[i].Local < li[j].Local
|
||||
}
|
||||
|
||||
// NewContextWD creates a new context. It looks for a root folder by finding
|
||||
// a vendor file.
|
||||
func NewContextWD(rt RootType) (*Context, error) {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pathToVendorFile := filepath.Join("vendor", vendorFilename)
|
||||
rootIndicator := "vendor"
|
||||
vendorFolder := "vendor"
|
||||
|
||||
root := wd
|
||||
if rt == RootVendor || rt == RootVendorOrWD {
|
||||
tryRoot, err := findRoot(wd, rootIndicator)
|
||||
switch rt {
|
||||
case RootVendor:
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
root = tryRoot
|
||||
case RootVendorOrWD:
|
||||
if err == nil {
|
||||
root = tryRoot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for old vendor file location.
|
||||
oldLocation := filepath.Join(root, vendorFilename)
|
||||
if _, err := os.Stat(oldLocation); err == nil {
|
||||
return nil, ErrOldVersion{`Use the "migrate" command to update.`}
|
||||
}
|
||||
|
||||
return NewContext(root, pathToVendorFile, vendorFolder, false)
|
||||
}
|
||||
|
||||
// NewContext creates new context from a given root folder and vendor file path.
|
||||
// The vendorFolder is where vendor packages should be placed.
|
||||
func NewContext(root, vendorFilePathRel, vendorFolder string, rewriteImports bool) (*Context, error) {
|
||||
dprintf("CTX: %s\n", root)
|
||||
var err error
|
||||
|
||||
// Get GOROOT. First check ENV, then run "go env" and find the GOROOT line.
|
||||
goroot := os.Getenv("GOROOT")
|
||||
if len(goroot) == 0 {
|
||||
// If GOROOT is not set, get from go cmd.
|
||||
cmd := exec.Command("go", "env")
|
||||
var goEnv []byte
|
||||
goEnv, err = cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, line := range strings.Split(string(goEnv), "\n") {
|
||||
if v, ok := pathos.GoEnv("GOROOT", line); ok {
|
||||
goroot = v
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if goroot == "" {
|
||||
return nil, ErrMissingGOROOT
|
||||
}
|
||||
goroot = filepath.Join(goroot, "src")
|
||||
|
||||
// Get the GOPATHs. Prepend the GOROOT to the list.
|
||||
all := os.Getenv("GOPATH")
|
||||
if len(all) == 0 {
|
||||
return nil, ErrMissingGOPATH
|
||||
}
|
||||
gopathList := filepath.SplitList(all)
|
||||
gopathGoroot := make([]string, 0, len(gopathList)+1)
|
||||
gopathGoroot = append(gopathGoroot, goroot)
|
||||
for _, gopath := range gopathList {
|
||||
srcPath := filepath.Join(gopath, "src") + string(filepath.Separator)
|
||||
srcPathEvaled, err := filepath.EvalSymlinks(srcPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gopathGoroot = append(gopathGoroot, srcPath, srcPathEvaled+string(filepath.Separator))
|
||||
}
|
||||
|
||||
rootToVendorFile, _ := filepath.Split(vendorFilePathRel)
|
||||
|
||||
vendorFilePath := filepath.Join(root, vendorFilePathRel)
|
||||
|
||||
ctx := &Context{
|
||||
RootDir: root,
|
||||
GopathList: gopathGoroot,
|
||||
Goroot: goroot,
|
||||
|
||||
VendorFilePath: vendorFilePath,
|
||||
VendorFolder: vendorFolder,
|
||||
RootToVendorFile: pathos.SlashToImportPath(rootToVendorFile),
|
||||
|
||||
VendorDiscoverFolder: "vendor",
|
||||
|
||||
Package: make(map[string]*Package),
|
||||
|
||||
RewriteRule: make(map[string]string, 3),
|
||||
|
||||
rewriteImports: rewriteImports,
|
||||
}
|
||||
|
||||
ctx.RootImportPath, ctx.RootGopath, err = ctx.findImportPath(root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vf, err := readVendorFile(path.Join(ctx.RootImportPath, vendorFolder)+"/", vendorFilePath)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
vf = &vendorfile.File{}
|
||||
}
|
||||
ctx.VendorFile = vf
|
||||
|
||||
ctx.IgnoreBuildAndPackage(vf.Ignore)
|
||||
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// IgnoreBuildAndPackage takes a space separated list of tags or package prefixes
|
||||
// to ignore.
|
||||
// Tags are words, packages are folders, containing or ending with a "/".
|
||||
// "a b c" will ignore tags "a" OR "b" OR "c".
|
||||
// "p/x q/" will ignore packages "p/x" OR "p/x/y" OR "q" OR "q/z", etc.
|
||||
func (ctx *Context) IgnoreBuildAndPackage(ignore string) {
|
||||
ctx.dirty = true
|
||||
ors := strings.Fields(ignore)
|
||||
ctx.ignoreTag = make([]string, 0, len(ors))
|
||||
ctx.excludePackage = make([]string, 0, len(ors))
|
||||
for _, or := range ors {
|
||||
if len(or) == 0 {
|
||||
continue
|
||||
}
|
||||
if strings.Index(or, "/") != -1 {
|
||||
// package
|
||||
ctx.excludePackage = append(ctx.excludePackage, strings.Trim(or, "./"))
|
||||
} else {
|
||||
// tag
|
||||
ctx.ignoreTag = append(ctx.ignoreTag, or)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write to the set io.Writer for logging.
|
||||
func (ctx *Context) Write(s []byte) (int, error) {
|
||||
if ctx.Logger != nil {
|
||||
return ctx.Logger.Write(s)
|
||||
}
|
||||
return len(s), nil
|
||||
}
|
||||
|
||||
// VendorFilePackagePath finds a given vendor file package give the import path.
|
||||
func (ctx *Context) VendorFilePackagePath(path string) *vendorfile.Package {
|
||||
for _, pkg := range ctx.VendorFile.Package {
|
||||
if pkg.Remove {
|
||||
continue
|
||||
}
|
||||
if pkg.Path == path {
|
||||
return pkg
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// findPackageChild finds any package under the current package.
|
||||
// Used for finding tree overlaps.
|
||||
func (ctx *Context) findPackageChild(ck *Package) []*Package {
|
||||
out := make([]*Package, 0, 3)
|
||||
for _, pkg := range ctx.Package {
|
||||
if pkg == ck {
|
||||
continue
|
||||
}
|
||||
if pkg.inVendor == false {
|
||||
continue
|
||||
}
|
||||
if pkg.Status.Presence == PresenceTree {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(pkg.Path, ck.Path+"/") {
|
||||
out = append(out, pkg)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// findPackageParentTree finds any parent tree package that would
|
||||
// include the given canonical path.
|
||||
func (ctx *Context) findPackageParentTree(ck *Package) []string {
|
||||
out := make([]string, 0, 1)
|
||||
for _, pkg := range ctx.Package {
|
||||
if pkg.inVendor == false {
|
||||
continue
|
||||
}
|
||||
if pkg.IncludeTree == false || pkg == ck {
|
||||
continue
|
||||
}
|
||||
// pkg.Path = github.com/usera/pkg, tree = true
|
||||
// ck.Path = github.com/usera/pkg/dance
|
||||
if strings.HasPrefix(ck.Path, pkg.Path+"/") {
|
||||
out = append(out, pkg.Local)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// updatePackageReferences populates the referenced field in each Package.
|
||||
func (ctx *Context) updatePackageReferences() {
|
||||
pathUnderDirLookup := make(map[string]map[string]*Package)
|
||||
findCanonicalUnderDir := func(dir, path string) *Package {
|
||||
if importMap, found := pathUnderDirLookup[dir]; found {
|
||||
if pkg, found2 := importMap[path]; found2 {
|
||||
return pkg
|
||||
}
|
||||
} else {
|
||||
pathUnderDirLookup[dir] = make(map[string]*Package)
|
||||
}
|
||||
for _, pkg := range ctx.Package {
|
||||
if !pkg.inVendor {
|
||||
continue
|
||||
}
|
||||
|
||||
removeFromEnd := len(pkg.Path) + len(ctx.VendorDiscoverFolder) + 2
|
||||
nextLen := len(pkg.Dir) - removeFromEnd
|
||||
if nextLen < 0 {
|
||||
continue
|
||||
}
|
||||
checkDir := pkg.Dir[:nextLen]
|
||||
if !pathos.FileHasPrefix(dir, checkDir) {
|
||||
continue
|
||||
}
|
||||
if pkg.Path != path {
|
||||
continue
|
||||
}
|
||||
pathUnderDirLookup[dir][path] = pkg
|
||||
return pkg
|
||||
}
|
||||
pathUnderDirLookup[dir][path] = nil
|
||||
return nil
|
||||
}
|
||||
for _, pkg := range ctx.Package {
|
||||
pkg.referenced = make(map[string]*Package, len(pkg.referenced))
|
||||
}
|
||||
for _, pkg := range ctx.Package {
|
||||
for _, f := range pkg.Files {
|
||||
for _, imp := range f.Imports {
|
||||
if vpkg := findCanonicalUnderDir(pkg.Dir, imp); vpkg != nil {
|
||||
vpkg.referenced[pkg.Local] = pkg
|
||||
continue
|
||||
}
|
||||
if other, found := ctx.Package[imp]; found {
|
||||
other.referenced[pkg.Local] = pkg
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transfer all references from the child to the top parent.
|
||||
for _, pkg := range ctx.Package {
|
||||
if parentTrees := ctx.findPackageParentTree(pkg); len(parentTrees) > 0 {
|
||||
if parentPkg := ctx.Package[parentTrees[0]]; parentPkg != nil {
|
||||
for opath, opkg := range pkg.referenced {
|
||||
// Do not transfer internal references.
|
||||
if strings.HasPrefix(opkg.Path, parentPkg.Path+"/") {
|
||||
continue
|
||||
}
|
||||
parentPkg.referenced[opath] = opkg
|
||||
}
|
||||
pkg.referenced = make(map[string]*Package, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
203
tools/vendor/github.com/kardianos/govendor/context/copy.go
generated
vendored
Normal file
203
tools/vendor/github.com/kardianos/govendor/context/copy.go
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
// Copyright 2015 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 context
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/kardianos/govendor/internal/pathos"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type fileInfoSort []os.FileInfo
|
||||
|
||||
func (l fileInfoSort) Len() int {
|
||||
return len(l)
|
||||
}
|
||||
func (l fileInfoSort) Less(i, j int) bool {
|
||||
a := l[i]
|
||||
b := l[j]
|
||||
if a.IsDir() == b.IsDir() {
|
||||
return l[i].Name() < l[j].Name()
|
||||
}
|
||||
return !a.IsDir()
|
||||
}
|
||||
func (l fileInfoSort) Swap(i, j int) {
|
||||
l[i], l[j] = l[j], l[i]
|
||||
}
|
||||
|
||||
// CopyPackage copies the files from the srcPath to the destPath, destPath
|
||||
// folder and parents are are created if they don't already exist.
|
||||
func (ctx *Context) CopyPackage(destPath, srcPath, lookRoot, pkgPath string, ignoreFiles []string, tree bool, h hash.Hash, beforeCopy func(deps []string) error) error {
|
||||
if pathos.FileStringEquals(destPath, srcPath) {
|
||||
return fmt.Errorf("Attempting to copy package to same location %q.", destPath)
|
||||
}
|
||||
err := os.MkdirAll(destPath, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Ensure the dest is empty of files.
|
||||
destDir, err := os.Open(destPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ignoreTest := false
|
||||
for _, ignore := range ctx.ignoreTag {
|
||||
if ignore == "test" {
|
||||
ignoreTest = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
fl, err := destDir.Readdir(-1)
|
||||
destDir.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, fi := range fl {
|
||||
if fi.IsDir() {
|
||||
if tree {
|
||||
err = errors.Wrap(os.RemoveAll(filepath.Join(destPath, fi.Name())), "remove all existing tree entries")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
err = errors.Wrap(os.Remove(filepath.Join(destPath, fi.Name())), "remove existing file")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Copy files into dest.
|
||||
srcDir, err := os.Open(srcPath)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "open srcPath directory")
|
||||
}
|
||||
|
||||
fl, err = srcDir.Readdir(-1)
|
||||
srcDir.Close()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "src readdir")
|
||||
}
|
||||
if h != nil {
|
||||
// Write relative path to GOPATH.
|
||||
h.Write([]byte(strings.Trim(pkgPath, "/")))
|
||||
// Sort file list to present a stable hash.
|
||||
sort.Sort(fileInfoSort(fl))
|
||||
}
|
||||
fileLoop:
|
||||
for _, fi := range fl {
|
||||
name := fi.Name()
|
||||
if name[0] == '.' {
|
||||
continue
|
||||
}
|
||||
if fi.IsDir() {
|
||||
isTestdata := name == "testdata"
|
||||
if !tree && !isTestdata {
|
||||
continue
|
||||
}
|
||||
if name[0] == '_' {
|
||||
continue
|
||||
}
|
||||
if ignoreTest {
|
||||
if strings.HasSuffix(name, "_test") || isTestdata {
|
||||
continue
|
||||
}
|
||||
}
|
||||
nextDestPath := filepath.Join(destPath, name)
|
||||
nextSrcPath := filepath.Join(srcPath, name)
|
||||
var nextIgnoreFiles, deps []string
|
||||
if !isTestdata && !strings.Contains(pkgPath, "/testdata/") {
|
||||
nextIgnoreFiles, deps, err = ctx.getIngoreFiles(nextSrcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if beforeCopy != nil {
|
||||
err = beforeCopy(deps)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "beforeCopy")
|
||||
}
|
||||
}
|
||||
err = ctx.CopyPackage(nextDestPath, nextSrcPath, lookRoot, path.Join(pkgPath, name), nextIgnoreFiles, true, h, beforeCopy)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err,
|
||||
"CopyPackage dest=%q src=%q lookRoot=%q pkgPath=%q ignoreFiles=%q tree=%t has beforeCopy=%t",
|
||||
nextDestPath, nextSrcPath, lookRoot, path.Join(pkgPath, name), nextIgnoreFiles, true, beforeCopy != nil,
|
||||
)
|
||||
}
|
||||
continue
|
||||
}
|
||||
for _, ignore := range ignoreFiles {
|
||||
if pathos.FileStringEquals(name, ignore) {
|
||||
continue fileLoop
|
||||
}
|
||||
}
|
||||
if h != nil {
|
||||
h.Write([]byte(name))
|
||||
}
|
||||
err = copyFile(
|
||||
filepath.Join(destPath, name),
|
||||
filepath.Join(srcPath, name),
|
||||
h,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "copyFile dest=%q src=%q", filepath.Join(destPath, name), filepath.Join(srcPath, name))
|
||||
}
|
||||
}
|
||||
|
||||
return errors.Wrapf(licenseCopy(lookRoot, srcPath, filepath.Join(ctx.RootDir, ctx.VendorFolder), pkgPath), "licenseCopy srcPath=%q", srcPath)
|
||||
}
|
||||
|
||||
func copyFile(destPath, srcPath string, h hash.Hash) error {
|
||||
ss, err := os.Stat(srcPath)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "copyFile Stat")
|
||||
}
|
||||
src, err := os.Open(srcPath)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "open src=%q", srcPath)
|
||||
}
|
||||
defer src.Close()
|
||||
// Ensure we are not trying to copy a directory. May happen with symlinks.
|
||||
if st, err := src.Stat(); err == nil {
|
||||
if st.IsDir() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
dest, err := os.Create(destPath)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "create dest=%q", destPath)
|
||||
}
|
||||
|
||||
r := io.Reader(src)
|
||||
|
||||
if h != nil {
|
||||
r = io.TeeReader(src, h)
|
||||
}
|
||||
|
||||
_, err = io.Copy(dest, r)
|
||||
// Close before setting mod and time.
|
||||
dest.Close()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "copy")
|
||||
}
|
||||
err = os.Chmod(destPath, ss.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Chtimes(destPath, ss.ModTime(), ss.ModTime())
|
||||
}
|
||||
80
tools/vendor/github.com/kardianos/govendor/context/err.go
generated
vendored
Normal file
80
tools/vendor/github.com/kardianos/govendor/context/err.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2015 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 context
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrMissingGOROOT returns if the GOROOT was not found.
|
||||
ErrMissingGOROOT = errors.New("Unable to determine GOROOT.")
|
||||
// ErrMissingGOPATH returns if no GOPATH was found.
|
||||
ErrMissingGOPATH = errors.New("Missing GOPATH. Check your environment variable GOPATH.")
|
||||
)
|
||||
|
||||
// ErrNotInGOPATH returns if not currently in the GOPATH.
|
||||
type ErrNotInGOPATH struct {
|
||||
Missing string
|
||||
}
|
||||
|
||||
func (err ErrNotInGOPATH) Error() string {
|
||||
return fmt.Sprintf("Package %q not a go package or not in GOPATH.", err.Missing)
|
||||
}
|
||||
|
||||
// ErrDirtyPackage returns if package is in dirty version control.
|
||||
type ErrDirtyPackage struct {
|
||||
ImportPath string
|
||||
}
|
||||
|
||||
func (err ErrDirtyPackage) Error() string {
|
||||
return fmt.Sprintf("Package %q has uncommitted changes in the vcs.", err.ImportPath)
|
||||
}
|
||||
|
||||
// ErrPackageExists returns if package already exists.
|
||||
type ErrPackageExists struct {
|
||||
Package string
|
||||
}
|
||||
|
||||
func (err ErrPackageExists) Error() string {
|
||||
return fmt.Sprintf("Package %q already in vendor.", err.Package)
|
||||
}
|
||||
|
||||
// ErrMissingVendorFile returns if package already exists.
|
||||
type ErrMissingVendorFile struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func (err ErrMissingVendorFile) Error() string {
|
||||
return fmt.Sprintf("Vendor file at %q not found.", err.Path)
|
||||
}
|
||||
|
||||
// ErrOldVersion returns if vendor file is not in the vendor folder.
|
||||
type ErrOldVersion struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
func (err ErrOldVersion) Error() string {
|
||||
return fmt.Sprintf("The vendor file or is old. %s", err.Message)
|
||||
}
|
||||
|
||||
type ErrTreeChildren struct {
|
||||
path string
|
||||
children []*Package
|
||||
}
|
||||
|
||||
func (err ErrTreeChildren) Error() string {
|
||||
return fmt.Sprintf("Cannot have a sub-tree %q contain sub-packages %q", err.path, err.children)
|
||||
}
|
||||
|
||||
type ErrTreeParents struct {
|
||||
path string
|
||||
parents []string
|
||||
}
|
||||
|
||||
func (err ErrTreeParents) Error() string {
|
||||
return fmt.Sprintf("Cannot add package %q which is already found in sub-tree %q", err.path, err.parents)
|
||||
}
|
||||
291
tools/vendor/github.com/kardianos/govendor/context/fetch.go
generated
vendored
Normal file
291
tools/vendor/github.com/kardianos/govendor/context/fetch.go
generated
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
// Copyright 2016 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 context
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kardianos/govendor/internal/pathos"
|
||||
"github.com/kardianos/govendor/pkgspec"
|
||||
gvvcs "github.com/kardianos/govendor/vcs"
|
||||
"github.com/kardianos/govendor/vendorfile"
|
||||
|
||||
"golang.org/x/tools/go/vcs"
|
||||
)
|
||||
|
||||
type fetcher struct {
|
||||
Ctx *Context
|
||||
CacheRoot string
|
||||
HavePkg map[string]bool
|
||||
}
|
||||
|
||||
func newFetcher(ctx *Context) (*fetcher, error) {
|
||||
// GOPATH here includes the "src" dir, go up one level.
|
||||
cacheRoot := filepath.Join(ctx.RootGopath, "..", ".cache", "govendor")
|
||||
err := os.MkdirAll(cacheRoot, 0700)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &fetcher{
|
||||
Ctx: ctx,
|
||||
CacheRoot: cacheRoot,
|
||||
HavePkg: make(map[string]bool, 30),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// op fetches the repo locally if not already present.
|
||||
// Transform the fetch op into a copy op.
|
||||
func (f *fetcher) op(op *Operation) ([]*Operation, error) {
|
||||
// vcs.ShowCmd = true
|
||||
var nextOps []*Operation
|
||||
vpkg := f.Ctx.VendorFilePackagePath(op.Pkg.Path)
|
||||
if vpkg == nil {
|
||||
return nextOps, fmt.Errorf("Could not find vendor file package for %q. Internal error.", op.Pkg.Path)
|
||||
}
|
||||
|
||||
op.Type = OpCopy
|
||||
ps, err := pkgspec.Parse("", op.Src)
|
||||
if err != nil {
|
||||
return nextOps, err
|
||||
}
|
||||
if len(ps.Version) == 0 {
|
||||
longest := ""
|
||||
for _, pkg := range f.Ctx.Package {
|
||||
if strings.HasPrefix(ps.Path, pkg.Path+"/") && len(pkg.Path) > len(longest) && pkg.HasVersion {
|
||||
longest = pkg.Path
|
||||
ps.Version = pkg.Version
|
||||
ps.HasVersion = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Don't check for bundle, rather check physical directory.
|
||||
// If no repo in dir, clone.
|
||||
// If there is a repo in dir, update to latest.
|
||||
// Get any tags.
|
||||
// If we have a specific revision, update to that revision.
|
||||
|
||||
pkgDir := filepath.Join(f.CacheRoot, pathos.SlashToFilepath(ps.PathOrigin()))
|
||||
sysVcsCmd, repoRoot, err := vcs.FromDir(pkgDir, f.CacheRoot)
|
||||
var vcsCmd *VCSCmd
|
||||
repoRootDir := filepath.Join(f.CacheRoot, repoRoot)
|
||||
if err != nil {
|
||||
rr, err := vcs.RepoRootForImportPath(ps.PathOrigin(), false)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "unrecognized import path") {
|
||||
return nextOps, nil
|
||||
}
|
||||
return nextOps, err
|
||||
}
|
||||
if !f.Ctx.Insecure && !vcsIsSecure(rr.Repo) {
|
||||
return nextOps, fmt.Errorf("repo remote not secure")
|
||||
}
|
||||
|
||||
vcsCmd = updateVcsCmd(rr.VCS)
|
||||
repoRoot = rr.Root
|
||||
repoRootDir = filepath.Join(f.CacheRoot, repoRoot)
|
||||
|
||||
err = vcsCmd.Create(repoRootDir, rr.Repo)
|
||||
if err != nil {
|
||||
return nextOps, fmt.Errorf("failed to create repo %q in %q %v", rr.Repo, repoRootDir, err)
|
||||
}
|
||||
|
||||
} else {
|
||||
vcsCmd = updateVcsCmd(sysVcsCmd)
|
||||
err = vcsCmd.Download(repoRootDir)
|
||||
if err != nil {
|
||||
return nextOps, fmt.Errorf("failed to download repo into %q %v", repoRootDir, err)
|
||||
}
|
||||
}
|
||||
|
||||
revision := ""
|
||||
if ps.HasVersion {
|
||||
switch {
|
||||
case len(ps.Version) == 0:
|
||||
vpkg.Version = ""
|
||||
case isVersion(ps.Version):
|
||||
vpkg.Version = ps.Version
|
||||
default:
|
||||
revision = ps.Version
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case len(revision) == 0 && len(vpkg.Version) > 0:
|
||||
fmt.Fprintf(f.Ctx, "Get version %q@%s\n", vpkg.Path, vpkg.Version)
|
||||
// Get a list of tags, match to version if possible.
|
||||
var tagNames []string
|
||||
tagNames, err = vcsCmd.Tags(repoRootDir)
|
||||
if err != nil {
|
||||
return nextOps, fmt.Errorf("failed to fetch tags %v", err)
|
||||
}
|
||||
labels := make([]Label, len(tagNames))
|
||||
for i, tag := range tagNames {
|
||||
labels[i].Source = LabelTag
|
||||
labels[i].Text = tag
|
||||
}
|
||||
result := FindLabel(vpkg.Version, labels)
|
||||
if result.Source == LabelNone {
|
||||
return nextOps, fmt.Errorf("No label found for specified version %q from %s", vpkg.Version, ps.String())
|
||||
}
|
||||
vpkg.VersionExact = result.Text
|
||||
fmt.Fprintf(f.Ctx, "\tFound exact version %q\n", vpkg.VersionExact)
|
||||
err = vcsCmd.TagSync(repoRootDir, result.Text)
|
||||
if err != nil {
|
||||
return nextOps, fmt.Errorf("failed to sync repo to tag %q %v", result.Text, err)
|
||||
}
|
||||
case len(revision) > 0:
|
||||
fmt.Fprintf(f.Ctx, "Get specific revision %q@%s\n", vpkg.Path, revision)
|
||||
// Get specific version.
|
||||
vpkg.Version = ""
|
||||
vpkg.VersionExact = ""
|
||||
err = vcsCmd.RevisionSync(repoRootDir, revision)
|
||||
if err != nil {
|
||||
return nextOps, fmt.Errorf("failed to sync repo to revision %q %v", revision, err)
|
||||
}
|
||||
default:
|
||||
fmt.Fprintf(f.Ctx, "Get latest revision %q\n", vpkg.Path)
|
||||
// Get latest version.
|
||||
err = vcsCmd.TagSync(repoRootDir, "")
|
||||
if err != nil {
|
||||
return nextOps, fmt.Errorf("failed to sync to latest revision %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// set op.Src to download dir.
|
||||
// /tmp/cache/1/[[github.com/kardianos/govendor]]context
|
||||
op.Src = pkgDir
|
||||
var deps []string
|
||||
op.IgnoreFile, deps, err = f.Ctx.getIngoreFiles(op.Src)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nextOps, nil
|
||||
}
|
||||
return nextOps, fmt.Errorf("failed to get ignore files and deps from %q %v", op.Src, err)
|
||||
}
|
||||
|
||||
f.HavePkg[ps.Path] = true
|
||||
|
||||
// Once downloaded, be sure to set the revision and revisionTime
|
||||
// in the vendor file package.
|
||||
// Find the VCS information.
|
||||
system, err := gvvcs.FindVcs(f.CacheRoot, op.Src)
|
||||
if err != nil {
|
||||
return nextOps, fmt.Errorf("failed to find vcs in %q %v", op.Src, err)
|
||||
}
|
||||
if system != nil {
|
||||
if system.Dirty {
|
||||
return nextOps, ErrDirtyPackage{ps.PathOrigin()}
|
||||
}
|
||||
vpkg.Revision = system.Revision
|
||||
if system.RevisionTime != nil {
|
||||
vpkg.RevisionTime = system.RevisionTime.UTC().Format(time.RFC3339)
|
||||
}
|
||||
}
|
||||
|
||||
processDeps := func(deps []string) error {
|
||||
// Queue up any missing package deps.
|
||||
depLoop:
|
||||
for _, dep := range deps {
|
||||
dep = strings.TrimSpace(dep)
|
||||
if len(dep) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check for deps we already have.
|
||||
if f.HavePkg[dep] {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, test := range f.Ctx.Package {
|
||||
if test.Path == dep {
|
||||
switch test.Status.Location {
|
||||
case LocationVendor, LocationLocal:
|
||||
continue depLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look for std lib deps
|
||||
var yes bool
|
||||
yes, err = f.Ctx.isStdLib(dep)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to check if in stdlib: %v", err)
|
||||
}
|
||||
if yes {
|
||||
continue
|
||||
}
|
||||
|
||||
// Look for tree deps.
|
||||
if op.Pkg.IncludeTree && strings.HasPrefix(dep, op.Pkg.Path+"/") {
|
||||
continue
|
||||
}
|
||||
version := ""
|
||||
hasVersion := false
|
||||
revision := ""
|
||||
for _, vv := range f.Ctx.VendorFile.Package {
|
||||
if vv.Remove {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(dep, vv.Path+"/") {
|
||||
if len(vv.Version) > 0 {
|
||||
version = vv.Version
|
||||
hasVersion = true
|
||||
revision = vv.Revision
|
||||
break
|
||||
}
|
||||
if len(vv.Revision) > 0 {
|
||||
revision = vv.Revision
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f.HavePkg[dep] = true
|
||||
dest := filepath.Join(f.Ctx.RootDir, f.Ctx.VendorFolder, dep)
|
||||
|
||||
// Update vendor file with correct Local field.
|
||||
vp := f.Ctx.VendorFilePackagePath(dep)
|
||||
if vp == nil {
|
||||
vp = &vendorfile.Package{
|
||||
Add: true,
|
||||
Path: dep,
|
||||
Revision: revision,
|
||||
Version: version,
|
||||
}
|
||||
f.Ctx.VendorFile.Package = append(f.Ctx.VendorFile.Package, vp)
|
||||
}
|
||||
if hasVersion {
|
||||
vp.Version = version
|
||||
}
|
||||
if len(vp.Revision) == 0 {
|
||||
vp.Revision = revision
|
||||
}
|
||||
spec := &pkgspec.Pkg{Path: dep, Version: version, HasVersion: hasVersion}
|
||||
nextOps = append(nextOps, &Operation{
|
||||
Type: OpFetch,
|
||||
Pkg: &Package{Pkg: spec},
|
||||
Src: spec.String(),
|
||||
Dest: dest,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
err = processDeps(deps)
|
||||
if err != nil {
|
||||
return nextOps, err
|
||||
}
|
||||
|
||||
err = f.Ctx.copyOperation(op, processDeps)
|
||||
if err != nil {
|
||||
return nextOps, err
|
||||
}
|
||||
|
||||
return nextOps, nil
|
||||
}
|
||||
94
tools/vendor/github.com/kardianos/govendor/context/get.go
generated
vendored
Normal file
94
tools/vendor/github.com/kardianos/govendor/context/get.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright 2016 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 context
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/kardianos/govendor/pkgspec"
|
||||
"golang.org/x/tools/go/vcs"
|
||||
)
|
||||
|
||||
func Get(logger io.Writer, pkgspecName string, insecure bool) (*pkgspec.Pkg, error) {
|
||||
// Get the GOPATHs.
|
||||
all := os.Getenv("GOPATH")
|
||||
if len(all) == 0 {
|
||||
return nil, ErrMissingGOPATH
|
||||
}
|
||||
gopathList := filepath.SplitList(all)
|
||||
gopath := gopathList[0]
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ps, err := pkgspec.Parse(cwd, pkgspecName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ps, get(logger, filepath.Join(gopath, "src"), ps, insecure)
|
||||
}
|
||||
|
||||
func get(logger io.Writer, gopath string, ps *pkgspec.Pkg, insecure bool) error {
|
||||
pkgDir := filepath.Join(gopath, ps.Path)
|
||||
sysVcsCmd, repoRoot, err := vcs.FromDir(pkgDir, gopath)
|
||||
var vcsCmd *VCSCmd
|
||||
repoRootDir := filepath.Join(gopath, repoRoot)
|
||||
if err != nil {
|
||||
rr, err := vcs.RepoRootForImportPath(ps.PathOrigin(), false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !insecure && !vcsIsSecure(rr.Repo) {
|
||||
return fmt.Errorf("repo remote not secure")
|
||||
}
|
||||
|
||||
vcsCmd = updateVcsCmd(rr.VCS)
|
||||
repoRoot = rr.Root
|
||||
repoRootDir = filepath.Join(gopath, repoRoot)
|
||||
|
||||
err = vcsCmd.Create(repoRootDir, rr.Repo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create repo %q in %q %v", rr.Repo, repoRootDir, err)
|
||||
}
|
||||
|
||||
} else {
|
||||
vcsCmd = updateVcsCmd(sysVcsCmd)
|
||||
err = vcsCmd.Download(repoRootDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to download repo into %q %v", repoRootDir, err)
|
||||
}
|
||||
}
|
||||
err = os.MkdirAll(filepath.Join(repoRootDir, "vendor"), 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx, err := NewContext(repoRootDir, filepath.Join("vendor", vendorFilename), "vendor", false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Insecure = insecure
|
||||
ctx.Logger = logger
|
||||
statusList, err := ctx.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
added := make(map[string]bool, len(statusList))
|
||||
for _, item := range statusList {
|
||||
switch item.Status.Location {
|
||||
case LocationExternal, LocationNotFound:
|
||||
if added[item.Pkg.Path] {
|
||||
continue
|
||||
}
|
||||
ctx.ModifyImport(item.Pkg, Fetch)
|
||||
added[item.Pkg.Path] = true
|
||||
}
|
||||
}
|
||||
defer ctx.WriteVendorFile()
|
||||
return ctx.Alter()
|
||||
}
|
||||
240
tools/vendor/github.com/kardianos/govendor/context/label.go
generated
vendored
Normal file
240
tools/vendor/github.com/kardianos/govendor/context/label.go
generated
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
// Copyright 2016 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 context
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type LabelSource byte
|
||||
|
||||
const (
|
||||
LabelNone LabelSource = iota
|
||||
LabelBranch
|
||||
LabelTag
|
||||
)
|
||||
|
||||
func (ls LabelSource) String() string {
|
||||
switch ls {
|
||||
default:
|
||||
panic("unknown label source")
|
||||
case LabelNone:
|
||||
return "none"
|
||||
case LabelBranch:
|
||||
return "branch"
|
||||
case LabelTag:
|
||||
return "tag"
|
||||
}
|
||||
}
|
||||
|
||||
type Label struct {
|
||||
Text string
|
||||
Source LabelSource
|
||||
}
|
||||
|
||||
func (l Label) String() string {
|
||||
return fmt.Sprintf("[%s]%s", l.Source, l.Text)
|
||||
}
|
||||
|
||||
type labelGroup struct {
|
||||
seq string
|
||||
sections []labelSection
|
||||
}
|
||||
|
||||
type labelSection struct {
|
||||
seq string
|
||||
number int64
|
||||
brokenBy rune
|
||||
}
|
||||
|
||||
type labelAnalysis struct {
|
||||
Label Label
|
||||
Groups []labelGroup
|
||||
}
|
||||
|
||||
func (item *labelAnalysis) fillSections(buf *bytes.Buffer) {
|
||||
previousNumber := false
|
||||
number := false
|
||||
|
||||
isBreak := func(r rune) bool {
|
||||
return r == '.'
|
||||
}
|
||||
add := func(r rune, group *labelGroup) {
|
||||
if buf.Len() > 0 {
|
||||
sVal := buf.String()
|
||||
buf.Reset()
|
||||
value, err := strconv.ParseInt(sVal, 10, 64)
|
||||
if err != nil {
|
||||
value = -1
|
||||
}
|
||||
if isBreak(r) == false {
|
||||
r = 0
|
||||
}
|
||||
group.sections = append(group.sections, labelSection{
|
||||
seq: sVal,
|
||||
number: value,
|
||||
brokenBy: r,
|
||||
})
|
||||
}
|
||||
}
|
||||
for _, groupText := range strings.Split(item.Label.Text, "-") {
|
||||
group := labelGroup{
|
||||
seq: groupText,
|
||||
}
|
||||
for index, r := range groupText {
|
||||
number = unicode.IsNumber(r)
|
||||
different := number != previousNumber && index > 0
|
||||
previousNumber = number
|
||||
if isBreak(r) {
|
||||
add(r, &group)
|
||||
continue
|
||||
}
|
||||
if different {
|
||||
add(r, &group)
|
||||
buf.WriteRune(r)
|
||||
continue
|
||||
}
|
||||
buf.WriteRune(r)
|
||||
}
|
||||
add(0, &group)
|
||||
buf.Reset()
|
||||
item.Groups = append(item.Groups, group)
|
||||
}
|
||||
}
|
||||
|
||||
type labelAnalysisList []*labelAnalysis
|
||||
|
||||
func (l labelAnalysisList) Len() int {
|
||||
return len(l)
|
||||
}
|
||||
func (l labelAnalysisList) Swap(i, j int) {
|
||||
l[i], l[j] = l[j], l[i]
|
||||
}
|
||||
|
||||
func (l labelAnalysisList) Less(i, j int) bool {
|
||||
const debug = false
|
||||
df := func(f string, a ...interface{}) {
|
||||
if debug {
|
||||
fmt.Printf(f, a...)
|
||||
}
|
||||
}
|
||||
a := l[i]
|
||||
b := l[j]
|
||||
|
||||
// Want to return the *smaller* of the two group counts.
|
||||
if len(a.Groups) != len(b.Groups) {
|
||||
return len(a.Groups) < len(b.Groups)
|
||||
}
|
||||
|
||||
gct := len(a.Groups)
|
||||
if gct > len(b.Groups) {
|
||||
gct = len(b.Groups)
|
||||
}
|
||||
|
||||
df(":: %s vs %s ::\n", a.Label.Text, b.Label.Text)
|
||||
for ig := 0; ig < gct; ig++ {
|
||||
ga := a.Groups[ig]
|
||||
gb := b.Groups[ig]
|
||||
|
||||
if ga.seq == gb.seq {
|
||||
df("pt 1 %q\n", ga.seq)
|
||||
continue
|
||||
}
|
||||
|
||||
ct := len(ga.sections)
|
||||
if ct > len(gb.sections) {
|
||||
ct = len(gb.sections)
|
||||
}
|
||||
|
||||
// Compare common sections.
|
||||
for i := 0; i < ct; i++ {
|
||||
sa := ga.sections[i]
|
||||
sb := gb.sections[i]
|
||||
|
||||
// Sort each section by number and alpha.
|
||||
if sa.number != sb.number {
|
||||
df("PT A\n")
|
||||
return sa.number > sb.number
|
||||
}
|
||||
if sa.seq != sb.seq {
|
||||
df("PT B\n")
|
||||
return sa.seq > sb.seq
|
||||
}
|
||||
}
|
||||
|
||||
// Sections that we can compare are equal, we want
|
||||
// the longer of the two sections if lengths un-equal.
|
||||
if len(ga.sections) != len(gb.sections) {
|
||||
return len(ga.sections) > len(gb.sections)
|
||||
}
|
||||
}
|
||||
// At this point we have same number of groups and same number
|
||||
// of sections. We can assume the labels are the same.
|
||||
// Check to see if the source of the label is different.
|
||||
if a.Label.Source != b.Label.Source {
|
||||
if a.Label.Source == LabelBranch {
|
||||
df("PT C\n")
|
||||
return true
|
||||
}
|
||||
}
|
||||
// We ran out of things to check. Assume one is not "less" then the other.
|
||||
df("PT D\n")
|
||||
return false
|
||||
}
|
||||
|
||||
// FindLabel matches a single label from a list of labels, given a version.
|
||||
// If the returning label.Source is LabelNone, then no labels match.
|
||||
//
|
||||
// Labels are first broken into sections separated by "-". Shortest wins.
|
||||
// If they have the same number of above sections, then they are compared
|
||||
// further. Number sequences are treated as numbers. Numbers do not need a
|
||||
// separator. The "." is a break point as well.
|
||||
func FindLabel(version string, labels []Label) Label {
|
||||
list := make([]*labelAnalysis, 0, 6)
|
||||
|
||||
exact := strings.HasPrefix(version, "=")
|
||||
version = strings.TrimPrefix(version, "=")
|
||||
|
||||
for _, label := range labels {
|
||||
if exact {
|
||||
if label.Text == version {
|
||||
return label
|
||||
}
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(label.Text, version) == false {
|
||||
continue
|
||||
}
|
||||
remain := strings.TrimPrefix(label.Text, version)
|
||||
if len(remain) > 0 {
|
||||
next := remain[0]
|
||||
// The stated version must either be the full label,
|
||||
// followed by a "." or "-".
|
||||
if next != '.' && next != '-' {
|
||||
continue
|
||||
}
|
||||
}
|
||||
list = append(list, &labelAnalysis{
|
||||
Label: label,
|
||||
Groups: make([]labelGroup, 0, 3),
|
||||
})
|
||||
}
|
||||
if len(list) == 0 {
|
||||
return Label{Source: LabelNone}
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
for _, item := range list {
|
||||
item.fillSections(buf)
|
||||
buf.Reset()
|
||||
}
|
||||
sort.Sort(labelAnalysisList(list))
|
||||
return list[0].Label
|
||||
}
|
||||
217
tools/vendor/github.com/kardianos/govendor/context/license.go
generated
vendored
Normal file
217
tools/vendor/github.com/kardianos/govendor/context/license.go
generated
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
// Copyright 2016 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 context
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/kardianos/govendor/internal/pathos"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type License struct {
|
||||
Path string
|
||||
Filename string
|
||||
Text string
|
||||
}
|
||||
|
||||
type LicenseSort []License
|
||||
|
||||
func (list LicenseSort) Len() int {
|
||||
return len(list)
|
||||
}
|
||||
func (list LicenseSort) Swap(i, j int) {
|
||||
list[i], list[j] = list[j], list[i]
|
||||
}
|
||||
func (list LicenseSort) Less(i, j int) bool {
|
||||
a, b := list[i], list[j]
|
||||
if a.Path == b.Path {
|
||||
return a.Filename < b.Filename
|
||||
}
|
||||
return a.Path < b.Path
|
||||
}
|
||||
|
||||
type licenseSearchType byte
|
||||
|
||||
const (
|
||||
licensePrefix licenseSearchType = iota
|
||||
licenseSubstring
|
||||
licenseSuffix
|
||||
)
|
||||
|
||||
type licenseSearch struct {
|
||||
Text string
|
||||
Search licenseSearchType
|
||||
}
|
||||
|
||||
func (t licenseSearchType) Test(filename, test string) bool {
|
||||
switch t {
|
||||
case licensePrefix:
|
||||
return strings.HasPrefix(filename, test)
|
||||
case licenseSubstring:
|
||||
return strings.Contains(filename, test)
|
||||
case licenseSuffix:
|
||||
return strings.HasSuffix(filename, test)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type licenseTest interface {
|
||||
Test(filename, test string) bool
|
||||
}
|
||||
|
||||
// licenses lists the filenames to copy over to the vendor folder.
|
||||
var licenses = []licenseSearch{
|
||||
{Text: "license", Search: licensePrefix},
|
||||
{Text: "unlicense", Search: licensePrefix},
|
||||
{Text: "copying", Search: licensePrefix},
|
||||
{Text: "copyright", Search: licensePrefix},
|
||||
{Text: "copyright", Search: licensePrefix},
|
||||
{Text: "legal", Search: licenseSubstring},
|
||||
{Text: "notice", Search: licenseSubstring},
|
||||
{Text: "disclaimer", Search: licenseSubstring},
|
||||
{Text: "patent", Search: licenseSubstring},
|
||||
{Text: "third-party", Search: licenseSubstring},
|
||||
{Text: "thirdparty", Search: licenseSubstring},
|
||||
}
|
||||
|
||||
var licenseNotExt = []string{
|
||||
".go",
|
||||
".c",
|
||||
".h",
|
||||
".cpp",
|
||||
".hpp",
|
||||
}
|
||||
|
||||
func isLicenseFile(name string) bool {
|
||||
cname := strings.ToLower(name)
|
||||
for _, X := range licenseNotExt {
|
||||
if filepath.Ext(name) == X {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for _, L := range licenses {
|
||||
if L.Search.Test(cname, L.Text) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// licenseWalk starts in a folder and searches up the folder tree
|
||||
// for license like files. Found files are reported to the found function.
|
||||
func licenseWalk(root, startIn string, found func(folder, name string) error) error {
|
||||
folder := startIn
|
||||
for i := 0; i <= looplimit; i++ {
|
||||
dir, err := os.Open(folder)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fl, err := dir.Readdir(-1)
|
||||
dir.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, fi := range fl {
|
||||
name := fi.Name()
|
||||
if name[0] == '.' {
|
||||
continue
|
||||
}
|
||||
if fi.IsDir() {
|
||||
continue
|
||||
}
|
||||
if !isLicenseFile(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
err = found(folder, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(folder) <= len(root) {
|
||||
return nil
|
||||
}
|
||||
|
||||
nextFolder := filepath.Clean(filepath.Join(folder, ".."))
|
||||
|
||||
if nextFolder == folder {
|
||||
return nil
|
||||
}
|
||||
folder = nextFolder
|
||||
}
|
||||
panic("licenseFind loop limit")
|
||||
}
|
||||
|
||||
// licenseCopy starts the search in the parent of "startIn" folder.
|
||||
// Looks in all sub-folders until root is reached. The root itself is not
|
||||
// searched.
|
||||
func licenseCopy(root, startIn, vendorRoot, pkgPath string) error {
|
||||
addTo, _ := pathos.TrimCommonSuffix(pathos.SlashToFilepath(pkgPath), startIn)
|
||||
startIn = filepath.Clean(filepath.Join(startIn, ".."))
|
||||
return licenseWalk(root, startIn, func(folder, name string) error {
|
||||
srcPath := filepath.Join(folder, name)
|
||||
trimTo := pathos.FileTrimPrefix(getLastVendorRoot(folder), root)
|
||||
|
||||
/*
|
||||
Path: "golang.org/x/tools/go/vcs"
|
||||
Root: "/tmp/govendor-cache280388238/1"
|
||||
StartIn: "/tmp/govendor-cache280388238/1/go/vcs"
|
||||
addTo: "golang.org/x/tools"
|
||||
$PROJ/vendor + addTo + pathos.FileTrimPrefix(folder, root) + "LICENSE"
|
||||
*/
|
||||
destPath := filepath.Join(vendorRoot, addTo, trimTo, name)
|
||||
|
||||
// Only copy if file does not exist.
|
||||
_, err := os.Stat(srcPath)
|
||||
if err != nil {
|
||||
return errors.Errorf("Source license path doesn't exist %q", srcPath)
|
||||
}
|
||||
destDir, _ := filepath.Split(destPath)
|
||||
os.MkdirAll(destDir, 0777)
|
||||
return errors.Wrapf(copyFile(destPath, srcPath, nil), "copyFile dest=%q src=%q", destPath, srcPath)
|
||||
})
|
||||
}
|
||||
|
||||
func getLastVendorRoot(s string) string {
|
||||
w := strings.Replace(s, "\\", "/", -1)
|
||||
ix := strings.LastIndex(w, "/vendor/")
|
||||
if ix < 0 {
|
||||
return s
|
||||
}
|
||||
return s[ix+len("/vendor"):]
|
||||
}
|
||||
|
||||
// LicenseDiscover looks for license files in a given path.
|
||||
func LicenseDiscover(root, startIn, overridePath string, list map[string]License) error {
|
||||
return licenseWalk(root, startIn, func(folder, name string) error {
|
||||
ipath := pathos.SlashToImportPath(strings.TrimPrefix(folder, root))
|
||||
if len(overridePath) > 0 {
|
||||
ipath = overridePath
|
||||
}
|
||||
if _, found := list[ipath]; found {
|
||||
return nil
|
||||
}
|
||||
p := filepath.Join(folder, name)
|
||||
text, err := ioutil.ReadFile(p)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to read license file %q %v", p, err)
|
||||
}
|
||||
key := path.Join(ipath, name)
|
||||
list[key] = License{
|
||||
Path: ipath,
|
||||
Filename: name,
|
||||
Text: string(text),
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
775
tools/vendor/github.com/kardianos/govendor/context/modify.go
generated
vendored
Normal file
775
tools/vendor/github.com/kardianos/govendor/context/modify.go
generated
vendored
Normal file
@@ -0,0 +1,775 @@
|
||||
// Copyright 2015 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 context gathers the status of packages and stores it in Context.
|
||||
// A new Context needs to be pointed to the root of the project and any
|
||||
// project owned vendor file.
|
||||
package context
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"math"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kardianos/govendor/internal/pathos"
|
||||
os "github.com/kardianos/govendor/internal/vos"
|
||||
"github.com/kardianos/govendor/pkgspec"
|
||||
"github.com/kardianos/govendor/vcs"
|
||||
"github.com/kardianos/govendor/vendorfile"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// OperationState is the state of the given package move operation.
|
||||
type OperationState byte
|
||||
|
||||
const (
|
||||
OpReady OperationState = iota // Operation is ready to go.
|
||||
OpIgnore // Operation should be ignored.
|
||||
OpDone // Operation has been completed.
|
||||
)
|
||||
|
||||
type OperationType byte
|
||||
|
||||
const (
|
||||
OpCopy OperationType = iota
|
||||
OpRemove
|
||||
OpFetch
|
||||
)
|
||||
|
||||
func (t OperationType) String() string {
|
||||
switch t {
|
||||
default:
|
||||
panic("unknown operation type")
|
||||
case OpCopy:
|
||||
return "copy"
|
||||
case OpRemove:
|
||||
return "remove"
|
||||
case OpFetch:
|
||||
return "fetch"
|
||||
}
|
||||
}
|
||||
|
||||
// Operation defines how packages should be moved.
|
||||
//
|
||||
// TODO (DT): Remove Pkg field and change Src and Dest to *pkgspec.Pkg types.
|
||||
type Operation struct {
|
||||
Type OperationType
|
||||
|
||||
Pkg *Package
|
||||
|
||||
// Source file path to move packages from.
|
||||
// Must not be empty.
|
||||
Src string
|
||||
|
||||
// Destination file path to move package to.
|
||||
// If Dest if empty the package is removed.
|
||||
Dest string
|
||||
|
||||
// Files to ignore for operation.
|
||||
IgnoreFile []string
|
||||
|
||||
State OperationState
|
||||
|
||||
// True if the operation should treat the package as uncommitted.
|
||||
Uncommitted bool
|
||||
}
|
||||
|
||||
// Conflict reports packages that are scheduled to conflict.
|
||||
type Conflict struct {
|
||||
Canonical string
|
||||
Local string
|
||||
Operation []*Operation
|
||||
OpIndex int
|
||||
Resolved bool
|
||||
}
|
||||
|
||||
// Modify is the type of modifcation to do.
|
||||
type Modify byte
|
||||
|
||||
const (
|
||||
AddUpdate Modify = iota // Add or update the import.
|
||||
Add // Only add, error if it already exists.
|
||||
Update // Only update, error if it doesn't currently exist.
|
||||
Remove // Remove from vendor path.
|
||||
Fetch // Get directly from remote repository.
|
||||
)
|
||||
|
||||
type ModifyOption byte
|
||||
|
||||
const (
|
||||
Uncommitted ModifyOption = iota
|
||||
MatchTree
|
||||
IncludeTree
|
||||
)
|
||||
|
||||
// ModifyStatus adds packages to the context by status.
|
||||
func (ctx *Context) ModifyStatus(sg StatusGroup, mod Modify, mops ...ModifyOption) error {
|
||||
if ctx.added == nil {
|
||||
ctx.added = make(map[string]bool, 10)
|
||||
}
|
||||
|
||||
list, err := ctx.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add packages from status.
|
||||
statusLoop:
|
||||
for _, item := range list {
|
||||
if !item.Status.MatchGroup(sg) {
|
||||
continue
|
||||
}
|
||||
if ctx.added[item.Pkg.PathOrigin()] {
|
||||
continue
|
||||
}
|
||||
// Do not add excluded packages
|
||||
if item.Status.Presence == PresenceExcluded {
|
||||
continue
|
||||
}
|
||||
// Do not attempt to add any existing status items that are
|
||||
// already present in vendor folder.
|
||||
if mod == Add {
|
||||
if ctx.VendorFilePackagePath(item.Pkg.Path) != nil {
|
||||
continue
|
||||
}
|
||||
for _, pkg := range ctx.Package {
|
||||
if pkg.Status.Location == LocationVendor && item.Pkg.Path == pkg.Path {
|
||||
continue statusLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = ctx.modify(item.Pkg, mod, mops)
|
||||
if err != nil {
|
||||
// Skip these errors if from status.
|
||||
if _, is := err.(ErrTreeChildren); is {
|
||||
continue
|
||||
}
|
||||
if _, is := err.(ErrTreeParents); is {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ModifyImport adds the package to the context.
|
||||
func (ctx *Context) ModifyImport(imp *pkgspec.Pkg, mod Modify, mops ...ModifyOption) error {
|
||||
var err error
|
||||
if ctx.added == nil {
|
||||
ctx.added = make(map[string]bool, 10)
|
||||
}
|
||||
// Grap the origin of the pkg spec from the vendor file as needed.
|
||||
if len(imp.Origin) == 0 {
|
||||
for _, vpkg := range ctx.VendorFile.Package {
|
||||
if vpkg.Remove {
|
||||
continue
|
||||
}
|
||||
if vpkg.Path == imp.Path {
|
||||
imp.Origin = vpkg.Origin
|
||||
}
|
||||
}
|
||||
}
|
||||
if !imp.MatchTree {
|
||||
if !ctx.added[imp.PathOrigin()] {
|
||||
err = ctx.modify(imp, mod, mops)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
list, err := ctx.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// If add any matched from "...".
|
||||
match := imp.Path + "/"
|
||||
for _, item := range list {
|
||||
if ctx.added[item.Pkg.PathOrigin()] {
|
||||
continue
|
||||
}
|
||||
if item.Pkg.Path != imp.Path && !strings.HasPrefix(item.Pkg.Path, match) {
|
||||
continue
|
||||
}
|
||||
if imp.HasVersion {
|
||||
item.Pkg.HasVersion = true
|
||||
item.Pkg.Version = imp.Version
|
||||
}
|
||||
item.Pkg.Origin = path.Join(imp.PathOrigin(), strings.TrimPrefix(item.Pkg.Path, imp.Path))
|
||||
err = ctx.modify(item.Pkg, mod, mops)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctx *Context) modify(ps *pkgspec.Pkg, mod Modify, mops []ModifyOption) error {
|
||||
ctx.added[ps.PathOrigin()] = true
|
||||
for _, mop := range mops {
|
||||
switch mop {
|
||||
default:
|
||||
panic("unknown case")
|
||||
case Uncommitted:
|
||||
ps.Uncommitted = true
|
||||
case MatchTree:
|
||||
ps.MatchTree = true
|
||||
case IncludeTree:
|
||||
ps.IncludeTree = true
|
||||
}
|
||||
}
|
||||
var err error
|
||||
if !ctx.loaded || ctx.dirty {
|
||||
err = ctx.loadPackage()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
tree := ps.IncludeTree
|
||||
|
||||
switch mod {
|
||||
// Determine if we can find the source path from an add or update.
|
||||
case Add, Update, AddUpdate:
|
||||
_, _, err = ctx.findImportDir("", ps.PathOrigin())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Does the local import exist?
|
||||
// If so either update or just return.
|
||||
// If not find the disk path from the canonical path, copy locally and rewrite (if needed).
|
||||
var pkg *Package
|
||||
var foundPkg bool
|
||||
if !foundPkg {
|
||||
localPath := path.Join(ctx.RootImportPath, ctx.VendorFolder, ps.Path)
|
||||
pkg, foundPkg = ctx.Package[localPath]
|
||||
foundPkg = foundPkg && pkg.Status.Presence != PresenceMissing
|
||||
}
|
||||
if !foundPkg {
|
||||
pkg, foundPkg = ctx.Package[ps.Path]
|
||||
foundPkg = foundPkg && pkg.Status.Presence != PresenceMissing
|
||||
}
|
||||
if !foundPkg {
|
||||
pkg, foundPkg = ctx.Package[ps.PathOrigin()]
|
||||
foundPkg = foundPkg && pkg.Status.Presence != PresenceMissing
|
||||
}
|
||||
if !foundPkg {
|
||||
pkg, err = ctx.addSingleImport(ctx.RootDir, ps.PathOrigin(), tree)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if pkg == nil {
|
||||
return nil
|
||||
}
|
||||
pkg.Origin = ps.PathOrigin()
|
||||
pkg.Path = ps.Path
|
||||
}
|
||||
|
||||
pkg.HasOrigin = ps.HasOrigin
|
||||
if ps.HasOrigin {
|
||||
pkg.Origin = ps.Origin
|
||||
}
|
||||
|
||||
// Do not support setting "tree" on Remove.
|
||||
if tree && mod != Remove {
|
||||
pkg.IncludeTree = true
|
||||
}
|
||||
|
||||
// A restriction where packages cannot live inside a tree package.
|
||||
if mod != Remove {
|
||||
if pkg.IncludeTree {
|
||||
children := ctx.findPackageChild(pkg)
|
||||
if len(children) > 0 {
|
||||
return ErrTreeChildren{path: pkg.Path, children: children}
|
||||
}
|
||||
}
|
||||
treeParents := ctx.findPackageParentTree(pkg)
|
||||
if len(treeParents) > 0 {
|
||||
return ErrTreeParents{path: pkg.Path, parents: treeParents}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (DT): figure out how to upgrade a non-tree package to a tree package with correct checks.
|
||||
localExists, err := hasGoFileInFolder(filepath.Join(ctx.RootDir, ctx.VendorFolder, pathos.SlashToFilepath(ps.Path)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if mod == Add && localExists {
|
||||
return ErrPackageExists{path.Join(ctx.RootImportPath, ctx.VendorFolder, ps.Path)}
|
||||
}
|
||||
dprintf("stage 2: begin!\n")
|
||||
switch mod {
|
||||
case Add:
|
||||
return ctx.modifyAdd(pkg, ps.Uncommitted)
|
||||
case AddUpdate:
|
||||
return ctx.modifyAdd(pkg, ps.Uncommitted)
|
||||
case Update:
|
||||
return ctx.modifyAdd(pkg, ps.Uncommitted)
|
||||
case Remove:
|
||||
return ctx.modifyRemove(pkg)
|
||||
case Fetch:
|
||||
return ctx.modifyFetch(pkg, ps.Uncommitted, ps.HasVersion, ps.Version)
|
||||
default:
|
||||
panic("mod switch: case not handled")
|
||||
}
|
||||
}
|
||||
|
||||
func (ctx *Context) getIngoreFiles(src string) (ignoreFile, imports []string, err error) {
|
||||
srcDir, err := os.Open(src)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fl, err := srcDir.Readdir(-1)
|
||||
srcDir.Close()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
importMap := make(map[string]struct{}, 12)
|
||||
imports = make([]string, 0, 12)
|
||||
for _, fi := range fl {
|
||||
if fi.IsDir() {
|
||||
continue
|
||||
}
|
||||
if fi.Name()[0] == '.' {
|
||||
continue
|
||||
}
|
||||
tags, fileImports, err := ctx.getFileTags(filepath.Join(src, fi.Name()), nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if tags.IgnoreItem(ctx.ignoreTag...) {
|
||||
ignoreFile = append(ignoreFile, fi.Name())
|
||||
} else {
|
||||
// Only add imports for non-ignored files.
|
||||
for _, imp := range fileImports {
|
||||
importMap[imp] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
for imp := range importMap {
|
||||
imports = append(imports, imp)
|
||||
}
|
||||
return ignoreFile, imports, nil
|
||||
}
|
||||
|
||||
func (ctx *Context) modifyAdd(pkg *Package, uncommitted bool) error {
|
||||
var err error
|
||||
src := pkg.OriginDir
|
||||
dprintf("found import: %q\n", src)
|
||||
// If the canonical package is also the local package, then the package
|
||||
// isn't copied locally already and has already been checked for tags.
|
||||
// If it has been vendored the source still needs to be examined.
|
||||
// Examine here and add to the operations list.
|
||||
var ignoreFile []string
|
||||
if cpkg, found := ctx.Package[pkg.Path]; found {
|
||||
ignoreFile = cpkg.ignoreFile
|
||||
} else {
|
||||
var err error
|
||||
ignoreFile, _, err = ctx.getIngoreFiles(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dest := filepath.Join(ctx.RootDir, ctx.VendorFolder, pathos.SlashToFilepath(pkg.Path))
|
||||
// TODO: This might cause other issues or might be hiding the underlying issues. Examine in depth later.
|
||||
if pathos.FileStringEquals(src, dest) {
|
||||
return nil
|
||||
}
|
||||
dprintf("add op: %q\n", src)
|
||||
|
||||
// Update vendor file with correct Local field.
|
||||
vp := ctx.VendorFilePackagePath(pkg.Path)
|
||||
if vp == nil {
|
||||
vp = &vendorfile.Package{
|
||||
Add: true,
|
||||
Path: pkg.Path,
|
||||
}
|
||||
ctx.VendorFile.Package = append(ctx.VendorFile.Package, vp)
|
||||
}
|
||||
if pkg.IncludeTree {
|
||||
vp.Tree = pkg.IncludeTree
|
||||
}
|
||||
|
||||
if pkg.HasOrigin {
|
||||
vp.Origin = pkg.Origin
|
||||
}
|
||||
if pkg.Path != pkg.Local && pkg.inVendor && vp.Add {
|
||||
vp.Origin = pkg.Local
|
||||
}
|
||||
|
||||
// Find the VCS information.
|
||||
system, err := vcs.FindVcs(pkg.Gopath, src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dirtyAndUncommitted := false
|
||||
if system != nil {
|
||||
if system.Dirty {
|
||||
if !uncommitted {
|
||||
return ErrDirtyPackage{pkg.Path}
|
||||
}
|
||||
dirtyAndUncommitted = true
|
||||
if len(vp.ChecksumSHA1) == 0 {
|
||||
vp.ChecksumSHA1 = "uncommitted/version="
|
||||
}
|
||||
} else {
|
||||
vp.Revision = system.Revision
|
||||
if system.RevisionTime != nil {
|
||||
vp.RevisionTime = system.RevisionTime.UTC().Format(time.RFC3339)
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.Operation = append(ctx.Operation, &Operation{
|
||||
Type: OpCopy,
|
||||
Pkg: pkg,
|
||||
Src: src,
|
||||
Dest: dest,
|
||||
IgnoreFile: ignoreFile,
|
||||
|
||||
Uncommitted: dirtyAndUncommitted,
|
||||
})
|
||||
|
||||
if !ctx.rewriteImports {
|
||||
return nil
|
||||
}
|
||||
|
||||
mvSet := make(map[*Package]struct{}, 3)
|
||||
ctx.makeSet(pkg, mvSet)
|
||||
|
||||
for r := range mvSet {
|
||||
to := path.Join(ctx.RootImportPath, ctx.VendorFolder, r.Path)
|
||||
dprintf("RULE: %s -> %s\n", r.Local, to)
|
||||
ctx.RewriteRule[r.Path] = to
|
||||
ctx.RewriteRule[r.Local] = to
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctx *Context) modifyRemove(pkg *Package) error {
|
||||
// Update vendor file with correct Local field.
|
||||
vp := ctx.VendorFilePackagePath(pkg.Path)
|
||||
if vp != nil {
|
||||
vp.Remove = true
|
||||
}
|
||||
if len(pkg.Dir) == 0 {
|
||||
return nil
|
||||
}
|
||||
// Protect non-project paths from being removed.
|
||||
if pathos.FileHasPrefix(pkg.Dir, ctx.RootDir) == false {
|
||||
return nil
|
||||
}
|
||||
if pkg.Status.Location == LocationLocal {
|
||||
return nil
|
||||
}
|
||||
ctx.Operation = append(ctx.Operation, &Operation{
|
||||
Type: OpRemove,
|
||||
Pkg: pkg,
|
||||
Src: pkg.Dir,
|
||||
Dest: "",
|
||||
})
|
||||
|
||||
if !ctx.rewriteImports {
|
||||
return nil
|
||||
}
|
||||
|
||||
mvSet := make(map[*Package]struct{}, 3)
|
||||
ctx.makeSet(pkg, mvSet)
|
||||
|
||||
for r := range mvSet {
|
||||
dprintf("RULE: %s -> %s\n", r.Local, r.Path)
|
||||
ctx.RewriteRule[r.Local] = r.Path
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// modify function to fetch given package.
|
||||
func (ctx *Context) modifyFetch(pkg *Package, uncommitted, hasVersion bool, version string) error {
|
||||
vp := ctx.VendorFilePackagePath(pkg.Path)
|
||||
if vp == nil {
|
||||
vp = &vendorfile.Package{
|
||||
Add: true,
|
||||
Path: pkg.Path,
|
||||
}
|
||||
ctx.VendorFile.Package = append(ctx.VendorFile.Package, vp)
|
||||
}
|
||||
if hasVersion {
|
||||
vp.Version = version
|
||||
pkg.Version = version
|
||||
pkg.HasVersion = true
|
||||
}
|
||||
if pkg.IncludeTree {
|
||||
vp.Tree = pkg.IncludeTree
|
||||
}
|
||||
pkg.Origin = strings.TrimPrefix(pkg.Origin, ctx.RootImportPath+"/"+ctx.VendorFolder+"/")
|
||||
vp.Origin = pkg.Origin
|
||||
origin := vp.Origin
|
||||
if len(vp.Origin) == 0 {
|
||||
origin = vp.Path
|
||||
}
|
||||
ps := &pkgspec.Pkg{
|
||||
Path: pkg.Path,
|
||||
Origin: origin,
|
||||
HasVersion: hasVersion,
|
||||
Version: version,
|
||||
}
|
||||
dest := filepath.Join(ctx.RootDir, ctx.VendorFolder, pathos.SlashToFilepath(pkg.Path))
|
||||
ctx.Operation = append(ctx.Operation, &Operation{
|
||||
Type: OpFetch,
|
||||
Pkg: pkg,
|
||||
Src: ps.String(),
|
||||
Dest: dest,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check returns any conflicts when more then one package can be moved into
|
||||
// the same path.
|
||||
func (ctx *Context) Check() []*Conflict {
|
||||
// Find duplicate packages that have been marked for moving.
|
||||
findDups := make(map[string][]*Operation, 3) // map[canonical][]local
|
||||
for _, op := range ctx.Operation {
|
||||
if op.State != OpReady {
|
||||
continue
|
||||
}
|
||||
findDups[op.Pkg.Path] = append(findDups[op.Pkg.Path], op)
|
||||
}
|
||||
|
||||
var ret []*Conflict
|
||||
for canonical, lop := range findDups {
|
||||
if len(lop) == 1 {
|
||||
continue
|
||||
}
|
||||
destDir := path.Join(ctx.RootImportPath, ctx.VendorFolder, canonical)
|
||||
ret = append(ret, &Conflict{
|
||||
Canonical: canonical,
|
||||
Local: destDir,
|
||||
Operation: lop,
|
||||
})
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// ResolveApply applies the conflict resolution selected. It chooses the
|
||||
// Operation listed in the OpIndex field.
|
||||
func (ctx *Context) ResloveApply(cc []*Conflict) {
|
||||
for _, c := range cc {
|
||||
if c.Resolved == false {
|
||||
continue
|
||||
}
|
||||
for i, op := range c.Operation {
|
||||
if op.State != OpReady {
|
||||
continue
|
||||
}
|
||||
if i == c.OpIndex {
|
||||
if vp := ctx.VendorFilePackagePath(c.Canonical); vp != nil {
|
||||
vp.Origin = c.Local
|
||||
}
|
||||
continue
|
||||
}
|
||||
op.State = OpIgnore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ResolveAutoLongestPath finds the longest local path in each conflict
|
||||
// and set it to be used.
|
||||
func ResolveAutoLongestPath(cc []*Conflict) []*Conflict {
|
||||
for _, c := range cc {
|
||||
if c.Resolved {
|
||||
continue
|
||||
}
|
||||
longestLen := 0
|
||||
longestIndex := 0
|
||||
for i, op := range c.Operation {
|
||||
if op.State != OpReady {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(op.Pkg.Local) > longestLen {
|
||||
longestLen = len(op.Pkg.Local)
|
||||
longestIndex = i
|
||||
}
|
||||
}
|
||||
c.OpIndex = longestIndex
|
||||
c.Resolved = true
|
||||
}
|
||||
return cc
|
||||
}
|
||||
|
||||
// ResolveAutoShortestPath finds the shortest local path in each conflict
|
||||
// and set it to be used.
|
||||
func ResolveAutoShortestPath(cc []*Conflict) []*Conflict {
|
||||
for _, c := range cc {
|
||||
if c.Resolved {
|
||||
continue
|
||||
}
|
||||
shortestLen := math.MaxInt32
|
||||
shortestIndex := 0
|
||||
for i, op := range c.Operation {
|
||||
if op.State != OpReady {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(op.Pkg.Local) < shortestLen {
|
||||
shortestLen = len(op.Pkg.Local)
|
||||
shortestIndex = i
|
||||
}
|
||||
}
|
||||
c.OpIndex = shortestIndex
|
||||
c.Resolved = true
|
||||
}
|
||||
return cc
|
||||
}
|
||||
|
||||
// ResolveAutoVendorFileOrigin resolves conflicts based on the vendor file
|
||||
// if possible.
|
||||
func (ctx *Context) ResolveAutoVendorFileOrigin(cc []*Conflict) []*Conflict {
|
||||
for _, c := range cc {
|
||||
if c.Resolved {
|
||||
continue
|
||||
}
|
||||
vp := ctx.VendorFilePackagePath(c.Canonical)
|
||||
if vp == nil {
|
||||
continue
|
||||
}
|
||||
// If this was just added, we still can't rely on it.
|
||||
// We still need to ask user.
|
||||
if vp.Add {
|
||||
continue
|
||||
}
|
||||
lookFor := vp.Path
|
||||
if len(vp.Origin) != 0 {
|
||||
lookFor = vp.Origin
|
||||
}
|
||||
for i, op := range c.Operation {
|
||||
if op.State != OpReady {
|
||||
continue
|
||||
}
|
||||
|
||||
if op.Pkg.Local == lookFor {
|
||||
c.OpIndex = i
|
||||
c.Resolved = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return cc
|
||||
}
|
||||
|
||||
// Alter runs any requested package alterations.
|
||||
func (ctx *Context) Alter() error {
|
||||
ctx.added = nil
|
||||
// Ensure there are no conflicts at this time.
|
||||
buf := &bytes.Buffer{}
|
||||
for _, conflict := range ctx.Check() {
|
||||
buf.WriteString(fmt.Sprintf("Different Canonical Packages for %s\n", conflict.Canonical))
|
||||
for _, op := range conflict.Operation {
|
||||
buf.WriteString(fmt.Sprintf("\t%s\n", op.Pkg.Local))
|
||||
}
|
||||
}
|
||||
if buf.Len() != 0 {
|
||||
return errors.New(buf.String())
|
||||
}
|
||||
|
||||
var err error
|
||||
fetch, err := newFetcher(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for {
|
||||
var nextOps []*Operation
|
||||
for _, op := range ctx.Operation {
|
||||
if op.State != OpReady {
|
||||
continue
|
||||
}
|
||||
|
||||
switch op.Type {
|
||||
case OpFetch:
|
||||
var ops []*Operation
|
||||
// Download packages, transform fetch op into a copy op.
|
||||
ops, err = fetch.op(op)
|
||||
if len(ops) > 0 {
|
||||
nextOps = append(nextOps, ops...)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Failed to fetch package %q", op.Pkg.Path)
|
||||
}
|
||||
}
|
||||
if len(nextOps) == 0 {
|
||||
break
|
||||
}
|
||||
ctx.Operation = append(ctx.Operation, nextOps...)
|
||||
}
|
||||
// Move and possibly rewrite packages.
|
||||
for _, op := range ctx.Operation {
|
||||
if op.State != OpReady {
|
||||
continue
|
||||
}
|
||||
pkg := op.Pkg
|
||||
|
||||
if pathos.FileStringEquals(op.Dest, op.Src) {
|
||||
panic("For package " + pkg.Local + " attempt to copy to same location: " + op.Src)
|
||||
}
|
||||
dprintf("MV: %s (%q -> %q)\n", pkg.Local, op.Src, op.Dest)
|
||||
// Copy the package or remove.
|
||||
switch op.Type {
|
||||
default:
|
||||
panic("unknown operation type")
|
||||
case OpRemove:
|
||||
ctx.dirty = true
|
||||
err = RemovePackage(op.Src, filepath.Join(ctx.RootDir, ctx.VendorFolder), pkg.IncludeTree)
|
||||
op.State = OpDone
|
||||
case OpCopy:
|
||||
err = ctx.copyOperation(op, nil)
|
||||
if os.IsNotExist(errors.Cause(err)) {
|
||||
// Ignore packages that don't exist, like appengine.
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Failed to %v package %q -> %q", op.Type, op.Src, op.Dest)
|
||||
}
|
||||
}
|
||||
if ctx.rewriteImports {
|
||||
return ctx.rewrite()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctx *Context) copyOperation(op *Operation, beforeCopy func(deps []string) error) error {
|
||||
var err error
|
||||
pkg := op.Pkg
|
||||
ctx.dirty = true
|
||||
h := sha1.New()
|
||||
var checksum []byte
|
||||
|
||||
root, _ := pathos.TrimCommonSuffix(op.Src, pkg.Path)
|
||||
|
||||
err = ctx.CopyPackage(op.Dest, op.Src, root, pkg.Path, op.IgnoreFile, pkg.IncludeTree, h, beforeCopy)
|
||||
if err == nil && !op.Uncommitted {
|
||||
checksum = h.Sum(nil)
|
||||
vpkg := ctx.VendorFilePackagePath(pkg.Path)
|
||||
if vpkg != nil {
|
||||
vpkg.ChecksumSHA1 = base64.StdEncoding.EncodeToString(checksum)
|
||||
}
|
||||
}
|
||||
op.State = OpDone
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "copy failed. dest: %q, src: %q, pkgPath %q", op.Dest, op.Src, root)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
235
tools/vendor/github.com/kardianos/govendor/context/path.go
generated
vendored
Normal file
235
tools/vendor/github.com/kardianos/govendor/context/path.go
generated
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
// Copyright 2015 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 context
|
||||
|
||||
import (
|
||||
"io"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/kardianos/govendor/internal/pathos"
|
||||
os "github.com/kardianos/govendor/internal/vos"
|
||||
)
|
||||
|
||||
// Import path is in GOROOT or is a special package.
|
||||
func (ctx *Context) isStdLib(importPath string) (yes bool, err error) {
|
||||
if importPath == "builtin" || importPath == "unsafe" || importPath == "C" {
|
||||
yes = true
|
||||
return
|
||||
}
|
||||
|
||||
dir := filepath.Join(ctx.Goroot, importPath)
|
||||
fi, _ := os.Stat(dir)
|
||||
if fi == nil {
|
||||
return
|
||||
}
|
||||
if fi.IsDir() == false {
|
||||
return
|
||||
}
|
||||
|
||||
yes, err = hasGoFileInFolder(dir)
|
||||
return
|
||||
}
|
||||
|
||||
// findImportDir finds the absolute directory. If rel is empty vendor folders
|
||||
// are not looked in.
|
||||
func (ctx *Context) findImportDir(relative, importPath string) (dir, gopath string, err error) {
|
||||
if importPath == "builtin" || importPath == "unsafe" || importPath == "C" {
|
||||
return filepath.Join(ctx.Goroot, importPath), ctx.Goroot, nil
|
||||
}
|
||||
if len(relative) != 0 {
|
||||
rel := relative
|
||||
for {
|
||||
look := filepath.Join(rel, ctx.VendorDiscoverFolder, importPath)
|
||||
nextRel := filepath.Join(rel, "..")
|
||||
if rel == nextRel {
|
||||
break
|
||||
}
|
||||
rel = nextRel
|
||||
fi, err := os.Stat(look)
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if fi.IsDir() == false {
|
||||
continue
|
||||
}
|
||||
for _, gopath = range ctx.GopathList {
|
||||
if pathos.FileHasPrefix(look, gopath) {
|
||||
hasGo, err := hasGoFileInFolder(look)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if hasGo {
|
||||
return look, gopath, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for _, gopath = range ctx.GopathList {
|
||||
dir := filepath.Join(gopath, importPath)
|
||||
fi, err := os.Stat(dir)
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
if fi == nil {
|
||||
continue
|
||||
}
|
||||
if fi.IsDir() == false {
|
||||
continue
|
||||
}
|
||||
|
||||
return dir, gopath, nil
|
||||
}
|
||||
return "", "", ErrNotInGOPATH{importPath}
|
||||
}
|
||||
|
||||
// findImportPath takes a absolute directory and returns the import path and go path.
|
||||
func (ctx *Context) findImportPath(dir string) (importPath, gopath string, err error) {
|
||||
dirResolved, err := filepath.EvalSymlinks(dir)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
dirs := make([]string, 1)
|
||||
dirs = append(dirs, dir)
|
||||
if dir != dirResolved {
|
||||
dirs = append(dirs, dirResolved)
|
||||
}
|
||||
|
||||
for _, gopath := range ctx.GopathList {
|
||||
for _, dir := range dirs {
|
||||
if pathos.FileHasPrefix(dir, gopath) {
|
||||
importPath = pathos.FileTrimPrefix(dir, gopath)
|
||||
importPath = pathos.SlashToImportPath(importPath)
|
||||
return importPath, gopath, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", "", ErrNotInGOPATH{dir}
|
||||
}
|
||||
|
||||
func findRoot(folder, vendorPath string) (root string, err error) {
|
||||
for i := 0; i <= looplimit; i++ {
|
||||
test := filepath.Join(folder, vendorPath)
|
||||
_, err := os.Stat(test)
|
||||
if os.IsNotExist(err) == false {
|
||||
return folder, nil
|
||||
}
|
||||
nextFolder := filepath.Clean(filepath.Join(folder, ".."))
|
||||
|
||||
// Check for root folder.
|
||||
if nextFolder == folder {
|
||||
return "", ErrMissingVendorFile{vendorPath}
|
||||
}
|
||||
folder = nextFolder
|
||||
}
|
||||
panic("findRoot loop limit")
|
||||
}
|
||||
|
||||
func hasGoFileInFolder(folder string) (bool, error) {
|
||||
dir, err := os.Open(folder)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// No folder present, no need to check for files.
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
fl, err := dir.Readdir(-1)
|
||||
dir.Close()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, fi := range fl {
|
||||
if fi.IsDir() == false && filepath.Ext(fi.Name()) == ".go" {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// RemovePackage removes the specified folder files. If folder is empty when
|
||||
// done (no nested folders, remove the folder and any empty parent folders.
|
||||
func RemovePackage(path, root string, tree bool) error {
|
||||
// Ensure the path is empty of files.
|
||||
dir, err := os.Open(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove package files.
|
||||
fl, err := dir.Readdir(-1)
|
||||
dir.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, fi := range fl {
|
||||
fullPath := filepath.Join(path, fi.Name())
|
||||
if fi.IsDir() {
|
||||
if tree {
|
||||
// If tree == true then remove sub-directories too.
|
||||
err = os.RemoveAll(fullPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
err = os.Remove(fullPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Remove empty parent folders.
|
||||
// Ignore errors here.
|
||||
for i := 0; i <= looplimit; i++ {
|
||||
if pathos.FileStringEquals(path, root) {
|
||||
return nil
|
||||
}
|
||||
dir, err := os.Open(path)
|
||||
if err != nil {
|
||||
// fmt.Fprintf(os.Stderr, "Failedd to open directory %q: %v\n", path, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
fl, err := dir.Readdir(1)
|
||||
dir.Close()
|
||||
if err != nil && err != io.EOF {
|
||||
// fmt.Fprintf(os.Stderr, "Failedd to list directory %q: %v\n", path, err)
|
||||
return nil
|
||||
}
|
||||
if len(fl) > 0 {
|
||||
allAreLicense := true
|
||||
for _, fi := range fl {
|
||||
if isLicenseFile(fi.Name()) == false {
|
||||
allAreLicense = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if !allAreLicense {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
err = os.RemoveAll(path)
|
||||
if err != nil {
|
||||
// fmt.Fprintf(os.Stderr, "Failedd to remove empty directory %q: %v\n", path, err)
|
||||
return nil
|
||||
}
|
||||
nextPath := filepath.Clean(filepath.Join(path, ".."))
|
||||
// Check for root.
|
||||
if nextPath == path {
|
||||
return nil
|
||||
}
|
||||
path = nextPath
|
||||
}
|
||||
panic("removePackage() remove parent folders")
|
||||
}
|
||||
550
tools/vendor/github.com/kardianos/govendor/context/resolve.go
generated
vendored
Normal file
550
tools/vendor/github.com/kardianos/govendor/context/resolve.go
generated
vendored
Normal file
@@ -0,0 +1,550 @@
|
||||
// Copyright 2015 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 context
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/kardianos/govendor/internal/pathos"
|
||||
filepath "github.com/kardianos/govendor/internal/vfilepath"
|
||||
os "github.com/kardianos/govendor/internal/vos"
|
||||
"github.com/kardianos/govendor/pkgspec"
|
||||
)
|
||||
|
||||
var knownOS = make(map[string]bool)
|
||||
var knownArch = make(map[string]bool)
|
||||
|
||||
func init() {
|
||||
for _, v := range strings.Fields(goosList) {
|
||||
knownOS[v] = true
|
||||
}
|
||||
for _, v := range strings.Fields(goarchList) {
|
||||
knownArch[v] = true
|
||||
}
|
||||
}
|
||||
|
||||
// loadPackage sets up the context with package information and
|
||||
// is called before any initial operation is performed.
|
||||
func (ctx *Context) loadPackage() error {
|
||||
ctx.loaded = true
|
||||
ctx.dirty = false
|
||||
ctx.statusCache = nil
|
||||
ctx.Package = make(map[string]*Package, len(ctx.Package))
|
||||
// We following the root symlink only in case the root of the repo is symlinked into the GOPATH
|
||||
// This could happen during on some CI that didn't checkout into the GOPATH
|
||||
rootdir, err := filepath.EvalSymlinks(ctx.RootDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = filepath.Walk(rootdir, func(path string, info os.FileInfo, err error) error {
|
||||
if info == nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
// We replace the directory path (followed by the symlink), to the real go repo package name/path
|
||||
// ex : replace "<somewhere>/govendor.source.repo" to "github.com/kardianos/govendor"
|
||||
path = strings.Replace(path, rootdir, ctx.RootDir, 1)
|
||||
_, err = ctx.addFileImports(path, ctx.RootGopath)
|
||||
return err
|
||||
}
|
||||
name := info.Name()
|
||||
// Still go into "_workspace" to aid godep migration.
|
||||
if name == "_workspace" {
|
||||
return nil
|
||||
}
|
||||
switch name[0] {
|
||||
case '.', '_':
|
||||
return filepath.SkipDir
|
||||
}
|
||||
switch name {
|
||||
case "testdata", "node_modules":
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Finally, set any unset status.
|
||||
return ctx.determinePackageStatus()
|
||||
}
|
||||
|
||||
func (ctx *Context) getFileTags(pathname string, f *ast.File) (tags *TagSet, imports []string, err error) {
|
||||
_, filenameExt := filepath.Split(pathname)
|
||||
|
||||
if strings.HasSuffix(pathname, ".go") == false {
|
||||
return nil, nil, nil
|
||||
}
|
||||
if f == nil {
|
||||
f, err = parser.ParseFile(token.NewFileSet(), pathname, nil, parser.ImportsOnly|parser.ParseComments)
|
||||
if f == nil {
|
||||
return nil, nil, nil
|
||||
}
|
||||
}
|
||||
tags = &TagSet{}
|
||||
if strings.HasSuffix(f.Name.Name, "_test") {
|
||||
tags.AddFileTag("test")
|
||||
}
|
||||
pkgNameNormalized := strings.TrimSuffix(f.Name.Name, "_test")
|
||||
|
||||
// Files with package name "documentation" should be ignored, per go build tool.
|
||||
if pkgNameNormalized == "documentation" {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
filename := filenameExt[:len(filenameExt)-3]
|
||||
|
||||
l := strings.Split(filename, "_")
|
||||
|
||||
if n := len(l); n > 1 && l[n-1] == "test" {
|
||||
l = l[:n-1]
|
||||
tags.AddFileTag("test")
|
||||
}
|
||||
n := len(l)
|
||||
if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
|
||||
tags.AddFileTag(l[n-2])
|
||||
tags.AddFileTag(l[n-1])
|
||||
}
|
||||
if n >= 1 && knownOS[l[n-1]] {
|
||||
tags.AddFileTag(l[n-1])
|
||||
}
|
||||
if n >= 1 && knownArch[l[n-1]] {
|
||||
tags.AddFileTag(l[n-1])
|
||||
}
|
||||
|
||||
const buildPrefix = "// +build "
|
||||
for _, cc := range f.Comments {
|
||||
for _, c := range cc.List {
|
||||
if strings.HasPrefix(c.Text, buildPrefix) {
|
||||
text := strings.TrimPrefix(c.Text, buildPrefix)
|
||||
tags.AddBuildTags(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
imports = make([]string, 0, len(f.Imports))
|
||||
|
||||
for i := range f.Imports {
|
||||
imp := f.Imports[i].Path.Value
|
||||
imp, err = strconv.Unquote(imp)
|
||||
if err != nil {
|
||||
// Best errort
|
||||
continue
|
||||
}
|
||||
imports = append(imports, imp)
|
||||
}
|
||||
|
||||
return tags, imports, nil
|
||||
}
|
||||
|
||||
// addFileImports is called from loadPackage and resolveUnknown.
|
||||
func (ctx *Context) addFileImports(pathname, gopath string) (*Package, error) {
|
||||
dir, filenameExt := filepath.Split(pathname)
|
||||
importPath := pathos.FileTrimPrefix(dir, gopath)
|
||||
importPath = pathos.SlashToImportPath(importPath)
|
||||
importPath = strings.Trim(importPath, "/")
|
||||
|
||||
if strings.HasSuffix(pathname, ".go") == false {
|
||||
return nil, nil
|
||||
}
|
||||
// No need to add the same file more then once.
|
||||
for _, pkg := range ctx.Package {
|
||||
if pathos.FileStringEquals(pkg.Dir, dir) == false {
|
||||
continue
|
||||
}
|
||||
for _, f := range pkg.Files {
|
||||
if pathos.FileStringEquals(f.Path, pathname) {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
for _, f := range pkg.ignoreFile {
|
||||
if pathos.FileStringEquals(f, filenameExt) {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ignore error here and continue on best effort.
|
||||
f, _ := parser.ParseFile(token.NewFileSet(), pathname, nil, parser.ImportsOnly|parser.ParseComments)
|
||||
if f == nil {
|
||||
return nil, nil
|
||||
}
|
||||
pkgNameNormalized := strings.TrimSuffix(f.Name.Name, "_test")
|
||||
|
||||
// Files with package name "documentation" should be ignored, per go build tool.
|
||||
if pkgNameNormalized == "documentation" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
tags, _, err := ctx.getFileTags(pathname, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If file has "// +build ignore", can mix package main with normal package.
|
||||
// For now, just ignore ignored packages.
|
||||
if tags.IgnoreItem() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
pkg, found := ctx.Package[importPath]
|
||||
if !found {
|
||||
status := Status{
|
||||
Type: TypePackage,
|
||||
Location: LocationUnknown,
|
||||
Presence: PresenceFound,
|
||||
}
|
||||
if pkgNameNormalized == "main" {
|
||||
status.Type = TypeProgram
|
||||
}
|
||||
pkg = ctx.setPackage(dir, importPath, importPath, gopath, status)
|
||||
ctx.Package[importPath] = pkg
|
||||
}
|
||||
if pkg.Status.Location != LocationLocal {
|
||||
if tags.IgnoreItem(ctx.ignoreTag...) {
|
||||
pkg.ignoreFile = append(pkg.ignoreFile, filenameExt)
|
||||
return pkg, nil
|
||||
}
|
||||
// package excluded if non-local && same name or sub-package of an excluded package
|
||||
for _, exclude := range ctx.excludePackage {
|
||||
if importPath == exclude || strings.HasPrefix(importPath, exclude+"/") {
|
||||
pkg.Status.Presence = PresenceExcluded
|
||||
}
|
||||
}
|
||||
}
|
||||
pf := &File{
|
||||
Package: pkg,
|
||||
Path: pathname,
|
||||
Imports: make([]string, len(f.Imports)),
|
||||
}
|
||||
pkg.Files = append(pkg.Files, pf)
|
||||
for i := range f.Imports {
|
||||
imp := f.Imports[i].Path.Value
|
||||
imp, err = strconv.Unquote(imp)
|
||||
if err != nil {
|
||||
// Best effort only.
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(imp, "./") {
|
||||
imp = path.Join(importPath, imp)
|
||||
}
|
||||
pf.Imports[i] = imp
|
||||
if pkg.Status.Presence != PresenceExcluded { // do not add package imports if it was explicitly excluded
|
||||
_, err = ctx.addSingleImport(pkg.Dir, imp, pkg.IncludeTree)
|
||||
if err != nil {
|
||||
return pkg, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Record any import comment for file.
|
||||
var ic *ast.Comment
|
||||
if f.Name != nil {
|
||||
pos := f.Name.Pos()
|
||||
big:
|
||||
// Find the next comment after the package name.
|
||||
for _, cblock := range f.Comments {
|
||||
for _, c := range cblock.List {
|
||||
if c.Pos() > pos {
|
||||
ic = c
|
||||
break big
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ic != nil {
|
||||
// If it starts with the import text, assume it is the import comment.
|
||||
if index := strings.Index(ic.Text, " import "); index > 0 && index < 5 {
|
||||
q := strings.TrimSpace(ic.Text[index+len(" import "):])
|
||||
pf.ImportComment, err = strconv.Unquote(q)
|
||||
if err != nil {
|
||||
pf.ImportComment = q
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pkg, nil
|
||||
}
|
||||
|
||||
func (ctx *Context) setPackage(dir, canonical, local, gopath string, status Status) *Package {
|
||||
if pkg, exists := ctx.Package[local]; exists {
|
||||
return pkg
|
||||
}
|
||||
at := 0
|
||||
vMiddle := "/" + pathos.SlashToImportPath(ctx.VendorDiscoverFolder) + "/"
|
||||
vStart := pathos.SlashToImportPath(ctx.VendorDiscoverFolder) + "/"
|
||||
switch {
|
||||
case strings.Contains(canonical, vMiddle):
|
||||
at = strings.LastIndex(canonical, vMiddle) + len(vMiddle)
|
||||
case strings.HasPrefix(canonical, vStart):
|
||||
at = strings.LastIndex(canonical, vStart) + len(vStart)
|
||||
}
|
||||
|
||||
originDir := dir
|
||||
inVendor := false
|
||||
tree := false
|
||||
origin := ""
|
||||
if at > 0 {
|
||||
canonical = canonical[at:]
|
||||
inVendor = true
|
||||
if status.Location == LocationUnknown {
|
||||
p := path.Join(ctx.RootImportPath, ctx.VendorDiscoverFolder)
|
||||
if strings.HasPrefix(local, p) {
|
||||
status.Location = LocationVendor
|
||||
od, _, err := ctx.findImportDir("", canonical)
|
||||
if err == nil {
|
||||
originDir = od
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if vp := ctx.VendorFilePackagePath(canonical); vp != nil {
|
||||
tree = vp.Tree
|
||||
origin = vp.Origin
|
||||
}
|
||||
// Set originDir correctly if origin is set.
|
||||
if len(origin) > 0 {
|
||||
od, _, err := ctx.findImportDir("", origin)
|
||||
if err == nil {
|
||||
originDir = od
|
||||
}
|
||||
}
|
||||
if status.Location == LocationUnknown && filepath.HasPrefixDir(canonical, ctx.RootImportPath) {
|
||||
status.Location = LocationLocal
|
||||
}
|
||||
spec, err := pkgspec.Parse("", canonical)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(origin) > 0 && origin != canonical {
|
||||
spec.Origin = origin
|
||||
}
|
||||
spec.IncludeTree = tree
|
||||
pkg := &Package{
|
||||
OriginDir: originDir,
|
||||
Dir: dir,
|
||||
Pkg: spec,
|
||||
Local: local,
|
||||
Gopath: gopath,
|
||||
Status: status,
|
||||
inVendor: inVendor,
|
||||
}
|
||||
ctx.Package[local] = pkg
|
||||
return pkg
|
||||
}
|
||||
|
||||
var testNeedsSortOrder = false
|
||||
|
||||
func (ctx *Context) addSingleImport(pkgInDir, imp string, tree bool) (*Package, error) {
|
||||
// Do not check for existing package right away. If a external package
|
||||
// has been added and we are looking in a vendor package, this won't work.
|
||||
// We need to search any relative vendor folders first.
|
||||
|
||||
// Also need to check for vendor paths that won't use the local path in import path.
|
||||
for _, pkg := range ctx.Package {
|
||||
if pkg.Path == imp && pkg.inVendor && pathos.FileHasPrefix(pkg.Dir, pkgInDir) {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
dir, gopath, err := ctx.findImportDir(pkgInDir, imp)
|
||||
if err != nil {
|
||||
if _, is := err.(ErrNotInGOPATH); is {
|
||||
presence := PresenceMissing
|
||||
// excluded packages, don't need to be present
|
||||
for _, exclude := range ctx.excludePackage {
|
||||
if imp == exclude || strings.HasPrefix(imp, exclude+"/") {
|
||||
presence = PresenceExcluded
|
||||
}
|
||||
}
|
||||
return ctx.setPackage("", imp, imp, "", Status{
|
||||
Type: TypePackage,
|
||||
Location: LocationNotFound,
|
||||
Presence: presence,
|
||||
}), nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if pathos.FileStringEquals(gopath, ctx.Goroot) {
|
||||
return ctx.setPackage(dir, imp, imp, ctx.Goroot, Status{
|
||||
Type: TypePackage,
|
||||
Location: LocationStandard,
|
||||
Presence: PresenceFound,
|
||||
}), nil
|
||||
}
|
||||
if tree {
|
||||
return ctx.setPackage(dir, imp, imp, ctx.RootGopath, Status{
|
||||
Type: TypePackage,
|
||||
Location: LocationVendor,
|
||||
Presence: PresenceFound,
|
||||
}), nil
|
||||
}
|
||||
df, err := os.Open(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info, err := df.Readdir(-1)
|
||||
df.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if testNeedsSortOrder {
|
||||
sort.Sort(fileInfoSort(info))
|
||||
}
|
||||
var pkg *Package
|
||||
for _, fi := range info {
|
||||
if fi.IsDir() {
|
||||
continue
|
||||
}
|
||||
switch fi.Name()[0] {
|
||||
case '.', '_':
|
||||
continue
|
||||
}
|
||||
if pathos.FileStringEquals(dir, pkgInDir) {
|
||||
continue
|
||||
}
|
||||
path := filepath.Join(dir, fi.Name())
|
||||
tryPkg, err := ctx.addFileImports(path, gopath)
|
||||
if tryPkg != nil {
|
||||
pkg = tryPkg
|
||||
}
|
||||
if err != nil {
|
||||
return pkg, err
|
||||
}
|
||||
}
|
||||
return pkg, nil
|
||||
}
|
||||
|
||||
func (ctx *Context) determinePackageStatus() error {
|
||||
// Add any packages in the vendor file but not in GOPATH or vendor dir.
|
||||
for _, vp := range ctx.VendorFile.Package {
|
||||
if vp.Remove {
|
||||
continue
|
||||
}
|
||||
if _, found := ctx.Package[vp.Path]; found {
|
||||
continue
|
||||
}
|
||||
pkg, err := ctx.addSingleImport(ctx.RootDir, vp.Path, vp.Tree)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if pkg != nil {
|
||||
pkg.Origin = vp.Origin
|
||||
pkg.inTree = vp.Tree
|
||||
pkg.inVendor = true
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the status of remaining imports.
|
||||
for _, pkg := range ctx.Package {
|
||||
if pkg.Status.Location != LocationUnknown {
|
||||
continue
|
||||
}
|
||||
if filepath.HasPrefixDir(pkg.Path, ctx.RootImportPath) {
|
||||
pkg.Status.Location = LocationLocal
|
||||
continue
|
||||
}
|
||||
pkg.Status.Location = LocationExternal
|
||||
}
|
||||
|
||||
ctx.updatePackageReferences()
|
||||
|
||||
// Mark sub-tree packages as "tree", but leave any existing bit (unused) on the
|
||||
// parent most tree package.
|
||||
for path, pkg := range ctx.Package {
|
||||
if vp := ctx.VendorFilePackagePath(pkg.Path); vp != nil && vp.Tree {
|
||||
// Remove internal tree references.
|
||||
del := make([]string, 0, 6)
|
||||
for opath, opkg := range pkg.referenced {
|
||||
if strings.HasPrefix(opkg.Path, pkg.Path+"/") {
|
||||
del = append(del, opath)
|
||||
}
|
||||
}
|
||||
delete(pkg.referenced, pkg.Local) // remove any self reference
|
||||
for _, d := range del {
|
||||
delete(pkg.referenced, d)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if parentTrees := ctx.findPackageParentTree(pkg); len(parentTrees) > 0 {
|
||||
pkg.Status.Presence = PresenceTree
|
||||
|
||||
// Transfer all references from the child to the top parent.
|
||||
if parentPkg := ctx.Package[parentTrees[0]]; parentPkg != nil {
|
||||
for opath, opkg := range pkg.referenced {
|
||||
// Do not transfer internal references.
|
||||
if strings.HasPrefix(opkg.Path, parentPkg.Path+"/") {
|
||||
continue
|
||||
}
|
||||
parentPkg.referenced[opath] = opkg
|
||||
}
|
||||
pkg.referenced = make(map[string]*Package, 0)
|
||||
for _, opkg := range ctx.Package {
|
||||
if _, has := opkg.referenced[path]; has {
|
||||
opkg.referenced[parentPkg.Local] = parentPkg
|
||||
delete(opkg.referenced, path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.updatePackageReferences()
|
||||
|
||||
// Determine any un-used internal vendor imports.
|
||||
for i := 0; i <= looplimit; i++ {
|
||||
altered := false
|
||||
for path, pkg := range ctx.Package {
|
||||
if pkg.Status.Presence == PresenceUnused || pkg.Status.Presence == PresenceTree || pkg.Status.Type == TypeProgram {
|
||||
continue
|
||||
}
|
||||
if len(pkg.referenced) > 0 || pkg.Status.Location != LocationVendor {
|
||||
continue
|
||||
}
|
||||
altered = true
|
||||
pkg.Status.Presence = PresenceUnused
|
||||
for _, other := range ctx.Package {
|
||||
delete(other.referenced, path)
|
||||
}
|
||||
}
|
||||
if !altered {
|
||||
break
|
||||
}
|
||||
if i == looplimit {
|
||||
panic("determinePackageStatus loop limit")
|
||||
}
|
||||
}
|
||||
|
||||
ctx.updatePackageReferences()
|
||||
|
||||
// Unused external references may have worked their way in through
|
||||
// vendor file. Remove any external leafs.
|
||||
for i := 0; i <= looplimit; i++ {
|
||||
altered := false
|
||||
for path, pkg := range ctx.Package {
|
||||
if len(pkg.referenced) > 0 || pkg.Status.Location != LocationExternal {
|
||||
continue
|
||||
}
|
||||
altered = true
|
||||
delete(ctx.Package, path)
|
||||
pkg.Status.Presence = PresenceUnused
|
||||
for _, other := range ctx.Package {
|
||||
delete(other.referenced, path)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !altered {
|
||||
break
|
||||
}
|
||||
if i == looplimit {
|
||||
panic("determinePackageStatus loop limit")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
207
tools/vendor/github.com/kardianos/govendor/context/rewrite.go
generated
vendored
Normal file
207
tools/vendor/github.com/kardianos/govendor/context/rewrite.go
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
// Copyright 2015 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 context
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/dchest/safefile"
|
||||
"github.com/kardianos/govendor/internal/pathos"
|
||||
os "github.com/kardianos/govendor/internal/vos"
|
||||
)
|
||||
|
||||
// Rewrite rewrites files to the local path.
|
||||
func (ctx *Context) rewrite() error {
|
||||
if !ctx.rewriteImports {
|
||||
return nil
|
||||
}
|
||||
if ctx.dirty {
|
||||
ctx.loadPackage()
|
||||
}
|
||||
ctx.dirty = true
|
||||
|
||||
fileImports := make(map[string]map[string]*File) // map[ImportPath]map[FilePath]File
|
||||
for _, pkg := range ctx.Package {
|
||||
for _, f := range pkg.Files {
|
||||
for _, imp := range f.Imports {
|
||||
fileList := fileImports[imp]
|
||||
if fileList == nil {
|
||||
fileList = make(map[string]*File, 1)
|
||||
fileImports[imp] = fileList
|
||||
}
|
||||
fileList[f.Path] = f
|
||||
}
|
||||
}
|
||||
}
|
||||
filePaths := make(map[string]*File, len(ctx.RewriteRule))
|
||||
for from, to := range ctx.RewriteRule {
|
||||
// Add files that contain an import path to rewrite.
|
||||
for _, f := range fileImports[from] {
|
||||
filePaths[f.Path] = f
|
||||
}
|
||||
|
||||
// Add files that contain import comments to remove.
|
||||
if pkg := ctx.Package[from]; pkg != nil {
|
||||
for _, f := range pkg.Files {
|
||||
if len(f.ImportComment) != 0 {
|
||||
filePaths[f.Path] = f
|
||||
}
|
||||
}
|
||||
}
|
||||
if pkg := ctx.Package[to]; pkg != nil {
|
||||
for _, f := range pkg.Files {
|
||||
if len(f.ImportComment) != 0 {
|
||||
filePaths[f.Path] = f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
RULE: co2/internal/co3/pk3 -> co1/internal/co3/pk3
|
||||
|
||||
i co1/internal/co2/pk2 [co2/pk2] < ["co1/pk1"]
|
||||
i co1/internal/co3/pk3 [co3/pk3] < ["co1/pk1"]
|
||||
e co2/internal/co3/pk3 [co3/pk3] < ["co1/internal/co2/pk2"]
|
||||
l co1/pk1 < []
|
||||
s strings < ["co1/internal/co3/pk3" "co2/internal/co3/pk3"]
|
||||
|
||||
Rewrite the package "co1/internal/co2/pk2" because it references a package with a rewrite.from package.
|
||||
*/
|
||||
ctx.updatePackageReferences()
|
||||
for from := range ctx.RewriteRule {
|
||||
pkg := ctx.Package[from]
|
||||
if pkg == nil {
|
||||
continue
|
||||
}
|
||||
for _, ref := range pkg.referenced {
|
||||
for _, f := range ref.Files {
|
||||
dprintf("REF RW %s\n", f.Path)
|
||||
filePaths[f.Path] = f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defer func() {
|
||||
ctx.RewriteRule = make(map[string]string, 3)
|
||||
}()
|
||||
|
||||
if len(ctx.RewriteRule) == 0 {
|
||||
return nil
|
||||
}
|
||||
goprint := &printer.Config{
|
||||
Mode: printer.TabIndent | printer.UseSpaces,
|
||||
Tabwidth: 8,
|
||||
}
|
||||
for _, fileInfo := range filePaths {
|
||||
if pathos.FileHasPrefix(fileInfo.Path, ctx.RootDir) == false {
|
||||
continue
|
||||
}
|
||||
|
||||
// Read the file into AST, modify the AST.
|
||||
fileset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fileset, fileInfo.Path, nil, parser.ParseComments)
|
||||
if f == nil {
|
||||
return nil
|
||||
}
|
||||
pkgNameNormalized := strings.TrimSuffix(f.Name.Name, "_test")
|
||||
// Files with package name "documentation" should be ignored, per go build tool.
|
||||
if pkgNameNormalized == "documentation" {
|
||||
return nil
|
||||
}
|
||||
|
||||
dprintf("RW:: File: %s\n", fileInfo.Path)
|
||||
|
||||
for _, impNode := range f.Imports {
|
||||
imp, err := strconv.Unquote(impNode.Path.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for from, to := range ctx.RewriteRule {
|
||||
if imp != from {
|
||||
continue
|
||||
}
|
||||
impNode.Path.Value = strconv.Quote(to)
|
||||
for i, metaImport := range fileInfo.Imports {
|
||||
if from == metaImport {
|
||||
dprintf("\tImport: %s -> %s\n", from, to)
|
||||
fileInfo.Imports[i] = to
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Remove import comment.
|
||||
st := fileInfo.Package.Status
|
||||
if st.Location == LocationVendor || st.Location == LocationExternal {
|
||||
var ic *ast.Comment
|
||||
if f.Name != nil {
|
||||
pos := f.Name.Pos()
|
||||
big:
|
||||
// Find the next comment after the package name.
|
||||
for _, cblock := range f.Comments {
|
||||
for _, c := range cblock.List {
|
||||
if c.Pos() > pos {
|
||||
ic = c
|
||||
break big
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ic != nil {
|
||||
// If it starts with the import text, assume it is the import comment and remove.
|
||||
if index := strings.Index(ic.Text, " import "); index > 0 && index < 5 {
|
||||
ic.Text = strings.Repeat(" ", len(ic.Text))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Don't sort or modify the imports to minimize diffs.
|
||||
|
||||
// Write the AST back to disk.
|
||||
fi, err := os.Stat(fileInfo.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w, err := safefile.Create(fileInfo.Path, fi.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = goprint.Fprint(w, fileset, f)
|
||||
if err != nil {
|
||||
w.Close()
|
||||
return err
|
||||
}
|
||||
err = w.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctx *Context) makeSet(pkg *Package, mvSet map[*Package]struct{}) {
|
||||
mvSet[pkg] = struct{}{}
|
||||
for _, f := range pkg.Files {
|
||||
for _, imp := range f.Imports {
|
||||
next := ctx.Package[imp]
|
||||
switch {
|
||||
default:
|
||||
if _, has := mvSet[next]; !has {
|
||||
ctx.makeSet(next, mvSet)
|
||||
}
|
||||
case next == nil:
|
||||
case next.Path == next.Local:
|
||||
case next.Status.Location != LocationExternal:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
271
tools/vendor/github.com/kardianos/govendor/context/status.go
generated
vendored
Normal file
271
tools/vendor/github.com/kardianos/govendor/context/status.go
generated
vendored
Normal file
@@ -0,0 +1,271 @@
|
||||
// Copyright 2015 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 context
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/kardianos/govendor/pkgspec"
|
||||
)
|
||||
|
||||
type (
|
||||
// Status is the package type, location, and presence indicators.
|
||||
Status struct {
|
||||
Type StatusType // program, package
|
||||
Location StatusLocation // vendor, local, external, stdlib
|
||||
Presence StatusPresence // missing, unused, tree, excluded
|
||||
|
||||
Not bool // Not indicates boolean operation "not" on above.
|
||||
}
|
||||
|
||||
StatusType byte // StatusType is main or not-main.
|
||||
StatusLocation byte // StatusLocation is where the package is.
|
||||
StatusPresence byte // StatusPresence is if it can be found or referenced.
|
||||
|
||||
// StatusGroup is the logical filter for status with "and", "not", and grouping.
|
||||
StatusGroup struct {
|
||||
Status []Status
|
||||
Group []StatusGroup
|
||||
And bool
|
||||
Not bool
|
||||
}
|
||||
)
|
||||
|
||||
func (s Status) String() string {
|
||||
t := ' '
|
||||
l := ' '
|
||||
p := ' '
|
||||
not := ""
|
||||
if s.Not {
|
||||
not = "!"
|
||||
}
|
||||
switch s.Type {
|
||||
default:
|
||||
panic("Unknown Type type")
|
||||
case TypeUnknown:
|
||||
t = '_'
|
||||
case TypePackage:
|
||||
t = ' '
|
||||
case TypeProgram:
|
||||
t = 'p'
|
||||
}
|
||||
switch s.Location {
|
||||
default:
|
||||
panic("Unkown Location type")
|
||||
case LocationUnknown:
|
||||
l = '_'
|
||||
case LocationNotFound:
|
||||
l = ' '
|
||||
case LocationLocal:
|
||||
l = 'l'
|
||||
case LocationExternal:
|
||||
l = 'e'
|
||||
case LocationVendor:
|
||||
l = 'v'
|
||||
case LocationStandard:
|
||||
l = 's'
|
||||
}
|
||||
switch s.Presence {
|
||||
default:
|
||||
panic("Unknown Presence type")
|
||||
case PresenceUnknown:
|
||||
p = '_'
|
||||
case PresenceFound:
|
||||
p = ' '
|
||||
case PresenceMissing:
|
||||
p = 'm'
|
||||
case PresenceUnused:
|
||||
p = 'u'
|
||||
case PresenceTree:
|
||||
p = 't'
|
||||
case PresenceExcluded:
|
||||
p = 'x'
|
||||
}
|
||||
return not + string(t) + string(l) + string(p)
|
||||
}
|
||||
|
||||
func (sg StatusGroup) String() string {
|
||||
buf := &bytes.Buffer{}
|
||||
if sg.And {
|
||||
buf.WriteString("and")
|
||||
} else {
|
||||
buf.WriteString("or")
|
||||
}
|
||||
buf.WriteRune('(')
|
||||
for i, s := range sg.Status {
|
||||
if i != 0 {
|
||||
buf.WriteRune(',')
|
||||
}
|
||||
buf.WriteString(s.String())
|
||||
}
|
||||
if len(sg.Status) > 0 && len(sg.Group) > 0 {
|
||||
buf.WriteRune(',')
|
||||
}
|
||||
for i, ssg := range sg.Group {
|
||||
if i != 0 {
|
||||
buf.WriteRune(',')
|
||||
}
|
||||
buf.WriteString(ssg.String())
|
||||
}
|
||||
buf.WriteRune(')')
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (pkgSt Status) Match(filterSt Status) bool {
|
||||
// not: true, pkg: A, filter: B
|
||||
// true == (A == B) -> true == false -> false
|
||||
//
|
||||
// not: false, pkg: A, filter: B
|
||||
// false == (A == B) -> false == false -> true
|
||||
//
|
||||
// not: true, pkg: A, filter: A
|
||||
// true == (A == A) -> true == true) -> true
|
||||
//
|
||||
// not: false, pkg: A, filter: A
|
||||
// false == (A == A) -> false == true -> false
|
||||
if filterSt.Location != LocationUnknown && filterSt.Not == (pkgSt.Location == filterSt.Location) {
|
||||
return false
|
||||
}
|
||||
if filterSt.Type != TypeUnknown && filterSt.Not == (pkgSt.Type == filterSt.Type) {
|
||||
return false
|
||||
}
|
||||
if filterSt.Presence != PresenceUnknown && filterSt.Not == (pkgSt.Presence == filterSt.Presence) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (status Status) MatchGroup(filter StatusGroup) bool {
|
||||
or := !filter.And
|
||||
for _, fs := range filter.Status {
|
||||
if status.Match(fs) == or {
|
||||
return or != filter.Not
|
||||
}
|
||||
}
|
||||
for _, fg := range filter.Group {
|
||||
if status.MatchGroup(fg) == or {
|
||||
return or != filter.Not
|
||||
}
|
||||
}
|
||||
return filter.And
|
||||
}
|
||||
|
||||
const (
|
||||
TypeUnknown StatusType = iota // TypeUnknown is unset StatusType.
|
||||
TypePackage // TypePackage package is a non-main package.
|
||||
TypeProgram // TypeProgram package is a main package.
|
||||
)
|
||||
|
||||
const (
|
||||
LocationUnknown StatusLocation = iota // LocationUnknown is unset StatusLocation.
|
||||
LocationNotFound // LocationNotFound package is not to be found (use PresenceMissing).
|
||||
LocationStandard // LocationStandard package is in the standard library.
|
||||
LocationLocal // LocationLocal package is in a project, not in a vendor folder.
|
||||
LocationExternal // LocationExternal package is not in a project, in GOPATH.
|
||||
LocationVendor // LocationVendor package is in a vendor folder.
|
||||
)
|
||||
|
||||
const (
|
||||
PresenceUnknown StatusPresence = iota // PresenceUnknown is unset StatusPresence.
|
||||
PresenceFound // PresenceFound package exists.
|
||||
PresenceMissing // PresenceMissing package is referenced but not found.
|
||||
PresenceUnused // PresenceUnused package is found locally but not referenced.
|
||||
PresenceTree // PresenceTree package is in vendor folder, in a tree, but not referenced.
|
||||
PresenceExcluded // PresenceExcluded package exists, but should not be vendored.
|
||||
)
|
||||
|
||||
// ListItem represents a package in the current project.
|
||||
type StatusItem struct {
|
||||
Status Status
|
||||
Pkg *pkgspec.Pkg
|
||||
VersionExact string
|
||||
Local string
|
||||
ImportedBy []*Package
|
||||
}
|
||||
|
||||
func (li StatusItem) String() string {
|
||||
if li.Local == li.Pkg.Path {
|
||||
return fmt.Sprintf("%s %s < %q", li.Status, li.Pkg.Path, li.ImportedBy)
|
||||
}
|
||||
return fmt.Sprintf("%s %s [%s] < %q", li.Status, li.Local, li.Pkg.Path, li.ImportedBy)
|
||||
}
|
||||
|
||||
type statusItemSort []StatusItem
|
||||
|
||||
func (li statusItemSort) Len() int { return len(li) }
|
||||
func (li statusItemSort) Swap(i, j int) { li[i], li[j] = li[j], li[i] }
|
||||
func (li statusItemSort) Less(i, j int) bool {
|
||||
if li[i].Status.Location != li[j].Status.Location {
|
||||
return li[i].Status.Location > li[j].Status.Location
|
||||
}
|
||||
return li[i].Local < li[j].Local
|
||||
}
|
||||
|
||||
// Status obtains the current package status list.
|
||||
func (ctx *Context) updateStatusCache() error {
|
||||
var err error
|
||||
if !ctx.loaded || ctx.dirty {
|
||||
err = ctx.loadPackage()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
ctx.updatePackageReferences()
|
||||
list := make([]StatusItem, 0, len(ctx.Package))
|
||||
for _, pkg := range ctx.Package {
|
||||
version := ""
|
||||
versionExact := ""
|
||||
if vp := ctx.VendorFilePackagePath(pkg.Path); vp != nil {
|
||||
version = vp.Version
|
||||
versionExact = vp.VersionExact
|
||||
}
|
||||
|
||||
origin := ""
|
||||
if pkg.Origin != pkg.Path {
|
||||
origin = pkg.Origin
|
||||
}
|
||||
if len(pkg.Origin) == 0 && pkg.Path != pkg.Local {
|
||||
origin = pkg.Local
|
||||
}
|
||||
|
||||
li := StatusItem{
|
||||
Status: pkg.Status,
|
||||
Pkg: &pkgspec.Pkg{Path: pkg.Path, IncludeTree: pkg.IncludeTree, Origin: origin, Version: version, FilePath: pkg.Dir},
|
||||
Local: pkg.Local,
|
||||
VersionExact: versionExact,
|
||||
ImportedBy: make([]*Package, 0, len(pkg.referenced)),
|
||||
}
|
||||
for _, ref := range pkg.referenced {
|
||||
li.ImportedBy = append(li.ImportedBy, ref)
|
||||
}
|
||||
sort.Sort(packageList(li.ImportedBy))
|
||||
list = append(list, li)
|
||||
}
|
||||
// Sort li by Status, then Path.
|
||||
sort.Sort(statusItemSort(list))
|
||||
|
||||
ctx.statusCache = list
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status obtains the current package status list.
|
||||
func (ctx *Context) Status() ([]StatusItem, error) {
|
||||
var err error
|
||||
if !ctx.loaded || ctx.dirty {
|
||||
err = ctx.loadPackage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if ctx.statusCache == nil {
|
||||
err = ctx.updateStatusCache()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return ctx.statusCache, nil
|
||||
}
|
||||
415
tools/vendor/github.com/kardianos/govendor/context/sync.go
generated
vendored
Normal file
415
tools/vendor/github.com/kardianos/govendor/context/sync.go
generated
vendored
Normal file
@@ -0,0 +1,415 @@
|
||||
// Copyright 2016 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 context
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/kardianos/govendor/internal/pathos"
|
||||
"github.com/kardianos/govendor/vendorfile"
|
||||
|
||||
"golang.org/x/tools/go/vcs"
|
||||
)
|
||||
|
||||
func skipperTree(name string, dir bool) bool {
|
||||
return false
|
||||
}
|
||||
func skipperPackage(name string, dir bool) bool {
|
||||
return dir
|
||||
}
|
||||
|
||||
func (ctx *Context) VerifyVendor() (outOfDate []*vendorfile.Package, err error) {
|
||||
vf := ctx.VendorFile
|
||||
root := filepath.Join(ctx.RootDir, ctx.VendorFolder)
|
||||
add := func(vp *vendorfile.Package) {
|
||||
outOfDate = append(outOfDate, vp)
|
||||
}
|
||||
for _, vp := range vf.Package {
|
||||
if vp.Remove {
|
||||
continue
|
||||
}
|
||||
if len(vp.Path) == 0 {
|
||||
continue
|
||||
}
|
||||
if len(vp.ChecksumSHA1) == 0 {
|
||||
add(vp)
|
||||
continue
|
||||
}
|
||||
fp := filepath.Join(root, pathos.SlashToFilepath(vp.Path))
|
||||
h := sha1.New()
|
||||
sk := skipperPackage
|
||||
if vp.Tree {
|
||||
sk = skipperTree
|
||||
}
|
||||
err = getHash(root, fp, h, sk)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
checksum := base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
if vp.ChecksumSHA1 != checksum {
|
||||
add(vp)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getHash(root, fp string, h hash.Hash, skipper func(name string, isDir bool) bool) error {
|
||||
rel := pathos.FileTrimPrefix(fp, root)
|
||||
rel = pathos.SlashToImportPath(rel)
|
||||
rel = strings.Trim(rel, "/")
|
||||
|
||||
h.Write([]byte(rel))
|
||||
|
||||
dir, err := os.Open(fp)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Failed to open dir %q: %v", fp, err)
|
||||
}
|
||||
filelist, err := dir.Readdir(-1)
|
||||
dir.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to read dir %q: %v", fp, err)
|
||||
}
|
||||
sort.Sort(fileInfoSort(filelist))
|
||||
for _, fi := range filelist {
|
||||
if skipper(fi.Name(), fi.IsDir()) {
|
||||
continue
|
||||
}
|
||||
p := filepath.Join(fp, fi.Name())
|
||||
if fi.IsDir() {
|
||||
err = getHash(root, p, h, skipper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
f, err := os.Open(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
h.Write([]byte(fi.Name()))
|
||||
_, err = io.Copy(h, f)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// similarSegments compares two paths and determines if they have
|
||||
// similar prefix segments. For example github.com/kardianos/rdb and
|
||||
// github.com/kardianos/govendor have 2 similar segments.
|
||||
func similarSegments(p1, p2 string) (string, int) {
|
||||
seg1 := strings.Split(p1, "/")
|
||||
seg2 := strings.Split(p2, "/")
|
||||
|
||||
ct := len(seg1)
|
||||
if len(seg2) < ct {
|
||||
ct = len(seg2)
|
||||
}
|
||||
|
||||
similar := &bytes.Buffer{}
|
||||
for i := 0; i < ct; i++ {
|
||||
if seg1[i] != seg2[i] {
|
||||
return similar.String(), i
|
||||
}
|
||||
if i != 0 {
|
||||
similar.WriteRune('/')
|
||||
}
|
||||
similar.WriteString(seg1[i])
|
||||
}
|
||||
return similar.String(), ct
|
||||
}
|
||||
|
||||
type remoteFailure struct {
|
||||
Path string
|
||||
Msg string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (fail remoteFailure) Error() string {
|
||||
return fmt.Sprintf("Failed for %q (%s): %v", fail.Path, fail.Msg, fail.Err)
|
||||
}
|
||||
|
||||
type remoteFailureList []remoteFailure
|
||||
|
||||
func (list remoteFailureList) Error() string {
|
||||
if len(list) == 0 {
|
||||
return "(no remote failure)"
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
buf.WriteString("Remotes failed for:\n")
|
||||
for _, item := range list {
|
||||
buf.WriteString("\t")
|
||||
buf.WriteString(item.Error())
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
type VCSCmd struct {
|
||||
*vcs.Cmd
|
||||
}
|
||||
|
||||
func (vcsCmd *VCSCmd) RevisionSync(dir, revision string) error {
|
||||
return vcsCmd.run(dir, vcsCmd.TagSyncCmd, "tag", revision)
|
||||
}
|
||||
|
||||
func (v *VCSCmd) run(dir string, cmd string, keyval ...string) error {
|
||||
_, err := v.run1(dir, cmd, keyval, true)
|
||||
return err
|
||||
}
|
||||
|
||||
// run1 is the generalized implementation of run and runOutput.
|
||||
func (vcsCmd *VCSCmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([]byte, error) {
|
||||
v := vcsCmd.Cmd
|
||||
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 vcs.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 {
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
func updateVcsCmd(cmd *vcs.Cmd) *VCSCmd {
|
||||
switch cmd.Name {
|
||||
case "Git":
|
||||
cmd.TagSyncCmd = "reset --hard {tag}"
|
||||
cmd.TagSyncDefault = "reset --hard origin/master"
|
||||
cmd.DownloadCmd = "fetch"
|
||||
case "Mercurial":
|
||||
case "Bazaar":
|
||||
case "Subversion":
|
||||
}
|
||||
return &VCSCmd{Cmd: cmd}
|
||||
}
|
||||
|
||||
var isSecureScheme = map[string]bool{
|
||||
"https": true,
|
||||
"git+ssh": true,
|
||||
"bzr+ssh": true,
|
||||
"svn+ssh": true,
|
||||
"ssh": true,
|
||||
}
|
||||
|
||||
func vcsIsSecure(repo string) bool {
|
||||
u, err := url.Parse(repo)
|
||||
if err != nil {
|
||||
// If repo is not a URL, it's not secure.
|
||||
return false
|
||||
}
|
||||
return isSecureScheme[u.Scheme]
|
||||
}
|
||||
|
||||
// Sync checks for outdated packages in the vendor folder and fetches the
|
||||
// correct revision from the remote.
|
||||
func (ctx *Context) Sync(dryrun bool) (err error) {
|
||||
// vcs.ShowCmd = true
|
||||
outOfDate, err := ctx.VerifyVendor()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to verify checksums: %v", err)
|
||||
}
|
||||
// GOPATH includes the src dir, move up a level.
|
||||
cacheRoot := filepath.Join(ctx.RootGopath, "..", ".cache", "govendor")
|
||||
err = os.MkdirAll(cacheRoot, 0700)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// collect errors and proceed where you can.
|
||||
rem := remoteFailureList{}
|
||||
|
||||
h := sha1.New()
|
||||
updatedVendorFile := false
|
||||
|
||||
for _, vp := range outOfDate {
|
||||
// Bundle packages together that have the same revision and share at least one root segment.
|
||||
if len(vp.Revision) == 0 {
|
||||
continue
|
||||
}
|
||||
from := vp.Path
|
||||
if len(vp.Origin) > 0 {
|
||||
from = vp.Origin
|
||||
}
|
||||
if from != vp.Path {
|
||||
fmt.Fprintf(ctx, "fetch %q from %q\n", vp.Path, from)
|
||||
} else {
|
||||
fmt.Fprintf(ctx, "fetch %q\n", vp.Path)
|
||||
}
|
||||
if dryrun {
|
||||
continue
|
||||
}
|
||||
pkgDir := filepath.Join(cacheRoot, from)
|
||||
|
||||
// See if repo exists.
|
||||
sysVcsCmd, repoRoot, err := vcs.FromDir(pkgDir, cacheRoot)
|
||||
var vcsCmd *VCSCmd
|
||||
repoRootDir := filepath.Join(cacheRoot, repoRoot)
|
||||
if err != nil {
|
||||
rr, err := vcs.RepoRootForImportPath(from, false)
|
||||
if err != nil {
|
||||
rem = append(rem, remoteFailure{Msg: "failed to ping remote repo", Path: vp.Path, Err: err})
|
||||
continue
|
||||
}
|
||||
if !ctx.Insecure && !vcsIsSecure(rr.Repo) {
|
||||
rem = append(rem, remoteFailure{Msg: "repo remote not secure", Path: vp.Path, Err: nil})
|
||||
continue
|
||||
}
|
||||
|
||||
vcsCmd = updateVcsCmd(rr.VCS)
|
||||
|
||||
repoRoot = rr.Root
|
||||
repoRootDir = filepath.Join(cacheRoot, repoRoot)
|
||||
err = os.MkdirAll(repoRootDir, 0700)
|
||||
if err != nil {
|
||||
rem = append(rem, remoteFailure{Msg: "failed to make repo root dir", Path: vp.Path, Err: err})
|
||||
continue
|
||||
}
|
||||
|
||||
err = vcsCmd.CreateAtRev(repoRootDir, rr.Repo, vp.Revision)
|
||||
if err != nil {
|
||||
rem = append(rem, remoteFailure{Msg: "failed to clone repo", Path: vp.Path, Err: err})
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
// Use cache.
|
||||
vcsCmd = updateVcsCmd(sysVcsCmd)
|
||||
|
||||
err = vcsCmd.RevisionSync(repoRootDir, vp.Revision)
|
||||
// If revision was not found in the cache, download and try again.
|
||||
if err != nil {
|
||||
err = vcsCmd.Download(repoRootDir)
|
||||
if err != nil {
|
||||
rem = append(rem, remoteFailure{Msg: "failed to download repo", Path: vp.Path, Err: err})
|
||||
continue
|
||||
}
|
||||
err = vcsCmd.RevisionSync(repoRootDir, vp.Revision)
|
||||
if err != nil {
|
||||
rem = append(rem, remoteFailure{Msg: "failed to sync repo to " + vp.Revision, Path: vp.Path, Err: err})
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
dest := filepath.Join(ctx.RootDir, ctx.VendorFolder, pathos.SlashToFilepath(vp.Path))
|
||||
// Path handling with single sub-packages and differing origins need to be properly handled.
|
||||
src := pkgDir
|
||||
|
||||
// Scan go files for files that should be ignored based on tags and filenames.
|
||||
ignoreFiles, _, err := ctx.getIngoreFiles(src)
|
||||
if err != nil {
|
||||
rem = append(rem, remoteFailure{Msg: "failed to get ignore files", Path: vp.Path, Err: err})
|
||||
continue
|
||||
}
|
||||
|
||||
root, _ := pathos.TrimCommonSuffix(src, vp.Path)
|
||||
|
||||
// Need to ensure we copy files from "b.Root/<import-path>" for the following command.
|
||||
err = ctx.CopyPackage(dest, src, root, vp.Path, ignoreFiles, vp.Tree, h, nil)
|
||||
if err != nil {
|
||||
fmt.Fprintf(ctx, "failed to copy package from %q to %q: %+v", src, dest, err)
|
||||
}
|
||||
checksum := h.Sum(nil)
|
||||
h.Reset()
|
||||
vp.ChecksumSHA1 = base64.StdEncoding.EncodeToString(checksum)
|
||||
updatedVendorFile = true
|
||||
}
|
||||
|
||||
// Only write a vendor file if something changes.
|
||||
if updatedVendorFile {
|
||||
err = ctx.WriteVendorFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Return network errors here.
|
||||
if len(rem) > 0 {
|
||||
return rem
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
8
tools/vendor/github.com/kardianos/govendor/context/syslist.go
generated
vendored
Normal file
8
tools/vendor/github.com/kardianos/govendor/context/syslist.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright 2011 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 context
|
||||
|
||||
const goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows "
|
||||
const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc s390 s390x sparc sparc64 "
|
||||
213
tools/vendor/github.com/kardianos/govendor/context/tags.go
generated
vendored
Normal file
213
tools/vendor/github.com/kardianos/govendor/context/tags.go
generated
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
// Copyright 2017 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 context
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Build tags come in the format "tagA tagB,tagC" -> "taga OR (tagB AND tagC)"
|
||||
// File tags compose with this as "ftag1 AND ftag2 AND (<build-tags>)".
|
||||
// However in govendor all questions are reversed. Rather then asking
|
||||
// "What should be built?" we ask "What should be ingored?".
|
||||
|
||||
type logical struct {
|
||||
and bool
|
||||
tag []logicalTag
|
||||
sub []logical
|
||||
}
|
||||
type logicalTag struct {
|
||||
not bool
|
||||
tag string
|
||||
}
|
||||
|
||||
func (lt logicalTag) match(lt2 logicalTag) bool {
|
||||
// A logicalTag is a match if
|
||||
// "tag == itag" or "!tag == !itag" or
|
||||
// "tag != !itag" or "!tag != itag"
|
||||
if lt.not || lt2.not {
|
||||
return false
|
||||
}
|
||||
return lt.tag == lt2.tag
|
||||
|
||||
if lt.not == lt2.not {
|
||||
return lt.tag == lt2.tag
|
||||
}
|
||||
return lt.tag != lt2.tag
|
||||
}
|
||||
|
||||
func (lt logicalTag) String() string {
|
||||
if lt.not {
|
||||
return "!" + lt.tag
|
||||
}
|
||||
return lt.tag
|
||||
}
|
||||
|
||||
func newLogicalTag(tag string) logicalTag {
|
||||
lt := logicalTag{}
|
||||
lt.not = strings.HasPrefix(tag, "!")
|
||||
lt.tag = strings.TrimPrefix(tag, "!")
|
||||
return lt
|
||||
}
|
||||
|
||||
func (l logical) empty() bool {
|
||||
if len(l.tag) > 0 {
|
||||
return false
|
||||
}
|
||||
for _, sub := range l.sub {
|
||||
if !sub.empty() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (l logical) ignored(ignoreTags []logicalTag) bool {
|
||||
// A logical is ingored if ANY AND conditions match or ALL OR conditions match.
|
||||
if len(ignoreTags) == 0 {
|
||||
return false
|
||||
}
|
||||
if l.empty() {
|
||||
return !l.and
|
||||
}
|
||||
if l.and {
|
||||
// Must have all tags in ignoreTags to be ignored.
|
||||
for _, t := range l.tag {
|
||||
for _, it := range ignoreTags {
|
||||
if t.match(it) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Must ignore all sub-logicals to be ignored.
|
||||
for _, sub := range l.sub {
|
||||
if sub.ignored(ignoreTags) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
hasOne := false
|
||||
// OR'ing the pieces together.
|
||||
// Must have at least one tag in ignoreTags to be ignored.
|
||||
for _, t := range l.tag {
|
||||
hasOne = true
|
||||
hasIgnoreTag := false
|
||||
for _, it := range ignoreTags {
|
||||
if t.match(it) {
|
||||
hasIgnoreTag = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasIgnoreTag {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Must have at least one sub section be ignored to be ignored.
|
||||
for _, sub := range l.sub {
|
||||
hasOne = true
|
||||
if !sub.ignored(ignoreTags) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return hasOne
|
||||
}
|
||||
|
||||
func (l logical) String() string {
|
||||
buf := bytes.Buffer{}
|
||||
if l.and {
|
||||
buf.WriteString(" AND (")
|
||||
} else {
|
||||
buf.WriteString(" OR (")
|
||||
}
|
||||
|
||||
for index, tag := range l.tag {
|
||||
if index != 0 {
|
||||
buf.WriteString(" ")
|
||||
}
|
||||
buf.WriteString(tag.String())
|
||||
}
|
||||
for index, sub := range l.sub {
|
||||
if index != 0 {
|
||||
buf.WriteString(" ")
|
||||
}
|
||||
buf.WriteString(sub.String())
|
||||
}
|
||||
|
||||
buf.WriteRune(')')
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
type TagSet struct {
|
||||
// ignore comes from a special build tag "ignore".
|
||||
ignore bool
|
||||
|
||||
root logical
|
||||
}
|
||||
|
||||
func (ts *TagSet) String() string {
|
||||
if ts == nil {
|
||||
return "(nil)"
|
||||
}
|
||||
if ts.ignore {
|
||||
return "ignore"
|
||||
}
|
||||
return ts.root.String()
|
||||
}
|
||||
|
||||
func (ts *TagSet) IgnoreItem(ignoreList ...string) bool {
|
||||
if ts == nil {
|
||||
return false
|
||||
}
|
||||
if ts.ignore {
|
||||
return true
|
||||
}
|
||||
ts.root.and = true
|
||||
ignoreTags := make([]logicalTag, len(ignoreList))
|
||||
for i := 0; i < len(ignoreList); i++ {
|
||||
ignoreTags[i] = newLogicalTag(ignoreList[i])
|
||||
}
|
||||
return ts.root.ignored(ignoreTags)
|
||||
}
|
||||
|
||||
func (ts *TagSet) AddFileTag(tag string) {
|
||||
if ts == nil {
|
||||
return
|
||||
}
|
||||
ts.root.and = true
|
||||
ts.root.tag = append(ts.root.tag, logicalTag{tag: tag})
|
||||
}
|
||||
func (ts *TagSet) AddBuildTags(tags string) {
|
||||
if ts == nil {
|
||||
return
|
||||
}
|
||||
ts.root.and = true
|
||||
if len(ts.root.sub) == 0 {
|
||||
ts.root.sub = append(ts.root.sub, logical{})
|
||||
}
|
||||
buildlogical := &ts.root.sub[0]
|
||||
ss := strings.Fields(tags)
|
||||
for _, s := range ss {
|
||||
if s == "ignore" {
|
||||
ts.ignore = true
|
||||
continue
|
||||
}
|
||||
if !strings.ContainsRune(s, ',') {
|
||||
buildlogical.tag = append(buildlogical.tag, newLogicalTag(s))
|
||||
continue
|
||||
}
|
||||
sub := logical{and: true}
|
||||
for _, and := range strings.Split(s, ",") {
|
||||
sub.tag = append(sub.tag, newLogicalTag(and))
|
||||
}
|
||||
buildlogical.sub = append(buildlogical.sub, sub)
|
||||
|
||||
}
|
||||
}
|
||||
79
tools/vendor/github.com/kardianos/govendor/context/vendorFile.go
generated
vendored
Normal file
79
tools/vendor/github.com/kardianos/govendor/context/vendorFile.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2015 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 context
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
ros "os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/dchest/safefile"
|
||||
"github.com/kardianos/govendor/vendorfile"
|
||||
|
||||
os "github.com/kardianos/govendor/internal/vos"
|
||||
)
|
||||
|
||||
// WriteVendorFile writes the current vendor file to the context location.
|
||||
func (ctx *Context) WriteVendorFile() (err error) {
|
||||
perm := ros.FileMode(0666)
|
||||
fi, err := os.Stat(ctx.VendorFilePath)
|
||||
if err == nil {
|
||||
perm = fi.Mode()
|
||||
}
|
||||
|
||||
ctx.VendorFile.RootPath = ctx.RootImportPath
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err = ctx.VendorFile.Marshal(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = buf.WriteByte('\n')
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dir, _ := filepath.Split(ctx.VendorFilePath)
|
||||
err = os.MkdirAll(dir, 0777)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for i := range ctx.VendorFile.Package {
|
||||
vp := ctx.VendorFile.Package[i]
|
||||
vp.Add = false
|
||||
}
|
||||
|
||||
err = safefile.WriteFile(ctx.VendorFilePath, buf.Bytes(), perm)
|
||||
if err == nil {
|
||||
for _, vp := range ctx.VendorFile.Package {
|
||||
vp.Add = false
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func readVendorFile(vendorRoot, vendorFilePath string) (*vendorfile.File, error) {
|
||||
vf := &vendorfile.File{}
|
||||
f, err := os.Open(vendorFilePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
err = vf.Unmarshal(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Remove any existing origin field if the prefix matches the
|
||||
// context package root. This fixes a previous bug introduced in the file,
|
||||
// that is now fixed.
|
||||
for _, row := range vf.Package {
|
||||
row.Origin = strings.TrimPrefix(row.Origin, vendorRoot)
|
||||
}
|
||||
|
||||
return vf, nil
|
||||
}
|
||||
47
tools/vendor/github.com/kardianos/govendor/context/version.go
generated
vendored
Normal file
47
tools/vendor/github.com/kardianos/govendor/context/version.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2016 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 context
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// IsVersion returns true if the string is a version.
|
||||
func isVersion(s string) bool {
|
||||
hasPunct := false
|
||||
onlyNumber := true
|
||||
onlyHexLetter := true
|
||||
for _, r := range s {
|
||||
isNumber := unicode.IsNumber(r)
|
||||
isLetter := unicode.IsLetter(r)
|
||||
|
||||
hasPunct = hasPunct || unicode.IsPunct(r)
|
||||
onlyNumber = onlyNumber && isNumber
|
||||
|
||||
if isLetter {
|
||||
low := unicode.ToLower(r)
|
||||
onlyHexLetter = onlyHexLetter && low <= 'f'
|
||||
}
|
||||
}
|
||||
if hasPunct {
|
||||
return true
|
||||
}
|
||||
if onlyHexLetter == false {
|
||||
return true
|
||||
}
|
||||
|
||||
num, err := strconv.ParseInt(s, 10, 64)
|
||||
if err == nil {
|
||||
if num > 100 {
|
||||
return false // numeric revision.
|
||||
}
|
||||
}
|
||||
|
||||
if len(s) > 5 && onlyHexLetter {
|
||||
return false // hex revision
|
||||
}
|
||||
return true
|
||||
}
|
||||
8
tools/vendor/github.com/kardianos/govendor/help/gen-license.template
generated
vendored
Normal file
8
tools/vendor/github.com/kardianos/govendor/help/gen-license.template
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
// Machine generated; DO NOT EDIT.
|
||||
|
||||
package help
|
||||
|
||||
var msgGovendorLicenses = `{{range $index, $t := .}}{{if ne $index 0}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
{{end}}{{.Filename}} - {{.Path}}
|
||||
{{.Text}}{{end}}
|
||||
`
|
||||
395
tools/vendor/github.com/kardianos/govendor/help/licenses.go
generated
vendored
Normal file
395
tools/vendor/github.com/kardianos/govendor/help/licenses.go
generated
vendored
Normal file
@@ -0,0 +1,395 @@
|
||||
// Machine generated; DO NOT EDIT.
|
||||
|
||||
package help
|
||||
|
||||
var msgGovendorLicenses = `LICENSE - go
|
||||
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.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PATENTS - go
|
||||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LICENSE - github.com/kardianos/govendor
|
||||
Copyright (c) 2015 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.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LICENSE - github.com/kardianos/govendor/vendor/github.com/Bowery/prompt
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2015 Bowery, Inc.
|
||||
|
||||
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.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LICENSE - github.com/kardianos/govendor/vendor/github.com/dchest/safefile
|
||||
Copyright (c) 2013 Dmitry Chestnykh <dmitry@codingrobots.com>
|
||||
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.
|
||||
|
||||
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.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
COPYING - github.com/kardianos/govendor/vendor/github.com/google/shlex
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LICENSE - github.com/kardianos/govendor/vendor/golang.org/x/tools
|
||||
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.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PATENTS - github.com/kardianos/govendor/vendor/golang.org/x/tools
|
||||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
||||
|
||||
`
|
||||
62
tools/vendor/github.com/kardianos/govendor/help/msg.go
generated
vendored
Normal file
62
tools/vendor/github.com/kardianos/govendor/help/msg.go
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
package help
|
||||
|
||||
type HelpMessage byte
|
||||
|
||||
const (
|
||||
MsgNone HelpMessage = iota
|
||||
MsgFull
|
||||
MsgInit
|
||||
MsgList
|
||||
MsgAdd
|
||||
MsgUpdate
|
||||
MsgRemove
|
||||
MsgFetch
|
||||
MsgStatus
|
||||
MsgSync
|
||||
MsgMigrate
|
||||
MsgGet
|
||||
MsgLicense
|
||||
MsgShell
|
||||
MsgGovendorLicense
|
||||
MsgGovendorVersion
|
||||
)
|
||||
|
||||
func (msg HelpMessage) String() string {
|
||||
msgText := ""
|
||||
switch msg {
|
||||
default:
|
||||
panic("Unknown message type")
|
||||
case MsgNone:
|
||||
case MsgFull:
|
||||
msgText = helpFull
|
||||
case MsgInit:
|
||||
msgText = helpInit
|
||||
case MsgList:
|
||||
msgText = helpList
|
||||
case MsgAdd:
|
||||
msgText = helpAdd
|
||||
case MsgUpdate:
|
||||
msgText = helpUpdate
|
||||
case MsgRemove:
|
||||
msgText = helpRemove
|
||||
case MsgFetch:
|
||||
msgText = helpFetch
|
||||
case MsgStatus:
|
||||
msgText = helpStatus
|
||||
case MsgSync:
|
||||
msgText = helpSync
|
||||
case MsgMigrate:
|
||||
msgText = helpMigrate
|
||||
case MsgGet:
|
||||
msgText = helpGet
|
||||
case MsgLicense:
|
||||
msgText = helpLicense
|
||||
case MsgShell:
|
||||
msgText = helpShell
|
||||
case MsgGovendorLicense:
|
||||
msgText = msgGovendorLicenses
|
||||
case MsgGovendorVersion:
|
||||
msgText = msgGovendorVersion
|
||||
}
|
||||
return msgText
|
||||
}
|
||||
169
tools/vendor/github.com/kardianos/govendor/help/text.go
generated
vendored
Normal file
169
tools/vendor/github.com/kardianos/govendor/help/text.go
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
// Copyright 2016 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 help
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/kardianos/govendor/migrate"
|
||||
)
|
||||
|
||||
//go:generate govendor license -o licenses.go -template gen-license.template
|
||||
|
||||
var helpFull = `govendor (` + version + `): record dependencies and copy into vendor folder
|
||||
-govendor-licenses Show govendor's licenses.
|
||||
-version Show govendor version
|
||||
|
||||
Sub-Commands
|
||||
|
||||
init Create the "vendor" folder and the "vendor.json" file.
|
||||
list List and filter existing dependencies and packages.
|
||||
add Add packages from $GOPATH.
|
||||
update Update packages from $GOPATH.
|
||||
remove Remove packages from the vendor folder.
|
||||
status Lists any packages missing, out-of-date, or modified locally.
|
||||
fetch Add new or update vendor folder packages from remote repository.
|
||||
sync Pull packages into vendor folder from remote repository with revisions
|
||||
from vendor.json file.
|
||||
migrate Move packages from a legacy tool to the vendor folder with metadata.
|
||||
get Like "go get" but copies dependencies into a "vendor" folder.
|
||||
license List discovered licenses for the given status or import paths.
|
||||
shell Run a "shell" to make multiple sub-commands more efficient for large
|
||||
projects.
|
||||
|
||||
go tool commands that are wrapped:
|
||||
"+status" package selection may be used with them
|
||||
fmt, build, install, clean, test, vet, generate, tool
|
||||
|
||||
Status Types
|
||||
|
||||
+local (l) packages in your project
|
||||
+external (e) referenced packages in GOPATH but not in current project
|
||||
+vendor (v) packages in the vendor folder
|
||||
+std (s) packages in the standard library
|
||||
|
||||
+excluded (x) external packages explicitly excluded from vendoring
|
||||
+unused (u) packages in the vendor folder, but unused
|
||||
+missing (m) referenced packages but not found
|
||||
|
||||
+program (p) package is a main package
|
||||
|
||||
+outside +external +missing
|
||||
+all +all packages
|
||||
|
||||
Status can be referenced by their initial letters.
|
||||
|
||||
Package specifier
|
||||
<path>[::<origin>][{/...|/^}][@[<version-spec>]]
|
||||
|
||||
Ignoring files with build tags, or excluding packages from being vendored:
|
||||
The "vendor.json" file contains a string field named "ignore".
|
||||
It may contain a space separated list of build tags to ignore when
|
||||
listing and copying files.
|
||||
This list may also contain package prefixes (containing a "/", possibly
|
||||
as last character) to exclude when copying files in the vendor folder.
|
||||
If "foo/" appears in this field, then package "foo" and all its sub-packages
|
||||
("foo/bar", …) will be excluded (but package "bar/foo" will not).
|
||||
By default the init command adds the "test" tag to the ignore list.
|
||||
|
||||
If using go1.5, ensure GO15VENDOREXPERIMENT=1 is set.
|
||||
|
||||
`
|
||||
|
||||
var helpInit = `govendor init
|
||||
Create a vendor folder in the working directory and a vendor/vendor.json
|
||||
metadata file.
|
||||
`
|
||||
|
||||
var helpList = `govendor list [options] ( +status or import-path-filter )
|
||||
List all dependencies and packages in folder tree.
|
||||
Options:
|
||||
-v verbose listing, show dependencies of each package
|
||||
-p show file path to package instead of import path
|
||||
-no-status do not prefix status to list, package names only
|
||||
Examples:
|
||||
$ govendor list -no-status +local
|
||||
$ govendor list -p -no-status +local
|
||||
$ govendor list +vend,prog +local,program
|
||||
$ govendor list +local,^prog
|
||||
`
|
||||
|
||||
var helpAdd = `govendor add [options] ( +status or import-path-filter )
|
||||
Copy one or more packages into the vendor folder from GOPATH.
|
||||
Options:
|
||||
-n dry run and print actions that would be taken
|
||||
-tree copy package(s) and all sub-folders under each package
|
||||
-uncommitted allows copying a package with uncommitted changes, doesn't
|
||||
update revision or checksum so it will always be out-of-date.
|
||||
|
||||
The following may be replaced with something else in the future.
|
||||
-short if conflict, take short path
|
||||
-long if conflict, take long path
|
||||
`
|
||||
|
||||
var helpUpdate = `govendor update [options] ( +status or import-path-filter )
|
||||
Update one or more packages from GOPATH into the vendor folder from GOPATH.
|
||||
Options:
|
||||
-n dry run and print actions that would be taken
|
||||
-tree copy package(s) and all sub-folders under each package
|
||||
-uncommitted allows copying a package with uncommitted changes, doesn't
|
||||
update revision or checksum so it will always be out-of-date.
|
||||
|
||||
The following may be replaced with something else in the future.
|
||||
-short if conflict, take short path
|
||||
-long if conflict, take long path
|
||||
`
|
||||
|
||||
var helpRemove = `govendor remove [options] ( +status or import-path-filter )
|
||||
Remove one or more packages from the vendor folder.
|
||||
Options:
|
||||
-n dry run and print actions that would be taken
|
||||
`
|
||||
|
||||
var helpFetch = `govendor fetch [options] ( +status or package-spec )
|
||||
Fetches packages directly into the vendor folder.
|
||||
package-spec = <path>[::<origin>][{/...|/^}][@[<version-spec>]]
|
||||
Options:
|
||||
-tree copy package(s) and all sub-folders under each package
|
||||
-insecure allow downloading over insecure connection
|
||||
-v verbose mode
|
||||
`
|
||||
|
||||
var helpSync = `govendor sync
|
||||
Ensures the contents of the vendor folder matches the vendor file.
|
||||
Options:
|
||||
-n dry run, print out action only
|
||||
-insecure allow downloading over insecure connection
|
||||
-v verbose output
|
||||
`
|
||||
|
||||
var helpStatus = `govendor status
|
||||
Shows any packages that are missing, out-of-date, or modified locally (according to the
|
||||
checksum) and should be sync'ed.
|
||||
`
|
||||
|
||||
var helpMigrate = `govendor migrate [` + strings.Join(migrate.SystemList(), ", ") + `]
|
||||
Change from a one schema to use the vendor folder. Default to auto detect.
|
||||
`
|
||||
|
||||
var helpGet = `govendor get [options] (import-path)...
|
||||
Download package into GOPATH, put all dependencies into vendor folder.
|
||||
Options:
|
||||
-insecure allow downloading over insecure connection
|
||||
-v verbose mode
|
||||
`
|
||||
|
||||
var helpLicense = `govendor license [options] ( +status or package-spec )
|
||||
Attempt to find and list licenses for the specified packages.
|
||||
Options:
|
||||
-o output to file name
|
||||
-template template file to use, input is "[]context.License"
|
||||
`
|
||||
var helpShell = `govendor shell
|
||||
Open a govendor "shell". Useful for faster queries on large projects.
|
||||
`
|
||||
|
||||
var msgGovendorVersion = version + `
|
||||
`
|
||||
7
tools/vendor/github.com/kardianos/govendor/help/version.go
generated
vendored
Normal file
7
tools/vendor/github.com/kardianos/govendor/help/version.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright 2016 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 help
|
||||
|
||||
var version = "v1.0.8"
|
||||
133
tools/vendor/github.com/kardianos/govendor/internal/pathos/path.go
generated
vendored
Normal file
133
tools/vendor/github.com/kardianos/govendor/internal/pathos/path.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright 2015 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 pathos
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func SlashToFilepath(path string) string {
|
||||
if '/' == filepath.Separator {
|
||||
return path
|
||||
}
|
||||
return strings.Replace(path, "/", string(filepath.Separator), -1)
|
||||
}
|
||||
func SlashToImportPath(path string) string {
|
||||
return strings.Replace(path, `\`, "/", -1)
|
||||
}
|
||||
|
||||
func FileHasPrefix(s, prefix string) bool {
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
s = strings.ToLower(s)
|
||||
prefix = strings.ToLower(prefix)
|
||||
}
|
||||
return strings.HasPrefix(s, prefix)
|
||||
}
|
||||
|
||||
func FileTrimPrefix(s, prefix string) string {
|
||||
if FileHasPrefix(s, prefix) {
|
||||
return s[len(prefix):]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func FileHasSuffix(s, suffix string) bool {
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
s = strings.ToLower(s)
|
||||
suffix = strings.ToLower(suffix)
|
||||
}
|
||||
return strings.HasSuffix(s, suffix)
|
||||
}
|
||||
|
||||
func FileTrimSuffix(s, suffix string) string {
|
||||
if FileHasSuffix(s, suffix) {
|
||||
return s[:len(s)-len(suffix)]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
var slashSep = filepath.Separator
|
||||
|
||||
func TrimCommonSuffix(base, suffix string) (string, string) {
|
||||
a, b := base, suffix
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
a = strings.ToLower(a)
|
||||
b = strings.ToLower(b)
|
||||
}
|
||||
a = strings.TrimSuffix(strings.TrimSuffix(a, "\\"), "/")
|
||||
b = strings.TrimSuffix(strings.TrimSuffix(b, "\\"), "/")
|
||||
base = strings.TrimSuffix(strings.TrimSuffix(base, "\\"), "/")
|
||||
|
||||
ff := func(r rune) bool {
|
||||
return r == '/' || r == '\\'
|
||||
}
|
||||
aa := strings.FieldsFunc(a, ff)
|
||||
bb := strings.FieldsFunc(b, ff)
|
||||
|
||||
min := len(aa)
|
||||
if min > len(bb) {
|
||||
min = len(bb)
|
||||
}
|
||||
i := 1
|
||||
for ; i <= min; i++ {
|
||||
// fmt.Printf("(%d) end aa: %q, end bb: %q\n", i, aa[len(aa)-i], bb[len(bb)-i])
|
||||
if aa[len(aa)-i] == bb[len(bb)-i] {
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
baseParts := strings.FieldsFunc(base, ff)
|
||||
// fmt.Printf("base parts: %q\n", baseParts)
|
||||
base1 := FileTrimSuffix(base, strings.Join(baseParts[len(baseParts)-i+1:], string(slashSep)))
|
||||
base1 = strings.TrimSuffix(strings.TrimSuffix(base1, "\\"), "/")
|
||||
base2 := strings.Trim(base[len(base1):], `\/`)
|
||||
return base1, base2
|
||||
}
|
||||
|
||||
func FileStringEquals(s1, s2 string) bool {
|
||||
if len(s1) == 0 {
|
||||
return len(s2) == 0
|
||||
}
|
||||
if len(s2) == 0 {
|
||||
return len(s1) == 0
|
||||
}
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
s1 = strings.ToLower(s1)
|
||||
s2 = strings.ToLower(s2)
|
||||
}
|
||||
r1End := s1[len(s1)-1]
|
||||
r2End := s2[len(s2)-1]
|
||||
if r1End == '/' || r1End == '\\' {
|
||||
s1 = s1[:len(s1)-1]
|
||||
}
|
||||
if r2End == '/' || r2End == '\\' {
|
||||
s2 = s2[:len(s2)-1]
|
||||
}
|
||||
return s1 == s2
|
||||
}
|
||||
|
||||
// GoEnv parses a "go env" line and checks for a specific
|
||||
// variable name.
|
||||
func GoEnv(name, line string) (value string, ok bool) {
|
||||
// Remove any leading "set " found on windows.
|
||||
// Match the name to the env var + "=".
|
||||
// Remove any quotes.
|
||||
// Return result.
|
||||
line = strings.TrimPrefix(line, "set ")
|
||||
if len(line) < len(name)+1 {
|
||||
return "", false
|
||||
}
|
||||
if name != line[:len(name)] || line[len(name)] != '=' {
|
||||
return "", false
|
||||
}
|
||||
line = line[len(name)+1:]
|
||||
if un, err := strconv.Unquote(line); err == nil {
|
||||
line = un
|
||||
}
|
||||
return line, true
|
||||
}
|
||||
14
tools/vendor/github.com/kardianos/govendor/internal/vfilepath/prefix.go
generated
vendored
Normal file
14
tools/vendor/github.com/kardianos/govendor/internal/vfilepath/prefix.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
package vfilepath
|
||||
|
||||
import "strings"
|
||||
|
||||
func HasPrefixDir(path string, prefix string) bool {
|
||||
return strings.HasPrefix(makeDirPath(path), makeDirPath(prefix))
|
||||
}
|
||||
|
||||
func makeDirPath(path string) string {
|
||||
if path != "/" {
|
||||
path += "/"
|
||||
}
|
||||
return path
|
||||
}
|
||||
17
tools/vendor/github.com/kardianos/govendor/internal/vfilepath/stub.go
generated
vendored
Normal file
17
tools/vendor/github.com/kardianos/govendor/internal/vfilepath/stub.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
package vfilepath
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func Split(path string) (string, string) {
|
||||
return filepath.Split(path)
|
||||
}
|
||||
|
||||
func Join(parts ...string) string {
|
||||
return filepath.Join(parts...)
|
||||
}
|
||||
|
||||
func EvalSymlinks(path string) (string, error) {
|
||||
return filepath.EvalSymlinks(path)
|
||||
}
|
||||
1
tools/vendor/github.com/kardianos/govendor/internal/vfilepath/switch.go
generated
vendored
Normal file
1
tools/vendor/github.com/kardianos/govendor/internal/vfilepath/switch.go
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
package vfilepath
|
||||
83
tools/vendor/github.com/kardianos/govendor/internal/vfilepath/walk.go
generated
vendored
Normal file
83
tools/vendor/github.com/kardianos/govendor/internal/vfilepath/walk.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
package vfilepath
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
os "github.com/kardianos/govendor/internal/vos"
|
||||
)
|
||||
|
||||
// SkipDir is used as a return value from WalkFuncs to indicate that
|
||||
// the directory named in the call is to be skipped. It is not returned
|
||||
// as an error by any function.
|
||||
var SkipDir = filepath.SkipDir
|
||||
|
||||
type WalkFunc func(path string, info os.FileInfo, err error) error
|
||||
|
||||
// walk recursively descends path, calling w.
|
||||
func walk(path string, info os.FileInfo, walkFn WalkFunc) error {
|
||||
err := walkFn(path, info, nil)
|
||||
if err != nil {
|
||||
if info.IsDir() && err == SkipDir {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if !info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
names, err := readDirNames(path)
|
||||
if err != nil {
|
||||
return walkFn(path, info, err)
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
filename := filepath.Join(path, name)
|
||||
fileInfo, err := os.Lstat(filename)
|
||||
if err != nil {
|
||||
if err := walkFn(filename, fileInfo, err); err != nil && err != SkipDir {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err = walk(filename, fileInfo, walkFn)
|
||||
if err != nil {
|
||||
if !fileInfo.IsDir() || err != SkipDir {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// readDirNames reads the directory named by dirname and returns
|
||||
// a sorted list of directory entries.
|
||||
func readDirNames(dirname string) ([]string, error) {
|
||||
f, err := os.Open(dirname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
names, err := f.Readdirnames(-1)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sort.Strings(names)
|
||||
return names, nil
|
||||
}
|
||||
|
||||
// Walk walks the file tree rooted at root, calling walkFn for each file or
|
||||
// directory in the tree, including root. All errors that arise visiting files
|
||||
// and directories are filtered by walkFn. The files are walked in lexical
|
||||
// order, which makes the output deterministic but means that for very
|
||||
// large directories Walk can be inefficient.
|
||||
// Walk does not follow symbolic links.
|
||||
func Walk(root string, walkFn WalkFunc) error {
|
||||
info, err := os.Lstat(root)
|
||||
if err != nil {
|
||||
return walkFn(root, nil, err)
|
||||
}
|
||||
return walk(root, info, walkFn)
|
||||
}
|
||||
61
tools/vendor/github.com/kardianos/govendor/internal/vos/stub.go
generated
vendored
Normal file
61
tools/vendor/github.com/kardianos/govendor/internal/vos/stub.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
package vos
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FileInfo os.FileInfo
|
||||
|
||||
func Stat(name string) (FileInfo, error) {
|
||||
l("stat", name)
|
||||
fi, err := os.Stat(name)
|
||||
return FileInfo(fi), err
|
||||
}
|
||||
func Lstat(name string) (FileInfo, error) {
|
||||
l("lstat", name)
|
||||
fi, err := os.Lstat(name)
|
||||
return FileInfo(fi), err
|
||||
}
|
||||
func IsNotExist(err error) bool {
|
||||
return os.IsNotExist(err)
|
||||
}
|
||||
|
||||
func Getwd() (string, error) {
|
||||
return os.Getwd()
|
||||
}
|
||||
|
||||
func Getenv(key string) string {
|
||||
return os.Getenv(key)
|
||||
}
|
||||
|
||||
func Open(name string) (*os.File, error) {
|
||||
l("open", name)
|
||||
return os.Open(name)
|
||||
}
|
||||
|
||||
func MkdirAll(path string, perm os.FileMode) error {
|
||||
l("mkdirall", path)
|
||||
return os.MkdirAll(path, perm)
|
||||
}
|
||||
|
||||
func Remove(name string) error {
|
||||
l("remove", name)
|
||||
return os.Remove(name)
|
||||
}
|
||||
func RemoveAll(name string) error {
|
||||
l("removeall", name)
|
||||
return os.RemoveAll(name)
|
||||
}
|
||||
func Create(name string) (*os.File, error) {
|
||||
l("create", name)
|
||||
return os.Create(name)
|
||||
}
|
||||
func Chmod(name string, mode os.FileMode) error {
|
||||
l("chmod", name)
|
||||
return os.Chmod(name, mode)
|
||||
}
|
||||
func Chtimes(name string, atime, mtime time.Time) error {
|
||||
l("chtimes", name)
|
||||
return os.Chtimes(name, atime, mtime)
|
||||
}
|
||||
13
tools/vendor/github.com/kardianos/govendor/internal/vos/switch.go
generated
vendored
Normal file
13
tools/vendor/github.com/kardianos/govendor/internal/vos/switch.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
package vos
|
||||
|
||||
import (
|
||||
"log"
|
||||
)
|
||||
|
||||
const debugLog = false
|
||||
|
||||
func l(fname, path string) {
|
||||
if debugLog {
|
||||
log.Println(fname, path)
|
||||
}
|
||||
}
|
||||
55
tools/vendor/github.com/kardianos/govendor/main.go
generated
vendored
Normal file
55
tools/vendor/github.com/kardianos/govendor/main.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2015 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.
|
||||
|
||||
// vendor tool to copy external source code from GOPATH or remote location to the
|
||||
// local vendor folder. See README.md for usage.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/kardianos/govendor/cliprompt"
|
||||
"github.com/kardianos/govendor/help"
|
||||
"github.com/kardianos/govendor/run"
|
||||
)
|
||||
|
||||
func main() {
|
||||
prompt := &cliprompt.Prompt{}
|
||||
|
||||
allArgs := os.Args
|
||||
|
||||
if allArgs[len(allArgs)-1] == "-" {
|
||||
stdin := &bytes.Buffer{}
|
||||
if _, err := io.Copy(stdin, os.Stdin); err == nil {
|
||||
stdinArgs := strings.Fields(stdin.String())
|
||||
allArgs = append(allArgs[:len(allArgs)-1], stdinArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
msg, err := run.Run(os.Stdout, allArgs, prompt)
|
||||
if err == flag.ErrHelp {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %+v\n", err)
|
||||
}
|
||||
msgText := msg.String()
|
||||
if len(msgText) > 0 {
|
||||
fmt.Fprint(os.Stderr, msgText)
|
||||
}
|
||||
if err != nil {
|
||||
os.Exit(2)
|
||||
}
|
||||
switch msg {
|
||||
case help.MsgNone, help.MsgGovendorVersion, help.MsgGovendorLicense:
|
||||
os.Exit(0)
|
||||
default:
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
29
tools/vendor/github.com/kardianos/govendor/migrate/gb.go
generated
vendored
Normal file
29
tools/vendor/github.com/kardianos/govendor/migrate/gb.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2015 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 migrate
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("gb", sysGb{})
|
||||
}
|
||||
|
||||
type sysGb struct{}
|
||||
|
||||
func (sys sysGb) Check(root string) (system, error) {
|
||||
if hasDirs(root, "src", filepath.Join("vendor", "src")) {
|
||||
return sys, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
func (sysGb) Migrate(root string) error {
|
||||
// Move files from "src" to first GOPATH.
|
||||
// Move vendor files from "vendor/src" to "vendor".
|
||||
// Translate "vendor/manifest" to vendor.json file.
|
||||
return errors.New("Migrate gb not implemented")
|
||||
}
|
||||
78
tools/vendor/github.com/kardianos/govendor/migrate/gdm.go
generated
vendored
Normal file
78
tools/vendor/github.com/kardianos/govendor/migrate/gdm.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright 2015 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 migrate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/kardianos/govendor/context"
|
||||
"github.com/kardianos/govendor/vendorfile"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("gdm", sysGdm{})
|
||||
}
|
||||
|
||||
type sysGdm struct{}
|
||||
|
||||
func (sys sysGdm) Check(root string) (system, error) {
|
||||
if hasFiles(root, "Godeps") {
|
||||
return sys, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sys sysGdm) Migrate(root string) error {
|
||||
gdmFilePath := filepath.Join(root, "Godeps")
|
||||
|
||||
ctx, err := context.NewContext(root, filepath.Join("vendor", "vendor.json"), "vendor", false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.VendorFile.Ignore = "test"
|
||||
|
||||
f, err := os.Open(gdmFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
pkgs, err := sys.parseGdmFile(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.VendorFile.Package = pkgs
|
||||
|
||||
if err := ctx.WriteVendorFile(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.RemoveAll(gdmFilePath)
|
||||
}
|
||||
|
||||
func (sysGdm) parseGdmFile(r io.Reader) ([]*vendorfile.Package, error) {
|
||||
var pkgs []*vendorfile.Package
|
||||
for {
|
||||
var path, rev string
|
||||
if _, err := fmt.Fscanf(r, "%s %s\n", &path, &rev); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pkgs = append(pkgs, &vendorfile.Package{
|
||||
Add: true,
|
||||
Path: path,
|
||||
Revision: rev,
|
||||
Tree: true,
|
||||
})
|
||||
}
|
||||
|
||||
return pkgs, nil
|
||||
}
|
||||
97
tools/vendor/github.com/kardianos/govendor/migrate/glock.go
generated
vendored
Normal file
97
tools/vendor/github.com/kardianos/govendor/migrate/glock.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright 2016 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 migrate
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/kardianos/govendor/context"
|
||||
"github.com/kardianos/govendor/pkgspec"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("glock", sysGlock{})
|
||||
}
|
||||
|
||||
type sysGlock struct{}
|
||||
|
||||
func (sys sysGlock) Check(root string) (system, error) {
|
||||
if hasFiles(root, "GLOCKFILE") {
|
||||
return sys, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
func (sysGlock) Migrate(root string) error {
|
||||
err := os.MkdirAll(filepath.Join(root, "vendor"), 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
filebytes, err := ioutil.ReadFile(filepath.Join(root, "GLOCKFILE"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lines := strings.Split(string(filebytes), "\n")
|
||||
for i, l := range lines {
|
||||
lines[i] = strings.TrimSpace(l)
|
||||
}
|
||||
|
||||
/*
|
||||
vf := &vendorfile.File{}
|
||||
vf.Package = make([]*vendorfile.Package, 0, len(lines))
|
||||
*/
|
||||
ctx, err := context.NewContext(root, filepath.Join("vendor", "vendor.json"), "vendor", false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
const cmdPrefix = "cmd "
|
||||
|
||||
for _, l := range lines {
|
||||
if len(l) == 0 {
|
||||
continue
|
||||
}
|
||||
isCmd := strings.HasPrefix(l, cmdPrefix)
|
||||
if isCmd {
|
||||
continue
|
||||
}
|
||||
field := strings.Fields(l)
|
||||
if len(field) < 2 {
|
||||
continue
|
||||
}
|
||||
ps, err := pkgspec.Parse("", field[0]+"@"+field[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ps.IncludeTree = true
|
||||
err = ctx.ModifyImport(ps, context.Fetch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, l := range lines {
|
||||
if len(l) == 0 {
|
||||
continue
|
||||
}
|
||||
isCmd := strings.HasPrefix(l, cmdPrefix)
|
||||
if !isCmd {
|
||||
continue
|
||||
}
|
||||
path := strings.TrimPrefix(l, cmdPrefix)
|
||||
ps, err := pkgspec.Parse("", path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ctx.ModifyImport(ps, context.Fetch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = ctx.WriteVendorFile()
|
||||
os.Remove(filepath.Join(root, "GLOCKFILE"))
|
||||
return err
|
||||
}
|
||||
129
tools/vendor/github.com/kardianos/govendor/migrate/godep.go
generated
vendored
Normal file
129
tools/vendor/github.com/kardianos/govendor/migrate/godep.go
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright 2015 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 migrate
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/kardianos/govendor/context"
|
||||
"github.com/kardianos/govendor/vendorfile"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("godep", sysGodep{})
|
||||
}
|
||||
|
||||
type sysGodep struct{}
|
||||
|
||||
func (sys sysGodep) Check(root string) (system, error) {
|
||||
if hasDirs(root, "Godeps") {
|
||||
return sys, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
func (sysGodep) Migrate(root string) error {
|
||||
// Determine if import paths are rewritten.
|
||||
// Un-rewrite import paths.
|
||||
// Copy files from Godeps/_workspace/src to "vendor".
|
||||
// Translate Godeps/Godeps.json to vendor.json.
|
||||
|
||||
vendorFilePath := filepath.Join("Godeps", "_workspace", "src")
|
||||
vendorPath := path.Join("Godeps", "_workspace", "src")
|
||||
godepFilePath := filepath.Join(root, "Godeps", "Godeps.json")
|
||||
|
||||
ctx, err := context.NewContext(root, "vendor.json", vendorFilePath, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.VendorDiscoverFolder = vendorPath
|
||||
|
||||
list, err := ctx.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
remove := make([]string, 0, len(list))
|
||||
for _, item := range list {
|
||||
if item.Status.Location != context.LocationVendor {
|
||||
continue
|
||||
}
|
||||
pkg := ctx.Package[item.Local]
|
||||
ctx.Operation = append(ctx.Operation, &context.Operation{
|
||||
Pkg: pkg,
|
||||
Src: pkg.Dir,
|
||||
Dest: filepath.Join(ctx.RootDir, "vendor", filepath.ToSlash(item.Pkg.Path)),
|
||||
})
|
||||
remove = append(remove, filepath.Join(ctx.RootGopath, filepath.ToSlash(item.Local)))
|
||||
ctx.RewriteRule[item.Local] = item.Pkg.Path
|
||||
}
|
||||
ctx.VendorFilePath = filepath.Join(ctx.RootDir, "vendor", "vendor.json")
|
||||
|
||||
ctx.VendorDiscoverFolder = "vendor"
|
||||
ctx.VendorFile.Ignore = "test"
|
||||
|
||||
// Translate then remove godeps.json file.
|
||||
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 // Description of commit, if present.
|
||||
Rev string // VCS-specific commit ID.
|
||||
}
|
||||
}
|
||||
|
||||
godeps := Godeps{}
|
||||
f, err := os.Open(godepFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
coder := json.NewDecoder(f)
|
||||
err = coder.Decode(&godeps)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, d := range godeps.Deps {
|
||||
for _, pkg := range ctx.Package {
|
||||
if strings.HasPrefix(pkg.Path, d.ImportPath) == false {
|
||||
continue
|
||||
}
|
||||
vf := ctx.VendorFilePackagePath(pkg.Path)
|
||||
if vf == nil {
|
||||
ctx.VendorFile.Package = append(ctx.VendorFile.Package, &vendorfile.Package{
|
||||
Add: true,
|
||||
Path: pkg.Path,
|
||||
Comment: d.Comment,
|
||||
Revision: d.Rev,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = ctx.WriteVendorFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ctx.Alter()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove existing.
|
||||
for _, r := range remove {
|
||||
err = context.RemovePackage(r, "", false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return os.RemoveAll(filepath.Join(root, "Godeps"))
|
||||
}
|
||||
133
tools/vendor/github.com/kardianos/govendor/migrate/migrate.go
generated
vendored
Normal file
133
tools/vendor/github.com/kardianos/govendor/migrate/migrate.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright 2015 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 migrate transforms a repository from a given vendor schema to
|
||||
// the vendor folder schema.
|
||||
package migrate
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type ErrNoSuchSystem struct {
|
||||
NotExist string
|
||||
Has []string
|
||||
}
|
||||
|
||||
func (err ErrNoSuchSystem) Error() string {
|
||||
return fmt.Sprintf("Migration system for %q doesn't exist. Current systems %q.", err.NotExist, err.Has)
|
||||
}
|
||||
|
||||
// From is the current vendor schema.
|
||||
type From string
|
||||
|
||||
// Migrate from the given system using the current working directory.
|
||||
func MigrateWD(from From) error {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return Migrate(from, wd)
|
||||
}
|
||||
|
||||
// SystemList list available migration systems.
|
||||
func SystemList() []string {
|
||||
list := make([]string, 0, len(registered))
|
||||
for key := range registered {
|
||||
list = append(list, string(key))
|
||||
}
|
||||
sort.Strings(list)
|
||||
return list
|
||||
}
|
||||
|
||||
// Migrate from the given system using the given root.
|
||||
func Migrate(from From, root string) error {
|
||||
sys, found := registered[from]
|
||||
if !found {
|
||||
return ErrNoSuchSystem{
|
||||
NotExist: string(from),
|
||||
Has: SystemList(),
|
||||
}
|
||||
}
|
||||
sys, err := sys.Check(root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sys == nil {
|
||||
return errors.New("Root not found.")
|
||||
}
|
||||
return sys.Migrate(root)
|
||||
}
|
||||
|
||||
type system interface {
|
||||
Check(root string) (system, error)
|
||||
Migrate(root string) error
|
||||
}
|
||||
|
||||
func register(name From, sys system) {
|
||||
_, found := registered[name]
|
||||
if found {
|
||||
panic("system " + name + " already registered.")
|
||||
}
|
||||
registered[name] = sys
|
||||
}
|
||||
|
||||
var registered = make(map[From]system, 10)
|
||||
|
||||
var errAutoSystemNotFound = errors.New("Unable to determine vendor system.")
|
||||
|
||||
func init() {
|
||||
register("auto", sysAuto{})
|
||||
}
|
||||
|
||||
type sysAuto struct{}
|
||||
|
||||
func (auto sysAuto) Check(root string) (system, error) {
|
||||
for _, sys := range registered {
|
||||
if sys == auto {
|
||||
continue
|
||||
}
|
||||
out, err := sys.Check(root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out != nil {
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
return nil, errAutoSystemNotFound
|
||||
}
|
||||
func (sysAuto) Migrate(root string) error {
|
||||
return errors.New("Auto.Migrate shouldn't be called")
|
||||
}
|
||||
|
||||
func hasDirs(root string, dd ...string) bool {
|
||||
for _, d := range dd {
|
||||
fi, err := os.Stat(filepath.Join(root, d))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if fi.IsDir() == false {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func hasFiles(root string, dd ...string) bool {
|
||||
for _, d := range dd {
|
||||
fi, err := os.Stat(filepath.Join(root, d))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if fi.IsDir() == true {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
97
tools/vendor/github.com/kardianos/govendor/migrate/old.go
generated
vendored
Normal file
97
tools/vendor/github.com/kardianos/govendor/migrate/old.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright 2015 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 migrate
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/kardianos/govendor/context"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("internal", sysInternal{})
|
||||
register("old-vendor", sysOldVendor{})
|
||||
}
|
||||
|
||||
type sysInternal struct{}
|
||||
|
||||
func (sys sysInternal) Check(root string) (system, error) {
|
||||
vendorFolder := "internal"
|
||||
override := os.Getenv("GOVENDORFOLDER")
|
||||
if len(override) != 0 {
|
||||
vendorFolder = override
|
||||
}
|
||||
if hasDirs(root, vendorFolder) && hasFiles(root, filepath.Join(vendorFolder, "vendor.json")) {
|
||||
return sys, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
func (sysInternal) Migrate(root string) error {
|
||||
// Un-rewrite import paths.
|
||||
// Copy files from internal to vendor.
|
||||
// Update and move vendor file from "internal/vendor.json" to "vendor.json".
|
||||
ctx, err := context.NewContext(root, filepath.Join("internal", "vendor.json"), "internal", true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
list, err := ctx.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
remove := make([]string, 0, len(list))
|
||||
for _, item := range list {
|
||||
if item.Status.Location != context.LocationVendor {
|
||||
continue
|
||||
}
|
||||
pkg := ctx.Package[item.Local]
|
||||
ctx.Operation = append(ctx.Operation, &context.Operation{
|
||||
Pkg: pkg,
|
||||
Src: pkg.Dir,
|
||||
Dest: filepath.Join(ctx.RootDir, "vendor", filepath.ToSlash(item.Pkg.Path)),
|
||||
})
|
||||
remove = append(remove, filepath.Join(ctx.RootGopath, filepath.ToSlash(item.Local)))
|
||||
ctx.RewriteRule[item.Local] = item.Pkg.Path
|
||||
}
|
||||
ctx.VendorFilePath = filepath.Join(ctx.RootDir, "vendor", "vendor.json")
|
||||
err = ctx.WriteVendorFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ctx.Alter()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove existing.
|
||||
for _, r := range remove {
|
||||
err = context.RemovePackage(r, "", false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return os.Remove(filepath.Join(ctx.RootDir, "internal", "vendor.json"))
|
||||
}
|
||||
|
||||
type sysOldVendor struct{}
|
||||
|
||||
func (sys sysOldVendor) Check(root string) (system, error) {
|
||||
if hasDirs(root, "vendor") && hasFiles(root, "vendor.json") {
|
||||
return sys, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
func (sysOldVendor) Migrate(root string) error {
|
||||
ctx, err := context.NewContext(root, "vendor.json", "vendor", false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.VendorFilePath = filepath.Join(ctx.RootDir, "vendor", "vendor.json")
|
||||
err = ctx.WriteVendorFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Remove(filepath.Join(ctx.RootDir, "vendor.json"))
|
||||
}
|
||||
50
tools/vendor/github.com/kardianos/govendor/pkgspec/pkg.go
generated
vendored
Normal file
50
tools/vendor/github.com/kardianos/govendor/pkgspec/pkg.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright 2016 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 pkgspec defines a schema that contains the path, origin, version
|
||||
// and other properties.
|
||||
package pkgspec
|
||||
|
||||
import "bytes"
|
||||
|
||||
type Pkg struct {
|
||||
Path string
|
||||
FilePath string
|
||||
Origin string
|
||||
IncludeTree bool
|
||||
MatchTree bool
|
||||
HasVersion bool
|
||||
HasOrigin bool
|
||||
Version string
|
||||
|
||||
Uncommitted bool
|
||||
}
|
||||
|
||||
func (pkg *Pkg) String() string {
|
||||
buf := &bytes.Buffer{}
|
||||
buf.WriteString(pkg.Path)
|
||||
if pkg.IncludeTree {
|
||||
buf.WriteString(TreeIncludeSuffix)
|
||||
} else if pkg.MatchTree {
|
||||
buf.WriteString(TreeMatchSuffix)
|
||||
}
|
||||
if len(pkg.Origin) > 0 {
|
||||
buf.WriteString(originMatch)
|
||||
buf.WriteString(pkg.Origin)
|
||||
}
|
||||
if pkg.HasVersion {
|
||||
buf.WriteString(versionMatch)
|
||||
if len(pkg.Version) > 0 {
|
||||
buf.WriteString(pkg.Version)
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (pkg *Pkg) PathOrigin() string {
|
||||
if len(pkg.Origin) > 0 {
|
||||
return pkg.Origin
|
||||
}
|
||||
return pkg.Path
|
||||
}
|
||||
99
tools/vendor/github.com/kardianos/govendor/pkgspec/pkgspec.go
generated
vendored
Normal file
99
tools/vendor/github.com/kardianos/govendor/pkgspec/pkgspec.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright 2016 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 pkgspec parses the package specification string
|
||||
package pkgspec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
TreeIncludeSuffix = "/^"
|
||||
TreeMatchSuffix = "/..."
|
||||
)
|
||||
|
||||
const (
|
||||
originMatch = "::"
|
||||
versionMatch = "@"
|
||||
vendorSegment = "/vendor/"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrEmptyPath = errors.New("Empty package path")
|
||||
ErrEmptyOrigin = errors.New("Empty origin specified")
|
||||
ErrInvalidPath = errors.New("Path contains a vendor folder and a origin")
|
||||
)
|
||||
|
||||
// Parse a package spec according to:
|
||||
// package-spec = <path>[{/...|/^}][::<origin>][@[<version-spec>]]
|
||||
func Parse(currentGoPath, s string) (*Pkg, error) {
|
||||
// Clean up the import path before
|
||||
s = strings.Trim(s, "/\\ \t")
|
||||
if len(s) == 0 {
|
||||
return nil, ErrEmptyPath
|
||||
}
|
||||
s = strings.Replace(s, `\`, `/`, -1)
|
||||
|
||||
originIndex := strings.Index(s, originMatch)
|
||||
versionIndex := strings.LastIndex(s, versionMatch)
|
||||
|
||||
if originIndex == 0 {
|
||||
return nil, ErrEmptyPath
|
||||
}
|
||||
|
||||
// Don't count the origin if it is after the "@" symbol.
|
||||
if originIndex > versionIndex && versionIndex > 0 {
|
||||
originIndex = -1
|
||||
}
|
||||
|
||||
pkg := &Pkg{
|
||||
Path: s,
|
||||
HasOrigin: (originIndex >= 0),
|
||||
}
|
||||
|
||||
if versionIndex > 0 {
|
||||
pkg.Path = s[:versionIndex]
|
||||
pkg.Version = s[versionIndex+len(versionMatch):]
|
||||
pkg.HasVersion = true
|
||||
}
|
||||
if originIndex > 0 {
|
||||
pkg.Path = s[:originIndex]
|
||||
endOrigin := len(s)
|
||||
if versionIndex > 0 {
|
||||
endOrigin = versionIndex
|
||||
}
|
||||
pkg.Origin = s[originIndex+len(originMatch) : endOrigin]
|
||||
if len(pkg.Origin) == 0 {
|
||||
return nil, ErrEmptyOrigin
|
||||
}
|
||||
}
|
||||
// Look for vendor folder in package path.
|
||||
// This is allowed in origin, but not path.
|
||||
vendorIndex := strings.LastIndex(pkg.Path, vendorSegment)
|
||||
if vendorIndex >= 0 {
|
||||
if len(pkg.Origin) > 0 {
|
||||
return nil, ErrInvalidPath
|
||||
}
|
||||
pkg.Origin = pkg.Path
|
||||
pkg.Path = pkg.Path[vendorIndex+len(vendorSegment):]
|
||||
}
|
||||
|
||||
if strings.HasSuffix(pkg.Path, TreeMatchSuffix) {
|
||||
pkg.MatchTree = true
|
||||
pkg.Path = strings.TrimSuffix(pkg.Path, TreeMatchSuffix)
|
||||
} else if strings.HasSuffix(pkg.Path, TreeIncludeSuffix) {
|
||||
pkg.IncludeTree = true
|
||||
pkg.Path = strings.TrimSuffix(pkg.Path, TreeIncludeSuffix)
|
||||
}
|
||||
if strings.HasPrefix(pkg.Path, ".") && len(currentGoPath) != 0 {
|
||||
currentGoPath = strings.Replace(currentGoPath, `\`, `/`, -1)
|
||||
currentGoPath = strings.TrimPrefix(currentGoPath, "/")
|
||||
pkg.Path = path.Join(currentGoPath, pkg.Path)
|
||||
}
|
||||
|
||||
return pkg, nil
|
||||
}
|
||||
117
tools/vendor/github.com/kardianos/govendor/prompt/prompt.go
generated
vendored
Normal file
117
tools/vendor/github.com/kardianos/govendor/prompt/prompt.go
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// Copyright 2016 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 prompt prompts user for feedback.
|
||||
package prompt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Option struct {
|
||||
key interface{}
|
||||
prompt string
|
||||
validation string
|
||||
other bool
|
||||
|
||||
Choosen bool // Set to true if choosen.
|
||||
Value string // Value used if choosen and option is "other".
|
||||
}
|
||||
|
||||
type OptionType byte
|
||||
|
||||
const (
|
||||
TypeSelectOne OptionType = iota // Allow user to choose single option.
|
||||
TypeSelectMultiple // Allow user to choose multiple options.
|
||||
)
|
||||
|
||||
type Response byte
|
||||
|
||||
const (
|
||||
RespAnswer Response = iota
|
||||
RespCancel
|
||||
)
|
||||
|
||||
func NewOption(key interface{}, prompt string, other bool) Option {
|
||||
return Option{key: key, prompt: prompt, other: other}
|
||||
}
|
||||
|
||||
func (opt Option) Key() interface{} {
|
||||
return opt.key
|
||||
}
|
||||
func (opt Option) Prompt() string {
|
||||
return opt.prompt
|
||||
}
|
||||
func (opt Option) Other() bool {
|
||||
return opt.other
|
||||
}
|
||||
func (opt Option) Validation() string {
|
||||
return opt.validation
|
||||
}
|
||||
func (opt Option) String() string {
|
||||
if opt.other {
|
||||
return opt.Value
|
||||
}
|
||||
return fmt.Sprintf("%v", opt.key)
|
||||
}
|
||||
|
||||
func ValidateOption(opt Option, validation string) Option {
|
||||
return Option{
|
||||
key: opt.key,
|
||||
prompt: opt.prompt,
|
||||
other: opt.other,
|
||||
|
||||
validation: validation,
|
||||
|
||||
Choosen: opt.Choosen,
|
||||
Value: opt.Value,
|
||||
}
|
||||
}
|
||||
|
||||
type Question struct {
|
||||
Error string
|
||||
Prompt string
|
||||
Type OptionType
|
||||
Options []Option
|
||||
}
|
||||
|
||||
func (q *Question) AnswerMultiple(must bool) []*Option {
|
||||
ans := []*Option{}
|
||||
for i := range q.Options {
|
||||
o := &q.Options[i]
|
||||
if o.Choosen {
|
||||
ans = append(ans, o)
|
||||
}
|
||||
}
|
||||
if must && len(ans) == 0 {
|
||||
panic("If no option is choosen, response must be cancelled")
|
||||
}
|
||||
return ans
|
||||
}
|
||||
|
||||
func (q *Question) AnswerSingle(must bool) *Option {
|
||||
var ans *Option
|
||||
if q.Type != TypeSelectOne {
|
||||
panic("Question Type should match answer type")
|
||||
}
|
||||
found := false
|
||||
for i := range q.Options {
|
||||
o := &q.Options[i]
|
||||
if found && o.Choosen {
|
||||
panic("Must only respond with single option")
|
||||
}
|
||||
if o.Choosen {
|
||||
found = true
|
||||
ans = o
|
||||
}
|
||||
}
|
||||
if must && !found {
|
||||
panic("If no option is choosen, response must be cancelled")
|
||||
}
|
||||
return ans
|
||||
}
|
||||
|
||||
type Prompt interface {
|
||||
Ask(q *Question) (Response, error)
|
||||
}
|
||||
156
tools/vendor/github.com/kardianos/govendor/run/command.go
generated
vendored
Normal file
156
tools/vendor/github.com/kardianos/govendor/run/command.go
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
// Copyright 2016 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 run
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/kardianos/govendor/context"
|
||||
"github.com/kardianos/govendor/help"
|
||||
"github.com/kardianos/govendor/migrate"
|
||||
)
|
||||
|
||||
func (r *runner) Init(w io.Writer, subCmdArgs []string) (help.HelpMessage, error) {
|
||||
flags := flag.NewFlagSet("init", flag.ContinueOnError)
|
||||
flags.SetOutput(nullWriter{})
|
||||
err := flags.Parse(subCmdArgs)
|
||||
if err != nil {
|
||||
return help.MsgInit, err
|
||||
}
|
||||
ctx, err := r.NewContextWD(context.RootWD)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
ctx.VendorFile.Ignore = "test" // Add default ignore rule.
|
||||
err = ctx.WriteVendorFile()
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
err = os.MkdirAll(filepath.Join(ctx.RootDir, ctx.VendorFolder), 0777)
|
||||
return help.MsgNone, err
|
||||
}
|
||||
func (r *runner) Migrate(w io.Writer, subCmdArgs []string) (help.HelpMessage, error) {
|
||||
flags := flag.NewFlagSet("migrate", flag.ContinueOnError)
|
||||
flags.SetOutput(nullWriter{})
|
||||
err := flags.Parse(subCmdArgs)
|
||||
if err != nil {
|
||||
return help.MsgMigrate, err
|
||||
}
|
||||
|
||||
from := migrate.From("auto")
|
||||
if len(flags.Args()) > 0 {
|
||||
from = migrate.From(flags.Arg(0))
|
||||
}
|
||||
err = migrate.MigrateWD(from)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
fmt.Fprintf(w, `You may wish to run "govendor sync" now.%s`, "\n")
|
||||
return help.MsgNone, nil
|
||||
}
|
||||
|
||||
func (r *runner) Get(w io.Writer, subCmdArgs []string) (help.HelpMessage, error) {
|
||||
flags := flag.NewFlagSet("get", flag.ContinueOnError)
|
||||
flags.SetOutput(nullWriter{})
|
||||
|
||||
insecure := flags.Bool("insecure", false, "allows insecure connection")
|
||||
verbose := flags.Bool("v", false, "verbose")
|
||||
|
||||
flags.Bool("u", false, "update") // For compatibility with "go get".
|
||||
|
||||
err := flags.Parse(subCmdArgs)
|
||||
if err != nil {
|
||||
return help.MsgGet, err
|
||||
}
|
||||
logger := w
|
||||
if !*verbose {
|
||||
logger = nil
|
||||
}
|
||||
for _, a := range flags.Args() {
|
||||
pkg, err := context.Get(logger, a, *insecure)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
|
||||
r.GoCmd("install", []string{pkg.Path})
|
||||
}
|
||||
return help.MsgNone, nil
|
||||
}
|
||||
|
||||
func (r *runner) GoCmd(subcmd string, args []string) (help.HelpMessage, error) {
|
||||
ctx, err := r.NewContextWD(context.RootVendorOrWD)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
list, err := ctx.Status()
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
cgp, err := currentGoPath(ctx)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
|
||||
otherArgs := make([]string, 1, len(args)+1)
|
||||
otherArgs[0] = subcmd
|
||||
|
||||
// Expand any status flags in-place. Some wrapped commands the order is
|
||||
// important to the operation of the command.
|
||||
for _, a := range args {
|
||||
if a[0] == '+' {
|
||||
f, err := parseFilter(cgp, []string{a})
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
for _, item := range list {
|
||||
if f.HasStatus(item) {
|
||||
add := item.Local
|
||||
// "go tool vet" takes dirs, not pkgs, so special case it.
|
||||
if subcmd == "tool" && len(args) > 0 && args[0] == "vet" {
|
||||
add = filepath.Join(ctx.RootGopath, add)
|
||||
}
|
||||
otherArgs = append(otherArgs, add)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
otherArgs = append(otherArgs, a)
|
||||
}
|
||||
}
|
||||
|
||||
cmd := exec.Command("go", otherArgs...)
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = os.Stdout
|
||||
return help.MsgNone, cmd.Run()
|
||||
}
|
||||
|
||||
func (r *runner) Status(w io.Writer, subCmdArgs []string) (help.HelpMessage, error) {
|
||||
flags := flag.NewFlagSet("status", flag.ContinueOnError)
|
||||
flags.SetOutput(nullWriter{})
|
||||
err := flags.Parse(subCmdArgs)
|
||||
if err != nil {
|
||||
return help.MsgStatus, err
|
||||
}
|
||||
ctx, err := r.NewContextWD(context.RootVendor)
|
||||
if err != nil {
|
||||
return help.MsgStatus, err
|
||||
}
|
||||
outOfDate, err := ctx.VerifyVendor()
|
||||
if err != nil {
|
||||
return help.MsgStatus, err
|
||||
}
|
||||
if len(outOfDate) == 0 {
|
||||
return help.MsgNone, nil
|
||||
}
|
||||
fmt.Fprintf(w, "The following packages are missing or modified locally:\n")
|
||||
for _, pkg := range outOfDate {
|
||||
fmt.Fprintf(w, "\t%s\n", pkg.Path)
|
||||
}
|
||||
return help.MsgNone, fmt.Errorf("status failed for %d package(s)", len(outOfDate))
|
||||
}
|
||||
179
tools/vendor/github.com/kardianos/govendor/run/filter.go
generated
vendored
Normal file
179
tools/vendor/github.com/kardianos/govendor/run/filter.go
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
// Copyright 2016 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 run
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/kardianos/govendor/context"
|
||||
"github.com/kardianos/govendor/internal/pathos"
|
||||
"github.com/kardianos/govendor/pkgspec"
|
||||
)
|
||||
|
||||
var (
|
||||
outside = []context.Status{
|
||||
{Location: context.LocationExternal},
|
||||
{Presence: context.PresenceMissing},
|
||||
}
|
||||
normal = []context.Status{
|
||||
{Location: context.LocationExternal},
|
||||
{Location: context.LocationVendor},
|
||||
{Location: context.LocationLocal},
|
||||
{Location: context.LocationNotFound},
|
||||
}
|
||||
all = []context.Status{
|
||||
{Location: context.LocationStandard},
|
||||
{Location: context.LocationExternal},
|
||||
{Location: context.LocationVendor},
|
||||
{Location: context.LocationLocal},
|
||||
{Location: context.LocationNotFound},
|
||||
}
|
||||
)
|
||||
|
||||
func statusGroupFromList(list []context.Status, and, not bool) context.StatusGroup {
|
||||
sg := context.StatusGroup{
|
||||
Not: not,
|
||||
And: and,
|
||||
}
|
||||
for _, s := range list {
|
||||
sg.Status = append(sg.Status, s)
|
||||
}
|
||||
return sg
|
||||
}
|
||||
|
||||
const notOp = "^"
|
||||
|
||||
func parseStatusGroup(statusString string) (sg context.StatusGroup, err error) {
|
||||
ss := strings.Split(statusString, ",")
|
||||
sg.And = true
|
||||
for _, s := range ss {
|
||||
st := context.Status{}
|
||||
if strings.HasPrefix(s, notOp) {
|
||||
st.Not = true
|
||||
s = strings.TrimPrefix(s, notOp)
|
||||
}
|
||||
var list []context.Status
|
||||
switch {
|
||||
case strings.HasPrefix("external", s):
|
||||
st.Location = context.LocationExternal
|
||||
case strings.HasPrefix("vendor", s):
|
||||
st.Location = context.LocationVendor
|
||||
case strings.HasPrefix("unused", s):
|
||||
st.Presence = context.PresenceUnused
|
||||
case strings.HasPrefix("missing", s):
|
||||
st.Presence = context.PresenceMissing
|
||||
case strings.HasPrefix("xcluded", s):
|
||||
st.Presence = context.PresenceExcluded
|
||||
case len(s) >= 3 && strings.HasPrefix("excluded", s): // len >= 3 to distinguish from "external"
|
||||
st.Presence = context.PresenceExcluded
|
||||
case strings.HasPrefix("local", s):
|
||||
st.Location = context.LocationLocal
|
||||
case strings.HasPrefix("program", s):
|
||||
st.Type = context.TypeProgram
|
||||
case strings.HasPrefix("std", s):
|
||||
st.Location = context.LocationStandard
|
||||
case strings.HasPrefix("standard", s):
|
||||
st.Location = context.LocationStandard
|
||||
case strings.HasPrefix("all", s):
|
||||
list = all
|
||||
case strings.HasPrefix("normal", s):
|
||||
list = normal
|
||||
case strings.HasPrefix("outside", s):
|
||||
list = outside
|
||||
default:
|
||||
err = fmt.Errorf("unknown status %q", s)
|
||||
return
|
||||
}
|
||||
if len(list) == 0 {
|
||||
sg.Status = append(sg.Status, st)
|
||||
} else {
|
||||
sg.Group = append(sg.Group, statusGroupFromList(list, false, st.Not))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type filter struct {
|
||||
Status context.StatusGroup
|
||||
Import []*pkgspec.Pkg
|
||||
}
|
||||
|
||||
func (f filter) String() string {
|
||||
return fmt.Sprintf("status %q, import: %q", f.Status, f.Import)
|
||||
}
|
||||
|
||||
func (f filter) HasStatus(item context.StatusItem) bool {
|
||||
return item.Status.MatchGroup(f.Status)
|
||||
}
|
||||
func (f filter) FindImport(item context.StatusItem) *pkgspec.Pkg {
|
||||
for _, imp := range f.Import {
|
||||
if imp.Path == item.Local || imp.Path == item.Pkg.Path {
|
||||
return imp
|
||||
}
|
||||
if imp.MatchTree {
|
||||
if strings.HasPrefix(item.Local, imp.Path) || strings.HasPrefix(item.Pkg.Path, imp.Path) {
|
||||
return imp
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func currentGoPath(ctx *context.Context) (string, error) {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
wdpath := pathos.FileTrimPrefix(wd, ctx.RootGopath)
|
||||
wdpath = pathos.SlashToFilepath(wdpath)
|
||||
wdpath = strings.Trim(wdpath, "/")
|
||||
return wdpath, nil
|
||||
}
|
||||
|
||||
func parseFilter(currentGoPath string, args []string) (filter, error) {
|
||||
f := filter{
|
||||
Import: make([]*pkgspec.Pkg, 0, len(args)),
|
||||
}
|
||||
for _, a := range args {
|
||||
if len(a) == 0 {
|
||||
continue
|
||||
}
|
||||
// Check if item is a status.
|
||||
if a[0] == '+' {
|
||||
sg, err := parseStatusGroup(a[1:])
|
||||
if err != nil {
|
||||
return f, err
|
||||
}
|
||||
f.Status.Group = append(f.Status.Group, sg)
|
||||
} else {
|
||||
pkg, err := pkgspec.Parse(currentGoPath, a)
|
||||
if err != nil {
|
||||
return f, err
|
||||
}
|
||||
f.Import = append(f.Import, pkg)
|
||||
}
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func insertListToAllNot(sg *context.StatusGroup, list []context.Status) {
|
||||
if len(sg.Group) == 0 {
|
||||
allStatusNot := true
|
||||
for _, s := range sg.Status {
|
||||
if s.Not == false {
|
||||
allStatusNot = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if allStatusNot {
|
||||
sg.Group = append(sg.Group, statusGroupFromList(list, false, false))
|
||||
}
|
||||
}
|
||||
for i := range sg.Group {
|
||||
insertListToAllNot(&sg.Group[i], list)
|
||||
}
|
||||
}
|
||||
107
tools/vendor/github.com/kardianos/govendor/run/license.go
generated
vendored
Normal file
107
tools/vendor/github.com/kardianos/govendor/run/license.go
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// Copyright 2016 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 run
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"text/template"
|
||||
|
||||
"github.com/kardianos/govendor/context"
|
||||
"github.com/kardianos/govendor/help"
|
||||
)
|
||||
|
||||
var defaultLicenseTemplate = `{{range $index, $t := .}}{{if ne $index 0}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
{{end}}{{.Filename}} - {{.Path}}
|
||||
{{.Text}}{{end}}
|
||||
`
|
||||
|
||||
func (r *runner) License(w io.Writer, subCmdArgs []string) (help.HelpMessage, error) {
|
||||
flags := flag.NewFlagSet("license", flag.ContinueOnError)
|
||||
flags.SetOutput(nullWriter{})
|
||||
outputFilename := flags.String("o", "", "output")
|
||||
templateFilename := flags.String("template", "", "custom template file")
|
||||
err := flags.Parse(subCmdArgs)
|
||||
if err != nil {
|
||||
return help.MsgLicense, err
|
||||
}
|
||||
args := flags.Args()
|
||||
|
||||
templateText := defaultLicenseTemplate
|
||||
if len(*templateFilename) > 0 {
|
||||
text, err := ioutil.ReadFile(*templateFilename)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
templateText = string(text)
|
||||
}
|
||||
t, err := template.New("").Parse(templateText)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
output := w
|
||||
if len(*outputFilename) > 0 {
|
||||
f, err := os.Create(*outputFilename)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
defer f.Close()
|
||||
output = f
|
||||
}
|
||||
|
||||
ctx, err := r.NewContextWD(context.RootVendorOrWD)
|
||||
if err != nil {
|
||||
return checkNewContextError(err)
|
||||
}
|
||||
cgp, err := currentGoPath(ctx)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
f, err := parseFilter(cgp, args)
|
||||
if err != nil {
|
||||
return help.MsgLicense, err
|
||||
}
|
||||
if len(f.Import) == 0 {
|
||||
insertListToAllNot(&f.Status, normal)
|
||||
} else {
|
||||
insertListToAllNot(&f.Status, all)
|
||||
}
|
||||
|
||||
list, err := ctx.Status()
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
var licenseList context.LicenseSort
|
||||
var lmap = make(map[string]context.License, 9)
|
||||
|
||||
err = context.LicenseDiscover(filepath.Clean(filepath.Join(ctx.Goroot, "..")), ctx.Goroot, " go", lmap)
|
||||
if err != nil {
|
||||
return help.MsgNone, fmt.Errorf("Failed to discover license for Go %q %v", ctx.Goroot, err)
|
||||
}
|
||||
|
||||
for _, item := range list {
|
||||
if f.HasStatus(item) == false {
|
||||
continue
|
||||
}
|
||||
if len(f.Import) != 0 && f.FindImport(item) == nil {
|
||||
continue
|
||||
}
|
||||
err = context.LicenseDiscover(ctx.RootGopath, filepath.Join(ctx.RootGopath, item.Local), "", lmap)
|
||||
if err != nil {
|
||||
return help.MsgNone, fmt.Errorf("Failed to discover license for %q %v", item.Local, err)
|
||||
}
|
||||
}
|
||||
for _, l := range lmap {
|
||||
licenseList = append(licenseList, l)
|
||||
}
|
||||
sort.Sort(licenseList)
|
||||
|
||||
return help.MsgNone, t.Execute(output, licenseList)
|
||||
}
|
||||
132
tools/vendor/github.com/kardianos/govendor/run/list.go
generated
vendored
Normal file
132
tools/vendor/github.com/kardianos/govendor/run/list.go
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
// Copyright 2016 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 run
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/kardianos/govendor/context"
|
||||
"github.com/kardianos/govendor/help"
|
||||
)
|
||||
|
||||
func (r *runner) List(w io.Writer, subCmdArgs []string) (help.HelpMessage, error) {
|
||||
listFlags := flag.NewFlagSet("list", flag.ContinueOnError)
|
||||
listFlags.SetOutput(nullWriter{})
|
||||
verbose := listFlags.Bool("v", false, "verbose")
|
||||
asFilePath := listFlags.Bool("p", false, "show file path to package instead of import path")
|
||||
noStatus := listFlags.Bool("no-status", false, "do not show the status")
|
||||
err := listFlags.Parse(subCmdArgs)
|
||||
if err != nil {
|
||||
return help.MsgList, err
|
||||
}
|
||||
args := listFlags.Args()
|
||||
// fmt.Printf("Status: %q\n", f.Status)
|
||||
|
||||
// Print all listed status.
|
||||
ctx, err := r.NewContextWD(context.RootVendorOrWD)
|
||||
if err != nil {
|
||||
return checkNewContextError(err)
|
||||
}
|
||||
cgp, err := currentGoPath(ctx)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
f, err := parseFilter(cgp, args)
|
||||
if err != nil {
|
||||
return help.MsgList, err
|
||||
}
|
||||
if len(f.Import) == 0 {
|
||||
insertListToAllNot(&f.Status, normal)
|
||||
} else {
|
||||
insertListToAllNot(&f.Status, all)
|
||||
}
|
||||
|
||||
list, err := ctx.Status()
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
|
||||
// If not verbose, remove any entries that will just confuse people.
|
||||
// For example, one package may reference pkgA inside vendor, another
|
||||
// package may reference pkgA outside vendor, resulting in both a
|
||||
// external reference and a vendor reference.
|
||||
// In the above case, remove the external reference.
|
||||
if !*verbose {
|
||||
next := make([]context.StatusItem, 0, len(list))
|
||||
for checkIndex, check := range list {
|
||||
if check.Status.Location != context.LocationExternal {
|
||||
next = append(next, check)
|
||||
continue
|
||||
}
|
||||
found := false
|
||||
for lookIndex, look := range list {
|
||||
if checkIndex == lookIndex {
|
||||
continue
|
||||
}
|
||||
if check.Pkg.Path != look.Pkg.Path {
|
||||
continue
|
||||
}
|
||||
if look.Status.Location == context.LocationVendor {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
next = append(next, check)
|
||||
}
|
||||
}
|
||||
list = next
|
||||
}
|
||||
|
||||
formatSame := "%[1]v %[2]s\t%[3]s\t%[4]s\n"
|
||||
formatDifferent := "%[1]v %[2]s\t%[4]s\t%[5]s\n"
|
||||
if *verbose {
|
||||
formatDifferent = "%[1]v %[2]s ::%[3]s\t%[4]s\t%[5]s\n"
|
||||
}
|
||||
if *noStatus {
|
||||
formatSame = "%[2]s\n"
|
||||
formatDifferent = "%[2]s\n"
|
||||
if *verbose {
|
||||
formatDifferent = "%[2]s ::%[3]s\n"
|
||||
}
|
||||
}
|
||||
tw := tabwriter.NewWriter(w, 0, 4, 2, ' ', 0)
|
||||
defer tw.Flush()
|
||||
for _, item := range list {
|
||||
if f.HasStatus(item) == false {
|
||||
continue
|
||||
}
|
||||
if len(f.Import) != 0 && f.FindImport(item) == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var path string
|
||||
if *asFilePath {
|
||||
path = item.Pkg.FilePath
|
||||
} else {
|
||||
path = item.Pkg.Path
|
||||
}
|
||||
|
||||
if item.Local == item.Pkg.Path {
|
||||
fmt.Fprintf(tw, formatSame, item.Status, path, item.Pkg.Version, item.VersionExact)
|
||||
} else {
|
||||
fmt.Fprintf(tw, formatDifferent, item.Status, path, strings.TrimPrefix(item.Local, ctx.RootImportPath), item.Pkg.Version, item.VersionExact)
|
||||
}
|
||||
if *verbose {
|
||||
for i, imp := range item.ImportedBy {
|
||||
if i != len(item.ImportedBy)-1 {
|
||||
fmt.Fprintf(tw, " ├── %s %s\n", imp.Status, imp)
|
||||
} else {
|
||||
fmt.Fprintf(tw, " └── %s %s\n", imp.Status, imp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return help.MsgNone, nil
|
||||
}
|
||||
161
tools/vendor/github.com/kardianos/govendor/run/modify.go
generated
vendored
Normal file
161
tools/vendor/github.com/kardianos/govendor/run/modify.go
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
// Copyright 2016 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 run
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/kardianos/govendor/context"
|
||||
"github.com/kardianos/govendor/help"
|
||||
"github.com/kardianos/govendor/prompt"
|
||||
)
|
||||
|
||||
func (r *runner) Modify(w io.Writer, subCmdArgs []string, mod context.Modify, ask prompt.Prompt) (help.HelpMessage, error) {
|
||||
msg := help.MsgFull
|
||||
switch mod {
|
||||
case context.Add:
|
||||
msg = help.MsgAdd
|
||||
case context.Update, context.AddUpdate:
|
||||
msg = help.MsgUpdate
|
||||
case context.Remove:
|
||||
msg = help.MsgRemove
|
||||
case context.Fetch:
|
||||
msg = help.MsgFetch
|
||||
}
|
||||
var err error
|
||||
/*
|
||||
// Fake example prompt.
|
||||
q := &prompt.Question{
|
||||
Error: "An error goes here",
|
||||
Prompt: "Do you want to do this?",
|
||||
Type: prompt.TypeSelectOne,
|
||||
Options: []prompt.Option{
|
||||
prompt.NewOption("yes", "Yes, continue", false),
|
||||
prompt.NewOption("no", "No, stop", false),
|
||||
prompt.NewOption("", "What?", true),
|
||||
},
|
||||
}
|
||||
q.Options[2].Choosen = true
|
||||
q.Options[2] = prompt.ValidateOption(q.Options[2], "Choose again!")
|
||||
resp, err := ask.Ask(q)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
if resp == prompt.RespCancel {
|
||||
fmt.Printf("Cancelled\n")
|
||||
return help.MsgNone, nil
|
||||
}
|
||||
choosen := q.AnswerSingle(true)
|
||||
|
||||
fmt.Printf("Choosen: %s\n", choosen.String())
|
||||
*/
|
||||
|
||||
listFlags := flag.NewFlagSet("mod", flag.ContinueOnError)
|
||||
listFlags.SetOutput(nullWriter{})
|
||||
dryrun := listFlags.Bool("n", false, "dry-run")
|
||||
verbose := listFlags.Bool("v", false, "verbose")
|
||||
short := listFlags.Bool("short", false, "choose the short path")
|
||||
long := listFlags.Bool("long", false, "choose the long path")
|
||||
tree := listFlags.Bool("tree", false, "copy all folders including and under selected folder")
|
||||
insecure := listFlags.Bool("insecure", false, "allow insecure network updates")
|
||||
uncommitted := listFlags.Bool("uncommitted", false, "allows adding uncommitted changes. Doesn't update revision or checksum")
|
||||
err = listFlags.Parse(subCmdArgs)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
if *short && *long {
|
||||
return help.MsgNone, errors.New("cannot select both long and short path")
|
||||
}
|
||||
args := listFlags.Args()
|
||||
if len(args) == 0 {
|
||||
return msg, errors.New("missing package or status")
|
||||
}
|
||||
ctx, err := r.NewContextWD(context.RootVendor)
|
||||
if err != nil {
|
||||
return checkNewContextError(err)
|
||||
}
|
||||
if *verbose {
|
||||
ctx.Logger = w
|
||||
}
|
||||
ctx.Insecure = *insecure
|
||||
cgp, err := currentGoPath(ctx)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
f, err := parseFilter(cgp, args)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
|
||||
mops := make([]context.ModifyOption, 0, 3)
|
||||
if *uncommitted {
|
||||
mops = append(mops, context.Uncommitted)
|
||||
}
|
||||
if *tree {
|
||||
mops = append(mops, context.IncludeTree)
|
||||
}
|
||||
|
||||
// Add explicit imports.
|
||||
for _, imp := range f.Import {
|
||||
err = ctx.ModifyImport(imp, mod, mops...)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
}
|
||||
err = ctx.ModifyStatus(f.Status, mod, mops...)
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
|
||||
// Auto-resolve package conflicts.
|
||||
conflicts := ctx.Check()
|
||||
conflicts = ctx.ResolveAutoVendorFileOrigin(conflicts)
|
||||
if *long {
|
||||
conflicts = context.ResolveAutoLongestPath(conflicts)
|
||||
}
|
||||
if *short {
|
||||
conflicts = context.ResolveAutoShortestPath(conflicts)
|
||||
}
|
||||
ctx.ResloveApply(conflicts)
|
||||
|
||||
// TODO: loop through conflicts to see if there are any remaining conflicts.
|
||||
// Print out any here.
|
||||
|
||||
if *dryrun {
|
||||
for _, op := range ctx.Operation {
|
||||
switch op.Type {
|
||||
case context.OpRemove:
|
||||
fmt.Fprintf(w, "Remove %q\n", op.Src)
|
||||
case context.OpCopy:
|
||||
fmt.Fprintf(w, "Copy %q -> %q\n", op.Src, op.Dest)
|
||||
for _, ignore := range op.IgnoreFile {
|
||||
fmt.Fprintf(w, "\tIgnore %q\n", ignore)
|
||||
}
|
||||
case context.OpFetch:
|
||||
fmt.Fprintf(w, "Fetch %q\n", op.Src)
|
||||
}
|
||||
}
|
||||
return help.MsgNone, nil
|
||||
}
|
||||
|
||||
// Write intent, make the changes, then record any checksums or recursive info.
|
||||
err = ctx.WriteVendorFile()
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
// Write out vendor file and do change.
|
||||
err = ctx.Alter()
|
||||
vferr := ctx.WriteVendorFile()
|
||||
if err != nil {
|
||||
return help.MsgNone, err
|
||||
}
|
||||
if vferr != nil {
|
||||
return help.MsgNone, vferr
|
||||
}
|
||||
return help.MsgNone, nil
|
||||
}
|
||||
117
tools/vendor/github.com/kardianos/govendor/run/run.go
generated
vendored
Normal file
117
tools/vendor/github.com/kardianos/govendor/run/run.go
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// Copyright 2015 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 run is a front-end to govendor.
|
||||
package run
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/kardianos/govendor/context"
|
||||
"github.com/kardianos/govendor/help"
|
||||
"github.com/kardianos/govendor/prompt"
|
||||
)
|
||||
|
||||
type nullWriter struct{}
|
||||
|
||||
func (nw nullWriter) Write(p []byte) (n int, err error) {
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
type runner struct {
|
||||
ctx *context.Context
|
||||
}
|
||||
|
||||
func (r *runner) NewContextWD(rt context.RootType) (*context.Context, error) {
|
||||
if r.ctx != nil {
|
||||
return r.ctx, nil
|
||||
}
|
||||
var err error
|
||||
r.ctx, err = context.NewContextWD(rt)
|
||||
return r.ctx, err
|
||||
}
|
||||
|
||||
// Run is isoloated from main and os.Args to help with testing.
|
||||
// Shouldn't directly print to console, just write through w.
|
||||
func Run(w io.Writer, appArgs []string, ask prompt.Prompt) (help.HelpMessage, error) {
|
||||
r := &runner{}
|
||||
return r.run(w, appArgs, ask)
|
||||
}
|
||||
func (r *runner) run(w io.Writer, appArgs []string, ask prompt.Prompt) (help.HelpMessage, error) {
|
||||
if len(appArgs) == 1 {
|
||||
return help.MsgFull, nil
|
||||
}
|
||||
|
||||
flags := flag.NewFlagSet("govendor", flag.ContinueOnError)
|
||||
licenses := flags.Bool("govendor-licenses", false, "show govendor's licenses")
|
||||
version := flags.Bool("version", false, "show govendor version")
|
||||
flags.SetOutput(nullWriter{})
|
||||
err := flags.Parse(appArgs[1:])
|
||||
if err != nil {
|
||||
return help.MsgFull, err
|
||||
}
|
||||
if *licenses {
|
||||
return help.MsgGovendorLicense, nil
|
||||
}
|
||||
if *version {
|
||||
return help.MsgGovendorVersion, nil
|
||||
}
|
||||
|
||||
args := flags.Args()
|
||||
|
||||
cmd := args[0]
|
||||
switch cmd {
|
||||
case "init":
|
||||
return r.Init(w, args[1:])
|
||||
case "list":
|
||||
return r.List(w, args[1:])
|
||||
case "add", "update", "remove", "fetch":
|
||||
var mod context.Modify
|
||||
switch cmd {
|
||||
case "add":
|
||||
mod = context.Add
|
||||
case "update":
|
||||
mod = context.Update
|
||||
case "remove":
|
||||
mod = context.Remove
|
||||
case "fetch":
|
||||
mod = context.Fetch
|
||||
}
|
||||
return r.Modify(w, args[1:], mod, ask)
|
||||
case "sync":
|
||||
return r.Sync(w, args[1:])
|
||||
case "status":
|
||||
return r.Status(w, args[1:])
|
||||
case "migrate":
|
||||
return r.Migrate(w, args[1:])
|
||||
case "get":
|
||||
return r.Get(w, args[1:])
|
||||
case "license":
|
||||
return r.License(w, args[1:])
|
||||
case "shell":
|
||||
return r.Shell(w, args[1:])
|
||||
case "fmt", "build", "install", "clean", "test", "vet", "generate", "tool":
|
||||
return r.GoCmd(cmd, args[1:])
|
||||
default:
|
||||
return help.MsgFull, fmt.Errorf("Unknown command %q", cmd)
|
||||
}
|
||||
}
|
||||
|
||||
func checkNewContextError(err error) (help.HelpMessage, error) {
|
||||
// Diagnose error, show current value of 1.5vendor, suggest alter.
|
||||
if err == nil {
|
||||
return help.MsgNone, nil
|
||||
}
|
||||
if _, is := err.(context.ErrMissingVendorFile); is {
|
||||
err = fmt.Errorf(`%v
|
||||
|
||||
Ensure the current folder or a parent folder contains a folder named "vendor".
|
||||
If in doubt, run "govendor init" in the project root.
|
||||
`, err)
|
||||
return help.MsgNone, err
|
||||
}
|
||||
return help.MsgNone, err
|
||||
}
|
||||
62
tools/vendor/github.com/kardianos/govendor/run/shell.go
generated
vendored
Normal file
62
tools/vendor/github.com/kardianos/govendor/run/shell.go
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright 2016 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 run
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/kardianos/govendor/help"
|
||||
|
||||
"github.com/Bowery/prompt"
|
||||
"github.com/google/shlex"
|
||||
)
|
||||
|
||||
func (r *runner) Shell(w io.Writer, subCmdArgs []string) (help.HelpMessage, error) {
|
||||
flags := flag.NewFlagSet("shell", flag.ContinueOnError)
|
||||
flags.SetOutput(nullWriter{})
|
||||
err := flags.Parse(subCmdArgs)
|
||||
if err != nil {
|
||||
return help.MsgShell, err
|
||||
}
|
||||
|
||||
out := os.Stdout
|
||||
|
||||
for {
|
||||
line, err := prompt.Basic("> ", false)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
args, err := shlex.Split(line)
|
||||
if err != nil {
|
||||
fmt.Fprintf(out, "%v", err.Error())
|
||||
}
|
||||
if len(args) == 0 {
|
||||
continue
|
||||
}
|
||||
cmd := args[0]
|
||||
next := make([]string, 0, len(args)+1)
|
||||
next = append(next, "govendor")
|
||||
args = append(next, args...)
|
||||
switch cmd {
|
||||
case "exit", "q", "quit", "/q":
|
||||
return help.MsgNone, nil
|
||||
case "shell":
|
||||
continue
|
||||
}
|
||||
msg, err := r.run(out, args, nil)
|
||||
if err != nil {
|
||||
fmt.Fprintf(out, "%v", err.Error())
|
||||
}
|
||||
msgText := msg.String()
|
||||
if len(msgText) > 0 {
|
||||
fmt.Fprintf(out, "%s\tType \"exit\" to exit.\n", msgText)
|
||||
}
|
||||
}
|
||||
|
||||
return help.MsgNone, nil
|
||||
}
|
||||
34
tools/vendor/github.com/kardianos/govendor/run/sync.go
generated
vendored
Normal file
34
tools/vendor/github.com/kardianos/govendor/run/sync.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2016 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 run
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"io"
|
||||
|
||||
"github.com/kardianos/govendor/context"
|
||||
"github.com/kardianos/govendor/help"
|
||||
)
|
||||
|
||||
func (r *runner) Sync(w io.Writer, subCmdArgs []string) (help.HelpMessage, error) {
|
||||
flags := flag.NewFlagSet("sync", flag.ContinueOnError)
|
||||
insecure := flags.Bool("insecure", false, "allow insecure network updates")
|
||||
dryrun := flags.Bool("n", false, "dry run, print what would be done")
|
||||
verbose := flags.Bool("v", false, "verbose output")
|
||||
flags.SetOutput(nullWriter{})
|
||||
err := flags.Parse(subCmdArgs)
|
||||
if err != nil {
|
||||
return help.MsgSync, err
|
||||
}
|
||||
ctx, err := r.NewContextWD(context.RootVendor)
|
||||
if err != nil {
|
||||
return help.MsgSync, err
|
||||
}
|
||||
ctx.Insecure = *insecure
|
||||
if *dryrun || *verbose {
|
||||
ctx.Logger = w
|
||||
}
|
||||
return help.MsgNone, ctx.Sync(*dryrun)
|
||||
}
|
||||
61
tools/vendor/github.com/kardianos/govendor/vcs/bzr.go
generated
vendored
Normal file
61
tools/vendor/github.com/kardianos/govendor/vcs/bzr.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2015 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/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
os "github.com/kardianos/govendor/internal/vos"
|
||||
)
|
||||
|
||||
type VcsBzr struct{}
|
||||
|
||||
func (VcsBzr) Find(dir string) (*VcsInfo, error) {
|
||||
fi, err := os.Stat(filepath.Join(dir, ".bzr"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if fi.IsDir() == false {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Get info.
|
||||
info := &VcsInfo{}
|
||||
|
||||
cmd := exec.Command("bzr", "status")
|
||||
cmd.Dir = dir
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if string(output) != "" {
|
||||
info.Dirty = true
|
||||
}
|
||||
|
||||
cmd = exec.Command("bzr", "log", "-r-1")
|
||||
cmd.Dir = dir
|
||||
output, err = cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
if strings.HasPrefix(line, "revno:") {
|
||||
info.Revision = strings.Split(strings.TrimSpace(strings.TrimPrefix(line, "revno:")), " ")[0]
|
||||
} else if strings.HasPrefix(line, "timestamp:") {
|
||||
tm, err := time.Parse("Mon 2006-01-02 15:04:05 -0700", strings.TrimSpace(strings.TrimPrefix(line, "timestamp:")))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info.RevisionTime = &tm
|
||||
}
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
55
tools/vendor/github.com/kardianos/govendor/vcs/git.go
generated
vendored
Normal file
55
tools/vendor/github.com/kardianos/govendor/vcs/git.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2015 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/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
os "github.com/kardianos/govendor/internal/vos"
|
||||
)
|
||||
|
||||
type VcsGit struct{}
|
||||
|
||||
func (VcsGit) Find(dir string) (*VcsInfo, error) {
|
||||
fi, err := os.Stat(filepath.Join(dir, ".git"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if fi.IsDir() == false {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Get info.
|
||||
info := &VcsInfo{}
|
||||
|
||||
cmd := exec.Command("git", "status", "--short")
|
||||
cmd.Dir = dir
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
info.Dirty = true
|
||||
}
|
||||
|
||||
cmd = exec.Command("git", "show", "--pretty=format:%H@%ai", "-s")
|
||||
cmd.Dir = dir
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
line := strings.TrimSpace(string(output))
|
||||
ss := strings.Split(line, "@")
|
||||
info.Revision = ss[0]
|
||||
tm, err := time.Parse("2006-01-02 15:04:05 -0700", ss[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info.RevisionTime = &tm
|
||||
return info, nil
|
||||
}
|
||||
65
tools/vendor/github.com/kardianos/govendor/vcs/hg.go
generated
vendored
Normal file
65
tools/vendor/github.com/kardianos/govendor/vcs/hg.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright 2015 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/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
os "github.com/kardianos/govendor/internal/vos"
|
||||
)
|
||||
|
||||
type VcsHg struct{}
|
||||
|
||||
func (VcsHg) Find(dir string) (*VcsInfo, error) {
|
||||
fi, err := os.Stat(filepath.Join(dir, ".hg"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if fi.IsDir() == false {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Get info.
|
||||
info := &VcsInfo{}
|
||||
|
||||
cmd := exec.Command("hg", "identify", "-i")
|
||||
cmd.Dir = dir
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rev := strings.TrimSpace(string(output))
|
||||
if strings.HasSuffix(rev, "+") {
|
||||
info.Dirty = true
|
||||
rev = strings.TrimSuffix(rev, "+")
|
||||
}
|
||||
|
||||
cmd = exec.Command("hg", "log", "-r", rev)
|
||||
cmd.Dir = dir
|
||||
output, err = cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
if strings.HasPrefix(line, "changeset:") {
|
||||
ss := strings.Split(line, ":")
|
||||
info.Revision = strings.TrimSpace(ss[len(ss)-1])
|
||||
}
|
||||
if strings.HasPrefix(line, "date:") {
|
||||
line = strings.TrimPrefix(line, "date:")
|
||||
tm, err := time.Parse("Mon Jan 02 15:04:05 2006 -0700", strings.TrimSpace(line))
|
||||
if err == nil {
|
||||
info.RevisionTime = &tm
|
||||
}
|
||||
}
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
60
tools/vendor/github.com/kardianos/govendor/vcs/svn.go
generated
vendored
Normal file
60
tools/vendor/github.com/kardianos/govendor/vcs/svn.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2016 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"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
os "github.com/kardianos/govendor/internal/vos"
|
||||
)
|
||||
|
||||
type VcsSvn struct{}
|
||||
|
||||
func (svn VcsSvn) Find(dir string) (*VcsInfo, error) {
|
||||
fi, err := os.Stat(filepath.Join(dir, ".svn"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if fi.IsDir() == false {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Get info.
|
||||
info := &VcsInfo{}
|
||||
|
||||
cmd := exec.Command("svn", "info", "--xml")
|
||||
cmd.Dir = dir
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return info, svn.parseInfo(output, info)
|
||||
}
|
||||
func (svn VcsSvn) parseInfo(output []byte, info *VcsInfo) error {
|
||||
var err error
|
||||
XX := struct {
|
||||
Commit struct {
|
||||
Revision string `xml:"revision,attr"`
|
||||
RevisionTime string `xml:"date"`
|
||||
} `xml:"entry>commit"`
|
||||
}{}
|
||||
err = xml.Unmarshal(output, &XX)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info.Revision = XX.Commit.Revision
|
||||
tm, err := time.Parse(time.RFC3339, XX.Commit.RevisionTime)
|
||||
if err == nil {
|
||||
info.RevisionTime = &tm
|
||||
}
|
||||
return nil
|
||||
}
|
||||
79
tools/vendor/github.com/kardianos/govendor/vcs/vcs.go
generated
vendored
Normal file
79
tools/vendor/github.com/kardianos/govendor/vcs/vcs.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2015 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 gets version control information from the file system.
|
||||
package vcs
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/kardianos/govendor/internal/pathos"
|
||||
)
|
||||
|
||||
// VcsInfo returns information about a given repo.
|
||||
type VcsInfo struct {
|
||||
Dirty bool
|
||||
Revision string
|
||||
RevisionTime *time.Time
|
||||
}
|
||||
|
||||
// Vcs represents a version control system.
|
||||
type Vcs interface {
|
||||
// Return nil VcsInfo if unable to determine VCS from directory.
|
||||
Find(dir string) (*VcsInfo, error)
|
||||
}
|
||||
|
||||
var vcsRegistry = []Vcs{
|
||||
VcsGit{},
|
||||
VcsHg{},
|
||||
VcsSvn{},
|
||||
VcsBzr{},
|
||||
}
|
||||
var registerSync = sync.Mutex{}
|
||||
|
||||
// RegisterVCS adds a new VCS to use.
|
||||
func RegisterVCS(vcs Vcs) {
|
||||
registerSync.Lock()
|
||||
defer registerSync.Unlock()
|
||||
|
||||
vcsRegistry = append(vcsRegistry, vcs)
|
||||
}
|
||||
|
||||
const looplimit = 10000
|
||||
|
||||
// FindVcs determines the version control information given a package dir and
|
||||
// lowest root dir.
|
||||
func FindVcs(root, packageDir string) (info *VcsInfo, err error) {
|
||||
if !filepath.IsAbs(root) {
|
||||
return nil, nil
|
||||
}
|
||||
if !filepath.IsAbs(packageDir) {
|
||||
return nil, nil
|
||||
}
|
||||
path := packageDir
|
||||
for i := 0; i <= looplimit; i++ {
|
||||
for _, vcs := range vcsRegistry {
|
||||
info, err = vcs.Find(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if info != nil {
|
||||
return info, nil
|
||||
}
|
||||
}
|
||||
|
||||
nextPath := filepath.Clean(filepath.Join(path, ".."))
|
||||
// Check for root.
|
||||
if nextPath == path {
|
||||
return nil, nil
|
||||
}
|
||||
if pathos.FileHasPrefix(nextPath, root) == false {
|
||||
return nil, nil
|
||||
}
|
||||
path = nextPath
|
||||
}
|
||||
panic("loop limit")
|
||||
}
|
||||
348
tools/vendor/github.com/kardianos/govendor/vendorfile/file.go
generated
vendored
Normal file
348
tools/vendor/github.com/kardianos/govendor/vendorfile/file.go
generated
vendored
Normal file
@@ -0,0 +1,348 @@
|
||||
// Copyright 2015 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 vendorfile is the meta-data file for vendoring.
|
||||
// Round-trips unknown fields.
|
||||
// It will also allow moving the vendor file to new locations.
|
||||
package vendorfile
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Name of the vendor file.
|
||||
const Name = "vendor.json"
|
||||
|
||||
// File is the structure of the vendor file.
|
||||
type File struct {
|
||||
RootPath string // Import path of vendor folder
|
||||
|
||||
Comment string
|
||||
|
||||
Ignore string
|
||||
|
||||
Package []*Package
|
||||
|
||||
// all preserves unknown values.
|
||||
all map[string]interface{}
|
||||
}
|
||||
|
||||
// Package represents each package.
|
||||
type Package struct {
|
||||
field map[string]interface{}
|
||||
|
||||
// If delete is set to true the package will not be written to the vendor file.
|
||||
Remove bool
|
||||
|
||||
// If new is set to true the package will be treated as a new package to the file.
|
||||
Add bool
|
||||
|
||||
// See the vendor spec for definitions.
|
||||
Origin string
|
||||
Path string
|
||||
Tree bool
|
||||
Revision string
|
||||
RevisionTime string
|
||||
Version string
|
||||
VersionExact string
|
||||
ChecksumSHA1 string
|
||||
Comment string
|
||||
}
|
||||
|
||||
func (pkg *Package) PathOrigin() string {
|
||||
if len(pkg.Origin) > 0 {
|
||||
return pkg.Origin
|
||||
}
|
||||
return pkg.Path
|
||||
}
|
||||
|
||||
// The following stringer functions are useful for debugging.
|
||||
|
||||
type packageList []*Package
|
||||
|
||||
func (list packageList) String() string {
|
||||
buf := &bytes.Buffer{}
|
||||
for _, item := range list {
|
||||
buf.WriteString("\t")
|
||||
buf.WriteString(fmt.Sprintf("(%v) ", item.field))
|
||||
if item.Remove {
|
||||
buf.WriteString(" X ")
|
||||
}
|
||||
buf.WriteString(item.Path)
|
||||
buf.WriteRune('\n')
|
||||
}
|
||||
buf.WriteRune('\n')
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func allString(all map[string]interface{}) string {
|
||||
obj, _ := all["package"]
|
||||
buf := &bytes.Buffer{}
|
||||
for _, itemObj := range obj.([]interface{}) {
|
||||
item := itemObj.(map[string]interface{})
|
||||
buf.WriteString("\t")
|
||||
buf.WriteString(item["path"].(string))
|
||||
buf.WriteRune('\n')
|
||||
}
|
||||
buf.WriteRune('\n')
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
var (
|
||||
rootPathNames = []string{"rootPath"}
|
||||
packageNames = []string{"package", "Package"}
|
||||
ignoreNames = []string{"ignore"}
|
||||
originNames = []string{"origin"}
|
||||
pathNames = []string{"path", "canonical", "Canonical", "vendor", "Vendor"}
|
||||
treeNames = []string{"tree"}
|
||||
revisionNames = []string{"revision", "Revision", "version", "Version"}
|
||||
revisionTimeNames = []string{"revisionTime", "RevisionTime", "versionTime", "VersionTime"}
|
||||
versionNames = []string{"version"}
|
||||
versionExactNames = []string{"versionExact"}
|
||||
checksumSHA1Names = []string{"checksumSHA1"}
|
||||
commentNames = []string{"comment", "Comment"}
|
||||
)
|
||||
|
||||
type vendorPackageSort []interface{}
|
||||
|
||||
func (vp vendorPackageSort) Len() int { return len(vp) }
|
||||
func (vp vendorPackageSort) Swap(i, j int) { vp[i], vp[j] = vp[j], vp[i] }
|
||||
func (vp vendorPackageSort) Less(i, j int) bool {
|
||||
a := vp[i].(map[string]interface{})
|
||||
b := vp[j].(map[string]interface{})
|
||||
aPath, _ := a[pathNames[0]].(string)
|
||||
bPath, _ := b[pathNames[0]].(string)
|
||||
|
||||
if aPath == bPath {
|
||||
aOrigin, _ := a[originNames[0]].(string)
|
||||
bOrigin, _ := b[originNames[0]].(string)
|
||||
return len(aOrigin) > len(bOrigin)
|
||||
}
|
||||
return aPath < bPath
|
||||
}
|
||||
|
||||
func setField(fieldObj interface{}, object map[string]interface{}, names []string) {
|
||||
loop:
|
||||
for _, name := range names {
|
||||
raw, found := object[name]
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
switch field := fieldObj.(type) {
|
||||
default:
|
||||
panic("unknown type")
|
||||
case *string:
|
||||
value, is := raw.(string)
|
||||
if !is {
|
||||
continue loop
|
||||
}
|
||||
*field = value
|
||||
if len(value) != 0 {
|
||||
break loop
|
||||
}
|
||||
case *bool:
|
||||
value, is := raw.(bool)
|
||||
if !is {
|
||||
continue loop
|
||||
}
|
||||
*field = value
|
||||
if value == true {
|
||||
break loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setObject(fieldObj interface{}, object map[string]interface{}, names []string, hideEmpty bool) {
|
||||
switch field := fieldObj.(type) {
|
||||
default:
|
||||
panic("unknown type")
|
||||
case string:
|
||||
for i, name := range names {
|
||||
if i != 0 || (hideEmpty && len(field) == 0) {
|
||||
delete(object, name)
|
||||
continue
|
||||
}
|
||||
object[name] = field
|
||||
}
|
||||
case bool:
|
||||
for i, name := range names {
|
||||
if i != 0 || (hideEmpty && field == false) {
|
||||
delete(object, name)
|
||||
continue
|
||||
}
|
||||
object[name] = field
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getRawPackageList gets the array of items from all object.
|
||||
func (vf *File) getRawPackageList() []interface{} {
|
||||
var rawPackageList []interface{}
|
||||
for index, name := range packageNames {
|
||||
rawPackageListObject, found := vf.all[name]
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
if index != 0 {
|
||||
vf.all[packageNames[0]] = rawPackageListObject
|
||||
delete(vf.all, name)
|
||||
}
|
||||
var is bool
|
||||
rawPackageList, is = rawPackageListObject.([]interface{})
|
||||
if is {
|
||||
break
|
||||
}
|
||||
}
|
||||
return rawPackageList
|
||||
}
|
||||
|
||||
// toFields moves values from "all" to the field values.
|
||||
func (vf *File) toFields() {
|
||||
setField(&vf.RootPath, vf.all, rootPathNames)
|
||||
setField(&vf.Comment, vf.all, commentNames)
|
||||
setField(&vf.Ignore, vf.all, ignoreNames)
|
||||
|
||||
rawPackageList := vf.getRawPackageList()
|
||||
|
||||
vf.Package = make([]*Package, len(rawPackageList))
|
||||
|
||||
for index, rawPackage := range rawPackageList {
|
||||
object, is := rawPackage.(map[string]interface{})
|
||||
if !is {
|
||||
continue
|
||||
}
|
||||
pkg := &Package{}
|
||||
vf.Package[index] = pkg
|
||||
pkg.field = object
|
||||
setField(&pkg.Origin, object, originNames)
|
||||
setField(&pkg.Path, object, pathNames)
|
||||
setField(&pkg.Tree, object, treeNames)
|
||||
setField(&pkg.Revision, object, revisionNames)
|
||||
setField(&pkg.RevisionTime, object, revisionTimeNames)
|
||||
setField(&pkg.Version, object, versionNames)
|
||||
setField(&pkg.VersionExact, object, versionExactNames)
|
||||
setField(&pkg.ChecksumSHA1, object, checksumSHA1Names)
|
||||
setField(&pkg.Comment, object, commentNames)
|
||||
}
|
||||
}
|
||||
|
||||
// toAll moves values from field values to "all".
|
||||
func (vf *File) toAll() {
|
||||
delete(vf.all, "Tool")
|
||||
|
||||
setObject(vf.RootPath, vf.all, rootPathNames, true)
|
||||
setObject(vf.Comment, vf.all, commentNames, false)
|
||||
setObject(vf.Ignore, vf.all, ignoreNames, false)
|
||||
|
||||
rawPackageList := vf.getRawPackageList()
|
||||
|
||||
setPkgFields := func(pkg *Package) {
|
||||
if pkg.Origin == pkg.Path {
|
||||
pkg.Origin = ""
|
||||
}
|
||||
if pkg.field == nil {
|
||||
pkg.field = make(map[string]interface{}, 10)
|
||||
}
|
||||
setObject(pkg.Origin, pkg.field, originNames, true)
|
||||
setObject(pkg.Path, pkg.field, pathNames, false)
|
||||
setObject(pkg.Tree, pkg.field, treeNames, true)
|
||||
setObject(pkg.Revision, pkg.field, revisionNames, false)
|
||||
setObject(pkg.RevisionTime, pkg.field, revisionTimeNames, true)
|
||||
setObject(pkg.Version, pkg.field, versionNames, true)
|
||||
setObject(pkg.VersionExact, pkg.field, versionExactNames, true)
|
||||
setObject(pkg.ChecksumSHA1, pkg.field, checksumSHA1Names, true)
|
||||
setObject(pkg.Comment, pkg.field, commentNames, true)
|
||||
}
|
||||
|
||||
for i := len(vf.Package) - 1; i >= 0; i-- {
|
||||
pkg := vf.Package[i]
|
||||
switch {
|
||||
case pkg.Remove:
|
||||
for index, rawObj := range rawPackageList {
|
||||
raw, is := rawObj.(map[string]interface{})
|
||||
if !is {
|
||||
continue
|
||||
}
|
||||
same := true
|
||||
for key, value := range pkg.field {
|
||||
if raw[key] != value {
|
||||
same = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if same {
|
||||
rawPackageList[index] = nil
|
||||
}
|
||||
}
|
||||
case pkg.Add:
|
||||
setPkgFields(pkg)
|
||||
rawPackageList = append(rawPackageList, pkg.field)
|
||||
default:
|
||||
if pkg.field == nil {
|
||||
pkg.field = make(map[string]interface{}, 10)
|
||||
}
|
||||
|
||||
delete(pkg.field, "local")
|
||||
delete(pkg.field, "Local")
|
||||
setPkgFields(pkg)
|
||||
}
|
||||
}
|
||||
nextRawPackageList := make([]interface{}, 0, len(rawPackageList))
|
||||
for _, raw := range rawPackageList {
|
||||
if raw == nil {
|
||||
continue
|
||||
}
|
||||
nextRawPackageList = append(nextRawPackageList, raw)
|
||||
}
|
||||
vf.all[packageNames[0]] = nextRawPackageList
|
||||
}
|
||||
|
||||
// Marshal the vendor file to the specified writer.
|
||||
// Retains read fields.
|
||||
func (vf *File) Marshal(w io.Writer) error {
|
||||
if vf.all == nil {
|
||||
vf.all = map[string]interface{}{}
|
||||
}
|
||||
vf.toAll()
|
||||
|
||||
rawList := vf.getRawPackageList()
|
||||
sort.Sort(vendorPackageSort(rawList))
|
||||
|
||||
jb, err := json.Marshal(vf.all)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
err = json.Indent(buf, jb, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(w, buf)
|
||||
return err
|
||||
}
|
||||
|
||||
// Unmarshal the vendor file from the specified reader.
|
||||
// Stores internally all fields.
|
||||
func (vf *File) Unmarshal(r io.Reader) error {
|
||||
bb, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if vf.all == nil {
|
||||
vf.all = make(map[string]interface{}, 3)
|
||||
}
|
||||
err = json.Unmarshal(bb, &vf.all)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vf.toFields()
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user