Flatito: Grep for YAML and JSON files
I’m happy to present Flatito, a tool I’ve worked on for the last few days.
It is a grep for YAML and (incidentally) JSON files. It allows you to search for a key and get the value and the line number where it is located. It is handy when you have a big YAML with several nested levels, for example, on the typical I18n Rails files.
You can find it on Github and install it
with gem install flatito
. It is a very simple tool, but I hope it can be helpful for someone else.
How it looks like
$ flatito
Usage: flatito PATH [options]
Example: flatito . -k hello
-h, --help Prints this help
-V, --version Show version
-k, --search-key=SEARCH Search string
--no-color Disable color output
-e, --extensions=EXTENSIONS File extensions to search, separated by comma, default: (json,yaml,yaml)
--no-skipping Do not skip hidden files
Let’s see an example of a search over the Rails repository:
$ flatito rails/ -k dev_server rails/railties/test/isolation/assets/config/webpacker.yml 24: development.dev_server.https => false 25: development.dev_server.host => localhost 26: development.dev_server.port => 3035 27: development.dev_server.public => localhost:3035 29: development.dev_server.hmr => false 31: development.dev_server.overlay => true 33: development.dev_server.compress => true 35: development.dev_server.disable_host_check => true 37: development.dev_server.use_local_ip => false 40: development.dev_server.quiet => false 41: development.dev_server.pretty => true 43: development.dev_server.headers.Access-Control-Allow-Origin => * 45: development.dev_server.watch_options.ignored => **/node_modules/** rails/actiontext/test/dummy/config/webpacker.yml 60: development.dev_server.https => false 61: development.dev_server.host => localhost 62: development.dev_server.port => 3035 63: development.dev_server.public => localhost:3035 64: development.dev_server.hmr => false 66: development.dev_server.inline => true 67: development.dev_server.overlay => true 68: development.dev_server.compress => true 69: development.dev_server.disable_host_check => true 70: development.dev_server.use_local_ip => false 71: development.dev_server.quiet => false 73: development.dev_server.headers.Access-Control-Allow-Origin => * 75: development.dev_server.watch_options.ignored => **/node_modules/** rails/activestorage/test/dummy/config/webpacker.yml 40: development.dev_server.https => false 41: development.dev_server.host => localhost 42: development.dev_server.port => 3035 43: development.dev_server.public => localhost:3035 44: development.dev_server.hmr => false 46: development.dev_server.inline => true 47: development.dev_server.overlay => true 48: development.dev_server.compress => true 49: development.dev_server.disable_host_check => true 50: development.dev_server.use_local_ip => false 51: development.dev_server.quiet => false 53: development.dev_server.headers.Access-Control-Allow-Origin => * 55: development.dev_server.watch_options.ignored => /node_modules/ rails/actionmailbox/test/dummy/config/webpacker.yml 33: development.dev_server.https => false 34: development.dev_server.host => localhost 35: development.dev_server.port => 3035 36: development.dev_server.public => localhost:3035 37: development.dev_server.hmr => false 39: development.dev_server.inline => true 40: development.dev_server.overlay => true 41: development.dev_server.compress => true 42: development.dev_server.disable_host_check => true 43: development.dev_server.use_local_ip => false 44: development.dev_server.quiet => false 46: development.dev_server.headers.Access-Control-Allow-Origin => * 48: development.dev_server.watch_options.ignored => /node_modules/
How it works
Flatito is written in Ruby and uses the psych
gem to parse YAML files. Initially, it was only for YAML files, but then I realized that it also works for JSON files, so I added support for them.
The big challenge was to get the keys with the line number where they are located. Psych does most of the work, but the documentation could be more explicit about how can I use it to get a different output. Luckily, there is a StackOverflow thread about a similar issue. This specific answer from John Carney was very helpful, and I used it as a base to build the tool with a few modifications to get exactly what I needed.