From f8a5a8cb0191e291c1dd07adb9632f553b4d5a70 Mon Sep 17 00:00:00 2001
From: Hernan Bandura <hbandura@gmail.com>
Date: Wed, 26 Jun 2019 17:42:12 -0300
Subject: [PATCH] Update depguard version to 1.0.0 (Performance improvements)

---
 go.mod                                        |   2 +-
 go.sum                                        |   4 +-
 .../github.com/OpenPeeDeeP/depguard/README.md |   4 +
 .../OpenPeeDeeP/depguard/depguard.go          | 118 +++++++++++-------
 .../OpenPeeDeeP/depguard/rootchecker.go       |  52 ++++++++
 vendor/modules.txt                            |   2 +-
 6 files changed, 131 insertions(+), 51 deletions(-)
 create mode 100644 vendor/github.com/OpenPeeDeeP/depguard/rootchecker.go

diff --git a/go.mod b/go.mod
index 1c452be0..3bff4e3e 100644
--- a/go.mod
+++ b/go.mod
@@ -2,7 +2,7 @@ module github.com/golangci/golangci-lint
 
 require (
 	github.com/BurntSushi/toml v0.3.1 // indirect
-	github.com/OpenPeeDeeP/depguard v0.0.0-20180806142446-a69c782687b2
+	github.com/OpenPeeDeeP/depguard v1.0.0
 	github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
 	github.com/fatih/color v1.6.0
 	github.com/go-critic/go-critic v0.0.0-20181204210945-1df300866540
diff --git a/go.sum b/go.sum
index 58ababec..6cce0d29 100644
--- a/go.sum
+++ b/go.sum
@@ -1,7 +1,7 @@
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/OpenPeeDeeP/depguard v0.0.0-20180806142446-a69c782687b2 h1:HTOmFEEYrWi4MW5ZKUx6xfeyM10Sx3kQF65xiQJMPYA=
-github.com/OpenPeeDeeP/depguard v0.0.0-20180806142446-a69c782687b2/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o=
+github.com/OpenPeeDeeP/depguard v1.0.0 h1:k9QF73nrHT3nPLz3lu6G5s+3Hi8Je36ODr1F5gjAXXM=
+github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o=
 github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
 github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
diff --git a/vendor/github.com/OpenPeeDeeP/depguard/README.md b/vendor/github.com/OpenPeeDeeP/depguard/README.md
index 6f742511..3f7f2a4b 100644
--- a/vendor/github.com/OpenPeeDeeP/depguard/README.md
+++ b/vendor/github.com/OpenPeeDeeP/depguard/README.md
@@ -28,6 +28,9 @@ The following is an example configuration file.
   "packages": [
     "github.com/OpenPeeDeeP/depguard"
   ],
+  "inTests": [
+    "github.com/stretchr/testify"
+  ],
   "includeGoRoot": true
 }
 ```
@@ -35,6 +38,7 @@ The following is an example configuration file.
 - `type` can be either `whitelist` or `blacklist`. This check is case insensitive.
 If not specified the default is `blacklist`.
 - `packages` is a list of packages for the list type specified.
+- `inTests` is a list of packages allowed/disallowed only in test files.
 - Set `includeGoRoot` to true if you want to check the list against standard lib.
 If not specified the default is false.
 
diff --git a/vendor/github.com/OpenPeeDeeP/depguard/depguard.go b/vendor/github.com/OpenPeeDeeP/depguard/depguard.go
index 433cf8ff..b547c0b6 100644
--- a/vendor/github.com/OpenPeeDeeP/depguard/depguard.go
+++ b/vendor/github.com/OpenPeeDeeP/depguard/depguard.go
@@ -1,7 +1,6 @@
 package depguard
 
 import (
-	"go/build"
 	"go/token"
 	"os"
 	"sort"
@@ -11,44 +10,50 @@ import (
 	"golang.org/x/tools/go/loader"
 )
 
-//ListType states what kind of list is passed in.
+// ListType states what kind of list is passed in.
 type ListType int
 
 const (
-	//LTBlacklist states the list given is a blacklist. (default)
+	// LTBlacklist states the list given is a blacklist. (default)
 	LTBlacklist ListType = iota
-	//LTWhitelist states the list given is a whitelist.
+	// LTWhitelist states the list given is a whitelist.
 	LTWhitelist
 )
 
-//StringToListType makes it easier to turn a string into a ListType.
-//It assumes that the string representation is lower case.
+// StringToListType makes it easier to turn a string into a ListType.
+// It assumes that the string representation is lower case.
 var StringToListType = map[string]ListType{
 	"whitelist": LTWhitelist,
 	"blacklist": LTBlacklist,
 }
 
-//Issue with the package with PackageName at the Position.
+// Issue with the package with PackageName at the Position.
 type Issue struct {
 	PackageName string
 	Position    token.Position
 }
 
-//Depguard checks imports to make sure they follow the given list and constraints.
+// Depguard checks imports to make sure they follow the given list and constraints.
 type Depguard struct {
-	ListType       ListType
+	ListType      ListType
+	IncludeGoRoot bool
+
 	Packages       []string
-	IncludeGoRoot  bool
 	prefixPackages []string
 	globPackages   []glob.Glob
-	buildCtx       *build.Context
-	cwd            string
+
+	TestPackages       []string
+	prefixTestPackages []string
+	globTestPackages   []glob.Glob
+
+	rootChecker *RootChecker
+	cwd         string
 }
 
-//Run checks for dependencies given the program and validates them against
-//Packages.
+// Run checks for dependencies given the program and validates them against
+// Packages.
 func (dg *Depguard) Run(config *loader.Config, prog *loader.Program) ([]*Issue, error) {
-	//Shortcut execution on an empty blacklist as that means every package is allowed
+	// Shortcut execution on an empty blacklist as that means every package is allowed
 	if dg.ListType == LTBlacklist && len(dg.Packages) == 0 {
 		return nil, nil
 	}
@@ -56,15 +61,20 @@ func (dg *Depguard) Run(config *loader.Config, prog *loader.Program) ([]*Issue,
 	if err := dg.initialize(config, prog); err != nil {
 		return nil, err
 	}
-
 	directImports, err := dg.createImportMap(prog)
 	if err != nil {
 		return nil, err
 	}
 	var issues []*Issue
 	for pkg, positions := range directImports {
-		if dg.flagIt(pkg) {
-			for _, pos := range positions {
+		for _, pos := range positions {
+
+			prefixList, globList := dg.prefixPackages, dg.globPackages
+			if len(dg.TestPackages) > 0 && strings.Index(pos.Filename, "_test.go") != -1 {
+				prefixList, globList = dg.prefixTestPackages, dg.globTestPackages
+			}
+
+			if dg.flagIt(pkg, prefixList, globList) {
 				issues = append(issues, &Issue{
 					PackageName: pkg,
 					Position:    pos,
@@ -76,7 +86,7 @@ func (dg *Depguard) Run(config *loader.Config, prog *loader.Program) ([]*Issue,
 }
 
 func (dg *Depguard) initialize(config *loader.Config, prog *loader.Program) error {
-	//Try and get the current working directory
+	// Try and get the current working directory
 	dg.cwd = config.Cwd
 	if dg.cwd == "" {
 		var err error
@@ -86,12 +96,9 @@ func (dg *Depguard) initialize(config *loader.Config, prog *loader.Program) erro
 		}
 	}
 
-	//Use the &build.Default if one is not specified
-	dg.buildCtx = config.Build
-	if dg.buildCtx == nil {
-		dg.buildCtx = &build.Default
-	}
+	dg.rootChecker = NewRootChecker(config.Build)
 
+	// parse ordinary guarded packages
 	for _, pkg := range dg.Packages {
 		if strings.ContainsAny(pkg, "!?*[]{}") {
 			g, err := glob.Compile(pkg, '/')
@@ -104,27 +111,44 @@ func (dg *Depguard) initialize(config *loader.Config, prog *loader.Program) erro
 		}
 	}
 
-	//Sort the packages so we can have a faster search in the array
+	// Sort the packages so we can have a faster search in the array
 	sort.Strings(dg.prefixPackages)
+
+	// parse guarded tests packages
+	for _, pkg := range dg.TestPackages {
+		if strings.ContainsAny(pkg, "!?*[]{}") {
+			g, err := glob.Compile(pkg, '/')
+			if err != nil {
+				return err
+			}
+			dg.globTestPackages = append(dg.globTestPackages, g)
+		} else {
+			dg.prefixTestPackages = append(dg.prefixTestPackages, pkg)
+		}
+	}
+
+	// Sort the test packages so we can have a faster search in the array
+	sort.Strings(dg.prefixTestPackages)
+
 	return nil
 }
 
 func (dg *Depguard) createImportMap(prog *loader.Program) (map[string][]token.Position, error) {
 	importMap := make(map[string][]token.Position)
-	//For the directly imported packages
+	// For the directly imported packages
 	for _, imported := range prog.InitialPackages() {
-		//Go through their files
+		// Go through their files
 		for _, file := range imported.Files {
-			//And populate a map of all direct imports and their positions
-			//This will filter out GoRoot depending on the Depguard.IncludeGoRoot
+			// And populate a map of all direct imports and their positions
+			// This will filter out GoRoot depending on the Depguard.IncludeGoRoot
 			for _, fileImport := range file.Imports {
 				fileImportPath := cleanBasicLitString(fileImport.Path.Value)
 				if !dg.IncludeGoRoot {
-					pkg, err := dg.buildCtx.Import(fileImportPath, dg.cwd, 0)
+					isRoot, err := dg.rootChecker.IsRoot(fileImportPath, dg.cwd)
 					if err != nil {
 						return nil, err
 					}
-					if pkg.Goroot {
+					if isRoot {
 						continue
 					}
 				}
@@ -143,29 +167,29 @@ func (dg *Depguard) createImportMap(prog *loader.Program) (map[string][]token.Po
 	return importMap, nil
 }
 
-func (dg *Depguard) pkgInList(pkg string) bool {
-	if dg.pkgInPrefixList(pkg) {
+func (dg *Depguard) pkgInList(pkg string, prefixList []string, globList []glob.Glob) bool {
+	if dg.pkgInPrefixList(pkg, prefixList) {
 		return true
 	}
-	return dg.pkgInGlobList(pkg)
+	return dg.pkgInGlobList(pkg, globList)
 }
 
-func (dg *Depguard) pkgInPrefixList(pkg string) bool {
-	//Idx represents where in the package slice the passed in package would go
-	//when sorted. -1 Just means that it would be at the very front of the slice.
-	idx := sort.Search(len(dg.prefixPackages), func(i int) bool {
-		return dg.prefixPackages[i] > pkg
+func (dg *Depguard) pkgInPrefixList(pkg string, prefixList []string) bool {
+	// Idx represents where in the package slice the passed in package would go
+	// when sorted. -1 Just means that it would be at the very front of the slice.
+	idx := sort.Search(len(prefixList), func(i int) bool {
+		return prefixList[i] > pkg
 	}) - 1
-	//This means that the package passed in has no way to be prefixed by anything
-	//in the package list as it is already smaller then everything
+	// This means that the package passed in has no way to be prefixed by anything
+	// in the package list as it is already smaller then everything
 	if idx == -1 {
 		return false
 	}
-	return strings.HasPrefix(pkg, dg.prefixPackages[idx])
+	return strings.HasPrefix(pkg, prefixList[idx])
 }
 
-func (dg *Depguard) pkgInGlobList(pkg string) bool {
-	for _, g := range dg.globPackages {
+func (dg *Depguard) pkgInGlobList(pkg string, globList []glob.Glob) bool {
+	for _, g := range globList {
 		if g.Match(pkg) {
 			return true
 		}
@@ -173,11 +197,11 @@ func (dg *Depguard) pkgInGlobList(pkg string) bool {
 	return false
 }
 
-//InList | WhiteList | BlackList
+// InList | WhiteList | BlackList
 //   y   |           |     x
 //   n   |     x     |
-func (dg *Depguard) flagIt(pkg string) bool {
-	return dg.pkgInList(pkg) == (dg.ListType == LTBlacklist)
+func (dg *Depguard) flagIt(pkg string, prefixList []string, globList []glob.Glob) bool {
+	return dg.pkgInList(pkg, prefixList, globList) == (dg.ListType == LTBlacklist)
 }
 
 func cleanBasicLitString(value string) string {
diff --git a/vendor/github.com/OpenPeeDeeP/depguard/rootchecker.go b/vendor/github.com/OpenPeeDeeP/depguard/rootchecker.go
new file mode 100644
index 00000000..7dae0efd
--- /dev/null
+++ b/vendor/github.com/OpenPeeDeeP/depguard/rootchecker.go
@@ -0,0 +1,52 @@
+package depguard
+
+import (
+	"go/build"
+)
+
+// RootChecker checks if import paths point to root packages.
+type RootChecker struct {
+	buildCtx *build.Context
+	cache    map[string]bool
+}
+
+// NewRootChecker creates a new RootChecker instance using the build.Context
+// given, or build.Default.
+func NewRootChecker(buildCtx *build.Context) *RootChecker {
+	// Use the &build.Default if build.Context is not specified
+	ctx := buildCtx
+	if ctx == nil {
+		ctx = &build.Default
+	}
+	return &RootChecker{
+		buildCtx: ctx,
+		cache:    make(map[string]bool, 0),
+	}
+}
+
+// IsRoot checks if the given import path (imported from sourceDir)
+// points to a a root package. Subsequent calls with the same arguments
+// are cached. This is not thread-safe.
+func (rc *RootChecker) IsRoot(path, sourceDir string) (bool, error) {
+	key := path + ":::" + sourceDir
+	isRoot, ok := rc.cache[key]
+	if ok {
+		return isRoot, nil
+	}
+	isRoot, err := rc.calcIsRoot(path, sourceDir)
+	if err != nil {
+		return false, err
+	}
+	rc.cache[key] = isRoot
+	return isRoot, nil
+}
+
+// calcIsRoot performs the call to the build context to check if
+// the import path points to a root package.
+func (rc *RootChecker) calcIsRoot(path, sourceDir string) (bool, error) {
+	pkg, err := rc.buildCtx.Import(path, sourceDir, build.FindOnly)
+	if err != nil {
+		return false, err
+	}
+	return pkg.Goroot, nil
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 0cb94687..89160bf2 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1,6 +1,6 @@
 # github.com/BurntSushi/toml v0.3.1
 github.com/BurntSushi/toml
-# github.com/OpenPeeDeeP/depguard v0.0.0-20180806142446-a69c782687b2
+# github.com/OpenPeeDeeP/depguard v1.0.0
 github.com/OpenPeeDeeP/depguard
 # github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6
 github.com/StackExchange/wmi