github.com/golang/dep@v0.5.4/gps/pkgtree/reachmap.go (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package pkgtree
     6  
     7  import (
     8  	"sort"
     9  	"strings"
    10  )
    11  
    12  // ReachMap maps a set of import paths (keys) to the sets of transitively
    13  // reachable tree-internal packages, and all the tree-external packages
    14  // reachable through those internal packages.
    15  //
    16  // See PackageTree.ToReachMap() for more information.
    17  type ReachMap map[string]struct {
    18  	Internal, External []string
    19  }
    20  
    21  // Eliminate import paths with any elements having leading dots, leading
    22  // underscores, or testdata. If these are internally reachable (which is
    23  // a no-no, but possible), any external imports will have already been
    24  // pulled up through ExternalReach. The key here is that we don't want
    25  // to treat such packages as themselves being sources.
    26  func pkgFilter(pkg string) bool {
    27  	for _, elem := range strings.Split(pkg, "/") {
    28  		if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" {
    29  			return false
    30  		}
    31  	}
    32  	return true
    33  }
    34  
    35  // FlattenFn flattens a reachmap into a sorted, deduplicated list of all the
    36  // external imports named by its contained packages, but excludes imports coming
    37  // from packages with disallowed patterns in their names: any path element with
    38  // a leading dot, a leading underscore, with the name "testdata".
    39  //
    40  // Imports for which exclude returns true will be left out.
    41  func (rm ReachMap) FlattenFn(exclude func(string) bool) []string {
    42  	exm := make(map[string]struct{})
    43  	for pkg, ie := range rm {
    44  		if pkgFilter(pkg) {
    45  			for _, ex := range ie.External {
    46  				if exclude != nil && exclude(ex) {
    47  					continue
    48  				}
    49  				exm[ex] = struct{}{}
    50  			}
    51  		}
    52  	}
    53  
    54  	if len(exm) == 0 {
    55  		return []string{}
    56  	}
    57  
    58  	ex := make([]string, 0, len(exm))
    59  	for p := range exm {
    60  		ex = append(ex, p)
    61  	}
    62  
    63  	sort.Strings(ex)
    64  	return ex
    65  }