3a9525b5ac
* rel/1.0.1: (66 commits) Update LZMA license with correct text Bump to 2.0.0-rc5-61427-04 Remove duplicate installer suffix Add license text to LZMA SDK license notice Updating the SDK to 1.0.0-alpha-20170224-6 Updating both platform abstractions and dependency model to 1.0.3. Bump Roslyn to 2.0.0-rc5-61424-02 Update Stage0 to use the latest build. Update README with new distros. Back porting #5597 into rel/1.0.0 Fixing the exclude pattern used by the Migration to exclude WEB SDK globs. Remove RID from test package creation Disable migrate and publish web app with content because CI does not have NPM Adding an E2E test for pack with content during migration. Fixing a failing test and adding a few more E2E tests around binplace content for migrated projects. Fix debian_config.json on ubuntu16.10 Updating publish, pack and build of content to use None with Never/false/Never in their metadata for excluded items. Intermediate commit to get a WIP PR out. This adds the None Update with CopyToOutputDirectory set to Never. Switching the CopyToOutput for build and publish and the file for pack to use None Update instead of include. Also, fixed the exclude patterns for web apps. Do not migrate Content that is already included in the Web SDK for web apps. ...
1018 lines
36 KiB
C#
1018 lines
36 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 Microsoft.Build.Construction;
|
|
using Microsoft.DotNet.TestFramework;
|
|
using Microsoft.DotNet.Tools.Common;
|
|
using Microsoft.DotNet.Tools.Test.Utilities;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Xunit;
|
|
using FluentAssertions;
|
|
using System.IO;
|
|
using Microsoft.DotNet.Tools.Migrate;
|
|
using BuildCommand = Microsoft.DotNet.Tools.Test.Utilities.BuildCommand;
|
|
using System.Runtime.Loader;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
using MigrateCommand = Microsoft.DotNet.Tools.Migrate.MigrateCommand;
|
|
|
|
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
|
|
|
namespace Microsoft.DotNet.Migration.Tests
|
|
{
|
|
public class GivenThatIWantToMigrateTestApps : TestBase
|
|
{
|
|
[Theory]
|
|
[InlineData("TestAppWithRuntimeOptions")]
|
|
[InlineData("TestAppWithContents")]
|
|
[InlineData("AppWithAssemblyInfo")]
|
|
[InlineData("TestAppWithEmbeddedResources")]
|
|
public void ItMigratesApps(string projectName)
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson(projectName)
|
|
.CreateInstance(identifier: projectName)
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
CleanBinObj(projectDirectory);
|
|
|
|
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory, projectName);
|
|
|
|
var outputsIdentical =
|
|
outputComparisonData.ProjectJsonBuildOutputs.SetEquals(outputComparisonData.MSBuildBuildOutputs);
|
|
|
|
if (!outputsIdentical)
|
|
{
|
|
OutputDiagnostics(outputComparisonData);
|
|
}
|
|
|
|
outputsIdentical.Should().BeTrue();
|
|
|
|
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
|
|
|
var outputCsProj = projectDirectory.GetFile(projectName + ".csproj");
|
|
|
|
outputCsProj.ReadAllText()
|
|
.Should().EndWith("\n");
|
|
}
|
|
|
|
[WindowsOnlyTheory]
|
|
[InlineData("AppWith2Tfm0Rid", null)]
|
|
[InlineData("AppWith4netTfm0Rid", "net461")]
|
|
public void ItMigratesAppsWithFullFramework(string projectName, string framework)
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson(projectName)
|
|
.CreateInstance(identifier: projectName)
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
CleanBinObj(projectDirectory);
|
|
|
|
MigrateProject(new [] { projectDirectory.FullName });
|
|
|
|
Restore(projectDirectory);
|
|
|
|
BuildMSBuild(projectDirectory, projectName, framework: framework);
|
|
}
|
|
|
|
[Fact]
|
|
public void ItMigratesSignedApps()
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson("TestAppWithSigning")
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
CleanBinObj(projectDirectory);
|
|
|
|
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory, "TestAppWithSigning");
|
|
|
|
var outputsIdentical =
|
|
outputComparisonData.ProjectJsonBuildOutputs.SetEquals(outputComparisonData.MSBuildBuildOutputs);
|
|
|
|
if (!outputsIdentical)
|
|
{
|
|
OutputDiagnostics(outputComparisonData);
|
|
}
|
|
|
|
outputsIdentical.Should().BeTrue();
|
|
|
|
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
|
|
|
VerifyAllMSBuildOutputsAreSigned(projectDirectory);
|
|
}
|
|
|
|
[Fact]
|
|
public void ItMigratesDotnetNewConsoleWithIdenticalOutputs()
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson("ProjectJsonConsoleTemplate")
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var outputComparisonData = GetComparisonData(projectDirectory);
|
|
|
|
var outputsIdentical =
|
|
outputComparisonData.ProjectJsonBuildOutputs.SetEquals(outputComparisonData.MSBuildBuildOutputs);
|
|
|
|
if (!outputsIdentical)
|
|
{
|
|
OutputDiagnostics(outputComparisonData);
|
|
}
|
|
|
|
outputsIdentical.Should().BeTrue();
|
|
|
|
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
|
}
|
|
|
|
[Fact]
|
|
public void ItMigratesOldDotnetNewWebWithoutToolsWithOutputsContainingProjectJsonOutputs()
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson("ProjectJsonWebTemplate")
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var globalDirectory = projectDirectory.Parent;
|
|
|
|
WriteGlobalJson(globalDirectory);
|
|
|
|
var outputComparisonData = GetComparisonData(projectDirectory);
|
|
|
|
var outputsIdentical =
|
|
outputComparisonData.ProjectJsonBuildOutputs.SetEquals(outputComparisonData.MSBuildBuildOutputs);
|
|
|
|
if (!outputsIdentical)
|
|
{
|
|
OutputDiagnostics(outputComparisonData);
|
|
}
|
|
|
|
outputsIdentical.Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void ItMigratesAndPublishesWebApp()
|
|
{
|
|
var projectName = "WebAppWithMissingFileInPublishOptions";
|
|
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson(projectName)
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
File.Copy("NuGet.tempaspnetpatch.config", projectDirectory.GetFile("NuGet.Config").FullName);
|
|
|
|
MigrateProject(new [] { projectDirectory.FullName });
|
|
|
|
Restore(projectDirectory);
|
|
PublishMSBuild(projectDirectory, projectName);
|
|
}
|
|
|
|
[Fact]
|
|
public void ItMigratesAPackageReferenceAsSuchEvenIfAFolderWithTheSameNameExistsInTheRepo()
|
|
{
|
|
var solutionDirectory = TestAssets
|
|
.GetProjectJson("AppWithPackageNamedAfterFolder")
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var appProject = solutionDirectory
|
|
.GetDirectory("src", "App")
|
|
.GetFile("App.csproj");
|
|
|
|
MigrateProject(solutionDirectory.FullName);
|
|
|
|
var projectRootElement = ProjectRootElement.Open(appProject.FullName);
|
|
|
|
projectRootElement.Items.Where(
|
|
i => i.Include == "EntityFramework" && i.ItemType == "PackageReference")
|
|
.Should().HaveCount(2);
|
|
}
|
|
[Fact]
|
|
public void ItMigratesAProjectThatDependsOnAMigratedProjectWithTheSkipProjectReferenceFlag()
|
|
{
|
|
const string dependentProject = "ProjectA";
|
|
const string dependencyProject = "ProjectB";
|
|
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson("TestAppDependencyGraph")
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
MigrateProject(projectDirectory.GetDirectory(dependencyProject).FullName);
|
|
|
|
MigrateProject("--skip-project-references", projectDirectory.GetDirectory(dependentProject).FullName);
|
|
}
|
|
|
|
[Fact]
|
|
public void ItAddsMicrosoftNetWebSdkToTheSdkAttributeOfAWebApp()
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.Get("ProjectJsonWebTemplate")
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var globalDirectory = projectDirectory.Parent;
|
|
var projectJsonFile = projectDirectory.GetFile("project.json");
|
|
|
|
MigrateProject(new [] { projectDirectory.FullName });
|
|
|
|
var csProj = projectDirectory.GetFile($"{projectDirectory.Name}.csproj");
|
|
|
|
csProj.ReadAllText().Should().Contain(@"Sdk=""Microsoft.NET.Sdk.Web""");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("TestLibraryWithTwoFrameworks")]
|
|
public void ItMigratesProjectsWithMultipleTFMs(string projectName)
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson(projectName)
|
|
.CreateInstance(identifier: projectName)
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory, projectName);
|
|
|
|
var outputsIdentical =
|
|
outputComparisonData.ProjectJsonBuildOutputs.SetEquals(outputComparisonData.MSBuildBuildOutputs);
|
|
|
|
if (!outputsIdentical)
|
|
{
|
|
OutputDiagnostics(outputComparisonData);
|
|
}
|
|
|
|
outputsIdentical.Should().BeTrue();
|
|
}
|
|
|
|
[WindowsOnlyFact]
|
|
public void ItMigratesLibraryWithMultipleTFMsAndFullFramework()
|
|
{
|
|
var projectName = "PJLibWithMultipleFrameworks";
|
|
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson(projectName)
|
|
.CreateInstance(identifier: projectName)
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory, projectName);
|
|
|
|
var outputsIdentical =
|
|
outputComparisonData.ProjectJsonBuildOutputs.SetEquals(outputComparisonData.MSBuildBuildOutputs);
|
|
|
|
if (!outputsIdentical)
|
|
{
|
|
OutputDiagnostics(outputComparisonData);
|
|
}
|
|
|
|
outputsIdentical.Should().BeTrue();
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("TestAppWithLibrary/TestLibrary")]
|
|
[InlineData("TestLibraryWithAnalyzer")]
|
|
[InlineData("PJTestLibraryWithConfiguration")]
|
|
public void ItMigratesALibrary(string projectName)
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson(projectName)
|
|
.CreateInstance(identifier: projectName)
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(
|
|
projectDirectory,
|
|
Path.GetFileNameWithoutExtension(projectName));
|
|
|
|
var outputsIdentical = outputComparisonData
|
|
.ProjectJsonBuildOutputs
|
|
.SetEquals(outputComparisonData.MSBuildBuildOutputs);
|
|
|
|
if (!outputsIdentical)
|
|
{
|
|
OutputDiagnostics(outputComparisonData);
|
|
}
|
|
|
|
outputsIdentical.Should().BeTrue();
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("ProjectA", "ProjectA,ProjectB,ProjectC,ProjectD,ProjectE")]
|
|
[InlineData("ProjectB", "ProjectB,ProjectC,ProjectD,ProjectE")]
|
|
[InlineData("ProjectC", "ProjectC,ProjectD,ProjectE")]
|
|
[InlineData("ProjectD", "ProjectD")]
|
|
[InlineData("ProjectE", "ProjectE")]
|
|
public void ItMigratesRootProjectAndReferences(string projectName, string expectedProjects)
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson("TestAppDependencyGraph")
|
|
.CreateInstance(identifier: $"{projectName}.RefsTest")
|
|
.WithSourceFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
MigrateProject(new [] { projectDirectory.GetDirectory(projectName).FullName });
|
|
|
|
string[] migratedProjects = expectedProjects.Split(new char[] { ',' });
|
|
|
|
VerifyMigration(migratedProjects, projectDirectory);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("ProjectA")]
|
|
[InlineData("ProjectB")]
|
|
[InlineData("ProjectC")]
|
|
[InlineData("ProjectD")]
|
|
[InlineData("ProjectE")]
|
|
public void ItMigratesRootProjectAndSkipsReferences(string projectName)
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson("TestAppDependencyGraph")
|
|
.CreateInstance($"{projectName}.SkipRefsTest")
|
|
.WithSourceFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
MigrateProject(new [] { projectDirectory.GetDirectory(projectName).FullName, "--skip-project-references" });
|
|
|
|
VerifyMigration(Enumerable.Repeat(projectName, 1), projectDirectory);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void ItMigratesAllProjectsInGivenDirectory(bool skipRefs)
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson("TestAppDependencyGraph")
|
|
.CreateInstance(callingMethod: $"MigrateDirectory.SkipRefs.{skipRefs}")
|
|
.WithSourceFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
if (skipRefs)
|
|
{
|
|
MigrateProject(new [] { projectDirectory.FullName, "--skip-project-references" });
|
|
}
|
|
else
|
|
{
|
|
MigrateProject(new [] { projectDirectory.FullName });
|
|
}
|
|
|
|
string[] migratedProjects = new string[] { "ProjectA", "ProjectB", "ProjectC", "ProjectD", "ProjectE", "ProjectF", "ProjectG", "ProjectH", "ProjectI", "ProjectJ" };
|
|
|
|
VerifyMigration(migratedProjects, projectDirectory);
|
|
}
|
|
|
|
[Fact]
|
|
public void ItMigratesGivenProjectJson()
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson("TestAppDependencyGraph")
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var project = projectDirectory
|
|
.GetDirectory("ProjectA")
|
|
.GetFile("project.json");
|
|
|
|
MigrateProject(new [] { project.FullName });
|
|
|
|
string[] migratedProjects = new string[] { "ProjectA", "ProjectB", "ProjectC", "ProjectD", "ProjectE" };
|
|
|
|
VerifyMigration(migratedProjects, projectDirectory);
|
|
}
|
|
|
|
[Fact]
|
|
// regression test for https://github.com/dotnet/cli/issues/4269
|
|
public void ItMigratesAndBuildsP2PReferences()
|
|
{
|
|
var assetsDir = TestAssets
|
|
.GetProjectJson("TestAppDependencyGraph")
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var projectDirectory = assetsDir.GetDirectory("ProjectF");
|
|
|
|
var restoreDirectories = new DirectoryInfo[]
|
|
{
|
|
projectDirectory,
|
|
assetsDir.GetDirectory("ProjectG")
|
|
};
|
|
|
|
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory, "ProjectF", new [] { projectDirectory.FullName }, restoreDirectories);
|
|
|
|
var outputsIdentical = outputComparisonData.ProjectJsonBuildOutputs
|
|
.SetEquals(outputComparisonData.MSBuildBuildOutputs);
|
|
|
|
if (!outputsIdentical)
|
|
{
|
|
OutputDiagnostics(outputComparisonData);
|
|
}
|
|
|
|
outputsIdentical.Should().BeTrue();
|
|
|
|
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("src", "H")]
|
|
[InlineData("src with spaces", "J")]
|
|
public void ItMigratesAndBuildsProjectsInGlobalJson(string path, string projectNameSuffix)
|
|
{
|
|
var assetsDir = TestAssets
|
|
.GetProjectJson("ProjectsWithGlobalJson")
|
|
.CreateInstance(identifier: projectNameSuffix)
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var projectName = $"Project{projectNameSuffix}";
|
|
|
|
var globalJson = assetsDir.GetFile("global.json");
|
|
|
|
var restoreDirectories = new DirectoryInfo[]
|
|
{
|
|
assetsDir.GetDirectory("src", "ProjectH"),
|
|
assetsDir.GetDirectory("src", "ProjectI"),
|
|
assetsDir.GetDirectory("src with spaces", "ProjectJ")
|
|
};
|
|
|
|
var projectDirectory = assetsDir.GetDirectory(path, projectName);
|
|
|
|
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory,
|
|
projectName,
|
|
new [] { globalJson.FullName },
|
|
restoreDirectories);
|
|
|
|
var outputsIdentical = outputComparisonData.ProjectJsonBuildOutputs
|
|
.SetEquals(outputComparisonData.MSBuildBuildOutputs);
|
|
|
|
if (!outputsIdentical)
|
|
{
|
|
OutputDiagnostics(outputComparisonData);
|
|
}
|
|
|
|
outputsIdentical.Should().BeTrue();
|
|
|
|
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void MigrationOutputsErrorWhenNoProjectsFound(bool useGlobalJson)
|
|
{
|
|
var projectDirectory = TestAssets.CreateTestDirectory("Migration_outputs_error_when_no_projects_found");
|
|
|
|
string argstr = string.Empty;
|
|
|
|
string errorMessage = string.Empty;
|
|
|
|
if (useGlobalJson)
|
|
{
|
|
var globalJson = projectDirectory.GetFile("global.json");
|
|
|
|
using (StreamWriter sw = globalJson.CreateText())
|
|
{
|
|
sw.WriteLine("{");
|
|
sw.WriteLine("\"projects\": [ \".\" ]");
|
|
sw.WriteLine("}");
|
|
}
|
|
|
|
argstr = globalJson.FullName;
|
|
|
|
errorMessage = "Unable to find any projects in global.json";
|
|
}
|
|
else
|
|
{
|
|
argstr = projectDirectory.FullName;
|
|
|
|
errorMessage = $"No project.json file found in '{projectDirectory.FullName}'";
|
|
}
|
|
|
|
var result = new TestCommand("dotnet")
|
|
.WithWorkingDirectory(projectDirectory)
|
|
.ExecuteWithCapturedOutput($"migrate {argstr}");
|
|
|
|
// Expecting an error exit code.
|
|
result.ExitCode.Should().Be(1);
|
|
|
|
// Verify the error messages. Note that debug builds also show the call stack, so we search
|
|
// for the error strings that should be present (rather than an exact match).
|
|
result.StdErr
|
|
.Should().Contain(errorMessage)
|
|
.And.Contain("Migration failed.");
|
|
}
|
|
|
|
[RequiresSpecificFrameworkFact("netcoreapp1.0")]
|
|
public void ItMigratesAndPublishesProjectsWithRuntimes()
|
|
{
|
|
var projectName = "PJTestAppSimple";
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson(projectName)
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
CleanBinObj(projectDirectory);
|
|
BuildProjectJsonMigrateBuildMSBuild(projectDirectory, projectName);
|
|
PublishMSBuild(projectDirectory, projectName, "win7-x64");
|
|
}
|
|
|
|
[WindowsOnlyTheory]
|
|
[InlineData("DesktopTestProjects", "AutoAddDesktopReferencesDuringMigrate", true)]
|
|
[InlineData("TestProjects", "PJTestAppSimple", false)]
|
|
public void ItAutoAddDesktopReferencesDuringMigrate(string testGroup, string projectName, bool isDesktopApp)
|
|
{
|
|
var runtime = DotnetLegacyRuntimeIdentifiers.InferLegacyRestoreRuntimeIdentifier();
|
|
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson(testGroup, projectName)
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
CleanBinObj(projectDirectory);
|
|
MigrateProject(new string[] { projectDirectory.FullName });
|
|
Restore(projectDirectory, runtime: runtime);
|
|
BuildMSBuild(projectDirectory, projectName, runtime:runtime);
|
|
VerifyAutoInjectedDesktopReferences(projectDirectory, projectName, isDesktopApp);
|
|
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
|
}
|
|
|
|
[Fact]
|
|
public void ItBuildsAMigratedAppWithAnIndirectDependency()
|
|
{
|
|
const string projectName = "ProjectA";
|
|
|
|
var solutionDirectory = TestAssets
|
|
.GetProjectJson("TestAppDependencyGraph")
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var projectDirectory = solutionDirectory.GetDirectory(projectName);
|
|
|
|
MigrateProject(new string[] { projectDirectory.FullName });
|
|
|
|
Restore(projectDirectory);
|
|
|
|
BuildMSBuild(projectDirectory, projectName);
|
|
|
|
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
|
}
|
|
|
|
[Fact]
|
|
public void ItMigratesProjectWithOutputName()
|
|
{
|
|
var projectName = "AppWithOutputAssemblyName";
|
|
var expectedOutputName = "MyApp";
|
|
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson(projectName)
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.WithRestoreFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
var expectedCsprojPath = projectDirectory.GetFile($"{projectName}.csproj");
|
|
|
|
if (expectedCsprojPath.Exists)
|
|
{
|
|
expectedCsprojPath.Delete();
|
|
}
|
|
|
|
CleanBinObj(projectDirectory);
|
|
MigrateProject(projectDirectory.FullName);
|
|
|
|
expectedCsprojPath.Refresh();
|
|
|
|
expectedCsprojPath.Should().Exist();
|
|
|
|
Restore(projectDirectory, projectName);
|
|
BuildMSBuild(projectDirectory, projectName);
|
|
projectDirectory
|
|
.GetDirectory("bin")
|
|
.EnumerateFiles($"{expectedOutputName}.pdb", SearchOption.AllDirectories)
|
|
.Count().Should().Be(1);
|
|
|
|
PackMSBuild(projectDirectory, projectName);
|
|
|
|
projectDirectory
|
|
.GetDirectory("bin")
|
|
.EnumerateFiles($"{projectName}.1.0.0.nupkg", SearchOption.AllDirectories)
|
|
.Count().Should().Be(1);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("LibraryWithoutNetStandardLibRef")]
|
|
[InlineData("LibraryWithNetStandardLibRef")]
|
|
public void ItMigratesAndBuildsLibrary(string projectName)
|
|
{
|
|
var projectDirectory = TestAssets
|
|
.GetProjectJson(projectName)
|
|
.CreateInstance(identifier: projectName)
|
|
.WithSourceFiles()
|
|
.WithEmptyGlobalJson()
|
|
.Root;
|
|
|
|
MigrateProject(projectDirectory.FullName);
|
|
Restore(projectDirectory, projectName);
|
|
BuildMSBuild(projectDirectory, projectName);
|
|
}
|
|
|
|
[Fact]
|
|
public void ItMigratesAndBuildsAppWithExplicitInclude()
|
|
{
|
|
const string projectName = "TestAppWithExplicitInclude";
|
|
var projectDirectory = TestAssets.Get(projectName)
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.Root;
|
|
|
|
MigrateProject(projectDirectory.FullName);
|
|
Restore(projectDirectory, projectName);
|
|
BuildMSBuild(projectDirectory, projectName);
|
|
}
|
|
|
|
[Fact]
|
|
public void ItMigratesAndBuildsAppWithExplicitIncludeGlob()
|
|
{
|
|
const string projectName = "TestAppWithExplicitIncludeGlob";
|
|
var projectDirectory = TestAssets.Get(projectName)
|
|
.CreateInstance()
|
|
.WithSourceFiles()
|
|
.Root;
|
|
|
|
MigrateProject(projectDirectory.FullName);
|
|
Restore(projectDirectory, projectName);
|
|
BuildMSBuild(projectDirectory, projectName);
|
|
}
|
|
|
|
private void VerifyAutoInjectedDesktopReferences(DirectoryInfo projectDirectory, string projectName, bool shouldBePresent)
|
|
{
|
|
if (projectName != null)
|
|
{
|
|
projectName = projectName + ".csproj";
|
|
}
|
|
|
|
var root = ProjectRootElement.Open(projectDirectory.GetFile(projectName).FullName);
|
|
|
|
var autoInjectedReferences = root
|
|
.Items
|
|
.Where(i => i.ItemType == "Reference"
|
|
&& (i.Include == "System" || i.Include == "Microsoft.CSharp"));
|
|
|
|
if (shouldBePresent)
|
|
{
|
|
autoInjectedReferences.Should().HaveCount(2);
|
|
}
|
|
else
|
|
{
|
|
autoInjectedReferences.Should().BeEmpty();
|
|
}
|
|
}
|
|
|
|
private void VerifyMigration(IEnumerable<string> expectedProjects, DirectoryInfo rootDir)
|
|
{
|
|
var backupDir = rootDir.GetDirectory("backup");
|
|
|
|
var migratedProjects = rootDir.EnumerateFiles("*.csproj", SearchOption.AllDirectories)
|
|
.Where(s => !PathUtility.IsChildOfDirectory(backupDir.FullName, s.FullName))
|
|
.Where(s => Directory.EnumerateFiles(Path.GetDirectoryName(s.FullName), "*.csproj").Count() == 1)
|
|
.Where(s => Path.GetFileName(Path.GetDirectoryName(s.FullName)).Contains("Project"))
|
|
.Select(s => Path.GetFileName(Path.GetDirectoryName(s.FullName)));
|
|
|
|
migratedProjects.Should().BeEquivalentTo(expectedProjects);
|
|
}
|
|
|
|
private MigratedBuildComparisonData GetComparisonData(DirectoryInfo projectDirectory)
|
|
{
|
|
File.Copy("NuGet.tempaspnetpatch.config", projectDirectory.GetFile("NuGet.Config").FullName);
|
|
|
|
RestoreProjectJson(projectDirectory);
|
|
|
|
var outputComparisonData =
|
|
BuildProjectJsonMigrateBuildMSBuild(projectDirectory, Path.GetFileNameWithoutExtension(projectDirectory.FullName));
|
|
|
|
return outputComparisonData;
|
|
}
|
|
|
|
private void VerifyAllMSBuildOutputsRunnable(DirectoryInfo projectDirectory)
|
|
{
|
|
if (!EnvironmentInfo.HasSharedFramework("netcoreapp1.0"))
|
|
{
|
|
// running the apps requires netcoreapp1.0
|
|
return;
|
|
}
|
|
|
|
var dllFileName = Path.GetFileName(projectDirectory.FullName) + ".dll";
|
|
|
|
var runnableDlls = projectDirectory
|
|
.GetDirectory("bin")
|
|
.GetFiles(dllFileName, SearchOption.AllDirectories);
|
|
|
|
foreach (var dll in runnableDlls)
|
|
{
|
|
new TestCommand("dotnet").ExecuteWithCapturedOutput($"\"{dll.FullName}\"").Should().Pass();
|
|
}
|
|
}
|
|
|
|
private void VerifyAllMSBuildOutputsAreSigned(DirectoryInfo projectDirectory)
|
|
{
|
|
var dllFileName = Path.GetFileName(projectDirectory.FullName) + ".dll";
|
|
|
|
var runnableDlls = projectDirectory
|
|
.GetDirectory("bin")
|
|
.EnumerateFiles(dllFileName, SearchOption.AllDirectories);
|
|
|
|
foreach (var dll in runnableDlls)
|
|
{
|
|
var assemblyName = AssemblyLoadContext.GetAssemblyName(dll.FullName);
|
|
|
|
var token = assemblyName.GetPublicKeyToken();
|
|
|
|
token.Should().NotBeNullOrEmpty();
|
|
}
|
|
}
|
|
|
|
private MigratedBuildComparisonData BuildProjectJsonMigrateBuildMSBuild(DirectoryInfo projectDirectory,
|
|
string projectName)
|
|
{
|
|
return BuildProjectJsonMigrateBuildMSBuild(projectDirectory,
|
|
projectName,
|
|
new [] { projectDirectory.FullName },
|
|
new [] { projectDirectory });
|
|
}
|
|
|
|
private MigratedBuildComparisonData BuildProjectJsonMigrateBuildMSBuild(DirectoryInfo projectDirectory,
|
|
string projectName,
|
|
string[] migrateArgs,
|
|
DirectoryInfo[] restoreDirectories)
|
|
{
|
|
BuildProjectJson(projectDirectory);
|
|
|
|
var projectJsonBuildOutputs = new HashSet<string>(CollectBuildOutputs(projectDirectory.FullName));
|
|
|
|
CleanBinObj(projectDirectory);
|
|
|
|
// Remove lock file for migration
|
|
foreach(var dir in restoreDirectories)
|
|
{
|
|
dir.GetFile("project.lock.json").Delete();
|
|
}
|
|
|
|
MigrateProject(migrateArgs);
|
|
|
|
DeleteXproj(projectDirectory);
|
|
|
|
foreach(var dir in restoreDirectories)
|
|
{
|
|
Restore(dir);
|
|
}
|
|
|
|
BuildMSBuild(projectDirectory, projectName);
|
|
|
|
var msbuildBuildOutputs = new HashSet<string>(CollectBuildOutputs(projectDirectory.FullName));
|
|
|
|
return new MigratedBuildComparisonData(projectJsonBuildOutputs, msbuildBuildOutputs);
|
|
}
|
|
|
|
private IEnumerable<string> CollectBuildOutputs(string projectDirectory)
|
|
{
|
|
var fullBinPath = Path.GetFullPath(Path.Combine(projectDirectory, "bin"));
|
|
|
|
return Directory.EnumerateFiles(fullBinPath, "*", SearchOption.AllDirectories)
|
|
.Select(p => Path.GetFullPath(p).Substring(fullBinPath.Length));
|
|
}
|
|
|
|
private void CleanBinObj(DirectoryInfo projectDirectory)
|
|
{
|
|
var dirs = new DirectoryInfo[] { projectDirectory.GetDirectory("bin"), projectDirectory.GetDirectory("obj") };
|
|
|
|
foreach (var dir in dirs)
|
|
{
|
|
if(dir.Exists)
|
|
{
|
|
dir.Delete(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void BuildProjectJson(DirectoryInfo projectDirectory)
|
|
{
|
|
Console.WriteLine(projectDirectory);
|
|
|
|
var projectFile = $"\"{projectDirectory.GetFile("project.json").FullName}\"";
|
|
|
|
var result = new BuildPJCommand()
|
|
.WithCapturedOutput()
|
|
.WithForwardingToConsole()
|
|
.Execute(projectFile);
|
|
|
|
result.Should().Pass();
|
|
}
|
|
|
|
private void MigrateProject(params string[] migrateArgs)
|
|
{
|
|
new TestCommand("dotnet")
|
|
.WithForwardingToConsole()
|
|
.Execute($"migrate {string.Join(" ", migrateArgs)}")
|
|
.Should()
|
|
.Pass();
|
|
}
|
|
|
|
private void RestoreProjectJson(DirectoryInfo projectDirectory)
|
|
{
|
|
var projectFile = $"\"{projectDirectory.GetFile("project.json").FullName}\"";
|
|
new RestoreProjectJsonCommand()
|
|
.Execute(projectFile)
|
|
.Should().Pass();
|
|
}
|
|
|
|
private void Restore(DirectoryInfo projectDirectory, string projectName=null, string runtime=null)
|
|
{
|
|
var command = new RestoreCommand()
|
|
.WithWorkingDirectory(projectDirectory)
|
|
.WithRuntime(runtime);
|
|
|
|
if (projectName != null)
|
|
{
|
|
if (!Path.HasExtension(projectName))
|
|
{
|
|
projectName += ".csproj";
|
|
}
|
|
command.Execute($"{projectName} /p:SkipInvalidConfigurations=true;_InvalidConfigurationWarning=false")
|
|
.Should().Pass();
|
|
}
|
|
else
|
|
{
|
|
command.Execute("/p:SkipInvalidConfigurations=true;_InvalidConfigurationWarning=false")
|
|
.Should().Pass();
|
|
}
|
|
}
|
|
|
|
private string BuildMSBuild(
|
|
DirectoryInfo projectDirectory,
|
|
string projectName,
|
|
string configuration="Debug",
|
|
string runtime=null,
|
|
string framework=null)
|
|
{
|
|
if (projectName != null && !Path.HasExtension(projectName))
|
|
{
|
|
projectName = projectName + ".csproj";
|
|
}
|
|
|
|
DeleteXproj(projectDirectory);
|
|
|
|
var result = new BuildCommand()
|
|
.WithWorkingDirectory(projectDirectory)
|
|
.WithRuntime(runtime)
|
|
.WithFramework(framework)
|
|
.ExecuteWithCapturedOutput($"{projectName} /p:Configuration={configuration}");
|
|
|
|
result
|
|
.Should().Pass();
|
|
|
|
return result.StdOut;
|
|
}
|
|
|
|
private string PublishMSBuild(
|
|
DirectoryInfo projectDirectory,
|
|
string projectName,
|
|
string runtime = null,
|
|
string configuration = "Debug")
|
|
{
|
|
if (projectName != null)
|
|
{
|
|
projectName = projectName + ".csproj";
|
|
}
|
|
|
|
DeleteXproj(projectDirectory);
|
|
|
|
var result = new PublishCommand()
|
|
.WithRuntime(runtime)
|
|
.WithWorkingDirectory(projectDirectory)
|
|
.ExecuteWithCapturedOutput($"{projectName} /p:Configuration={configuration}");
|
|
|
|
result.Should().Pass();
|
|
|
|
return result.StdOut;
|
|
}
|
|
|
|
private string PackMSBuild(DirectoryInfo projectDirectory, string projectName)
|
|
{
|
|
if (projectName != null && !Path.HasExtension(projectName))
|
|
{
|
|
projectName = projectName + ".csproj";
|
|
}
|
|
|
|
var result = new PackCommand()
|
|
.WithWorkingDirectory(projectDirectory)
|
|
.ExecuteWithCapturedOutput($"{projectName}");
|
|
|
|
result.Should().Pass();
|
|
|
|
return result.StdOut;
|
|
}
|
|
|
|
private void DeleteXproj(DirectoryInfo projectDirectory)
|
|
{
|
|
var xprojFiles = projectDirectory.EnumerateFiles("*.xproj");
|
|
|
|
foreach (var xprojFile in xprojFiles)
|
|
{
|
|
xprojFile.Delete();
|
|
}
|
|
}
|
|
|
|
private void OutputDiagnostics(MigratedBuildComparisonData comparisonData)
|
|
{
|
|
OutputDiagnostics(comparisonData.MSBuildBuildOutputs, comparisonData.ProjectJsonBuildOutputs);
|
|
}
|
|
|
|
private void OutputDiagnostics(HashSet<string> msbuildBuildOutputs, HashSet<string> projectJsonBuildOutputs)
|
|
{
|
|
Console.WriteLine("Project.json Outputs:");
|
|
|
|
Console.WriteLine(string.Join("\n", projectJsonBuildOutputs));
|
|
|
|
Console.WriteLine("");
|
|
|
|
Console.WriteLine("MSBuild Outputs:");
|
|
|
|
Console.WriteLine(string.Join("\n", msbuildBuildOutputs));
|
|
}
|
|
|
|
private class MigratedBuildComparisonData
|
|
{
|
|
public HashSet<string> ProjectJsonBuildOutputs { get; }
|
|
|
|
public HashSet<string> MSBuildBuildOutputs { get; }
|
|
|
|
public MigratedBuildComparisonData(HashSet<string> projectJsonBuildOutputs,
|
|
HashSet<string> msBuildBuildOutputs)
|
|
{
|
|
ProjectJsonBuildOutputs = projectJsonBuildOutputs;
|
|
|
|
MSBuildBuildOutputs = msBuildBuildOutputs;
|
|
}
|
|
}
|
|
|
|
private void WriteGlobalJson(DirectoryInfo globalDirectory)
|
|
{
|
|
var file = globalDirectory.GetFile("global.json");
|
|
|
|
File.WriteAllText(file.FullName, @"
|
|
{
|
|
""projects"": [ ]
|
|
}");
|
|
}
|
|
}
|
|
}
|