Skip to content

Commit

Permalink
[andrewabestGH-87] Added new conventions to enforce that a project re…
Browse files Browse the repository at this point in the history
…ferences/does not reference a package (by name)

An example use-case is something like the coverlet collector (https://github.com/coverlet-coverage/coverlet) which should be added ONLY to (ALL) test projects
  • Loading branch information
eddie.stanley committed Jan 5, 2024
1 parent e160a4c commit ee0b163
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -241,5 +241,45 @@ public void MustNotIncludeProjectReferences_Failure()
result.IsSatisfied.Should().BeFalse();
result.Failures.Single().Should().StartWith("Conventional.Tests includes reference to project");
}

[Test]
public void MustReferencePackage_Success()
{
var result = TheAssembly
.WithNameMatching("SdkClassLibrary1")
.MustConformTo(Convention.MustReferencePackage("coverlet.collector"));

result.IsSatisfied.Should().BeTrue();
}

[Test]
public void MustReferencePackage_Failure()
{
var result = TheAssembly
.WithNameMatching("SdkClassLibrary1")
.MustConformTo(Convention.MustReferencePackage("koverlet.kollector"));

result.IsSatisfied.Should().BeFalse();
}

[Test]
public void MustNotReferencePackage_Success()
{
var result = TheAssembly
.WithNameMatching("SdkClassLibrary1")
.MustConformTo(Convention.MustNotReferencePackage("foo.bar.baz"));

result.IsSatisfied.Should().BeTrue();
}

[Test]
public void MustNotReferencePackage_Failure()
{
var result = TheAssembly
.WithNameMatching("SdkClassLibrary1")
.MustConformTo(Convention.MustNotReferencePackage("coverlet.collector"));

result.IsSatisfied.Should().BeFalse();
}
}
}
10 changes: 10 additions & 0 deletions src/Core/Conventional/Convention.Assembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,15 @@ public static MustBeIncludedInSetOfAssembliesConventionSpecification MustBeInclu

public static MustNotIncludeProjectReferencesConventionSpecification MustNotIncludeProjectReferences =>
new MustNotIncludeProjectReferencesConventionSpecification();

public static MustReferencePackageAssemblyConventionSpecification MustReferencePackage(string packageName)
{
return new MustReferencePackageAssemblyConventionSpecification(packageName);
}

public static MustNotReferencePackageAssemblyConventionSpecification MustNotReferencePackage(string packageName)
{
return new MustNotReferencePackageAssemblyConventionSpecification(packageName);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Linq;
using System.Xml.Linq;

namespace Conventional.Conventions.Assemblies
{
public class MustNotReferencePackageAssemblyConventionSpecification : PackageReferenceAssemblyConventionSpecification
{
private readonly string _needlePackage;

public MustNotReferencePackageAssemblyConventionSpecification(string needlePackage)
{
_needlePackage = needlePackage;
}

protected override ConventionResult IsSatisfiedBy(string assemblyName, XDocument projectDocument)
{
if (GetPackageReferences(projectDocument).Contains(_needlePackage))
{
return ConventionResult.NotSatisfied(assemblyName, string.Format(FailureMessage, assemblyName));
}

return ConventionResult.Satisfied(assemblyName);
}

protected override string FailureMessage => "{0} should not reference package " + _needlePackage;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Linq;
using System.Xml.Linq;

namespace Conventional.Conventions.Assemblies
{
public class MustReferencePackageAssemblyConventionSpecification : PackageReferenceAssemblyConventionSpecification
{
private readonly string _needlePackage;

public MustReferencePackageAssemblyConventionSpecification(string needlePackage)
{
_needlePackage = needlePackage;
}

protected override ConventionResult IsSatisfiedBy(string assemblyName, XDocument projectDocument)
{
if (GetPackageReferences(projectDocument).Contains(_needlePackage))
{
return ConventionResult.Satisfied(assemblyName);
}

return ConventionResult.NotSatisfied(assemblyName, string.Format(FailureMessage, assemblyName));
}

protected override string FailureMessage => "{0} should reference package " + _needlePackage;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;

namespace Conventional.Conventions.Assemblies
{
public abstract class PackageReferenceAssemblyConventionSpecification : AssemblyConventionSpecification
{
protected IEnumerable<string> GetPackageReferences(XDocument projectDocument)
{
return projectDocument.XPathSelectElements("/Project/ItemGroup/PackageReference")
.Select(referenceElement => referenceElement.Attribute("Include")?.Value)
.Where(value => value != null);
}

protected override ConventionResult IsSatisfiedByLegacyCsprojFormat(string assemblyName, XDocument projectDocument)
{
return IsSatisfiedBy(assemblyName, projectDocument);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestSolution.TestProject",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProjectTwo", "..\TestProjectTwo\TestProjectTwo.csproj", "{DA39482D-C4B4-41B8-9908-BF715AE9DD7C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SdkClassLibrary1", "SdkClassLibrary1\SdkClassLibrary1.csproj", "{C0988207-0023-4364-BFE0-04F8954501C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -21,6 +23,10 @@ Global
{DA39482D-C4B4-41B8-9908-BF715AE9DD7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA39482D-C4B4-41B8-9908-BF715AE9DD7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA39482D-C4B4-41B8-9908-BF715AE9DD7C}.Release|Any CPU.Build.0 = Release|Any CPU
{C0988207-0023-4364-BFE0-04F8954501C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0988207-0023-4364-BFE0-04F8954501C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0988207-0023-4364-BFE0-04F8954501C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0988207-0023-4364-BFE0-04F8954501C4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit ee0b163

Please sign in to comment.