Skip to content

Commit bff241c

Browse files
committed
melting-pot: improve leading documentation
We give a real-world example now, rather than a contrived foo/bar one. And we link to a helpful "diamond dependency" explanation.
1 parent 65f99cb commit bff241c

1 file changed

Lines changed: 28 additions & 35 deletions

File tree

melting-pot.sh

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,50 +5,43 @@
55
# ============================================================================
66
# Tests all components of a project affected by changes in its dependencies.
77
#
8-
# First, an anecdote illustrating the problem this script solves:
8+
# In particular, this script detects problems caused by diamond dependency
9+
# structures:
910
#
10-
# Suppose you have a large application, org:app:1.0.0, with many dependencies:
11-
# org:foo:1.2.3, org:bar:3.4.5, and many others.
11+
# https://jlbp.dev/what-is-a-diamond-dependency-conflict
1212
#
13-
# Now suppose you make some changes to foo, and want to know whether deploying
14-
# them (i.e., releasing a new foo and updating app to depend on that release)
15-
# will break the app. So you manually update your local copy of app to depend
16-
# on org:foo:1.3.0-SNAPSHOT, and run the build (including tests, of course).
13+
# This "melting pot" build rebuilds every dependency of a project, but at
14+
# unified dependency versions matching those of the toplevel project.
1715
#
18-
# The build passes, but this alone is insufficient: org:bar:3.4.5 also depends
19-
# on org:foo:1.2.3, so you manually update bar to use org:foo:1.3.0-SNAPSHOT,
20-
# then build bar to verify that it also is not broken by the update.
16+
# For example, net.imagej:imagej:2.5.0 depends on many components including
17+
# org.scijava:scijava-common:2.88.1 and net.imagej:imagej-ops:0.46.1,
18+
# both of which depend on org.scijava:parsington. But:
2119
#
22-
# This process quickly becomes very tedious when there are dozens of
23-
# components of app which all depend on foo.
20+
# - org.scijava:scijava-common:2.88.1 depends on org.scijava:parsington:3.0.0
21+
# - net.imagej:imagej-ops:0.46.1 depends on org.scijava:parsington:2.0.0
2422
#
25-
# And more importantly, testing each component individually in this manner is
26-
# still insufficient to determine whether all of them will truly work together
27-
# at runtime, where only a single version of each component is deployed.
23+
# ImageJ2 can only depend on one of these versions at runtime. The newer one,
24+
# ideally. SciJava projects use the pom-scijava parent POM as a Bill of
25+
# Materials (BOM) to declare these winning versions, which works great...
26+
# EXCEPT for when newer versions break backwards compatibility, as happened
27+
# here: it's a SemVer-versioned project at different major version numbers.
2828
#
29-
# For example: suppose org:bar:3.4.5 depends on org:lib:8.0.0, while
30-
# org:foo:1.2.3 depends on org:lib:7.0.0. The relevant facts are:
29+
# Enter this melting-pot script. It rebuilds each project dependency from
30+
# source and runs the unit tests, but with all dependency versions pinned to
31+
# match those of the toplevel project.
3132
#
32-
# * Your new foo (org:foo:1.3.0-SNAPSHOT) builds against lib 7, and portions
33-
# of it rely on lib-7-specific API.
33+
# So in the example above, this script:
3434
#
35-
# * The bar component pinned to foo 1.3.0-SNAPSHOT builds against lib 8; it
36-
# compiles with passing tests because bar only invokes portions of the foo
37-
# API which do not require lib-7-specific API.
35+
# 1. gathers the dependencies of net.imagej:imagej:2.5.0;
36+
# 2. clones each dependency from SCM at the correct release tag;
37+
# 3. rebuilds each dependency, but with dependency versions overridden to
38+
# those of net.imagej:imagej:2.5.0 rather than those originally used for
39+
# that dependency at that release.
3840
#
39-
# In this scenario, it is lib 8 that is actually deployed at runtime with the
40-
# app, so parts of foo will be broken, even though both foo and bar build with
41-
# passing tests individually.
42-
#
43-
# This "melting pot" build seeks to overcome many of these issues by unifying
44-
# all components of the app into a single multi-module build, with all
45-
# versions uniformly pinned to the ones that will actually be deployed at
46-
# runtime.
47-
#
48-
# This goal is achieved by synthesizing a multi-module build including all
49-
# affected components (or optionally, all components period) of the specific
50-
# project, and then executing a Maven build with uniformly overridden versions
51-
# of all components to the ones resolved for the project itself.
41+
# So e.g. in the above scenario, net.imagej:imagej-ops:0.46.1 will be rebuilt
42+
# against org.scijava:parsington:3.0.0, and we will discover whether any of
43+
# parsington's breaking API changes from 2.0.0 to 3.0.0 actually impact the
44+
# compilation or (tested) runtime behavior of imagej-ops.
5245
#
5346
# IMPORTANT IMPLEMENTATION DETAIL! The override works by setting a version
5447
# property for each component of the form "artifactId.version"; it is assumed

0 commit comments

Comments
 (0)