You keep talking about hard dependencies. Are there any soft dependencies?

In the last few posts I’ve discussed the hard dependencies you want to eliminate from your build scripts - things like absolute paths and databases. It’s quite natural to ask why I used the term “hard dependencies”, and what a “soft” dependency would look like. Soft dependencies are basically any thing that you can get from your VCS or that is setup automatically when you create a new development or build machine. Let’s look at some examples.

Relative paths

In the post on absolute paths I mentioned the value of relative paths. These are typically a soft dependency because they point to either 1) code or other files that were retrieved from the VCS or 2) build tools or other programs initialized with a dev environment setup script.

Source code and files from other repositories

Besides the paths themselves, the files you get from other repositories or from other locations in the same repository are soft dependencies. You obviously need them for your build scripts to work, but you basically get them for free. If the source and other files in question come from a different repository in your VCS, you should use a tool like svn:externals or hg subrepos to make sure that code is available on your machine before building.

Any hard dependency for which there is a robust fallback behavior

For all of the hard dependencies mentioned here, you can change them to be soft dependencies by having a robust fallback behavior. This means that if the dependency is not available for whatever reason, the build script can continue unaltered and still succeed using an alternative method for building the code that is equally valid. Of course, if that is the case, you should probably eliminate the hard dependency altogether. This stage can be an important step on the way from having lots of hard dependencies in your scripts to few or none.

Hard dependencies that are setup automatically with a dev machine setup script

Dev machine setup scripts are not ideal (for more on the ideal, keep reading), but they can be very useful when you’ve got some tough hard dependencies for which it really doesn’t make business sense to use one of the methods already listed for turning it into a soft dependency. By using a script to setup these hard dependencies automatically for dev machines, you make it much easier for new developers (and experienced devs on new machines) to get up and coding quickly. Your build scripts now have an implied dependency (i.e. that the machine setup script has been run), but that one dependency can cover a whole range of issues.

Ideal build system

The ideal build system will have no hard dependencies. So what will it look like? Well, you’ll still need to get the code onto your dev machine, but you won’t need a dev machine setup script. So basically, you’ll just:

  1. Install the VCS client
  2. Checkout your code
  3. Run the build script

This ideal build system will not require you to install any development tools. They’ll be available at relative paths inside the repository you checked out (or a common build tools repository included via svn:externals or hg subrepositories). You wont’ have to worry about the current state of the operating system, setting up registry keys, creating databases, or anything else.

One step back from this would be to replace step one with “Run the dev machine setup script”. This script would install the VCS client, take care of any other hard dependencies and get you ready to go.