From b596122d5c8965a50a2fcbc5c6929301dc5c2fee Mon Sep 17 00:00:00 2001 From: Todd Moscinski Date: Fri, 3 Jun 2016 14:53:58 -0700 Subject: [PATCH 1/3] Adding support for --serviceable option to pack command which puts true into the output nuspec --- src/Microsoft.DotNet.ProjectModel/Project.cs | 2 ++ src/dotnet/commands/dotnet-pack/NuGet/Manifest.cs | 1 + src/dotnet/commands/dotnet-pack/NuGet/ManifestMetadata.cs | 2 ++ src/dotnet/commands/dotnet-pack/NuGet/ManifestReader.cs | 3 +++ .../commands/dotnet-pack/NuGet/ManifestSchemaUtility.cs | 8 +++++++- .../commands/dotnet-pack/NuGet/ManifestVersionUtility.cs | 8 +++++++- src/dotnet/commands/dotnet-pack/NuGet/PackageBuilder.cs | 7 +++++++ .../dotnet-pack/NuGet/PackageMetadataXmlExtensions.cs | 4 ++++ src/dotnet/commands/dotnet-pack/PackageGenerator.cs | 1 + src/dotnet/commands/dotnet-pack/Program.cs | 3 +++ 10 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.DotNet.ProjectModel/Project.cs b/src/Microsoft.DotNet.ProjectModel/Project.cs index 737206c40..3aba2a6ac 100644 --- a/src/Microsoft.DotNet.ProjectModel/Project.cs +++ b/src/Microsoft.DotNet.ProjectModel/Project.cs @@ -68,6 +68,8 @@ namespace Microsoft.DotNet.ProjectModel public PackOptions PackOptions { get; set; } + public bool Serviceable { get; set; } + public RuntimeOptions RuntimeOptions { get; set; } public IDictionary Commands { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase); diff --git a/src/dotnet/commands/dotnet-pack/NuGet/Manifest.cs b/src/dotnet/commands/dotnet-pack/NuGet/Manifest.cs index 330add22e..e400f5c55 100644 --- a/src/dotnet/commands/dotnet-pack/NuGet/Manifest.cs +++ b/src/dotnet/commands/dotnet-pack/NuGet/Manifest.cs @@ -109,6 +109,7 @@ namespace NuGet metadata.Authors = copy.Authors.Distinct(); metadata.Owners = copy.Owners.Distinct(); metadata.Tags = string.Join(",", copy.Tags).Trim(); + metadata.Serviceable = copy.Serviceable; metadata.LicenseUrl = copy.LicenseUrl; metadata.ProjectUrl = copy.ProjectUrl; metadata.IconUrl = copy.IconUrl; diff --git a/src/dotnet/commands/dotnet-pack/NuGet/ManifestMetadata.cs b/src/dotnet/commands/dotnet-pack/NuGet/ManifestMetadata.cs index 59fcdefd4..1010c8140 100644 --- a/src/dotnet/commands/dotnet-pack/NuGet/ManifestMetadata.cs +++ b/src/dotnet/commands/dotnet-pack/NuGet/ManifestMetadata.cs @@ -77,6 +77,8 @@ namespace NuGet public string Tags { get; set; } + public bool Serviceable { get; set; } + public IEnumerable DependencySets { get; set; } = new List(); public ICollection PackageAssemblyReferences { get; set; } = new List(); diff --git a/src/dotnet/commands/dotnet-pack/NuGet/ManifestReader.cs b/src/dotnet/commands/dotnet-pack/NuGet/ManifestReader.cs index a8196a62b..d3a81b680 100644 --- a/src/dotnet/commands/dotnet-pack/NuGet/ManifestReader.cs +++ b/src/dotnet/commands/dotnet-pack/NuGet/ManifestReader.cs @@ -130,6 +130,9 @@ namespace NuGet case "tags": manifestMetadata.Tags = value; break; + case "serviceable": + manifestMetadata.Serviceable = XmlConvert.ToBoolean(value); + break; case "dependencies": manifestMetadata.DependencySets = ReadDependencySets(element); break; diff --git a/src/dotnet/commands/dotnet-pack/NuGet/ManifestSchemaUtility.cs b/src/dotnet/commands/dotnet-pack/NuGet/ManifestSchemaUtility.cs index defcd12cc..510aad70a 100644 --- a/src/dotnet/commands/dotnet-pack/NuGet/ManifestSchemaUtility.cs +++ b/src/dotnet/commands/dotnet-pack/NuGet/ManifestSchemaUtility.cs @@ -41,13 +41,19 @@ namespace NuGet /// internal const string SchemaVersionV6 = "http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"; + /// + /// Added serviceble element under metadata. + /// + internal const string SchemaVersionV7 = "http://schemas.microsoft.com/packaging/2016/06/nuspec.xsd"; + private static readonly string[] VersionToSchemaMappings = new[] { SchemaVersionV1, SchemaVersionV2, SchemaVersionV3, SchemaVersionV4, SchemaVersionV5, - SchemaVersionV6 + SchemaVersionV6, + SchemaVersionV7 }; public static int GetVersionFromNamespace(string @namespace) diff --git a/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs b/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs index c549a48ea..e3e841cbc 100644 --- a/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs +++ b/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs @@ -15,6 +15,7 @@ namespace NuGet public const int TargetFrameworkSupportForDependencyContentsAndToolsVersion = 4; public const int TargetFrameworkSupportForReferencesVersion = 5; public const int XdtTransformationVersion = 6; + public const int ServiceableVersion = 7; public static int GetManifestVersion(ManifestMetadata metadata) { @@ -23,7 +24,12 @@ namespace NuGet private static int GetMaxVersionFromMetadata(ManifestMetadata metadata) { - // Important: check for version 5 before version 4 + // Important: always add newer version checks at the top + if (metadata.Serviceable) + { + return ServiceableVersion; + } + bool referencesHasTargetFramework = metadata.PackageAssemblyReferences != null && metadata.PackageAssemblyReferences.Any(r => r.TargetFramework != null); diff --git a/src/dotnet/commands/dotnet-pack/NuGet/PackageBuilder.cs b/src/dotnet/commands/dotnet-pack/NuGet/PackageBuilder.cs index 8a8c99282..f6596df79 100644 --- a/src/dotnet/commands/dotnet-pack/NuGet/PackageBuilder.cs +++ b/src/dotnet/commands/dotnet-pack/NuGet/PackageBuilder.cs @@ -87,6 +87,12 @@ namespace NuGet set; } + public bool Serviceable + { + get; + set; + } + public bool DevelopmentDependency { get; @@ -284,6 +290,7 @@ namespace NuGet ProjectUrl = manifestMetadata.ProjectUrl; RequireLicenseAcceptance = manifestMetadata.RequireLicenseAcceptance; DevelopmentDependency = manifestMetadata.DevelopmentDependency; + Serviceable = manifestMetadata.Serviceable; Description = manifestMetadata.Description; Summary = manifestMetadata.Summary; ReleaseNotes = manifestMetadata.ReleaseNotes; diff --git a/src/dotnet/commands/dotnet-pack/NuGet/PackageMetadataXmlExtensions.cs b/src/dotnet/commands/dotnet-pack/NuGet/PackageMetadataXmlExtensions.cs index 3d25de307..c654dd5ec 100644 --- a/src/dotnet/commands/dotnet-pack/NuGet/PackageMetadataXmlExtensions.cs +++ b/src/dotnet/commands/dotnet-pack/NuGet/PackageMetadataXmlExtensions.cs @@ -51,6 +51,10 @@ namespace NuGet AddElementIfNotNull(elem, ns, "copyright", metadata.Copyright); AddElementIfNotNull(elem, ns, "language", metadata.Language); AddElementIfNotNull(elem, ns, "tags", metadata.Tags); + if (metadata.Serviceable) + { + elem.Add(new XElement(ns + "serviceable", metadata.Serviceable)); + } elem.Add(GetXElementFromGroupableItemSets( ns, diff --git a/src/dotnet/commands/dotnet-pack/PackageGenerator.cs b/src/dotnet/commands/dotnet-pack/PackageGenerator.cs index 4b4f891aa..1997b95ec 100644 --- a/src/dotnet/commands/dotnet-pack/PackageGenerator.cs +++ b/src/dotnet/commands/dotnet-pack/PackageGenerator.cs @@ -390,6 +390,7 @@ namespace Microsoft.DotNet.Tools.Compiler builder.ReleaseNotes = project.PackOptions.ReleaseNotes; builder.Language = project.Language; builder.Tags.AddRange(project.PackOptions.Tags); + builder.Serviceable = project.Serviceable; if (!string.IsNullOrEmpty(project.PackOptions.IconUrl)) { diff --git a/src/dotnet/commands/dotnet-pack/Program.cs b/src/dotnet/commands/dotnet-pack/Program.cs index 0c89edea9..352e8bd01 100644 --- a/src/dotnet/commands/dotnet-pack/Program.cs +++ b/src/dotnet/commands/dotnet-pack/Program.cs @@ -29,6 +29,7 @@ namespace Microsoft.DotNet.Tools.Compiler var buildBasePath = app.Option("-b|--build-base-path ", "Directory in which to place temporary build outputs", CommandOptionType.SingleValue); var configuration = app.Option("-c|--configuration ", "Configuration under which to build", CommandOptionType.SingleValue); var versionSuffix = app.Option("--version-suffix ", "Defines what `*` should be replaced with in version field in project.json", CommandOptionType.SingleValue); + var serviceable = app.Option("-s|--serviceable", "Set the serviceable flag in the output nuspec", CommandOptionType.NoValue); var path = app.Argument("", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory"); app.OnExecute(() => @@ -64,6 +65,8 @@ namespace Microsoft.DotNet.Tools.Compiler var artifactPathsCalculator = new ArtifactPathsCalculator(project, buildBasePathValue, outputValue, configValue); var packageBuilder = new PackagesGenerator(contexts, artifactPathsCalculator, configValue); + project.Serviceable = serviceable.HasValue(); + int buildResult = 0; if (!noBuild.HasValue()) { From e45259c6fa3727144022561e65ecd41e0b59bec7 Mon Sep 17 00:00:00 2001 From: Todd Moscinski Date: Fri, 3 Jun 2016 15:46:16 -0700 Subject: [PATCH 2/3] Changing schema version to 8 to match NuGet internal value and adding a pack test for the --serviceable option. --- .../NuGet/ManifestSchemaUtility.cs | 4 +-- .../NuGet/ManifestVersionUtility.cs | 2 +- .../Commands/PackCommand.cs | 17 ++++++++-- test/dotnet-pack.Tests/PackTests.cs | 31 +++++++++++++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/dotnet/commands/dotnet-pack/NuGet/ManifestSchemaUtility.cs b/src/dotnet/commands/dotnet-pack/NuGet/ManifestSchemaUtility.cs index 510aad70a..f839f8c19 100644 --- a/src/dotnet/commands/dotnet-pack/NuGet/ManifestSchemaUtility.cs +++ b/src/dotnet/commands/dotnet-pack/NuGet/ManifestSchemaUtility.cs @@ -44,7 +44,7 @@ namespace NuGet /// /// Added serviceble element under metadata. /// - internal const string SchemaVersionV7 = "http://schemas.microsoft.com/packaging/2016/06/nuspec.xsd"; + internal const string SchemaVersionV8 = "http://schemas.microsoft.com/packaging/2016/06/nuspec.xsd"; private static readonly string[] VersionToSchemaMappings = new[] { SchemaVersionV1, @@ -53,7 +53,7 @@ namespace NuGet SchemaVersionV4, SchemaVersionV5, SchemaVersionV6, - SchemaVersionV7 + SchemaVersionV8 }; public static int GetVersionFromNamespace(string @namespace) diff --git a/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs b/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs index e3e841cbc..6c1a719e8 100644 --- a/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs +++ b/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs @@ -15,7 +15,7 @@ namespace NuGet public const int TargetFrameworkSupportForDependencyContentsAndToolsVersion = 4; public const int TargetFrameworkSupportForReferencesVersion = 5; public const int XdtTransformationVersion = 6; - public const int ServiceableVersion = 7; + public const int ServiceableVersion = 8; public static int GetManifestVersion(ManifestMetadata metadata) { diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PackCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PackCommand.cs index ffedf3f0a..54cff340d 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PackCommand.cs +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PackCommand.cs @@ -14,6 +14,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities private string _tempOutputDirectory; private string _configuration; private string _versionSuffix; + private string _serviceable; private string OutputOption { @@ -64,13 +65,24 @@ namespace Microsoft.DotNet.Tools.Test.Utilities } } + private string ServiceableOption + { + get + { + return _serviceable == string.Empty ? + "" : + $"--serviceable"; + } + } + public PackCommand( string projectPath, string output = "", string buildBasePath = "", string tempOutput="", string configuration="", - string versionSuffix="") + string versionSuffix="", + string serviceable = "") : base("dotnet") { _projectPath = projectPath; @@ -79,6 +91,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities _tempOutputDirectory = tempOutput; _configuration = configuration; _versionSuffix = versionSuffix; + _serviceable = serviceable; } public override CommandResult Execute(string args = "") @@ -89,7 +102,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities private string BuildArgs() { - return $"{_projectPath} {OutputOption} {BuildBasePathOption} {TempOutputOption} {ConfigurationOption} {VersionSuffixOption}"; + return $"{_projectPath} {OutputOption} {BuildBasePathOption} {TempOutputOption} {ConfigurationOption} {VersionSuffixOption} {ServiceableOption}"; } } } diff --git a/test/dotnet-pack.Tests/PackTests.cs b/test/dotnet-pack.Tests/PackTests.cs index 7613ed159..ed4d35224 100644 --- a/test/dotnet-pack.Tests/PackTests.cs +++ b/test/dotnet-pack.Tests/PackTests.cs @@ -4,6 +4,8 @@ using System; using System.IO; using System.IO.Compression; +using System.Linq; +using System.Xml.Linq; using FluentAssertions; using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.Tools.Test.Utilities; @@ -150,6 +152,35 @@ namespace Microsoft.DotNet.Tools.Compiler.Tests .Pass(); } + [Fact] + public void HasServiceableFlagWhenArgumentPassed() + { + var root = Temp.CreateDirectory(); + + var testLibDir = root.CreateDirectory("TestLibrary"); + var sourceTestLibDir = Path.Combine(_testProjectsRoot, "TestLibraryWithConfiguration"); + + CopyProjectToTempDir(sourceTestLibDir, testLibDir); + + var testProject = GetProjectPath(testLibDir); + var packCommand = new PackCommand(testProject, configuration: "Debug", serviceable: "true"); + var result = packCommand.Execute(); + result.Should().Pass(); + + var outputDir = new DirectoryInfo(Path.Combine(testLibDir.Path, "bin", "Debug")); + outputDir.Should().Exist(); + outputDir.Should().HaveFiles(new[] { "TestLibrary.1.0.0.nupkg", "TestLibrary.1.0.0.symbols.nupkg" }); + + var outputPackage = Path.Combine(outputDir.FullName, "TestLibrary.1.0.0.nupkg"); + var zip = ZipFile.Open(outputPackage, ZipArchiveMode.Read); + zip.Entries.Should().Contain(e => e.FullName == "TestLibrary.nuspec"); + + var manifestReader = new StreamReader(zip.Entries.First(e => e.FullName == "TestLibrary.nuspec").Open()); + var nuspecXml = XDocument.Parse(manifestReader.ReadToEnd()); + var node = nuspecXml.Descendants().Single(e => e.Name.LocalName == "serviceable"); + Assert.Equal("true", node.Value); + } + private void CopyProjectToTempDir(string projectDir, TempDirectory tempDir) { // copy all the files to temp dir From 72ad34b566b770b8335261c356286cb41c700927 Mon Sep 17 00:00:00 2001 From: Todd Moscinski Date: Sun, 5 Jun 2016 11:52:41 -0700 Subject: [PATCH 3/3] Fixing schema version number, tweaking a string, and making test call pass a bool instead of a string to enable serviceable. --- .../dotnet-pack/NuGet/ManifestVersionUtility.cs | 4 +++- src/dotnet/commands/dotnet-pack/Program.cs | 2 +- .../Commands/PackCommand.cs | 10 +++++----- test/dotnet-pack.Tests/PackTests.cs | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs b/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs index 6c1a719e8..ce4665153 100644 --- a/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs +++ b/src/dotnet/commands/dotnet-pack/NuGet/ManifestVersionUtility.cs @@ -15,7 +15,9 @@ namespace NuGet public const int TargetFrameworkSupportForDependencyContentsAndToolsVersion = 4; public const int TargetFrameworkSupportForReferencesVersion = 5; public const int XdtTransformationVersion = 6; - public const int ServiceableVersion = 8; + // Note that this version should change from 7 to 8 when the PackageType + // schema is merged into here + public const int ServiceableVersion = 7; public static int GetManifestVersion(ManifestMetadata metadata) { diff --git a/src/dotnet/commands/dotnet-pack/Program.cs b/src/dotnet/commands/dotnet-pack/Program.cs index 352e8bd01..0d167ec2b 100644 --- a/src/dotnet/commands/dotnet-pack/Program.cs +++ b/src/dotnet/commands/dotnet-pack/Program.cs @@ -29,7 +29,7 @@ namespace Microsoft.DotNet.Tools.Compiler var buildBasePath = app.Option("-b|--build-base-path ", "Directory in which to place temporary build outputs", CommandOptionType.SingleValue); var configuration = app.Option("-c|--configuration ", "Configuration under which to build", CommandOptionType.SingleValue); var versionSuffix = app.Option("--version-suffix ", "Defines what `*` should be replaced with in version field in project.json", CommandOptionType.SingleValue); - var serviceable = app.Option("-s|--serviceable", "Set the serviceable flag in the output nuspec", CommandOptionType.NoValue); + var serviceable = app.Option("-s|--serviceable", "Set the serviceable flag in the package", CommandOptionType.NoValue); var path = app.Argument("", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory"); app.OnExecute(() => diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PackCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PackCommand.cs index 54cff340d..de3adae6c 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PackCommand.cs +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PackCommand.cs @@ -14,7 +14,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities private string _tempOutputDirectory; private string _configuration; private string _versionSuffix; - private string _serviceable; + private bool _serviceable; private string OutputOption { @@ -69,9 +69,9 @@ namespace Microsoft.DotNet.Tools.Test.Utilities { get { - return _serviceable == string.Empty ? - "" : - $"--serviceable"; + return _serviceable ? + $"--serviceable" : + ""; } } @@ -82,7 +82,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities string tempOutput="", string configuration="", string versionSuffix="", - string serviceable = "") + bool serviceable = false) : base("dotnet") { _projectPath = projectPath; diff --git a/test/dotnet-pack.Tests/PackTests.cs b/test/dotnet-pack.Tests/PackTests.cs index ed4d35224..5091e7fd7 100644 --- a/test/dotnet-pack.Tests/PackTests.cs +++ b/test/dotnet-pack.Tests/PackTests.cs @@ -163,7 +163,7 @@ namespace Microsoft.DotNet.Tools.Compiler.Tests CopyProjectToTempDir(sourceTestLibDir, testLibDir); var testProject = GetProjectPath(testLibDir); - var packCommand = new PackCommand(testProject, configuration: "Debug", serviceable: "true"); + var packCommand = new PackCommand(testProject, configuration: "Debug", serviceable: true); var result = packCommand.Execute(); result.Should().Pass();