Skip to content

Commit 9e93c70

Browse files
T-GroCopilot
andcommitted
Fix packaging of design-time providers referenced via ProjectReference
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d31c517 commit 9e93c70

4 files changed

Lines changed: 40 additions & 29 deletions

File tree

docs/release-notes/.FSharp.Compiler.Service/11.0.100.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
### Fixed
22

3+
* Restore packaging of an F# design-time type provider that is activated via a `ProjectReference` carrying `IsFSharpDesignTimeProvider="true"`. The provider assembly is again included under `fsharp41` when packing (including `pack --no-build`); `PackageFSharpDesignTimeTools` now resolves the provider via `GetTargetPath`, which works in `dotnet pack`'s `BuildProjectReferences=false` content build without forcing an early `ResolveReferences`. ([Issue #18924](https://github.com/dotnet/fsharp/issues/18924), [PR #19979](https://github.com/dotnet/fsharp/pull/19979))
34
* Tooltip "Full name" now shows demangled companion module names (e.g. `MyType.func` instead of `MyTypeModule.func`). ([Issue #17335](https://github.com/dotnet/fsharp/issues/17335), [PR #19867](https://github.com/dotnet/fsharp/pull/19867))
45
* Fix internal error (FS0193) when calling an indexed property setter with a named argument that matches an indexer parameter. ([Issue #16034](https://github.com/dotnet/fsharp/issues/16034), [PR #19851](https://github.com/dotnet/fsharp/pull/19851))
56
* Fix missing FS1182 ("unused binding") warning for unused `let` function bindings inside class types. ([Issue #13849](https://github.com/dotnet/fsharp/issues/13849), [PR #19805](https://github.com/dotnet/fsharp/pull/19805))

src/FSharp.Build/Microsoft.FSharp.NetSdk.targets

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,23 +49,11 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
4949
<PackProjectInputFile>$(MSBuildProjectFullPath)</PackProjectInputFile>
5050
</PropertyGroup>
5151

52-
<!-- Gate inclusion of PackageFSharpDesignTimeTools target when design-time provider is present -->
53-
<PropertyGroup Condition=" '$(IsFSharpDesignTimeProvider)' == 'true' ">
52+
<!-- Register unconditionally at eval time (NuGet fixes the TargetsForTfmSpecificContentInPackage schedule before any target runs); the target's own Condition gates execution. -->
53+
<PropertyGroup>
5454
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);PackageFSharpDesignTimeTools</TargetsForTfmSpecificContentInPackage>
5555
</PropertyGroup>
5656

57-
<!-- Check for design-time provider references and add target if needed -->
58-
<!-- This target attempts to update TargetsForTfmSpecificContentInPackage based on reference metadata -->
59-
<Target Name="_CheckForDesignTimeProviderReferences" BeforeTargets="GenerateNuspec" Condition=" '$(IsFSharpDesignTimeProvider)' != 'true' ">
60-
<ItemGroup>
61-
<_FSharpDesignTimeProviderProject Include="@(ProjectReference)" Condition="'%(ProjectReference.IsFSharpDesignTimeProvider)' == 'true'" />
62-
<_FSharpDesignTimeProviderPackage Include="@(PackageReference)" Condition="'%(PackageReference.IsFSharpDesignTimeProvider)' == 'true'" />
63-
</ItemGroup>
64-
<PropertyGroup Condition=" '@(_FSharpDesignTimeProviderProject)' != '' or '@(_FSharpDesignTimeProviderPackage)' != '' ">
65-
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);PackageFSharpDesignTimeTools</TargetsForTfmSpecificContentInPackage>
66-
</PropertyGroup>
67-
</Target>
68-
6957
<PropertyGroup Condition=" '$(DisableImplicitLibraryPacksFolder)' != 'true' ">
7058
<RestoreAdditionalProjectSources Condition="Exists('$(_FSharpCoreLibraryPacksFolder)')">$(RestoreAdditionalProjectSources);$(_FSharpCoreLibraryPacksFolder)</RestoreAdditionalProjectSources>
7159
</PropertyGroup>
@@ -78,7 +66,9 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
7866
</ItemGroup>
7967
</Target>
8068

81-
<Target Name="PackageFSharpDesignTimeTools" AfterTargets="ResolveReferences">
69+
<!-- Pack-only (run via TargetsForTfmSpecificContentInPackage, no AfterTargets); execution-time Condition skips non-providers. -->
70+
<Target Name="PackageFSharpDesignTimeTools"
71+
Condition="'$(IsFSharpDesignTimeProvider)' == 'true' or '@(ProjectReference->WithMetadataValue('IsFSharpDesignTimeProvider', 'true'))' != ''">
8272
<PropertyGroup>
8373
<FSharpDesignTimeProtocol Condition = " '$(FSharpDesignTimeProtocol)' == '' ">fsharp41</FSharpDesignTimeProtocol>
8474
<FSharpToolsDirectory Condition = " '$(FSharpToolsDirectory)' == '' ">tools</FSharpToolsDirectory>
@@ -87,12 +77,19 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
8777
<Error Text="'$(FSharpToolsDirectory)' is an invalid value for 'FSharpToolsDirectory' valid values are 'typeproviders' and 'tools'." Condition="'$(FSharpToolsDirectory)' != 'typeproviders' and '$(FSharpToolsDirectory)' != 'tools'" />
8878
<Error Text="The 'FSharpDesignTimeProtocol' property can be only 'fsharp41'" Condition="'$(FSharpDesignTimeProtocol)' != 'fsharp41'" />
8979

80+
<!-- pack uses BuildProjectReferences=false (=> _ResolvedProjectReferencePaths empty); GetTargetPath reads each provider's already-built path without building it (no NETSDK1085) or forcing an early ResolveReferences. -->
81+
<MSBuild Projects="@(ProjectReference->WithMetadataValue('IsFSharpDesignTimeProvider', 'true'))"
82+
Targets="GetTargetPath"
83+
RemoveProperties="TargetFramework">
84+
<Output TaskParameter="TargetOutputs" ItemName="_FSharpDesignTimeProviderPath" />
85+
</MSBuild>
86+
9087
<ItemGroup>
9188
<_ResolvedOutputFiles
92-
Include="%(_ResolvedProjectReferencePaths.RootDir)%(_ResolvedProjectReferencePaths.Directory)/**/*"
93-
Exclude="%(_ResolvedProjectReferencePaths.RootDir)%(_ResolvedProjectReferencePaths.Directory)/**/FSharp.Core.dll;%(_ResolvedProjectReferencePaths.RootDir)%(_ResolvedProjectReferencePaths.Directory)/**/System.ValueTuple.dll"
94-
Condition="'%(_ResolvedProjectReferencePaths.IsFSharpDesignTimeProvider)' == 'true'">
95-
<NearestTargetFramework>%(_ResolvedProjectReferencePaths.NearestTargetFramework)</NearestTargetFramework>
89+
Condition="'@(_FSharpDesignTimeProviderPath)' != ''"
90+
Include="%(_FSharpDesignTimeProviderPath.RootDir)%(_FSharpDesignTimeProviderPath.Directory)/**/*"
91+
Exclude="%(_FSharpDesignTimeProviderPath.RootDir)%(_FSharpDesignTimeProviderPath.Directory)/**/FSharp.Core.dll;%(_FSharpDesignTimeProviderPath.RootDir)%(_FSharpDesignTimeProviderPath.Directory)/**/System.ValueTuple.dll">
92+
<NearestTargetFramework>$(TargetFramework)</NearestTargetFramework>
9693
</_ResolvedOutputFiles>
9794

9895
<_ResolvedOutputFiles

tests/EndToEndBuildTests/DesignTimeProviderPackaging/TestDesignTimeProviderPackaging.cmd

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ echo [Test 2] PASSED: Provider test passed
8484

8585
echo.
8686
echo === Test 3: Host with ProjectReference to Provider ===
87-
echo [Test 3] Packing Host with ProjectReference to Provider...
88-
echo [Test 3] Note: This tests experimental execution-time reference checking
87+
echo [Test 3] Packing Host that activates a design-time provider via ProjectReference metadata...
8988
echo [Test 3] Command: dotnet pack Host\Host.fsproj -o %~dp0artifacts -c %configuration% -v minimal -bl:%~dp0artifacts\host.binlog -p:FSharpTestCompilerVersion=coreclr
9089
dotnet pack Host\Host.fsproj -o %~dp0artifacts -c %configuration% -v minimal -bl:%~dp0artifacts\host.binlog -p:FSharpTestCompilerVersion=coreclr
9190
if ERRORLEVEL 1 (
@@ -94,9 +93,17 @@ if ERRORLEVEL 1 (
9493
goto :failure
9594
)
9695

97-
rem Note: This test may not work as expected due to MSBuild evaluation phase limitations
98-
rem The current implementation only checks IsFSharpDesignTimeProvider property directly
99-
echo [Test 3] PASSED: Host test completed (implementation limitation noted - may not check references correctly)
96+
rem Check that tools folder exists in nupkg (provider activated via ProjectReference IsFSharpDesignTimeProvider metadata)
97+
echo [Test 3] Checking that package contains tools/fsharp41 folder...
98+
powershell -command "& { Add-Type -AssemblyName System.IO.Compression.FileSystem; $zip = [System.IO.Compression.ZipFile]::OpenRead('%~dp0artifacts\Host.1.0.0.nupkg'); $hasTools = $zip.Entries | Where-Object { $_.FullName -like 'tools/fsharp41/*' }; if ($hasTools) { exit 0 } else { exit 1 } }"
99+
if ERRORLEVEL 1 (
100+
echo [Test 3] FAILED: Package does not contain tools/fsharp41 folder
101+
echo [Test 3] Expected: provider referenced via ProjectReference should be packaged
102+
echo [Test 3] Actual: No tools/fsharp41 folder found in Host.1.0.0.nupkg
103+
goto :failure
104+
)
105+
106+
echo [Test 3] PASSED: Host (ProjectReference gesture) test passed
100107

101108
echo.
102109
echo === Test 4: Pack with --no-build (No Provider) ===

tests/EndToEndBuildTests/DesignTimeProviderPackaging/TestDesignTimeProviderPackaging.sh

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,24 @@ echo "[Test 2] PASSED: Provider test passed"
7373

7474
echo
7575
echo "=== Test 3: Host with ProjectReference to Provider ==="
76-
echo "[Test 3] Packing Host with ProjectReference to Provider..."
77-
echo "[Test 3] Note: This tests experimental execution-time reference checking"
76+
echo "[Test 3] Packing Host that activates a design-time provider via ProjectReference metadata..."
7877
echo "[Test 3] Command: dotnet pack Host/Host.fsproj -o artifacts -c $configuration -v minimal -bl:artifacts/host.binlog -p:FSharpTestCompilerVersion=coreclr"
7978
if ! dotnet pack Host/Host.fsproj -o artifacts -c $configuration -v minimal -bl:artifacts/host.binlog -p:FSharpTestCompilerVersion=coreclr; then
8079
echo "[Test 3] FAILED: Pack command returned error code $?"
8180
echo "[Test 3] Check artifacts/host.binlog for details"
8281
exit 1
8382
fi
8483

85-
# Note: This test may not work as expected due to MSBuild evaluation phase limitations
86-
# The current implementation only checks IsFSharpDesignTimeProvider property directly
87-
echo "[Test 3] PASSED: Host test completed (implementation limitation noted - may not check references correctly)"
84+
# Check that tools folder exists in nupkg (provider activated via ProjectReference IsFSharpDesignTimeProvider metadata)
85+
echo "[Test 3] Checking that package contains tools/fsharp41 folder..."
86+
if ! unzip -l artifacts/Host.1.0.0.nupkg | grep -q "tools/fsharp41/"; then
87+
echo "[Test 3] FAILED: Package does not contain tools/fsharp41 folder"
88+
echo "[Test 3] Expected: provider referenced via ProjectReference should be packaged"
89+
echo "[Test 3] Actual: No tools/fsharp41 folder found in Host.1.0.0.nupkg"
90+
exit 1
91+
fi
92+
93+
echo "[Test 3] PASSED: Host (ProjectReference gesture) test passed"
8894

8995
echo
9096
echo "=== Test 4: Pack with --no-build (No Provider) ==="

0 commit comments

Comments
 (0)