github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tiltfile/config/resources.go (about) 1 package config 2 3 import ( 4 "fmt" 5 6 "github.com/pkg/errors" 7 "go.starlark.net/starlark" 8 9 "github.com/tilt-dev/tilt/internal/sliceutils" 10 "github.com/tilt-dev/tilt/internal/tiltfile/starkit" 11 "github.com/tilt-dev/tilt/internal/tiltfile/value" 12 "github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1" 13 "github.com/tilt-dev/tilt/pkg/model" 14 ) 15 16 func setEnabledResources(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 17 var slResources starlark.Sequence 18 err := starkit.UnpackArgs(thread, fn.Name(), args, kwargs, 19 "resources", 20 &slResources, 21 ) 22 if err != nil { 23 return starlark.None, err 24 } 25 26 resources, err := value.SequenceToStringSlice(slResources) 27 if err != nil { 28 return starlark.None, errors.Wrap(err, "resources must be a list of string") 29 } 30 31 var mns []model.ManifestName 32 for _, r := range resources { 33 mns = append(mns, model.ManifestName(r)) 34 } 35 36 err = starkit.SetState(thread, func(settings Settings) Settings { 37 settings.disableAll = false 38 settings.enabledResources = mns 39 return settings 40 }) 41 if err != nil { 42 return starlark.None, err 43 } 44 45 return starlark.None, nil 46 } 47 48 func clearEnabledResources(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 49 err := starkit.UnpackArgs(thread, fn.Name(), args, kwargs) 50 if err != nil { 51 return starlark.None, err 52 } 53 54 err = starkit.SetState(thread, func(settings Settings) Settings { 55 settings.disableAll = true 56 settings.enabledResources = nil 57 return settings 58 }) 59 return starlark.None, err 60 } 61 62 // for the given args and list of full manifests, figure out which manifests the user actually selected 63 func (s Settings) EnabledResources(tf *v1alpha1.Tiltfile, manifests []model.Manifest) ([]model.ManifestName, error) { 64 if s.disableAll { 65 return nil, nil 66 } 67 68 // by default, nil = match all resources 69 var requestedManifests []model.ManifestName 70 71 // if the user called set_enabled_resources, that trumps everything 72 if s.enabledResources != nil { 73 requestedManifests = s.enabledResources 74 } else { 75 args := tf.Spec.Args 76 77 // if the user has not called config.parse and has specified args, use those to select which resources 78 if args != nil && !s.configParseCalled { 79 for _, arg := range args { 80 requestedManifests = append(requestedManifests, model.ManifestName(arg)) 81 } 82 } 83 } 84 85 return match(manifests, requestedManifests) 86 } 87 88 // add `manifestToAdd` and all of its transitive deps to `result` 89 func addManifestAndDeps(result map[model.ManifestName]bool, allManifestsByName map[model.ManifestName]model.Manifest, manifestToAdd model.ManifestName) { 90 if result[manifestToAdd] { 91 return 92 } 93 result[manifestToAdd] = true 94 for _, dep := range allManifestsByName[manifestToAdd].ResourceDependencies { 95 addManifestAndDeps(result, allManifestsByName, dep) 96 } 97 } 98 99 // If the user requested only a subset of manifests, get just those manifests 100 func match(manifests []model.Manifest, requestedManifests []model.ManifestName) ([]model.ManifestName, error) { 101 if len(requestedManifests) == 0 { 102 var result []model.ManifestName 103 for _, m := range manifests { 104 result = append(result, m.Name) 105 } 106 return result, nil 107 } 108 109 manifestsByName := make(map[model.ManifestName]model.Manifest) 110 for _, m := range manifests { 111 manifestsByName[m.Name] = m 112 } 113 114 manifestsToRun := make(map[model.ManifestName]bool) 115 var unknownNames []string 116 117 for _, m := range requestedManifests { 118 if _, ok := manifestsByName[m]; !ok { 119 unknownNames = append(unknownNames, string(m)) 120 continue 121 } 122 123 addManifestAndDeps(manifestsToRun, manifestsByName, m) 124 } 125 126 var result []model.ManifestName 127 for _, m := range manifests { 128 // Default to including UnresourcedYAML ("Uncategorized") to match historical behavior. 129 if manifestsToRun[m.Name] || m.Name == model.UnresourcedYAMLManifestName { 130 result = append(result, m.Name) 131 } 132 } 133 134 if len(unknownNames) > 0 { 135 unmatchedNames := unmatchedManifestNames(manifests, requestedManifests) 136 137 return nil, fmt.Errorf(`You specified some resources that could not be found: %s 138 Is this a typo? Existing resources in Tiltfile: %s`, 139 sliceutils.QuotedStringList(unknownNames), 140 sliceutils.QuotedStringList(unmatchedNames)) 141 } 142 143 return result, nil 144 } 145 146 func unmatchedManifestNames(manifests []model.Manifest, requestedManifests []model.ManifestName) []string { 147 requestedManifestsByName := make(map[model.ManifestName]bool) 148 for _, m := range requestedManifests { 149 requestedManifestsByName[m] = true 150 } 151 152 var ret []string 153 for _, m := range manifests { 154 if _, ok := requestedManifestsByName[m.Name]; !ok { 155 ret = append(ret, string(m.Name)) 156 } 157 } 158 159 return ret 160 }