normalize application config and logging

This commit is contained in:
Alex Goodman 2021-02-15 13:13:08 -05:00
parent ae89e3dc2c
commit bcebe0491c
41 changed files with 734 additions and 480 deletions

View file

@ -2,12 +2,12 @@ package cmd
import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
"github.com/wagoodman/dive/dive"
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/wagoodman/dive/dive"
"github.com/wagoodman/dive/internal/log"
"github.com/wagoodman/dive/runtime"
)
@ -59,7 +59,7 @@ func doAnalyzeCmd(cmd *cobra.Command, args []string) {
ignoreErrors, err := cmd.PersistentFlags().GetBool("ignore-errors")
if err != nil {
logrus.Error("unable to get 'ignore-errors' option:", err)
log.Error("unable to get 'ignore-errors' option:", err)
}
runtime.Run(runtime.Options{
@ -69,5 +69,6 @@ func doAnalyzeCmd(cmd *cobra.Command, args []string) {
ExportFile: exportFile,
CiConfig: ciConfig,
IgnoreErrors: viper.GetBool("ignore-errors") || ignoreErrors,
})
},
*appConfig)
}

View file

@ -33,5 +33,5 @@ func doBuildCmd(cmd *cobra.Command, args []string) {
BuildArgs: args,
ExportFile: exportFile,
CiConfig: ciConfig,
})
}, *appConfig)
}

View file

@ -2,20 +2,20 @@ package cmd
import (
"fmt"
"io/ioutil"
"os"
"path"
"strings"
"github.com/wagoodman/dive/dive"
"github.com/wagoodman/dive/dive/filetree"
"github.com/mitchellh/go-homedir"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/wagoodman/dive/dive"
"github.com/wagoodman/dive/dive/filetree"
"github.com/wagoodman/dive/internal/log"
"github.com/wagoodman/dive/internal/logger"
"github.com/wagoodman/dive/runtime"
"github.com/wagoodman/dive/runtime/config"
)
var appConfig *config.ApplicationConfig
var cfgFile string
var exportFile string
var ciConfigFile string
@ -60,12 +60,16 @@ func initCli() {
for _, key := range []string{"lowestEfficiency", "highestWastedBytes", "highestUserWastedPercent"} {
if err := ciConfig.BindPFlag(fmt.Sprintf("rules.%s", key), rootCmd.Flags().Lookup(key)); err != nil {
log.Fatalf("Unable to bind '%s' flag: %v", key, err)
panic(fmt.Errorf("unable to bind '%s' flag: %v", key, err))
}
}
if err := ciConfig.BindPFlag("ignore-errors", rootCmd.PersistentFlags().Lookup("ignore-errors")); err != nil {
log.Fatalf("Unable to bind 'ignore-errors' flag: %v", err)
panic(fmt.Errorf("unable to bind 'ignore-errors' flag: %w", err))
}
if err := viper.BindPFlag("source", rootCmd.PersistentFlags().Lookup("source")); err != nil {
panic(fmt.Errorf("unable to bind 'source' flag: %w", err))
}
}
@ -73,143 +77,25 @@ func initCli() {
func initConfig() {
var err error
//viper.SetDefault("log.level", log.InfoLevel.String())
viper.SetDefault("log.level", "debug")
viper.SetDefault("log.path", "./dive.log")
viper.SetDefault("log.enabled", true)
// keybindings: status view / global
// keybindings: status view / global
viper.SetDefault("keybinding.quit", "Ctrl+C")
viper.SetDefault("keybinding.toggle-view", "Tab")
viper.SetDefault("keybinding.filter-files", "Ctrl+f")
// keybindings: layer view
viper.SetDefault("keybinding.compare-all", "Ctrl+A")
viper.SetDefault("keybinding.compare-layer", "Ctrl+L")
// keybindings: filetree view
viper.SetDefault("keybinding.toggle-collapse-dir", "Space")
viper.SetDefault("keybinding.toggle-collapse-all-dir", "Ctrl+Space")
viper.SetDefault("keybinding.toggle-filetree-attributes", "Ctrl+B")
viper.SetDefault("keybinding.toggle-added-files", "Ctrl+A")
viper.SetDefault("keybinding.toggle-removed-files", "Ctrl+R")
viper.SetDefault("keybinding.toggle-modified-files", "Ctrl+N")
viper.SetDefault("keybinding.toggle-unmodified-files", "Ctrl+U")
viper.SetDefault("keybinding.toggle-wrap-tree", "Ctrl+P")
viper.SetDefault("keybinding.page-up", "PgUp")
viper.SetDefault("keybinding.page-down", "PgDn")
viper.SetDefault("diff.hide", "")
viper.SetDefault("layer.show-aggregated-changes", false)
viper.SetDefault("filetree.collapse-dir", false)
viper.SetDefault("filetree.pane-width", 0.5)
viper.SetDefault("filetree.show-attributes", true)
viper.SetDefault("container-engine", "docker")
viper.SetDefault("ignore-errors", false)
err = viper.BindPFlag("source", rootCmd.PersistentFlags().Lookup("source"))
appConfig, err = config.LoadApplicationConfig(viper.GetViper(), cfgFile)
if err != nil {
fmt.Println(err)
os.Exit(1)
panic(err)
}
viper.SetEnvPrefix("DIVE")
// replace all - with _ when looking for matching environment variables
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
viper.AutomaticEnv()
// if config files are present, load them
if cfgFile == "" {
// default configs are ignored if not found
filepathToCfg := getDefaultCfgFile()
viper.SetConfigFile(filepathToCfg)
} else {
viper.SetConfigFile(cfgFile)
}
err = viper.ReadInConfig()
if err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
} else if cfgFile != "" {
fmt.Println(err)
os.Exit(0)
}
// set global defaults (for performance)
filetree.GlobalFileTreeCollapse = viper.GetBool("filetree.collapse-dir")
// set global defaults
filetree.GlobalFileTreeCollapse = appConfig.FileTree.CollapseDir
}
// initLogging sets up the logging object with a formatter and location
func initLogging() {
var logFileObj *os.File
var err error
if viper.GetBool("log.enabled") {
logFileObj, err = os.OpenFile(viper.GetString("log.path"), os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
log.SetOutput(logFileObj)
} else {
log.SetOutput(ioutil.Discard)
logCfg := logger.LogrusConfig{
EnableConsole: false,
EnableFile: appConfig.Log.Enabled,
FileLocation: appConfig.Log.Path,
Level: appConfig.Log.Level,
}
runtime.SetLogger(logger.NewLogrusLogger(logCfg))
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
Formatter := new(log.TextFormatter)
Formatter.DisableTimestamp = true
log.SetFormatter(Formatter)
level, err := log.ParseLevel(viper.GetString("log.level"))
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
log.SetLevel(level)
log.Debug("Starting Dive...")
log.Debugf("config filepath: %s", viper.ConfigFileUsed())
for k, v := range viper.AllSettings() {
log.Debug("config value: ", k, " : ", v)
}
}
// getDefaultCfgFile checks for config file in paths from xdg specs
// and in $HOME/.config/dive/ directory
// defaults to $HOME/.dive.yaml
func getDefaultCfgFile() string {
home, err := homedir.Dir()
if err != nil {
fmt.Println(err)
os.Exit(0)
}
xdgHome := os.Getenv("XDG_CONFIG_HOME")
xdgDirs := os.Getenv("XDG_CONFIG_DIRS")
xdgPaths := append([]string{xdgHome}, strings.Split(xdgDirs, ":")...)
allDirs := append(xdgPaths, path.Join(home, ".config"))
for _, val := range allDirs {
file := findInPath(val)
if len(file) > 0 {
return file
}
}
return path.Join(home, ".dive.yaml")
}
// findInPath returns first "*.yaml" file in path's subdirectory "dive"
// if not found returns empty string
func findInPath(pathTo string) string {
directory := path.Join(pathTo, "dive")
files, err := ioutil.ReadDir(directory)
if err != nil {
return ""
}
for _, file := range files {
filename := file.Name()
if path.Ext(filename) == ".yaml" {
return path.Join(directory, filename)
}
}
return ""
log.Debug("starting dive")
log.Debug("config contents:\n", appConfig.String())
}

View file

@ -2,7 +2,8 @@ package filetree
import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/internal/log"
)
type TreeIndexKey struct {
@ -77,7 +78,7 @@ func (cmp *Comparer) get(key TreeIndexKey) (*FileTree, []PathError, error) {
markPathErrors, err := newTree.CompareAndMark(cmp.refTrees[idx])
pathErrors = append(pathErrors, markPathErrors...)
if err != nil {
logrus.Errorf("error while building tree: %+v", err)
log.Errorf("error while building tree: %+v", err)
return nil, nil, err
}
}

View file

@ -3,7 +3,7 @@ package filetree
import (
"sort"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/internal/log"
)
// EfficiencyData represents the storage and reference statistics for a given file tree path.
@ -65,11 +65,11 @@ func Efficiency(trees []*FileTree) (float64, EfficiencySlice) {
stackedTree, failedPaths, err := StackTreeRange(trees, 0, currentTree-1)
if len(failedPaths) > 0 {
for _, path := range failedPaths {
logrus.Errorf(path.String())
log.Errorf(path.String())
}
}
if err != nil {
logrus.Errorf("unable to stack tree range: %+v", err)
log.Errorf("unable to stack tree range: %+v", err)
return err
}
@ -81,7 +81,7 @@ func Efficiency(trees []*FileTree) (float64, EfficiencySlice) {
if previousTreeNode.Data.FileInfo.IsDir {
err = previousTreeNode.VisitDepthChildFirst(sizer, nil)
if err != nil {
logrus.Errorf("unable to propagate whiteout dir: %+v", err)
log.Errorf("unable to propagate whiteout dir: %+v", err)
return err
}
}
@ -109,7 +109,7 @@ func Efficiency(trees []*FileTree) (float64, EfficiencySlice) {
currentTree = idx
err := tree.VisitDepthChildFirst(visitor, visitEvaluator)
if err != nil {
logrus.Errorf("unable to propagate ref tree: %+v", err)
log.Errorf("unable to propagate ref tree: %+v", err)
}
}

View file

@ -2,10 +2,11 @@ package filetree
import (
"archive/tar"
"github.com/cespare/xxhash"
"github.com/sirupsen/logrus"
"io"
"os"
"github.com/cespare/xxhash"
"github.com/wagoodman/dive/internal/log"
)
// FileInfo contains tar metadata for a specific FileNode
@ -54,7 +55,7 @@ func NewFileInfo(realPath, path string, info os.FileInfo) FileInfo {
linkName, err = os.Readlink(realPath)
if err != nil {
logrus.Panic("unable to read link:", realPath, err)
log.Errorf("unable to read link=%q : %+v", realPath, err)
}
} else if info.IsDir() {
@ -69,7 +70,7 @@ func NewFileInfo(realPath, path string, info os.FileInfo) FileInfo {
if fileType != tar.TypeDir {
file, err := os.Open(realPath)
if err != nil {
logrus.Panic("unable to read file:", realPath)
log.Errorf("unable to read file: %s", realPath)
}
defer file.Close()
hash = getHashFromReader(file)
@ -127,7 +128,7 @@ func getHashFromReader(reader io.Reader) uint64 {
for {
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
logrus.Panic(err)
log.Error(err)
}
if n == 0 {
break
@ -135,7 +136,7 @@ func getHashFromReader(reader io.Reader) uint64 {
_, err = h.Write(buf[:n])
if err != nil {
logrus.Panic(err)
log.Error(err)
}
}

View file

@ -6,11 +6,10 @@ import (
"sort"
"strings"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/runtime/ui/format"
"github.com/dustin/go-humanize"
"github.com/phayes/permbits"
"github.com/wagoodman/dive/internal/log"
"github.com/wagoodman/dive/runtime/ui/format"
)
const (
@ -173,7 +172,7 @@ func (node *FileNode) MetadataString() string {
err := node.VisitDepthChildFirst(sizer, nil)
if err != nil {
logrus.Errorf("unable to propagate node for metadata: %+v", err)
log.Errorf("unable to propagate node for metadata: %+v", err)
}
}

View file

@ -6,8 +6,9 @@ import (
"sort"
"strings"
"github.com/wagoodman/dive/internal/log"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
)
const (
@ -52,8 +53,7 @@ type renderParams struct {
isLast bool
}
// renderStringTreeBetween returns a string representing the given tree between the given rows. Since each node
// renderStringTreeBetween returns a string representing the given tree between the given rows. Since each node
// is rendered on its own line, the returned string shows the visible nodes not affected by a collapsed parent.
func (tree *FileTree) renderStringTreeBetween(startRow, stopRow int, showAttributes bool) string {
// generate a list of nodes to render
@ -75,7 +75,7 @@ func (tree *FileTree) renderStringTreeBetween(startRow, stopRow int, showAttribu
// we should always visit nodes in order
sort.Strings(keys)
lastIndex := len(keys) - 1
for ; lastIndex > 0; lastIndex--{
for ; lastIndex > 0; lastIndex-- {
key := keys[lastIndex]
if currentParams.node.Children[key].Data.ViewInfo.Hidden {
continue
@ -158,7 +158,7 @@ func (tree *FileTree) VisibleSize() int {
}
err := tree.VisitDepthParentFirst(visitor, visitEvaluator)
if err != nil {
logrus.Errorf("unable to determine visible tree size: %+v", err)
log.Errorf("unable to determine visible tree size: %+v", err)
}
// don't include root
@ -191,7 +191,7 @@ func (tree *FileTree) Copy() *FileTree {
}, nil)
if err != nil {
logrus.Errorf("unable to propagate tree on copy(): %+v", err)
log.Errorf("unable to propagate tree on copy(): %+v", err)
}
return newTree
@ -393,7 +393,7 @@ func StackTreeRange(trees []*FileTree, start, stop int) (*FileTree, []PathError,
errors = append(errors, failedPaths...)
}
if err != nil {
logrus.Errorf("could not stack tree range: %v", err)
log.Errorf("could not stack tree range: %v", err)
return nil, nil, err
}
}

View file

@ -2,7 +2,6 @@ package docker
import (
"encoding/json"
"github.com/sirupsen/logrus"
)
type config struct {
@ -28,7 +27,7 @@ func newConfig(configBytes []byte) config {
var imageConfig config
err := json.Unmarshal(configBytes, &imageConfig)
if err != nil {
logrus.Panic(err)
panic(err)
}
layerIdx := 0

View file

@ -2,7 +2,6 @@ package docker
import (
"encoding/json"
"github.com/sirupsen/logrus"
)
type manifest struct {
@ -15,7 +14,7 @@ func newManifest(manifestBytes []byte) manifest {
var manifest []manifest
err := json.Unmarshal(manifestBytes, &manifest)
if err != nil {
logrus.Panic(err)
panic(err)
}
return manifest[0]
}

15
go.mod
View file

@ -3,28 +3,33 @@ module github.com/wagoodman/dive
go 1.13
require (
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 // indirect
github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/buildpacks/imgutil v0.0.0-20200805143852-1844b230530d // indirect
github.com/buildpacks/lifecycle v0.7.2
github.com/buildpacks/pack v0.14.2
github.com/cespare/xxhash v1.1.0
github.com/containerd/containerd v1.3.3 // indirect
github.com/docker/cli v20.10.0-beta1+incompatible
github.com/docker/docker v1.4.2-0.20200221181110-62bd5a33f707
github.com/dustin/go-humanize v1.0.0
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/gdamore/tcell/v2 v2.1.0
github.com/gogo/protobuf v1.3.1 // indirect
github.com/golang/mock v1.4.1 // indirect
github.com/golang/protobuf v1.4.3 // indirect
github.com/google/go-cmp v0.5.2 // indirect
github.com/google/go-containerregistry v0.0.0-20200313165449-955bf358a3d8 // indirect
github.com/google/uuid v1.1.2
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/jroimartin/gocui v0.4.0
github.com/kr/text v0.2.0 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/lunixbochs/vtclean v1.0.0
github.com/magiconair/properties v1.8.4 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.3.3 // indirect
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/pelletier/go-toml v1.8.1 // indirect
github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee
@ -39,8 +44,8 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.6.1 // indirect
github.com/x-cray/logrus-prefixed-formatter v0.5.2
gitlab.com/tslocum/cbind v0.1.4
go.uber.org/zap v1.10.0
golang.org/x/net v0.0.0-20201029055024-942e2f445f3c
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 // indirect
golang.org/x/text v0.3.4 // indirect
@ -51,7 +56,7 @@ require (
google.golang.org/protobuf v1.25.0 // indirect
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
gotest.tools/v3 v3.0.3 // indirect
)

130
go.sum
View file

@ -1,4 +1,3 @@
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@ -35,13 +34,9 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg=
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
@ -50,24 +45,16 @@ github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/apex/log v1.1.2-0.20190827100214-baa5455d1012 h1:r9k3B0K539tmbDOdyCIuz/6qtn8q+lp+qvEStcFUIdM=
github.com/apex/log v1.1.2-0.20190827100214-baa5455d1012/go.mod h1:Ls949n1HFtXfbDcjiTTFQqkVUrte0puoIBfO3SVgwOA=
github.com/apex/log v1.1.2 h1:bnDuVoi+o98wOdVqfEzNDlY0tcmBia7r4YkjS9EqGYk=
github.com/apex/log v1.1.2/go.mod h1:SyfRweFO+TlkIJ3DVizTSeI1xk7jOIIqOnUPZQTTsww=
github.com/apex/logs v0.0.3/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo=
github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE=
github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
@ -76,34 +63,21 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/buildpacks/imgutil v0.0.0-20200313170640-a02052f47d62/go.mod h1:TjPmM78urjQIiMal4T7en6iBekAPv6z1yVMZobc4Kd8=
github.com/buildpacks/imgutil v0.0.0-20200805143852-1844b230530d h1:uVTFIiev3f7fi5BSv1RtM5W5lcqQodqLRBG5AdoDe2U=
github.com/buildpacks/imgutil v0.0.0-20200805143852-1844b230530d/go.mod h1:uVv0fNwOEBNgyM9ZvwV0g2Dvzk31q5TtSeoC1GGmW+k=
github.com/buildpacks/lifecycle v0.7.2 h1:FO7i2cokLNc7lcuThq/LYt1jmkB8HBrjpK+2GWWsaLI=
github.com/buildpacks/lifecycle v0.7.2/go.mod h1:k41tT3XOt7ufaMGAvOpEsXyuJpUPoo4F686Z652lU3E=
github.com/buildpacks/pack v0.14.2 h1:4/3+2mwmb2LmpFVEHUlOk07PLcIoA1LCCAbNgNnbp3s=
github.com/buildpacks/pack v0.14.2/go.mod h1:P7Hj8ltMWZ/Yt++ZbvAU/Zr8C7iTZT0L5pO5H7dfRKY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.3 h1:LoIzb5y9x5l8VKAlyrbusNPXqBY0+kviRloxFUMFwKc=
github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41 h1:kIFnQBO7rQ0XkMe6xEwbybYHBEaWmh/f++laI6Emt7M=
github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@ -128,7 +102,6 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v0.0.0-20200312141509-ef2f64abbd37/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v20.10.0-beta1+incompatible h1:K4hmHhtBIAZ8BIcvjtk3Fi63o2UlGp7D4Y1w9fLI7rc=
github.com/docker/cli v20.10.0-beta1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
@ -152,16 +125,12 @@ github.com/dwillist/tview v0.0.0-20210114215028-5f3be7b5a4ec/go.mod h1:0ha5CGeka
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@ -173,9 +142,8 @@ github.com/gdamore/tcell/v2 v2.0.1-0.20201017141208-acf90d56d591/go.mod h1:vSVL/
github.com/gdamore/tcell/v2 v2.1.0 h1:UnSmozHgBkQi2PGsFr+rpdXuAPRRucMegpQp3Z3kDro=
github.com/gdamore/tcell/v2 v2.1.0/go.mod h1:vSVL/GV5mCSlPC6thFP5kfOFdM9MGZcalipmpTxTgQA=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
@ -193,7 +161,6 @@ github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dp
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
@ -212,7 +179,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
@ -234,8 +200,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-containerregistry v0.0.0-20200311163244-4b1985e5ea21/go.mod h1:m8YvHwSOuBCq25yrj1DaX/fIMrv6ec3CNg8jY8+5PEA=
github.com/google/go-containerregistry v0.0.0-20200313165449-955bf358a3d8 h1:S7U1nPK3fi2xjZkMrQKcRayVtMmqMFJs9UtXQW3GPzM=
github.com/google/go-containerregistry v0.0.0-20200313165449-955bf358a3d8/go.mod h1:pD1UFYs7MCAx+ZLShBdttcaOSbyc8F9Na/9IZLNwJeA=
github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQFEufcolZ95JfU8=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
@ -268,12 +232,10 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
@ -297,15 +259,10 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
github.com/jroimartin/gocui v0.4.0 h1:52jnalstgmc25FmtGcWqa0tcbMEWS6RpFLsOIO+I+E8=
github.com/jroimartin/gocui v0.4.0/go.mod h1:7i7bbj99OgFHzo7kB2zPb8pXLqMBSQegY7azfqXMkyY=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@ -314,8 +271,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@ -326,7 +281,6 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
@ -348,7 +302,6 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
@ -362,8 +315,10 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@ -373,8 +328,6 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/ioprogress v0.0.0-20180201004757-6a23b12fa88e h1:Qa6dnn8DlasdXRnacluu8HzPts0S1I9zvvUPDbBnXFI=
github.com/mitchellh/ioprogress v0.0.0-20180201004757-6a23b12fa88e/go.mod h1:waEya8ee1Ro/lgxpVhkJI4BVASzkm3UZqkx/cFJiYHM=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
@ -392,36 +345,23 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 h1:lh3PyZvY+B9nFliSGTn5uFuqQQJGuNrD0MLCokv09ag=
github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo=
github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
@ -429,7 +369,6 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR
github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee h1:P6U24L02WMfj9ymZTxl7CxS73JC99x3ukk+DBkgQGQs=
github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee/go.mod h1:3uODdxMgOaPYeWU7RzZLxVtJHZ/x1f/iHkBZuKJDzuY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -444,6 +383,7 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
@ -451,7 +391,6 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
@ -463,7 +402,6 @@ github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvf
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94/go.mod h1:b18R55ulyQ/h3RaWyloPyER7fWQVZvimKKhnI5OfrJQ=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
@ -473,7 +411,6 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@ -498,28 +435,22 @@ github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
@ -531,25 +462,19 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238/go.mod h1:JwQJCMWpUDqjZrB5jpw0f5VbN7U95zxFy1ZDpoEarGo=
github.com/vdemeester/k8s-pkg-credentialprovider v1.17.4/go.mod h1:inCTmtUdr5KJbreVojo06krnTgaeAz/Z7lynpPk/Q2c=
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
gitlab.com/tslocum/cbind v0.1.4 h1:cbZXPPcieXspk8cShoT6efz7HAT8yMNQcofYWNizis4=
@ -566,23 +491,19 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -607,8 +528,6 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -623,17 +542,14 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201029055024-942e2f445f3c h1:rpcgRPA7OvNEOdprt2Wx8/Re2cBTd8NPo/lvo3AyMqk=
golang.org/x/net v0.0.0-20201029055024-942e2f445f3c/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -657,30 +573,25 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201013132646-2da7054afaeb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -697,7 +608,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -720,13 +630,11 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200210192313-1ace956b0e17/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -757,20 +665,17 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200313141609-30c55424f95d/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20201029200359-8ce4113da6f7 h1:2BaavIGjmdbQJl0IFOYI8SBd5WLIjH+tIOMIFf9QENo=
google.golang.org/genproto v0.0.0-20201029200359-8ce4113da6f7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.33.1 h1:DGeFlSan2f+WEtCERJ4J9GJWk15TxUi8QGagfI87Xyc=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@ -784,12 +689,10 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
@ -797,7 +700,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
@ -805,30 +707,21 @@ gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg=
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg=
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE=
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@ -857,7 +750,6 @@ k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUc
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/legacy-cloud-providers v0.17.0/go.mod h1:DdzaepJ3RtRy+e5YhNtrCYwlgyK87j/5+Yfp0L9Syp8=
k8s.io/legacy-cloud-providers v0.17.4/go.mod h1:FikRNoD64ECjkxO36gkDgJeiQWwyZTuBkhu+yxOc1Js=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=

61
internal/log/log.go Normal file
View file

@ -0,0 +1,61 @@
package log
import "github.com/wagoodman/dive/runtime/logger"
// Log is the singleton used to facilitate logging internally within dive
var Log logger.Logger = &nopLogger{}
// Errorf takes a formatted template string and template arguments for the error logging level.
func Errorf(format string, args ...interface{}) {
Log.Errorf(format, args...)
}
// Error logs the given arguments at the error logging level.
func Error(args ...interface{}) {
Log.Error(args...)
}
// Warnf takes a formatted template string and template arguments for the warning logging level.
func Warnf(format string, args ...interface{}) {
Log.Warnf(format, args...)
}
// Warn logs the given arguments at the warning logging level.
func Warn(args ...interface{}) {
Log.Warn(args...)
}
// Infof takes a formatted template string and template arguments for the info logging level.
func Infof(format string, args ...interface{}) {
Log.Infof(format, args...)
}
// Info logs the given arguments at the info logging level.
func Info(args ...interface{}) {
Log.Info(args...)
}
// Debugf takes a formatted template string and template arguments for the debug logging level.
func Debugf(format string, args ...interface{}) {
Log.Debugf(format, args...)
}
// Debug logs the given arguments at the debug logging level.
func Debug(args ...interface{}) {
Log.Debug(args...)
}
// Tracef takes a formatted template string and template arguments for the trace logging level.
func Tracef(format string, args ...interface{}) {
Log.Tracef(format, args...)
}
// Trace logs the given arguments at the trace logging level.
func Trace(args ...interface{}) {
Log.Trace(args...)
}
// WithFields returns a message logger with multiple key-value fields.
func WithFields(fields ...interface{}) logger.MessageLogger {
return Log.WithFields(fields...)
}

19
internal/log/nop.go Normal file
View file

@ -0,0 +1,19 @@
package log
import (
"github.com/wagoodman/dive/runtime/logger"
)
type nopLogger struct{}
func (l *nopLogger) Errorf(format string, args ...interface{}) {}
func (l *nopLogger) Error(args ...interface{}) {}
func (l *nopLogger) Warnf(format string, args ...interface{}) {}
func (l *nopLogger) Warn(args ...interface{}) {}
func (l *nopLogger) Infof(format string, args ...interface{}) {}
func (l *nopLogger) Info(args ...interface{}) {}
func (l *nopLogger) Debugf(format string, args ...interface{}) {}
func (l *nopLogger) Debug(args ...interface{}) {}
func (l *nopLogger) Tracef(format string, args ...interface{}) {}
func (l *nopLogger) Trace(args ...interface{}) {}
func (l *nopLogger) WithFields(fields ...interface{}) logger.MessageLogger { return l }

149
internal/logger/logrus.go Normal file
View file

@ -0,0 +1,149 @@
package logger
import (
"fmt"
"io"
"io/ioutil"
"os"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/runtime/logger"
prefixed "github.com/x-cray/logrus-prefixed-formatter"
)
// LogrusConfig contains all configurable values for the Logrus logger
type LogrusConfig struct {
EnableConsole bool
EnableFile bool
Structured bool
Level string
FileLocation string
}
// LogrusLogger contains all runtime values for using Logrus with the configured output target and input configuration values.
type LogrusLogger struct {
Config LogrusConfig
Logger *logrus.Logger
Output io.Writer
}
// NewLogrusLogger creates a new LogrusLogger with the given configuration
func NewLogrusLogger(cfg LogrusConfig) *LogrusLogger {
appLogger := logrus.New()
var output io.Writer
switch {
case cfg.EnableConsole && cfg.EnableFile:
logFile, err := os.OpenFile(cfg.FileLocation, os.O_WRONLY|os.O_CREATE, 0755)
if err != nil {
panic(fmt.Errorf("unable to setup log file: %w", err))
}
output = io.MultiWriter(os.Stderr, logFile)
case cfg.EnableConsole:
output = os.Stderr
case cfg.EnableFile:
logFile, err := os.OpenFile(cfg.FileLocation, os.O_WRONLY|os.O_CREATE, 0755)
if err != nil {
panic(fmt.Errorf("unable to setup log file: %w", err))
}
output = logFile
default:
output = ioutil.Discard
}
level, err := logrus.ParseLevel(cfg.Level)
if err != nil {
panic(err)
}
appLogger.SetOutput(output)
appLogger.SetLevel(level)
if cfg.Structured {
appLogger.SetFormatter(&logrus.JSONFormatter{
TimestampFormat: "2006-01-02 15:04:05",
DisableTimestamp: false,
DisableHTMLEscape: false,
PrettyPrint: false,
})
} else {
appLogger.SetFormatter(&prefixed.TextFormatter{
TimestampFormat: "2006-01-02 15:04:05",
ForceColors: true,
ForceFormatting: true,
})
}
return &LogrusLogger{
Config: cfg,
Logger: appLogger,
Output: output,
}
}
// Tracef takes a formatted template string and template arguments for the trace logging level.
func (l *LogrusLogger) Tracef(format string, args ...interface{}) {
l.Logger.Tracef(format, args...)
}
// Debugf takes a formatted template string and template arguments for the debug logging level.
func (l *LogrusLogger) Debugf(format string, args ...interface{}) {
l.Logger.Debugf(format, args...)
}
// Infof takes a formatted template string and template arguments for the info logging level.
func (l *LogrusLogger) Infof(format string, args ...interface{}) {
l.Logger.Infof(format, args...)
}
// Warnf takes a formatted template string and template arguments for the warning logging level.
func (l *LogrusLogger) Warnf(format string, args ...interface{}) {
l.Logger.Warnf(format, args...)
}
// Errorf takes a formatted template string and template arguments for the error logging level.
func (l *LogrusLogger) Errorf(format string, args ...interface{}) {
l.Logger.Errorf(format, args...)
}
// Trace logs the given arguments at the trace logging level.
func (l *LogrusLogger) Trace(args ...interface{}) {
l.Logger.Trace(args...)
}
// Debug logs the given arguments at the debug logging level.
func (l *LogrusLogger) Debug(args ...interface{}) {
l.Logger.Debug(args...)
}
// Info logs the given arguments at the info logging level.
func (l *LogrusLogger) Info(args ...interface{}) {
l.Logger.Info(args...)
}
// Warn logs the given arguments at the warning logging level.
func (l *LogrusLogger) Warn(args ...interface{}) {
l.Logger.Warn(args...)
}
// Error logs the given arguments at the error logging level.
func (l *LogrusLogger) Error(args ...interface{}) {
l.Logger.Error(args...)
}
// WithFields returns a message logger with multiple key-value fields.
func (l *LogrusLogger) WithFields(fields ...interface{}) logger.MessageLogger {
f := make(map[string]interface{}, len(fields)/2)
var key, value interface{}
for i := 0; i+1 < len(fields); i = i + 2 {
key = fields[i]
value = fields[i+1]
if s, ok := key.(string); ok {
f[s] = value
} else if s, ok := key.(fmt.Stringer); ok {
f[s.String()] = value
}
}
return l.Logger.WithFields(f)
}

View file

@ -7,12 +7,10 @@ import (
"strings"
"github.com/dustin/go-humanize"
"github.com/logrusorgru/aurora"
"github.com/spf13/viper"
"github.com/wagoodman/dive/dive/image"
"github.com/wagoodman/dive/utils"
"github.com/spf13/viper"
"github.com/logrusorgru/aurora"
)
type CiEvaluator struct {

View file

@ -0,0 +1,159 @@
package config
import (
"fmt"
"io/ioutil"
"os"
"path"
"strings"
"github.com/mitchellh/go-homedir"
"github.com/spf13/viper"
"gopkg.in/yaml.v2"
)
type ApplicationConfig struct {
ConfigFile string
FileTree fileTreeViewConfig `mapstructure:"filetree"`
Layer layerViewConfig `mapstructure:"layer"`
Keybinding keybindingConfig `mapstructure:"keybinding"`
Diff diffConfig `mapstructure:"diff"`
Log loggingConfig `mapstructure:"log"`
ContainerEngine string `mapstructure:"container-engine"`
IgnoreErrors bool `mapstructure:"ignore-errors"`
}
func LoadApplicationConfig(v *viper.Viper, cfgFile string) (*ApplicationConfig, error) {
setDefaultConfigValues(v)
readConfig(cfgFile)
instance := &ApplicationConfig{}
if err := v.Unmarshal(instance); err != nil {
return nil, fmt.Errorf("unable to unmarshal application config: %w", err)
}
instance.ConfigFile = v.ConfigFileUsed()
return instance, instance.build()
}
func (a *ApplicationConfig) build() error {
// currently no other configs need to be built
return a.Diff.build()
}
func (a ApplicationConfig) String() string {
content, err := yaml.Marshal(&a)
if err != nil {
return "[no config]"
}
return string(content)
}
func readConfig(cfgFile string) {
viper.SetEnvPrefix("DIVE")
// replace all - with _ when looking for matching environment variables
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
viper.AutomaticEnv()
// if config files are present, load them
if cfgFile == "" {
// default configs are ignored if not found
cfgFile = getDefaultCfgFile()
}
if cfgFile == "" {
return
}
viper.SetConfigFile(cfgFile)
if err := viper.ReadInConfig(); err != nil {
panic(fmt.Errorf("unable to read config file: %w", err))
}
}
// getDefaultCfgFile checks for config file in paths from xdg specs
// and in $HOME/.config/dive/ directory
// defaults to $HOME/.dive.yaml
func getDefaultCfgFile() string {
home, err := homedir.Dir()
if err != nil {
err = fmt.Errorf("unable to get home dir: %w", err)
panic(err)
}
xdgHome := os.Getenv("XDG_CONFIG_HOME")
xdgDirs := os.Getenv("XDG_CONFIG_DIRS")
xdgPaths := append([]string{xdgHome}, strings.Split(xdgDirs, ":")...)
allDirs := append(xdgPaths, path.Join(home, ".config"))
for _, val := range allDirs {
file := findInPath(val)
if len(file) > 0 {
return file
}
}
for _, altPath := range []string{path.Join(home, ".dive.yaml"), path.Join(home, ".dive.yml")} {
if _, err := os.Stat(altPath); os.IsNotExist(err) {
continue
} else if err != nil {
panic(err)
}
return altPath
}
return ""
}
// findInPath returns first "*.yaml" or "*.yml" file in path's subdirectory "dive"
// if not found returns empty string
func findInPath(pathTo string) string {
directory := path.Join(pathTo, "dive")
files, err := ioutil.ReadDir(directory)
if err != nil {
return ""
}
for _, file := range files {
filename := file.Name()
if path.Ext(filename) == ".yaml" || path.Ext(filename) == ".yml" {
return path.Join(directory, filename)
}
}
return ""
}
func setDefaultConfigValues(v *viper.Viper) {
// logging
v.SetDefault("log.enabled", true)
v.SetDefault("log.level", "debug")
v.SetDefault("log.path", "./dive.log")
// keybindings: status view / global
v.SetDefault("keybinding.quit", "Ctrl+C")
v.SetDefault("keybinding.toggle-view", "Tab")
v.SetDefault("keybinding.filter-files", "Ctrl+f")
// keybindings: layer view
v.SetDefault("keybinding.compare-all", "Ctrl+A")
v.SetDefault("keybinding.compare-layer", "Ctrl+L")
// keybindings: filetree view
v.SetDefault("keybinding.toggle-collapse-dir", "Space")
v.SetDefault("keybinding.toggle-collapse-all-dir", "Ctrl+Space")
v.SetDefault("keybinding.toggle-filetree-attributes", "Ctrl+B")
v.SetDefault("keybinding.toggle-added-files", "Ctrl+A")
v.SetDefault("keybinding.toggle-removed-files", "Ctrl+R")
v.SetDefault("keybinding.toggle-modified-files", "Ctrl+N")
v.SetDefault("keybinding.toggle-unmodified-files", "Ctrl+U")
v.SetDefault("keybinding.toggle-wrap-tree", "Ctrl+P")
v.SetDefault("keybinding.page-up", "PgUp")
v.SetDefault("keybinding.page-down", "PgDn")
// layer view
v.SetDefault("layer.show-aggregated-changes", false)
// filetree view
v.SetDefault("diff.hide", "")
v.SetDefault("filetree.collapse-dir", false)
v.SetDefault("filetree.pane-width", 0.5)
v.SetDefault("filetree.show-attributes", true)
// general behavior
v.SetDefault("container-engine", "docker")
v.SetDefault("ignore-errors", false)
}

View file

@ -0,0 +1,26 @@
package config
import "github.com/wagoodman/dive/dive/filetree"
type diffConfig struct {
// note: this really relates to the fileTreeViewConfig, but is here for legacy reasons
Hide []string `mapstructure:"hide"`
DiffTypes []filetree.DiffType `yaml:"-"`
}
func (c *diffConfig) build() error {
c.DiffTypes = nil
for _, hideType := range c.Hide {
switch hideType {
case "added":
c.DiffTypes = append(c.DiffTypes, filetree.Added)
case "removed":
c.DiffTypes = append(c.DiffTypes, filetree.Removed)
case "modified":
c.DiffTypes = append(c.DiffTypes, filetree.Modified)
case "unmodified":
c.DiffTypes = append(c.DiffTypes, filetree.Unmodified)
}
}
return nil
}

View file

@ -0,0 +1,7 @@
package config
type fileTreeViewConfig struct {
CollapseDir bool `mapstructure:"collapse-dir"`
PaneWidthRatio float64 `mapstructure:"pane-width"`
ShowAttributes bool `mapstructure:"show-attributes"`
}

View file

@ -0,0 +1,19 @@
package config
type keybindingConfig struct {
Quit string `mapstructure:"quit"`
ToggleViews string `mapstructure:"toggle-view"`
FilterFiles string `mapstructure:"filter-files"`
CompareAll string `mapstructure:"compare-all"`
CompareLayer string `mapstructure:"compare-layer"`
ToggleCollapseDir string `mapstructure:"toggle-collapse-dir"`
ToggleCollapseAllDir string `mapstructure:"toggle-collapse-all-dir"`
ToggleFileTreeAttributes string `mapstructure:"toggle-filetree-attributes"`
ToggleAddedFiles string `mapstructure:"toggle-added-files"`
ToggleRemovedFiles string `mapstructure:"toggle-removed-files"`
ToggleModifiedFiles string `mapstructure:"toggle-modified-files"`
ToggleUnmodifiedFiles string `mapstructure:"toggle-unmodified-files"`
ToggleWrapTree string `mapstructure:"toggle-wrap-tree"`
PageUp string `mapstructure:"page-up"`
PageDown string `mapstructure:"page-down"`
}

View file

@ -0,0 +1,5 @@
package config
type layerViewConfig struct {
ShowAggregatedChanges bool `mapstructure:"show-aggregated-changes"`
}

View file

@ -0,0 +1,7 @@
package config
type loggingConfig struct {
Enabled bool `mapstructure:"enabled"`
Level string `mapstructure:"level"`
Path string `mapstructure:"path"`
}

11
runtime/log.go Normal file
View file

@ -0,0 +1,11 @@
package runtime
import (
"github.com/wagoodman/dive/internal/log"
"github.com/wagoodman/dive/runtime/logger"
)
// SetLogger sets the logger object used for all logging calls.
func SetLogger(logger logger.Logger) {
log.Log = logger
}

23
runtime/logger/logger.go Normal file
View file

@ -0,0 +1,23 @@
package logger
type Logger interface {
MessageLogger
FieldLogger
}
type FieldLogger interface {
WithFields(fields ...interface{}) MessageLogger
}
type MessageLogger interface {
Errorf(format string, args ...interface{})
Error(args ...interface{})
Warnf(format string, args ...interface{})
Warn(args ...interface{})
Infof(format string, args ...interface{})
Info(args ...interface{})
Debugf(format string, args ...interface{})
Debug(args ...interface{})
Tracef(format string, args ...interface{})
Trace(args ...interface{})
}

View file

@ -4,19 +4,21 @@ import (
"fmt"
"os"
"github.com/wagoodman/dive/runtime/config"
"github.com/dustin/go-humanize"
"github.com/sirupsen/logrus"
"github.com/spf13/afero"
"github.com/wagoodman/dive/dive"
"github.com/wagoodman/dive/dive/filetree"
"github.com/wagoodman/dive/dive/image"
"github.com/wagoodman/dive/internal/log"
"github.com/wagoodman/dive/runtime/ci"
"github.com/wagoodman/dive/runtime/export"
"github.com/wagoodman/dive/runtime/ui"
"github.com/wagoodman/dive/utils"
)
func run(enableUi bool, options Options, imageResolver image.Resolver, events eventChannel, filesystem afero.Fs) {
func run(config config.ApplicationConfig, enableUi bool, options Options, imageResolver image.Resolver, events eventChannel, filesystem afero.Fs) {
var img *image.Image
var err error
defer close(events)
@ -24,6 +26,10 @@ func run(enableUi bool, options Options, imageResolver image.Resolver, events ev
doExport := options.ExportFile != ""
doBuild := len(options.BuildArgs) > 0
if config.ConfigFile != "" {
events.message(fmt.Sprintf("Using config file: %s", config.ConfigFile))
}
if doBuild {
events.message(utils.TitleFormat("Building image..."))
img, err = imageResolver.Build(options.BuildArgs)
@ -102,9 +108,11 @@ func run(enableUi bool, options Options, imageResolver image.Resolver, events ev
}
if enableUi {
err = ui.Run(analysis, treeStack)
err = ui.Run(config, analysis, treeStack)
if err != nil {
logrus.Fatal("run info exit: ", err.Error())
log.WithFields(
"error", err,
).Errorf("UI error")
events.exitWithError(err)
return
}
@ -112,20 +120,19 @@ func run(enableUi bool, options Options, imageResolver image.Resolver, events ev
}
}
func Run(options Options) {
func Run(options Options, config config.ApplicationConfig) {
var exitCode int
var events = make(eventChannel)
imageResolver, err := dive.GetImageResolver(options.Source)
if err != nil {
message := "cannot determine image provider"
logrus.Error(message)
logrus.Error(err)
log.Errorf("%s : %+v", message, err.Error())
fmt.Fprintf(os.Stderr, "%s: %+v\n", message, err)
os.Exit(1)
}
go run(true, options, imageResolver, events, afero.NewOsFs())
go run(config, true, options, imageResolver, events, afero.NewOsFs())
for event := range events {
if event.stdout != "" {
@ -140,7 +147,7 @@ func Run(options Options) {
}
if event.err != nil {
logrus.Error(event.err)
log.Error(event.err)
_, err := fmt.Fprintln(os.Stderr, event.err.Error())
if err != nil {
fmt.Println("error: could not write to buffer:", err)

View file

@ -2,12 +2,12 @@ package ui
import (
"fmt"
"log"
"sync"
"github.com/wagoodman/dive/runtime/config"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/dive/filetree"
"github.com/wagoodman/dive/dive/image"
"github.com/wagoodman/dive/runtime/ui/components"
@ -28,27 +28,36 @@ type UI struct {
fileTree tview.Primitive
}
func newApp(app *tview.Application, analysis *image.AnalysisResult, cache filetree.Comparer) (*UI, error) {
func newApp(config config.ApplicationConfig, app *tview.Application, analysis *image.AnalysisResult, cache filetree.Comparer) (*UI, error) {
var err error
once.Do(func() {
// TODO: Extract initilaization logic into its own package
format.SyncWithTermColors()
config := constructors.NewKeyConfig()
appConfig := components.AppConfig{}
keyConfig := constructors.NewKeyConfig()
diveApplication := components.NewDiveApplication(app)
//initialize viewmodels
modelConfig := constructors.ModelConfig{
Cache: &CacheWrapper{Cache: &cache},
Layers: analysis.Layers,
}
_, layersViewModel, treeViewModel, err := constructors.InitializeModels(modelConfig)
filterViewModel := viewmodels.NewFilterViewModel(nil)
layersViewModel := viewmodels.NewLayersViewModel(analysis.Layers)
cacheWrapper := CacheWrapper{Cache: &cache}
treeViewModel, err := viewmodels.NewTreeViewModel(&cacheWrapper, layersViewModel, filterViewModel)
if err != nil {
log.Fatal(fmt.Errorf("unable to initialize viewmodels: %q", err))
panic(err)
}
// TODO: this seemed to be partially pushed, commented out for the meantime
//modelConfig := constructors.ModelConfig{
// Cache: &CacheWrapper{Cache: &cache},
// Layers: analysis.Layers,
//}
//_, layersViewModel, treeViewModel, err := constructors.InitializeModels(modelConfig)
//if err != nil {
// log.Fatal(fmt.Errorf("unable to initialize viewmodels: %q", err))
//}
regularLayerDetailsView := components.NewLayerDetailsView(layersViewModel).Setup()
layerDetailsBox := components.NewWrapper("Layer Details", "", regularLayerDetailsView).Setup()
layerDetailsBox.SetVisibility(components.MinHeightVisibility(10))
@ -60,13 +69,13 @@ func newApp(app *tview.Application, analysis *image.AnalysisResult, cache filetr
filterView := components.NewFilterView(treeViewModel).Setup()
layersView := components.NewLayerList(treeViewModel).Setup(config)
layersView := components.NewLayerList(treeViewModel).Setup(keyConfig)
layerSubtitle := fmt.Sprintf("Cmp%7s %s", "Size", "Command")
layersBox := components.NewWrapper("Layers", layerSubtitle, layersView).Setup()
fileTreeView := components.NewTreeView(treeViewModel)
fileTreeView = fileTreeView.Setup(config)
fileTreeView = fileTreeView.Setup(keyConfig)
fileTreeBox := components.NewWrapper("Current Layer Contents", "", fileTreeView).Setup()
keyMenuView := components.NewKeyMenuView()
@ -92,7 +101,8 @@ func newApp(app *tview.Application, analysis *image.AnalysisResult, cache filetr
AddItem(filterView, 1, 0, false).
SetConsumers(filterView, fileTreeBox)
leftPortion, rightPortion := appConfig.GetPaneWidth()
rightPortion := int(config.FileTree.PaneWidthRatio * 100)
leftPortion := int((1 - config.FileTree.PaneWidthRatio) * 100)
totalVisibleGrid.AddItem(leftVisibleGrid, 0, leftPortion, true).
AddItem(rightVisibleGrid, 0, rightPortion, false)
@ -104,18 +114,18 @@ func newApp(app *tview.Application, analysis *image.AnalysisResult, cache filetr
keyMenuView.AddBoundViews(diveApplication)
quitBinding, err := config.GetKeyBinding("keybinding.quit")
quitBinding, err := keyConfig.GetKeyBinding("keybinding.quit")
if err != nil {
// TODO handle this as an error
panic(err)
}
filterBinding, err := config.GetKeyBinding("keybinding.filter-files")
filterBinding, err := keyConfig.GetKeyBinding("keybinding.filter-files")
if err != nil {
// TODO handle this as an error
panic(err)
}
switchBinding, err := config.GetKeyBinding("keybinding.toggle-view")
switchBinding, err := keyConfig.GetKeyBinding("keybinding.toggle-view")
if err != nil {
// TODO handle this as an error
panic(err)
@ -154,22 +164,22 @@ func newApp(app *tview.Application, analysis *image.AnalysisResult, cache filetr
diveApplication.SetFocus(gridWithFooter)
// additional setup configuration
if appConfig.GetAggregateLayerSetting() {
if config.Layer.ShowAggregatedChanges {
err := layersViewModel.SwitchLayerMode()
if err != nil {
panic(err)
}
}
if appConfig.GetCollapseDir() {
if config.FileTree.CollapseDir {
fileTreeView.CollapseOrExpandAll()
}
for _, hideType := range appConfig.GetDefaultHide() {
for _, hideType := range config.Diff.DiffTypes {
treeViewModel.ToggleHiddenFileType(hideType)
}
if appConfig.GetShowAttributes() {
if config.FileTree.ShowAttributes {
fileTreeView.ToggleHideAttributes()
}
})
@ -178,18 +188,15 @@ func newApp(app *tview.Application, analysis *image.AnalysisResult, cache filetr
}
// Run is the UI entrypoint.
func Run(analysis *image.AnalysisResult, treeStack filetree.Comparer) error {
app := tview.NewApplication()
_, err := newApp(app, analysis, treeStack)
func Run(config config.ApplicationConfig, analysis *image.AnalysisResult, treeStack filetree.Comparer) error {
_, err := newApp(config, tview.NewApplication(), analysis, treeStack)
if err != nil {
return err
}
if err = uiSingleton.app.Run(); err != nil {
logrus.Error("app error: ", err.Error())
return err
}
logrus.Info("app run loop exited")
return nil
}

View file

@ -1,44 +0,0 @@
package components
import (
"github.com/spf13/viper"
"github.com/wagoodman/dive/dive/filetree"
)
type AppConfig struct {}
func (a *AppConfig) GetDefaultHide() (result []filetree.DiffType) {
slice := viper.GetStringSlice("diff.hide")
for _, hideType := range slice {
switch hideType{
case "added":
result = append(result, filetree.Added)
case "removed":
result = append(result, filetree.Removed)
case "modified":
result = append(result, filetree.Modified)
case "unmodified":
result = append(result, filetree.Unmodified)
}
}
return result
}
func (a *AppConfig) GetAggregateLayerSetting() bool {
return viper.GetBool("layer.show-aggregated-changes")
}
func (a *AppConfig) GetCollapseDir() bool {
return viper.GetBool("filetree.collapse-dir")
}
func (a *AppConfig) GetPaneWidth() (int,int) {
fwp := viper.GetFloat64("filetree.pane-width")
lwp := 1 - fwp
return int(fwp*100), int(lwp*100)
}
func (a *AppConfig) GetShowAttributes() bool {
return viper.GetBool("filetree.show-attributes")
}

View file

@ -1,19 +1,15 @@
package components
import (
"fmt"
"github.com/rivo/tview"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/internal/log"
"github.com/wagoodman/dive/runtime/ui/components/helpers"
)
type DiveApplication struct {
*tview.Application
boundList []BoundView
bindings []helpers.KeyBinding
bindings []helpers.KeyBinding
}
func NewDiveApplication(app *tview.Application) *DiveApplication {
@ -24,10 +20,10 @@ func NewDiveApplication(app *tview.Application) *DiveApplication {
}
func (d *DiveApplication) GetKeyBindings() []helpers.KeyBindingDisplay {
result := []helpers.KeyBindingDisplay{}
var result []helpers.KeyBindingDisplay
for i := 0; i < len(d.bindings); i++ {
binding := d.bindings[i]
logrus.Debug(fmt.Sprintf("adding keybinding with name %s", binding.Display))
log.WithFields("name", binding.Display).Tracef("adding keybinding")
result = append(result, helpers.KeyBindingDisplay{KeyBinding: &binding, Selected: AlwaysFalse, Hide: AlwaysFalse})
}

View file

@ -6,8 +6,8 @@ import (
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/dive/filetree"
"github.com/wagoodman/dive/internal/log"
"github.com/wagoodman/dive/runtime/ui/components/helpers"
"github.com/wagoodman/dive/runtime/ui/format"
)
@ -306,23 +306,17 @@ func (t *TreeView) HasFocus() bool {
func (t *TreeView) collapseDir() bool {
node := t.getAbsPositionNode()
if node != nil && node.Data.FileInfo.IsDir {
logrus.Debugf("collapsing node %s", node.Path())
log.WithFields(
"path", node.Path(),
).Trace("collapsing node")
node.Data.ViewInfo.Collapsed = !node.Data.ViewInfo.Collapsed
}
if node != nil {
logrus.Debugf("unable to collapse node %s", node.Path())
logrus.Debugf(" IsDir: %t", node.Data.FileInfo.IsDir)
} else {
logrus.Debugf("unable to collapse nil node")
}
return true
}
func (t *TreeView) CollapseOrExpandAll() bool {
visitor := func(n *filetree.FileNode) error {
if n.Data.FileInfo.IsDir {
if n != nil && n.Data.FileInfo.IsDir {
n.Data.ViewInfo.Collapsed = t.globalCollapseAll
}
return nil
@ -332,9 +326,9 @@ func (t *TreeView) CollapseOrExpandAll() bool {
return true
}
if err := t.tree.VisitDepthParentFirst(visitor, evaluator); err != nil {
panic(fmt.Errorf("error callapsing all dir: %w", err))
// TODO log error here
//return false
err = fmt.Errorf("error collapsing all directories: %w", err)
log.Error(err)
panic(err)
}
t.globalCollapseAll = !t.globalCollapseAll
@ -363,7 +357,7 @@ func (t *TreeView) getAbsPositionNode() (node *filetree.FileNode) {
err := t.tree.VisitDepthParentFirst(visitor, evaluator)
if err != nil {
logrus.Errorf("unable to get node position: %+v", err)
log.Errorf("unable to get node position: %+v", err)
}
return node
@ -386,10 +380,13 @@ func (t *TreeView) keyDown() bool {
t.bufferIndexLowerBound++
}
logrus.Debugf(" treeIndex: %d", t.treeIndex)
logrus.Debugf(" bufferIndexLowerBound: %d", t.bufferIndexLowerBound)
logrus.Debugf(" height: %d", height)
log.WithFields(
"component", "TreeView",
"path", t.getAbsPositionNode().Path(),
"treeIndex", t.treeIndex,
"bufferIndexLowerBound", t.bufferIndexLowerBound,
"height", height,
).Tracef("keyDown event")
return true
}
@ -402,9 +399,12 @@ func (t *TreeView) keyUp() bool {
t.bufferIndexLowerBound--
}
logrus.Debugf("keyUp end at: %s", t.getAbsPositionNode().Path())
logrus.Debugf(" treeIndex: %d", t.treeIndex)
logrus.Debugf(" bufferIndexLowerBound: %d", t.bufferIndexLowerBound)
log.WithFields(
"component", "TreeView",
"path", t.getAbsPositionNode().Path(),
"treeIndex", t.treeIndex,
"bufferIndexLowerBound", t.bufferIndexLowerBound,
).Tracef("keyUp event")
return true
}

View file

@ -49,16 +49,16 @@ func (fv *FilterView) Setup() *FilterView {
return fv
}
func (ll *FilterView) getBox() *tview.Box {
return ll.Box
func (fv *FilterView) getBox() *tview.Box {
return fv.Box
}
func (ll *FilterView) getDraw() drawFn {
return ll.Draw
func (fv *FilterView) getDraw() drawFn {
return fv.Draw
}
func (ll *FilterView) getInputWrapper() inputFn {
return ll.InputHandler
func (fv *FilterView) getInputWrapper() inputFn {
return fv.InputHandler
}
func (fv *FilterView) Empty() bool {

View file

@ -19,8 +19,8 @@ type KeyBindingDisplay struct {
}
func (kb *KeyBindingDisplay) Name() string {
s := ""
m := []string{}
var s string
var m []string
kMod := kb.Modifiers()
if kMod&tcell.ModShift != 0 {
m = append(m, "Shift")
@ -39,7 +39,7 @@ func (kb *KeyBindingDisplay) Name() string {
key := kb.Key()
if s, ok = tcell.KeyNames[key]; !ok {
if key == tcell.KeyRune {
if kb.Rune() == rune(' ') {
if kb.Rune() == ' ' {
s = "Space"
} else {
s = string(kb.Rune())
@ -50,7 +50,7 @@ func (kb *KeyBindingDisplay) Name() string {
}
if len(m) != 0 {
if kMod&tcell.ModCtrl != 0 && strings.HasPrefix(s, "Ctrl-") {
s = s[5:]
s = strings.TrimPrefix(s, "Ctrl-")
}
return fmt.Sprintf("%s%s", strings.Join(m, ""), s)
}

View file

@ -6,7 +6,7 @@ import (
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/internal/log"
"github.com/wagoodman/dive/runtime/ui/components/helpers"
"github.com/wagoodman/dive/runtime/ui/format"
)
@ -34,7 +34,7 @@ func (t *KeyMenuView) AddBoundViews(b ...BoundView) *KeyMenuView {
}
func (t *KeyMenuView) RemoveViews(b ...BoundView) *KeyMenuView {
newBoundList := []BoundView{}
var newBoundList []BoundView
boundSet := map[BoundView]interface{}{}
for _, v := range b {
boundSet[v] = true
@ -51,8 +51,8 @@ func (t *KeyMenuView) RemoveViews(b ...BoundView) *KeyMenuView {
}
func (t *KeyMenuView) GetKeyBindings() []helpers.KeyBindingDisplay {
logrus.Debug("Getting binding keys from keybinding primitive")
result := []helpers.KeyBindingDisplay{}
log.Trace("getting binding keys from keybinding primitive")
var result []helpers.KeyBindingDisplay
for _, view := range t.boundList {
if view.HasFocus() {
result = append(result, view.GetKeyBindings()...)
@ -66,7 +66,7 @@ func (t *KeyMenuView) Draw(screen tcell.Screen) {
t.Box.Draw(screen)
x, y, width, _ := t.Box.GetInnerRect()
lines := []string{}
var lines []string
keyBindings := t.GetKeyBindings()
for idx, binding := range keyBindings {
if binding.Hide() {
@ -87,8 +87,8 @@ func (t *KeyMenuView) Draw(screen tcell.Screen) {
prefix = ""
}
keyBindingContent := keyBindingFormatter(prefix + binding.Name() + " ")
displayContnet := displayFormatter(binding.Display + postfix)
lines = append(lines, fmt.Sprintf("%s%s", keyBindingContent, displayContnet))
displayContent := displayFormatter(binding.Display + postfix)
lines = append(lines, fmt.Sprintf("%s%s", keyBindingContent, displayContent))
}
joinedLine := strings.Join(lines, "")
_, w := tview.PrintWithStyle(screen, joinedLine, x, y, width, tview.AlignLeft, tcell.StyleDefault)

View file

@ -55,7 +55,7 @@ func (lv *LayerDetailsView) GetKeyBindings() []helpers.KeyBindingDisplay {
}
func layerDetailsText(layer *image.Layer) string {
lines := []string{}
var lines []string
if layer.Names != nil && len(layer.Names) > 0 {
lines = append(lines, boldString("Tags: ")+strings.Join(layer.Names, ", "))
} else {

View file

@ -5,11 +5,10 @@ import (
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/internal/log"
"github.com/wagoodman/dive/runtime/ui/components/helpers"
"github.com/wagoodman/dive/runtime/ui/format"
"github.com/wagoodman/dive/runtime/ui/viewmodels"
"go.uber.org/zap"
)
type LayersViewModel interface {
@ -99,7 +98,7 @@ func SwitchCompareLayerListBindingOption(k helpers.KeyBinding) LayerListViewOpti
}
ll.keyInputHandler.AddBinding(displayBinding, func() {
if err := ll.SwitchLayerMode(); err != nil {
logrus.Error("SwitchCompareLayers error: ", err.Error())
log.Error("SwitchCompareLayers error: ", err.Error())
}
})
}
@ -223,9 +222,12 @@ func (ll *LayerList) keyUp() bool {
ll.bufferIndexLowerBound--
}
logrus.Debugln("keyUp in layers")
logrus.Debugf(" cmpIndex: %d", ll.cmpIndex)
logrus.Debugf(" bufferIndexLowerBound: %d", ll.bufferIndexLowerBound)
log.WithFields(
"component", "LayerList",
"cmpIndex", ll.cmpIndex,
"bufferIndexLowerBound", ll.bufferIndexLowerBound,
).Tracef("keyUp event")
return ll.SetLayerIndex(ll.cmpIndex)
}
@ -241,15 +243,21 @@ func (ll *LayerList) keyDown() bool {
if ll.cmpIndex-ll.bufferIndexLowerBound >= height {
ll.bufferIndexLowerBound++
}
logrus.Debugln("keyDown in layers")
logrus.Debugf(" cmpIndex: %d", ll.cmpIndex)
logrus.Debugf(" bufferIndexLowerBound: %d", ll.bufferIndexLowerBound)
log.WithFields(
"component", "LayerList",
"cmpIndex", ll.cmpIndex,
"bufferIndexLowerBound", ll.bufferIndexLowerBound,
).Tracef("keyDown event")
return ll.SetLayerIndex(ll.cmpIndex)
}
func (ll *LayerList) pageUp() bool {
zap.S().Info("layer page up call")
log.WithFields(
"component", "LayerList",
).Tracef("pageUp event")
_, _, _, height := ll.Box.GetInnerRect()
ll.cmpIndex = intMax(0, ll.cmpIndex-height)
@ -261,7 +269,9 @@ func (ll *LayerList) pageUp() bool {
}
func (ll *LayerList) pageDown() bool {
zap.S().Info("layer page down call")
log.WithFields(
"component", "LayerList",
).Tracef("pageDown event")
// two parts of this are moving both the currently selected item & the window as a whole
_, _, _, height := ll.Box.GetInnerRect()

View file

@ -24,15 +24,12 @@ type VisibleFlex struct {
*tview.Box
// The items to be positioned.
items []*flexItem
items []*flexItem
consume [][]int
// FlexRow or FlexColumn.
direction int
visible VisibleFunc
direction int
visible VisibleFunc
bindingArray []helpers.KeyBinding
}

View file

@ -12,7 +12,7 @@ import (
// This was pretty helpful: https://github.com/rivo/tview/wiki/Primitives
type wrapable interface {
type wrappable interface {
getBox() *tview.Box
getDraw() drawFn
getInputWrapper() inputFn
@ -24,7 +24,7 @@ type Wrapper struct {
flex *tview.Flex
titleTextView *tview.TextView
subtitleTextView *tview.TextView
inner wrapable
inner wrappable
titleRightBox *tview.Box
title string
subtitle string
@ -35,7 +35,7 @@ type Wrapper struct {
type drawFn func(screen tcell.Screen)
type inputFn func() func(event *tcell.EventKey, setFocus func(p tview.Primitive))
func NewWrapper(title, subtitle string, inner wrapable) *Wrapper {
func NewWrapper(title, subtitle string, inner wrappable) *Wrapper {
flex := tview.NewFlex().SetDirection(tview.FlexRow)
w := &Wrapper{
Box: flex.Box,

View file

@ -3,12 +3,33 @@ package constructors
import (
"fmt"
"github.com/wagoodman/dive/internal/log"
"github.com/gdamore/tcell/v2"
"github.com/spf13/viper"
"github.com/wagoodman/dive/runtime/ui/components/helpers"
"gitlab.com/tslocum/cbind"
)
// TODO: this was partially pushed, feel free to remove when the final location is settled
// TODO move key constants out to their own file
var DisplayNames = map[string]string{
"keybinding.quit": "Quit",
"keybinding.toggle-view": "Switch View",
"keybinding.filter-files": "Find",
"keybinding.compare-all": "Compare All",
"keybinding.compare-layer": "Compare Layer",
"keybinding.toggle-collapse-dir": "Collapse",
"keybinding.toggle-collapse-all-dir": "Collapse All",
"keybinding.toggle-filetree-attributes": "Attributes",
"keybinding.toggle-added-files": "Added",
"keybinding.toggle-removed-files": "Removed",
"keybinding.toggle-modified-files": "Modified",
"keybinding.toggle-unmodified-files": "Unmodified",
"keybinding.page-up": "Pg Up",
"keybinding.page-down": "Pg Down",
}
type KeyConfig struct{}
type MissingConfigError struct {
@ -39,7 +60,13 @@ func (k *KeyConfig) GetKeyBinding(key string) (helpers.KeyBinding, error) {
if err != nil {
return helpers.KeyBinding{}, fmt.Errorf("unable to create binding from dive.config file: %q", err)
}
fmt.Printf("creating key event for %s\n", key)
fmt.Printf("mod %d, key %d, ch %s\n", mod, tKey, string(ch))
log.WithFields(
"component", "KeyConfig",
"configuredKey", key,
"mod", mod,
"decodedKey", tKey,
"char", fmt.Sprintf("%+v", ch),
).Tracef("creating key event")
return helpers.NewKeyBinding(name, tcell.NewEventKey(tKey, ch, mod)), nil
}

View file

@ -4,7 +4,7 @@ import (
"fmt"
"regexp"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/internal/log"
)
type FilterViewModel struct {
@ -19,9 +19,9 @@ func NewFilterViewModel(r *regexp.Regexp) *FilterViewModel {
func (fm *FilterViewModel) SetFilter(r *regexp.Regexp) {
if r != nil {
logrus.Info(fmt.Sprintf("setting filter: %s", r.String()))
log.Info(fmt.Sprintf("setting filter: %s", r.String()))
} else {
logrus.Info("setting filter: nil")
log.Info("setting filter: nil")
}
fm.filterRegex = r
}

View file

@ -3,9 +3,9 @@ package viewmodels
import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/dive/filetree"
"github.com/wagoodman/dive/dive/image"
"github.com/wagoodman/dive/internal/log"
)
const (
@ -59,7 +59,12 @@ func (lm *LayersViewModel) GetCompareIndicies() filetree.TreeIndexKey {
func (lm *LayersViewModel) SetLayerIndex(index int) bool {
if 0 <= index && index < len(lm.layers) {
logrus.Debug(fmt.Sprintf("setting index, old: %d, new: %d", lm.index, index))
log.WithFields(
"component", "LayersViewModel",
"from", lm.index,
"to", index,
).Tracef("setting layer index")
lm.index = index
return true
}

View file

@ -4,9 +4,9 @@ import (
"fmt"
"regexp"
"github.com/sirupsen/logrus"
"github.com/wagoodman/dive/dive/filetree"
"github.com/wagoodman/dive/dive/image"
"github.com/wagoodman/dive/internal/log"
)
//go:generate faux --interface FilterModel --output fakes/fake_filter_model.go
@ -14,6 +14,7 @@ type FilterModel interface {
SetFilter(r *regexp.Regexp)
GetFilter() *regexp.Regexp
}
//go:generate faux --interface LayersModel --output fakes/fake_layers_model.go
type LayersModel interface {
SetLayerIndex(index int) bool
@ -36,7 +37,6 @@ type TreeModel interface {
VisitDepthChildFirst(visitor filetree.Visitor, evaluator filetree.VisitEvaluator) error
RemovePath(path string) error
VisibleSize() int
}
type TreeViewModel struct {
@ -105,9 +105,11 @@ func (tvm *TreeViewModel) GetHiddenFileType(filetype filetree.DiffType) bool {
return tvm.hiddenDiffTypes[filetype]
}
func (tvm *TreeViewModel) filterUpdate() error {
log.WithFields(
"model", "treeView",
).Trace("updating filter")
// keep the t selection in parity with the current DiffType selection
filter := tvm.GetFilter()
err := tvm.currentTree.VisitDepthChildFirst(func(node *filetree.FileNode) error {
@ -132,7 +134,7 @@ func (tvm *TreeViewModel) filterUpdate() error {
}, nil)
if err != nil {
logrus.Errorf("error updating filter on current tree: %s", err)
log.Errorf("error updating filter on current tree: %s", err)
return err
}

View file

@ -1,20 +0,0 @@
package utils
import (
"github.com/jroimartin/gocui"
"github.com/sirupsen/logrus"
)
// isNewView determines if a view has already been created based on the set of errors given (a bit hokie)
func IsNewView(errs ...error) bool {
for _, err := range errs {
if err == nil {
return false
}
if err != gocui.ErrUnknownView {
logrus.Errorf("IsNewView() unexpected error: %+v", err)
return true
}
}
return true
}