From 6b22fc7df6eb06413ffba98fcc88d5a6ada47be8 Mon Sep 17 00:00:00 2001 From: Mattias Karlsson Date: Tue, 5 Oct 2021 18:49:06 +0200 Subject: [PATCH] (GH-3517) Add NuGet Pack ReadMe Support --- .../Properties/Resources.Designer.cs | 27 ++++++++++++++ .../Properties/Resources.resx | 21 +++++++++++ .../Unit/Tools/NuGet/Pack/NuGetPackerTests.cs | 24 +++++++++++++ .../Tools/NuGet/Pack/NuGetPackSettings.cs | 6 ++++ .../Tools/NuGet/Pack/NuspecTransformer.cs | 36 +++++++++++++------ 5 files changed, 104 insertions(+), 10 deletions(-) diff --git a/src/Cake.Common.Tests/Properties/Resources.Designer.cs b/src/Cake.Common.Tests/Properties/Resources.Designer.cs index e820ea1240..bcf4feb3a7 100644 --- a/src/Cake.Common.Tests/Properties/Resources.Designer.cs +++ b/src/Cake.Common.Tests/Properties/Resources.Designer.cs @@ -643,6 +643,33 @@ public static string Nuspec_Repository { return ResourceManager.GetString("Nuspec_Repository", resourceCulture); } } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> + ///<package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + /// <metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> + /// <id>TheID</id> + /// <version>1.0.0</version> + /// <title>The Title</title> + /// <authors>Author #1,Author #2</authors> + /// <owners>Owner #1,Owner #2</owners> + /// <description>The Description</description> + /// <readme>docs\NuGet.org.md</readme> + /// </metadata> + /// <files> + /// <file src="Cake.Core.dll" target="lib/net45" /> + /// <file src="Cake.Core.xml" target="lib/net45" /> + /// <file src="Cake.Core.pdb" target="lib/net45" /> + /// <file src="LICENSE" /> + /// <file src="../nuspec/NuGet.org.md" target="docs\" /> + /// </files> + ///</package> + /// + public static string Nuspec_ReadMe { + get { + return ResourceManager.GetString("Nuspec_ReadMe", resourceCulture); + } + } /// /// Looks up a localized string similar to Microsoft Visual Studio Solution File, Format Version 12.00 diff --git a/src/Cake.Common.Tests/Properties/Resources.resx b/src/Cake.Common.Tests/Properties/Resources.resx index 612ace1a7a..30b74e5b4b 100644 --- a/src/Cake.Common.Tests/Properties/Resources.resx +++ b/src/Cake.Common.Tests/Properties/Resources.resx @@ -1370,6 +1370,27 @@ Line #3]]></releaseNotes> <file src="Cake.Core.pdb" target="lib/net45" /> <file src="LICENSE" /> </files> +</package> + + + <?xml version="1.0" encoding="utf-8"?> +<package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> + <id>TheID</id> + <version>1.0.0</version> + <title>The Title</title> + <authors>Author #1,Author #2</authors> + <owners>Owner #1,Owner #2</owners> + <description>The Description</description> + <readme>docs\NuGet.org.md</readme> + </metadata> + <files> + <file src="Cake.Core.dll" target="lib/net45" /> + <file src="Cake.Core.xml" target="lib/net45" /> + <file src="Cake.Core.pdb" target="lib/net45" /> + <file src="LICENSE" /> + <file src="../nuspec/NuGet.org.md" target="docs" /> + </files> </package> diff --git a/src/Cake.Common.Tests/Unit/Tools/NuGet/Pack/NuGetPackerTests.cs b/src/Cake.Common.Tests/Unit/Tools/NuGet/Pack/NuGetPackerTests.cs index afedbdd3fd..efae53f241 100644 --- a/src/Cake.Common.Tests/Unit/Tools/NuGet/Pack/NuGetPackerTests.cs +++ b/src/Cake.Common.Tests/Unit/Tools/NuGet/Pack/NuGetPackerTests.cs @@ -899,6 +899,30 @@ public void Should_Replace_Template_Tokens_In_Nuspec_With_Files_And_DependencyTa Resources.Nuspec_Metadata_WithoutNamespaces_WithTargetFramworkDependencies.NormalizeLineEndings(), result.NuspecContent.NormalizeLineEndings()); } + + [Fact] + public void Should_Add_ReadMe_Element_To_Nuspec_If_Missing() + { + // Given + var fixture = new NuGetPackerWithNuSpecFixture(); + fixture.WithNuSpecXml(Resources.Nuspec_NoMetadataElement); + + fixture.Settings.Id = "TheID"; + fixture.Settings.Version = "1.0.0"; + fixture.Settings.Title = "The Title"; + fixture.Settings.Authors = new[] { "Author #1", "Author #2" }; + fixture.Settings.Owners = new[] { "Owner #1", "Owner #2" }; + fixture.Settings.Description = "The Description"; + fixture.Settings.ReadMePath = "../nuspec/NuGet.org.md"; + + // When + var result = fixture.Run(); + + // Then + Assert.Equal( + Resources.Nuspec_ReadMe.NormalizeLineEndings(), + result.NuspecContent.NormalizeLineEndings()); + } } public sealed class WithProjectFile diff --git a/src/Cake.Common/Tools/NuGet/Pack/NuGetPackSettings.cs b/src/Cake.Common/Tools/NuGet/Pack/NuGetPackSettings.cs index 732c38dd82..7d29af948c 100644 --- a/src/Cake.Common/Tools/NuGet/Pack/NuGetPackSettings.cs +++ b/src/Cake.Common/Tools/NuGet/Pack/NuGetPackSettings.cs @@ -272,5 +272,11 @@ public sealed class NuGetPackSettings : ToolSettings /// true if the output should be placed in the tool folder inside the NuGet package; otherwise false. /// public bool OutputToToolFolder { get; set; } + + /// + /// Gets or sets Path to markdown Markdown (.md) file containing package readme packed into docs folder. + /// + /// The readme path. + public FilePath ReadMePath { get; set; } } } \ No newline at end of file diff --git a/src/Cake.Common/Tools/NuGet/Pack/NuspecTransformer.cs b/src/Cake.Common/Tools/NuGet/Pack/NuspecTransformer.cs index c10e625cd6..9533bdfadf 100644 --- a/src/Cake.Common/Tools/NuGet/Pack/NuspecTransformer.cs +++ b/src/Cake.Common/Tools/NuGet/Pack/NuspecTransformer.cs @@ -54,7 +54,8 @@ private static IDictionary> CreateMappin { "copyright", x => ToString(settings.Copyright) }, { "language", x => ToString(settings.Language) }, { "tags", x => ToSpaceSeparatedString(settings.Tags) }, - { "serviceable", x => ToString(settings.Serviceable) } + { "serviceable", x => ToString(settings.Serviceable) }, + { "readme", x => settings.ReadMePath is { } readme ? string.Concat("docs\\", readme.GetFilename().FullPath) : null }, }; } @@ -108,17 +109,25 @@ private static void AddComplexTypesToXmlDocument(XmlDocument document, NuGetPack private static void CreateFileElements(XmlDocument document, NuGetPackSettings settings, XmlNamespaceManager namespaceManager) { - if (settings.Files != null && settings.Files.Count > 0) + var hasFiles = settings.Files != null && settings.Files.Count > 0; + var hasReadMe = settings.ReadMePath != null; + + if (!hasFiles && !hasReadMe) { - var filesPath = string.Format(CultureInfo.InvariantCulture, - "//*[local-name()='package']/*[local-name()='files']"); - var filesElement = document.SelectSingleNode(filesPath, namespaceManager); - if (filesElement == null) - { - var package = GetPackageElement(document); - filesElement = document.CreateAndAppendElement(package, "files"); - } + return; + } + var filesPath = string.Format(CultureInfo.InvariantCulture, + "//*[local-name()='package']/*[local-name()='files']"); + var filesElement = document.SelectSingleNode(filesPath, namespaceManager); + if (filesElement == null) + { + var package = GetPackageElement(document); + filesElement = document.CreateAndAppendElement(package, "files"); + } + + if (hasFiles) + { filesElement.RemoveAll(); foreach (var file in settings.Files) { @@ -131,6 +140,13 @@ private static void CreateFileElements(XmlDocument document, NuGetPackSettings s } } } + + if (hasReadMe) + { + var fileElement = document.CreateAndAppendElement(filesElement, "file"); + fileElement.AddAttributeIfSpecified(settings.ReadMePath.FullPath, "src"); + fileElement.AddAttributeIfSpecified("docs", "target"); + } } private static void CreateContentFileElements(XmlDocument document, NuGetPackSettings settings,