diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-02-16 23:02:04 -0500 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-02-16 23:02:04 -0500 |
commit | 9b3dd42cbf62a8524ac390d9418cf961c502868a (patch) | |
tree | 3f87447cc6e2e8b370701eb8e95ba6622393b9b3 | |
parent | d926133608b227add19f0aa711bf3efb5da5f0bd (diff) | |
download | SMAPI-9b3dd42cbf62a8524ac390d9418cf961c502868a.tar.gz SMAPI-9b3dd42cbf62a8524ac390d9418cf961c502868a.tar.bz2 SMAPI-9b3dd42cbf62a8524ac390d9418cf961c502868a.zip |
encapsulate update key to URL logic for reuse (#437)
-rw-r--r-- | src/SMAPI.Tests/Core/ModResolverTests.cs | 14 | ||||
-rw-r--r-- | src/SMAPI/Constants.cs | 33 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModLoading/ModResolver.cs | 16 | ||||
-rw-r--r-- | src/SMAPI/Program.cs | 2 |
4 files changed, 38 insertions, 27 deletions
diff --git a/src/SMAPI.Tests/Core/ModResolverTests.cs b/src/SMAPI.Tests/Core/ModResolverTests.cs index 900a6c4f..d63eb1a2 100644 --- a/src/SMAPI.Tests/Core/ModResolverTests.cs +++ b/src/SMAPI.Tests/Core/ModResolverTests.cs @@ -120,7 +120,7 @@ namespace StardewModdingAPI.Tests.Core [Test(Description = "Assert that validation doesn't fail if there are no mods installed.")] public void ValidateManifests_NoMods_DoesNothing() { - new ModResolver().ValidateManifests(new ModMetadata[0], apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>()); + new ModResolver().ValidateManifests(new ModMetadata[0], apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null); } [Test(Description = "Assert that validation skips manifests that have already failed without calling any other properties.")] @@ -131,7 +131,7 @@ namespace StardewModdingAPI.Tests.Core mock.Setup(p => p.Status).Returns(ModMetadataStatus.Failed); // act - new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>()); + new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null); // assert mock.VerifyGet(p => p.Status, Times.Once, "The validation did not check the manifest status."); @@ -149,7 +149,7 @@ namespace StardewModdingAPI.Tests.Core }); // act - new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>()); + new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null); // assert mock.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the metadata."); @@ -164,7 +164,7 @@ namespace StardewModdingAPI.Tests.Core this.SetupMetadataForValidation(mock); // act - new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>()); + new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null); // assert mock.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the metadata."); @@ -178,7 +178,7 @@ namespace StardewModdingAPI.Tests.Core this.SetupMetadataForValidation(mock); // act - new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>()); + new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null); // assert mock.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the metadata."); @@ -195,7 +195,7 @@ namespace StardewModdingAPI.Tests.Core this.SetupMetadataForValidation(mod); // act - new ModResolver().ValidateManifests(new[] { modA.Object, modB.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>()); + new ModResolver().ValidateManifests(new[] { modA.Object, modB.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null); // assert modA.Verify(p => p.SetStatus(ModMetadataStatus.Failed, It.IsAny<string>()), Times.Once, "The validation did not fail the first mod with a unique ID."); @@ -221,7 +221,7 @@ namespace StardewModdingAPI.Tests.Core mock.Setup(p => p.DirectoryPath).Returns(modFolder); // act - new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), vendorModUrls: new Dictionary<string, string>()); + new ModResolver().ValidateManifests(new[] { mock.Object }, apiVersion: new SemanticVersion("1.0"), getUpdateUrl: key => null); // assert // if Moq doesn't throw a method-not-setup exception, the validation didn't override the status. diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 515e9870..caee93e4 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -21,6 +21,14 @@ namespace StardewModdingAPI /// <summary>Whether the directory containing the current save's data exists on disk.</summary> private static bool SavePathReady => Context.IsSaveLoaded && Directory.Exists(Constants.RawSavePath); + /// <summary>Maps vendor keys (like <c>Nexus</c>) to their mod URL template (where <c>{0}</c> is the mod ID). This doesn't affect update checks, which defer to the remote web API.</summary> + private static readonly IDictionary<string, string> VendorModUrls = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase) + { + ["Chucklefish"] = "https://community.playstarbound.com/resources/{0}", + ["Nexus"] = "http://nexusmods.com/stardewvalley/mods/{0}", + ["GitHub"] = "https://github.com/{0}/releases" + }; + /********* ** Accessors @@ -87,14 +95,6 @@ namespace StardewModdingAPI Platform.Mono; #endif - /// <summary>Maps vendor keys (like <c>Nexus</c>) to their mod URL template (where <c>{0}</c> is the mod ID) during mod compatibility checks. This doesn't affect update checks, which defer to the remote web API.</summary> - internal static readonly IDictionary<string, string> VendorModUrls = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase) - { - ["Chucklefish"] = "https://community.playstarbound.com/resources/{0}", - ["Nexus"] = "http://nexusmods.com/stardewvalley/mods/{0}", - ["GitHub"] = "https://github.com/{0}/releases" - }; - /********* ** Internal methods @@ -145,6 +145,23 @@ namespace StardewModdingAPI return new PlatformAssemblyMap(targetPlatform, removeAssemblyReferences, targetAssemblies); } + /// <summary>Get an update URL for an update key (if valid).</summary> + /// <param name="updateKey">The update key.</param> + internal static string GetUpdateUrl(string updateKey) + { + string[] parts = updateKey.Split(new[] { ':' }, 2); + if (parts.Length != 2) + return null; + + string vendorKey = parts[0].Trim(); + string modID = parts[1].Trim(); + + if (Constants.VendorModUrls.TryGetValue(vendorKey, out string urlTemplate)) + return string.Format(urlTemplate, modID); + + return null; + } + /********* ** Private methods diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index 09a9299e..99d86bf8 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -73,8 +73,8 @@ namespace StardewModdingAPI.Framework.ModLoading /// <summary>Validate manifest metadata.</summary> /// <param name="mods">The mod manifests to validate.</param> /// <param name="apiVersion">The current SMAPI version.</param> - /// <param name="vendorModUrls">Maps vendor keys (like <c>Nexus</c>) to their mod URL template (where <c>{0}</c> is the mod ID).</param> - public void ValidateManifests(IEnumerable<IModMetadata> mods, ISemanticVersion apiVersion, IDictionary<string, string> vendorModUrls) + /// <param name="getUpdateUrl">Get an update URL for an update key (if valid).</param> + public void ValidateManifests(IEnumerable<IModMetadata> mods, ISemanticVersion apiVersion, Func<string, string> getUpdateUrl) { mods = mods.ToArray(); @@ -101,15 +101,9 @@ namespace StardewModdingAPI.Framework.ModLoading List<string> updateUrls = new List<string>(); foreach (string key in mod.Manifest.UpdateKeys ?? new string[0]) { - string[] parts = key.Split(new[] { ':' }, 2); - if (parts.Length != 2) - continue; - - string vendorKey = parts[0].Trim(); - string modID = parts[1].Trim(); - - if (vendorModUrls.TryGetValue(vendorKey, out string urlTemplate)) - updateUrls.Add(string.Format(urlTemplate, modID)); + string url = getUpdateUrl(key); + if (url != null) + updateUrls.Add(url); } if (mod.DataRecord.AlternativeUrl != null) updateUrls.Add(mod.DataRecord.AlternativeUrl); diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index ec841f4c..85bc83a7 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -360,7 +360,7 @@ namespace StardewModdingAPI // load manifests IModMetadata[] mods = resolver.ReadManifests(Constants.ModPath, new JsonHelper(), modDatabase).ToArray(); - resolver.ValidateManifests(mods, Constants.ApiVersion, Constants.VendorModUrls); + resolver.ValidateManifests(mods, Constants.ApiVersion, Constants.GetUpdateUrl); // process dependencies mods = resolver.ProcessDependencies(mods, modDatabase).ToArray(); |