A few months back, we coined an idea we call “dependency drift” — a metric for tracking the recency of your software dependency packages. Now we’re releasing the algorithm we use to calculate this drift, which we’re calling a Drift Score.
The dependency drift concept is a way for us to track how far out of date our projects are: Are we keeping up with patch releases, security updates, and the feature improvements that come with the endless version bumps inherent in open source? If you simply do nothing, your software will drift out of date over time. Leaping over major version is much more work than incrementally upgrading consistently.
Our proposal was well received by the community. Our humble blog post received a crush of traffic from Hacker News and other communities. We’ve been hard at work putting that metric into practice. Our calculation is simple — some basic arithmetic at its core. Here’s how it works.
To calculate a Drift Score for a given package, we find all the releases of that package between the version you have specified and today. We find these by querying the relevant package management repository such as RubyGems or NPM. Then we sequentially subtract the difference between each of the package versions using math like so:
Split the version string into an array of numbers:
"0.17.3" => [0,17,3] "0.17.2" => [0,17,2]
Subtract each segment:
[0,17,3] - [0,17,2] = [0,0,1]
Next, we find the index of the first non-zero element of the array. In the example above, this would be 2.
Finally, we return a drift score of 10 raised to power of -1 times the index. Let’s show that in Ruby code:
(10 ** (-1 * index)).to_f || 0
The net effect is that for a major package version difference, a 1.0 Drift Score is retuned. For a minor version release, the Drift Score is 0.1. For a patch level, the Drift Score is 0.01.
To calculate an entire project’s score, we add up the scores of every package they depend on. That includes direct dependencies: packages you add specifically. But it also includes indirect dependencies which are packages included by the packages you include.
Example Drift Score
Let’s say you are running version 2.4.5 of a given package and three newer versions are available. Here’s how the Drift Score plays out while calculating the total difference.
2.4.5 is your version 2.4.5 to 2.4.6 is a 0.01 difference 2.4.6 to 2.5.0 is a 0.1 difference 2.5.0 to 3.0.0 is a 1.0 difference
The difference between each release gets summed up and your total Drift Score for that package 1.11. Then all the Drift Scores of all the packages in your project are summed and that’s your total project Drift Score.
For the past several months, we’ve been running Drift Scores daily on all of our projects and our consulting clients’ projects. We call our app DriftWatch and we’re using it ourselves already. Since some of our consulting work involves getting (and keeping) large Rails projects up to date, we’ve been on our own DriftWatch alpha testers. It’s been incredibly valuable to be able to produce regular charts and graphs for our client’s showing how far out of date they were, and how far they’ve come with a little investment.
What do you think of our Drift Score calculation? The math is basic but the data gleaned from this simple metric has numerous uses. Do you have a use for DriftWatch? Sign up to receive future updates and beta test!
If you have comments or questions about DriftWatch, email us! We want to hear from you.