summaryrefslogtreecommitdiff
path: root/src/SMAPI.Web/Framework/Clients/GitHub
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI.Web/Framework/Clients/GitHub')
-rw-r--r--src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs39
-rw-r--r--src/SMAPI.Web/Framework/Clients/GitHub/GitLicense.cs20
-rw-r--r--src/SMAPI.Web/Framework/Clients/GitHub/GitRepo.cs20
-rw-r--r--src/SMAPI.Web/Framework/Clients/GitHub/IGitHubClient.cs5
4 files changed, 68 insertions, 16 deletions
diff --git a/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs b/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs
index 22950db9..84c20957 100644
--- a/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs
+++ b/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs
@@ -12,12 +12,6 @@ namespace StardewModdingAPI.Web.Framework.Clients.GitHub
/*********
** Fields
*********/
- /// <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;
@@ -27,17 +21,12 @@ namespace StardewModdingAPI.Web.Framework.Clients.GitHub
*********/
/// <summary>Construct an instance.</summary>
/// <param name="baseUrl">The base URL for the GitHub API.</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 stableReleaseUrlFormat, string anyReleaseUrlFormat, string userAgent, string acceptHeader, string username, string password)
+ public GitHubClient(string baseUrl, string userAgent, string acceptHeader, string username, string password)
{
- this.StableReleaseUrlFormat = stableReleaseUrlFormat;
- this.AnyReleaseUrlFormat = anyReleaseUrlFormat;
-
this.Client = new FluentClient(baseUrl)
.SetUserAgent(userAgent)
.AddDefault(req => req.WithHeader("Accept", acceptHeader));
@@ -45,25 +34,43 @@ namespace StardewModdingAPI.Web.Framework.Clients.GitHub
this.Client = this.Client.SetBasicAuthentication(username, password);
}
+ /// <summary>Get basic metadata for a GitHub repository, if available.</summary>
+ /// <param name="repo">The repository key (like <c>Pathoschild/SMAPI</c>).</param>
+ /// <returns>Returns the repository info if it exists, else <c>null</c>.</returns>
+ public async Task<GitRepo> GetRepositoryAsync(string repo)
+ {
+ this.AssertKeyFormat(repo);
+ try
+ {
+ return await this.Client
+ .GetAsync($"repos/{repo}")
+ .As<GitRepo>();
+ }
+ catch (ApiException ex) when (ex.Status == HttpStatusCode.NotFound)
+ {
+ return null;
+ }
+ }
+
/// <summary>Get the latest release for a GitHub repository.</summary>
/// <param name="repo">The repository key (like <c>Pathoschild/SMAPI</c>).</param>
/// <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)
{
- this.AssetKeyFormat(repo);
+ this.AssertKeyFormat(repo);
try
{
if (includePrerelease)
{
GitRelease[] results = await this.Client
- .GetAsync(string.Format(this.AnyReleaseUrlFormat, repo))
+ .GetAsync($"repos/{repo}/releases?per_page=2") // allow for draft release (only visible if GitHub repo is owned by same account as the update check credentials)
.AsArray<GitRelease>();
return results.FirstOrDefault(p => !p.IsDraft);
}
return await this.Client
- .GetAsync(string.Format(this.StableReleaseUrlFormat, repo))
+ .GetAsync($"repos/{repo}/releases/latest")
.As<GitRelease>();
}
catch (ApiException ex) when (ex.Status == HttpStatusCode.NotFound)
@@ -85,7 +92,7 @@ namespace StardewModdingAPI.Web.Framework.Clients.GitHub
/// <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)
+ private void AssertKeyFormat(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));
diff --git a/src/SMAPI.Web/Framework/Clients/GitHub/GitLicense.cs b/src/SMAPI.Web/Framework/Clients/GitHub/GitLicense.cs
new file mode 100644
index 00000000..736efbe6
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/GitHub/GitLicense.cs
@@ -0,0 +1,20 @@
+using Newtonsoft.Json;
+
+namespace StardewModdingAPI.Web.Framework.Clients.GitHub
+{
+ /// <summary>The license info for a GitHub project.</summary>
+ internal class GitLicense
+ {
+ /// <summary>The license display name.</summary>
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ /// <summary>The SPDX ID for the license.</summary>
+ [JsonProperty("spdx_id")]
+ public string SpdxId { get; set; }
+
+ /// <summary>The URL for the license info.</summary>
+ [JsonProperty("url")]
+ public string Url { get; set; }
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/GitHub/GitRepo.cs b/src/SMAPI.Web/Framework/Clients/GitHub/GitRepo.cs
new file mode 100644
index 00000000..7d80576e
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/GitHub/GitRepo.cs
@@ -0,0 +1,20 @@
+using Newtonsoft.Json;
+
+namespace StardewModdingAPI.Web.Framework.Clients.GitHub
+{
+ /// <summary>Basic metadata about a GitHub project.</summary>
+ internal class GitRepo
+ {
+ /// <summary>The full repository name, including the owner.</summary>
+ [JsonProperty("full_name")]
+ public string FullName { get; set; }
+
+ /// <summary>The URL to the repository web page, if any.</summary>
+ [JsonProperty("html_url")]
+ public string WebUrl { get; set; }
+
+ /// <summary>The code license, if any.</summary>
+ [JsonProperty("license")]
+ public GitLicense License { get; set; }
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/GitHub/IGitHubClient.cs b/src/SMAPI.Web/Framework/Clients/GitHub/IGitHubClient.cs
index 9519c26f..a34f03bd 100644
--- a/src/SMAPI.Web/Framework/Clients/GitHub/IGitHubClient.cs
+++ b/src/SMAPI.Web/Framework/Clients/GitHub/IGitHubClient.cs
@@ -9,6 +9,11 @@ namespace StardewModdingAPI.Web.Framework.Clients.GitHub
/*********
** Methods
*********/
+ /// <summary>Get basic metadata for a GitHub repository, if available.</summary>
+ /// <param name="repo">The repository key (like <c>Pathoschild/SMAPI</c>).</param>
+ /// <returns>Returns the repository info if it exists, else <c>null</c>.</returns>
+ Task<GitRepo> GetRepositoryAsync(string repo);
+
/// <summary>Get the latest release for a GitHub repository.</summary>
/// <param name="repo">The repository key (like <c>Pathoschild/SMAPI</c>).</param>
/// <param name="includePrerelease">Whether to return a prerelease version if it's latest.</param>