Configuring assets for analyzers packages - c#

My solution consists of multiple projects. In the root we have Directory.Build.props
<Project>
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SonarAnalyzer.CSharp" Version="8.51.0.59060" Condition="$(MSBuildProjectExtension) == '.csproj'">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" Condition="$(MSBuildProjectExtension) == '.csproj'">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
These static code analyzers are using only during development. I see that I can configure assets and prevent exposing these packages. My solution structure:
ServiceA.Api.csproj
ServiceA.Core.csproj
ServiceA.Domain.csproj
ServiceA.Infrastructure.csproj
ServiceA.SDK.csproj
What are the implications for setting PrivateAssets and IncludeAssets in certain ways? What practice for the values of these makes sense in the context of analyzer packages?

If the analyzers are only used for development on the developer's machines, I recommend accepting the package references however NuGet adds them, and then conditionally only including them using the parent <ItemGroup> in your DevOps pipeline. This usually means only include them for Debug but not Release.
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
...
</ItemGroup>
If that is not granular enough (e.g. when you want to build both Debug and Release locally and/or in the pipeline, or you want the analyzers to run during DevOps pipeline exection always), you can take the advice in Controlling dependency assets.
There is no one best practice for this because requirements vary. The defaults are most likely what you should start with because the defaults are chosen for a reason.
The defaults, as mentioned in the content for the above link, are
IncludeAssets --> all
ExcludeAssets --> none
PrivateAssets --> contentfiles;analyzers;build
Unless you are optimizing the size of your final solution, trying to prevent exposure of analyzers to prevent some sort of security issue or misuse, or otherwise trying to avoid some sort of problem, I would say, "just use them as they are, assets set to the values NuGet used when adding the analyzer package".

Related

CompilationAction in Roslyn Analyzer not running on dotnet build

I have created dotnet roslyn analyzer which run on compilation.
[System.Diagnostics.CodeAnalysis.SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1026:Enable concurrent execution", Justification = "<Pending>")]
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.ReportDiagnostics);
context.RegisterCompilationAction(AnalyzeCompilation);
}
I added it as a package to one of our projects, it didn't run.
I figured that i need to allow Entire Solution Analysis in VS2022.
Tools => Options => Text Editor => c# => Analysis => Entire Solution
Visual Studio Entire Solution Analysis feature
After i allowed it, my analyzer working correctly.
I also want it to run in our pipeline, but the analyzer not running on dotnet build .
I am not sure if it's related to Entire Solution which i allowed in VS2022 or not.
we have other analyzer which running correctly on dotnet build.
this is how our Directory.BUild.props file looks.
<Project>
<PropertyGroup>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="16.10.56">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
and Microsoft.VisualStudio.Threading.Analyzers working on dotnet build.
How can i enable my Analyzer which run on ComplilationAction to work on dotnet build like it working in VS2022?

The attribute "Include" in element <PackageReference> is unrecognized

I created a Directory.Build.props file by right clicking the Solution on Solution Explorer, creating an XML file, and named it so. I then input this XML and tried building but was met with errors:
<Project>
<PropertyGroup>
<Version>1.2.3</Version>
<Authors>John Doe</Authors>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</PropertyGroup>
</Project>
The errors say:
The attribute "Include" in element <PackageReference> is unrecognized. and
Project "C:\redacted\Directory.Build.props" was not imported by "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Microsoft.Common.props" at (33,3), due to the file being invalid. ProjectName C:\Users\me\source\redacted\ProjectName\Directory.Build.props 33
I am so confused here. The other articles said to locate the MSBuild and I know that its on my machine. The build was working just fine prior to me adding the XML too. Any guidance would be very appreciated! I am currently on Visual Studio 2022 by the way.
The PackageReference element needs to be in an ItemGroup - you've got it in a PropertyGroup. It should look like this:
<Project>
<PropertyGroup>
<Version>1.2.3</Version>
<Authors>John Doe</Authors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
I had the same kind of problem one time and I found out it was caused by ‘\xef\xbb\xbf#’ which is a ‘Unicode BOM(Byte Order Mark)’ and consists of invisible characters added by certain text editors like Notepad++, for instance. The BOM often functions as a magic number used to pass along information to the program reading the file, such as the Unicode character encoding or endianess but it's presence can interfere with software that does not expect it.
The way I found it by fluke was I had my csproj file on github and when I clicked 'edit', the BOM stuck out like a red dot. I simply backspaced on it and then everything went well.
I came accross the same kind of problem, for me it was due to invalid XML structure :
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.2.32">
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.3">
</PackageReference>
</ItemGroup>
As you can see, the first PackageReference tag was not closed, leading to the exact same error The attribute "Include" in element <PackageReference> is unrecognized. on the second PackageReference tag.
Valid XML structure :
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.2.32"/>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.3"/>
</ItemGroup>
I hope that can help somebody else !

Adding Reference to Class LIbrary in Azure Function project causes assembly not found

I dont really have much to go on here, but I have an Azure Function project (.NET Core 3.1 with Azure Functions v3)
This function has a Http Trigger which works perfectly on its own
However, as soon as I reference one of my existing projects, I get the error
System.Private.CoreLib: Exception while executing function: MyFunction.
FunctionApp2: Could not load file or assembly 'Microsoft.Extensions.Primitives,
Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
Is this related to assembly binding? How can I force this version to be available to my function application?
I dont have a web.config so the standard assembly binding wont work
Below is the file
I have tried adding the assembly directly to the project and that makes no difference
The project I am referencing doesnt have this package either so I am not sure which package this comes from
My function app has the following packages
<ItemGroup>
<PackageReference Include="Fody" Version="6.5.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="LoadAssembliesOnStartup.Fody" Version="4.5.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.ServiceBus" Version="4.3.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.13" />
</ItemGroup>
I tried to use Fody to ensure that the referenced project assembly is loaded on startup but that made no difference
As soon as I remove my other project it works fine
Paul
I found the problem eventually, there is an issue with Redis and Azure Functions
I had to downgrade Redis and it worked

Coverage always at 0% on sonarqube even i added test unit

I created a test unit for a class and it passed well on my local, on sonarqube it is shown as 0% for Coverage, I found post advice to add coverlet.msbuild I added but still no news:
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.0" />
<PackageReference Include="coverlet.msbuild" Version="3.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
Any idea?
Try adding the following to your .csproj
<PropertyGroup>
<DebugType>Full</DebugType>
</PropertyGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="16.9.4" />
Can you try coverlet.collector instead of coverlet.msbuild? I have personally used coverlet collector several times successfully.
<PackageReference Include="coverlet.collector" Version="1.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
According to this GitHub issue.
Collectors are pretty new(last arrived) and are the best way to do coverage because are strictly integrated with vstest platform(dotnet test) and due to that is the default choice for every .NET core xunit project by Microsoft.
So if you create xunit project Microsoft xunit template inject by design our coverage engine as first class coverage tool running with dotnet test --collect:"XPlat Code Coverage"
It may be possible that you are running into this known issue.

Using ANTLR4 in .NET Core without the use of external Java library?

I've followed through these instructions but I get a ton of compilation errors after the files have been compiled.
What I have done:
Created a new Console project in .NET Core 3.1.
Installed NuGet package Antlr4.
Added a new text file named example.g4 to the project, and saved it in encoding UTF-8 without signature.
Populated the grammar with some demo features.
Build Solution.
Ton of errors after successful compilation of lexer/visitor/parser/etc.
Some of those errors include the following:
The name '_interp' does not exist in the current context AntlrDemo C:\AntlrDemo\obj\Debug\netcoreapp3.1\exampleLexer.cs 45 Active
'ParserATNSimulator' does not contain a constructor that takes 2 arguments AntlrDemo C:\AntlrDemo\obj\Debug\netcoreapp3.1\exampleParser.cs 95 Active
'exampleParser.TokenNames': no suitable method found to override AntlrDemo C:\AntlrDemo\obj\Debug\netcoreapp3.1\exampleParser.cs 69 Active
What's going on?
The issue is not from the grammar - it successfully compiles in .NET Framework.
If you don't mind working with the official Antlr4 code generator and runtime, but don't want to actually download and install Java and the Antlr Tool .jar by hand, try this instead:
Install the latest NET 5, or use old NET Core.
dotnet new -i Antlr4BuildTasks.Templates
mkdir Foo
cd Foo
dotnet new antlr
dotnet build
dotnet run
This does use the Antlr4 Java tool, but it's completely hidden. You don't download the runtime, nor Java. It's all contained in the Antlr4BuildTasks tool that you just reference in your .csproj. If you want to work with an older Antlr4 version, like 4.8 or 4.7, Antlr4BuildTasks will download the tool and runtime from Maven Central and NuGet.org; you just set the versions in the .csproj file then "dotnet build".
I have another tool that generates a driver for grammar and support code for C# (both official and Harwell's version), Java, and JavaScript targets. It is now being used for CI in github.com/antlr/grammars-v4.
If you try swapping between Antlr4 (the official Antlr4) and Antlr4cs (Harwell's tool/runtime), you will find the tools and runtime are quite different. There is no shim to allow code written for one runtime to be used in the other, but I am working on one.
As far as the <PrivateAssets> code in the .csproj file, getting rid of the lines as you suggest is fine. The reason it is included is to not propagate the dependent assemblies of the build tool directly into your code. But, while the tool is only useful in building the app, not running it, <PrivateAssets> doesn't prevent the assembly for the tool itself is still being included.
--Ken
After you install Antlr4 NuGet package, the following code is added to your .csproj file:
<ItemGroup>
<PackageReference Include="Antlr4" Version="4.6.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
The fix was to change the above to the following:
<ItemGroup>
<PackageReference Include="Antlr4" Version="4.6.6">
<!--<PrivateAssets>all</PrivateAssets>-->
</PackageReference>
</ItemGroup>
It also seems to work by uncommenting the PrivateAssets element. But I have no idea what the actual problem is here, and if I'm doing something wrong. Can someone shine some light about it?
EDIT: Another alternative solution is to instead install the two NuGet Packages Antlr4.CodeGenerator and Antlr4.Runtime.
Hopefully, this won't cause more confusion. I just moved my C# parser library from NET Framework 4.8 to NET 5 and was able to build it without errors with this .csproj file.
I changed the target framework from net5.0 to net5.0-windows7.0 in the example below to avoid compiler warning CA1416 which protested that I was using debug print methods (based on Console.Writeline calls with param[] arguments) in my code. I wanted to keep my debugging messages so I switched from the net5.0 target.
But the plain 'net5.0' compiled okay for me (except for the warnings I just described). My simple test cases ran fine with net5.0.
Here is an excerpt from my class library file, showing that I could leave the PrivateAssets and IncludeAssets lines alone.
<PropertyGroup>
<!-- use net5.0-windows7.0 to avoid CA1416 warnings about Console Writeline calls only available in win7 and later-->
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Antlr4" Version="4.6.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Antlr4.Runtime" Version="4.6.6" />
</ItemGroup>
Here is an excerpt from my unit test project, showing the inclusion of Antlr4(4.6.6) and the Antlr4.Runtime(4.6.6).
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Antlr4" Version="4.6.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Antlr4.Runtime" Version="4.6.6" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
<PackageReference Include="coverlet.collector" Version="3.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

Categories