Print
Contributing

We appreciate your interest in contributing to the Dentaku Project. Time is the most valuable thing that any of us have (whether or not we always realize it), and we believe the goal of any open source project is to enable doing the most with as little time as possible. There are dozens of reasons to contribute to an open source project, but we believe that they always revolve around time, and hope that the following always holds true:

  • That your investment in this project can save others time. Whether this is fixing a problem that you have already solved and others may not have yet noticed, squeezing out builds 10% faster than they happened before, or adding a completely new perspective and process to doing a common task.
  • That our procedures of accepting your changes can save you time. One of the most difficult aspects of Open Source development is change management. Our goal is not just to open our doors to your contribution, but show you our appreciation for your efforts by trying to make your contributions as painless (i.e. fast) and rewarding as possible.

With an eye toward these goals, we aim for Dentaku development aims to be entirely driven by tests. This is commonly known as TDD. When someone develops code using TDD, they write clean code. Dan North of Thoughtworks makes the point well in an article at JDJ:

Writing the test before you write the code focuses the mind - and the development process - on delivering only what is absolutely necessary. In the large, this means that the system you develop does exactly what it needs to do and no more. This in turn means that it is easy to modify to make it do more things in the future as they are driven out by more tests.

This focus to task will be something that we will be very thankful for as the project evolves, if only to get a few more years out of it before, like most projects, it collapses under it's own weight.

Another focus of TDD in Dentaku is about the longevity of your contribution. A contribution made without tests is a contribution that is waiting to be misunderstood and maligned into a task that it was not designed for and cannot handle. Because of the limitless number of reasons and goals involved with any addition or change, it is virtually impossible to ensure that other developers will fully understand why the change that you added is there. Nor can any amount of documentation rectify this situation; too much documentation will not be read and too little does not explain the problem well enough.

Enter TDD. While exhaustive documentation relies on a programmer reading and understanding the documents before making changes, TDD and test suites simply require that they pass an automated test that is a part of the build. By contributing a test that exercises your code in the way that you use the code, you can ensure that your code will not be broken without the test being changed. This is powerful insurance that will save time for you – issues regarding features you rely on being broken are eliminated.

Another way that TDD will save you time and energy is the speed with which you can contribute new changes. Typical Open Source projects are maintained by volunteers who usually have day jobs. We really do try hard to attend to our chores, but some of the patches really are hard to determine whether they are going to create more problems than they are going to fix. Certainly, no developer with enough sense to fix a bug is going to intentionally create new ones, but what about the unintentional side-effects? As a developer with repository access, is there a way for me to know whether this patch will break other things? If it does, will I have time during this week to fix them?

Sometimes, these questions result in patches not being applied for so long that they become stale. Not only is the time of the contributor wasted, but it's not likely that person will be back to contribute any time soon.

Write the test first!

Let's consider an alternate reality, one where the contributor writes (or modifies) the applicable test(s) first. Because the test does not affect the mainline code base, adding the test to the tree can be done without any question, right away. "Patch sponsors" (developers with repository access and a willingness for the cause of the patch or person) will have time to review the expectations of the test changes, and update the test if there are any conflicts or misfeatures that might be created by following through with writing code for that test. Once the patch sponsor and the contributor agree that the test covers the expectations of both parties, the working patch is contributed. The patch sponsor simply applies the patch, looks for any tests that have failed as a result, and if none are found, commits the changes!

While this sounds like more work, it actually is less. When bad patches make it into the source tree, the build can be broken for days, or worse, subtle bugs are introduced to the code that can linger for months or years. The latter are very difficult to track, and sometimes even difficult to keep from being re-introduced. This can't happen when a test is written to expose a bug after it is found. By checking in the test that exposes that bug, not only is a satisfactory solution ensured, but any reappearance of the bug will immediately be caught. One could consider this as "semantic enforcement" for the code.

Are you convinced yet?

Missing Facilities

As we add tests to the build that are propositional in nature, the build is going to generate quite a bit more noise. Two solutions to this are possible:

  1. Keep a fork open for patches. This fork would be merged on a (weekly?) basis so as to minimize merge conflicts.
  1. Instrument JUnit such that it understood the propositional nature of some tests. Since we are using Subversion, which has a monotonically incrementing revision number, it would be practical for a test to set something akin to a "since revision" number that did not flag a test in error unless the current revision was greater than this number. This metadata would have additional benefits if it included information about the JIRA issue that prompted it's inclusion, helping systems like Maven to give more historical information about build issues.
Powered by Atlassian Confluence