github.com/tilt-dev/tilt@v0.36.0/internal/tiltfile/local_resource.go (about) 1 package tiltfile 2 3 import ( 4 "fmt" 5 "path/filepath" 6 7 "github.com/pkg/errors" 8 "go.starlark.net/starlark" 9 10 "github.com/tilt-dev/tilt/internal/tiltfile/links" 11 "github.com/tilt-dev/tilt/internal/tiltfile/probe" 12 "github.com/tilt-dev/tilt/internal/tiltfile/starkit" 13 "github.com/tilt-dev/tilt/internal/tiltfile/value" 14 "github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1" 15 "github.com/tilt-dev/tilt/pkg/logger" 16 "github.com/tilt-dev/tilt/pkg/model" 17 ) 18 19 const testDeprecationMsg = "test() is deprecated and will be removed in a future release.\n" + 20 "Change this call to use `local_resource(..., allow_parallel=True)`" 21 22 type localResource struct { 23 name string 24 updateCmd model.Cmd 25 serveCmd model.Cmd 26 // The working directory of the execution thread where the local resource was created. 27 threadDir string 28 deps []string 29 triggerMode triggerMode 30 autoInit bool 31 resourceDeps []string 32 ignores []string 33 allowParallel bool 34 links []model.Link 35 labels map[string]string 36 37 readinessProbe *v1alpha1.Probe 38 } 39 40 func (s *tiltfileState) localResource(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 41 var name value.Name 42 var updateCmdVal, updateCmdBatVal, serveCmdVal, serveCmdBatVal starlark.Value 43 var updateEnv, serveEnv value.StringStringMap 44 var triggerMode triggerMode 45 var readinessProbe probe.Probe 46 var updateCmdDirVal, serveCmdDirVal starlark.Value 47 48 deps := value.NewLocalPathListUnpacker(thread) 49 50 var resourceDepsVal starlark.Sequence 51 var ignoresVal starlark.Value 52 var allowParallel bool 53 var links links.LinkList 54 var labels value.LabelSet 55 autoInit := true 56 if fn.Name() == testN { 57 // If we're initializing a test, by default parallelism is on 58 allowParallel = true 59 logger.Get(s.ctx).Warnf("%s", testDeprecationMsg) 60 } 61 62 if err := s.unpackArgs(fn.Name(), args, kwargs, 63 "name", &name, 64 "cmd?", &updateCmdVal, 65 "deps?", &deps, 66 "trigger_mode?", &triggerMode, 67 "resource_deps?", &resourceDepsVal, 68 "ignore?", &ignoresVal, 69 "auto_init?", &autoInit, 70 "serve_cmd?", &serveCmdVal, 71 "cmd_bat?", &updateCmdBatVal, 72 "serve_cmd_bat?", &serveCmdBatVal, 73 "allow_parallel?", &allowParallel, 74 "links?", &links, 75 "labels?", &labels, 76 "env?", &updateEnv, 77 "serve_env?", &serveEnv, 78 "readiness_probe?", &readinessProbe, 79 "dir?", &updateCmdDirVal, 80 "serve_dir?", &serveCmdDirVal, 81 ); err != nil { 82 return nil, err 83 } 84 85 resourceDeps, err := value.SequenceToStringSlice(resourceDepsVal) 86 if err != nil { 87 return nil, errors.Wrapf(err, "%s: resource_deps", fn.Name()) 88 } 89 90 ignores, err := parseValuesToStrings(ignoresVal, "ignore") 91 if err != nil { 92 return nil, err 93 } 94 95 updateCmd, err := value.ValueGroupToCmdHelper(thread, updateCmdVal, updateCmdBatVal, updateCmdDirVal, updateEnv) 96 if err != nil { 97 return nil, err 98 } 99 serveCmd, err := value.ValueGroupToCmdHelper(thread, serveCmdVal, serveCmdBatVal, serveCmdDirVal, serveEnv) 100 if err != nil { 101 return nil, err 102 } 103 104 // Validate dir/cmd combinations to prevent common mistakes 105 if updateCmdDirVal != nil && updateCmd.Empty() { 106 if !serveCmd.Empty() { 107 return nil, fmt.Errorf("local_resource: 'dir' only affects 'cmd', not 'serve_cmd'. Did you mean to use 'serve_dir' instead?") 108 } 109 return nil, fmt.Errorf("local_resource: 'dir' specified but 'cmd' is empty") 110 } 111 112 if serveCmdDirVal != nil && serveCmd.Empty() { 113 return nil, fmt.Errorf("local_resource: 'serve_dir' specified but 'serve_cmd' is empty") 114 } 115 116 if updateCmd.Empty() && serveCmd.Empty() { 117 return nil, fmt.Errorf("local_resource must have a cmd and/or a serve_cmd, but both were empty") 118 } 119 120 probeSpec := readinessProbe.Spec() 121 if probeSpec != nil && serveCmd.Empty() { 122 s.logger.Warnf("Ignoring readiness probe for local resource %q (no serve_cmd was defined)", name) 123 probeSpec = nil 124 } 125 126 res := &localResource{ 127 name: string(name), 128 updateCmd: updateCmd, 129 serveCmd: serveCmd, 130 threadDir: filepath.Dir(starkit.CurrentExecPath(thread)), 131 deps: deps.Value, 132 triggerMode: triggerMode, 133 autoInit: autoInit, 134 resourceDeps: resourceDeps, 135 ignores: ignores, 136 allowParallel: allowParallel, 137 links: links.Links, 138 labels: labels.Values, 139 readinessProbe: probeSpec, 140 } 141 142 // check for duplicate resources by name and throw error if found 143 err = s.checkResourceConflict(res.name) 144 if err != nil { 145 return nil, err 146 } 147 s.localResources = append(s.localResources, res) 148 s.localByName[res.name] = res 149 150 return starlark.None, nil 151 }