diff --git a/README.md b/README.md
index 94a3c9cd..29f5afd5 100644
--- a/README.md
+++ b/README.md
@@ -62,7 +62,7 @@ item metadata. It can also be turned off by default for all items of a given typ
The basic item metadata that drive pack inference are:
1. **Pack**: *true*/*false*, determines whether inference applies to the item at all.
-2. **PackagePath**: final path within the package.
+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.
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:
@@ -136,7 +136,7 @@ This even works transitively, so if you use *PrivateAssets=all* on package refer
As usual, you can change this default behavior by using `Pack=false` metadata.
-### Project References
+### ProjectReference
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.
@@ -181,6 +181,8 @@ Package: Sample.1.0.0.nupkg
sample.pdb
```
+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.
+
### dotnet-nugetize
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.
diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets
index 3a723967..7860700c 100644
--- a/src/Directory.Build.targets
+++ b/src/Directory.Build.targets
@@ -32,7 +32,7 @@
-
+
$(Description)
diff --git a/src/NuGetizer.Tasks/AssignPackagePath.cs b/src/NuGetizer.Tasks/AssignPackagePath.cs
index 9ede7673..6295336a 100644
--- a/src/NuGetizer.Tasks/AssignPackagePath.cs
+++ b/src/NuGetizer.Tasks/AssignPackagePath.cs
@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
-using static ThisAssembly.Strings;
using NuGet.Packaging;
+using static ThisAssembly.Strings;
namespace NuGetizer.Tasks
{
@@ -31,6 +32,9 @@ public class AssignPackagePath : Task
public override bool Execute()
{
+ if (Environment.GetEnvironmentVariable("DEBUG_NUGETIZER") == "1")
+ Debugger.Break();
+
var kindMap = KnownFolders.ToDictionary(
kind => kind.ItemSpec,
StringComparer.OrdinalIgnoreCase);
@@ -79,8 +83,25 @@ ITaskItem EnsurePackagePath(ITaskItem file, IDictionary kindM
}
// If PackagePath already specified, we're done.
- if (!string.IsNullOrEmpty(file.GetMetadata("PackagePath")))
+ if (file.TryGetMetadata("PackagePath", out var packagePath))
+ {
+ // If PackagePath ends in directory separator, we assume
+ // the file/path needs to be appended too.
+ if (packagePath.EndsWith("\\"))
+ {
+ if (file.TryGetMetadata("Link", out var link))
+ packagePath = Path.Combine(packagePath, link);
+ else
+ packagePath = Path.Combine(packagePath,
+ file.GetMetadata("RelativeDir"),
+ file.GetMetadata("FileName") +
+ file.GetMetadata("Extension"));
+
+ output.SetMetadata("PackagePath", packagePath);
+ }
+
return output;
+ }
// If a packaging project is requesting the package path assignment,
// perform it regardless of whether there is a PackageId on the items,
@@ -180,7 +201,7 @@ ITaskItem EnsurePackagePath(ITaskItem file, IDictionary kindM
// If we have no known package folder, files go to their RelativeDir location.
// This allows custom packaging paths such as "workbooks", "docs" or whatever, which aren't prohibited by
// the format.
- var packagePath = string.IsNullOrEmpty(packageFolder) ?
+ packagePath = string.IsNullOrEmpty(packageFolder) ?
// File goes to the determined target path (or the root of the package), such as a readme.txt
targetPath :
frameworkSpecific ?
diff --git a/src/NuGetizer.Tasks/CreatePackage.cs b/src/NuGetizer.Tasks/CreatePackage.cs
index 1f1bb096..160afa86 100644
--- a/src/NuGetizer.Tasks/CreatePackage.cs
+++ b/src/NuGetizer.Tasks/CreatePackage.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
@@ -41,6 +42,9 @@ public class CreatePackage : Task
public override bool Execute()
{
+ if (Environment.GetEnvironmentVariable("DEBUG_NUGETIZER") == "1")
+ Debugger.Break();
+
try
{
if (bool.TryParse(EmitPackage, out var emitPkg) && emitPkg)
@@ -78,8 +82,8 @@ public Manifest Execute(Stream output)
public Manifest CreateManifest()
{
var metadata = new ManifestMetadata();
-
- metadata.Id = Manifest.GetMetadata(nameof(MetadataName.PackageId));
+
+ metadata.Id = Manifest.GetNullableMetadata(MetadataName.PackageId) ?? Manifest.GetMetadata("Id");
if (Manifest.TryGetMetadata(nameof(ManifestMetadata.Version), out var version))
metadata.Version = NuGetVersion.Parse(Manifest.GetMetadata(MetadataName.Version));
@@ -102,7 +106,7 @@ public Manifest CreateManifest()
if (Manifest.TryGetMetadata("Copyright", out var copyright))
metadata.Copyright = copyright;
- if (Manifest.TryGetBoolMetadata("RequireLicenseAcceptance", out var requireLicenseAcceptance) &&
+ if (Manifest.TryGetBoolMetadata("RequireLicenseAcceptance", out var requireLicenseAcceptance) &&
requireLicenseAcceptance)
metadata.RequireLicenseAcceptance = requireLicenseAcceptance;
@@ -185,6 +189,7 @@ void GeneratePackage(Stream output = null)
if (output == null)
{
+ Directory.CreateDirectory(Path.GetDirectoryName(TargetPath));
using var stream = File.Create(TargetPath);
builder.Save(stream);
}
diff --git a/src/NuGetizer.Tasks/Extensions.cs b/src/NuGetizer.Tasks/Extensions.cs
index 2006e5c3..269caf48 100644
--- a/src/NuGetizer.Tasks/Extensions.cs
+++ b/src/NuGetizer.Tasks/Extensions.cs
@@ -4,10 +4,10 @@
using System.Runtime.Versioning;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
-using NuGetizer.Tasks;
using NuGet.Frameworks;
using NuGet.Packaging;
using NuGet.Packaging.Core;
+using NuGetizer.Tasks;
namespace NuGetizer
{
diff --git a/src/NuGetizer.Tasks/InferImplicitPackageReference.cs b/src/NuGetizer.Tasks/InferImplicitPackageReference.cs
index f0f1ce54..f2a1ca22 100644
--- a/src/NuGetizer.Tasks/InferImplicitPackageReference.cs
+++ b/src/NuGetizer.Tasks/InferImplicitPackageReference.cs
@@ -41,7 +41,7 @@ public override bool Execute()
var inferred = new HashSet();
- foreach (var reference in PackageReferences.Where(x =>
+ foreach (var reference in PackageReferences.Where(x =>
"all".Equals(x.GetMetadata("PrivateAssets"), StringComparison.OrdinalIgnoreCase) &&
// Unless explicitly set to Pack=false
(!x.TryGetBoolMetadata("Pack", out var pack) || pack != false) &&
@@ -58,8 +58,8 @@ public override bool Execute()
ImplicitPackageReferences = inferred
.Select(x => new TaskItem(
x.Id,
- new Dictionary
- {
+ new Dictionary
+ {
{ "Version", x.Version } ,
{ "PrivateAssets", "all" },
}))
@@ -92,7 +92,7 @@ public PackageIdentity(string id, string version)
public string Id { get; }
public string Version { get; }
- public override bool Equals(object obj)
+ public override bool Equals(object obj)
=> obj is PackageIdentity dependency &&
dependency.Id == Id &&
dependency.Version == Version;
diff --git a/src/NuGetizer.Tasks/NuGetizer.Shared.targets b/src/NuGetizer.Tasks/NuGetizer.Shared.targets
index c26a1419..f69a51c1 100644
--- a/src/NuGetizer.Tasks/NuGetizer.Shared.targets
+++ b/src/NuGetizer.Tasks/NuGetizer.Shared.targets
@@ -37,6 +37,9 @@ Copyright (c) .NET Foundation. All rights reserved.
+
+ $(AssemblyName)
+
true
false
@@ -236,7 +239,6 @@ Copyright (c) .NET Foundation. All rights reserved.
-
diff --git a/src/NuGetizer.Tasks/NuGetizer.Tasks.csproj b/src/NuGetizer.Tasks/NuGetizer.Tasks.csproj
index eba95674..4b63be6c 100644
--- a/src/NuGetizer.Tasks/NuGetizer.Tasks.csproj
+++ b/src/NuGetizer.Tasks/NuGetizer.Tasks.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/src/NuGetizer.Tasks/NuGetizer.targets b/src/NuGetizer.Tasks/NuGetizer.targets
index a5c315a1..5ec2b727 100644
--- a/src/NuGetizer.Tasks/NuGetizer.targets
+++ b/src/NuGetizer.Tasks/NuGetizer.targets
@@ -34,7 +34,7 @@ Copyright (c) .NET Foundation. All rights reserved.
item containing the manifest information will also be returned, as
Identity=$(PackageId)
- %(PackFolder)=metadata
+ %(PackFolder)=Metadata
... all manifest values as metadata items ...
All items returned from this target contain a %(PackageId) metadata
@@ -81,7 +81,7 @@ Copyright (c) .NET Foundation. All rights reserved.
- metadata
+ Metadata
$(PackageId)
$(Platform)
$(TargetFrameworkMoniker)
@@ -89,13 +89,14 @@ Copyright (c) .NET Foundation. All rights reserved.
-
+
+
+ Code="NG0011"
+ Text="Some project references cannot be properly packaged. Please install the NuGetizer package on the following projects: @(_NonNuGetizedProjectReference)." />
$(PackageId)
$(TargetFrameworkMoniker)
@@ -123,14 +128,16 @@ Copyright (c) .NET Foundation. All rights reserved.
<_PackageContentFromDependency Include="@(_ReferencedPackageContent)"
- Condition="'%(_ReferencedPackageContent.PackageId)' != '' and '%(_ReferencedPackageContent.PackageId)' != '$(PackageId)'" />
+ Condition="'%(_ReferencedPackageContent.PackageId)' != '' and
+ '%(_ReferencedPackageContent.PackageId)' != '$(PackageId)'" />
<_ReferencedPackageContent Remove="@(_PackageContentFromDependency)" />
+ AdditionalMetadata="OriginalTargetFramework=%(_ReferencedPackageContent.TargetFramework);
+ OriginalTargetFrameworkMoniker=%(_ReferencedPackageContent.TargetFrameworkMoniker)">
@@ -192,6 +199,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<_ShouldPack>%(_MSBuildProjectReferenceExistent.Pack)
<_IsNuGetized>%(_ReferencedProjectTargetPath.IsNuGetized)
+ <_PrivateAssets>%(_MSBuildProjectReferenceExistent.PrivateAssets)
@@ -199,7 +207,14 @@ Copyright (c) .NET Foundation. All rights reserved.
<_NonNuGetizedProjectReference Include="@(_MSBuildProjectReferenceExistent)" Condition="'$(_IsNuGetized)' != 'true'" />
- <_NuGetizedProjectReference Include="@(_MSBuildProjectReferenceExistent)" Condition="'$(_IsNuGetized)' == 'true'" />
+ <_NuGetizedProjectReference Include="@(_MSBuildProjectReferenceExistent)" Condition="'$(_IsNuGetized)' == 'true'">
+
+ IsPackable=false;PackFolder=$(PackFolder)
+
diff --git a/src/NuGetizer.Tests/AssignPackagePathTests.cs b/src/NuGetizer.Tests/AssignPackagePathTests.cs
index 2bd95a9e..83021477 100644
--- a/src/NuGetizer.Tests/AssignPackagePathTests.cs
+++ b/src/NuGetizer.Tests/AssignPackagePathTests.cs
@@ -1,788 +1,863 @@
+using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
+using NuGetizer.Tasks;
using Xunit;
using Xunit.Abstractions;
-using System.Linq;
-using NuGetizer.Tasks;
using Metadata = System.Collections.Generic.Dictionary;
-using System;
namespace NuGetizer
{
- public class AssignPackagePathTests
- {
+ public class AssignPackagePathTests
+ {
static ITaskItem[] kinds;
- static ITaskItem[] Kinds
+ static ITaskItem[] Kinds
=> kinds ??= new Project(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NuGetizer.props"), null, null, new ProjectCollection())
.GetItems("PackFolderKind")
.Select(item => new TaskItem(item.EvaluatedInclude, item.Metadata.ToDictionary(meta => meta.Name, meta => meta.UnevaluatedValue)))
.ToArray();
- ITestOutputHelper output;
- MockBuildEngine engine;
+ ITestOutputHelper output;
+ MockBuildEngine engine;
+
+ public AssignPackagePathTests(ITestOutputHelper output)
+ {
+ this.output = output;
+ engine = new MockBuildEngine(output);
+ }
+
+ [Fact]
+ public void when_file_has_no_kind_then_logs_error_code()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem("library.dll", new Metadata
+ {
+ { "PackageId", "A" },
+ { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" }
+ })
+ }
+ };
+
+ Assert.False(task.Execute());
+ Assert.Equal(nameof(ThisAssembly.Strings.ErrorCode.NG0010), engine.LoggedErrorEvents[0].Code);
+ }
+
+ [Fact]
+ public void when_file_has_no_kind_and_no_framework_specific_then_it_is_not_assigned_target_framework()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem("library.dll", new Metadata
+ {
+ { "PackagePath", "workbooks\\library.dll" },
+ { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" }
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+ Assert.Contains(task.AssignedFiles, item => item.Matches(new
+ {
+ PackagePath = "workbooks\\library.dll",
+ TargetFramework = ""
+ }));
+ }
+
+ [Fact]
+ public void when_file_has_no_kind_and_package_path_and_framework_specific_then_it_is_assigned_target_framework_only()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem("library.dll", new Metadata
+ {
+ { "PackagePath", "workbooks\\library.dll" },
+ { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
+ { "FrameworkSpecific", "true" }
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+ Assert.Contains(task.AssignedFiles, item => item.Matches(new
+ {
+ PackagePath = "workbooks\\library.dll",
+ TargetFramework = "net45"
+ }));
+ }
+
+ [Fact]
+ public void assigned_files_contains_all_files()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem("a.dll", new Metadata
+ {
+ { "PackageId", "A" },
+ { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
+ { "PackFolder", "lib" }
+ }),
+ new TaskItem("a.pdb", new Metadata
+ {
+ { "PackageId", "A" },
+ { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
+ { "PackFolder", "symbols" }
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+
+ Assert.Equal(task.Files.Length, task.AssignedFiles.Length);
+ }
+
+ [Fact]
+ public void when_file_has_no_package_id_then_package_path_is_not_specified()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem("library.dll", new Metadata
+ {
+ { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
+ { "PackFolder", "lib" }
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+ Assert.Equal("", task.AssignedFiles[0].GetMetadata(MetadataName.PackagePath));
+ }
+
+ [Fact]
+ public void when_file_has_no_package_id_but_is_packaging_true_then_package_path_is_specified()
+ {
+ var task = new AssignPackagePath
+ {
+ IsPackaging = "true",
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem("library.dll", new Metadata
+ {
+ { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
+ { "PackFolder", "lib" }
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+ Assert.Equal(@"lib\net45\library.dll", task.AssignedFiles[0].GetMetadata(MetadataName.PackagePath));
+ }
+
+ [Fact]
+ public void when_file_has_no_package_id_then_target_framework_is_calculated_anyway()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem("library.dll", new Metadata
+ {
+ { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
+ { "PackFolder", "lib" }
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+ Assert.Contains(task.AssignedFiles, item => item.Matches(new
+ {
+ TargetFramework = "net45"
+ }));
+ }
+
+ [Fact]
+ public void when_file_has_no_package_id_then_package_folder_is_calculated_anyway()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem("library.dll", new Metadata
+ {
+ { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
+ { "PackFolder", "lib" }
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+ Assert.Contains(task.AssignedFiles, item => item.Matches(new
+ {
+ PackageFolder = "lib"
+ }));
+ }
+
+ [Fact]
+ public void when_file_has_no_tfm_then_assigned_file_contains_no_target_framework()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem("library.dll", new Metadata
+ {
+ { "PackageId", "A" },
+ { "PackFolder", "lib" }
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+ Assert.Contains(task.AssignedFiles, item => item.Matches(new
+ {
+ PackageFolder = "lib",
+ PackagePath = "lib\\library.dll",
+ TargetFramework = ""
+ }));
+ }
+
+ [Fact]
+ public void when_file_has_target_framework_and_tfm_then_existing_value_is_preserved()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem("library.dll", new Metadata
+ {
+ { "PackageId", "A" },
+ { "PackFolder", "contentFiles" },
+ { "TargetFramework", "any" },
+ { "TargetFrameworkMoniker", "MonoAndroid,Version=v2.5" },
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+
+ Assert.Contains(task.AssignedFiles, item => item.Matches(new
+ {
+ TargetFramework = "any",
+ }));
+ }
+
+ [Fact]
+ public void when_content_file_has_link_then_package_path_is_relative_to_link()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem(@"..\..\readme.txt", new Metadata
+ {
+ { "Link", @"docs\readme.txt" },
+ { "PackageId", "A" },
+ { "PackFolder", "content" },
+ { "TargetFramework", "any" },
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+
+ Assert.Contains(task.AssignedFiles, item => item.Matches(new
+ {
+ TargetPath = @"docs\readme.txt",
+ PackagePath = @"contentFiles\any\any\docs\readme.txt",
+ }));
+ }
+
+ [Fact]
+ public void when_none_file_has_link_then_package_path_is_relative_to_link()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem(@"..\..\readme.txt", new Metadata
+ {
+ { "Link", @"docs\readme.txt" },
+ { "PackageId", "A" },
+ { "PackFolder", "none" },
+ { "TargetFramework", "any" },
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+
+ Assert.Contains(task.AssignedFiles, item => item.Matches(new
+ {
+ TargetPath = @"docs\readme.txt",
+ PackagePath = @"docs\readme.txt",
+ }));
+ }
+
+ [Fact]
+ public void when_package_file_has_directory_package_path_then_appends_file_and_extension()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem(@"readme.txt", new Metadata
+ {
+ { "PackageId", "A" },
+ { "PackFolder", "none" },
+ { "PackagePath", @"build\" },
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+ Assert.Contains(task.AssignedFiles, item => item.Matches(new
+ {
+ PackagePath = @"build\readme.txt",
+ }));
+ }
- public AssignPackagePathTests(ITestOutputHelper output)
- {
- this.output = output;
- engine = new MockBuildEngine(output);
+ [Fact]
+ public void when_package_file_has_directory_package_path_and_relative_dir_then_appends_relative_path_file_and_extension()
+ {
+ var task = new AssignPackagePath
+ {
+ BuildEngine = engine,
+ KnownFolders = Kinds,
+ Files = new ITaskItem[]
+ {
+ new TaskItem(@"quickstarts\readme.txt", new Metadata
+ {
+ { "PackageId", "A" },
+ { "PackFolder", "none" },
+ { "PackagePath", @"docs\" },
+ })
+ }
+ };
+
+ Assert.True(task.Execute());
+ Assert.Contains(task.AssignedFiles, item => item.Matches(new
+ {
+ PackagePath = @"docs\quickstarts\readme.txt",
+ }));
}
[Fact]
- public void when_file_has_no_kind_then_logs_error_code()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("library.dll", new Metadata
- {
- { "PackageId", "A" },
- { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" }
- })
- }
- };
-
- Assert.False(task.Execute());
- Assert.Equal(nameof(ThisAssembly.Strings.ErrorCode.NG0010), engine.LoggedErrorEvents[0].Code);
- }
-
- [Fact]
- public void when_file_has_no_kind_and_no_framework_specific_then_it_is_not_assigned_target_framework()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("library.dll", new Metadata
- {
- { "PackagePath", "workbooks\\library.dll" },
- { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" }
- })
- }
- };
-
- Assert.True(task.Execute());
- Assert.Contains(task.AssignedFiles, item => item.Matches(new
- {
- PackagePath = "workbooks\\library.dll",
- TargetFramework = ""
- }));
- }
-
- [Fact]
- public void when_file_has_no_kind_and_package_path_and_framework_specific_then_it_is_assigned_target_framework_only()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("library.dll", new Metadata
- {
- { "PackagePath", "workbooks\\library.dll" },
- { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
- { "FrameworkSpecific", "true" }
- })
- }
- };
-
- Assert.True(task.Execute());
- Assert.Contains(task.AssignedFiles, item => item.Matches(new
- {
- PackagePath = "workbooks\\library.dll",
- TargetFramework = "net45"
- }));
- }
-
- [Fact]
- public void assigned_files_contains_all_files()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("a.dll", new Metadata
- {
- { "PackageId", "A" },
- { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
- { "PackFolder", "lib" }
- }),
- new TaskItem("a.pdb", new Metadata
- {
- { "PackageId", "A" },
- { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
- { "PackFolder", "symbols" }
- })
- }
- };
-
- Assert.True(task.Execute());
-
- Assert.Equal(task.Files.Length, task.AssignedFiles.Length);
- }
-
- [Fact]
- public void when_file_has_no_package_id_then_package_path_is_not_specified()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("library.dll", new Metadata
- {
- { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
- { "PackFolder", "lib" }
- })
- }
- };
-
- Assert.True(task.Execute());
- Assert.Equal("", task.AssignedFiles[0].GetMetadata(MetadataName.PackagePath));
- }
-
- [Fact]
- public void when_file_has_no_package_id_but_is_packaging_true_then_package_path_is_specified()
- {
- var task = new AssignPackagePath
- {
- IsPackaging = "true",
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("library.dll", new Metadata
- {
- { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
- { "PackFolder", "lib" }
- })
- }
- };
-
- Assert.True(task.Execute());
- Assert.Equal(@"lib\net45\library.dll", task.AssignedFiles[0].GetMetadata(MetadataName.PackagePath));
- }
-
- [Fact]
- public void when_file_has_no_package_id_then_target_framework_is_calculated_anyway()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("library.dll", new Metadata
- {
- { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
- { "PackFolder", "lib" }
- })
- }
- };
-
- Assert.True(task.Execute());
- Assert.Contains(task.AssignedFiles, item => item.Matches(new
- {
- TargetFramework = "net45"
- }));
- }
-
- [Fact]
- public void when_file_has_no_package_id_then_package_folder_is_calculated_anyway()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("library.dll", new Metadata
- {
- { "TargetFrameworkMoniker", ".NETFramework,Version=v4.5" },
- { "PackFolder", "lib" }
- })
- }
- };
-
- Assert.True(task.Execute());
- Assert.Contains(task.AssignedFiles, item => item.Matches(new
- {
- PackageFolder = "lib"
- }));
- }
-
- [Fact]
- public void when_file_has_no_tfm_then_assigned_file_contains_no_target_framework()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("library.dll", new Metadata
- {
- { "PackageId", "A" },
- { "PackFolder", "lib" }
- })
- }
- };
-
- Assert.True(task.Execute());
- Assert.Contains(task.AssignedFiles, item => item.Matches(new
- {
- PackageFolder = "lib",
- PackagePath = "lib\\library.dll",
- TargetFramework = ""
- }));
- }
-
- [Fact]
- public void when_file_has_target_framework_and_tfm_then_existing_value_is_preserved()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("library.dll", new Metadata
- {
- { "PackageId", "A" },
- { "PackFolder", "contentFiles" },
- { "TargetFramework", "any" },
- { "TargetFrameworkMoniker", "MonoAndroid,Version=v2.5" },
- })
- }
- };
-
- Assert.True(task.Execute());
-
- Assert.Contains(task.AssignedFiles, item => item.Matches(new
- {
- TargetFramework = "any",
- }));
- }
-
- [Fact]
- public void when_content_file_has_link_then_package_path_is_relative_to_link()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem(@"..\..\readme.txt", new Metadata
- {
- { "Link", @"docs\readme.txt" },
- { "PackageId", "A" },
- { "PackFolder", "content" },
- { "TargetFramework", "any" },
- })
- }
- };
-
- Assert.True(task.Execute());
-
- Assert.Contains(task.AssignedFiles, item => item.Matches(new
- {
- TargetPath = @"docs\readme.txt",
- PackagePath = @"contentFiles\any\any\docs\readme.txt",
- }));
- }
-
- [Fact]
- public void when_none_file_has_link_then_package_path_is_relative_to_link()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem(@"..\..\readme.txt", new Metadata
- {
- { "Link", @"docs\readme.txt" },
- { "PackageId", "A" },
- { "PackFolder", "none" },
- { "TargetFramework", "any" },
- })
- }
- };
-
- Assert.True(task.Execute());
-
- Assert.Contains(task.AssignedFiles, item => item.Matches(new
- {
- TargetPath = @"docs\readme.txt",
- PackagePath = @"docs\readme.txt",
- }));
- }
-
-
- [Fact]
- public void when_content_is_not_framework_specific_then_has_any_lang_and_tfm()
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("readme.txt", new Metadata
- {
- { "PackageId", "A" },
- { "PackFolder", "content" },
- { "FrameworkSpecific", "false" },
- { "TargetFrameworkMoniker", "MonoAndroid,Version=v2.5" },
- })
- }
- };
-
- Assert.True(task.Execute());
-
- Assert.Contains(task.AssignedFiles, item => item.Matches(new
- {
- CodeLanguage = "any",
- TargetFramework = "any",
- PackagePath = @"contentFiles\any\any\readme.txt"
- }));
- }
-
- // TODO: these all end up in all lowercase, but MonoAndroid, Xamarin.iOS are usually properly
- // cased in nupkgs out in the wild (i.e. Rx)
- [InlineData(".NETFramework,Version=v4.5", "net45")]
- [InlineData(".NETPortable,Version=v5.0", "portable50")]
- [InlineData("Xamarin.iOS,Version=v1.0", "xamarinios10")]
- // TODO: should somehow we allow targetting monoandroid without the version suffix?
- [InlineData("MonoAndroid,Version=v2.5", "monoandroid25")]
- [Theory]
- public void when_file_has_tfm_then_assigned_file_contains_target_framework(string targetFrameworkMoniker, string expectedTargetFramework)
- {
- var task = new AssignPackagePath
- {
- BuildEngine = engine,
- KnownFolders = Kinds,
- Files = new ITaskItem[]
- {
- new TaskItem("library.dll", new Metadata
- {
- { "PackageId", "A" },
- { "TargetFrameworkMoniker", targetFrameworkMoniker },
- { "PackFolder", "lib" }
- })
- }
- };
-
- Assert.True(task.Execute());
-
- Assert.Contains(task.AssignedFiles, item => item.Matches(new
- {
- PackageFolder = "lib",
- PackagePath = $"lib\\{ expectedTargetFramework}\\library.dll",
- TargetFramework = expectedTargetFramework,
- }));
- }
-
- public static IEnumerable