Working in Ruby, as with most scripting languages, you’ll find yourself with a bunch of dotfiles littering your project’s root directory. Dotfiles serve their purpose and take care of a lot of configuration and setup. When you’re working alone you create them and never think about them again but when you’re working with a team or on an open source project you end up having to make the difficult decision of what goes into your
.gitignore file. Don’t let this argument play itself out again. It’s pretty clear what should and shouldn’t be checked into version control and every project should have a policy backing that decision.
Right now I’m working on a spec and a proof-of-concept app that follows it. It’s another Ruby app (Ruby, not Rails) that’s open source. I’m in my second iteration of it and this time around I found myself ignoring files I had purposely left checked in the first time. Why are
.ruby-version, and others on ignore list this time around? Because an open source project is not in the business of telling people how to set up their environment. The code you write should be as portable as possible and you shouldn’t need an exact point release of Ruby for a feature to work unless there’s a damn good reason for it. You should be deciding what version range of your language your project will be compatible with, make it clear in the readme, then test against it and let developers develop against any version within your range.
The Dotfiles You Should and Should Not Ignore
These are some common dotfiles you’ll come across and my general policies on ignoring them. Note that this list is very Ruby oriented. Maybe I’ll flesh it out more in the future.
Ignore: .ruby-gemset, .ruby-version, and .rvmrc
These are all files that tell your Ruby version manager, whether that be rbenv or RVM, which gemset and version of Ruby to be using. These files assume everyone getting a copy of your code will be using a version management tool. Not everyone will. Not everyone is a developer or a contributor. As much as we’d like to enforce a version and gemset for our projects the majority of end-users and developers are going to have to modify or get rid of those files anyway. Even if everyone who gets a copy of the code is using RVM or rbenv they may want to deploy on a different version of Ruby. Unless you have a damn good reason, your project should not depend on one and only one very specific Ruby build to work properly. You should be adding these files to your .gignore, making the project’s system requirements clear, and still be confident that most users will have no trouble. For anyone who does have issues the solution isn’t to enforce an environment on them. Instead you decide whether you’re going to support the environment the user reports bugs in and fix your software or point your bug reporter to your readme which clearly states the version ranges the project’s been tested against.
This folder has your Bundler configuration in it. Everyone should be using Bundler to manage the project’s dependencies regardless of their status as a contributor or user but including the configuration is, again, enforcing a certain environment on a user. If I run
bundle install --without production then check in my bundler config that means that everyone using that project from them on will never install production dependencies unless they specifically try (even in production). You want people to be able to mess with the Bundler options in any way they want. It might not be best practice, it might be a waste of space in some cases, and it might even be a bad idea but it’s not our job to tell people what to do. We offer code, make it clear how that code should be set up and run, and leave the rest up to each user. In the end it’s better to have people run a plain
bundle install and have extra gems installed on their system than it is to enforce only a subset of dependencies on them and make them remember to install gems with a certain flag when it comes time to deploy. Your app shouldn’t be breaking just because a few extra gems exist in the same environment.
Track: Gemfile and Gemfile.lock
If you’re working on a Gem you should ignore it otherwise there’s no question that you should be checking both these files into version control.
Other random files
Editorconfig is a cool little dotfile/standard that tells editors how to handle spacing in different files. It’s super useful for enforcing certain coding styles. It’s not a replacement for a formal styleguide but it is a great supplement to it. My view is that this file should be kept as it doesn’t enforce an environment on the end-user. By including the
.editorconfig file in your repository you can help keep contributors’ code nice and clean while introducing some best practices to newer developers. If someone feels strongly enough about code style they can just throw the file out. They’re likely not going to be a contributor anyway. Most people never edit the code they download and only use it. For those people it does end up being one extra unnecessary file. I like to keep a balance between having the files needed for contributors and other developers to easily dive into the code while not having so many that it makes the project look messy for those who just want to deploy the code. In this case this one extra file isn’t going to hurt many people and so I let it slide where I’d normally put it on the ignore list.
Track: README.md, License.txt, Contributing.md
These aren’t really files that have any effect on a project’s functionality but it’s sometimes unclear whether they should be checked into version control. The argument for leaving these out is that end users don’t need to see them. They don’t care. They just want to read the instructions on your website and get your app working. The README file is important. That’s where your setup instructions should be so you have to track it. The license file is also incredibly important. You’d be surprised how many developers won’t touch your code without a license in place. The contributing file should also be left in there so people know the process. It might seem weird to even mention these but what’s at issue here is the tug of war between what a developer wants to see and what an end-user wants to see. Developers want to see all of these files but people who just want to use your code don’t really care. One thing you can do is have a release branch of your repository that cuts out the unnecessary files. For example, if you download Codeigniter from their website you get a pretty bare-bones zip file with only what you need to run the framework. If you clone their Git repository however, you’ll get a whole lot more which still lets you run the framework just the same as downloading the zip file but also sets you up to be a contributor to the project as well.
Ignore: Every IDE file ever
You never ever want an Eclipse settings file or
.sublime-workspace file in your repository. You don’t know what editor someone is using and shouldn’t presume to know. If someone happens to be using the same one as you, you don’t want their personal preferences overwritten by yours. I don’t even know why I’m including this here… it’s just common sense.