Skip to content

Commit 9ea4572

Browse files
authored
Merge pull request #9 from kzu/dev
Dev > Main
2 parents 0f94fae + 3db4b89 commit 9ea4572

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+3950
-3468
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ item metadata. It can also be turned off by default for all items of a given typ
6262
The basic item metadata that drive pack inference are:
6363

6464
1. **Pack**: *true*/*false*, determines whether inference applies to the item at all.
65-
2. **PackagePath**: final path within the package.
65+
2. **PackagePath**: final path within the package. Can be a directory path ending in `\` and in that case the item's *RelativeDir*, *Filename* and *Extension* will be appended automatically. Linked files are also supported automatically.
6666

6767
If the item does **not** provide a *PackagePath*, and *Pack* is not *false*, the inference targets wil try to determine the right value, based on the following additional metadata:
6868

@@ -136,7 +136,7 @@ This even works transitively, so if you use *PrivateAssets=all* on package refer
136136

137137
As usual, you can change this default behavior by using `Pack=false` metadata.
138138

139-
### Project References
139+
### ProjectReference
140140

141141
Unlike SDK Pack that [considers project references as package references by default](https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#project-to-project-references), NuGetizer has an explicit contract between projects: the `GetPackageContents` target. This target is invoked when packing project references, and it returns whatever the referenced project exposes as package contents (including the inference rules above). If the project is *packable* (that is, it produces a package, denoted by the presence of a `PackageId` property), it will be packed as a dependency/package reference instead.
142142

@@ -181,6 +181,8 @@ Package: Sample.1.0.0.nupkg
181181
sample.pdb
182182
```
183183

184+
Finally, you can focedly turn a project reference build output into a private asset even if it defines a `PackageId` by adding `PrivateAssets=all`. This is very useful for build and analyzer packages, which typically reference the main library project too, but need its output as private, since neither can use dependencies at run-time.
185+
184186
### dotnet-nugetize
185187

186188
Carefully tweaking your packages until they look exactly the way you want them should not be a tedious and slow process. Even requiring your project to be built between changes can be costly and reduce the speed at which you can iterate on the packaging aspects of the project. Also, generating the final `.nupkg`, opening it in a tool and inspecting its content, is also not ideal for rapid iteration.

src/Directory.Build.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<MakeDir Directories="$(PackageOutputPath)" Condition="'$(PackageOutputPath)' != '' And !Exists('$(PackageOutputPath)')" />
3333
</Target>
3434

35-
<Target Name="UpdatePackageMetadata" BeforeTargets="PrepareForBuild;GetAssemblyVersion;GenerateNuspec;Pack" Condition="$(IsPackable) And '$(RepositoryUrl)' != '' And '$(SourceRevisionId)' != ''">
35+
<Target Name="UpdatePackageMetadata" BeforeTargets="PrepareForBuild;GetAssemblyVersion;GetPackageMetadata;GenerateNuspec;Pack" Condition="$(IsPackable) And '$(RepositoryUrl)' != '' And '$(SourceRevisionId)' != ''">
3636
<PropertyGroup>
3737
<Description>
3838
$(Description)

src/NuGetizer.Tasks/AssignPackagePath.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
34
using System.IO;
45
using System.Linq;
56
using Microsoft.Build.Framework;
67
using Microsoft.Build.Utilities;
7-
using static ThisAssembly.Strings;
88
using NuGet.Packaging;
9+
using static ThisAssembly.Strings;
910

1011
namespace NuGetizer.Tasks
1112
{
@@ -31,6 +32,9 @@ public class AssignPackagePath : Task
3132

3233
public override bool Execute()
3334
{
35+
if (Environment.GetEnvironmentVariable("DEBUG_NUGETIZER") == "1")
36+
Debugger.Break();
37+
3438
var kindMap = KnownFolders.ToDictionary(
3539
kind => kind.ItemSpec,
3640
StringComparer.OrdinalIgnoreCase);
@@ -79,8 +83,25 @@ ITaskItem EnsurePackagePath(ITaskItem file, IDictionary<string, ITaskItem> kindM
7983
}
8084

8185
// If PackagePath already specified, we're done.
82-
if (!string.IsNullOrEmpty(file.GetMetadata("PackagePath")))
86+
if (file.TryGetMetadata("PackagePath", out var packagePath))
87+
{
88+
// If PackagePath ends in directory separator, we assume
89+
// the file/path needs to be appended too.
90+
if (packagePath.EndsWith("\\"))
91+
{
92+
if (file.TryGetMetadata("Link", out var link))
93+
packagePath = Path.Combine(packagePath, link);
94+
else
95+
packagePath = Path.Combine(packagePath,
96+
file.GetMetadata("RelativeDir"),
97+
file.GetMetadata("FileName") +
98+
file.GetMetadata("Extension"));
99+
100+
output.SetMetadata("PackagePath", packagePath);
101+
}
102+
83103
return output;
104+
}
84105

85106
// If a packaging project is requesting the package path assignment,
86107
// perform it regardless of whether there is a PackageId on the items,
@@ -180,7 +201,7 @@ ITaskItem EnsurePackagePath(ITaskItem file, IDictionary<string, ITaskItem> kindM
180201
// If we have no known package folder, files go to their RelativeDir location.
181202
// This allows custom packaging paths such as "workbooks", "docs" or whatever, which aren't prohibited by
182203
// the format.
183-
var packagePath = string.IsNullOrEmpty(packageFolder) ?
204+
packagePath = string.IsNullOrEmpty(packageFolder) ?
184205
// File goes to the determined target path (or the root of the package), such as a readme.txt
185206
targetPath :
186207
frameworkSpecific ?

src/NuGetizer.Tasks/CreatePackage.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
34
using System.IO;
45
using System.Linq;
56
using System.Security.Cryptography;
@@ -41,6 +42,9 @@ public class CreatePackage : Task
4142

4243
public override bool Execute()
4344
{
45+
if (Environment.GetEnvironmentVariable("DEBUG_NUGETIZER") == "1")
46+
Debugger.Break();
47+
4448
try
4549
{
4650
if (bool.TryParse(EmitPackage, out var emitPkg) && emitPkg)
@@ -78,8 +82,8 @@ public Manifest Execute(Stream output)
7882
public Manifest CreateManifest()
7983
{
8084
var metadata = new ManifestMetadata();
81-
82-
metadata.Id = Manifest.GetMetadata(nameof(MetadataName.PackageId));
85+
86+
metadata.Id = Manifest.GetNullableMetadata(MetadataName.PackageId) ?? Manifest.GetMetadata("Id");
8387

8488
if (Manifest.TryGetMetadata(nameof(ManifestMetadata.Version), out var version))
8589
metadata.Version = NuGetVersion.Parse(Manifest.GetMetadata(MetadataName.Version));
@@ -102,7 +106,7 @@ public Manifest CreateManifest()
102106
if (Manifest.TryGetMetadata("Copyright", out var copyright))
103107
metadata.Copyright = copyright;
104108

105-
if (Manifest.TryGetBoolMetadata("RequireLicenseAcceptance", out var requireLicenseAcceptance) &&
109+
if (Manifest.TryGetBoolMetadata("RequireLicenseAcceptance", out var requireLicenseAcceptance) &&
106110
requireLicenseAcceptance)
107111
metadata.RequireLicenseAcceptance = requireLicenseAcceptance;
108112

@@ -185,6 +189,7 @@ void GeneratePackage(Stream output = null)
185189

186190
if (output == null)
187191
{
192+
Directory.CreateDirectory(Path.GetDirectoryName(TargetPath));
188193
using var stream = File.Create(TargetPath);
189194
builder.Save(stream);
190195
}

src/NuGetizer.Tasks/Extensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
using System.Runtime.Versioning;
55
using Microsoft.Build.Framework;
66
using Microsoft.Build.Utilities;
7-
using NuGetizer.Tasks;
87
using NuGet.Frameworks;
98
using NuGet.Packaging;
109
using NuGet.Packaging.Core;
10+
using NuGetizer.Tasks;
1111

1212
namespace NuGetizer
1313
{

src/NuGetizer.Tasks/InferImplicitPackageReference.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public override bool Execute()
4141

4242
var inferred = new HashSet<PackageIdentity>();
4343

44-
foreach (var reference in PackageReferences.Where(x =>
44+
foreach (var reference in PackageReferences.Where(x =>
4545
"all".Equals(x.GetMetadata("PrivateAssets"), StringComparison.OrdinalIgnoreCase) &&
4646
// Unless explicitly set to Pack=false
4747
(!x.TryGetBoolMetadata("Pack", out var pack) || pack != false) &&
@@ -58,8 +58,8 @@ public override bool Execute()
5858
ImplicitPackageReferences = inferred
5959
.Select(x => new TaskItem(
6060
x.Id,
61-
new Dictionary<string, string>
62-
{
61+
new Dictionary<string, string>
62+
{
6363
{ "Version", x.Version } ,
6464
{ "PrivateAssets", "all" },
6565
}))
@@ -92,7 +92,7 @@ public PackageIdentity(string id, string version)
9292
public string Id { get; }
9393
public string Version { get; }
9494

95-
public override bool Equals(object obj)
95+
public override bool Equals(object obj)
9696
=> obj is PackageIdentity dependency &&
9797
dependency.Id == Id &&
9898
dependency.Version == Version;

src/NuGetizer.Tasks/NuGetizer.Shared.targets

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ Copyright (c) .NET Foundation. All rights reserved.
3737
</PropertyGroup>
3838

3939
<PropertyGroup Label="Hidden">
40+
<!-- Matches the SDK Pack default when set to true. -->
41+
<PackageId Condition="'$(IsPackable)' == 'true' and '$(PackageId)' == ''">$(AssemblyName)</PackageId>
42+
4043
<IsPackable Condition="'$(IsPackable)' == '' and '$(PackageId)' != ''">true</IsPackable>
4144
<IsPackable Condition="'$(IsPackable)' == '' and '$(PackageId)' == ''">false</IsPackable>
4245
<!-- When the project is building a package, AssignPackagePath always assigns a PackagePath, regardless of the project PackageId -->
@@ -236,7 +239,6 @@ Copyright (c) .NET Foundation. All rights reserved.
236239
</PropertyGroup>
237240

238241
<Target Name="Pack" DependsOnTargets="$(PackDependsOn)" Returns="@(_PackageTargetPath)" Condition="'$(IsPackable)' == 'true'">
239-
<MakeDir Directories="$(PackageOutputPath)" Condition="!Exists('$(PackageOutputPath)')" />
240242
<ItemGroup Condition="'@(NuspecFile)' == ''">
241243
<NuspecFile Include="$(NuspecFile)" />
242244
</ItemGroup>

src/NuGetizer.Tasks/NuGetizer.Tasks.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.9.20" PrivateAssets="all" />
1313
<PackageReference Include="NuGet.Packaging" Version="5.7.0" PrivateAssets="all" />
1414
<PackageReference Include="NuGet.ProjectManagement" Version="4.2.0" PrivateAssets="all" />
15-
<PackageReference Include="ThisAssembly" Version="0.10.6" PrivateAssets="all" />
15+
<PackageReference Include="ThisAssembly" Version="1.0.0-alpha" />
1616
</ItemGroup>
1717

1818
<ItemGroup>

src/NuGetizer.Tasks/NuGetizer.targets

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Copyright (c) .NET Foundation. All rights reserved.
3434
item containing the manifest information will also be returned, as
3535
3636
Identity=$(PackageId)
37-
%(PackFolder)=metadata
37+
%(PackFolder)=Metadata
3838
... all manifest values as metadata items ...
3939
4040
All items returned from this target contain a %(PackageId) metadata
@@ -81,21 +81,22 @@ Copyright (c) .NET Foundation. All rights reserved.
8181
<!-- If packaging the project, provide the metadata as a non-file item -->
8282
<ItemGroup>
8383
<PackageFile Include="@(PackageMetadata)">
84-
<PackFolder>metadata</PackFolder>
84+
<PackFolder>Metadata</PackFolder>
8585
<PackageId>$(PackageId)</PackageId>
8686
<Platform>$(Platform)</Platform>
8787
<TargetFrameworkMoniker Condition="'$(IsPackagingProject)' != 'true'">$(TargetFrameworkMoniker)</TargetFrameworkMoniker>
8888
</PackageFile>
8989
</ItemGroup>
9090
</Target>
9191

92-
<Target Name="_GetReferencedPackageContents"
93-
Condition="'$(_SupportsProjectReferences)' == 'true'"
94-
DependsOnTargets="$(_GetReferencedPackageContentsDependsOn)"
95-
Returns="@(PackageFile)">
92+
<Target Name="_GetReferencedPackageContents"
93+
Condition="'$(_SupportsProjectReferences)' == 'true'"
94+
DependsOnTargets="$(_GetReferencedPackageContentsDependsOn)"
95+
Returns="@(PackageFile)">
96+
9697
<Error Condition="'@(_NonNuGetizedProjectReference)' != ''"
97-
Code="NG0011"
98-
Text="Some project references cannot be properly packaged. Please install the NuGetizer package on the following projects: @(_NonNuGetizedProjectReference)." />
98+
Code="NG0011"
99+
Text="Some project references cannot be properly packaged. Please install the NuGetizer package on the following projects: @(_NonNuGetizedProjectReference)." />
99100

100101
<!--
101102
PackageId metadata on all PackageFile items means we can tell appart which ones came from which dependencies
@@ -107,30 +108,36 @@ Copyright (c) .NET Foundation. All rights reserved.
107108
<MSBuild Projects="@(_NuGetizedProjectReference)"
108109
Targets="GetPackageContents"
109110
BuildInParallel="$(BuildInParallel)"
110-
Properties="%(_NuGetizedProjectReference.SetConfiguration); %(_NuGetizedProjectReference.SetPlatform); BuildingPackage=$(BuildingPackage); DesignTimeBuild=false"
111+
Properties="%(_NuGetizedProjectReference.SetConfiguration);
112+
%(_NuGetizedProjectReference.SetPlatform);
113+
BuildingPackage=$(BuildingPackage);
114+
DesignTimeBuild=false"
111115
Condition="'@(ProjectReferenceWithConfiguration)' != '' and '@(_NuGetizedProjectReference)' != ''"
112116
RemoveProperties="%(_NuGetizedProjectReference.GlobalPropertiesToRemove)">
113117
<Output TaskParameter="TargetOutputs" ItemName="_ReferencedPackageContent" />
114118
</MSBuild>
115119

116120
<ItemGroup>
117121
<_ReferencedPackageDependency Include="@(_ReferencedPackageContent)"
118-
Condition="'%(_ReferencedPackageContent.PackageId)' != '$(PackageId)' and '%(_ReferencedPackageContent.PackFolder)' == 'metadata'">
122+
Condition="'%(_ReferencedPackageContent.PackageId)' != '$(PackageId)' and
123+
'%(_ReferencedPackageContent.PackFolder)' == 'Metadata'">
119124
<!-- For consistency, annotate like the rest -->
120125
<PackageId Condition="'$(IsPackable)' == 'true'">$(PackageId)</PackageId>
121126
<TargetFrameworkMoniker Condition="'$(IsPackagingProject)' != 'true'">$(TargetFrameworkMoniker)</TargetFrameworkMoniker>
122127
<PackFolder>Dependency</PackFolder>
123128
</_ReferencedPackageDependency>
124129
<!-- Remove the referenced package actual contents if it provides a manifest, since it will be a dependency in that case. -->
125130
<_PackageContentFromDependency Include="@(_ReferencedPackageContent)"
126-
Condition="'%(_ReferencedPackageContent.PackageId)' != '' and '%(_ReferencedPackageContent.PackageId)' != '$(PackageId)'" />
131+
Condition="'%(_ReferencedPackageContent.PackageId)' != '' and
132+
'%(_ReferencedPackageContent.PackageId)' != '$(PackageId)'" />
127133
<_ReferencedPackageContent Remove="@(_PackageContentFromDependency)" />
128134
</ItemGroup>
129135

130136
<!-- Always annotate package contents with the original target framework and moniker -->
131137
<CreateItem Include="@(_ReferencedPackageContent)" PreserveExistingMetadata="true"
132138
Condition="'@(_ReferencedPackageContent)' != ''"
133-
AdditionalMetadata="OriginalTargetFramework=%(_ReferencedPackageContent.TargetFramework);OriginalTargetFrameworkMoniker=%(_ReferencedPackageContent.TargetFrameworkMoniker)">
139+
AdditionalMetadata="OriginalTargetFramework=%(_ReferencedPackageContent.TargetFramework);
140+
OriginalTargetFrameworkMoniker=%(_ReferencedPackageContent.TargetFrameworkMoniker)">
134141
<Output TaskParameter="Include" ItemName="_ReferencedPackageContentWithOriginalValues"/>
135142
</CreateItem>
136143

@@ -192,14 +199,22 @@ Copyright (c) .NET Foundation. All rights reserved.
192199
<PropertyGroup>
193200
<_ShouldPack>%(_MSBuildProjectReferenceExistent.Pack)</_ShouldPack>
194201
<_IsNuGetized>%(_ReferencedProjectTargetPath.IsNuGetized)</_IsNuGetized>
202+
<_PrivateAssets>%(_MSBuildProjectReferenceExistent.PrivateAssets)</_PrivateAssets>
195203
</PropertyGroup>
196204

197205
<!-- Only process references that aren't excluded from Pack -->
198206
<ItemGroup Condition="'$(_ShouldPack)' != 'false'">
199207
<!-- We will fail for this first group: project references that aren't excluded from packaging, yet haven't been nugetized -->
200208
<_NonNuGetizedProjectReference Include="@(_MSBuildProjectReferenceExistent)" Condition="'$(_IsNuGetized)' != 'true'" />
201209
<!-- We will only process for packaging the project references that haven't been excluded from packaging and are nugetized -->
202-
<_NuGetizedProjectReference Include="@(_MSBuildProjectReferenceExistent)" Condition="'$(_IsNuGetized)' == 'true'" />
210+
<_NuGetizedProjectReference Include="@(_MSBuildProjectReferenceExistent)" Condition="'$(_IsNuGetized)' == 'true'">
211+
<!-- By flagging PrivateAssets=all nugetized references as IsPackable=false, we cause its assets to be
212+
packed together with the build output, instead of referenced as a dependency.
213+
This works because default value for IsPackable checks for '' before defaulting
214+
to whether there is a PackageId property.
215+
Also, passing our own PackFolder causes it to be the overriden default for the referenced project. -->
216+
<AdditionalProperties Condition="'$(_PrivateAssets)' == 'all'">IsPackable=false;PackFolder=$(PackFolder)</AdditionalProperties>
217+
</_NuGetizedProjectReference>
203218
</ItemGroup>
204219

205220
</Target>

0 commit comments

Comments
 (0)