zshell, zshell by the zshore
Author: John on February 01, 2016
While working on a feature recently I found myself executing the following command at the command line to get a listing of files I would want to run through cucumber to make sure I didn't break anything with my new change:
fgrep -rl 'I follow "Downloads"' features/*/*.feature
In case that looks foreign to you, let me summarize what I was doing. Hopefully you are familar with the basic use of grep. One could use grep -F as it is the same as fgrep, however I am used to using the fgrep syntax. Following the command, fgrep, we have two flags which we initiate with the dash (-). These flags are r for recursive and l for listing the files that contain what we are looking for. In my example above, I want a listing of all files that contain: I follow "Downloads".
The last part of the command is a location where I want to start searching - features/*/*.feature. Using this path, along with the -r argument to fgrep, we will search for I follow "Downloads" in the features directory and all subdirectories, in files that end in .feature. No sense in searching our step definition files.
The result of running the command fgrep -rl 'I follow "Downloads"' features/*/*.feature is a list of all *.feature files that contain the requested string. But this is only a part of what I need to do. After I have a list of the files, I then needed to type cucumber and then copy and paste all of the found files so that I could run the related tests.
If this were a one time deal, I would have left things alone. But I knew that I would be running these tests again, and probably other tests in a similar fashion. So I had to find a cure for my laziness, err, efficiencies. Enter using our shell, in my case zshell (zsh) to help us automate things. Yes we can create mini programs/scripts using the shell.
Let's review what I was trying to do. I want to search in all *.feature files in my project for a particular cucumber step, I follow "Downloads". I want to collect these files and then run the command cucumber for each file that I have collected. Two words should have stood out to you - 'collect' and 'each'.
We saw earlier how I could use fgrep to find the files that contained my criteria string. So we can re-use that snippet. But we need to use that syntax with a little bit of zshell syntax in order to create an array. Take a look at the code below:
feature_files=("${(f)$(fgrep -rl 'I follow "Downloads"' features/*/*.feature)}")
You can test that the array has elements by using something like this:
echo $feature_files[1] #list one element of the array
-OR-
echo $feature_files #list all of the elements in the array
Ok, we are getting closer. We now have a nice collection of files stored in our array - $feature_files. Now we just need to loop (iterate) over the array of files, excecuting the command cucumber for each file. (Note: I have an alias called cuc which is the same as cucumber - just less typing.) We can use the following zshell syntax (works with other shells as well,) to wrap up our automation task:
for feature in $feature_files; do
cuc $feature
done
Pretty neat, huh? One day I may take this a bit further and create a zshell executable script that can take two arguments - path and search string. But for now, this works just fine.
Learn Something New Everyday
Last Edited by: John on February 01, 2016