From aeaf8f03809e526d32c73179b44c77386119c928 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Wed, 13 Apr 2016 12:19:38 -0500 Subject: [PATCH 1/3] Add back in copying of RuntimeAssets during publish. Any NuGet packages that had contentFiles weren't getting the content files added to the published output directory. This breaks things like debugging in VS Code. Fix #2459 --- .../commands/dotnet-publish/PublishCommand.cs | 94 ++++++++----------- 1 file changed, 37 insertions(+), 57 deletions(-) diff --git a/src/dotnet/commands/dotnet-publish/PublishCommand.cs b/src/dotnet/commands/dotnet-publish/PublishCommand.cs index 90ae4e8fb..f035550f2 100644 --- a/src/dotnet/commands/dotnet-publish/PublishCommand.cs +++ b/src/dotnet/commands/dotnet-publish/PublishCommand.cs @@ -1,21 +1,20 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.ProjectModel.Compilation; -using NuGet.Frameworks; using System; using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.DotNet.Cli.Compiler.Common; -using Microsoft.Extensions.PlatformAbstractions; +using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Files; -using Microsoft.DotNet.Tools.Common; -using Microsoft.DotNet.ProjectModel.Utilities; +using Microsoft.DotNet.ProjectModel; +using Microsoft.DotNet.ProjectModel.Compilation; using Microsoft.DotNet.ProjectModel.Graph; -using NuGet.Versioning; +using Microsoft.DotNet.ProjectModel.Utilities; +using Microsoft.DotNet.Tools.Common; +using Microsoft.Extensions.PlatformAbstractions; +using NuGet.Frameworks; namespace Microsoft.DotNet.Tools.Publish { @@ -134,6 +133,10 @@ namespace Microsoft.DotNet.Tools.Publish .ToDictionary(e => e.Library.Identity.Name); var collectExclusionList = context.IsPortable ? GetExclusionList(context, packageExports) : new HashSet(); + // Get the output paths used by the call to `dotnet build` above (since we didn't pass `--output`, they will be different from + // our current output paths) + var buildOutputPaths = context.GetOutputPaths(configuration, buildBasePath); + var exports = exporter.GetAllExports(); foreach (var export in exports.Where(e => !collectExclusionList.Contains(e.Library.Identity.Name))) { @@ -141,6 +144,19 @@ namespace Microsoft.DotNet.Tools.Publish PublishAssetGroups(export.RuntimeAssemblyGroups, outputPath, nativeSubdirectories: false, includeRuntimeGroups: context.IsPortable); PublishAssetGroups(export.NativeLibraryGroups, outputPath, nativeSubdirectories, includeRuntimeGroups: context.IsPortable); + + var runtimeAssetsToCopy = export.RuntimeAssets.Where(a => ShouldCopyExportRuntimeAsset(context, buildOutputPaths, export, a)); + runtimeAssetsToCopy.StructuredCopyTo(outputPath, outputPaths.IntermediateOutputDirectoryPath); + } + + if (context.ProjectFile.HasRuntimeOutput(configuration) && !context.TargetFramework.IsDesktop()) + { + PublishFiles( + new[] { + buildOutputPaths.RuntimeFiles.DepsJson, + buildOutputPaths.RuntimeFiles.RuntimeConfigJson + }, + outputPath); } if (options.PreserveCompilationContext.GetValueOrDefault()) @@ -151,9 +167,6 @@ namespace Microsoft.DotNet.Tools.Publish } } - var buildOutputPaths = context.GetOutputPaths(configuration, buildBasePath, null); - PublishBuildOutputFiles(buildOutputPaths, context, outputPath, Configuration); - var contentFiles = new ContentFiles(context); contentFiles.StructuredCopyTo(outputPath); @@ -171,59 +184,26 @@ namespace Microsoft.DotNet.Tools.Publish return true; } - private void PublishBuildOutputFiles(OutputPaths buildOutputPaths, ProjectContext context, string outputPath, string configuration) + /// + /// Filters which export's RuntimeAssets should get copied to the output path. + /// + /// + /// True if the asset should be copied to the output path; otherwise, false. + /// + private static bool ShouldCopyExportRuntimeAsset(ProjectContext context, OutputPaths buildOutputPaths, LibraryExport export, LibraryAsset asset) { - List filesToPublish = new List(); + // The current project has the host .exe in its runtime assets, but it shouldn't be copied + // to the output path during publish. The host will come from the export that has the real host in it. - string[] buildOutputFiles = null; - - if (context.ProjectFile.HasRuntimeOutput(configuration)) + if (context.RootProject.Identity == export.Library.Identity) { - Reporter.Verbose.WriteLine($"publish: using runtime build output files"); - - buildOutputFiles = new string[] + if (asset.ResolvedPath == buildOutputPaths.RuntimeFiles.Executable) { - buildOutputPaths.RuntimeFiles.DepsJson, - buildOutputPaths.RuntimeFiles.RuntimeConfigJson, - buildOutputPaths.RuntimeFiles.Config, - buildOutputPaths.RuntimeFiles.Assembly, - buildOutputPaths.RuntimeFiles.PdbPath, - Path.ChangeExtension(buildOutputPaths.RuntimeFiles.Assembly, "xml") - }; - - filesToPublish.AddRange(buildOutputPaths.RuntimeFiles.Resources()); - } - else - { - Reporter.Verbose.WriteLine($"publish: using compilation build output files"); - - buildOutputFiles = new string[] - { - buildOutputPaths.CompilationFiles.Assembly, - buildOutputPaths.CompilationFiles.PdbPath, - Path.ChangeExtension(buildOutputPaths.CompilationFiles.Assembly, "xml") - }; - - filesToPublish.AddRange(buildOutputPaths.CompilationFiles.Resources()); - } - - foreach (var buildOutputFile in buildOutputFiles) - { - if (File.Exists(buildOutputFile)) - { - filesToPublish.Add(buildOutputFile); - } - else - { - Reporter.Verbose.WriteLine($"publish: build output file not found {buildOutputFile} "); + return false; } } - - Reporter.Verbose.WriteLine($"publish: Copying build output files:\n {string.Join("\n", filesToPublish)}"); - PublishFiles( - filesToPublish, - outputPath); + return true; } private bool InvokeBuildOnProject(ProjectContext context, string buildBasePath, string configuration) From f6f1a52ec4f91fb24ed95c1031ab0bdd379d5164 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Wed, 13 Apr 2016 16:24:37 -0500 Subject: [PATCH 2/3] Add publish test for an app with a dependency with contents. --- .../PublishAppWithDependencies.cs | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 test/dotnet-publish.Tests/PublishAppWithDependencies.cs diff --git a/test/dotnet-publish.Tests/PublishAppWithDependencies.cs b/test/dotnet-publish.Tests/PublishAppWithDependencies.cs new file mode 100644 index 000000000..3ccd53334 --- /dev/null +++ b/test/dotnet-publish.Tests/PublishAppWithDependencies.cs @@ -0,0 +1,51 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.IO; +using Microsoft.DotNet.TestFramework; +using Microsoft.DotNet.Tools.Test.Utilities; +using Xunit; + +namespace Microsoft.DotNet.Tools.Publish.Tests +{ + public class PublishAppWithDependencies : TestBase + { + [Fact] + public void PublishTestAppWithContentPackage() + { + var testInstance = TestAssetsManager.CreateTestInstance("TestAppWithContentPackage") + .WithLockFiles(); + + var publishDir = Publish(testInstance); + + publishDir.Should().HaveFiles(new[] + { + "TestAppWithContentPackage.exe", + "TestAppWithContentPackage.dll", + "TestAppWithContentPackage.deps.json" + }); + + // these files come from the contentFiles of the SharedContentA dependency + publishDir + .Sub("scripts") + .Should() + .Exist() + .And + .HaveFile("run.cmd"); + + publishDir + .Should() + .HaveFile("config.xml"); + } + + private DirectoryInfo Publish(TestInstance testInstance) + { + var publishCommand = new PublishCommand(testInstance.TestRoot); + var publishResult = publishCommand.Execute(); + + publishResult.Should().Pass(); + + return publishCommand.GetOutputDirectory(portable: false); + } + } +} From deef7f867fa0242912b081f81c531df22547a57b Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Wed, 13 Apr 2016 18:38:15 -0500 Subject: [PATCH 3/3] Fix PublishTestAppWithContentPackage test to work on all platforms. --- .../PublishAppWithDependencies.cs | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/test/dotnet-publish.Tests/PublishAppWithDependencies.cs b/test/dotnet-publish.Tests/PublishAppWithDependencies.cs index 3ccd53334..df2907f82 100644 --- a/test/dotnet-publish.Tests/PublishAppWithDependencies.cs +++ b/test/dotnet-publish.Tests/PublishAppWithDependencies.cs @@ -16,13 +16,18 @@ namespace Microsoft.DotNet.Tools.Publish.Tests var testInstance = TestAssetsManager.CreateTestInstance("TestAppWithContentPackage") .WithLockFiles(); - var publishDir = Publish(testInstance); + var publishCommand = new PublishCommand(testInstance.TestRoot); + var publishResult = publishCommand.Execute(); + + publishResult.Should().Pass(); + + var publishDir = publishCommand.GetOutputDirectory(portable: false); publishDir.Should().HaveFiles(new[] { - "TestAppWithContentPackage.exe", - "TestAppWithContentPackage.dll", - "TestAppWithContentPackage.deps.json" + $"AppWithContentPackage{publishCommand.GetExecutableExtension()}", + "AppWithContentPackage.dll", + "AppWithContentPackage.deps.json" }); // these files come from the contentFiles of the SharedContentA dependency @@ -37,15 +42,5 @@ namespace Microsoft.DotNet.Tools.Publish.Tests .Should() .HaveFile("config.xml"); } - - private DirectoryInfo Publish(TestInstance testInstance) - { - var publishCommand = new PublishCommand(testInstance.TestRoot); - var publishResult = publishCommand.Execute(); - - publishResult.Should().Pass(); - - return publishCommand.GetOutputDirectory(portable: false); - } } }