github.com/candidpartners/terraform@v0.9.5-0.20171005231213-29f5f88820f6/terraform/util.go (about) 1 package terraform 2 3 import ( 4 "sort" 5 "strings" 6 ) 7 8 // Semaphore is a wrapper around a channel to provide 9 // utility methods to clarify that we are treating the 10 // channel as a semaphore 11 type Semaphore chan struct{} 12 13 // NewSemaphore creates a semaphore that allows up 14 // to a given limit of simultaneous acquisitions 15 func NewSemaphore(n int) Semaphore { 16 if n == 0 { 17 panic("semaphore with limit 0") 18 } 19 ch := make(chan struct{}, n) 20 return Semaphore(ch) 21 } 22 23 // Acquire is used to acquire an available slot. 24 // Blocks until available. 25 func (s Semaphore) Acquire() { 26 s <- struct{}{} 27 } 28 29 // TryAcquire is used to do a non-blocking acquire. 30 // Returns a bool indicating success 31 func (s Semaphore) TryAcquire() bool { 32 select { 33 case s <- struct{}{}: 34 return true 35 default: 36 return false 37 } 38 } 39 40 // Release is used to return a slot. Acquire must 41 // be called as a pre-condition. 42 func (s Semaphore) Release() { 43 select { 44 case <-s: 45 default: 46 panic("release without an acquire") 47 } 48 } 49 50 // resourceProvider returns the provider name for the given type. 51 func resourceProvider(t, alias string) string { 52 if alias != "" { 53 return alias 54 } 55 56 idx := strings.IndexRune(t, '_') 57 if idx == -1 { 58 // If no underscores, the resource name is assumed to be 59 // also the provider name, e.g. if the provider exposes 60 // only a single resource of each type. 61 return t 62 } 63 64 return t[:idx] 65 } 66 67 // strSliceContains checks if a given string is contained in a slice 68 // When anybody asks why Go needs generics, here you go. 69 func strSliceContains(haystack []string, needle string) bool { 70 for _, s := range haystack { 71 if s == needle { 72 return true 73 } 74 } 75 return false 76 } 77 78 // deduplicate a slice of strings 79 func uniqueStrings(s []string) []string { 80 if len(s) < 2 { 81 return s 82 } 83 84 sort.Strings(s) 85 result := make([]string, 1, len(s)) 86 result[0] = s[0] 87 for i := 1; i < len(s); i++ { 88 if s[i] != result[len(result)-1] { 89 result = append(result, s[i]) 90 } 91 } 92 return result 93 }