summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI/Framework/ModLoading
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2017-05-13 21:36:50 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2017-05-13 21:36:50 -0400
commit53547a8ca3a5cba45bd0a5a478d0f40daa282888 (patch)
treed0ccbdf5b8fed2edc43c83724acc9eb734939c44 /src/StardewModdingAPI/Framework/ModLoading
parent7f368aa8896baa551aa156a8e67e9dd16416022d (diff)
downloadSMAPI-53547a8ca3a5cba45bd0a5a478d0f40daa282888.tar.gz
SMAPI-53547a8ca3a5cba45bd0a5a478d0f40daa282888.tar.bz2
SMAPI-53547a8ca3a5cba45bd0a5a478d0f40daa282888.zip
pass API version into mod metadata validation to simplify unit testing (#285)
Diffstat (limited to 'src/StardewModdingAPI/Framework/ModLoading')
-rw-r--r--src/StardewModdingAPI/Framework/ModLoading/IModMetadata.cs39
-rw-r--r--src/StardewModdingAPI/Framework/ModLoading/ModMetadata.cs14
-rw-r--r--src/StardewModdingAPI/Framework/ModLoading/ModMetadataStatus.cs12
-rw-r--r--src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs22
4 files changed, 64 insertions, 23 deletions
diff --git a/src/StardewModdingAPI/Framework/ModLoading/IModMetadata.cs b/src/StardewModdingAPI/Framework/ModLoading/IModMetadata.cs
new file mode 100644
index 00000000..3771ffdd
--- /dev/null
+++ b/src/StardewModdingAPI/Framework/ModLoading/IModMetadata.cs
@@ -0,0 +1,39 @@
+using StardewModdingAPI.Framework.Models;
+
+namespace StardewModdingAPI.Framework.ModLoading
+{
+ /// <summary>Metadata for a mod.</summary>
+ internal interface IModMetadata
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The mod's display name.</summary>
+ string DisplayName { get; }
+
+ /// <summary>The mod's full directory path.</summary>
+ string DirectoryPath { get; }
+
+ /// <summary>The mod manifest.</summary>
+ IManifest Manifest { get; }
+
+ /// <summary>Optional metadata about a mod version that SMAPI should assume is compatible or broken, regardless of whether it detects incompatible code.</summary>
+ ModCompatibility Compatibility { get; }
+
+ /// <summary>The metadata resolution status.</summary>
+ ModMetadataStatus Status { get; }
+
+ /// <summary>The reason the metadata is invalid, if any.</summary>
+ string Error { get; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Set the mod status.</summary>
+ /// <param name="status">The metadata resolution status.</param>
+ /// <param name="error">The reason the metadata is invalid, if any.</param>
+ /// <returns>Return the instance for chaining.</returns>
+ IModMetadata SetStatus(ModMetadataStatus status, string error = null);
+ }
+}
diff --git a/src/StardewModdingAPI/Framework/ModLoading/ModMetadata.cs b/src/StardewModdingAPI/Framework/ModLoading/ModMetadata.cs
index 5ec2d4e0..7b25e090 100644
--- a/src/StardewModdingAPI/Framework/ModLoading/ModMetadata.cs
+++ b/src/StardewModdingAPI/Framework/ModLoading/ModMetadata.cs
@@ -3,7 +3,7 @@
namespace StardewModdingAPI.Framework.ModLoading
{
/// <summary>Metadata for a mod.</summary>
- internal class ModMetadata
+ internal class ModMetadata : IModMetadata
{
/*********
** Accessors
@@ -47,21 +47,11 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <param name="status">The metadata resolution status.</param>
/// <param name="error">The reason the metadata is invalid, if any.</param>
/// <returns>Return the instance for chaining.</returns>
- public ModMetadata SetStatus(ModMetadataStatus status, string error = null)
+ public IModMetadata SetStatus(ModMetadataStatus status, string error = null)
{
this.Status = status;
this.Error = error;
return this;
}
}
-
- /// <summary>Indicates the status of a mod's metadata resolution.</summary>
- internal enum ModMetadataStatus
- {
- /// <summary>The mod has been found, but hasn't been processed yet.</summary>
- Found,
-
- /// <summary>The mod cannot be loaded.</summary>
- Failed
- }
}
diff --git a/src/StardewModdingAPI/Framework/ModLoading/ModMetadataStatus.cs b/src/StardewModdingAPI/Framework/ModLoading/ModMetadataStatus.cs
new file mode 100644
index 00000000..1b2b0b55
--- /dev/null
+++ b/src/StardewModdingAPI/Framework/ModLoading/ModMetadataStatus.cs
@@ -0,0 +1,12 @@
+namespace StardewModdingAPI.Framework.ModLoading
+{
+ /// <summary>Indicates the status of a mod's metadata resolution.</summary>
+ internal enum ModMetadataStatus
+ {
+ /// <summary>The mod has been found, but hasn't been processed yet.</summary>
+ Found,
+
+ /// <summary>The mod cannot be loaded.</summary>
+ Failed
+ }
+} \ No newline at end of file
diff --git a/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs b/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs
index 9b26e8b0..a3d4ce3e 100644
--- a/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs
+++ b/src/StardewModdingAPI/Framework/ModLoading/ModResolver.cs
@@ -18,7 +18,7 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <param name="jsonHelper">The JSON helper with which to read manifests.</param>
/// <param name="compatibilityRecords">Metadata about mods that SMAPI should assume is compatible or broken, regardless of whether it detects incompatible code.</param>
/// <returns>Returns the manifests by relative folder.</returns>
- public IEnumerable<ModMetadata> ReadManifests(string rootPath, JsonHelper jsonHelper, IEnumerable<ModCompatibility> compatibilityRecords)
+ public IEnumerable<IModMetadata> ReadManifests(string rootPath, JsonHelper jsonHelper, IEnumerable<ModCompatibility> compatibilityRecords)
{
compatibilityRecords = compatibilityRecords.ToArray();
foreach (DirectoryInfo modDir in this.GetModFolders(rootPath))
@@ -75,9 +75,9 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>Validate manifest metadata.</summary>
/// <param name="mods">The mod manifests to validate.</param>
- public void ValidateManifests(IEnumerable<ModMetadata> mods)
+ public void ValidateManifests(IEnumerable<IModMetadata> mods)
{
- foreach (ModMetadata mod in mods)
+ foreach (IModMetadata mod in mods)
{
// skip if already failed
if (mod.Status == ModMetadataStatus.Failed)
@@ -127,12 +127,12 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>Sort the given mods by the order they should be loaded.</summary>
/// <param name="mods">The mods to process.</param>
- public IEnumerable<ModMetadata> ProcessDependencies(IEnumerable<ModMetadata> mods)
+ public IEnumerable<IModMetadata> ProcessDependencies(IEnumerable<IModMetadata> mods)
{
var unsortedMods = mods.ToList();
- var sortedMods = new Stack<ModMetadata>();
+ var sortedMods = new Stack<IModMetadata>();
var visitedMods = new bool[unsortedMods.Count];
- var currentChain = new List<ModMetadata>();
+ var currentChain = new List<IModMetadata>();
bool success = true;
for (int index = 0; index < unsortedMods.Count; index++)
@@ -162,7 +162,7 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <param name="currentChain">The current change of mod dependencies.</param>
/// <param name="unsortedMods">The mods remaining to sort.</param>
/// <returns>Returns whether the mod can be loaded.</returns>
- private bool ProcessDependencies(int modIndex, bool[] visitedMods, Stack<ModMetadata> sortedMods, List<ModMetadata> currentChain, List<ModMetadata> unsortedMods)
+ private bool ProcessDependencies(int modIndex, bool[] visitedMods, Stack<IModMetadata> sortedMods, List<IModMetadata> currentChain, List<IModMetadata> unsortedMods)
{
// visit mod
if (visitedMods[modIndex])
@@ -170,7 +170,7 @@ namespace StardewModdingAPI.Framework.ModLoading
visitedMods[modIndex] = true;
// mod already failed
- ModMetadata mod = unsortedMods[modIndex];
+ IModMetadata mod = unsortedMods[modIndex];
if (mod.Status == ModMetadataStatus.Failed)
return false;
@@ -194,7 +194,7 @@ namespace StardewModdingAPI.Framework.ModLoading
}
// get mods which should be loaded before this one
- ModMetadata[] modsToLoadFirst =
+ IModMetadata[] modsToLoadFirst =
(
from unsorted in unsortedMods
where mod.Manifest.Dependencies.Any(required => required.UniqueID == unsorted.Manifest.UniqueID)
@@ -203,7 +203,7 @@ namespace StardewModdingAPI.Framework.ModLoading
.ToArray();
// detect circular references
- ModMetadata circularReferenceMod = currentChain.FirstOrDefault(modsToLoadFirst.Contains);
+ IModMetadata circularReferenceMod = currentChain.FirstOrDefault(modsToLoadFirst.Contains);
if (circularReferenceMod != null)
{
mod.SetStatus(ModMetadataStatus.Failed, $"its dependencies have a circular reference: {string.Join(" => ", currentChain.Select(p => p.DisplayName))} => {circularReferenceMod.DisplayName}).");
@@ -212,7 +212,7 @@ namespace StardewModdingAPI.Framework.ModLoading
currentChain.Add(mod);
// recursively sort dependencies
- foreach (ModMetadata requiredMod in modsToLoadFirst)
+ foreach (IModMetadata requiredMod in modsToLoadFirst)
{
int index = unsortedMods.IndexOf(requiredMod);
success = this.ProcessDependencies(index, visitedMods, sortedMods, currentChain, unsortedMods);