Feature request: until / line parser
aight8 opened this issue · 3 comments
Following functions I am missing at the most. They can be implemented in pure bash, but they would fit very nicely in this libraries scope.
Until - Stdout evaluation until (bash like)
Raw implementation (bash):
cmd.run 'until [ $(kubectl get pods -n kube-system -l app=helm,name=tiller -o jsonpath="{.items[0].status.containerStatuses[0].ready}") = "true" ]; do
sleep 2
done'
Better:
cmd.until 'kubectl get pods -n kube-system -l app=helm,name=tiller -o jsonpath="{.items[0].status.containerStatuses[0].ready}', 'Ready'
So this waits until the output of the command is Ready. The stdout which get compared should be striped.
Wait - Log running script line match
Similar but not the same. Long running bash process which output log style lines - it should be possible to wait until a specific pattern match to a line. Example:
cmd.wait 'tail -f /var/log/php.log', /something happened/
Ignore errors (no detailed concept now)
Sometimes shell executions could output some errors which should not cause a raise. A regexp pattern could help here.
I like the concept of intuitive wrappers. I've already added test
bash function and I'm open to more. Please do submit PRs if you have working implementation(s). I'm currently taking a leave from OSS until next month - too busy so won't be able to review or work on this.
Hey Sebastian,
I had a closer look at your feature request and I think this will require a bit more work. Fundamentally, there is currently no way to terminate command process directly (only through timeout). I believe this to be a key requirement needing implementation in order to actually stop command and its logging once pattern has been matched etc... Once I have mechanism to arbitrarily kill running command process, I should be able to inject special output processor that will verify messages and if no match is found pass them through to printer for logging; and if match is found kill the command. This is more akin to the wait
implementation of a long running child process. In regard to until
, I believe this would be sligthly different as I would simply have an infinite loop that checks command result and keeps on executing command until it matches output. Is my thinking correct or am I missing some key points here?
@aight8 I have some good news. I had to rewrite how run
method works underneath and expose some api calls. Now it is possible to actually write the requested functionality fairly easily:
begin
cmd.run('tail -f /var/log/php.log') do |out, err|
raise ArgumentError if out =~ /pattern/
# raising inside a command block will exit cleanly, e.i.
# close any pipes and detach the process
end
rescue TTY::Command::ExitError
# we have a match!!!
end
I have also added the above as a wait
api call so you can do:
cmd.wait('tail -f /var/log/php.log', /pattern/)
Please see example.
However, I haven't implemented the until
version as it can easily be handled by infinite calls to wait
:
loop { cmd.wait('cmd to fire', /pattern/) }