Software Engineering at Google Chapter #21 - Dependency Management
(3 of 3)
The bundle everything model...
Uses "distributions" (think Ubuntu or RedHat Linux)
In essence the distribution's maintainer gathers up all
necessary software, draws a box around it, then releases as a
single package or distribution
Another example of this model is selling source code and
including it's dependencies in the distribution (vs the customer
pulling down dependencies from external sources)
It's up to the distributor to bundle, test, and integrate all
components of each distribution's release
Version selection is handled by the distributor
The live at head model...
Used by Google and is "costly but effective" for a single
organization (vs Ubuntu Linux who is a single
distributor but is a collection of packages from other
This method can be viewed as the dependency management extension
of the trunk-based development model
The method attempts to remove time and choice from the equation.
It does not let developers choose a version (a'la SemVer)
Many assumptions are made in this model
This model requires strong CI and extensive testing
One downside to SemVer is that version changes are a guess. There
is not 100% assurance that going from 2.14.5 to 2.16.1 will still
work correctly. It should but there's no way to guarantee
When the SemVer solvers attempt to do their magic they fail by
both overconstraining and under-protecting us
Consider a scenario where a library changes one of its two
interfaces and thus the major version is incremented. If you are
building software that only uses the unchanged interface the
solver will fail due to the major version bump
Another issue with SemVer is one where things change but yet there
is no major version bump. Think of things like data types, logging
output, or delay (increased by 10ms). These changes will clearly
break some things yet it "doesn't count" as a major version change
SemVer also has human issues. What if a project does a major
version bump every 6 months regardless of changes?
Consider that when software says it requires a library of >=
version 2.14 it was probably built by the developer with version
2.14 and it assumes future versions are compatible
In the above scenario one should consider trying 2.14 first even
if 2.15 is available. You can use a newer version but first
try the "known good" version in case a newer version introduces
Scale is what shows the weakness of SemVer
The intent of SemVer is to say "In my estimation this change will
be easy (or not) to adopt"
Given time, all forks become expensive
When creating a dependency (such as open sourcing a library that
your company developed) consider the following...
Portability concerns (in-house toolchains to build it, in-house
flags within the code, etc)
Can user contributions to the open source version be
re-integrated into the in-house version?
How will the in-house version keep in sync with the open source
version and how much engineering effort will that cost?
Create a long-term plan before releasing it
If done incorrectly your organization's reputation will suffer
When imposing a dependency on your organization carefully consider
the ongoing costs
SemVer should be viewed as a lossy estimate of compatibility. CI
and testing provides a more accurate representation of
compatibility (theory vs practice)