diff --git a/src/backend/PkgDiff.Application/Services/PackageCacheService.cs b/src/backend/PkgDiff.Application/Services/PackageCacheService.cs index 6fbdcc4..8edadc8 100644 --- a/src/backend/PkgDiff.Application/Services/PackageCacheService.cs +++ b/src/backend/PkgDiff.Application/Services/PackageCacheService.cs @@ -233,11 +233,27 @@ private async Task BuildMetadataFromCache(CachedPackage cached, }; } + private async Task ForgetEmptyReleaseNotesAsync(int cachedPackageId, string registry, string packageId) + { + var emptyNotes = (await _unitOfWork.CachedReleaseNotes + .FindAsync(rn => rn.CachedPackageId == cachedPackageId && rn.IsEmpty && rn.ReleaseNotesSource != null)) + .ToList(); + if (emptyNotes.Count == 0) + return; + + foreach (var note in emptyNotes) + note.ReleaseNotesSource = null; + await _unitOfWork.SaveChangesAsync(); + + _jobs.Enqueue(service => service.ScrapePackageReleaseNotesAsync(packageId, registry)); + } + private async Task SaveFreshMetadataToCache( CachedPackage? cached, PackageMetadata metadata, string registry, string packageId) { var registryId = await ResolveRegistryIdAsync(registry); + var repositoryChanged = false; if (cached == null) { cached = new CachedPackage @@ -263,6 +279,8 @@ private async Task SaveFreshMetadataToCache( cached.Authors = metadata.Authors; cached.IconUrl = metadata.IconUrl; cached.ProjectUrl = metadata.ProjectUrl; + repositoryChanged = metadata.GitHubRepositoryUrl != null + && !string.Equals(metadata.GitHubRepositoryUrl, cached.GitHubRepositoryUrl, StringComparison.OrdinalIgnoreCase); // A repository found while scraping release notes is kept when the registry names none cached.GitHubRepositoryUrl = metadata.GitHubRepositoryUrl ?? cached.GitHubRepositoryUrl; cached.AllVersionsJson = JsonSerializer.Serialize(metadata.Versions.Select(v => v.Version)); @@ -273,6 +291,9 @@ private async Task SaveFreshMetadataToCache( await _unitOfWork.SaveChangesAsync(); + if (repositoryChanged) + await ForgetEmptyReleaseNotesAsync(cached.Id, registry.ToLowerInvariant(), packageId); + var latestVersion = metadata.LatestVersion ?? string.Empty; var latestPublished = metadata.Versions.FirstOrDefault(v => v.Version == latestVersion)?.PublishedDate; await _liveUpdates.RecordLatestVersionAsync(cached, registry, latestVersion, latestPublished, authoritative: true); diff --git a/src/backend/PkgDiff.Infrastructure/Services/GitHubScraperService.cs b/src/backend/PkgDiff.Infrastructure/Services/GitHubScraperService.cs index 9028542..b572d4f 100644 --- a/src/backend/PkgDiff.Infrastructure/Services/GitHubScraperService.cs +++ b/src/backend/PkgDiff.Infrastructure/Services/GitHubScraperService.cs @@ -336,6 +336,7 @@ private static IEnumerable TagCandidates(string? packageId, string versi } yield return $"release-{version}"; yield return $"release/{version}"; + yield return $"rel_{version.Replace('.', '_')}"; } [System.Text.RegularExpressions.GeneratedRegex(@"^[vV]?\d")] diff --git a/src/backend/PkgDiff.Infrastructure/Services/NpmService.cs b/src/backend/PkgDiff.Infrastructure/Services/NpmService.cs index 94332df..a1d6751 100644 --- a/src/backend/PkgDiff.Infrastructure/Services/NpmService.cs +++ b/src/backend/PkgDiff.Infrastructure/Services/NpmService.cs @@ -265,7 +265,7 @@ private class NpmAuthorConverter : JsonConverter var propName = reader.GetString(); reader.Read(); if (propName == "name") author.Name = reader.GetString(); - else reader.Skip(); + else reader.TrySkip(); } } return author; @@ -299,7 +299,7 @@ private class NpmRepositoryConverter : JsonConverter return new NpmRepository { Url = reader.GetString() }; if (reader.TokenType != JsonTokenType.StartObject) { - reader.Skip(); + reader.TrySkip(); return null; } @@ -312,7 +312,7 @@ private class NpmRepositoryConverter : JsonConverter reader.Read(); var value = reader.TokenType == JsonTokenType.String ? reader.GetString() : null; if (reader.TokenType is JsonTokenType.StartObject or JsonTokenType.StartArray) - reader.Skip(); + reader.TrySkip(); switch (propName) { case "type": repository.Type = value; break; @@ -349,11 +349,11 @@ private class LooseStringConverter : JsonConverter if (reader.TokenType == JsonTokenType.String) first ??= reader.GetString(); else if (reader.TokenType is JsonTokenType.StartObject or JsonTokenType.StartArray) - reader.Skip(); + reader.TrySkip(); } return first; case JsonTokenType.StartObject: - reader.Skip(); + reader.TrySkip(); return null; default: return null;