Skip to content

Commit

Permalink
Merge pull request #11 from danielklecha/master
Browse files Browse the repository at this point in the history
Search for license in repository url and in local package folder
  • Loading branch information
bugproof authored Feb 21, 2024
2 parents 9d9a3ff + 107c9c0 commit 5b8ac72
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ internal static class ResolvedFileInfoExtensions
private static readonly Lazy<List<IProjectUriLicenseResolver>> ProjectUriLicenseResolvers =
new(() => LicenseResolvers.Value.OfType<IProjectUriLicenseResolver>().ToList());

private static readonly Lazy<List<IRepositoryUriLicenseResolver>> RepositoryUriLicenseResolvers =
new(() => LicenseResolvers.Value.OfType<IRepositoryUriLicenseResolver>().ToList());

private static readonly Lazy<List<IFileVersionInfoLicenseResolver>> FileVersionInfoLicenseResolvers =
new(() => LicenseResolvers.Value.OfType<IFileVersionInfoLicenseResolver>().ToList());

Expand All @@ -35,6 +38,12 @@ private static bool TryFindLicenseUriLicenseResolver(Uri licenseUri, out ILicens
return resolver != null;
}

private static bool TryFindRepositoryUriLicenseResolver( Uri licenseUri, out IRepositoryUriLicenseResolver resolver )
{
resolver = RepositoryUriLicenseResolvers.Value.FirstOrDefault(r => r.CanResolve(licenseUri));
return resolver != null;
}

private static bool TryFindProjectUriLicenseResolver(Uri projectUri, out IProjectUriLicenseResolver resolver)
{
resolver = ProjectUriLicenseResolvers.Value.FirstOrDefault(r => r.CanResolve(projectUri));
Expand Down Expand Up @@ -66,6 +75,7 @@ private static async Task<string> ResolveLicense(NuSpec nuSpec)
return LicenseCache[nuSpec.Id];

var licenseUrl = nuSpec.LicenseUrl;
var repositoryUrl = nuSpec.RepositoryUrl;
var projectUrl = nuSpec.ProjectUrl;

// Try to get the license from license url
Expand All @@ -83,6 +93,20 @@ private static async Task<string> ResolveLicense(NuSpec nuSpec)
}
}

// Try to get the license from repository url
if (!string.IsNullOrEmpty(repositoryUrl))
{
if (LicenseCache.ContainsKey(repositoryUrl ))
return LicenseCache[repositoryUrl];
var license = await ResolveLicenseFromRepositoryUri(new Uri(repositoryUrl));
if (license != null)
{
LicenseCache[repositoryUrl] = license;
LicenseCache[nuSpec.Id] = license;
return license;
}
}

// Otherwise try to get the license from project url
if (string.IsNullOrEmpty(projectUrl)) return null;

Expand Down Expand Up @@ -111,6 +135,20 @@ private static async Task<string> ResolveLicenseFromLicenseUri(Uri licenseUri)
return await licenseUri.GetPlainText();
}

private static async Task<string> ResolveLicenseFromRepositoryUri(Uri repositoryUri)
{
if (TryFindRepositoryUriLicenseResolver(repositoryUri, out var repositoryUriLicenseResolver))
return await repositoryUriLicenseResolver.Resolve(repositoryUri);

// TODO: redirect uris should be checked at the very end to save us from redundant requests (when no resolver for anything can be found)
var redirectUri = await repositoryUri.GetRedirectUri();
if (redirectUri != null)
return await ResolveLicenseFromLicenseUri(redirectUri);

// Finally, if no license uri can be found despite all the redirects, try to blindly get it
return await repositoryUri.GetPlainText();
}

private static async Task<string> ResolveLicenseFromProjectUri(Uri projectUri)
{
if (TryFindProjectUriLicenseResolver(projectUri, out var projectUriLicenseResolver))
Expand Down
2 changes: 2 additions & 0 deletions src/DotnetThirdPartyNotices/GithubService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public async Task<string> GetLicenseContentFromId(string licenseId)
public async Task<string> GetLicenseContentFromRepositoryPath(string repositoryPath)
{
repositoryPath = repositoryPath.TrimEnd('/');
if (repositoryPath.EndsWith(".git"))
repositoryPath = repositoryPath[..^4];
var json = await _httpClient.GetStringAsync($"repos{repositoryPath}/license");
var jsonDocument = JsonDocument.Parse(json);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

namespace DotnetThirdPartyNotices.LicenseResolvers;

internal class GithubLicenseResolver : ILicenseUriLicenseResolver, IProjectUriLicenseResolver
internal class GithubLicenseResolver : ILicenseUriLicenseResolver, IProjectUriLicenseResolver, IRepositoryUriLicenseResolver
{
bool ILicenseUriLicenseResolver.CanResolve(Uri uri) => uri.IsGithubUri();
bool IProjectUriLicenseResolver.CanResolve(Uri uri) => uri.IsGithubUri();
bool IRepositoryUriLicenseResolver.CanResolve(Uri uri) => uri.IsGithubUri();

Task<string> ILicenseUriLicenseResolver.Resolve(Uri licenseUri)
{
Expand All @@ -22,4 +23,10 @@ async Task<string> IProjectUriLicenseResolver.Resolve(Uri projectUri)
using var githubService = new GithubService();
return await githubService.GetLicenseContentFromRepositoryPath(projectUri.AbsolutePath);
}

async Task<string> IRepositoryUriLicenseResolver.Resolve(Uri projectUri)
{
using var githubService = new GithubService();
return await githubService.GetLicenseContentFromRepositoryPath(projectUri.AbsolutePath);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DotnetThirdPartyNotices.LicenseResolvers.Interfaces;

internal interface IRepositoryUriLicenseResolver : ILicenseResolver
{
bool CanResolve(Uri projectUri);
Task<string> Resolve(Uri projectUri);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using DotnetThirdPartyNotices.LicenseResolvers.Interfaces;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DotnetThirdPartyNotices.LicenseResolvers;

internal class LocalPackageLicenseResolver : IFileVersionInfoLicenseResolver
{
public bool CanResolve( FileVersionInfo fileVersionInfo ) => true;

public async Task<string> Resolve( FileVersionInfo fileVersionInfo )
{
var packageName = Path.GetFileNameWithoutExtension(fileVersionInfo.FileName);
var directoryParts = Path.GetDirectoryName(fileVersionInfo.FileName ).Split('\\', StringSplitOptions.RemoveEmptyEntries);
for ( var i = 0; i < directoryParts.Length; i++ )
{
var directoryPath = string.Join('\\', directoryParts.SkipLast(i));
var licensePath = Directory.EnumerateFiles(directoryPath, "license.txt", SearchOption.TopDirectoryOnly)
.FirstOrDefault();
if (licensePath != null)
return await File.ReadAllTextAsync(licensePath);
if (directoryPath.EndsWith($"\\{packageName}", StringComparison.OrdinalIgnoreCase))
break;
}
return null;
}
}
4 changes: 3 additions & 1 deletion src/DotnetThirdPartyNotices/NuSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public record NuSpec
public string Version { get; init; }
public string LicenseUrl { get; init; }
public string ProjectUrl { get; init; }
public string RepositoryUrl { get; init; }

private static NuSpec FromTextReader(TextReader streamReader)
{
Expand All @@ -29,7 +30,8 @@ private static NuSpec FromTextReader(TextReader streamReader)
Id = metadata.Element(ns + "id")?.Value,
Version = metadata.Element(ns + "version")?.Value,
LicenseUrl = metadata.Element(ns + "licenseUrl")?.Value,
ProjectUrl = metadata.Element(ns + "projectUrl")?.Value
ProjectUrl = metadata.Element(ns + "projectUrl")?.Value,
RepositoryUrl = metadata.Element(ns + "repository")?.Attribute("url")?.Value
};
}

Expand Down

0 comments on commit 5b8ac72

Please sign in to comment.