From 2d3a1fd1775ef46b4282c0ca4a6bf885f9d5746b Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Fri, 8 Apr 2016 08:51:51 -0700 Subject: [PATCH] Make desktop publishing "half-portable" by default --- .../KestrelDesktop/.noautobuild | 0 .../KestrelDesktop/project.json | 17 ++++++ .../KestrelDesktopWithRuntimes/.noautobuild | 0 .../KestrelDesktopWithRuntimes/project.json | 21 +++++++ .../dotnet-dependency-tool-invoker.xproj | 3 +- .../TestAppWithArgs/TestAppWithArgs.xproj | 3 +- .../TestAppWithContents.xproj | 3 +- scripts/dotnet-cli-build/CompileTargets.cs | 3 - scripts/dotnet-cli-build/TestTargets.cs | 1 - .../Executable.cs | 12 +--- .../Compilation/LibraryExporter.cs | 41 +++++++++++-- .../ProjectContext.cs | 54 +++++++++++++++-- .../ProjectContextBuilder.cs | 58 ++++++++++++++++--- .../RuntimeEnvironmentRidExtensions.cs | 0 .../project.json | 1 + .../dotnet-compile/CompilerCommandApp.cs | 2 +- .../commands/dotnet-publish/PublishCommand.cs | 10 ++-- .../Microsoft.DotNet.Cli.Msi.Tests.xproj | 2 +- .../LibraryExporterPackageTests.cs | 2 +- .../WindowsOnlyFactAttribute.cs | 11 ++++ .../PublishDesktopTests.cs | 52 +++++++++++++++++ test/dotnet-publish.Tests/project.json | 9 ++- 22 files changed, 256 insertions(+), 49 deletions(-) create mode 100644 TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktop/.noautobuild create mode 100644 TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktop/project.json create mode 100644 TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktopWithRuntimes/.noautobuild create mode 100644 TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktopWithRuntimes/project.json rename src/{Microsoft.DotNet.Cli.Utils => Microsoft.DotNet.ProjectModel}/RuntimeEnvironmentRidExtensions.cs (100%) create mode 100644 test/dotnet-publish.Tests/PublishDesktopTests.cs diff --git a/TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktop/.noautobuild b/TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktop/.noautobuild new file mode 100644 index 000000000..e69de29bb diff --git a/TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktop/project.json b/TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktop/project.json new file mode 100644 index 000000000..38aa90cba --- /dev/null +++ b/TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktop/project.json @@ -0,0 +1,17 @@ +{ + "version": "1.0.0-*", + "dependencies": { + "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-20113", + "Microsoft.AspNetCore.Hosting": "1.0.0-rc2-20113", + "Microsoft.Extensions.Logging.Console": "1.0.0-rc2-20254" + }, + "compilationOptions": { + "emitEntryPoint": true + }, + "compile": [ + "../../../TestProjects/KestrelSample/src/*.cs" + ], + "frameworks": { + "net451": { } + } +} diff --git a/TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktopWithRuntimes/.noautobuild b/TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktopWithRuntimes/.noautobuild new file mode 100644 index 000000000..e69de29bb diff --git a/TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktopWithRuntimes/project.json b/TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktopWithRuntimes/project.json new file mode 100644 index 000000000..8242cc27a --- /dev/null +++ b/TestAssets/DesktopTestProjects/DesktopKestrelSample/KestrelDesktopWithRuntimes/project.json @@ -0,0 +1,21 @@ +{ + "version": "1.0.0-*", + "dependencies": { + "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-20113", + "Microsoft.AspNetCore.Hosting": "1.0.0-rc2-20113", + "Microsoft.Extensions.Logging.Console": "1.0.0-rc2-20254" + }, + "compilationOptions": { + "emitEntryPoint": true + }, + "compile": [ + "../../../TestProjects/KestrelSample/src/*.cs" + ], + "frameworks": { + "net451": { } + }, + "runtimes": { + "win7-x64": {}, + "osx.10.11-x64": {} + } +} diff --git a/TestAssets/TestPackages/dotnet-dependency-tool-invoker/dotnet-dependency-tool-invoker.xproj b/TestAssets/TestPackages/dotnet-dependency-tool-invoker/dotnet-dependency-tool-invoker.xproj index 7811e7531..f115e2bc5 100644 --- a/TestAssets/TestPackages/dotnet-dependency-tool-invoker/dotnet-dependency-tool-invoker.xproj +++ b/TestAssets/TestPackages/dotnet-dependency-tool-invoker/dotnet-dependency-tool-invoker.xproj @@ -9,9 +9,8 @@ c26a48bb-193f-450c-ab09-4d3324c78188 dotnet-dependency-tool-invoker ..\..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\..\artifacts\bin\$(MSBuildProjectName)\ + ..\..\..\artifacts\ - 2.0 diff --git a/TestAssets/TestProjects/TestAppWithArgs/TestAppWithArgs.xproj b/TestAssets/TestProjects/TestAppWithArgs/TestAppWithArgs.xproj index fbd214cbd..9a39a775b 100644 --- a/TestAssets/TestProjects/TestAppWithArgs/TestAppWithArgs.xproj +++ b/TestAssets/TestProjects/TestAppWithArgs/TestAppWithArgs.xproj @@ -9,9 +9,8 @@ da8e0e9e-a6d6-4583-864c-8f40465e3a48 TestAppWithArgs ..\..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\..\artifacts\bin\$(MSBuildProjectName)\ + ..\..\..\artifacts\ - 2.0 diff --git a/TestAssets/TestProjects/TestAppWithContents/TestAppWithContents.xproj b/TestAssets/TestProjects/TestAppWithContents/TestAppWithContents.xproj index 00103e020..fa06ff0b3 100644 --- a/TestAssets/TestProjects/TestAppWithContents/TestAppWithContents.xproj +++ b/TestAssets/TestProjects/TestAppWithContents/TestAppWithContents.xproj @@ -9,9 +9,8 @@ 0138cb8f-4aa9-4029-a21e-c07c30f425ba TestAppWithContents ..\..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\..\artifacts\bin\$(MSBuildProjectName)\ + ..\..\..\artifacts\ - 2.0 diff --git a/scripts/dotnet-cli-build/CompileTargets.cs b/scripts/dotnet-cli-build/CompileTargets.cs index 17056f0f8..dafea7f89 100644 --- a/scripts/dotnet-cli-build/CompileTargets.cs +++ b/scripts/dotnet-cli-build/CompileTargets.cs @@ -248,7 +248,6 @@ namespace Microsoft.DotNet.Cli.Build CleanOutputDir(Path.Combine(Dirs.Stage1, "sdk")); FS.CopyRecursive(Dirs.Stage1, Dirs.Stage1Symbols); - RemovePdbsFromDir(Path.Combine(Dirs.Stage1, "sdk")); return result; } @@ -301,8 +300,6 @@ namespace Microsoft.DotNet.Cli.Build CleanOutputDir(Path.Combine(Dirs.Stage2, "sdk")); FS.CopyRecursive(Dirs.Stage2, Dirs.Stage2Symbols); - RemovePdbsFromDir(Path.Combine(Dirs.Stage2, "sdk")); - return c.Success(); } diff --git a/scripts/dotnet-cli-build/TestTargets.cs b/scripts/dotnet-cli-build/TestTargets.cs index d19ef1ea1..70e414da9 100644 --- a/scripts/dotnet-cli-build/TestTargets.cs +++ b/scripts/dotnet-cli-build/TestTargets.cs @@ -245,7 +245,6 @@ namespace Microsoft.DotNet.Cli.Build Rmdir(Path.Combine(Dirs.NuGetPackages, ".tools", packageProject.Name)); } } - return c.Success(); } diff --git a/src/Microsoft.DotNet.Compiler.Common/Executable.cs b/src/Microsoft.DotNet.Compiler.Common/Executable.cs index 5582e7d57..89878dbe9 100644 --- a/src/Microsoft.DotNet.Compiler.Common/Executable.cs +++ b/src/Microsoft.DotNet.Compiler.Common/Executable.cs @@ -147,16 +147,10 @@ namespace Microsoft.Dotnet.Cli.Compiler.Common private void WriteFramework(JObject runtimeOptions, LibraryExporter exporter) { - var redistPackage = _context.RootProject.Dependencies - .Where(r => r.Type.Equals(LibraryDependencyType.Platform)) - .ToList(); - if (redistPackage.Count > 0) + var redistPackage = _context.PlatformLibrary; + if (redistPackage != null) { - if (redistPackage.Count > 1) - { - throw new InvalidOperationException("Multiple packages with type: \"platform\" were specified!"); - } - var packageName = redistPackage.Single().Name; + var packageName = redistPackage.Identity.Name; var redistExport = exporter.GetAllExports() .FirstOrDefault(e => e.Library.Identity.Name.Equals(packageName)); diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs index 8fc68ba34..d3b09991f 100644 --- a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs +++ b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs @@ -20,6 +20,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation { private readonly string _configuration; private readonly string _runtime; + private readonly string[] _runtimeFallbacks; private readonly ProjectDescription _rootProject; private readonly string _buildBasePath; private readonly string _solutionRootPath; @@ -28,6 +29,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation LibraryManager manager, string configuration, string runtime, + string[] runtimeFallbacks, string buildBasePath, string solutionRootPath) { @@ -39,6 +41,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation LibraryManager = manager; _configuration = configuration; _runtime = runtime; + _runtimeFallbacks = runtimeFallbacks; _buildBasePath = buildBasePath; _solutionRootPath = solutionRootPath; _rootProject = rootProject; @@ -96,7 +99,6 @@ namespace Microsoft.DotNet.ProjectModel.Compilation var analyzerReferences = new List(); var libraryExport = GetExport(library); - // We need to filter out source references from non-root libraries, // so we rebuild the library export foreach (var reference in libraryExport.CompilationAssemblies) @@ -114,12 +116,22 @@ namespace Microsoft.DotNet.ProjectModel.Compilation analyzerReferences.AddRange(libraryExport.AnalyzerReferences); } - yield return LibraryExportBuilder.Create(library) + var builder = LibraryExportBuilder.Create(library); + if (_runtime != null && _runtimeFallbacks != null) + { + builder.WithRuntimeAssemblyGroups(TrimAssetGroups(libraryExport.RuntimeAssemblyGroups, _runtimeFallbacks)); + builder.WithNativeLibraryGroups(TrimAssetGroups(libraryExport.NativeLibraryGroups, _runtimeFallbacks)); + } + else + { + builder.WithRuntimeAssemblyGroups(libraryExport.RuntimeAssemblyGroups); + builder.WithNativeLibraryGroups(libraryExport.NativeLibraryGroups); + } + + yield return builder .WithCompilationAssemblies(compilationAssemblies) .WithSourceReferences(sourceReferences) - .WithRuntimeAssemblyGroups(libraryExport.RuntimeAssemblyGroups) .WithRuntimeAssets(libraryExport.RuntimeAssets) - .WithNativeLibraryGroups(libraryExport.NativeLibraryGroups) .WithEmbedddedResources(libraryExport.EmbeddedResources) .WithAnalyzerReference(analyzerReferences) .WithResourceAssemblies(libraryExport.ResourceAssemblies) @@ -127,6 +139,27 @@ namespace Microsoft.DotNet.ProjectModel.Compilation } } + private IEnumerable TrimAssetGroups(IEnumerable runtimeAssemblyGroups, + string[] runtimeFallbacks) + { + LibraryAssetGroup runtimeAssets; + foreach (var rid in runtimeFallbacks) + { + runtimeAssets = runtimeAssemblyGroups.GetRuntimeGroup(rid); + if (runtimeAssets != null) + { + yield return new LibraryAssetGroup(runtimeAssets.Assets); + yield break; + } + } + + runtimeAssets = runtimeAssemblyGroups.GetDefaultGroup(); + if (runtimeAssets != null) + { + yield return runtimeAssets; + } + } + /// /// Create a LibraryExport from LibraryDescription. /// diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs b/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs index 4ac31b2ec..303269f23 100644 --- a/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs +++ b/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs @@ -9,17 +9,47 @@ using Microsoft.DotNet.ProjectModel.Compilation; using Microsoft.DotNet.ProjectModel.Graph; using Microsoft.DotNet.ProjectModel.Resolution; using NuGet.Frameworks; +using NuGet.RuntimeModel; namespace Microsoft.DotNet.ProjectModel { + class RuntimeGraphCollector + { + private const string RuntimeJsonFileName = "runtime.json"; + + public static RuntimeGraph Collect(IEnumerable libraries) + { + var graph = RuntimeGraph.Empty; + foreach (var library in libraries) + { + if (library.Identity.Type == LibraryType.Package) + { + var runtimeJson = ((PackageDescription)library).PackageLibrary.Files.FirstOrDefault(f => f == RuntimeJsonFileName); + if (runtimeJson != null) + { + var runtimeJsonFullName = Path.Combine(library.Path, runtimeJson); + graph = RuntimeGraph.Merge(graph, JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonFullName)); + } + } + } + return graph; + } + } + public class ProjectContext { + private string[] _runtimeFallbacks; + public GlobalSettings GlobalSettings { get; } public ProjectDescription RootProject { get; } public NuGetFramework TargetFramework { get; } + public LibraryDescription PlatformLibrary { get; } + + public bool IsPortable { get; } + public string RuntimeIdentifier { get; } public Project ProjectFile => RootProject?.Project; @@ -37,7 +67,9 @@ namespace Microsoft.DotNet.ProjectModel internal ProjectContext( GlobalSettings globalSettings, ProjectDescription rootProject, + LibraryDescription platformLibrary, NuGetFramework targetFramework, + bool isPortable, string runtimeIdentifier, string packagesDirectory, LibraryManager libraryManager, @@ -45,16 +77,29 @@ namespace Microsoft.DotNet.ProjectModel { GlobalSettings = globalSettings; RootProject = rootProject; + PlatformLibrary = platformLibrary; TargetFramework = targetFramework; RuntimeIdentifier = runtimeIdentifier; PackagesDirectory = packagesDirectory; LibraryManager = libraryManager; LockFile = lockfile; + IsPortable = isPortable; } public LibraryExporter CreateExporter(string configuration, string buildBasePath = null) { - return new LibraryExporter(RootProject, LibraryManager, configuration, RuntimeIdentifier, buildBasePath, RootDirectory); + if (IsPortable && RuntimeIdentifier != null && _runtimeFallbacks == null) + { + var graph = RuntimeGraphCollector.Collect(LibraryManager.GetLibraries()); + _runtimeFallbacks = graph.ExpandRuntime(RuntimeIdentifier).ToArray(); + } + return new LibraryExporter(RootProject, + LibraryManager, + configuration, + RuntimeIdentifier, + _runtimeFallbacks, + buildBasePath, + RootDirectory); } /// @@ -146,15 +191,12 @@ namespace Microsoft.DotNet.ProjectModel return this; } - var standalone = !RootProject.Dependencies - .Any(d => d.Type.Equals(LibraryDependencyType.Platform)); - var context = CreateBuilder(ProjectFile.ProjectFilePath, TargetFramework) - .WithRuntimeIdentifiers(standalone ? runtimeIdentifiers : Enumerable.Empty()) + .WithRuntimeIdentifiers(runtimeIdentifiers) .WithLockFile(LockFile) .Build(); - if (standalone && context.RuntimeIdentifier == null) + if (!context.IsPortable && context.RuntimeIdentifier == null) { // We are standalone, but don't support this runtime var rids = string.Join(", ", runtimeIdentifiers); diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs b/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs index 2399d1d92..0ce1a0f95 100644 --- a/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs +++ b/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs @@ -9,6 +9,7 @@ using System.Text; using Microsoft.DotNet.ProjectModel.Graph; using Microsoft.DotNet.ProjectModel.Resolution; using Microsoft.Extensions.Internal; +using Microsoft.Extensions.PlatformAbstractions; using NuGet.Frameworks; namespace Microsoft.DotNet.ProjectModel @@ -32,7 +33,7 @@ namespace Microsoft.DotNet.ProjectModel private string PackagesDirectory { get; set; } private string ReferenceAssembliesPath { get; set; } - + private bool IsDesignTime { get; set; } private Func ProjectResolver { get; set; } @@ -118,7 +119,7 @@ namespace Microsoft.DotNet.ProjectModel Settings = settings; return this; } - + public ProjectContextBuilder AsDesignTime() { IsDesignTime = true; @@ -197,10 +198,20 @@ namespace Microsoft.DotNet.ProjectModel libraries.Add(new LibraryKey(mainProject.Identity.Name), mainProject); } + LibraryRange? platformDependency = null; + if (mainProject != null) + { + platformDependency = mainProject.Dependencies + .Where(d => d.Type.Equals(LibraryDependencyType.Platform)) + .Cast() + .FirstOrDefault(); + } + bool isPortable = platformDependency != null || TargetFramework.IsDesktop(); + LockFileTarget target = null; if (lockFileLookup != null) { - target = SelectTarget(LockFile); + target = SelectTarget(LockFile, isPortable); if (target != null) { var nugetPackageResolver = new PackageDependencyProvider(PackagesDirectory, frameworkReferenceResolver); @@ -209,6 +220,30 @@ namespace Microsoft.DotNet.ProjectModel } } + string runtime; + if (TargetFramework.IsDesktop()) + { + var legacyRuntime = PlatformServices.Default.Runtime.GetLegacyRestoreRuntimeIdentifier(); + if (RuntimeIdentifiers.Contains(legacyRuntime)) + { + runtime = legacyRuntime; + } + else + { + runtime = RuntimeIdentifiers.FirstOrDefault(); + } + } + else + { + runtime = target?.RuntimeIdentifier; + } + + LibraryDescription platformLibrary = null; + if(platformDependency != null) + { + platformLibrary = libraries[new LibraryKey(platformDependency.Value.Name)]; + } + var referenceAssemblyDependencyResolver = new ReferenceAssemblyDependencyResolver(frameworkReferenceResolver); bool requiresFrameworkAssemblies; @@ -272,8 +307,10 @@ namespace Microsoft.DotNet.ProjectModel return new ProjectContext( GlobalSettings, mainProject, + platformLibrary, TargetFramework, - target?.RuntimeIdentifier, + isPortable, + runtime, PackagesDirectory, libraryManager, LockFile); @@ -454,15 +491,18 @@ namespace Microsoft.DotNet.ProjectModel } } - private LockFileTarget SelectTarget(LockFile lockFile) + private LockFileTarget SelectTarget(LockFile lockFile, bool isPortable) { - foreach (var runtimeIdentifier in RuntimeIdentifiers) + if (!isPortable) { - foreach (var scanTarget in lockFile.Targets) + foreach (var runtimeIdentifier in RuntimeIdentifiers) { - if (Equals(scanTarget.TargetFramework, TargetFramework) && string.Equals(scanTarget.RuntimeIdentifier, runtimeIdentifier, StringComparison.Ordinal)) + foreach (var scanTarget in lockFile.Targets) { - return scanTarget; + if (Equals(scanTarget.TargetFramework, TargetFramework) && string.Equals(scanTarget.RuntimeIdentifier, runtimeIdentifier, StringComparison.Ordinal)) + { + return scanTarget; + } } } } diff --git a/src/Microsoft.DotNet.Cli.Utils/RuntimeEnvironmentRidExtensions.cs b/src/Microsoft.DotNet.ProjectModel/RuntimeEnvironmentRidExtensions.cs similarity index 100% rename from src/Microsoft.DotNet.Cli.Utils/RuntimeEnvironmentRidExtensions.cs rename to src/Microsoft.DotNet.ProjectModel/RuntimeEnvironmentRidExtensions.cs diff --git a/src/Microsoft.DotNet.ProjectModel/project.json b/src/Microsoft.DotNet.ProjectModel/project.json index 24e563c6b..321004869 100644 --- a/src/Microsoft.DotNet.ProjectModel/project.json +++ b/src/Microsoft.DotNet.ProjectModel/project.json @@ -17,6 +17,7 @@ }, "Newtonsoft.Json": "7.0.1", "NuGet.Packaging": "3.5.0-beta-1130", + "NuGet.RuntimeModel": "3.5.0-beta-1130", "System.Reflection.Metadata": "1.3.0-rc2-24008" }, "frameworks": { diff --git a/src/dotnet/commands/dotnet-compile/CompilerCommandApp.cs b/src/dotnet/commands/dotnet-compile/CompilerCommandApp.cs index 8da23d62e..fea09a404 100644 --- a/src/dotnet/commands/dotnet-compile/CompilerCommandApp.cs +++ b/src/dotnet/commands/dotnet-compile/CompilerCommandApp.cs @@ -161,7 +161,7 @@ namespace Microsoft.DotNet.Tools.Compiler Debug.Assert(targets.Count == 1); } - Debug.Assert(targets.All(t => string.IsNullOrEmpty(t.RuntimeIdentifier))); + //Debug.Assert(targets.All(t => string.IsNullOrEmpty(t.RuntimeIdentifier))); var success = execute(targets, this); diff --git a/src/dotnet/commands/dotnet-publish/PublishCommand.cs b/src/dotnet/commands/dotnet-publish/PublishCommand.cs index 81b3a32f6..90ae4e8fb 100644 --- a/src/dotnet/commands/dotnet-publish/PublishCommand.cs +++ b/src/dotnet/commands/dotnet-publish/PublishCommand.cs @@ -128,21 +128,19 @@ namespace Microsoft.DotNet.Tools.Publish // Use a library exporter to collect publish assets var exporter = context.CreateExporter(configuration, buildBasePath); - var isPortable = string.IsNullOrEmpty(context.RuntimeIdentifier); - // Collect all exports and organize them var packageExports = exporter.GetAllExports() .Where(e => e.Library.Identity.Type.Equals(LibraryType.Package)) .ToDictionary(e => e.Library.Identity.Name); - var collectExclusionList = isPortable ? GetExclusionList(context, packageExports) : new HashSet(); + var collectExclusionList = context.IsPortable ? GetExclusionList(context, packageExports) : new HashSet(); var exports = exporter.GetAllExports(); foreach (var export in exports.Where(e => !collectExclusionList.Contains(e.Library.Identity.Name))) { Reporter.Verbose.WriteLine($"publish: Publishing {export.Library.Identity.ToString().Green().Bold()} ..."); - PublishAssetGroups(export.RuntimeAssemblyGroups, outputPath, nativeSubdirectories: false, includeRuntimeGroups: isPortable); - PublishAssetGroups(export.NativeLibraryGroups, outputPath, nativeSubdirectories, includeRuntimeGroups: isPortable); + PublishAssetGroups(export.RuntimeAssemblyGroups, outputPath, nativeSubdirectories: false, includeRuntimeGroups: context.IsPortable); + PublishAssetGroups(export.NativeLibraryGroups, outputPath, nativeSubdirectories, includeRuntimeGroups: context.IsPortable); } if (options.PreserveCompilationContext.GetValueOrDefault()) @@ -152,7 +150,7 @@ namespace Microsoft.DotNet.Tools.Publish PublishRefs(export, outputPath, !collectExclusionList.Contains(export.Library.Identity.Name)); } } - + var buildOutputPaths = context.GetOutputPaths(configuration, buildBasePath, null); PublishBuildOutputFiles(buildOutputPaths, context, outputPath, Configuration); diff --git a/test/Installer/Microsoft.DotNet.Cli.Msi.Tests/Microsoft.DotNet.Cli.Msi.Tests.xproj b/test/Installer/Microsoft.DotNet.Cli.Msi.Tests/Microsoft.DotNet.Cli.Msi.Tests.xproj index 64ee27ba4..00b0d9710 100644 --- a/test/Installer/Microsoft.DotNet.Cli.Msi.Tests/Microsoft.DotNet.Cli.Msi.Tests.xproj +++ b/test/Installer/Microsoft.DotNet.Cli.Msi.Tests/Microsoft.DotNet.Cli.Msi.Tests.xproj @@ -9,7 +9,7 @@ 0B31C336-149D-471A-B7B1-27B0F1E80F83 Microsoft.DotNet.Cli.Msi.Tests ..\..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\..\artifacts\bin\$(MSBuildProjectName)\ + ..\..\..\artifacts\ 2.0 diff --git a/test/Microsoft.DotNet.ProjectModel.Tests/LibraryExporterPackageTests.cs b/test/Microsoft.DotNet.ProjectModel.Tests/LibraryExporterPackageTests.cs index 2c98adae6..0a555e7b0 100644 --- a/test/Microsoft.DotNet.ProjectModel.Tests/LibraryExporterPackageTests.cs +++ b/test/Microsoft.DotNet.ProjectModel.Tests/LibraryExporterPackageTests.cs @@ -328,7 +328,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests } var libraryManager = new LibraryManager(new[] { description }, new DiagnosticMessage[] { }, ""); - var allExports = new LibraryExporter(rootProjectDescription, libraryManager, "config", "runtime", "basepath", "solutionroot").GetAllExports(); + var allExports = new LibraryExporter(rootProjectDescription, libraryManager, "config", "runtime", null, "basepath", "solutionroot").GetAllExports(); var export = allExports.Single(); return export; } diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/WindowsOnlyFactAttribute.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/WindowsOnlyFactAttribute.cs index fbc766729..07341b2a7 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/WindowsOnlyFactAttribute.cs +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/WindowsOnlyFactAttribute.cs @@ -16,4 +16,15 @@ namespace Microsoft.DotNet.Tools.Test.Utilities } } } + + public class WindowsOnlyTheoryAttribute : TheoryAttribute + { + public WindowsOnlyTheoryAttribute() + { + if (PlatformServices.Default.Runtime.OperatingSystemPlatform != Platform.Windows) + { + this.Skip = "This test requires windows to run"; + } + } + } } \ No newline at end of file diff --git a/test/dotnet-publish.Tests/PublishDesktopTests.cs b/test/dotnet-publish.Tests/PublishDesktopTests.cs new file mode 100644 index 000000000..331e1e595 --- /dev/null +++ b/test/dotnet-publish.Tests/PublishDesktopTests.cs @@ -0,0 +1,52 @@ +using System.IO; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.TestFramework; +using Microsoft.DotNet.Tools.Test.Utilities; +using Xunit; + +namespace Microsoft.DotNet.Tools.Publish.Tests +{ + public class PublishDesktopTests : TestBase + { + [WindowsOnlyTheory] + [InlineData("KestrelDesktopWithRuntimes", "http://localhost:20201", null)] + [InlineData("KestrelDesktopWithRuntimes", "http://localhost:20201", "win7-x64")] + [InlineData("KestrelDesktop", "http://localhost:20203", null)] + [InlineData("KestrelDesktop", "http://localhost:20204", "win7-x64")] + public async Task DesktopApp_WithKestrel_WorksWhenPublishedWithRID(string project, string url, string runtime) + { + var testInstance = GetTestInstance(project) + .WithLockFiles() + .WithBuildArtifacts(); + + var publishCommand = new PublishCommand(testInstance.TestRoot, runtime); + var result = await publishCommand.ExecuteAsync(); + + result.Should().Pass(); + + // Test the output + var outputDir = publishCommand.GetOutputDirectory(portable: false); + outputDir.Should().HaveFile("libuv.dll"); + outputDir.Should().HaveFile(publishCommand.GetOutputExecutable()); + + var command = new TestCommand(Path.Combine(outputDir.FullName, publishCommand.GetOutputExecutable())); + try + { + command.Execute(url); + NetworkHelper.IsServerUp(url).Should().BeTrue($"Unable to connect to kestrel server - {project} @ {url}"); + NetworkHelper.TestGetRequest(url, url); + } + finally + { + command.KillTree(); + } + } + + private static TestInstance GetTestInstance(string name) + { + return TestAssetsManager.CreateTestInstance(Path.Combine("..", "DesktopTestProjects", "DesktopKestrelSample", name)); + } + } +} diff --git a/test/dotnet-publish.Tests/project.json b/test/dotnet-publish.Tests/project.json index 6a50d1868..52cf37469 100644 --- a/test/dotnet-publish.Tests/project.json +++ b/test/dotnet-publish.Tests/project.json @@ -10,8 +10,13 @@ "Microsoft.DotNet.Tools.Tests.Utilities": { "target": "project" }, - "Microsoft.DotNet.Cli.Utils": { - "target": "project" + "frameworks": { + "netstandardapp1.5": { + "imports": [ + "dnxcore50", + "portable-net45+win8" + ] + } }, "xunit": "2.1.0", "xunit.netcore.extensions": "1.0.0-prerelease-00206",