Enable Cross Publishing and add tests

WIP

WIP

WIP

Test out not publishing runtimeAssets

WIP

WiP x-publish

update cross-publish-test

Update Cross Publish tests

remove --config from restore

fix build

update cross publish tests

fix test compilation error

test failure fix

fix test failure

update tests

tracing

fix desktop publishing

do publish with no build, call build manually

fix

Make host publish optional, fix faux libraries?

update

Cross Publish test working

try changing test to netcore.app

fallback to host from current platform

revert change to project.json to target Microsoft.NETCore.App

fallback to compilation build output

update kestrel standalone app project.json

Make project tools command resolver test more self-contained.

make Kestrel Standalone restore against N-1
This commit is contained in:
Bryan Thornbury 2016-04-01 18:49:36 -07:00
parent 1a0b9bba98
commit 709f7b7d14
12 changed files with 220 additions and 36 deletions

View file

@ -0,0 +1,12 @@
using System;
namespace StandaloneApp
{
public static class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}
}
}

View file

@ -0,0 +1,35 @@
{
"compilationOptions": {
"emitEntryPoint": true
},
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dnxcore50",
"portable-net45+win8"
],
"dependencies": {
"Microsoft.NETCore.App": "1.0.0-rc2-*"
}
}
},
"runtimes": {
"win7-x64": {},
"win7-x86": {},
"osx.10.10-x64": {},
"osx.10.11-x64": {},
"ubuntu.14.04-x64": {},
"centos.7-x64": {},
"rhel.7.2-x64": {},
"debian.8.2-x64": {}
},
"runtimeOptions": {
"somethingString": "anything",
"somethingBoolean": true,
"someArray": ["one", "two"],
"someObject": {
"someProperty": "someValue"
}
}
}

View file

@ -12,9 +12,9 @@
"../src/*.cs"
],
"frameworks": {
"netstandardapp1.5": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": "1.0.0-rc2-24008"
"Microsoft.NETCore.App": "1.0.0-rc2-3002306"
},
"imports": [
"dnxcore50",

View file

@ -422,6 +422,9 @@ namespace Microsoft.DotNet.Cli.Build
File.Copy(
Path.Combine(Dirs.Corehost, HostPolicyBaseName),
Path.Combine(SharedFrameworkNameAndVersionRoot, HostPolicyBaseName), true);
File.Copy(
Path.Combine(Dirs.Corehost, DotnetHostFxrBaseName),
Path.Combine(SharedFrameworkNameAndVersionRoot, DotnetHostFxrBaseName), true);
if (File.Exists(Path.Combine(SharedFrameworkNameAndVersionRoot, "mscorlib.ni.dll")))
{

View file

@ -58,7 +58,7 @@ namespace Microsoft.DotNet.Cli.Build
[Target(nameof(RestoreTestAssetPackages), nameof(BuildTestAssetPackages))]
public static BuildTargetResult SetupTestPackages(BuildTargetContext c) => c.Success();
[Target(nameof(RestoreTestAssetProjects), nameof(RestoreDesktopTestAssetProjects), nameof(BuildTestAssetProjects))]
[Target(nameof(RestoreTestAssetProjects), nameof(RestoreDesktopTestAssetProjects), nameof(RestoreCrossPublishTestAssetProjects), nameof(BuildTestAssetProjects))]
public static BuildTargetResult SetupTestProjects(BuildTargetContext c) => c.Success();
[Target]
@ -137,6 +137,18 @@ namespace Microsoft.DotNet.Cli.Build
return c.Success();
}
[Target]
public static BuildTargetResult RestoreCrossPublishTestAssetProjects(BuildTargetContext c)
{
var dotnet = DotNetCli.Stage2;
dotnet.Restore("--verbosity", "verbose")
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "CrossPublishTestProjects"))
.Execute().EnsureSuccessful();
return c.Success();
}
[Target(nameof(CleanTestPackages), nameof(CleanProductPackages))]
public static BuildTargetResult BuildTestAssetPackages(BuildTargetContext c)

View file

@ -34,6 +34,7 @@ namespace Microsoft.DotNet.Cli.Utils
public static readonly string ResponseFileSuffix = ".rsp";
public static readonly string PublishedHostExecutableName = "dotnet";
public static readonly string HostExecutableName = "corehost" + ExeSuffix;
public static readonly string[] HostBinaryNames = new string[] {
HostExecutableName,

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System;
using System.Linq;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Compilation;

View file

@ -139,11 +139,10 @@ namespace Microsoft.DotNet.Tools.Publish
var exports = exporter.GetAllExports();
foreach (var export in exports.Where(e => !collectExclusionList.Contains(e.Library.Identity.Name)))
{
Reporter.Verbose.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ...");
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);
export.RuntimeAssets.StructuredCopyTo(outputPath, outputPaths.IntermediateOutputDirectoryPath);
}
if (options.PreserveCompilationContext.GetValueOrDefault())
@ -153,19 +152,9 @@ namespace Microsoft.DotNet.Tools.Publish
PublishRefs(export, outputPath, !collectExclusionList.Contains(export.Library.Identity.Name));
}
}
if (context.ProjectFile.HasRuntimeOutput(configuration) && !context.TargetFramework.IsDesktop())
{
// 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);
PublishFiles(
new[] {
buildOutputPaths.RuntimeFiles.DepsJson,
buildOutputPaths.RuntimeFiles.RuntimeConfigJson
},
outputPath);
}
var buildOutputPaths = context.GetOutputPaths(configuration, buildBasePath, null);
PublishBuildOutputFiles(buildOutputPaths, context, outputPath, Configuration);
var contentFiles = new ContentFiles(context);
contentFiles.StructuredCopyTo(outputPath);
@ -173,17 +162,72 @@ namespace Microsoft.DotNet.Tools.Publish
// Publish a host if this is an application
if (options.EmitEntryPoint.GetValueOrDefault() && !string.IsNullOrEmpty(context.RuntimeIdentifier))
{
Reporter.Verbose.WriteLine($"Copying native host to output to create fully standalone output.");
PublishHost(context, outputPath, options);
Reporter.Verbose.WriteLine($"publish: Renaming native host in output to create fully standalone output.");
RenamePublishedHost(context, outputPath, options);
}
RunScripts(context, ScriptNames.PostPublish, contextVariables);
Reporter.Output.WriteLine($"Published to {outputPath}".Green().Bold());
Reporter.Output.WriteLine($"publish: Published to {outputPath}".Green().Bold());
return true;
}
private void PublishBuildOutputFiles(OutputPaths buildOutputPaths, ProjectContext context, string outputPath, string configuration)
{
List<string> filesToPublish = new List<string>();
string[] buildOutputFiles = null;
if (context.ProjectFile.HasRuntimeOutput(configuration))
{
Reporter.Verbose.WriteLine($"publish: using runtime build output files");
buildOutputFiles = new string[]
{
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} ");
}
}
Reporter.Verbose.WriteLine($"publish: Copying build output files:\n {string.Join("\n", filesToPublish)}");
PublishFiles(
filesToPublish,
outputPath);
}
private bool InvokeBuildOnProject(ProjectContext context, string buildBasePath, string configuration)
{
var args = new List<string>()
@ -272,33 +316,60 @@ namespace Microsoft.DotNet.Tools.Publish
}
}
private static int PublishHost(ProjectContext context, string outputPath, CommonCompilerOptions compilationOptions)
private static int RenamePublishedHost(ProjectContext context, string outputPath, CommonCompilerOptions compilationOptions)
{
if (context.TargetFramework.IsDesktop())
{
return 0;
}
foreach (var binaryName in Constants.HostBinaryNames)
var publishedHostFile = ResolvePublishedHostFile(outputPath);
if (publishedHostFile == null)
{
var hostBinaryPath = Path.Combine(AppContext.BaseDirectory, binaryName);
if (!File.Exists(hostBinaryPath))
{
Reporter.Error.WriteLine($"Cannot find {binaryName} in the dotnet directory.".Red());
return 1;
}
Reporter.Output.WriteLine($"publish: warning: host executable not available in dependencies, using host for current platform");
// TODO should this be an error?
var outputBinaryName = binaryName.Equals(Constants.HostExecutableName)
? compilationOptions.OutputName + Constants.ExeSuffix
: binaryName;
var outputBinaryPath = Path.Combine(outputPath, outputBinaryName);
CoreHost.CopyTo(outputPath, compilationOptions.OutputName + Constants.ExeSuffix);
return 0;
}
File.Copy(hostBinaryPath, outputBinaryPath, overwrite: true);
var publishedHostExtension = Path.GetExtension(publishedHostFile);
var renamedHostName = compilationOptions.OutputName + publishedHostExtension;
var renamedHostFile = Path.Combine(outputPath, renamedHostName);
try
{
Reporter.Verbose.WriteLine($"publish: renaming published host {publishedHostFile} to {renamedHostFile}");
File.Copy(publishedHostFile, renamedHostFile, true);
File.Delete(publishedHostFile);
}
catch (Exception e)
{
Reporter.Error.WriteLine($"publish: Failed to rename {publishedHostFile} to {renamedHostFile}: {e.Message}");
return 1;
}
return 0;
}
private static string ResolvePublishedHostFile(string outputPath)
{
var tryExtensions = new string[] { "", ".exe" };
foreach (var extension in tryExtensions)
{
var hostFile = Path.Combine(outputPath, Constants.PublishedHostExecutableName + extension);
if (File.Exists(hostFile))
{
Reporter.Verbose.WriteLine($"resolved published host: {hostFile}");
return hostFile;
}
}
Reporter.Verbose.WriteLine($"failed to resolve published host in: {outputPath}");
return null;
}
private static void PublishFiles(IEnumerable<string> files, string outputPath)
{
foreach (var file in files)
@ -326,6 +397,7 @@ namespace Microsoft.DotNet.Tools.Publish
Directory.CreateDirectory(destinationDirectory);
}
Reporter.Verbose.WriteLine($"Publishing file {Path.GetFileName(file.RelativePath)} to {destinationDirectory}");
File.Copy(file.ResolvedPath, Path.Combine(destinationDirectory, file.FileName), overwrite: true);
}
}

View file

@ -218,6 +218,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
projectToolsCommandResolver.GenerateDepsJsonFile(lockFile, depsJsonFile);
File.ReadAllText(depsJsonFile).Should().Be("temp");
File.Delete(depsJsonFile);
}
private ProjectToolsCommandResolver SetupProjectToolsCommandResolver(

View file

@ -55,13 +55,20 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
{
if (s_testsAssetsMgr == null)
{
string assetsRoot = Path.Combine(RepoRoot, "TestAssets", "TestProjects");
s_testsAssetsMgr = new TestAssetsManager(assetsRoot);
s_testsAssetsMgr = GetTestGroupTestAssetsManager("TestProjects");
}
return s_testsAssetsMgr;
}
}
protected static TestAssetsManager GetTestGroupTestAssetsManager(string testGroup)
{
string assetsRoot = Path.Combine(RepoRoot, "TestAssets", testGroup);
var testAssetsMgr = new TestAssetsManager(assetsRoot);
return testAssetsMgr;
}
protected TestBase()
{

View file

@ -92,6 +92,46 @@ namespace Microsoft.DotNet.Tools.Publish.Tests
publishCommand.Execute().Should().Fail();
}
[Theory]
[InlineData("centos.7-x64", "", new string[] { "libhostfxr.so", "libcoreclr.so", "libhostpolicy.so" })]
[InlineData("rhel.7.2-x64", "", new string[] { "libhostfxr.so", "libcoreclr.so", "libhostpolicy.so" })]
[InlineData("ubuntu.14.04-x64", "", new string[] { "libhostfxr.so", "libcoreclr.so", "libhostpolicy.so" })]
[InlineData("win7-x64", ".exe", new string[] { "hostfxr.dll", "coreclr.dll", "hostpolicy.dll" })]
[InlineData("osx.10.11-x64", "", new string[] { "libhostfxr.dylib", "libcoreclr.dylib", "libhostpolicy.dylib" })]
public void CrossPublishingSucceedsAndHasExpectedArtifacts(string rid, string hostExtension, string[] expectedArtifacts)
{
var testNugetCache = "packages_cross_publish_test";
TestInstance instance = GetTestGroupTestAssetsManager("CrossPublishTestProjects")
.CreateTestInstance("StandaloneAppCrossPublish");
var testProject = Path.Combine(instance.TestRoot, "project.json");
var restoreCommand = new RestoreCommand();
restoreCommand.WorkingDirectory = Path.GetDirectoryName(testProject);
restoreCommand.Environment["NUGET_PACKAGES"] = testNugetCache;
restoreCommand.Execute().Should().Pass();
var buildCommand = new BuildCommand(testProject, runtime: rid);
buildCommand.WorkingDirectory = Path.GetDirectoryName(testProject);
buildCommand.Environment["NUGET_PACKAGES"] = testNugetCache;
buildCommand.Execute().Should().Pass();
var publishCommand = new PublishCommand(testProject, runtime: rid, noBuild: true);
publishCommand.Environment["NUGET_PACKAGES"] = testNugetCache;
publishCommand.WorkingDirectory = Path.GetDirectoryName(testProject);
publishCommand.Execute().Should().Pass();
var publishedDir = publishCommand.GetOutputDirectory();
publishedDir.Should().HaveFile("StandaloneAppCrossPublish"+ hostExtension);
foreach (var artifact in expectedArtifacts)
{
publishedDir.Should().HaveFile(artifact);
}
}
[Fact]
public void LibraryPublishTest()
{