a35ae177ff
- Project dependencies are always built into their specific folders and the main project is the only one that uses the output path and intermediate output path variable. - Publish respects the output path for publish only, not compile as part of publish. This means that publishing multiple runtimes will stomp on each other. So don't do that. We can throw if you specify and output location and you haven't specified a specific combination of RID and framework. Alternatively it should probably just pick the first TFM/RID pair from the lock file. This is similar to how `dotnet run` works. - Cleaned up the incremental build output formatting - Use a single stream (output stream) since interleaving them was causing formatting issues (like losing random characters in the middle of outputting things). - Didn't change how pack works, it still preserves the output structure when passing `--output`, this one is worth discussing. We could leave the build output inplace and only move the package to the output location. That's more consistent with how everything else works and can be a follow up PR.
125 lines
No EOL
4.4 KiB
C#
125 lines
No EOL
4.4 KiB
C#
// 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.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Microsoft.DotNet.Cli.Utils;
|
|
using Microsoft.DotNet.Tools.Test.Utilities;
|
|
using Xunit;
|
|
|
|
namespace Microsoft.DotNet.Tools.Builder.Tests
|
|
{
|
|
public class IncrementalTestBase : TestBase
|
|
{
|
|
protected readonly TempDirectory _tempProjectRoot;
|
|
|
|
private readonly string _testProjectsRoot;
|
|
protected readonly string _mainProject;
|
|
protected readonly string _expectedOutput;
|
|
|
|
public IncrementalTestBase(string testProjectsRoot, string mainProject, string expectedOutput)
|
|
{
|
|
_testProjectsRoot = testProjectsRoot;
|
|
_mainProject = mainProject;
|
|
_expectedOutput = expectedOutput;
|
|
|
|
// create unique directories in the 'temp' folder
|
|
var root = Temp.CreateDirectory();
|
|
|
|
// recursively copy projects to the temp dir and restore them
|
|
_tempProjectRoot = root.CopyDirectory(testProjectsRoot);
|
|
RunRestore(_tempProjectRoot.Path);
|
|
}
|
|
|
|
protected void TouchSourcesOfProject()
|
|
{
|
|
TouchSourcesOfProject(_mainProject);
|
|
}
|
|
|
|
protected void TouchSourcesOfProject(string projectToTouch)
|
|
{
|
|
foreach (var sourceFile in GetSourceFilesForProject(projectToTouch))
|
|
{
|
|
TouchFile(sourceFile);
|
|
}
|
|
}
|
|
|
|
protected static void TouchFile(string file)
|
|
{
|
|
File.SetLastWriteTimeUtc(file, DateTime.UtcNow);
|
|
}
|
|
|
|
protected CommandResult BuildProject(bool forceIncrementalUnsafe = false, bool expectBuildFailure = false)
|
|
{
|
|
var outputDir = GetBinDirectory();
|
|
var intermediateOutputDir = Path.Combine(Directory.GetParent(outputDir).FullName, "obj", _mainProject);
|
|
var mainProjectFile = GetProjectFile(_mainProject);
|
|
|
|
var buildCommand = new BuildCommand(mainProjectFile, output: outputDir, tempOutput: intermediateOutputDir ,forceIncrementalUnsafe : forceIncrementalUnsafe);
|
|
var result = buildCommand.ExecuteWithCapturedOutput();
|
|
|
|
if (!expectBuildFailure)
|
|
{
|
|
result.Should().Pass();
|
|
TestOutputExecutable(outputDir, buildCommand.GetOutputExecutableName(), _expectedOutput);
|
|
}
|
|
else
|
|
{
|
|
result.Should().Fail();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
protected static void AssertProjectSkipped(string skippedProject, CommandResult buildResult)
|
|
{
|
|
Assert.Contains($"Project {skippedProject} (DNXCore,Version=v5.0) was previously compiled. Skipping compilation.", buildResult.StdOut, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
protected static void AssertProjectCompiled(string rebuiltProject, CommandResult buildResult)
|
|
{
|
|
Assert.Contains($"Project {rebuiltProject} (DNXCore,Version=v5.0) will be compiled", buildResult.StdOut, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
protected string GetBinDirectory()
|
|
{
|
|
return Path.Combine(_tempProjectRoot.Path, "bin");
|
|
}
|
|
|
|
protected virtual string GetProjectDirectory(string projectName)
|
|
{
|
|
return Path.Combine(_tempProjectRoot.Path);
|
|
}
|
|
|
|
protected string GetProjectFile(string projectName)
|
|
{
|
|
return Path.Combine(GetProjectDirectory(projectName), "project.json");
|
|
}
|
|
|
|
private string GetOutputFileForProject(string projectName)
|
|
{
|
|
return Path.Combine(GetCompilationOutputPath(), projectName + ".dll");
|
|
}
|
|
|
|
private IEnumerable<string> GetSourceFilesForProject(string projectName)
|
|
{
|
|
return Directory.EnumerateFiles(GetProjectDirectory(projectName)).
|
|
Where(f => f.EndsWith(".cs"));
|
|
}
|
|
|
|
protected string GetCompilationOutputPath()
|
|
{
|
|
var executablePath = Path.Combine(GetBinDirectory(), "Debug", "dnxcore50");
|
|
|
|
return executablePath;
|
|
}
|
|
|
|
private void RunRestore(string args)
|
|
{
|
|
var restoreCommand = new RestoreCommand();
|
|
restoreCommand.Execute($"--quiet {args}").Should().Pass();
|
|
}
|
|
}
|
|
} |