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.