Changing multiple dotnet commands to be aware of $configuration/$tfm folder structure under the --output path option.

Changing the build scripts to copy files over from debug\dnxcore and to check for the folders existence before trying that.
Making the build command aware of the subfolders and making E2E tests aware of subfolders.
Fixing compiler tests to look for the xml in the right plae taking into consideration the configuration and tfm.
Modifying publish tests to not take into consideration the runtime. This is a temporary change. will bring it back once the commands all understand rid.
Making the packaging step work by placing binaries where dotnet pack expects.
This commit is contained in:
Livar Cunha 2016-01-20 15:41:46 -08:00
parent b276fd2857
commit ac2d0e36a9
18 changed files with 165 additions and 58 deletions

View file

@ -19,6 +19,7 @@ $IntermediatePackagesDir = "$RepoRoot\artifacts\packages\intermediate"
$PackagesDir = "$RepoRoot\artifacts\packages"
New-Item -ItemType Directory -Force -Path $IntermediatePackagesDir
New-Item -ItemType Directory -Force -Path $PackagesDir\$Configuration\$Tfm
$Projects = @(
"Microsoft.DotNet.Cli.Utils",
@ -29,14 +30,16 @@ $Projects = @(
"Microsoft.Extensions.Testing.Abstractions"
)
cp $Stage2Dir\bin\* $PackagesDir\$Configuration\$Tfm -force -recurse
foreach ($ProjectName in $Projects) {
$ProjectFile = "$RepoRoot\src\$ProjectName\project.json"
& $toolsDir\dotnet pack "$ProjectFile" --basepath "$Stage2Dir\bin" --output "$IntermediatePackagesDir" $versionArg
& $toolsDir\dotnet pack "$ProjectFile" --basepath "$PackagesDir" --output "$IntermediatePackagesDir" $versionArg
if (!$?) {
Write-Host "$toolsDir\dotnet pack failed for: $ProjectFile"
Exit 1
}
}
Get-ChildItem $IntermediatePackagesDir -Filter *.nupkg | ? {$_.Name -NotLike "*.symbols.nupkg"} | Copy-Item -Destination $PackagesDir
Get-ChildItem $IntermediatePackagesDir\$Configuration -Filter *.nupkg | ? {$_.Name -NotLike "*.symbols.nupkg"} | Copy-Item -Destination $PackagesDir

View file

@ -49,6 +49,8 @@ $FilesToClean = @(
)
$RuntimeOutputDir = "$OutputDir\runtime\coreclr"
$binariesOutputDir = "$OutputDir\bin\$Configuration\$Tfm"
$runtimeBinariesOutputDir = "$RuntimeOutputDir\$Configuration\$Tfm"
# Publish each project
$Projects | ForEach-Object {
@ -59,6 +61,11 @@ $Projects | ForEach-Object {
}
}
if (Test-Path $binariesOutputDir) {
cp $binariesOutputDir\* $OutputDir\bin -force -recurse
Remove-Item $binariesOutputDir -recurse
}
# Publish the runtime
dotnet publish --framework "$Tfm" --runtime "$Rid" --output "$RuntimeOutputDir" --configuration "$Configuration" "$RepoRoot\src\Microsoft.DotNet.Runtime"
if (!$?) {
@ -66,6 +73,11 @@ if (!$?) {
Exit 1
}
if (Test-Path $runtimeBinariesOutputDir) {
cp $runtimeBinariesOutputDir\* $RuntimeOutputDir -force -recurse
Remove-Item $runtimeBinariesOutputDir -recurse
}
# Clean up bogus additional files
$FilesToClean | ForEach-Object {
$path = Join-Path $RuntimeOutputDir $_
@ -75,7 +87,13 @@ $FilesToClean | ForEach-Object {
}
# Copy the runtime app-local for the tools
cp -rec "$RuntimeOutputDir\*" "$OutputDir\bin"
cp -rec "$RuntimeOutputDir\*" "$OutputDir\bin" -ErrorVariable capturedErrors -ErrorAction SilentlyContinue
$capturedErrors | foreach-object {
if ($_ -notmatch "already exists") {
write-error $_
Exit 1
}
}
# Deploy the CLR host to the output
cp "$HostDir\corehost.exe" "$OutputDir\bin"
@ -96,6 +114,6 @@ if (-not (Test-Path "$OutputDir\bin\csc.ni.exe")) {
# Copy in AppDeps
if (-not (Test-Path "$OutputDir\bin\appdepsdk\")) {
$env:PATH = "$OutputDir\bin;$StartPath"
header "Acquiring Native App Dependencies"
_cmd "$RepoRoot\scripts\build\build_appdeps.cmd ""$OutputDir"""
header "Acquiring Native App Dependencies"
_cmd "$RepoRoot\scripts\build\build_appdeps.cmd ""$OutputDir"""
}

View file

@ -26,6 +26,11 @@ $TestProjects | ForEach-Object {
}
}
if (Test-Path $TestBinRoot\$Configuration\dnxcore50) {
cp $TestBinRoot\$Configuration\dnxcore50\* $TestBinRoot -force -recurse
Remove-Item $TestBinRoot\$Configuration\dnxcore50 -recurse
}
## Temporary Workaround for Native Compilation
## Need x64 Native Tools Dev Prompt Env Vars
## Tracked Here: https://github.com/dotnet/cli/issues/301

View file

@ -7,7 +7,13 @@
# Run Validation for Project.json dependencies
dotnet publish $RepoRoot\tools\MultiProjectValidator -o $Stage2Dir\..\tools
& "$Stage2Dir\..\tools\pjvalidate" "$RepoRoot\src"
$pjvalidatePath = "$Stage2Dir\..\tools\$Configuration\$Tfm"
if (! (Test-Path $pjvalidatePath)) {
$pjvalidatePath = "$Stage2Dir\..\tools"
}
& "$pjvalidatePath\pjvalidate" "$RepoRoot\src"
# TODO For release builds, this should be uncommented and fail.
# if (!$?) {
# Write-Host "Project Validation Failed"

View file

@ -0,0 +1,40 @@
// 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 NuGet.Frameworks;
namespace Microsoft.DotNet.ProjectModel
{
public class OutputPathCalculator
{
private readonly ProjectContext _project;
public string BaseRootOutputPath { get; }
public OutputPathCalculator(
ProjectContext project,
string rootOutputPath)
{
_project = project;
BaseRootOutputPath = string.IsNullOrWhiteSpace(rootOutputPath)
? Path.Combine(_project.ProjectDirectory, DirectoryNames.Bin)
: rootOutputPath;
}
public string GetOutputDirectoryPath(string buildConfiguration)
{
var outDir = Path.Combine(
BaseRootOutputPath,
buildConfiguration,
_project.TargetFramework.GetTwoDigitShortFolderName());
// if (!string.IsNullOrEmpty(_project.RuntimeIdentifier))
// {
// outDir = Path.Combine(outDir, _project.RuntimeIdentifier);
// }
return outDir;
}
}
}

View file

@ -147,5 +147,10 @@ namespace Microsoft.DotNet.ProjectModel
}
return outDir;
}
public OutputPathCalculator GetOutputPathCalculator(string rootOutputPath)
{
return new OutputPathCalculator(this, rootOutputPath);
}
}
}

View file

@ -39,7 +39,7 @@ namespace Microsoft.DotNet.Tools.Build
_args = (BuilderCommandApp) args.ShallowCopy();
// Set up Output Paths. They are unique per each CompileContext
_args.OutputValue = _rootProject.GetOutputPath(_args.ConfigValue, _args.OutputValue);
_args.OutputValue = _rootProject.GetOutputPathCalculator(_args.OutputValue).BaseRootOutputPath;
_args.IntermediateValue = _rootProject.GetIntermediateOutputPath(_args.ConfigValue, _args.IntermediateValue, _args.OutputValue);
// Set up dependencies
@ -338,7 +338,8 @@ namespace Microsoft.DotNet.Tools.Build
public static CompilerIO GetCompileIO(ProjectContext project, string config, string outputPath, string intermediaryOutputPath, ProjectDependenciesFacade dependencies)
{
var compilerIO = new CompilerIO(new List<string>(), new List<string>());
var compilationOutput = CompilerUtil.GetCompilationOutput(project.ProjectFile, project.TargetFramework, config, outputPath);
var binariesOutputPath = project.GetOutputPathCalculator(outputPath).GetOutputDirectoryPath(config);
var compilationOutput = CompilerUtil.GetCompilationOutput(project.ProjectFile, project.TargetFramework, config, binariesOutputPath);
// input: project.json
compilerIO.Inputs.Add(project.ProjectFile.ProjectFilePath);
@ -363,7 +364,7 @@ namespace Microsoft.DotNet.Tools.Build
AddCultureResources(project, intermediaryOutputPath, compilerIO);
// input / output: resources with culture
AddNonCultureResources(project, outputPath, compilerIO);
AddNonCultureResources(project, binariesOutputPath, compilerIO);
return compilerIO;
}

View file

@ -61,7 +61,7 @@ namespace Microsoft.DotNet.Tools.Compiler
ProjectContext context,
CompilerCommandApp args)
{
var outputPath = context.GetOutputPath(args.ConfigValue, args.OutputValue);
var outputPath = context.GetOutputPathCalculator(args.OutputValue).GetOutputDirectoryPath(args.ConfigValue);
var nativeOutputPath = Path.Combine(outputPath, "native");
var intermediateOutputPath =
context.GetIntermediateOutputPath(args.ConfigValue, args.IntermediateValue, outputPath);
@ -160,7 +160,7 @@ namespace Microsoft.DotNet.Tools.Compiler
private static bool CompileProject(ProjectContext context, CompilerCommandApp args)
{
// Set up Output Paths
string outputPath = context.GetOutputPath(args.ConfigValue, args.OutputValue);
var outputPath = context.GetOutputPathCalculator(args.OutputValue).GetOutputDirectoryPath(args.ConfigValue);
string intermediateOutputPath = context.GetIntermediateOutputPath(args.ConfigValue, args.IntermediateValue, outputPath);
Directory.CreateDirectory(outputPath);

View file

@ -14,9 +14,7 @@ namespace Microsoft.DotNet.Tools.Pack
private readonly string _configuration;
private bool PackageArtifactsPathSet => !string.IsNullOrWhiteSpace(PackageArtifactsPathParameter);
private bool ShouldCombinePathWithFramework => !CompiledArtifactsPathSet && !PackageArtifactsPathSet;
public bool PackageArtifactsPathSet => !string.IsNullOrWhiteSpace(PackageArtifactsPathParameter);
public string CompiledArtifactsPathParameter { get; }
@ -38,8 +36,7 @@ namespace Microsoft.DotNet.Tools.Pack
var outputPath = Path.Combine(
_project.ProjectDirectory,
Constants.BinDirectoryName,
_configuration);
Constants.BinDirectoryName);
return outputPath;
}
@ -59,9 +56,10 @@ namespace Microsoft.DotNet.Tools.Pack
public string InputPathForContext(ProjectContext context)
{
return ShouldCombinePathWithFramework ?
Path.Combine(CompiledArtifactsPath, context.TargetFramework.GetTwoDigitShortFolderName()) :
CompiledArtifactsPath;
return Path.Combine(
CompiledArtifactsPath,
_configuration,
context.TargetFramework.GetTwoDigitShortFolderName());
}
}
}

View file

@ -42,7 +42,7 @@ namespace Microsoft.DotNet.Tools.Pack
var argsBuilder = new StringBuilder();
argsBuilder.Append($"--configuration {_configuration}");
if (!string.IsNullOrEmpty(_artifactPathsCalculator.PackageArtifactsPathParameter))
if (_artifactPathsCalculator.PackageArtifactsPathSet)
{
argsBuilder.Append($" --output \"{_artifactPathsCalculator.PackageArtifactsPathParameter}\"");
}

View file

@ -59,6 +59,7 @@ namespace Microsoft.DotNet.Tools.Compiler
var packageOutputPath = Path.Combine(
ArtifactPathsCalculator.PackageArtifactsPath,
Configuration,
GetPackageName() + NuGet.Constants.PackageExtension);
if (GeneratePackage(packageOutputPath, packDiagnostics))

View file

@ -73,46 +73,38 @@ namespace Microsoft.DotNet.Tools.Publish
/// Publish the project for given 'framework (ex - dnxcore50)' and 'runtimeID (ex - win7-x64)'
/// </summary>
/// <param name="context">project that is to be published</param>
/// <param name="outputPath">Location of published files</param>
/// <param name="baseOutputPath">Location of published files</param>
/// <param name="configuration">Debug or Release</param>
/// <param name="nativeSubdirectories"></param>
/// <returns>Return 0 if successful else return non-zero</returns>
private static bool PublishProjectContext(ProjectContext context, string outputPath, string configuration, bool nativeSubdirectories)
private static bool PublishProjectContext(ProjectContext context, string baseOutputPath, string configuration, bool nativeSubdirectories)
{
Reporter.Output.WriteLine($"Publishing {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}/{context.RuntimeIdentifier.Yellow()}");
var options = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration);
// Generate the output path
if (string.IsNullOrEmpty(outputPath))
{
outputPath = Path.Combine(
context.ProjectFile.ProjectDirectory,
Constants.BinDirectoryName,
configuration,
context.TargetFramework.GetTwoDigitShortFolderName(),
context.RuntimeIdentifier);
}
var outputPathCalculator = context.GetOutputPathCalculator(baseOutputPath);
var outputPath = outputPathCalculator.GetOutputDirectoryPath(configuration);
var contextVariables = new Dictionary<string, string>
{
{ "publish:ProjectPath", context.ProjectDirectory },
{ "publish:Configuration", configuration },
{ "publish:OutputPath", outputPath },
{ "publish:OutputPath", outputPathCalculator.BaseRootOutputPath },
{ "publish:Framework", context.TargetFramework.Framework },
{ "publish:Runtime", context.RuntimeIdentifier },
};
RunScripts(context, ScriptNames.PrePublish, contextVariables);
if (!Directory.Exists(outputPath))
if (!Directory.Exists(outputPathCalculator.BaseRootOutputPath))
{
Directory.CreateDirectory(outputPath);
Directory.CreateDirectory(outputPathCalculator.BaseRootOutputPath);
}
// Compile the project (and transitively, all it's dependencies)
var result = Command.Create("dotnet-build",
$"--framework \"{context.TargetFramework.DotNetFrameworkName}\" " +
$"--output \"{outputPath}\" " +
$"--output \"{outputPathCalculator.BaseRootOutputPath}\" " +
$"--configuration \"{configuration}\" " +
"--no-host " +
$"\"{context.ProjectFile.ProjectDirectory}\"")

View file

@ -101,7 +101,9 @@ namespace Microsoft.DotNet.Tools.Run
}
// Now launch the output and give it the results
var outputName = Path.Combine(tempDir, _context.ProjectFile.Name + Constants.ExeSuffix);
var outputName = Path.Combine(
_context.GetOutputPathCalculator(tempDir).GetOutputDirectoryPath(Configuration),
_context.ProjectFile.Name + Constants.ExeSuffix);
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
if (_context.TargetFramework.IsDesktop())

View file

@ -23,6 +23,15 @@
"System.Reflection": "4.1.0-rc2-23616",
"System.Dynamic.Runtime": "4.0.11-rc2-23616"
}
},
"dnxcore50": {
"dependencies": {
"System.IO.FileSystem": "4.0.1-rc2-23616",
"System.Linq": "4.0.1-rc2-23616",
"System.Runtime": "4.0.21-rc2-23616",
"System.Reflection": "4.1.0-rc2-23616",
"System.Dynamic.Runtime": "4.0.11-rc2-23616"
}
}
},
"scripts": {

View file

@ -58,13 +58,16 @@ namespace Microsoft.DotNet.Tests.EndToEnd
buildCommand.Execute().Should().Pass();
TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName(), s_expectedOutput);
var latestWriteTimeFirstBuild = GetLastWriteTimeOfDirectoryFiles(OutputDirectory);
var binariesOutputDirectory = GetBinariesOutputDirectory(OutputDirectory, false);
var latestWriteTimeFirstBuild = GetLastWriteTimeOfDirectoryFiles(
binariesOutputDirectory);
// second build; should get skipped (incremental because no inputs changed)
buildCommand.Execute().Should().Pass();
TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName(), s_expectedOutput);
var latestWriteTimeSecondBuild = GetLastWriteTimeOfDirectoryFiles(OutputDirectory);
var latestWriteTimeSecondBuild = GetLastWriteTimeOfDirectoryFiles(
binariesOutputDirectory);
Assert.Equal(latestWriteTimeFirstBuild, latestWriteTimeSecondBuild);
TouchSourceFileInDirectory(TestDirectory);
@ -73,7 +76,8 @@ namespace Microsoft.DotNet.Tests.EndToEnd
buildCommand.Execute().Should().Pass();
TestOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName(), s_expectedOutput);
var latestWriteTimeThirdBuild = GetLastWriteTimeOfDirectoryFiles(OutputDirectory);
var latestWriteTimeThirdBuild = GetLastWriteTimeOfDirectoryFiles(
binariesOutputDirectory);
Assert.NotEqual(latestWriteTimeSecondBuild, latestWriteTimeThirdBuild);
}
@ -91,8 +95,7 @@ namespace Microsoft.DotNet.Tests.EndToEnd
buildCommand.Execute().Should().Pass();
var nativeOut = Path.Combine(OutputDirectory, "native");
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName(), s_expectedOutput);
TestNativeOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName(), s_expectedOutput);
}
[Fact]
@ -108,8 +111,7 @@ namespace Microsoft.DotNet.Tests.EndToEnd
buildCommand.Execute().Should().Pass();
var nativeOut = Path.Combine(OutputDirectory, "native");
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName(), s_expectedOutput);
TestNativeOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName(), s_expectedOutput);
}
[Fact]
@ -121,20 +123,22 @@ namespace Microsoft.DotNet.Tests.EndToEnd
return;
}
var nativeOut = Path.Combine(OutputDirectory, "native");
// first build
var buildCommand = new BuildCommand(TestProject, output: OutputDirectory, native: true, nativeCppMode: true);
buildCommand.Execute().Should().Pass();
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName(), s_expectedOutput);
var binariesOutputDirectory = GetBinariesOutputDirectory(OutputDirectory, false);
var latestWriteTimeFirstBuild = GetLastWriteTimeOfDirectoryFiles(OutputDirectory);
buildCommand.Execute().Should().Pass();
TestNativeOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName(), s_expectedOutput);
var latestWriteTimeFirstBuild = GetLastWriteTimeOfDirectoryFiles(binariesOutputDirectory);
// second build; should be skipped because nothing changed
buildCommand.Execute().Should().Pass();
TestOutputExecutable(nativeOut, buildCommand.GetOutputExecutableName(), s_expectedOutput);
var latestWriteTimeSecondBuild = GetLastWriteTimeOfDirectoryFiles(OutputDirectory);
TestNativeOutputExecutable(OutputDirectory, buildCommand.GetOutputExecutableName(), s_expectedOutput);
var latestWriteTimeSecondBuild = GetLastWriteTimeOfDirectoryFiles(binariesOutputDirectory);
Assert.Equal(latestWriteTimeFirstBuild, latestWriteTimeSecondBuild);
}

View file

@ -1,6 +1,7 @@
// 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;
using System.IO;
using Microsoft.DotNet.Tools.Test.Utilities;
using Xunit;
@ -32,7 +33,8 @@ namespace Microsoft.DotNet.Tools.Publish.Tests
result.Should().Pass();
// verify the output xml file
var outputXml = Path.Combine(outputDir, "TestLibrary.xml");
var outputXml = Path.Combine(outputDir, "Debug", "dnxcore50", "TestLibrary.xml");
Console.WriteLine("OUTPUT XML PATH: " + outputXml);
Assert.True(File.Exists(outputXml));
Assert.Contains("Gets the message from the helper", File.ReadAllText(outputXml));
}

View file

@ -61,7 +61,8 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
string framework = string.IsNullOrEmpty(_framework) ?
_project.GetTargetFrameworks().First().FrameworkName.GetShortFolderName() : _framework;
string runtime = string.IsNullOrEmpty(_runtime) ? PlatformServices.Default.Runtime.GetLegacyRestoreRuntimeIdentifier() : _runtime;
string output = Path.Combine("bin", config, framework, runtime);
//TODO: add runtime back as soon as it gets propagated through the various commands.
string output = Path.Combine(config, framework);
return output;
}
@ -70,10 +71,10 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
{
if (!string.IsNullOrEmpty(_output))
{
return new DirectoryInfo(_output);
return new DirectoryInfo(Path.Combine(_output, BuildRelativeOutputPath()));
}
string output = Path.Combine(_project.ProjectDirectory, BuildRelativeOutputPath());
string output = Path.Combine(_project.ProjectDirectory, "bin", BuildRelativeOutputPath());
return new DirectoryInfo(output);
}

View file

@ -58,9 +58,13 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
string.Equals("on", val, StringComparison.OrdinalIgnoreCase));
}
protected void TestOutputExecutable(string outputDir, string executableName, string expectedOutput)
protected void TestOutputExecutable(
string outputDir,
string executableName,
string expectedOutput,
bool native = false)
{
var executablePath = Path.Combine(outputDir, executableName);
var executablePath = Path.Combine(GetBinariesOutputDirectory(outputDir, native), executableName);
var executableCommand = new TestCommand(executablePath);
@ -70,5 +74,21 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
result.Should().NotHaveStdErr();
result.Should().Pass();
}
private void TestNativeOutputExecutable(string outputDir, string executableName, string expectedOutput)
{
TestOutputExecutable(outputDir, executableName, expectedOutput, true);
}
private string GetBinariesOutputDirectory(string outputDir, bool native)
{
var executablePath = Path.Combine(outputDir, "Debug", "dnxcore50");
if (native)
{
executablePath = Path.Combine(outputDir, "Debug", "dnxcore50", "native");
}
return executablePath;
}
}
}