Warnings and errors whenever overriding subproject junction configurations
Summary
When junctioning in a subproject, we want to have absolute certainty that the for a given ref and combination of project options of the subproject, we will be using exactly the same artifacts as we would get if we had built that subproject directly.
However, with even slightly complicated inter-project dependency graphs, we have situations where we override a subproject's junction configuration to a common sub-project dependency - and we do this without triggering any warnings or errors.
While it is impossible to automatically keep all project junction points in sync, overwriting the junction configuration without the user explicitly asking, and without any feedback, is a very bad thing and will result in users building things which they did not expect, without knowing why.
Background
It was pointed out in this discussion recently that when junctioned subprojects share common dependency subprojects, there is opportunity to have projects which are out of sync, and even more concerning is that the only current solution to synchronize these subprojects results in the subproject's references to their subprojects being overwritten by the highest level project, instead of being derived from subprojects.
The problem arises when you have a dependency on two subprojects, and one day one of your subprojects starts to have a dependency on the other subproject:
(A)
/ \
/ \
(B)---->(C)
Part of the solution will be to allow the topmost project to derive it's declaration of one subproject from another, such that in the above example; project (A) will use the junction ref and configuration from project (B) in order to access project (C), this will be implemented in !1293 (merged).
However, this solution alone is not sufficient to ensure parity across more complex inter-project dependency pattern.
For instance, consider a project dependency graph with a diamond pattern:
(A)
/ | \
/ | \
(B) | (C)
\ | /
\ | /
(D)
In the above case, project (A) absolutely must declare a junction to (D) in order to reconcile the common references to (D) from projects (B) and (C).
-
Currently the (A)->(D) junction declaration will override both of the (B)->(D) and (C)->(D) junction declarations, causing projects (B) and (C) to no longer be configured exactly how they were advertized.
-
After !1293 (merged), project (A) can choose to derive the common junction configuration to (D) from either (B) or (C), but there will still remain a case where we silently overwrite the configuration of the other, unchosen junction.
Task description
-
Configurable warning when a project overrides a subproject junction configuration with one that does not match. If configured to be fatal, it is only fatal if the calling project overrides a subproject.
After !1293 (merged) is implemented, considering the examples shown above; even if the higher level project (A) is inheriting it's (A)->(D) junction configuration from (B), it is still considered to be fatal that the (C)->(D) junction gets overridden by (A)'s derivation of (B)'s junction.
This implies that we must have an algorithm which actually compares junction configurations, i.e. if the junction configurations (B)->(D) and (C)->(D) are a match, then it is not a warning or an error at all.
-
Ability to whitelist which junctions are allowed to be overridden, disabling the warning/error completely. Similar to file overlap whitelists, we should have a way for the project author of (A) be allowed to explicitly whitelist a subproject junction which it allows to be overwritten.
Considering the above diamond example, this would mean that after !1293 (merged) is implemented, one could decide that:
- Project (A) derives it's (A)->(D) junction from project (B)
- Project (A) explicitly overwrites the (C)->(D) junction with whatever configuration it happens to have derived from (B)