Task Attachments (#104)
This commit is contained in:
16
vendor/github.com/KyleBanks/depth/.gitignore
generated
vendored
Normal file
16
vendor/github.com/KyleBanks/depth/.gitignore
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||
.glide/
|
||||
|
||||
bin/
|
9
vendor/github.com/KyleBanks/depth/.travis.yml
generated
vendored
Normal file
9
vendor/github.com/KyleBanks/depth/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.9.x
|
||||
before_install:
|
||||
- go get github.com/mattn/goveralls
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -service=travis-ci
|
||||
#script: go test $(go list ./... | grep -v vendor/)
|
21
vendor/github.com/KyleBanks/depth/LICENSE
generated
vendored
Normal file
21
vendor/github.com/KyleBanks/depth/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Kyle Banks
|
||||
|
||||
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.
|
32
vendor/github.com/KyleBanks/depth/Makefile
generated
vendored
Normal file
32
vendor/github.com/KyleBanks/depth/Makefile
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
VERSION = 1.2.1
|
||||
|
||||
RELEASE_PKG = ./cmd/depth
|
||||
INSTALL_PKG = $(RELEASE_PKG)
|
||||
|
||||
|
||||
# Remote includes require 'mmake'
|
||||
# github.com/tj/mmake
|
||||
include github.com/KyleBanks/make/go/install
|
||||
include github.com/KyleBanks/make/go/sanity
|
||||
include github.com/KyleBanks/make/go/release
|
||||
include github.com/KyleBanks/make/go/bench
|
||||
include github.com/KyleBanks/make/git/precommit
|
||||
|
||||
# Runs a number of depth commands as examples of what's possible.
|
||||
example: | install
|
||||
depth github.com/KyleBanks/depth/cmd/depth strings ./
|
||||
|
||||
depth -internal strings
|
||||
|
||||
depth -json github.com/KyleBanks/depth/cmd/depth
|
||||
|
||||
depth -test github.com/KyleBanks/depth/cmd/depth
|
||||
|
||||
depth -test -internal strings
|
||||
|
||||
depth -test -internal -max 3 strings
|
||||
|
||||
depth .
|
||||
|
||||
depth ./cmd/depth
|
||||
.PHONY: example
|
232
vendor/github.com/KyleBanks/depth/README.md
generated
vendored
Normal file
232
vendor/github.com/KyleBanks/depth/README.md
generated
vendored
Normal file
@ -0,0 +1,232 @@
|
||||
# depth
|
||||
|
||||
[](https://godoc.org/github.com/KyleBanks/depth)
|
||||
[](https://travis-ci.org/KyleBanks/depth)
|
||||
[](https://goreportcard.com/report/github.com/KyleBanks/depth)
|
||||
[](https://coveralls.io/github/KyleBanks/depth?branch=master)
|
||||
|
||||
`depth` is tool to retrieve and visualize Go source code dependency trees.
|
||||
|
||||
## Install
|
||||
|
||||
Download the appropriate binary for your platform from the [Releases](https://github.com/KyleBanks/depth/releases) page, or:
|
||||
|
||||
```sh
|
||||
go get github.com/KyleBanks/depth/cmd/depth
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
`depth` can be used as a standalone command-line application, or as a package within your own project.
|
||||
|
||||
### Command-Line
|
||||
|
||||
Simply execute `depth` with one or more package names to visualize. You can use the fully qualified import path of the package, like so:
|
||||
|
||||
```sh
|
||||
$ depth github.com/KyleBanks/depth/cmd/depth
|
||||
github.com/KyleBanks/depth/cmd/depth
|
||||
├ encoding/json
|
||||
├ flag
|
||||
├ fmt
|
||||
├ io
|
||||
├ log
|
||||
├ os
|
||||
├ strings
|
||||
└ github.com/KyleBanks/depth
|
||||
├ fmt
|
||||
├ go/build
|
||||
├ path
|
||||
├ sort
|
||||
└ strings
|
||||
12 dependencies (11 internal, 1 external, 0 testing).
|
||||
```
|
||||
|
||||
Or you can use a relative path, for example:
|
||||
|
||||
```sh
|
||||
$ depth .
|
||||
$ depth ./cmd/depth
|
||||
$ depth ../
|
||||
```
|
||||
|
||||
You can also use `depth` on the Go standard library:
|
||||
|
||||
```sh
|
||||
$ depth strings
|
||||
strings
|
||||
├ errors
|
||||
├ io
|
||||
├ unicode
|
||||
└ unicode/utf8
|
||||
5 dependencies (5 internal, 0 external, 0 testing).
|
||||
```
|
||||
|
||||
Visualizing multiple packages at a time is supported by simply naming the packages you'd like to visualize:
|
||||
|
||||
```sh
|
||||
$ depth strings github.com/KyleBanks/depth
|
||||
strings
|
||||
├ errors
|
||||
├ io
|
||||
├ unicode
|
||||
└ unicode/utf8
|
||||
5 dependencies (5 internal, 0 external, 0 testing).
|
||||
github.com/KyleBanks/depth
|
||||
├ fmt
|
||||
├ go/build
|
||||
├ path
|
||||
├ sort
|
||||
└ strings
|
||||
7 dependencies (7 internal, 0 external, 0 testing).
|
||||
```
|
||||
|
||||
#### `-internal`
|
||||
|
||||
By default, `depth` only resolves the top level of dependencies for standard library packages, however you can use the `-internal` flag to visualize all internal dependencies:
|
||||
|
||||
```sh
|
||||
$ depth -internal strings
|
||||
strings
|
||||
├ errors
|
||||
├ io
|
||||
├ errors
|
||||
└ sync
|
||||
├ internal/race
|
||||
└ unsafe
|
||||
├ runtime
|
||||
├ runtime/internal/atomic
|
||||
└ unsafe
|
||||
├ runtime/internal/sys
|
||||
└ unsafe
|
||||
├ sync/atomic
|
||||
└ unsafe
|
||||
└ unsafe
|
||||
├ unicode
|
||||
└ unicode/utf8
|
||||
12 dependencies (12 internal, 0 external, 0 testing).
|
||||
```
|
||||
|
||||
#### `-max`
|
||||
|
||||
The `-max` flag limits the dependency tree to the maximum depth provided. For example, if you supply `-max 1` on the `depth` package, your output would look like so:
|
||||
|
||||
```
|
||||
$ depth -max 1 github.com/KyleBanks/depth/cmd/depth
|
||||
github.com/KyleBanks/depth/cmd/depth
|
||||
├ encoding/json
|
||||
├ flag
|
||||
├ fmt
|
||||
├ io
|
||||
├ log
|
||||
├ os
|
||||
├ strings
|
||||
└ github.com/KyleBanks/depth
|
||||
7 dependencies (6 internal, 1 external, 0 testing).
|
||||
```
|
||||
|
||||
The `-max` flag is particularly useful in conjunction with the `-internal` flag which can lead to very deep dependency trees.
|
||||
|
||||
#### `-test`
|
||||
|
||||
By default, `depth` ignores dependencies that are only required for testing. However, you can view test dependencies using the `-test` flag:
|
||||
|
||||
```sh
|
||||
$ depth -test strings
|
||||
strings
|
||||
├ bytes
|
||||
├ errors
|
||||
├ fmt
|
||||
├ io
|
||||
├ io/ioutil
|
||||
├ math/rand
|
||||
├ reflect
|
||||
├ sync
|
||||
├ testing
|
||||
├ unicode
|
||||
├ unicode/utf8
|
||||
└ unsafe
|
||||
13 dependencies (13 internal, 0 external, 8 testing).
|
||||
```
|
||||
|
||||
#### `-explain target-package`
|
||||
|
||||
The `-explain` flag instructs `depth` to print import chains in which the
|
||||
`target-package` is found:
|
||||
|
||||
```sh
|
||||
$ depth -explain strings github.com/KyleBanks/depth/cmd/depth
|
||||
github.com/KyleBanks/depth/cmd/depth -> strings
|
||||
github.com/KyleBanks/depth/cmd/depth -> github.com/KyleBanks/depth -> strings
|
||||
```
|
||||
|
||||
#### `-json`
|
||||
|
||||
The `-json` flag instructs `depth` to output dependencies in JSON format:
|
||||
|
||||
```sh
|
||||
$ depth -json github.com/KyleBanks/depth/cmd/depth
|
||||
{
|
||||
"name": "github.com/KyleBanks/depth/cmd/depth",
|
||||
"deps": [
|
||||
{
|
||||
"name": "encoding/json",
|
||||
"internal": true,
|
||||
"deps": null
|
||||
},
|
||||
...
|
||||
{
|
||||
"name": "github.com/KyleBanks/depth",
|
||||
"internal": false,
|
||||
"deps": [
|
||||
{
|
||||
"name": "go/build",
|
||||
"internal": true,
|
||||
"deps": null
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Integrating With Your Project
|
||||
|
||||
The `depth` package can easily be used to retrieve the dependency tree for a particular package in your own project. For example, here's how you would retrieve the dependency tree for the `strings` package:
|
||||
|
||||
```go
|
||||
import "github.com/KyleBanks/depth"
|
||||
|
||||
var t depth.Tree
|
||||
err := t.Resolve("strings")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Output: "'strings' has 4 dependencies."
|
||||
log.Printf("'%v' has %v dependencies.", t.Root.Name, len(t.Root.Deps))
|
||||
```
|
||||
|
||||
For additional customization, simply set the appropriate flags on the `Tree` before resolving:
|
||||
|
||||
```go
|
||||
import "github.com/KyleBanks/depth"
|
||||
|
||||
t := depth.Tree {
|
||||
ResolveInternal: true,
|
||||
ResolveTest: true,
|
||||
MaxDepth: 10,
|
||||
}
|
||||
|
||||
|
||||
err := t.Resolve("strings")
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
`depth` was developed by [Kyle Banks](https://twitter.com/kylewbanks).
|
||||
|
||||
## License
|
||||
|
||||
`depth` is available under the [MIT](./LICENSE) license.
|
129
vendor/github.com/KyleBanks/depth/depth.go
generated
vendored
Normal file
129
vendor/github.com/KyleBanks/depth/depth.go
generated
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
// Package depth provides the ability to traverse and retrieve Go source code dependencies in the form of
|
||||
// internal and external packages.
|
||||
//
|
||||
// For example, the dependencies of the stdlib `strings` package can be resolved like so:
|
||||
//
|
||||
// import "github.com/KyleBanks/depth"
|
||||
//
|
||||
// var t depth.Tree
|
||||
// err := t.Resolve("strings")
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
//
|
||||
// // Output: "strings has 4 dependencies."
|
||||
// log.Printf("%v has %v dependencies.", t.Root.Name, len(t.Root.Deps))
|
||||
//
|
||||
// For additional customization, simply set the appropriate flags on the `Tree` before resolving:
|
||||
//
|
||||
// import "github.com/KyleBanks/depth"
|
||||
//
|
||||
// t := depth.Tree {
|
||||
// ResolveInternal: true,
|
||||
// ResolveTest: true,
|
||||
// MaxDepth: 10,
|
||||
// }
|
||||
// err := t.Resolve("strings")
|
||||
package depth
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"go/build"
|
||||
"os"
|
||||
)
|
||||
|
||||
// ErrRootPkgNotResolved is returned when the root Pkg of the Tree cannot be resolved,
|
||||
// typically because it does not exist.
|
||||
var ErrRootPkgNotResolved = errors.New("unable to resolve root package")
|
||||
|
||||
// Importer defines a type that can import a package and return its details.
|
||||
type Importer interface {
|
||||
Import(name, srcDir string, im build.ImportMode) (*build.Package, error)
|
||||
}
|
||||
|
||||
// Tree represents the top level of a Pkg and the configuration used to
|
||||
// initialize and represent its contents.
|
||||
type Tree struct {
|
||||
Root *Pkg
|
||||
|
||||
ResolveInternal bool
|
||||
ResolveTest bool
|
||||
MaxDepth int
|
||||
|
||||
Importer Importer
|
||||
|
||||
importCache map[string]struct{}
|
||||
}
|
||||
|
||||
// Resolve recursively finds all dependencies for the root Pkg name provided,
|
||||
// and the packages it depends on.
|
||||
func (t *Tree) Resolve(name string) error {
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Root = &Pkg{
|
||||
Name: name,
|
||||
Tree: t,
|
||||
SrcDir: pwd,
|
||||
Test: false,
|
||||
}
|
||||
|
||||
// Reset the import cache each time to ensure a reused Tree doesn't
|
||||
// reuse the same cache.
|
||||
t.importCache = nil
|
||||
|
||||
// Allow custom importers, but use build.Default if none is provided.
|
||||
if t.Importer == nil {
|
||||
t.Importer = &build.Default
|
||||
}
|
||||
|
||||
t.Root.Resolve(t.Importer)
|
||||
if !t.Root.Resolved {
|
||||
return ErrRootPkgNotResolved
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// shouldResolveInternal determines if internal packages should be further resolved beyond the
|
||||
// current parent.
|
||||
//
|
||||
// For example, if the parent Pkg is `github.com/foo/bar` and true is returned, all the
|
||||
// internal dependencies it relies on will be resolved. If for example `strings` is one of those
|
||||
// dependencies, and it is passed as the parent here, false may be returned and its internal
|
||||
// dependencies will not be resolved.
|
||||
func (t *Tree) shouldResolveInternal(parent *Pkg) bool {
|
||||
if t.ResolveInternal {
|
||||
return true
|
||||
}
|
||||
|
||||
return parent == t.Root
|
||||
}
|
||||
|
||||
// isAtMaxDepth returns true when the depth of the Pkg provided is at or beyond the maximum
|
||||
// depth allowed by the tree.
|
||||
//
|
||||
// If the Tree has a MaxDepth of zero, true is never returned.
|
||||
func (t *Tree) isAtMaxDepth(p *Pkg) bool {
|
||||
if t.MaxDepth == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return p.depth() >= t.MaxDepth
|
||||
}
|
||||
|
||||
// hasSeenImport returns true if the import name provided has already been seen within the tree.
|
||||
// This function only returns false for a name once.
|
||||
func (t *Tree) hasSeenImport(name string) bool {
|
||||
if t.importCache == nil {
|
||||
t.importCache = make(map[string]struct{})
|
||||
}
|
||||
|
||||
if _, ok := t.importCache[name]; ok {
|
||||
return true
|
||||
}
|
||||
t.importCache[name] = struct{}{}
|
||||
return false
|
||||
}
|
184
vendor/github.com/KyleBanks/depth/pkg.go
generated
vendored
Normal file
184
vendor/github.com/KyleBanks/depth/pkg.go
generated
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
package depth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"go/build"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Pkg represents a Go source package, and its dependencies.
|
||||
type Pkg struct {
|
||||
Name string `json:"name"`
|
||||
SrcDir string `json:"-"`
|
||||
|
||||
Internal bool `json:"internal"`
|
||||
Resolved bool `json:"resolved"`
|
||||
Test bool `json:"-"`
|
||||
|
||||
Tree *Tree `json:"-"`
|
||||
Parent *Pkg `json:"-"`
|
||||
Deps []Pkg `json:"deps"`
|
||||
|
||||
Raw *build.Package `json:"-"`
|
||||
}
|
||||
|
||||
// Resolve recursively finds all dependencies for the Pkg and the packages it depends on.
|
||||
func (p *Pkg) Resolve(i Importer) {
|
||||
// Resolved is always true, regardless of if we skip the import,
|
||||
// it is only false if there is an error while importing.
|
||||
p.Resolved = true
|
||||
|
||||
name := p.cleanName()
|
||||
if name == "" {
|
||||
return
|
||||
}
|
||||
|
||||
// Stop resolving imports if we've reached max depth or found a duplicate.
|
||||
var importMode build.ImportMode
|
||||
if p.Tree.hasSeenImport(name) || p.Tree.isAtMaxDepth(p) {
|
||||
importMode = build.FindOnly
|
||||
}
|
||||
|
||||
pkg, err := i.Import(name, p.SrcDir, importMode)
|
||||
if err != nil {
|
||||
// TODO: Check the error type?
|
||||
p.Resolved = false
|
||||
return
|
||||
}
|
||||
p.Raw = pkg
|
||||
|
||||
// Update the name with the fully qualified import path.
|
||||
p.Name = pkg.ImportPath
|
||||
|
||||
// If this is an internal dependency, we may need to skip it.
|
||||
if pkg.Goroot {
|
||||
p.Internal = true
|
||||
if !p.Tree.shouldResolveInternal(p) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//first we set the regular dependencies, then we add the test dependencies
|
||||
//sharing the same set. This allows us to mark all test-only deps linearly
|
||||
unique := make(map[string]struct{})
|
||||
p.setDeps(i, pkg.Imports, pkg.Dir, unique, false)
|
||||
if p.Tree.ResolveTest {
|
||||
p.setDeps(i, append(pkg.TestImports, pkg.XTestImports...), pkg.Dir, unique, true)
|
||||
}
|
||||
}
|
||||
|
||||
// setDeps takes a slice of import paths and the source directory they are relative to,
|
||||
// and creates the Deps of the Pkg. Each dependency is also further resolved prior to being added
|
||||
// to the Pkg.
|
||||
func (p *Pkg) setDeps(i Importer, imports []string, srcDir string, unique map[string]struct{}, isTest bool) {
|
||||
for _, imp := range imports {
|
||||
// Mostly for testing files where cyclic imports are allowed.
|
||||
if imp == p.Name {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip duplicates.
|
||||
if _, ok := unique[imp]; ok {
|
||||
continue
|
||||
}
|
||||
unique[imp] = struct{}{}
|
||||
|
||||
p.addDep(i, imp, srcDir, isTest)
|
||||
}
|
||||
|
||||
sort.Sort(byInternalAndName(p.Deps))
|
||||
}
|
||||
|
||||
// addDep creates a Pkg and it's dependencies from an imported package name.
|
||||
func (p *Pkg) addDep(i Importer, name string, srcDir string, isTest bool) {
|
||||
dep := Pkg{
|
||||
Name: name,
|
||||
SrcDir: srcDir,
|
||||
Tree: p.Tree,
|
||||
Parent: p,
|
||||
Test: isTest,
|
||||
}
|
||||
dep.Resolve(i)
|
||||
|
||||
p.Deps = append(p.Deps, dep)
|
||||
}
|
||||
|
||||
// isParent goes recursively up the chain of Pkgs to determine if the name provided is ever a
|
||||
// parent of the current Pkg.
|
||||
func (p *Pkg) isParent(name string) bool {
|
||||
if p.Parent == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if p.Parent.Name == name {
|
||||
return true
|
||||
}
|
||||
|
||||
return p.Parent.isParent(name)
|
||||
}
|
||||
|
||||
// depth returns the depth of the Pkg within the Tree.
|
||||
func (p *Pkg) depth() int {
|
||||
if p.Parent == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return p.Parent.depth() + 1
|
||||
}
|
||||
|
||||
// cleanName returns a cleaned version of the Pkg name used for resolving dependencies.
|
||||
//
|
||||
// If an empty string is returned, dependencies should not be resolved.
|
||||
func (p *Pkg) cleanName() string {
|
||||
name := p.Name
|
||||
|
||||
// C 'package' cannot be resolved.
|
||||
if name == "C" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Internal golang_org/* packages must be prefixed with vendor/
|
||||
//
|
||||
// Thanks to @davecheney for this:
|
||||
// https://github.com/davecheney/graphpkg/blob/master/main.go#L46
|
||||
if strings.HasPrefix(name, "golang_org") {
|
||||
name = path.Join("vendor", name)
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
// String returns a string representation of the Pkg containing the Pkg name and status.
|
||||
func (p *Pkg) String() string {
|
||||
b := bytes.NewBufferString(p.Name)
|
||||
|
||||
if !p.Resolved {
|
||||
b.Write([]byte(" (unresolved)"))
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// byInternalAndName ensures a slice of Pkgs are sorted such that the internal stdlib
|
||||
// packages are always above external packages (ie. github.com/whatever).
|
||||
type byInternalAndName []Pkg
|
||||
|
||||
func (b byInternalAndName) Len() int {
|
||||
return len(b)
|
||||
}
|
||||
|
||||
func (b byInternalAndName) Swap(i, j int) {
|
||||
b[i], b[j] = b[j], b[i]
|
||||
}
|
||||
|
||||
func (b byInternalAndName) Less(i, j int) bool {
|
||||
if b[i].Internal && !b[j].Internal {
|
||||
return true
|
||||
} else if !b[i].Internal && b[j].Internal {
|
||||
return false
|
||||
}
|
||||
|
||||
return b[i].Name < b[j].Name
|
||||
}
|
Reference in New Issue
Block a user