github.com/golang/dep@v0.5.4/gps/pkgtree/ignored_ruleset.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 "github.com/armon/go-radix" 12 ) 13 14 // IgnoredRuleset comprises a set of rules for ignoring import paths. It can 15 // manage both literal and prefix-wildcard matches. 16 type IgnoredRuleset struct { 17 t *radix.Tree 18 } 19 20 // NewIgnoredRuleset processes a set of strings into an IgnoredRuleset. Strings 21 // that end in "*" are treated as wildcards, where any import path with a 22 // matching prefix will be ignored. IgnoredRulesets are immutable once created. 23 // 24 // Duplicate and redundant (i.e. a literal path that has a prefix of a wildcard 25 // path) declarations are discarded. Consequently, it is possible that the 26 // returned IgnoredRuleset may have a smaller Len() than the input slice. 27 func NewIgnoredRuleset(ig []string) *IgnoredRuleset { 28 if len(ig) == 0 { 29 return &IgnoredRuleset{} 30 } 31 32 ir := &IgnoredRuleset{ 33 t: radix.New(), 34 } 35 36 // Sort the list of all the ignores in order to ensure that wildcard 37 // precedence is recorded correctly in the trie. 38 sort.Strings(ig) 39 for _, i := range ig { 40 // Skip global ignore and empty string. 41 if i == "*" || i == "" { 42 continue 43 } 44 45 _, wildi, has := ir.t.LongestPrefix(i) 46 // We may not always have a value here, but if we do, then it's a bool. 47 wild, _ := wildi.(bool) 48 // Check if it's a wildcard ignore. 49 if strings.HasSuffix(i, "*") { 50 // Check if it is ineffectual. 51 if has && wild { 52 // Skip ineffectual wildcard ignore. 53 continue 54 } 55 // Create the ignore prefix and insert in the radix tree. 56 ir.t.Insert(i[:len(i)-1], true) 57 } else if !has || !wild { 58 ir.t.Insert(i, false) 59 } 60 } 61 62 if ir.t.Len() == 0 { 63 ir.t = nil 64 } 65 66 return ir 67 } 68 69 // IsIgnored indicates whether the provided path should be ignored, according to 70 // the ruleset. 71 func (ir *IgnoredRuleset) IsIgnored(path string) bool { 72 if path == "" || ir == nil || ir.t == nil { 73 return false 74 } 75 76 prefix, wildi, has := ir.t.LongestPrefix(path) 77 return has && (wildi.(bool) || path == prefix) 78 } 79 80 // Len indicates the number of rules in the ruleset. 81 func (ir *IgnoredRuleset) Len() int { 82 if ir == nil || ir.t == nil { 83 return 0 84 } 85 86 return ir.t.Len() 87 } 88 89 // ToSlice converts the contents of the IgnoredRuleset to a string slice. 90 // 91 // This operation is symmetrically dual to NewIgnoredRuleset. 92 func (ir *IgnoredRuleset) ToSlice() []string { 93 irlen := ir.Len() 94 if irlen == 0 { 95 return nil 96 } 97 98 items := make([]string, 0, irlen) 99 ir.t.Walk(func(s string, v interface{}) bool { 100 if s != "" { 101 if v.(bool) { 102 items = append(items, s+"*") 103 } else { 104 items = append(items, s) 105 } 106 } 107 return false 108 }) 109 110 return items 111 }