Skip to content

Commit

Permalink
added ability to validate mapped library info (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmcdavid authored Jun 6, 2020
1 parent 1416124 commit 20fce8a
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 29 deletions.
33 changes: 23 additions & 10 deletions src/InvalidLicensesException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,34 @@

namespace NugetUtility
{
public class InvalidLicensesException : Exception
public class InvalidLicensesException<T> : Exception
{
public InvalidLicensesException(ValidationResult validationResult, ICollection<string> allowedLicenses) : base(GetMessage(validationResult, allowedLicenses))
public InvalidLicensesException(IValidationResult<T> validationResult, ICollection<string> allowedLicenses)
: base(GetMessage(validationResult, allowedLicenses))
{
}
}

private static string GetMessage(ValidationResult validationResult, ICollection<string> allowedLicenses)
private static string GetMessage(IValidationResult<T> validationResult, ICollection<string> allowedLicenses)
{
allowedLicenses = allowedLicenses ?? Array.Empty<string>();
allowedLicenses ??= Array.Empty<string>();
var message = $"Only the following packages are allowed: {string.Join(", ", allowedLicenses.ToArray())}{Environment.NewLine}";

if (validationResult is IValidationResult<KeyValuePair<string, Package>> packageValidation)
{
return message + string.Join(Environment.NewLine, packageValidation.InvalidPackages.Select(x =>
{
return $"Project ({x.Key}) Package({x.Value.Metadata.Id}-{x.Value.Metadata.Version}) LicenseUrl({x.Value.Metadata.LicenseUrl}) License Type ({x.Value.Metadata.License?.Text})";
}));
}
else if (validationResult is IValidationResult<LibraryInfo> libraryInfos)
{
return message + string.Join(Environment.NewLine, libraryInfos.InvalidPackages.Select(x =>
{
return $"Project ({x.Projects}) Package({x.PackageName}-{x.PackageVersion}) LicenseUrl({x.LicenseUrl}) License Type ({x.LicenseType})";
}));
}

return $"Only the following packages are allowed: {string.Join(", ", allowedLicenses.ToArray())}{Environment.NewLine}"
+ string.Join(Environment.NewLine, validationResult.InvalidPackages.Select(x =>
{
return $"Project ({x.Key}) Package({x.Value.Metadata.Id}-{x.Value.Metadata.Version}) LicenseUrl({x.Value.Metadata.LicenseUrl}) License Type ({x.Value.Metadata.License?.Text})";
}));
return message;
}
}
}
50 changes: 41 additions & 9 deletions src/Methods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml.Serialization;
Expand Down Expand Up @@ -336,11 +337,11 @@ public void SaveAsTextFile(List<LibraryInfo> libraries)
File.WriteAllText(GetOutputFilename("licences.txt"), sb.ToString());
}

public ValidationResult ValidateLicenses(Dictionary<string, PackageList> projectPackages)
public IValidationResult<KeyValuePair<string, Package>> ValidateLicenses(Dictionary<string, PackageList> projectPackages)
{
if (_packageOptions.AllowedLicenseType.Count == 0)
{
return new ValidationResult { IsValid = true };
return new ValidationResult<KeyValuePair<string,Package>> { IsValid = true };
}

WriteOutput(() => $"Starting {nameof(ValidateLicenses)}...", logLevel: LogLevel.Verbose);
Expand Down Expand Up @@ -379,7 +380,38 @@ public ValidationResult ValidateLicenses(Dictionary<string, PackageList> project
}))
.ToList();

return new ValidationResult { IsValid = invalidPackages.Count == 0, InvalidPackages = invalidPackages };
return new ValidationResult<KeyValuePair<string, Package>> { IsValid = invalidPackages.Count == 0, InvalidPackages = invalidPackages };
}

public ValidationResult<LibraryInfo> ValidateLicenses(List<LibraryInfo> projectPackages)
{
if (_packageOptions.AllowedLicenseType.Count == 0)
{
return new ValidationResult<LibraryInfo> { IsValid = true };
}

WriteOutput(() => $"Starting {nameof(ValidateLicenses)}...", logLevel: LogLevel.Verbose);
var invalidPackages = projectPackages
.Where(p => !_packageOptions.AllowedLicenseType.Any(allowed =>
{
if (p.LicenseUrl is string licenseUrl)
{
if (_licenseMappings.TryGetValue(licenseUrl, out var license))
{
return allowed == license;
}

if (p.LicenseUrl?.Contains(allowed, StringComparison.OrdinalIgnoreCase) == true)
{
return true;
}
}

return allowed == p.LicenseType;
}))
.ToList();

return new ValidationResult<LibraryInfo> { IsValid = invalidPackages.Count == 0, InvalidPackages = invalidPackages };
}

private async Task<T> GetNuGetPackageFileResult<T>(string packageName, string versionNumber, string fileInPackage)
Expand All @@ -389,7 +421,7 @@ private async Task<T> GetNuGetPackageFileResult<T>(string packageName, string ve
var fallbackEndpoint = new Uri(string.Format(fallbackPackageUrl, packageName, versionNumber));
WriteOutput(() => "Attempting to download: " + fallbackEndpoint.ToString(), logLevel: LogLevel.Verbose);
using (var packageRequest = new HttpRequestMessage(HttpMethod.Get, fallbackEndpoint))
using (var packageResponse = await _httpClient.SendAsync(packageRequest))
using (var packageResponse = await _httpClient.SendAsync(packageRequest, CancellationToken.None))
{
if (!packageResponse.IsSuccessStatusCode)
{
Expand Down Expand Up @@ -493,9 +525,9 @@ private string GetOutputDirectory()
/// <returns></returns>
private IEnumerable<string> GetProjectReferencesFromNewProjectFile(string projectPath)
{
var projDefinition = XDocument.Load(projectPath);
// Uses an XPath instead of direct navigation (using Elements("…")) as the project file may use xml namespaces
var projDefinition = XDocument.Load(projectPath);

// Uses an XPath instead of direct navigation (using Elements("…")) as the project file may use xml namespaces
return projDefinition
?.XPathSelectElements("/*[local-name()='Project']/*[local-name()='ItemGroup']/*[local-name()='PackageReference']")
?.Select(refElem => (refElem.Attribute("Include") == null ? "" : refElem.Attribute("Include").Value) + "," +
Expand Down Expand Up @@ -657,8 +689,8 @@ private string CorrectUri(string uri)
if (!IsGithub(uri))
{
return uri;
}
}

if (uri.Contains("/blob/", StringComparison.Ordinal))
{
uri = uri.Replace("/blob/", "/raw/", StringComparison.Ordinal);
Expand Down
10 changes: 10 additions & 0 deletions src/Model/IValidationResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;

namespace NugetUtility
{
public interface IValidationResult<T>
{
bool IsValid { get; }
IReadOnlyCollection<T> InvalidPackages { get; }
}
}
4 changes: 2 additions & 2 deletions src/Model/ValidationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace NugetUtility
{
public class ValidationResult
public class ValidationResult<T> : IValidationResult<T>
{
public bool IsValid { get; set; } = false;

public IReadOnlyCollection<KeyValuePair<string, Package>> InvalidPackages { get; set; } = new List<KeyValuePair<string, Package>>();
public IReadOnlyCollection<T> InvalidPackages { get; set; } = new List<T>();
}
}
2 changes: 1 addition & 1 deletion src/NugetUtility.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<RepositoryType>git</RepositoryType>
<PackageId>dotnet-project-licenses</PackageId>
<ToolCommandName>dotnet-project-licenses</ToolCommandName>
<Version>2.1.0</Version>
<Version>2.2.0</Version>
<Authors>Tom Chavakis</Authors>
<Company>-</Company>
<Title>.NET Core Tool to print a list of the licenses of a projects</Title>
Expand Down
8 changes: 4 additions & 4 deletions src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ private static async Task<int> Execute(PackageOptions options)

Methods methods = new Methods(options);
var projectsWithPackages = await methods.GetPackages();
HandleInvalidLicenses(methods, projectsWithPackages, options.AllowedLicenseType);
var mappedLibraryInfo = methods.MapPackagesToLibraryInfo(projectsWithPackages);
HandleInvalidLicenses(methods, mappedLibraryInfo, options.AllowedLicenseType);

if (options.ExportLicenseTexts)
{
Expand All @@ -54,13 +54,13 @@ private static async Task<int> Execute(PackageOptions options)
return 0;
}

private static void HandleInvalidLicenses(Methods methods, Dictionary<string, PackageList> projectsWithPackages, ICollection<string> allowedLicenseType)
private static void HandleInvalidLicenses(Methods methods, List<LibraryInfo> libraries, ICollection<string> allowedLicenseType)
{
var invalidPackages = methods.ValidateLicenses(projectsWithPackages);
var invalidPackages = methods.ValidateLicenses(libraries);

if (!invalidPackages.IsValid)
{
throw new InvalidLicensesException(invalidPackages, allowedLicenseType);
throw new InvalidLicensesException<LibraryInfo>(invalidPackages, allowedLicenseType);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions tests/NugetUtility.Tests/InvalidLicenseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class InvalidLicenseTests
[Test]
public void Should_Format_Exceptions_On_NewLines_With_Allowed_Header(bool hasAllowed)
{
var result = new ValidationResult
var result = new ValidationResult<KeyValuePair<string,Package>>
{
IsValid = false,
InvalidPackages = new List<KeyValuePair<string, Package>>
Expand All @@ -25,7 +25,7 @@ public void Should_Format_Exceptions_On_NewLines_With_Allowed_Header(bool hasAll
new KeyValuePair<string, Package>(@"c:\some\project.csproj",new Package{ Metadata = new Metadata { Id = "BadLicense3", Version = "0.1.0"} }),
}
};
var exception = new InvalidLicensesException(result, !hasAllowed ? null : new List<string> { "MIT" });
var exception = new InvalidLicensesException<KeyValuePair<string,Package>>(result, !hasAllowed ? null : new List<string> { "MIT" });

exception.Should().NotBeNull();
exception.Message.Split(Environment.NewLine)
Expand Down
2 changes: 1 addition & 1 deletion tests/NugetUtility.Tests/ProgramTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public async Task Main_Should_Throw_When_InvalidLicenses(string args)
{
Func<Task> act = async () => await Program.Main(args.Split(' '));

await act.Should().ThrowExactlyAsync<InvalidLicensesException>();
await act.Should().ThrowExactlyAsync<InvalidLicensesException<LibraryInfo>>();
}

[Test]
Expand Down

0 comments on commit 20fce8a

Please sign in to comment.