diff --git a/docs/release-notes.md b/docs/release-notes.md index 5cdc539b..36568e09 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -5,6 +5,9 @@ * For players: * Fixed `log_context` command not disabling the extra logs when run again. +* For external tools: + * Added toolkit method to read the compatibility list from a local copy of its Git repo. + ## 4.1.10 Released 18 December 2024 for Stardew Valley 1.6.14 or later. diff --git a/src/SMAPI.Toolkit/Framework/Clients/CompatibilityRepo/CompatibilityRepoClient.cs b/src/SMAPI.Toolkit/Framework/Clients/CompatibilityRepo/CompatibilityRepoClient.cs index e25d890a..ba889910 100644 --- a/src/SMAPI.Toolkit/Framework/Clients/CompatibilityRepo/CompatibilityRepoClient.cs +++ b/src/SMAPI.Toolkit/Framework/Clients/CompatibilityRepo/CompatibilityRepoClient.cs @@ -1,7 +1,9 @@ using System; +using System.IO; using System.Linq; using System.Threading.Tasks; using Markdig; +using Newtonsoft.Json; using Pathoschild.Http.Client; using StardewModdingAPI.Toolkit.Framework.Clients.CompatibilityRepo.Internal; using StardewModdingAPI.Toolkit.Framework.Clients.CompatibilityRepo.RawDataModels; @@ -53,6 +55,25 @@ public class CompatibilityRepoClient : IDisposable .ToArray(); } + /// Fetch mods from the compatibility list by reading a local copy of the compatibility list repo. + /// The full path to the compatibility list repo folder. + public async Task FetchModsFromLocalGitFolderAsync(string gitRepoPath) + { + string modsJsonPath = Path.Combine(gitRepoPath, "data", "mods.jsonc"); + string contentPacksJsonPath = Path.Combine(gitRepoPath, "data", "broken-content-packs.jsonc"); + if (!File.Exists(modsJsonPath) || !File.Exists(contentPacksJsonPath)) + throw new InvalidOperationException("The compatibility list repo folder doesn't contain the required JSON files."); + + RawCompatibilityList? mods = JsonConvert.DeserializeObject(File.ReadAllText(modsJsonPath)); + RawCompatibilityList? brokenContentPacks = JsonConvert.DeserializeObject(File.ReadAllText(contentPacksJsonPath)); + + return + (mods?.Mods ?? Array.Empty()) + .Concat(brokenContentPacks?.BrokenContentPacks ?? Array.Empty()) + .Select(this.ParseRawModEntry) + .ToArray(); + } + /// Get the inline HTML produced by a Markdown string in a compatibility repo field. /// The Markdown to parse. /// This is a low-level method. Most code should use instead. diff --git a/src/SMAPI.Toolkit/ModToolkit.cs b/src/SMAPI.Toolkit/ModToolkit.cs index b0284966..b7117a67 100644 --- a/src/SMAPI.Toolkit/ModToolkit.cs +++ b/src/SMAPI.Toolkit/ModToolkit.cs @@ -70,6 +70,14 @@ public class ModToolkit return await client.FetchModsAsync(); } + /// Extract mod metadata from the compatibility list repo by reading a local copy of the repo. + /// The full path to the compatibility list repo folder. + public async Task GetCompatibilityListFromLocalGitFolderAsync(string gitRepoPath) + { + using CompatibilityRepoClient client = new(this.UserAgent); + return await client.FetchModsFromLocalGitFolderAsync(gitRepoPath); + } + /// Get SMAPI's internal mod database. /// The file path for the SMAPI metadata file. public ModDatabase GetModDatabase(string metadataPath)