tilt
tilt copied to clipboard
Support for local_resource stdout capturing
I have a local that is used to inject configuration requirements for local iteration on a helm chart. This local depends on another resource being available to poll for certain information. I could use local_resource to satisfy the dependency constraint, but this does not provide stdout.
My workaround ends up being something along the lines of:
local_resource('local_requirement', './script.sh > generated_file', resource_deps=upstreams)
k8s_yaml(helm('chart_name', set=['arg={}'.format(read_file('generated_file')))
A small quality of life improvement would be to allow local_resource to return stdout (perhaps disabled by default).
Thanks for the feature request! The use case is definitely compelling, the problem is that it doesn't jive with how Tiltfile evaluation currently works. Right now, we evaluate the whole Tiltfile to figure out what resources exist, and THEN start executing the resources -- there's no good way to execute a local resource, then use its output for something else in the Tiltfile.
We'll keep thinking on this. Is this workaround feeling okay right now, or causing you any pain beyond "this is awkward"?
The alternative, of course, being using local() instead of local_resource to run the script. I wouldn't recommend this if your script takes a particularly long time to run (b/c the downside of this approach is that your script will execute every time your Tiltfile reloads, even if the reload stems from something totally unrelated to your script), but given that we don't actually have a good solution for this use case, this might be the lesser of two evils:
helm_arg = local('./script.sh')
k8s_yaml(helm('chart_name', set=['arg={}'.format(str(helm_arg)))
For the time being, this workflow is working fine other than the clunkiness.
I can definitely see how this use case could be very counter to how Tiltfile is processed. The only way I could see this working reasonably is capturing stdout if the local_resource is a dependency of another resource. E.g.
local_resource('not_captured', cmd='echo "not captured"')
local_out = local_resource('captured', cmd='whoami')
k8s_yaml(helm('chart_name', set=['arg={}'.format(local_out), resource_deps=['captured'])
This feels a little more natural, but could seem like a special language exception to remember for an end user. This approach also does not get an implicit dependency added to the k8s_yaml that the initial workaround provides. The implicit dependency allows a user to avoid requiring an additional k8s_resource to specify ordering constraints.
As for using local, my use case has a dependency on another k8s_resource being available for local_resource to interact with. Running at startup is not viable unless I move the k8s_resource initial creation outside my Tiltfile. Otherwise, local would be fine.
Based on the implementation constraints, I am amenable to illustrating the relevant use cases in the Tilt cookbooks section of the user docs. E.g. "How to: Execute a local command after another resource becomes available". The current documentation provides everything a user needs to come up with a similar solution on their own, but not necessarily in an obvious centralized location.
another suggestion that came up was also to have a write_file api like
write_file(contents, filename, append=False)
While it doesn't address the general case of "capture local_resource output", Tilt has added k8s_custom_deploy, which is pretty similar to running k8s_yaml on the result of a local_resource and is likely to be helpful for the specific example in this issue.