diff options
Diffstat (limited to 'src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs')
-rw-r--r-- | src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs b/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs index 0b205660..4abe0737 100644 --- a/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs +++ b/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Net; using System.Threading.Tasks; using Pathoschild.Http.Client; @@ -11,8 +12,11 @@ namespace StardewModdingAPI.Web.Framework.Clients.GitHub /********* ** Properties *********/ - /// <summary>The URL for a GitHub releases API query excluding the base URL, where {0} is the repository owner and name.</summary> - private readonly string ReleaseUrlFormat; + /// <summary>The URL for a GitHub API query for the latest stable release, excluding the base URL, where {0} is the organisation and project name.</summary> + private readonly string StableReleaseUrlFormat; + + /// <summary>The URL for a GitHub API query for the latest release (including prerelease), excluding the base URL, where {0} is the organisation and project name.</summary> + private readonly string AnyReleaseUrlFormat; /// <summary>The underlying HTTP client.</summary> private readonly IClient Client; @@ -23,14 +27,16 @@ namespace StardewModdingAPI.Web.Framework.Clients.GitHub *********/ /// <summary>Construct an instance.</summary> /// <param name="baseUrl">The base URL for the GitHub API.</param> - /// <param name="releaseUrlFormat">The URL for a GitHub releases API query excluding the <paramref name="baseUrl"/>, where {0} is the repository owner and name.</param> + /// <param name="stableReleaseUrlFormat">The URL for a GitHub API query for the latest stable release, excluding the <paramref name="baseUrl"/>, where {0} is the organisation and project name.</param> + /// <param name="anyReleaseUrlFormat">The URL for a GitHub API query for the latest release (including prerelease), excluding the <paramref name="baseUrl"/>, where {0} is the organisation and project name.</param> /// <param name="userAgent">The user agent for the API client.</param> /// <param name="acceptHeader">The Accept header value expected by the GitHub API.</param> /// <param name="username">The username with which to authenticate to the GitHub API.</param> /// <param name="password">The password with which to authenticate to the GitHub API.</param> - public GitHubClient(string baseUrl, string releaseUrlFormat, string userAgent, string acceptHeader, string username, string password) + public GitHubClient(string baseUrl, string stableReleaseUrlFormat, string anyReleaseUrlFormat, string userAgent, string acceptHeader, string username, string password) { - this.ReleaseUrlFormat = releaseUrlFormat; + this.StableReleaseUrlFormat = stableReleaseUrlFormat; + this.AnyReleaseUrlFormat = anyReleaseUrlFormat; this.Client = new FluentClient(baseUrl) .SetUserAgent(userAgent) @@ -41,18 +47,23 @@ namespace StardewModdingAPI.Web.Framework.Clients.GitHub /// <summary>Get the latest release for a GitHub repository.</summary> /// <param name="repo">The repository key (like <c>Pathoschild/SMAPI</c>).</param> - /// <returns>Returns the latest release if found, else <c>null</c>.</returns> - public async Task<GitRelease> GetLatestReleaseAsync(string repo) + /// <param name="includePrerelease">Whether to return a prerelease version if it's latest.</param> + /// <returns>Returns the release if found, else <c>null</c>.</returns> + public async Task<GitRelease> GetLatestReleaseAsync(string repo, bool includePrerelease = false) { - // validate key format - if (!repo.Contains("/") || repo.IndexOf("/", StringComparison.InvariantCultureIgnoreCase) != repo.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase)) - throw new ArgumentException($"The value '{repo}' isn't a valid GitHub repository key, must be a username and project name like 'Pathoschild/SMAPI'.", nameof(repo)); - - // fetch info + this.AssetKeyFormat(repo); try { + if (includePrerelease) + { + GitRelease[] results = await this.Client + .GetAsync(string.Format(this.AnyReleaseUrlFormat, repo)) + .AsArray<GitRelease>(); + return results.FirstOrDefault(); + } + return await this.Client - .GetAsync(string.Format(this.ReleaseUrlFormat, repo)) + .GetAsync(string.Format(this.StableReleaseUrlFormat, repo)) .As<GitRelease>(); } catch (ApiException ex) when (ex.Status == HttpStatusCode.NotFound) @@ -66,5 +77,18 @@ namespace StardewModdingAPI.Web.Framework.Clients.GitHub { this.Client?.Dispose(); } + + + /********* + ** Private methods + *********/ + /// <summary>Assert that a repository key is formatted correctly.</summary> + /// <param name="repo">The repository key (like <c>Pathoschild/SMAPI</c>).</param> + /// <exception cref="ArgumentException">The repository key is invalid.</exception> + private void AssetKeyFormat(string repo) + { + if (repo == null || !repo.Contains("/") || repo.IndexOf("/", StringComparison.InvariantCultureIgnoreCase) != repo.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase)) + throw new ArgumentException($"The value '{repo}' isn't a valid GitHub repository key, must be a username and project name like 'Pathoschild/SMAPI'.", nameof(repo)); + } } } |