Resolve virtual module dependencies in same order as non-virtual #3476
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Background
During the addition of RP1 Express (see KSP-CKAN/NetKAN#8701), we observed some unexpected quirks with how dependencies were resolved. We had to restructure the modules in that pull request to fit the peculiar way the relationship resolver works.
I think it's highly likely that the WildBlue play modes (see KSP-CKAN/NetKAN#8275) are also affected by these quirks, but I do not know of a specific example of this.
Non-virtual dependencies
Consider this set of mods:
When the user tries to install A:
Successful installation without unnecessary prompting is good, and this is probably how most people would expect it to work.
Problem
Virtual dependencies
Now suppose B is virtual and provided by two non-virtual modules B1 and B2, which each depend on their own preferred module satisfying C:
When the user tries to install A:
TooManyModsProvideKraken
to tell the UI to make the user choose.TooManyModsProvideKraken
is not thrown for B.TooManyModsProvideKraken
to make the user choose between C1 and C2.Note that the presence of a virtual dependency has caused the dependency tree to be resolved in a different order than in the previous scenario (in step 4). Since the user has been prompted to make an unnecessary choice and the installation ultimately failed, we can regard this as a bad outcome.
This is what happened with RP1 Express. The main module depends on a virtual module representing different levels of graphical detail. Originally, the main module was also supposed to depend on the rest of the core modules needed to install RP1, some of which are virtual and were intended to be overridden by the specific graphics level chosen by the user. However, this resulted in extra contradictory prompts to choose those virtual modules anyway, because the graphics level module was waiting for its turn at the end of the change set. To get it to work, we had to move all of the dependencies into the graphical modules themselves, turning the main module into a very small shell:
While this works, the original structure was preferable for maintenance as it factored out common functionality into the main module rather than duplicating it into three modules.
Semi-virtual dependencies and
any_of
It is possible for this problem to sneak up on us. Suppose that, starting from the first set of relationships above, we later add a new module B2 providing B (
MechJeb2-dev
andCustomBarnKit-RO
both do this):Now even though B itself is not virtual and was never intended to be virtual, the dependency of A on B is treated as virtual, and so B and/or B2's dependencies will be resolved after C, again resulting in potential unexpected conflicts.
The
any_of
property also works by throwingTooManyModsProvideKraken
and submission of updated change sets, so it has the same problem, again for modules that were never planned to be virtual in themselves.Changes
Now if we find that a dependency is resolved by a module already in the change set, we resolve that module's dependencies immediately rather than making it wait its turn. This makes the change set containing A and B1 automatically pull in C1 without prompting the user, as desired.
Incidental build stuff
Mono seems to have enabled HTTP to HTTPS redirection for their APT repo recently. Unfortunately their Docker images for Mono 6.6 and earlier don't haveapt-transport-https
installed and so they fail onapt-get update
. Now we install that package so these images will work.These changes were cherry-picked in 83f54bf.