Search code examples
c#.netmsbuildnuget

How to prevent the package manager of Visual Studio / Rider from tweaking certain .csproj <PackageReference> elements


Essentially what the subject says. I have certain nuget package references that are meant to be loaded only in simulators for the sake of debugging:

<PackageReference Include="Foo.Bar" Version="1.2.4" Condition=" '$(IsForSimulator)' == 'false' ">

<PackageReference Include="Foo.Bar" Version="1.2.3-force-dud" Condition=" '$(IsForSimulator)' == 'true' ">
            <NoWarn>$(NoWarn);NU1605</NoWarn>
</PackageReference>

If I update the nuget package using the nuget package manager GUI to version 1.2.5, then both elements will be updated!

I want the second one to remain unaffected somehow. Is this possible?


Solution

  • I came up with a method that works but note that if you need to update the -force-dud nuget to a newer version you must do so manually (I don't mind much in my own case since those nugets are meant to cater to the needs of simulators used in internal QA ...)

    1. Sniff whether you're building for a simulator:
    <Target Name="EvaluateWhetherWeAimRealDevicesOrSimulators" BeforeTargets="BeforeBuild">
            <!-- the evaluation of these variables needs to happen late in the build and not at the beginning because RuntimeIdentifier is    -->
            <!-- empty during the early stages of the build                                                                                                          -->
            <PropertyGroup>
                <IsForSimulator Condition=" '$(RuntimeIdentifier.Contains(simulator))' == 'false' ">false</IsForSimulator>
                <IsForSimulator Condition=" '$(RuntimeIdentifier.Contains(simulator))' == 'true'  ">true</IsForSimulator>
            </PropertyGroup>
    </Target>
    
    1. Inside the .csproj keep only this bit
    <!-- it's safer to keep the condition on the item-group (rather on the package-ref element) so that it won't be yanked-off by mistake -->
    <ItemGroup Condition=" '$(IsForSimulator)' == '' or '$(IsForSimulator)' == 'false' ">
         <PackageReference Include="Foo.Bar" Version="1.2.4">
    </ItemGroup>
    
    1. Now create a separate file called 'NugetTweaksForSimulators.targets' and put this in:
    <?xml version="1.0" encoding="utf-8"?>
    
    <!-- the package manager cannot affect these nuget-entries because they're living inside this side-file! -->
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <ItemGroup Condition=" '$(IsForSimulator)' == 'true' ">
        <PackageReference Include="Foo.Bar" Version="1.2.3-force-dud">
           <NoWarn>$(NoWarn);NU1605</NoWarn>
        </PackageReference>
      </ItemGroup>
    </Project>
    
    1. Include the 'NugetTweaksForSimulators.targets' on your main project:
    <Import Project="NugetTweaksForSimulators.targets"/>
    

    Mission accomplished!