From befaf8e0d19d63d7aeac983ea7964fbcb9fbc855 Mon Sep 17 00:00:00 2001 From: Canon Date: Sun, 19 Jul 2026 01:42:21 +0800 Subject: [PATCH] Change Refresh Status to also clear repository cache --- .../Services/GitHubApiServiceTests.cs | 24 +++++++++++++++++++ README.md | 6 +++++ Services/GitHubApiService.cs | 6 +++++ Services/IGitHubApiService.cs | 1 + UI/InteractiveMenu.cs | 7 +++--- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/FCPModUpdater.Tests/Services/GitHubApiServiceTests.cs b/FCPModUpdater.Tests/Services/GitHubApiServiceTests.cs index 50db0d3..ba06c79 100644 --- a/FCPModUpdater.Tests/Services/GitHubApiServiceTests.cs +++ b/FCPModUpdater.Tests/Services/GitHubApiServiceTests.cs @@ -110,6 +110,30 @@ public class GitHubApiServiceTests : IDisposable Assert.Equal(1, _handler.RequestCount); } + [Fact] + public async Task ClearCache_NextRequestFetchesFreshRepositories() + { + CancellationToken token = TestContext.Current.CancellationToken; + + _handler.ResponseQueue.Enqueue(new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent(JsonSerializer.Serialize(new[] { MakeRepo("FCP-Weapons") })) + }); + _handler.ResponseQueue.Enqueue(new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent(JsonSerializer.Serialize(new[] { MakeRepo("FCP-Armor") })) + }); + + IReadOnlyList cached = await _service.GetOrganizationReposAsync(token); + + _service.ClearCache(); + IReadOnlyList refreshed = await _service.GetOrganizationReposAsync(token); + + Assert.Equal("FCP-Weapons", Assert.Single(cached).Name); + Assert.Equal("FCP-Armor", Assert.Single(refreshed).Name); + Assert.Equal(2, _handler.RequestCount); + } + [Fact] public async Task RateLimitHeaders_Parsed() { diff --git a/README.md b/README.md index 7481ce6..568d42f 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,12 @@ The tool opens an interactive menu — use the **arrow keys** to navigate, **Ent 2. Choose the mod you want to manage 3. Select **Switch Branch** to pick a branch, or **Checkout Specific Commit** to pin to a specific version +### To clear cached data and refresh mod status: +1. Select **Clear Cache & Refresh** from the main menu +2. The manager retrieves the FCP repository list again, rescans the Mods directory, and fetches the latest Git status for every installed Git mod + +This does not pull updates, switch versions, or overwrite local changes. + ### To Batch Update Mods ```bash diff --git a/Services/GitHubApiService.cs b/Services/GitHubApiService.cs index 8299e07..2a4138d 100644 --- a/Services/GitHubApiService.cs +++ b/Services/GitHubApiService.cs @@ -17,6 +17,12 @@ public class GitHubApiService(HttpClient httpClient) : IGitHubApiService public int? RemainingRateLimit { get; private set; } public DateTimeOffset? RateLimitReset { get; private set; } + public void ClearCache() + { + _cachedRepos = null; + _cacheTime = DateTimeOffset.MinValue; + } + public async Task> GetOrganizationReposAsync(CancellationToken ct = default) { if (_cachedRepos != null && DateTimeOffset.UtcNow - _cacheTime < _cacheExpiry) diff --git a/Services/IGitHubApiService.cs b/Services/IGitHubApiService.cs index 9512e2f..1cf6597 100644 --- a/Services/IGitHubApiService.cs +++ b/Services/IGitHubApiService.cs @@ -4,6 +4,7 @@ namespace FCPModUpdater.Services; public interface IGitHubApiService { + void ClearCache(); Task> GetOrganizationReposAsync(CancellationToken ct = default); Task GetRepoByNameAsync(string repoName, CancellationToken ct = default); int? RemainingRateLimit { get; } diff --git a/UI/InteractiveMenu.cs b/UI/InteractiveMenu.cs index 924867a..b55528d 100644 --- a/UI/InteractiveMenu.cs +++ b/UI/InteractiveMenu.cs @@ -66,7 +66,7 @@ public class InteractiveMenu "Uninstall Mods", "Convert Local to Git", "Mod Version Selector", - "Refresh Status", + "Clear Cache & Refresh", "Exit" ), ct); @@ -79,7 +79,7 @@ public class InteractiveMenu "Uninstall Mods" => await HandleUninstallAsync(ct), "Convert Local to Git" => await HandleConvertAsync(ct), "Mod Version Selector" => await HandleVersionSelectorAsync(ct), - "Refresh Status" => await HandleRefreshAsync(ct), + "Clear Cache & Refresh" => await HandleClearCacheAndRefreshAsync(ct), "Exit" => true, _ => false }; @@ -549,8 +549,9 @@ public class InteractiveMenu WaitForKey(); } - private async Task HandleRefreshAsync(CancellationToken ct) + private async Task HandleClearCacheAndRefreshAsync(CancellationToken ct) { + _gitHubApiService.ClearCache(); await RefreshModsAsync(ct); return false; }