Skip to content

Commit

Permalink
(chocolatey-community#37) Implement note rule CPMR0068
Browse files Browse the repository at this point in the history
This implements the note rule CPMR0068 that verifies whether the owners
field matches the authors field or not.

This is equivalent to what is implemented in Package Validator, and
should be enhanced in the future.
  • Loading branch information
AdmiringWorm authored and gep13 committed Dec 5, 2024
1 parent 4355968 commit 82c1b97
Show file tree
Hide file tree
Showing 9 changed files with 206 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
RegisteredServices: {
chocolatey.infrastructure.rules.IMetadataRule: [
Chocolatey.Community.Validation.Rules.AnyElementRules,
Chocolatey.Community.Validation.Rules.AuthorMatchesMaintainerRule,
Chocolatey.Community.Validation.Rules.CopyrightElementRules,
Chocolatey.Community.Validation.Rules.DependenciesElementRules,
Chocolatey.Community.Validation.Rules.DescriptionElementRules,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
RegisteredServices: {
chocolatey.infrastructure.rules.IMetadataRule: [
Chocolatey.Community.Validation.Rules.AnyElementRules,
Chocolatey.Community.Validation.Rules.AuthorMatchesMaintainerRule,
Chocolatey.Community.Validation.Rules.CopyrightElementRules,
Chocolatey.Community.Validation.Rules.DependenciesElementRules,
Chocolatey.Community.Validation.Rules.DescriptionElementRules,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
HelpUrl: https://ch0.co/rules/cpmr0068,
Id: CPMR0068,
Message: The package maintainer field (owners) matches the software author field (authors) in the nuspec.,
Severity: Note
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
HelpUrl: https://ch0.co/rules/cpmr0068,
Id: CPMR0068,
Message: The package maintainer field (owners) matches the software author field (authors) in the nuspec.,
Severity: Note
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
HelpUrl: https://ch0.co/rules/cpmr0068,
Id: CPMR0068,
Message: The package maintainer field (owners) matches the software author field (authors) in the nuspec.,
Severity: Note
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
Severity: Note,
Id: CPMR0068,
Summary: The package maintainer field (owners) matches the software author field (authors) in the nuspec.,
HelpUrl: https://ch0.co/rules/cpmr0068
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
namespace Chocolatey.Community.Validation.Tests.Rules
{
using System.Threading.Tasks;
using chocolatey;
using Chocolatey.Community.Validation.Rules;
using NUnit.Framework;

[Category("Notes")]
public class AuthorMatchesMaintainerRuleTests : RuleTestBase<AuthorMatchesMaintainerRule>
{
[Test]
public async Task ShouldFlagRuleWhenAuthorAndMaintainerIsSame()
{
const string testContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
<!-- Do not remove this test for UTF-8: if “Ω” doesn’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one. -->
<package xmlns=""http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd"">
<metadata>
<id>short-copyright</id>
<title>[Deprecated] Test PKG</title>
<version>1.0.0</version>
<authors>Package-Author</authors>
<owners>Package-Author</owners>
<packageSourceUrl>https://test-url.com/</packageSourceUrl>
</metadata>
<files />
</package>";

await VerifyNuspec(testContent);
}
[Test]
public async Task ShouldFlagRuleWhenAuthorAndMaintainerUsesDifferentCase()
{
const string testContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
<!-- Do not remove this test for UTF-8: if “Ω” doesn’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one. -->
<package xmlns=""http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd"">
<metadata>
<id>short-copyright</id>
<title>[Deprecated] Test PKG</title>
<version>1.0.0</version>
<authors>Package-Author</authors>
<owners>package-author</owners>
<packageSourceUrl>https://test-url.com/</packageSourceUrl>
</metadata>
<files />
</package>";

await VerifyNuspec(testContent);
}

[Test]
public async Task ShouldFlagRuleWhenMultipleSameAuthorsAndMaintainers()
{
const string testContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
<!-- Do not remove this test for UTF-8: if “Ω” doesn’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one. -->
<package xmlns=""http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd"">
<metadata>
<id>short-copyright</id>
<title>[Deprecated] Test PKG</title>
<version>1.0.0</version>
<authors>Package-Author Package-Maintainer</authors>
<owners>Package-Author Package-Maintainer</owners>
<packageSourceUrl>https://test-url.com/</packageSourceUrl>
</metadata>
<files />
</package>";

await VerifyNuspec(testContent);
}

[TestCaseSource(nameof(EmptyTestValues))]
public async Task ShouldNotFlagOnEmptyValues(string value)
{
const string testContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
<!-- Do not remove this test for UTF-8: if “Ω” doesn’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one. -->
<package xmlns=""http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd"">
<metadata>
<id>short-copyright</id>
<title>[Deprecated] Test PKG</title>
<version>1.0.0</version>
<authors>{0}</authors>
<owners>{0}</owners>
<packageSourceUrl>https://test-url.com/</packageSourceUrl>
</metadata>
<files />
</package>";

await VerifyEmptyResults(testContent.FormatWith(value));
}

[Test]
public async Task ShouldNotFlagWhenDifferentMaintanerCountThanAuthors()
{
const string testContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
<!-- Do not remove this test for UTF-8: if “Ω” doesn’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one. -->
<package xmlns=""http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd"">
<metadata>
<id>short-copyright</id>
<title>[Deprecated] Test PKG</title>
<version>1.0.0</version>
<authors>Package-Author</authors>
<owners>Package-Author Package-Maintainer</owners>
<packageSourceUrl>https://test-url.com/</packageSourceUrl>
</metadata>
<files />
</package>";

await VerifyEmptyResults(testContent);
}
}
}
3 changes: 3 additions & 0 deletions src/Chocolatey.Community.Validation/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Chocolatey.Community.Validation.Registration.ChocolateyCCRRegistrationModule.Reg
Chocolatey.Community.Validation.Registration.ChocolateyCCRRegistrationModule.register_dependencies(chocolatey.infrastructure.app.registration.IContainerRegistrator! registrator, chocolatey.infrastructure.app.configuration.ChocolateyConfiguration? configuration) -> void
Chocolatey.Community.Validation.Rules.AnyElementRules
Chocolatey.Community.Validation.Rules.AnyElementRules.AnyElementRules() -> void
Chocolatey.Community.Validation.Rules.AuthorMatchesMaintainerRule
Chocolatey.Community.Validation.Rules.AuthorMatchesMaintainerRule.AuthorMatchesMaintainerRule() -> void
Chocolatey.Community.Validation.Rules.CCRMetadataRuleBase
Chocolatey.Community.Validation.Rules.CCRMetadataRuleBase.CCRMetadataRuleBase() -> void
Chocolatey.Community.Validation.Rules.CopyrightElementRules
Expand All @@ -29,6 +31,7 @@ Chocolatey.Community.Validation.Validations.CommunityRepositoryPushValidation.Co
Chocolatey.Community.Validation.Validations.CommunityRepositoryPushValidation.Validate(chocolatey.infrastructure.app.configuration.ChocolateyConfiguration! config) -> System.Collections.Generic.ICollection<chocolatey.infrastructure.validations.ValidationResult!>!
Chocolatey.Community.Validation.Validations.CommunityRepositoryPushValidation.validate(chocolatey.infrastructure.app.configuration.ChocolateyConfiguration! config) -> System.Collections.Generic.ICollection<chocolatey.infrastructure.validations.ValidationResult!>!
override Chocolatey.Community.Validation.Rules.AnyElementRules.Validate(NuGet.Packaging.NuspecReader! reader) -> System.Collections.Generic.IEnumerable<chocolatey.infrastructure.rules.RuleResult!>!
override Chocolatey.Community.Validation.Rules.AuthorMatchesMaintainerRule.Validate(NuGet.Packaging.NuspecReader! reader) -> System.Collections.Generic.IEnumerable<chocolatey.infrastructure.rules.RuleResult!>!
override Chocolatey.Community.Validation.Rules.CopyrightElementRules.Validate(NuGet.Packaging.NuspecReader! reader) -> System.Collections.Generic.IEnumerable<chocolatey.infrastructure.rules.RuleResult!>!
override Chocolatey.Community.Validation.Rules.DependenciesElementRules.Validate(NuGet.Packaging.NuspecReader! reader) -> System.Collections.Generic.IEnumerable<chocolatey.infrastructure.rules.RuleResult!>!
override Chocolatey.Community.Validation.Rules.DescriptionElementRules.Validate(NuGet.Packaging.NuspecReader! reader) -> System.Collections.Generic.IEnumerable<chocolatey.infrastructure.rules.RuleResult!>!
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
namespace Chocolatey.Community.Validation.Rules
{
using System;
using System.Collections.Generic;
using System.Linq;
using chocolatey.infrastructure.rules;

public sealed class AuthorMatchesMaintainerRule : CCRMetadataRuleBase
{
private const string RuleId = "CPMR0068";

public override IEnumerable<RuleResult> Validate(global::NuGet.Packaging.NuspecReader reader)
{
if (reader is null)
{
throw new ArgumentNullException(nameof(reader));
}

var owners = GetNormalized(reader.GetOwners()).ToArray();
var authors = GetNormalized(reader.GetAuthors()).ToArray();

if (owners.Length != authors.Length || owners.Length == 0)
{
yield break;
}

for (var i = 0; i < owners.Length; i++)
{
if (string.Compare(owners[i], authors[i], StringComparison.OrdinalIgnoreCase) != 0)
{
yield break;
}
}

yield return GetRule(RuleId);
}

protected internal override IEnumerable<(RuleType severity, string? id, string summary)> GetRulesInformation()
{
yield return (RuleType.Note, RuleId, "The package maintainer field (owners) matches the software author field (authors) in the nuspec.");
}

private static IEnumerable<string> GetNormalized(string content)
{
if (string.IsNullOrWhiteSpace(content))
{
yield break;
}

foreach (var owner in content.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries))
{
if (!string.IsNullOrWhiteSpace(owner))
{
yield return owner;
}
}
}
}
}

0 comments on commit 82c1b97

Please sign in to comment.