I recently came across this problem with the
~/.gemrc file used by the
gem command since I needed to store a
a private token for accessing a GemFury gem source. I struggled to figure
out a way to keep the file in my dotfiles without exposing myself to the possibility that I would publish them. Finally,
at the end of my rope I reached out to my colleagues with this problem and within minutes
Adam Strickland responded with a great approach that was not-obvious but ends up
being a great way to provide configuration outside of the committed
~/.gemrc file. A true hidden gem.
–do you see what I did there?
GEMRC: the environment variable
It turns out that you can specify another place for the
gem command to look for configuration. If you define
in your shell to point to a file, it will shallow-merge the configuration in
~/.gemrc with that file. The shallow
merge behavior is important - what I mean by that is any configuration key found in both places will be completely
overwritten by the value in the file
GEMRC points to. More-concretely, if you define sources in both places you don’t
end up with the union of all sources, you end up with whatever sources are defined in the
Armed with that knowledge, I added this snippet to my shell initialization scripts:
I manually moved all the sources, including the sources containing auth, to that file. Then I removed the sensitive
sources from my tracked
~/.gemrc file, and boom I have my credentials working, but I also have a tracked file for
How it works
I wanted to dig just a bit deeper in order to understand how this worked, because I found it -extremely- difficult to find any reference to it across the internet. Trying to google GEMRC lands you with explanations of the “standard” home directory file and not much else. There was a stack overflow post that I finally dug up, and it DOES appear in the docs if you dig a fair amount. For me the best explanation of how it works is in the source where you can see that it can be a colon or semicolon-separated list of files. It seems like an opportunity for a documentation improvement - perhaps in the RubyGems website FAQ.
You can define an environment variable
GEMRC that points to a file that gets loaded in addition to system config or
user (home directory) config, and it will be loaded/merged after those other configs - totally useful for hiding sources
containing credentials if you commit your dotfiles to a public repository.
That’s it! Cheers!