Reputation: 4206
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?
Upvotes: 0
Views: 46
Reputation: 4206
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 ...)
<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>
<!-- 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>
<?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>
<Import Project="NugetTweaksForSimulators.targets"/>
Mission accomplished!
Upvotes: 0
Reputation: 5163
This is effectively an addendum to the answer from @XDS that wouldn't fit in a comment.
When a project file is changed by a tool, the tool should evaluate the project, should honor Condition
attributes, and should add or update but not remove content (including attributes).
Unfortunately, NuGet seems to break with this etiquette. I suspect it just parses the XML for PackageReference
and doesn't understand the file content as an MSBuild Project.
The code shown in the answer from @XDS can be streamlined by being changed as follows.
project file
The test for $(IsForSimulator)
can be moved to the Import
.
<ItemGroup>
<PackageReference Include="Foo.Bar" Version="1.2.4">
</ItemGroup>
<Import Project="NugetTweaksForSimulators.targets" Condition="'$(IsForSimulator)' == 'true'"/>
NugetTweaksForSimulators.targets file
The reason the technique of importing a separate file works is because the project is apparently not being evaluated. If the project were evaluated, the Import
would be performed and the content of the NugetTweaksForSimulators.targets would be visible to the package manager.
The NugetTweaksForSimulators.targets file can be more self contained. It doesn't need to know the $(IsForSimulator)
property and it can remove any existing Foo.Bar
PackageReference
before adding the special one for the simulator.
<?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>
<!-- Remove 'Foo.Bar' if it is already in the item collection -->
<PackageReference Remove="Foo.Bar">
<!-- Replace with the version for simulator -->
<PackageReference Include="Foo.Bar" Version="1.2.3-force-dud">
<NoWarn>$(NoWarn);NU1605</NoWarn>
</PackageReference>
</ItemGroup>
</Project>
If there are other changes required for the simulator, they could all be located in the NugetTweaksForSimulators.targets file. Instead of potentially lots of Condition
s in the project, there would be just the one Condition
on the Import
.
Upvotes: 1