Many development projects rely on tools in addition to standard integrated development environments. How these tools are managed can have a significant impact on the maintainability of the project. Problems can occur when different development environments are using different versions of tools, or when tools are assumed available but not present in some environments. This can also be an issue between different branches in the same environment when tools or tool versions change.

It’s unfortunately common for developers to rely on tools being installed in an environment. This makes changing the tool version problematic as the change must be coordinated with all team members. If there is shared build infrastructure then changes may potentially impact multiple projects and can introduce undesirable coupling between otherwise unrelated development efforts.

What is required is a solution that allows projects to maintain their own versions of tools and that provides a mechanism for distributing changes to all environments. In development this solution is source control. Placing tools in the source control repository causes updated versions of tools to be automatically distributed when a new version is pulled from the repository.

Placing tools in the repository solves the problem of distribution, but will not necessarily resolve all the potential issues. In particular if the repository contains a single instance of the tools shared between branches then changes made for one branch may adversely impact other branches. This is obviously undesirable and defeats the point of branching. This is resolved by having the tools be part of each branch, allowing versioning to be conducted for specific branches without affecting others.

This relies on tools that can run from any location without requiring installation. Most development tools I’ve encountered will work in this fashion, but there are exceptions. This should be a factor in tool selection. Where a tool cannot work in this fashion there are in most cases alternatives that can. Over the life of a project the ability to manage tools effectively will generally outweigh the incremental gains from using a tool that cannot be managed in source control. This will of course not always apply, as in some scenarios there are no suitable alternatives. In these scenarios careful management and coordination will be required. Where possible projects relying on such tools should not share development infrastructure so that they are not subject to issues introduced through changes to other projects.

There are some tools that it is reasonable to assume are installed. This is generally true of tools that are part of the platform. For instance it is reasonable to assume that the .NET Framework SDK is installed on a machine used for development tasks. When making such assumptions it is necessary to consider that the available tools can vary between versions of the platform. This is generally not an issue with the .NET Framework which is consistent across OS versions (assuming the full version is installed) but can be an issue for system utilities.

The same kind of versioning issues can apply to libraries referenced by projects. Outside assemblies that form part of the .NET Framework each branch should contain copies of all the assemblies required to build the system. It is desirable but not necessary that this allow the system to run, although it should be possible to execute all the unit tests without having custom software installed.