diff --git a/src/backend/PkgDiff.Infrastructure/Services/PyPIService.cs b/src/backend/PkgDiff.Infrastructure/Services/PyPIService.cs index 2e863a0..7f376ac 100644 --- a/src/backend/PkgDiff.Infrastructure/Services/PyPIService.cs +++ b/src/backend/PkgDiff.Infrastructure/Services/PyPIService.cs @@ -163,9 +163,26 @@ private static bool IsGitHubUrl(string? url) .Concat(links.Where(l => !NotRepositoryKeys.Any(k => l.Key.Contains(k, StringComparison.OrdinalIgnoreCase))) .Select(l => l.Value)); - return candidates.Select(RepositoryRoot).FirstOrDefault(url => url != null); + return candidates.Select(RepositoryRoot).FirstOrDefault(url => url != null) + ?? RepositoryFromDescription(info); } + private static string? RepositoryFromDescription(PyPIPackageInfo info) + { + if (string.IsNullOrEmpty(info.Description) || string.IsNullOrEmpty(info.Name)) + return null; + + var name = NormalizeName(info.Name); + return System.Text.RegularExpressions.Regex.Matches(info.Description, + @"https?://(?:www\.)?github\.com/[\w.-]+/[\w.-]+", + System.Text.RegularExpressions.RegexOptions.IgnoreCase) + .Select(m => RepositoryRoot(m.Value.TrimEnd('.'))) + .FirstOrDefault(url => url != null && NormalizeName(url[(url.LastIndexOf('/') + 1)..]) == name); + } + + private static string NormalizeName(string name) => + System.Text.RegularExpressions.Regex.Replace(name, @"[-_.]+", "-").ToLowerInvariant(); + // https://github.com/{owner}/{repo} of a GitHub link (issues, a changelog file, releases), keeping a // /tree/{ref}/{folder} part that names the package folder of a monorepo; null for any other link private static string? RepositoryRoot(string? url) @@ -245,6 +262,9 @@ private class PyPIPackageInfo [JsonPropertyName("project_urls")] public Dictionary? ProjectUrls { get; set; } + + [JsonPropertyName("description")] + public string? Description { get; set; } } private class PyPIReleaseFile