diff --git a/readme.md b/readme.md index 5fa1e652..bd0bbc58 100644 --- a/readme.md +++ b/readme.md @@ -445,6 +445,7 @@ You can also add a reference to a CLI *tools* program like the following: net6.0 + Exe tools false @@ -465,6 +466,20 @@ content inference. This section contains miscellaneous useful features that are typically used in advanced scenarios and are not necessarily mainstream. +### PackAsPublish for CLI tools + +When a project's output type is `Exe` and it's not set to `PackAsTool=true` (used specifically for .NET tools), +it will default to be use the `Publish` output for packing. This is typically what you want for a CLI +project, since dependencies are included in the publish directory automatically without having to annotate +any references with `PrivateAssets=all`. + +This can be turned off by setting `PackAsPublish=false` on the project, which will cause the project +to be packed as a regular class library, with the dependencies inference rules applied (such as +`PrivateAssets=all` for package reference and `CopyLocal=true` for references). + +When packing as publish, the output won't be framework-specific by default, and will just contribute +the published contents to the specified `PackFolder`. + ### Dynamically Extending Package Contents If you need to calculate additional items to inject into the package dynamically, you can run a target diff --git a/src/NuGetizer.Tasks/NuGetizer.Inference.targets b/src/NuGetizer.Tasks/NuGetizer.Inference.targets index 3c85598a..3a801550 100644 --- a/src/NuGetizer.Tasks/NuGetizer.Inference.targets +++ b/src/NuGetizer.Tasks/NuGetizer.Inference.targets @@ -248,6 +248,7 @@ Copyright (c) .NET Foundation. All rights reserved. + @@ -294,7 +295,7 @@ Copyright (c) .NET Foundation. All rights reserved. '%(_InferenceCandidateWithTargetPath.CopyToOutputDirectory)' == 'Never'" /> - + @@ -318,9 +319,20 @@ Copyright (c) .NET Foundation. All rights reserved. <_InferredPackageFile Include="@(_InferredProjectOutput -> Distinct())" /> + + <_InferredPublishItem Include="@(PublishItemsOutputGroupOutputs -> '%(OutputPath)')" /> + <_InferredPackageFile Include="@(_InferredPublishItem -> '%(FullPath)')"> + $(PackFolder) + false + + + + <_InferredPackageFile Include="@(PackageReference)" Condition="'$(PackAsTool)' != 'true' and + '$(PackAsPublish)' != 'true' and '%(PackageReference.Identity)' != 'NuGetizer' and '%(PackageReference.Identity)' != 'NETStandard.Library' and '%(PackageReference.PrivateAssets)' != 'all' and @@ -334,6 +346,7 @@ Copyright (c) .NET Foundation. All rights reserved. TBD: maybe include ResolvedFrom=ImplicitlyExpandDesignTimeFacades too? --> <_InferredPackageFile Include="@(ReferencePath->'%(OriginalItemSpec)')" Condition="'$(PackAsTool)' != 'true' and + '$(PackAsPublish)' != 'true' and '$(PackFrameworkReferences)' == 'true' and '%(ReferencePath.ResolvedFrom)' == '{TargetFrameworkDirectory}' and '%(ReferencePath.Pack)' != 'false'"> @@ -385,7 +398,9 @@ Copyright (c) .NET Foundation. All rights reserved. - + @@ -416,6 +431,7 @@ Copyright (c) .NET Foundation. All rights reserved. - + <_SupportsReferences Condition=" @@ -500,7 +516,26 @@ Copyright (c) .NET Foundation. All rights reserved. $(InferPackageContentsDependsOn); AllProjectOutputGroups + + + true + + + $(InferPackageContentsDependsOn); + PublishItemsOutputGroup + + diff --git a/src/NuGetizer.Tests/given_a_tool_project.cs b/src/NuGetizer.Tests/given_a_tool_project.cs index c6df2ef3..d9185c7a 100644 --- a/src/NuGetizer.Tests/given_a_tool_project.cs +++ b/src/NuGetizer.Tests/given_a_tool_project.cs @@ -85,5 +85,59 @@ public void when_pack_folder_tool_but_no_pack_as_tool_then_packs_dependencies_no Identity = "Microsoft.Extensions.DependencyModel" })); } + + [Fact] + public void when_pack_folder_tool_no_pack_as_tool_and_executable_then_packs_as_publish_with_no_dependencies() + { + var result = Builder.BuildProject( + """ + + + Exe + MyTool + net6.0 + MyTool + tools + + + + + + """, + "GetPackageContents", output); + + result.AssertSuccess(output); + Assert.DoesNotContain(result.Items, item => item.Matches(new + { + Identity = "Microsoft.Extensions.DependencyModel" + })); + + Assert.All(result.Items, item => item.Matches(new + { + OutputGroup = "PublishItemsOutputGroup", + })); + } + + [Fact] + public void when_both_PackAsTool_and_PackAsPublish_true_then_fails() + { + var result = Builder.BuildProject( + """ + + + Exe + net6.0 + MyTool + tools + true + true + + + """, + "GetPackageContents", output); + + Assert.Equal(Microsoft.Build.Execution.BuildResultCode.Failure, result.BuildResult.OverallResult); + } + } } diff --git a/src/dotnet-nugetize/Program.cs b/src/dotnet-nugetize/Program.cs index cf49f0ac..c8182ef2 100644 --- a/src/dotnet-nugetize/Program.cs +++ b/src/dotnet-nugetize/Program.cs @@ -128,8 +128,7 @@ int Run(string[] args) "-p:SkipCompilerExecution=true", "-p:DesignTimeBuild=true", "-p:DesignTimeSilentResolution=true", - "-p:ResolveAssemblyReferencesSilent=true", - "-p:IsPublishable=false" + "-p:ResolveAssemblyReferencesSilent=true" }); if (help)