nunit.analyzers icon indicating copy to clipboard operation
nunit.analyzers copied to clipboard

Option to make a single package version support multiple versions of Roslyn

Open jnm2 opened this issue 2 years ago • 5 comments

StrongInject is gaining the ability to build for both Roslyn 3.8 and 4.0 in the same package: https://github.com/YairHalberstadt/stronginject/pull/181. Another package that does the same thing is https://github.com/reactiveui/refit.

A similar (but not exactly identical) approach could be used to build for both Roslyn 2.x and 3.x (and even 4.x) in one package if you were interested.

The .NET SDK starting with v6 (= VS2022) natively understands how to properly load from .nupkg structures such as analyzers/dotnet/roslyn3.8/cs/nunit.analyzers.dll, and a package .targets file can fill in the gap for earlier versions.

image

Besides the package file structure, this is the entirety of the .targets file needed in order to simultaneously support both Roslyn 3.8 and 4.0. It would need a few tweaks to work for 2.x and 3.x simultaneously:

<Project>

  <!-- Required for supporting .NET SDK < 6 (and VS < 2022) which would otherwise also reference the v4 assembly -->
  <Target Name="_StrongInjectRemoveAnalyzersNotMatchingRoslynVersion"
          Condition="'$(SupportsRoslynComponentVersioning)' != 'true'"
          AfterTargets="ResolvePackageDependenciesForBuild;ResolveNuGetPackageAssets">

    <ItemGroup>
      <Analyzer Remove="@(Analyzer)" Condition="
        '%(Analyzer.NuGetPackageId)' == 'StrongInject'
        and $([System.String]::Copy('%(Analyzer.Identity)').Contains('roslyn4'))"/>
    </ItemGroup>
  </Target>

</Project>

For more on package .targets and .props files:

  • https://docs.microsoft.com/en-us/nuget/create-packages/creating-a-package#from-a-convention-based-working-directory
  • https://docs.microsoft.com/en-us/nuget/create-packages/creating-a-package#include-msbuild-props-and-targets-in-a-package

jnm2 avatar Jan 02 '22 21:01 jnm2

@jnm2 I have used this approach for my company analyzer and it works for switching between 3.x and 4.0 version. How would you update the target to switch between 2.x, 3.x and 4.x? is the Roslyn version known as an msbuild variable?

manfred-brands avatar Feb 03 '22 03:02 manfred-brands

I'd have to look through MSBuild Structured Log Viewer for candidates, but I'm pretty sure I've seen the SDK version itself as a properly and the major versions line up in parallel if all else fails.

jnm2 avatar Feb 03 '22 18:02 jnm2

I think it would be good to have. If also supporting 2.x is too hard, then I think we should leave it behind.

Looking at the download number from nuget we have 584 downloads of version 2.x and 252K downloads of version 3.x. So very few use the analyzers in VS 2017.

mikkelbu avatar Feb 03 '22 18:02 mikkelbu

@mikkelbu I will be working on this. Can you assign it to me (or give me assign limited rights in this repository)?

manfred-brands avatar Feb 27 '22 23:02 manfred-brands

Thanks @manfred-brands. I've assigned the issue to you and I will look into giving you more rights in this repo as you have been the main driving force the last couple of years 👍

mikkelbu avatar Feb 28 '22 21:02 mikkelbu