The Refactotum Project has two objectives:
- Show developers how to contribute to open source projects.
- Encourage healthy code through refactoring
To perform a refactotum exercise, you need to set aside four hours, and perform the following steps:
- Select an open source project.
- Download the project and run the tests.
- Find a bite-sized problem to solve.
- Spec out and implement your solution.
- Create and submit a patch.
The four-hour timebox is very important. The number one enemy of contributing to open source is inertia. (You are fighting that battle by reading this.) The number two enemy is overambition. Start small.
Selecting an open source project
Start by selecting an open source project. You do not necessarily have to know much about the project, but you do need to know the programming language the code is written in! We will give examples written in Ruby, but the ideas are general and can be used with any language.
Here are some Ruby projects that are easy to get started with:
Download the project and run the tests
The next step is to download the project and run the tests. Most projects will give you at least three different options:
- Download a compressed dump of the project source
- Anonymous source control checkout (no commit access)
- Developer source control (commit access)
You will want the anonymous source control checkout. Having a source control checkout should guarantee that you are working on the latest, greatest code. Since you are contributing to this project for the first time, commit access is not an option. (You have to earn that.)
To get the repository
- For a Rubyforge project: Go to the project homepage, and then click on the "SCM" menu for instructions.
- For a github project: Go to the project homepage, and copy the "Clone URL" link. Then execute
git clone {clone url}
Many Rails applications rely on implicit loading of gems, so you may find that you don't have all the gems you need to run the tests. If you see a message of the form
no such file to load -- foo
your best bet is to gem install foo
.
Find a bite-sized problem to solve
Pick something small and simple. You'll be amazed at how quickly a small change grows into something more ambitious. Here are some easy ways to brainstorm ideas for a Rails application.
- Take advantage of being a beginner. If you had any trouble getting the project tests to run, others will too. Solve this problem first. This can often be as simple as a README change. Patches that help new developers get started are especially welcome. Project maintainers are blind to these issues, because they have internalized important bits of HOWTO knowledge that are not documented anywhere.
- Fix any tests that are failing.
- If the project publishes a TODO list, see if there are any small tasks that you can do quickly.
- Run rcov on the test suite. Pick a single method that is missing code coverage. Write a test that provides coverage (and fix any defects you encounter). If the application does not include an rcov rake task, contribute one.
- Run flog on the application. Review the methods with a flog score higher than 80, and find one that can be refactored for simplicity. (You probably want to avoid methods with a flog score higher than 150, as these will likely blow out the four hour timebox.
- Run tarantula on the application. Add tests for any inputs that Tarantula generates that cause HTTP 500 errors, and then fix the errors.
- Review the code in application_helper.rb. This is often a hiding place for code that needs refactoring.
- Scan the log for warning messages, and fix them.
- Look for logic in the view templates, and extract it into helpers.
- Look for controller methods that do model work, and extract into models.
Spec and implement your solution
Write specs, or tests, that demonstrate the code you plan to write. Then write the code to pass the tests. Look at the other tests in the project and follow their lead.
Create and submit a patch
Most open source projects welcome well-organized patches. (If they don't, fork 'em.) Make sure you make it easy for a busy maintainer to understand your patch.
- Include complete test coverage for your changes. (Use rcov to make sure.)
- Make sure all the other tests still pass.
- Give your patch a descriptive name. Describe what it does and why.
- Assign your patch an accurate severity and priority.
Most importantly, read the project instructions for contributors, and follow them. Here are a few examples:
Pitfalls
There are several ways to stumble during your first open source contribution. Keep an eye out for these warning signs:
- Do not shave yaks. If your small change triggers big ideas, don't chase them down (yet). For example: maybe you are not git-taculous yet. If not, then pick an svn-based project for your first refactotum. Git is way cool, and you should learn about it, but not while trying to do something else.
- Do not be opinionated. When you are in someone else's project, code to their idioms. You can be opinionated later, once your contributions have earned credibility. Maybe you love rspec. But if the project prefers Test::Unit tests, then so do you. Once you have contributed a few patches, they are a lot more likely to entertain your suggestion of moving to rspec.
- Do not introduce library dependencies. To make your patch acceptable, you want to minimize the potential objections. Requiring a new library can be a big-impact change. Deployment may change, users may need to review the license, etc. If you are working on a refactotum where the obvious solution drags in a new library, pick something else. The time to propose a new library is after the initial success.
Let us know how it goes. Happy refactoring!