Use current metadata for installed module compatibility #2886
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.
Problem
If a module's compatibility metadata changes after you install it, the GUI filters will always reflect the compatibility at time of install. For example, AblativeAirbrakes 0.3.0 only supported KSP 1.3.1 in March 2018, but now supports 1.2.2–1.7.3. If you installed it back then and kept it installed to the present, it would only be counted as compatible in GUI if you have 1.3.1 marked as compatible, but if you uninstall and/or reinstall, it will be considered compatible with all of 1.2.2–1.7.3.
Cause
GUIMod
has multiple layered constructors; at the bottom level you can create aGUIMod
if you only know the identifier, above that you can create aGUIMod
from aCkanModule
, and at the top you can create aGUIMod
using anInstalledModule
. Each layer calls the level below it and then fills in extra info; theInstalledModule
layer passes its source module (metadata from time of install), and theCkanModule
layer passes its identifier.The handling of compatibility in this hierarchy had some flaws. By default, everything was assumed to be compatible, which could be overridden by a constructor parameter or based on the
CkanModule
parameter's compatibility info. In the case of anInstalledModule
, this meant that an incompatible source module would mark the overall module as incompatible, even if its current available module had subsequently been updated in CKAN-meta to be compatible.Changes
Now the
incompatible
constructor parameters are nullable andnull
by default. If set to true or false, we use that value. If not passed in (i.e., stillnull
by the time we get to the identifier level), then we use the identifier to look up the compatibility from the registry based on the current metadata for all versions of the module.To avoid paying the cost of this computation for compatible modules,
MainModList
now passesincompatible
=false
for known-compatible modules. This saves a few operations per compatible module. This function was already passingtrue
for incompatible modules, and it will leave the parameternull
for installed modules to force a check of the current metadata.The
CkanModule
-levelGUIMod
constructor no longer checks compatibility because it was not strictly correct and is now redundant. The identifier-level constructor that it calls will set the correct value before theCkanModule
-level constructor runs.Several functions are changed to return
IEnumerable
instead ofList
for possible performance improvements when a search stops early (e.g., if the new.All
call finds a false value early on, the rest of the list does not need to be generated).Fixes #2883.