mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-20 01:46:13 +00:00
Clarify BepInDependency version errors and docs (#1330)
The chainloader collected both not-installed dependencies and installed-but-incompatible-version dependencies into one list and reported them all as "missing dependencies", which is confusing when the plugin is present but on a version outside the requested range. Separate the two cases and log distinct, actionable messages: one for dependencies that are not installed, and one for dependencies present with an incompatible version (showing the found version and the required range). Also expand the BepInDependency(string, string) xmldoc: the version is a SemVer range, link the range syntax, and warn about the BepInEx 5 -> 6 behaviour change (a bare version was a minimum, now it is exact). Fixes #779
This commit is contained in:
1 parent
f8ba0a41af
commit
77d438cf69
2 files changed
+41
-11
No files matched your search
@@ -344,6 +344,7 @@ public abstract class BaseChainloader<TPlugin>
|
||||
{
|
||||
var dependsOnInvalidPlugin = false;
|
||||
var missingDependencies = new List<BepInDependency>();
|
||||
var incompatibleDependencies = new List<KeyValuePair<BepInDependency, string>>();
|
||||
foreach (var dependency in plugin.Dependencies)
|
||||
{
|
||||
static bool IsHardDependency(BepInDependency dep) =>
|
||||
@@ -359,15 +360,22 @@ public abstract class BaseChainloader<TPlugin>
|
||||
pluginVersion = pluginInfo?.Metadata.Version;
|
||||
}
|
||||
|
||||
if (!dependencyExists || dependency.VersionRange != null &&
|
||||
!dependency.VersionRange.IsSatisfied(pluginVersion))
|
||||
// The dependency is not installed at all.
|
||||
if (!dependencyExists)
|
||||
{
|
||||
// If the dependency is hard, collect it into a list to show
|
||||
if (IsHardDependency(dependency))
|
||||
missingDependencies.Add(dependency);
|
||||
continue;
|
||||
}
|
||||
|
||||
// The dependency is installed, but its version does not satisfy the requested range.
|
||||
if (dependency.VersionRange != null && !dependency.VersionRange.IsSatisfied(pluginVersion))
|
||||
{
|
||||
if (IsHardDependency(dependency))
|
||||
incompatibleDependencies.Add(new KeyValuePair<BepInDependency, string>(dependency, pluginVersion?.ToString()));
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the dependency is a hard and is invalid (e.g. has missing dependencies), report that to the user
|
||||
if (invalidPlugins.Contains(dependency.DependencyGUID) && IsHardDependency(dependency))
|
||||
{
|
||||
@@ -387,13 +395,25 @@ public abstract class BaseChainloader<TPlugin>
|
||||
continue;
|
||||
}
|
||||
|
||||
if (missingDependencies.Count != 0)
|
||||
if (missingDependencies.Count != 0 || incompatibleDependencies.Count != 0)
|
||||
{
|
||||
var message = $@"Could not load [{plugin}] because it has missing dependencies: {
|
||||
string.Join(", ", missingDependencies.Select(s => s.VersionRange == null ? s.DependencyGUID : $"{s.DependencyGUID} ({s.VersionRange})").ToArray())
|
||||
}";
|
||||
DependencyErrors.Add(message);
|
||||
Logger.Log(LogLevel.Error, message);
|
||||
if (missingDependencies.Count != 0)
|
||||
{
|
||||
var message = $@"Could not load [{plugin}] because it has missing dependencies: {
|
||||
string.Join(", ", missingDependencies.Select(s => s.VersionRange == null ? s.DependencyGUID : $"{s.DependencyGUID} ({s.VersionRange})").ToArray())
|
||||
}. Install the listed plugin(s) and restart the game.";
|
||||
DependencyErrors.Add(message);
|
||||
Logger.Log(LogLevel.Error, message);
|
||||
}
|
||||
|
||||
if (incompatibleDependencies.Count != 0)
|
||||
{
|
||||
var message = $@"Could not load [{plugin}] because the following dependencies are installed with an incompatible version: {
|
||||
string.Join(", ", incompatibleDependencies.Select(s => $"{s.Key.DependencyGUID} (found {s.Value}, requires {s.Key.VersionRange})").ToArray())
|
||||
}. Update the listed plugin(s) to a version that satisfies the requirement.";
|
||||
DependencyErrors.Add(message);
|
||||
Logger.Log(LogLevel.Error, message);
|
||||
}
|
||||
|
||||
invalidPlugins.Add(plugin.Metadata.GUID);
|
||||
continue;
|
||||
|
||||
@@ -120,8 +120,18 @@ public class BepInDependency : Attribute, ICacheable
|
||||
/// not load and an error will be logged instead.
|
||||
/// </summary>
|
||||
/// <param name="guid">The GUID of the referenced plugin.</param>
|
||||
/// <param name="version">The version range of the referenced plugin.</param>
|
||||
/// <remarks>When version is supplied the dependency is always treated as HardDependency</remarks>
|
||||
/// <param name="version">
|
||||
/// The version requirement of the referenced plugin, parsed as a SemVer range
|
||||
/// (see <see href="https://github.com/adamreeve/semver.net#ranges" />). A plain version such as
|
||||
/// <c>1.2.0</c> requires that exact version; use a range such as <c>>=1.2.0</c>, <c>1.2.*</c>,
|
||||
/// <c>~1.2.0</c> or <c>^1.2.0</c> to accept more than one version.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// When a version is supplied the dependency is always treated as a hard dependency.
|
||||
/// Plugins migrating from BepInEx 5 should note a behaviour change: a bare version was previously
|
||||
/// treated as a minimum (<c>>=</c>), whereas in BepInEx 6 it is an exact match. Use
|
||||
/// <c>>=1.2.0</c> to keep the old behaviour.
|
||||
/// </remarks>
|
||||
public BepInDependency(string guid, string version) : this(guid)
|
||||
{
|
||||
VersionRange = Range.Parse(version);
|
||||
|
||||
Reference in new issue
Block a user