github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/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  }