github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/legacy/terraform/util.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package terraform
     5  
     6  import (
     7  	"sort"
     8  )
     9  
    10  // Semaphore is a wrapper around a channel to provide
    11  // utility methods to clarify that we are treating the
    12  // channel as a semaphore
    13  type Semaphore chan struct{}
    14  
    15  // NewSemaphore creates a semaphore that allows up
    16  // to a given limit of simultaneous acquisitions
    17  func NewSemaphore(n int) Semaphore {
    18  	if n <= 0 {
    19  		panic("semaphore with limit <=0")
    20  	}
    21  	ch := make(chan struct{}, n)
    22  	return Semaphore(ch)
    23  }
    24  
    25  // Acquire is used to acquire an available slot.
    26  // Blocks until available.
    27  func (s Semaphore) Acquire() {
    28  	s <- struct{}{}
    29  }
    30  
    31  // TryAcquire is used to do a non-blocking acquire.
    32  // Returns a bool indicating success
    33  func (s Semaphore) TryAcquire() bool {
    34  	select {
    35  	case s <- struct{}{}:
    36  		return true
    37  	default:
    38  		return false
    39  	}
    40  }
    41  
    42  // Release is used to return a slot. Acquire must
    43  // be called as a pre-condition.
    44  func (s Semaphore) Release() {
    45  	select {
    46  	case <-s:
    47  	default:
    48  		panic("release without an acquire")
    49  	}
    50  }
    51  
    52  // strSliceContains checks if a given string is contained in a slice
    53  // When anybody asks why Go needs generics, here you go.
    54  func strSliceContains(haystack []string, needle string) bool {
    55  	for _, s := range haystack {
    56  		if s == needle {
    57  			return true
    58  		}
    59  	}
    60  	return false
    61  }
    62  
    63  // deduplicate a slice of strings
    64  func uniqueStrings(s []string) []string {
    65  	if len(s) < 2 {
    66  		return s
    67  	}
    68  
    69  	sort.Strings(s)
    70  	result := make([]string, 1, len(s))
    71  	result[0] = s[0]
    72  	for i := 1; i < len(s); i++ {
    73  		if s[i] != result[len(result)-1] {
    74  			result = append(result, s[i])
    75  		}
    76  	}
    77  	return result
    78  }