sdk: PackageDefinition metadata seems to be missing

Before upgrading to DotNet Core 2.1.3, the following minimal example worked as expected:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="FSharp.Compiler.Tools" Version="4.0.0.1"/>
  </ItemGroup>
 <Target Name="GetToolFiles">
    <CreateItem Include="@(PackageDefinitions)" Condition="'%(Name)' == 'FSharp.Compiler.Tools'">
      <Output TaskParameter="Include" ItemName="FSharpCompilerToolsRef"/>
    </CreateItem>
    <PropertyGroup>
      <FSharpCompilerTools>@(FSharpCompilerToolsRef->'%(ResolvedPath)')/tools/*.*</FSharpCompilerTools>
    </PropertyGroup>
    <ItemGroup>
      <FSharpFiles Include="$(FSharpCompilerTools)"/>
    </ItemGroup>
  </Target>
  <Target Name="CopyToolsAfterBuild" AfterTargets="Build" DependsOnTargets="GetToolFiles">
    <Copy SourceFiles="@(FSharpFiles)" DestinationFolder="$(OutDir)/FSharp/"/>
  </Target>
</Project>

The expected output would be the contents of the Tools directory under the FSharp.Compiler.Tools would be copied to Debug/netcoreapp2.0/FSharp. Since upgrading to 2.1.300, the %(ResolvedPath) metadata attribute is not being populated with a value, and the result would copy files located in a tools folder off the root of the current drive if one exists. The following lines are written to a detailed output: Copying file from "/tools\file1.txt" to "bin\Debug\netcoreapp2.0\/FSharp/file1.txt".

Modifiying the SDK version using either global.json or uninstalling the most recent versions of DotnetCore (2.1.300), results in the expected files being copied from the source package reference. Copying file from "C:\Users\username\.nuget\packages\fsharp.compiler.tools\4.0.0.1\tools\fsc.exe" to "bin\Debug\netcoreapp2.0\\FSharp\fsc.exe".

I have tested this issue using SDK version 2.1.300 and 2.1.400 and get the same missing metadata, any earlier version seems set the ResolvedPath value to the correct value for the PackageReference

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 15 (12 by maintainers)

Commits related to this issue

Most upvoted comments

Calculating those PackageDefinitions is very expensive so we made a modest breaking change in exchange for vastly improved build performance to stop doing it in every build since it is usually not required. You can request them explicitly by adding a dependency on RunResolvePackageDependencies.

-<Target Name="GetToolFiles">
+<Target Name="GetToolFiles" DependsOnTargets="RunResolvePackageDependencies">

I found that if you add:

  <Target Name="RunResolvePackageDependencies" Condition="'$(RunResolvePackageDependencies)' != ''"/>

It will define a new empty target if it doesn’t already exist, and then it’ll work for both new code and old.

given the proposed work around

<Target Name="GetToolFiles" DependsOnTargets="RunResolvePackageDependencies">

will cause The target "RunResolvePackageDependencies" does not exist in the project in the old csproj format.

So in the context of a extension being consumed by other projects (both old and new csproj formats), how would you propose doing a “DependsOnTargets if exists”?

This is not a great solution. Can we at least fail the build or something? Silently skipping this step, with no warning and breaking builds is not good.