github.com/myhau/pulumi/pkg/v3@v3.70.2-0.20221116134521-f2775972e587/codegen/utilities.go (about)

     1  // Copyright 2016-2020, Pulumi Corporation.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package codegen
    16  
    17  import (
    18  	"os"
    19  	"path/filepath"
    20  	"reflect"
    21  	"sort"
    22  
    23  	"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
    24  )
    25  
    26  type StringSet map[string]struct{}
    27  
    28  func NewStringSet(values ...string) StringSet {
    29  	s := StringSet{}
    30  	for _, v := range values {
    31  		s.Add(v)
    32  	}
    33  	return s
    34  }
    35  
    36  func (ss StringSet) Add(s string) {
    37  	ss[s] = struct{}{}
    38  }
    39  
    40  func (ss StringSet) Any() bool {
    41  	return len(ss) > 0
    42  }
    43  
    44  func (ss StringSet) Delete(s string) {
    45  	delete(ss, s)
    46  }
    47  
    48  func (ss StringSet) Has(s string) bool {
    49  	_, ok := ss[s]
    50  	return ok
    51  }
    52  
    53  // StringSet.Except returns the string set setminus s.
    54  func (ss StringSet) Except(s string) StringSet {
    55  	return ss.Subtract(NewStringSet(s))
    56  }
    57  
    58  func (ss StringSet) SortedValues() []string {
    59  	values := make([]string, 0, len(ss))
    60  	for v := range ss {
    61  		values = append(values, v)
    62  	}
    63  	sort.Strings(values)
    64  	return values
    65  }
    66  
    67  // Contains returns true if all elements of the subset are also present in the current set. It also returns true
    68  // if subset is empty.
    69  func (ss StringSet) Contains(subset StringSet) bool {
    70  	for v := range subset {
    71  		if !ss.Has(v) {
    72  			return false
    73  		}
    74  	}
    75  	return true
    76  }
    77  
    78  // Subtract returns a new string set with all elements of the current set that are not present in the other set.
    79  func (ss StringSet) Subtract(other StringSet) StringSet {
    80  	result := NewStringSet()
    81  	for v := range ss {
    82  		if !other.Has(v) {
    83  			result.Add(v)
    84  		}
    85  	}
    86  	return result
    87  }
    88  
    89  func (ss StringSet) Union(other StringSet) StringSet {
    90  	result := NewStringSet()
    91  	for v := range ss {
    92  		result.Add(v)
    93  	}
    94  	for v := range other {
    95  		result.Add(v)
    96  	}
    97  	return result
    98  }
    99  
   100  type Set map[interface{}]struct{}
   101  
   102  func (s Set) Add(v interface{}) {
   103  	s[v] = struct{}{}
   104  }
   105  
   106  func (s Set) Delete(v interface{}) {
   107  	delete(s, v)
   108  }
   109  
   110  func (s Set) Has(v interface{}) bool {
   111  	_, ok := s[v]
   112  	return ok
   113  }
   114  
   115  // SortedKeys returns a sorted list of keys for the given map. The map's key type must be of kind string.
   116  func SortedKeys(m interface{}) []string {
   117  	mv := reflect.ValueOf(m)
   118  
   119  	contract.Require(mv.Type().Kind() == reflect.Map, "m")
   120  	contract.Require(mv.Type().Key().Kind() == reflect.String, "m")
   121  
   122  	keys := make([]string, mv.Len())
   123  	for i, k := range mv.MapKeys() {
   124  		keys[i] = k.String()
   125  	}
   126  	sort.Strings(keys)
   127  
   128  	return keys
   129  }
   130  
   131  // CleanDir removes all existing files from a directory except those in the exclusions list.
   132  // Note: The exclusions currently don't function recursively, so you cannot exclude a single file
   133  // in a subdirectory, only entire subdirectories. This function will need improvements to be able to
   134  // target that use-case.
   135  func CleanDir(dirPath string, exclusions StringSet) error {
   136  	subPaths, err := os.ReadDir(dirPath)
   137  	if err != nil {
   138  		return err
   139  	}
   140  
   141  	if len(subPaths) > 0 {
   142  		for _, path := range subPaths {
   143  			if !exclusions.Has(path.Name()) {
   144  				err = os.RemoveAll(filepath.Join(dirPath, path.Name()))
   145  				if err != nil {
   146  					return err
   147  				}
   148  			}
   149  		}
   150  	}
   151  
   152  	return nil
   153  }
   154  
   155  var commonEnumNameReplacements = map[string]string{
   156  	"*": "Asterisk",
   157  	"0": "Zero",
   158  	"1": "One",
   159  	"2": "Two",
   160  	"3": "Three",
   161  	"4": "Four",
   162  	"5": "Five",
   163  	"6": "Six",
   164  	"7": "Seven",
   165  	"8": "Eight",
   166  	"9": "Nine",
   167  }
   168  
   169  func ExpandShortEnumName(name string) string {
   170  	if replacement, ok := commonEnumNameReplacements[name]; ok {
   171  		return replacement
   172  	}
   173  	return name
   174  }
   175  
   176  // A simple in memory file system.
   177  type Fs map[string][]byte
   178  
   179  // Add a new file to the Fs.
   180  //
   181  // Panic if the file is a duplicate.
   182  func (fs Fs) Add(path string, contents []byte) {
   183  	_, has := fs[path]
   184  	contract.Assertf(!has, "duplicate file: %s", path)
   185  	fs[path] = contents
   186  }