6161 <PackageVersion Include =" SharpFuzz" Version =" 2.2.0" />
6262 <PackageVersion Include =" WinSharpFuzz" Version =" 1.0.0" />
6363 </ItemGroup >
64+ <!--
65+ Serialization project references that are restricted to Tests and Benchmarks projects only.
66+ Verifiable.Json and Verifiable.Cbor are interchangeable serialization layers. Library projects
67+ must not depend on them directly, keeping the core stack serialization-agnostic.
68+ -->
69+ <PropertyGroup >
70+ <RestrictedSerializationProjects >Verifiable.Cbor;Verifiable.Json</RestrictedSerializationProjects >
71+ </PropertyGroup >
6472 <!--
6573 Validates that labeled packages are only referenced in appropriate projects.
6674 Runs after package references are collected but before compilation begins.
8088 -->
8189 <ValidateScopedPackages Condition =" '$(_IsLibraryProject)' == 'true' AND '@(PackageReference)' != ''" ProjectName =" $(MSBuildProjectName)" PackageReferences =" @(PackageReference)" DirectoryPackagesPropsPath =" $(MSBuildThisFileFullPath)" />
8290 </Target >
91+ <!--
92+ Validates that serialization projects (Verifiable.Json, Verifiable.Cbor) are only referenced
93+ by Tests and Benchmarks projects. This enforces a clean architecture boundary where the core
94+ library stack remains serialization-agnostic and consumers choose their serialization layer.
95+ Runs after project references are resolved but before compilation begins.
96+ -->
97+ <Target Name =" ValidateProjectReferences" AfterTargets =" ResolveProjectReferences" Condition =" '$(DesignTimeBuild)' != 'true'" >
98+ <PropertyGroup >
99+ <_IsTestProject Condition =" $(MSBuildProjectName.EndsWith('.Tests'))" >true</_IsTestProject >
100+ <_IsBenchmarkProject Condition =" $(MSBuildProjectName.EndsWith('.Benchmarks'))" >true</_IsBenchmarkProject >
101+ <_IsAllowedToReferenceSerializationProjects Condition =" '$(_IsTestProject)' == 'true' OR '$(_IsBenchmarkProject)' == 'true'" >true</_IsAllowedToReferenceSerializationProjects >
102+ </PropertyGroup >
103+ <ValidateSerializationProjectReferences Condition =" '$(_IsAllowedToReferenceSerializationProjects)' != 'true' AND '@(ProjectReference)' != ''" ProjectName =" $(MSBuildProjectName)" ProjectReferences =" @(ProjectReference)" RestrictedProjects =" $(RestrictedSerializationProjects)" />
104+ </Target >
83105 <!-- Inline Roslyn task for validating package references. Compiled once per build session and cached in memory.-->
84106 <UsingTask TaskName =" ValidateScopedPackages" TaskFactory =" RoslynCodeTaskFactory" AssemblyFile =" $(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
85107 <ParameterGroup >
147169 ]]> </Code >
148170 </Task >
149171 </UsingTask >
172+ <!--
173+ Inline Roslyn task for validating project references to serialization projects.
174+ Ensures that only Tests and Benchmarks projects can reference Verifiable.Json and Verifiable.Cbor.
175+ Compiled once per build session and cached in memory.
176+ -->
177+ <UsingTask TaskName =" ValidateSerializationProjectReferences" TaskFactory =" RoslynCodeTaskFactory" AssemblyFile =" $(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
178+ <ParameterGroup >
179+ <ProjectName Required =" true" />
180+ <ProjectReferences ParameterType =" Microsoft.Build.Framework.ITaskItem[]" Required =" true" />
181+ <RestrictedProjects Required =" true" />
182+ </ParameterGroup >
183+ <Task >
184+ <Using Namespace =" System" />
185+ <Using Namespace =" System.Collections.Generic" />
186+ <Using Namespace =" System.IO" />
187+ <Using Namespace =" System.Linq" />
188+ <Code Type =" Method" Language =" cs" ><![CDATA[
189+ public override bool Execute()
190+ {
191+ //Early exit if no project references.
192+ if(ProjectReferences == null || ProjectReferences.Length == 0)
193+ {
194+ return true;
195+ }
196+
197+ //Parse the semicolon-delimited list of restricted project names.
198+ var restricted = new HashSet<string>(
199+ RestrictedProjects.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries),
200+ StringComparer.OrdinalIgnoreCase);
201+
202+ //Extract project name from each reference path and check against the restricted set.
203+ var violations = new List<string>();
204+ foreach(var projRef in ProjectReferences)
205+ {
206+ var referencedProjectName = Path.GetFileNameWithoutExtension(projRef.ItemSpec);
207+ if(restricted.Contains(referencedProjectName))
208+ {
209+ violations.Add(referencedProjectName);
210+ }
211+ }
212+
213+ if(violations.Count > 0)
214+ {
215+ Log.LogError(
216+ $"Restricted project reference(s) '{string.Join(", ", violations)}' " +
217+ $"found in '{ProjectName}'. " +
218+ "Verifiable.Json and Verifiable.Cbor can only be referenced by Tests and Benchmarks projects.");
219+ return false;
220+ }
221+
222+ return true;
223+ }
224+ ]]> </Code >
225+ </Task >
226+ </UsingTask >
150227</Project >
0 commit comments