Skip to content

Commit

Permalink
By default, packing Compile should not include generated files
Browse files Browse the repository at this point in the history
Like the target framework attribute and assembly info.
Additional exclusions should be configurable as needed, so we moved the <PackInference> item to a .props file so the project can update/remove as needed.

This adds another customization point too, allowing to tweak the exclusions for any PackInference (i.e. for Content, EmbeddedResource, None and so on).
  • Loading branch information
kzu committed Oct 21, 2020
1 parent d83509f commit e9430c0
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 19 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,32 @@ 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.

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:

```xml
<ItemGroup>
<PackInference Update="Content" PackExclude="docs/**/*.*" />
</ItemGroup>
```

Of course you could have achieved a similar effect by updating the Content items themselves too instead:

```xml
<ItemGroup>
<Content Update="docs/**/*.*" Pack="false" />
</ItemGroup>
```

By default (see [NuGetizer.Inference.props](src/NuGetizer.Tasks/NuGetizer.Inference.props)), `Compile` has the following exclude expression, so generated intermediate compile files aren't packed:

```xml
<ItemGroup>
<PackInference Include="Compile"
PackExclude="$(IntermediateOutputPath)/**/*$(DefaultLanguageSourceExtension)" />
</ItemGroup>
```


### CopyToOutputDirectory

There is a common metadata item that's used quite frequently: *CopyToOutputDirectory*, which is typically set to *PreserveNewest* to change it from its default behavior (when empty or set to *Never*).
Expand Down
21 changes: 21 additions & 0 deletions src/NuGetizer.Tasks/NuGetizer.Inference.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!--
***********************************************************************************************
NuGetizer.Inference.props
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
created a backup copy. Incorrect changes to this file will make it
impossible to load or build your projects from the command-line or the IDE.
Copyright (c) .NET Foundation. All rights reserved.
***********************************************************************************************
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<ItemGroup>
<PackInference Include="Compile" PackExclude="$(IntermediateOutputPath)/**/*$(DefaultLanguageSourceExtension)" />
<PackInference Include="Content;EmbeddedResource;None;ApplicationDefinition;Page;
Resource;SplashScreen;DesignData;DesignDataWithDesignTimeCreatableTypes;
CodeAnalysisDictionary;AndroidAsset;AndroidResource;BundleResource" />
</ItemGroup>

</Project>
13 changes: 5 additions & 8 deletions src/NuGetizer.Tasks/NuGetizer.Inference.targets
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ Copyright (c) .NET Foundation. All rights reserved.
<Pack Condition="'$(PackBundleResource)' == true">true</Pack>
<BuildAction>BundleResource</BuildAction>
</BundleResource>


<PackInference>
<PackExclude />
</PackInference>
<InferenceCandidate>
<DefaultPackFolder />
<Pack />
Expand Down Expand Up @@ -163,16 +166,10 @@ Copyright (c) .NET Foundation. All rights reserved.
Pack="false" />
</ItemGroup>
</Target>

<ItemGroup>
<PackInference Include="Compile;Content;EmbeddedResource;None;ApplicationDefinition;Page;
Resource;SplashScreen;DesignData;DesignDataWithDesignTimeCreatableTypes;
CodeAnalysisDictionary;AndroidAsset;AndroidResource;BundleResource" />
</ItemGroup>

<Target Name="InferPackageContents" DependsOnTargets="$(InferPackageContentsDependsOn)" Returns="@(PackageFile)">
<ItemGroup>
<InferenceCandidate Include="@(%(PackInference.Identity))" />
<InferenceCandidate Include="@(%(PackInference.Identity))" Exclude="@(%(PackInference.Identity) -> '%(PackExclude)')"/>
<InferenceCandidate>
<ShouldPack Condition="('%(Pack)' == 'true' or '%(PackagePath)' != '' or '%(PackFolder)' != '') and '%(Pack)' != 'false'">true</ShouldPack>
</InferenceCandidate>
Expand Down
1 change: 1 addition & 0 deletions src/NuGetizer.Tasks/NuGetizer.props
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ Copyright (c) .NET Foundation. All rights reserved.
</PropertyGroup>

<Import Project="NuGetizer.Version.props" />
<Import Project="NuGetizer.Inference.props" Condition="'$(EnablePackInference)' != 'false'" />
<Import Project="NuGetizer.Authoring.props" Condition="'$(IsPackagingProject)' == 'true'" />
<Import Project="dotnet-nugetize.props" Condition="'$(dotnet-nugetize)' != ''"/>
</Project>
13 changes: 6 additions & 7 deletions src/NuGetizer.Tests/Builder.NuGetizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using Microsoft.Build.Execution;
using Microsoft.Build.Framework;
using Microsoft.Build.Logging.StructuredLogger;
using NuGet.ProjectManagement;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;
Expand Down Expand Up @@ -77,12 +76,12 @@ public static TargetResult BuildProjects(
}

public static TargetResult BuildScenario(
string scenarioName,
object properties = null,
string projectName = null,
string target = "GetPackageContents",
ITestOutputHelper output = null,
LoggerVerbosity? verbosity = null)
string scenarioName,
object properties = null,
string projectName = null,
string target = "GetPackageContents",
ITestOutputHelper output = null,
LoggerVerbosity? verbosity = null)
{
var scenarioDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Scenarios", scenarioName);
if (projectName != null && !Path.HasExtension(projectName))
Expand Down
4 changes: 4 additions & 0 deletions src/NuGetizer.Tests/Scenarios/Scenario.props
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,9 @@
<NuGetizerTargets>$(NuGetTargetsPath)\NuGetizer.Shared.targets</NuGetizerTargets>
</PropertyGroup>

<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)_._" />
</ItemGroup>

<Import Project="$(NuGetTargetsPath)\NuGetizer.props" Condition="'$(NuGetizerPropsImported)' != 'true'" />
</Project>
4 changes: 0 additions & 4 deletions src/NuGetizer.Tests/Scenarios/Scenario.targets
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
<ScenarioTargetsImported>true</ScenarioTargetsImported>
</PropertyGroup>

<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)_._" />
</ItemGroup>

<Target Name="Report" DependsOnTargets="GetPackageContents">
<Message Importance="high"
Text="%(_PackageContent.RelativeDir)%(_PackageContent.Filename)%(_PackageContent.Extension)
Expand Down
Empty file.
Empty file.
18 changes: 18 additions & 0 deletions src/NuGetizer.Tests/Scenarios/given_a_library/library.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$([MSBuild]::GetPathOfFileAbove(Scenario.props, $(MSBuildThisFileDirectory)))" />
<PropertyGroup>
<AssemblyName>library</AssemblyName>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>true</IsPackable>
<EnableDefaultItems>true</EnableDefaultItems>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<GenerateTargetFrameworkAttribute>true</GenerateTargetFrameworkAttribute>
</PropertyGroup>
<ItemGroup>
<!-- The _._ is added by the scenario targets so that projects aren't entirely empty of compile items -->
<Compile Remove="@(Compile -> WithMetadataValue('Extension', '._'))" />
</ItemGroup>
<ItemGroup Condition="'$(PackOnlyApi)' == 'true'">
<PackInference Update="Compile" PackExclude="%(PackExclude);*.cs" />
</ItemGroup>
</Project>
58 changes: 58 additions & 0 deletions src/NuGetizer.Tests/given_a_library.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System.IO;
using System.Linq;
using System.ServiceModel.Configuration;
using Microsoft.Build.Execution;
using Xunit;
using Xunit.Abstractions;

namespace NuGetizer
{
public class given_a_library
{
ITestOutputHelper output;

public given_a_library(ITestOutputHelper output)
{
this.output = output;
using var disable = OpenBuildLogAttribute.Disable();
Builder.BuildScenario(nameof(given_a_library), target: "Restore")
.AssertSuccess(output);
}

[Fact]
public void when_pack_compile_then_excludes_generated_files()
{
var result = Builder.BuildScenario(nameof(given_a_library),
new { PackCompile = "true" },
target: "Build,GetPackageContents,Pack");

Assert.True(result.BuildResult.HasResultsForTarget("GetPackageContents"));

var items = result.BuildResult.ResultsByTarget["GetPackageContents"];
var compile = items.Items.Where(item => item.Matches(new
{
BuildAction = "Compile",
})).ToArray();

Assert.Equal(2, compile.Length);
}

[Fact]
public void when_pack_excludes_additional_items_then_contains_only_matching_files()
{
var result = Builder.BuildScenario(nameof(given_a_library),
new { PackCompile = "true", PackOnlyApi = "true" },
target: "Build,GetPackageContents,Pack");

Assert.True(result.BuildResult.HasResultsForTarget("GetPackageContents"));

var items = result.BuildResult.ResultsByTarget["GetPackageContents"];
var compile = items.Items.Where(item => item.Matches(new
{
BuildAction = "Compile",
})).ToArray();

Assert.Single(compile);
}
}
}

0 comments on commit e9430c0

Please sign in to comment.