Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically pack dependencies satellite resources for private packages #342

Merged
merged 1 commit into from
Mar 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ Whether items are packed by default or not is controlled by properties named aft
| PackBuildOutput | true |
| PackReadme | true |
| PackSymbols | true if PackBuildOutput=true (*) |
| PackDependencies| empty (**) |
| PackSatelliteDlls | true if PackBuildOutput=true (**) |
| PackDependencies| empty (***) |
| PackFrameworkReferences | true if PackFolder=lib, false if PackDependencies=false |
| PackProjectReferences | true |

Expand All @@ -239,7 +240,10 @@ Whether items are packed by default or not is controlled by properties named aft
\* Back in the day, PDBs were Windows-only and fat files. Nowadays, portable PDBs
(the new default) are lightweight and can even be embedded. Combined with [SourceLink](https://github.com/dotnet/sourcelink), including them in the package (either standalone or embeded) provides the best experience for your users, so it's the default.

\** In some scenarios, you might want to turn off packing behavior for all PackageReference and FrameworkReferences alike. Setting PackDependencies=false achieves that.
\** Satellite resources can come from the main project or from dependencies, if those PackageReferences
have `PrivateAssets=all`.

\*** In some scenarios, you might want to turn off packing behavior for all PackageReference and FrameworkReferences alike. Setting PackDependencies=false achieves that.


The various supported item inference are surfaced as `<PackInference Include="Compile;Content;None;..." />` items, which are ultimately evaluated together with the metadata for the individual items. These make the package inference candidates. You can also provide an exclude expression for that evaluation so that certain items are excluded by default, even if every other item of the same type is included. For example, to pack all `Content` items, except those in the `docs` folder, you can simply update the inference item like so:
Expand Down
52 changes: 37 additions & 15 deletions src/NuGetizer.Tasks/NuGetizer.Inference.targets
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ Copyright (c) .NET Foundation. All rights reserved.

<!-- Whether to include @(Content) items with CopyToOutputDirectory != '' in the package -->
<PackContent Condition="'$(PackContent)' == ''">true</PackContent>

<!-- Whether to include @(BuiltProjectOutputGroupOutput), @(DocumentationProjectOutputGroupOutput) and @(SatelliteDllsProjectOutputGroupOutput) items in the package -->
<!-- When packing as a tool (SDK compatibility mode), primary output should not be packed by us, since the SDK PackTool target will already collect the output of /publish instead. -->
<PackBuildOutput Condition="'$(PackBuildOutput)' == '' and '$(IsPackagingProject)' != 'true' and '$(PackAsTool)' != 'true'">true</PackBuildOutput>


<!-- Whether to @(SatelliteDllsProjectOutputGroupOutput) items in the package. Used when inferring for PackBuildOutput=true -->
<PackSatelliteDlls Condition="'$(PackSatelliteDlls)' == '' and '$(PackBuildOutput)' == 'true'">true</PackSatelliteDlls>

<!-- Whether to include @(DebugSymbolsProjectOutputGroupOutput) items in the package -->
<PackSymbols Condition="'$(PackSymbols)' == '' and '$(PackBuildOutput)' == 'true'">true</PackSymbols>

Expand Down Expand Up @@ -187,7 +190,7 @@ Copyright (c) .NET Foundation. All rights reserved.
_SetPackTargetFramework;
InferPackageContents
</GetPackageContentsDependsOn>

</PropertyGroup>

<Target Name="_SetDefaultPackageReferencePack" Condition="'$(PackFolder)' == 'build' or '$(PackFolder)' == 'buildTransitive'"
Expand Down Expand Up @@ -215,15 +218,15 @@ Copyright (c) .NET Foundation. All rights reserved.
PackagePath="%(None.Link)"
Condition="%(None.Identity) == '$(PackageIcon)' or %(None.Link) == '$(PackageIcon)'" />

<Content Update="@(Content)"
<Content Update="@(Content)"
Pack="true"
BuildAction="None"
PackFolder="None"
PackagePath="%(Content.Link)"
Condition="%(Content.Identity) == '$(PackageIcon)' or %(Content.Link) == '$(PackageIcon)'" />
PackagePath="%(Content.Link)"
Condition="%(Content.Identity) == '$(PackageIcon)' or %(Content.Link) == '$(PackageIcon)'" />
</ItemGroup>
</Target>

<Target Name="_CollectInferenceCandidates" Inputs="@(PackInference)" Outputs="|%(PackInference.Identity)|">
<PropertyGroup>
<PackExclude>%(PackInference.PackExclude)</PackExclude>
Expand Down Expand Up @@ -295,7 +298,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<PackageIconFilename Condition="'$(PackageIconExists)' == 'true'">@(_PackageIcon -> '%(Filename)')</PackageIconFilename>
<PackageIconExtension Condition="'$(PackageIconExists)' == 'true'">@(_PackageIcon -> '%(Extension)')</PackageIconExtension>
</PropertyGroup>

<!-- Even if all these conditions are false, the user can still explicitly pack the icon file, of course -->
<ItemGroup Label="Icon" Condition="'$(PackageIcon)' != ''">
<_ExistingIcon Include="@(None -> WithMetadataValue('Filename', '$(PackageReadmeFilename)'))" />
Expand All @@ -308,7 +311,7 @@ Copyright (c) .NET Foundation. All rights reserved.
PackagePath="%(Filename)%(Extension)"
Condition="'%(Extension)' == '$(PackageReadmeExtension)'" />
</ItemGroup>

<ItemGroup>
<InferenceCandidate>
<ShouldPack Condition="('%(Pack)' == 'true' or '%(PackagePath)' != '' or '%(PackFolder)' != '' or '%(PackageReference)' != '') and '%(Pack)' != 'false'">true</ShouldPack>
Expand Down Expand Up @@ -348,7 +351,8 @@ Copyright (c) .NET Foundation. All rights reserved.
.NETFramework, the desktop WinFX.targets are imported which don't have the fix, so we need to
do it "the old way" for this particular output group -->
<_SatelliteDllsProjectOutputGroupOutput Include="@(SatelliteDllsProjectOutputGroupOutput)"
FinalOutputPath="%(FullPath)" />
FinalOutputPath="%(FullPath)"
Condition="'$(PackSatelliteDlls)' != 'false'"/>

<_InferredProjectOutput Include="@(BuiltProjectOutputGroupOutput -> '%(FinalOutputPath)');
@(BuiltProjectOutputGroupKeyOutput -> '%(FinalOutputPath)');
Expand All @@ -359,14 +363,23 @@ Copyright (c) .NET Foundation. All rights reserved.
</_InferredProjectOutput>

<_InferredProjectOutput Include="@(DebugSymbolsProjectOutputGroupOutput -> '%(FinalOutputPath)')"
Condition="'$(PackSymbols)' != 'false'">
Condition="'$(PackSymbols)' != 'false'">
<PackFolder>$(PackFolder)</PackFolder>
<FrameworkSpecific>$(BuildOutputFrameworkSpecific)</FrameworkSpecific>
</_InferredProjectOutput>

<_InferredPackageFile Include="@(_InferredProjectOutput -> Distinct())" />
</ItemGroup>

<ItemGroup Label="SatelliteDll Resources from Dependencies" Condition="'$(PackBuildOutput)' == 'true' and '$(PackAsPublish)' != 'true'">
<!-- Include transitive resources if their NuGetPackageId has PrivateAssets=all and Pack!=false only. -->
<_InferredPackageFile Include="@(ResourceCopyLocalItems)"
PackFolder="$(PackFolder)"
TargetPath="%(ResourceCopyLocalItems.DestinationSubPath)"
FrameworkSpecific="$(BuildOutputFrameworkSpecific)"
Condition="$(PrivatePackageReferenceIds.Contains(';%(ResourceCopyLocalItems.NuGetPackageId);'))" />
</ItemGroup>

<ItemGroup Label="Publishable Inference" Condition="'$(PackAsPublish)' == 'true' and '$(PackAsTool)' != 'true'">
<_InferredPublishItem Include="@(PublishItemsOutputGroupOutputs -> '%(OutputPath)')" />
<_InferredPackageFile Include="@(_InferredPublishItem -> '%(FullPath)')">
Expand Down Expand Up @@ -446,8 +459,8 @@ Copyright (c) .NET Foundation. All rights reserved.

</Target>

<Target Name="_CollectPrimaryOutputDependencies"
DependsOnTargets="ReferenceCopyLocalPathsOutputGroup;RunResolvePackageDependencies"
<Target Name="_CollectPrimaryOutputDependencies"
DependsOnTargets="ReferenceCopyLocalPathsOutputGroup;RunResolvePackageDependencies"
Returns="@(ImplicitPackageReference)">
<Error Code="NG1003" Text="Centrally managed package versions is only supported when using the Microsoft.NET.Sdk."
Condition="'$(ManagePackageVersionsCentrally)' == 'true' and '$(UsingMicrosoftNETSdk)' != 'true'" />
Expand All @@ -474,14 +487,23 @@ Copyright (c) .NET Foundation. All rights reserved.
PackageDependencies="@(PackageDependencies)">
<Output TaskParameter="ImplicitPackageReferences" ItemName="ImplicitPackageReference" />
</InferImplicitPackageReference>

<ItemGroup>
<_PrivatePackageReference Include="@(PackageReference)" Condition="%(PackageReference.Pack) != 'false' and '%(PackageReference.PrivateAssets)' == 'all'" />
<_PrivatePackageReference Include="@(ImplicitPackageReference)" Condition="%(PackageReference.Pack) != 'false' and '%(PackageReference.PrivateAssets)' == 'all'" />
</ItemGroup>
<PropertyGroup>
<PrivatePackageReferenceIds>;@(_PrivatePackageReference);</PrivatePackageReferenceIds>
</PropertyGroup>

</Target>

<Target Name="_ResolvePackageDependencies" Condition="'$(UsingMicrosoftNETSdk)' == 'true'" DependsOnTargets="RunResolvePackageDependencies" />

<Target Name="InferPrimaryOutputDependencies"
Condition="'$(PackAsTool)' != 'true' and '$(PackAsPublish)' != 'true'"
Condition="'$(PackAsTool)' != 'true' and '$(PackAsPublish)' != 'true'"
Inputs="@(_PrimaryOutputRelatedFile)"
Outputs="%(_PrimaryOutputRelatedFile.NuGetPackageId)"
Outputs="|%(_PrimaryOutputRelatedFile.NuGetPackageId)|"
Returns="@(_InferredPackageFile)"
DependsOnTargets="_ResolvePackageDependencies;_CollectPrimaryOutputDependencies">

Expand Down
33 changes: 33 additions & 0 deletions src/NuGetizer.Tests/given_packinference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -595,5 +595,38 @@ public void when_direct_and_indirect_packagereference_then_packs_once()
Extension = ".dll",
}));
}

[Fact]
public void when_packing_dependencies_then_includes_satellite_resources_for_private_assets()
{
var result = Builder.BuildProject(
"""
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>true</IsPackable>
<LangVersion>Latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" PrivateAssets="all" />
</ItemGroup>
</Project>
""", output: output);

result.AssertSuccess(output);

Assert.Contains(result.Items, item => item.Matches(new
{
PackagePath = "lib/netstandard2.0/es/Microsoft.CodeAnalysis.CSharp.resources.dll",
}));

Assert.Contains(result.Items, item => item.Matches(new
{
PackagePath = "lib/netstandard2.0/es/Microsoft.CodeAnalysis.resources.dll",
}));
}

}
}