By now, most developers (and computer users in general) know the mantra “Save Early, Save Often”. During a heavy storm a week or two ago, I was reminded of the importance of this, and its implications for software development. However, in addition to never having a file go unsaved during catastrophic failure (such as the power outage which trashed our designer’s latest Photoshop work), the concept of save early, save often can be applied in several other areas of the software process, and often with beneficial results.
I feel like I’m probably beating a dead horse with this, but the first area would be version control. If you haven’t read some of my earlier blog posts, I’ve recently been gaining a fairly large chip on my shoulder about version control misuse. Our policy at work is that nothing gets committed until it’s tested in Dev, and pushed live in Production, at which point it gets committed to the trunk in CVS (making the version control system effectively always representing the latest stable build). However, I constantly have several small maintenance or feature-development projects running at the same time, and many of them add different changes to Java classes, configuration files, and the like.
As such, I’ve taken to using a local Mercurial repository to track my own changes, so I can hunt them down later and revert the files I need, and delete or revert files that aren’t relevant to my current build. Before this, I used to feel insecure about deleting a file from my working copy of the code, because I’d have no way to revert it without copying it out to some other directory (and documenting where I put that durned directory in Trello); now, I have my own version control that’s kept up to date on my computer. I can switch between versions whenever I want, commit when I have a personal milestone completed (with documentation!), and revert or update to a branch when I need to switch between projects. It’s not the best solution, since merging incoming changes from the CVS trunk that everyone else uses is a bit nasty, but it works. Instead of just saving individual files often, I’ve gone to saving entire versions often.
The concept of Save Early, Save Often can be applied to project management and requirements as well; quick, atomic changes to both project management and requirements/design specification are necessary, and should have some means of tracking who did what, and when.
For tracking my own progress at work, I use a combination of pen-and-paper, Trello, and our in-house issue tracker. Each of these methods has their own specific uses: pen-and-paper for quick ideas and progress reports (for our twice-weekly meetings), Trello for kanban-style task breakdowns, and our issue tracker for ongoing status notes. The benefits of all of these methods are that they are accessible from multiple locations (except for pen-and-paper, which doesn’t need this requirement), they’re instantaneous, and they don’t require you to take any special actions to commit them to persistent storage (except for perhaps the issue tracker, in which you have to submit what are referred to as Progress Notes).
On an old project’s requirements document, which was being passed around by me and a bunch of fellow college classmates, I decided to use Word’s Review tools, enabling change tracking in the document, and annotating by using comments where necessary. The net result was that we could demonstrate to our project manager (the professor) when and where changes were being made to our requirements, in each week’s Scrum meetings, and combine those with the Trac tickets we’ve worked on and the SVN-backed histories of our code changes to illustrate the progress that each team member had made. However, this got tiring after a while of passing a Word document around, and we instead switched to using Google Docs for collaborative work, and MediaWiki for customer-facing instructions and individual design documentation; both of these contained revision histories and diff logs of each author’s contribution.
Code Stability and Testing
Another one I’m working on right now at work is the ability to simplify the code-and-fix cycle of building and testing new changes. The deployment process we use at work right now involves a ton of different steps, and many of them are liable for interruption.
Before deploying, we have to synchronize any modified projects against the stable trunk of CVS to ensure that we are pushing the latest stable version plus our own changes. Then, we have to rebuild any JARs which are modified, make timestamped backups of any modified files via FTP client, and copy out any modified or new files via FTP, before bouncing the two production servers via SSH. It gets worse; in two of our projects, we don’t even have build scripts for JARs; we have to ensure the entire project builds cleanly via the IDE, then manually copy out the class files via FTP to the server. This is made even better by the fact that any errors in compiling the entire project cause absolutely zero class files to be generated, and our IDE error/warning log has about 15,000 warnings clogging it up due to pre-generics Java code and use of deprecated Struts classes.
Rant aside, it’s a pain in the butt, and a constant source of frustration for me and many other employees. I’ve been working on putting together repeatable unit tests and a framework that can do Web testing as well as behind-the-scenes database setup, so the code-and-fix cycle becomes a little more robust; in addition, along with another coworker, I’ve been looking for ways to automate the deployment process a bit more so that there aren’t as many steps involved to get from changes to a functioning build. One of these is to run sites locally; the aforementioned coworker has already gotten this working for some sites, but it’s not yet scalable. We’re also working on automating backups, and eventually, I want to look into a full Continuous Integration suite.
The benefit of all of this is that it minimizes the time and risk between coding and testing, which means that we can Test Early, and Test Often, which is the next logical step from Save Early, Save Often, as applied to software.
(Header image stolen from keep-calm-o-matic)