Merge from rel/1.0.0

This commit is contained in:
Justin Goshi 2017-01-23 10:25:16 -08:00
commit 3884c90938
64 changed files with 1474 additions and 1805 deletions

View file

@ -0,0 +1,16 @@
// 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;
namespace TestApp
{
public class Program
{
public static int Main(string[] args)
{
Console.WriteLine(TestLibrary.Helper.GetMessage());
return 0;
}
}
}

View file

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestApp", "TestApp.xproj", "{0138CB8F-4AA9-4029-A21E-C07C30F425BA}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestLibrary", "..\TestLibrary\TestLibrary.csproj", "{DC0B35D0-8A36-4B52-8A11-B86739F055D2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|Any CPU.Build.0 = Release|Any CPU
{DC0B35D0-8A36-4B52-8A11-B86739F055D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC0B35D0-8A36-4B52-8A11-B86739F055D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC0B35D0-8A36-4B52-8A11-B86739F055D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC0B35D0-8A36-4B52-8A11-B86739F055D2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.23107" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.23107</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>0138cb8f-4aa9-4029-a21e-c07c30f425ba</ProjectGuid>
<RootNamespace>TestAppWithContents</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\..\artifacts\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,30 @@
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"dependencies": {
"TestLibrary": {
"target": "project",
"version": "1.0.0-*"
},
"Microsoft.NETCore.App": "1.0.1"
},
"frameworks": {
"netcoreapp1.0": {}
},
"runtimes": {
"win7-x64": {},
"win7-x86": {},
"osx.10.10-x64": {},
"osx.10.11-x64": {},
"ubuntu.14.04-x64": {},
"ubuntu.16.04-x64": {},
"centos.7-x64": {},
"rhel.7.2-x64": {},
"debian.8-x64": {},
"fedora.23-x64": {},
"opensuse.13.2-x64": {}
}
}

View file

@ -0,0 +1,15 @@
// 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;
namespace TestLibrary
{
public static class Helper
{
public static string GetMessage()
{
return "This string came from the test library!";
}
}
}

View file

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.5</TargetFramework>
<AssemblyName>TestLibrary</AssemblyName>
<PackageId>TestLibrary</PackageId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NETStandard.Library" Version="1.6.0" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.23107" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.23107</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>dc0b35d0-8a36-4b52-8a11-b86739f055d2</ProjectGuid>
<RootNamespace>TestAppWithContents</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\..\artifacts\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,9 @@
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.6.0"
},
"frameworks": {
"netstandard1.5": {}
}
}

View file

@ -0,0 +1,4 @@
{
"projects": [ "src", "src with spaces", "src without projects" ]
}

View file

@ -0,0 +1,19 @@
// 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.Diagnostics;
namespace TestApp
{
public class Program
{
public static int Main(string[] args)
{
Console.WriteLine("This string came from ProjectJ");
string helperStr = TestLibrary.ProjectI.GetMessage();
Console.WriteLine(helperStr);
return 0;
}
}
}

View file

@ -0,0 +1,20 @@
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"dependencies": {
"ProjectI": {
"target": "project",
"version": "1.0.0-*"
},
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"frameworks": {
"netcoreapp1.0": {}
}
}

View file

@ -0,0 +1,19 @@
// 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.Diagnostics;
namespace TestApp
{
public class Program
{
public static int Main(string[] args)
{
Console.WriteLine("This string came from ProjectH");
string helperStr = TestLibrary.ProjectI.GetMessage();
Console.WriteLine(helperStr);
return 0;
}
}
}

View file

@ -0,0 +1,20 @@
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"dependencies": {
"ProjectI": {
"target": "project",
"version": "1.0.0-*"
},
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"frameworks": {
"netcoreapp1.0": {}
}
}

View file

@ -0,0 +1,15 @@
// 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;
namespace TestLibrary
{
public static class ProjectI
{
public static string GetMessage()
{
return "This string came from ProjectI";
}
}
}

View file

@ -0,0 +1,18 @@
{
"version": "1.0.0-*",
"buildOptions": {
"nowarn": [
"CS1591"
],
"xmlDoc": true,
"additionalArguments": [
"-highentropyva+"
]
},
"dependencies": {
"NETStandard.Library": "1.6.0"
},
"frameworks": {
"netstandard1.5": {}
}
}

View file

@ -0,0 +1,39 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26006.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "App", "src\App\App.csproj", "{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{72BFCA87-B033-4721-8712-4D12166B4A39}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Debug|x64.ActiveCfg = Debug|x64
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Debug|x64.Build.0 = Debug|x64
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Debug|x86.ActiveCfg = Debug|x86
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Debug|x86.Build.0 = Debug|x86
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Release|Any CPU.Build.0 = Release|Any CPU
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Release|x64.ActiveCfg = Release|x64
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Release|x64.Build.0 = Release|x64
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Release|x86.ActiveCfg = Release|x86
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{DDF3765C-59FB-4AA6-BE83-779ED13AA64A} = {72BFCA87-B033-4721-8712-4D12166B4A39}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\src\Lib\Lib.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.App" Version="1.0.3" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,10 @@
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello from the main app");
Console.WriteLine(Lib.Library.GetMessage());
}
}

View file

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NETStandard.Library" Version="1.6" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,12 @@
using System;
namespace Lib
{
public class Library
{
public static string GetMessage()
{
return "Message from Lib";
}
}
}

View file

@ -5,7 +5,7 @@
<CLI_Roslyn_Version>2.0.0-rc3-61212-03</CLI_Roslyn_Version>
<CLI_NETSDK_Version>1.0.0-alpha-20170117-4</CLI_NETSDK_Version>
<CLI_NuGet_Version>4.0.0-rc3</CLI_NuGet_Version>
<CLI_WEBSDK_Version>1.0.0-alpha-20170114-1-223</CLI_WEBSDK_Version>
<CLI_WEBSDK_Version>1.0.0-alpha-20170120-3-249</CLI_WEBSDK_Version>
<CLI_TestPlatform_Version>15.0.0-preview-20170106-08</CLI_TestPlatform_Version>
<TemplateEngineVersion>1.0.0-beta1-20170108-83</TemplateEngineVersion>
</PropertyGroup>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="14.0" DefaultTargets="Test">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<PathSeparator>/</PathSeparator>
@ -7,14 +7,11 @@
</PropertyGroup>
<Import Project="test/TestPackageProjects.targets" />
<Import Project="test/TestAssetProjects.targets" />
<Import Project="test/TestProjects.targets" />
<Target Name="Test"
Condition=" '$(CLIBUILD_SKIP_TESTS)' != 'true' "
DependsOnTargets="PrepareTests;
BuildTestAssets;
BuildTests;">
DependsOnTargets="BuildTests;">
<PropertyGroup>
<PathListSeparator>:</PathListSeparator>
@ -39,11 +36,10 @@
CLIBuildDll=$(CLIBuildDll);
Configuration=$(Configuration);
EnvironmentVariables=$(RunTestEnvironmentVariables);
TestProject=%(TestProjects.ProjectPath);
TestProjectName=%(TestProjects.OutputName);
TestProject=%(TestProjects.Identity);
TestResultXmlDir=$(TestResultXmlDir);
ToolPath=$(Stage0Directory);
WorkingDirectory=%(TestProjects.ProjectDir)
WorkingDirectory=$([System.IO.Directory]::GetParent(%(TestProjects.Identity)))
</Properties>
</ProjectsToTest>
</ItemGroup>
@ -59,7 +55,8 @@
</Target>
<Target Name="PrepareTests"
DependsOnTargets="Init">
DependsOnTargets="Init;
SetupTestProjectData">
<PropertyGroup>
<TestPackageBuildVersionSuffix>$(CommitCount)</TestPackageBuildVersionSuffix>
<TestOutputDir>$(RepoRoot)/artifacts/testpackages/</TestOutputDir>
@ -74,113 +71,21 @@
<MakeDir Directories="$(TestPackagesDir)" Condition="!Exists('$(TestPackagesDir)')"/>
</Target>
<Target Name="BuildTests"
DependsOnTargets="RestoreTests;
SetupTestProjectData;"
Inputs="%(TestProjects.BuildInputs)"
Outputs="%(TestProjects.BuildOutput)">
<DotNetBuild Configuration="$(Configuration)"
Framework="%(TestProjects.Framework)"
ToolPath="$(Stage0Directory)"
ProjectPath="%(TestProjects.ProjectPath)" />
</Target>
<Target Name="RestoreTests"
DependsOnTargets="CreateTestAssetPackageNuPkgs;">
<CallTarget Targets="CleanTestProjectsLockFiles"/>
DependsOnTargets="PrepareTests;
CreateTestAssetPackageNuPkgs;">
<DotNetRestore ToolPath="$(Stage0Directory)"
ProjectPath="&quot;$(TestDirectory)/Microsoft.DotNet.Cli.Tests.sln&quot;" />
</Target>
<Target Name="BuildTestAssets"
DependsOnTargets="BuildTestAssetProjects;
BuildDesktopTestAssetProjects;">
</Target>
<Target Name="BuildTestAssetProjects"
DependsOnTargets="RestoreTestAssetProjects;
SetupTestAssetProjectData;"
Inputs="%(TestAssetProjects.BuildInputs)"
Outputs="%(TestAssetProjects.BuildOutput)">
<DotNetBuildPj Framework="netcoreapp1.0"
ProjectPath="$(RepoRoot)%(TestAssetProjects.ProjectPath)"
ToolPath="$(Stage0PjDirectory)" />
</Target>
<Target Name="RestoreTestAssetProjects"
DependsOnTargets="CreateTestAssetPackageNuPkgs;
SetupRestoreTestAssetProjectsInputs;"
Inputs="@(RestoreTestAssetProjectsInputs)"
Outputs="@(RestoreTestAssetProjectsInputs->'%(RelativeDir)/project.lock.json')">
<DotNetRestorePj FallbackSource="$(TestPackagesDir)"
ToolPath="$(Stage0PjDirectory)"
WorkingDirectory="$(RepoRoot)TestAssets/TestProjects/" />
</Target>
<Target Name="SetupRestoreTestAssetProjectsInputs" >
<ItemGroup>
<RestoreTestAssetProjectsInputs Include="$(RepoRoot)/TestAssets/TestProjects/**/project.json" />
</ItemGroup>
</Target>
<Target Name="CleanTestAssetProjectsLockFiles" >
<ItemGroup>
<TestAssetProjectsLockFiles Include="$(RepoRoot)/TestAssets/TestProjects/**/project.lock.json" />
</ItemGroup>
<Delete Files="@(TestAssetProjectsLockFiles)" />
</Target>
<Target Name="CleanTestProjectsLockFiles" >
<ItemGroup>
<TestProjectsLockFiles Include="$(RepoRoot)/test/**/project.assets.json;$(RepoRoot)/test/**/*.csproj.nuget.g.props;$(RepoRoot)/test/**/*.csproj.nuget.g.targets" />
</ItemGroup>
<Delete Files="@(TestProjectsLockFiles)" />
</Target>
<Target Name="BuildDesktopTestAssetProjects"
Condition=" '$(IsDesktopAvailable)' == 'True' "
DependsOnTargets="RestoreDesktopTestAssetProjects">
<ItemGroup>
<NoAutoBuildDesktopTestAssets Include="$(RepoRoot)TestAssets\DesktopTestProjects\**\.noautobuild" />
<NoAutoBuildDesktopTestAssetProjects Include="%(NoAutoBuildDesktopTestAssets.RelativeDir)project.json" />
<BuildableDesktopTestAssetProjects Include="$(RepoRoot)TestAssets\DesktopTestProjects\**\project.json"
Exclude="@(NoAutoBuildDesktopTestAssetProjects)" />
</ItemGroup>
<Message Text="Skipping projects with .noautobuild files:" />
<Message Text="%(NoAutoBuildDesktopTestAssetProjects.FullPath)" />
<DotNetBuild Condition="'@(BuildableDesktopTestAssetProjects)' != ''"
Configuration="$(Configuration)"
Framework="net46"
ProjectPath="%(BuildableDesktopTestAssetProjects.FullPath)"
ToolPath="$(Stage0PjDirectory)" />
</Target>
<Target Name="RestoreDesktopTestAssetProjects"
Condition=" '$(IsDesktopAvailable)' == 'True' "
DependsOnTargets="CreateTestAssetPackageNuPkgs;
SetupRestoreDesktopTestAssetProjectsInputs;"
Inputs="@(RestoreDesktopTestAssetProjectsInputs)"
Outputs="@(RestoreDesktopTestAssetProjectsInputs->'%(RelativeDir)/project.lock.json')">
<DotNetRestorePj FallbackSource="$(TestPackagesDir)"
ToolPath="$(Stage0PjDirectory)"
WorkingDirectory="$(RepoRoot)TestAssets\DesktopTestProjects\" />
</Target>
<Target Name="SetupRestoreDesktopTestAssetProjectsInputs">
<ItemGroup>
<RestoreDesktopTestAssetProjectsInputs Include="$(RepoRoot)TestAssets\DesktopTestProjects\**\project.json" />
</ItemGroup>
<Target Name="BuildTests"
DependsOnTargets="RestoreTests;">
<DotNetBuild ToolPath="$(Stage0Directory)"
ProjectPath="&quot;$(TestDirectory)/Microsoft.DotNet.Cli.Tests.sln&quot;" />
</Target>
<Target Name="CreateTestAssetPackageNuPkgs"
DependsOnTargets="PrepareTests;
SetupTestPackageProjectData;"
DependsOnTargets="SetupTestPackageProjectData;"
Inputs="%(TestPackageProject.PackInputs)"
Outputs="%(TestPackageProject.PackOutputs)">

View file

@ -1,32 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="SetupTestProjectData"
DependsOnTargets="AssociateTestInputFilesWithProject">
</Target>
<Target Name="AssociateTestInputFilesWithProject"
DependsOnTargets="IdentifyTestInputFilesForProject;"
Outputs="%(TestProjects.ProjectPath)">
<PropertyGroup>
<CurrentProject>%(TestProjects.ProjectPath)</CurrentProject>
</PropertyGroup>
<ItemGroup>
<TestProjects Condition=" '%(ProjectPath)' == '$(CurrentProject)' ">
<BuildInputs>@(TestProjectInputs)</BuildInputs>
</TestProjects>
</ItemGroup>
</Target>
<Target Name="IdentifyTestInputFilesForProject"
DependsOnTargets="SetupBuildTestProjectInputs;"
Outputs="%(TestProjects.ProjectPath)">
<ItemGroup>
<TestProjectInputs Include="%(TestProjects.BuildInputIncludeFilter)"
Exclude="%(TestProjects.BuildInputExcludeFilter)">
<ProjectPath>%(TestProjects.ProjectPath)</ProjectPath>
</TestProjectInputs>
</ItemGroup>
DependsOnTargets="SetupBuildTestProjectInputs">
</Target>
<Target Name="SetupBuildTestProjectInputs">
@ -37,53 +12,21 @@
-->
<PreTestProjectsToExclude Include="test$(PathSeparator)binding-redirects.Tests$(PathSeparator)binding-redirects.Tests.csproj;" />
<PreTestProjectsToExclude Condition=" 'https://github.com/dotnet/cli/issues/3216' != 'fixed' "
Include="test$(PathSeparator)Kestrel.Tests$(PathSeparator)Kestrel.Tests.csproj" />
<PreTestProjectsToExclude Condition=" 'Non-test projects in test directory' != 'consider moving elsewhere' "
Include="test$(PathSeparator)ArgumentsReflector$(PathSeparator)ArgumentsReflector.csproj;
test$(PathSeparator)Microsoft.DotNet.Tools.Tests.Utilities$(PathSeparator)Microsoft.DotNet.Tools.Tests.Utilities.csproj;
test$(PathSeparator)TestingAbstractions$(PathSeparator)TestAppWithFullPdbs$(PathSeparator)TestAppWithFullPdbs.csproj;
test$(PathSeparator)TestingAbstractions$(PathSeparator)TestAppWithPortablePdbs$(PathSeparator)TestAppWithPortablePdbs.csproj;
test$(PathSeparator)Msbuild.Tests.Utilities$(PathSeparator)Msbuild.Tests.Utilities.csproj" />
test$(PathSeparator)Msbuild.Tests.Utilities$(PathSeparator)Msbuild.Tests.Utilities.csproj;
test$(PathSeparator)Performance$(PathSeparator)Performance.csproj" />
<PreTestProjectsToExclude Condition=" 'Executed after primary test phase.' != ' Consider moving.' "
Include="test$(PathSeparator)Installer$(PathSeparator)Microsoft.DotNet.Cli.Msi.Tests$(PathSeparator)Microsoft.DotNet.Cli.Msi.Tests.csproj;" />
<PreTestProjectsToExclude Include="test$(PathSeparator)**$(PathSeparator)bin$(PathSeparator)**$(PathSeparator)*.csproj" />
<!-- The current ResolveNuGetAssets target does not work on case-sensitive file systems. We need https://github.com/dotnet/sdk/pull/10 -->
<PreTestProjectsToExclude Condition="'$(OSName)' != 'win' and '$(OSName)' != 'osx'"
Include="test$(PathSeparator)dotnet-build3.Tests$(PathSeparator)dotnet-build3.Tests.csproj" />
<TestProjectsToExclude Include="%(PreTestProjectsToExclude.Fullpath)" />
<PreTestProjects Include="test$(PathSeparator)**$(PathSeparator)*.csproj;" />
<PreTestProjects Include="test$(PathSeparator)*$(PathSeparator)*.csproj;" />
<TestProjects Include="%(PreTestProjects.Fullpath)"
Exclude="@(TestProjectsToExclude)" />
<TestProjects>
<BuildInputIncludeFilter>%(RelativeDir)**/*.*</BuildInputIncludeFilter>
<BuildInputExcludeFilter>%(RelativeDir)bin/**/*.*;%(RelativeDir)obj/**/*.*</BuildInputExcludeFilter>
<ProjectDir>$([System.IO.Directory]::GetParent(%(Identity)))</ProjectDir>
<ProjectPath>%(Identity)</ProjectPath>
<Framework>netcoreapp1.0</Framework>
</TestProjects>
<TestProjects>
<OutputName>$([System.IO.Path]::GetFileName(%(ProjectDir)))</OutputName>
</TestProjects>
<TestProjects>
<BuildOutput>$(RepoRoot)%(TestProjects.RelativeDir)bin/$(Configuration)/%(TestProjects.Framework)/%(TestProjects.OutputName).dll</BuildOutput>
</TestProjects>
<TestProjects Condition=" '%(RelativeDir)' == 'test\Installer\Microsoft.DotNet.Cli.Msi.Tests\' ">
<Framework>net46</Framework>
</TestProjects>
</ItemGroup>
<Message Text="%(TestProjects.Identity) %(TestProjects.RelativeDir) %(TestProjects.Framework)" />
</Target>
</Project>
</Project>

View file

@ -5,86 +5,217 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.DotNet.Internal.ProjectModel.Utilities;
namespace Microsoft.DotNet.ProjectJsonMigration
{
internal class MigrationBackupPlan
{
private const string TempCsprojExtention = ".migration_in_place_backup";
private readonly FileInfo globalJson;
private readonly Dictionary<DirectoryInfo, IEnumerable<FileInfo>> mapOfProjectBackupDirectoryToFilesToMove;
public DirectoryInfo RootBackupDirectory { get; }
public DirectoryInfo[] ProjectBackupDirectories { get; }
public IEnumerable<FileInfo> FilesToMove(DirectoryInfo projectBackupDirectory)
=> mapOfProjectBackupDirectoryToFilesToMove[projectBackupDirectory];
public MigrationBackupPlan(
DirectoryInfo projectDirectory,
IEnumerable<DirectoryInfo> projectDirectories,
DirectoryInfo workspaceDirectory,
Func<DirectoryInfo, IEnumerable<FileInfo>> getFiles = null)
{
if (projectDirectory == null)
if (projectDirectories == null)
{
throw new ArgumentNullException(nameof(projectDirectory));
throw new ArgumentNullException(nameof(projectDirectories));
}
if (!projectDirectories.Any())
{
throw new ArgumentException("No project directories provided.", nameof(projectDirectories));
}
if (workspaceDirectory == null)
{
throw new ArgumentNullException(nameof(workspaceDirectory));
}
globalJson = new FileInfo(Path.Combine(
workspaceDirectory.FullName,
"global.json"));
MigrationTrace.Instance.WriteLine("Computing migration backup plan...");
projectDirectory = new DirectoryInfo(projectDirectory.FullName.EnsureTrailingSlash());
projectDirectories = projectDirectories.Select(pd => new DirectoryInfo(pd.FullName.EnsureTrailingSlash()));
workspaceDirectory = new DirectoryInfo(workspaceDirectory.FullName.EnsureTrailingSlash());
MigrationTrace.Instance.WriteLine($" Workspace: {workspaceDirectory.FullName}");
foreach (var projectDirectory in projectDirectories)
{
MigrationTrace.Instance.WriteLine($" Project: {projectDirectory.FullName}");
}
var rootDirectory = FindCommonRootPath(projectDirectories.ToArray()) ?? workspaceDirectory;
rootDirectory = new DirectoryInfo(rootDirectory.FullName.EnsureTrailingSlash());
MigrationTrace.Instance.WriteLine($" Root: {rootDirectory.FullName}");
globalJson = new FileInfo(
Path.Combine(
workspaceDirectory.FullName,
"global.json"));
RootBackupDirectory = new DirectoryInfo(
Path.Combine(
workspaceDirectory.Parent.FullName,
"backup")
GetUniqueDirectoryPath(
Path.Combine(
rootDirectory.FullName,
"backup"))
.EnsureTrailingSlash());
ProjectBackupDirectory = new DirectoryInfo(
Path.Combine(
RootBackupDirectory.FullName,
projectDirectory.Name)
.EnsureTrailingSlash());
MigrationTrace.Instance.WriteLine($" Root Backup: {RootBackupDirectory.FullName}");
var relativeDirectory = PathUtility.GetRelativePath(
workspaceDirectory.FullName,
projectDirectory.FullName);
var projectBackupDirectories = new List<DirectoryInfo>();
mapOfProjectBackupDirectoryToFilesToMove = new Dictionary<DirectoryInfo, IEnumerable<FileInfo>>();
getFiles = getFiles ?? (dir => dir.EnumerateFiles());
getFiles = getFiles ??
(dir => dir.EnumerateFiles());
foreach (var projectDirectory in projectDirectories)
{
var projectBackupDirectory = ComputeProjectBackupDirectoryPath(rootDirectory, projectDirectory, RootBackupDirectory);
var filesToMove = getFiles(projectDirectory).Where(NeedsBackup);
FilesToMove = getFiles(projectDirectory)
.Where(f => f.Name == "project.json"
|| f.Extension == ".xproj"
|| f.FullName.EndsWith(".xproj.user")
|| f.FullName.EndsWith(".lock.json"));
projectBackupDirectories.Add(projectBackupDirectory);
mapOfProjectBackupDirectoryToFilesToMove.Add(projectBackupDirectory, filesToMove);
}
ProjectBackupDirectories = projectBackupDirectories.ToArray();
}
public DirectoryInfo ProjectBackupDirectory { get; }
public DirectoryInfo RootBackupDirectory { get; }
public IEnumerable<FileInfo> FilesToMove { get; }
public void PerformBackup()
{
if (globalJson.Exists)
{
PathUtility.EnsureDirectoryExists(RootBackupDirectory.FullName);
globalJson.MoveTo(Path.Combine(
ProjectBackupDirectory.Parent.FullName,
globalJson.Name));
}
PathUtility.EnsureDirectoryExists(ProjectBackupDirectory.FullName);
foreach (var file in FilesToMove)
{
file.MoveTo(
globalJson.MoveTo(
Path.Combine(
ProjectBackupDirectory.FullName, file.Name));
RootBackupDirectory.FullName,
globalJson.Name));
}
foreach (var kvp in mapOfProjectBackupDirectoryToFilesToMove)
{
var projectBackupDirectory = kvp.Key;
var filesToMove = kvp.Value;
PathUtility.EnsureDirectoryExists(projectBackupDirectory.FullName);
foreach (var file in filesToMove)
{
var fileName = file.Name.EndsWith(TempCsprojExtention)
? Path.GetFileNameWithoutExtension(file.Name)
: file.Name;
file.MoveTo(
Path.Combine(
projectBackupDirectory.FullName,
fileName));
}
}
}
private static DirectoryInfo ComputeProjectBackupDirectoryPath(
DirectoryInfo rootDirectory, DirectoryInfo projectDirectory, DirectoryInfo rootBackupDirectory)
{
if (PathUtility.IsChildOfDirectory(rootDirectory.FullName, projectDirectory.FullName))
{
var relativePath = PathUtility.GetRelativePath(
rootDirectory.FullName,
projectDirectory.FullName);
return new DirectoryInfo(
Path.Combine(
rootBackupDirectory.FullName,
relativePath)
.EnsureTrailingSlash());
}
// Ensure that we use a unique name to avoid collisions as a fallback.
return new DirectoryInfo(
GetUniqueDirectoryPath(
Path.Combine(
rootBackupDirectory.FullName,
projectDirectory.Name)
.EnsureTrailingSlash()));
}
private static bool NeedsBackup(FileInfo file)
=> file.Name == "project.json"
|| file.Extension == ".xproj"
|| file.FullName.EndsWith(".xproj.user")
|| file.FullName.EndsWith(".lock.json")
|| file.FullName.EndsWith(TempCsprojExtention);
private static string GetUniqueDirectoryPath(string directoryPath)
{
var candidatePath = directoryPath;
var suffix = 1;
while (Directory.Exists(candidatePath))
{
candidatePath = $"{directoryPath}_{suffix++}";
}
return candidatePath;
}
private static DirectoryInfo FindCommonRootPath(DirectoryInfo[] paths)
{
var pathSplits = new string[paths.Length][];
var shortestLength = int.MaxValue;
for (int i = 0; i < paths.Length; i++)
{
pathSplits[i] = paths[i].FullName.Split(new[] { Path.DirectorySeparatorChar });
shortestLength = Math.Min(shortestLength, pathSplits[i].Length);
}
var builder = new StringBuilder();
var splitIndex = 0;
while (splitIndex < shortestLength)
{
var split = pathSplits[0][splitIndex];
var done = false;
for (int i = 1; i < pathSplits.Length; i++)
{
if (pathSplits[i][splitIndex] != split)
{
done = true;
break;
}
}
if (done)
{
break;
}
builder.Append(split);
builder.Append(Path.DirectorySeparatorChar);
splitIndex++;
}
return new DirectoryInfo(builder.ToString().EnsureTrailingSlash());
}
public static void RenameCsprojFromMigrationOutputNameToTempName(string outputProject)
{
var backupFileName = $"{outputProject}{TempCsprojExtention}";
if (File.Exists(backupFileName))
{
File.Delete(backupFileName);
}
File.Move(outputProject, backupFileName);
}
}
}

View file

@ -20,6 +20,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
{
private readonly IMigrationRule _ruleSet;
private readonly ProjectDependencyFinder _projectDependencyFinder = new ProjectDependencyFinder();
private HashSet<string> _migratedProjects = new HashSet<string>();
public ProjectMigrator() : this(new DefaultMigrationRuleSet()) { }
@ -76,7 +77,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration
var settings = new MigrationSettings(projectDir,
projectDir,
rootSettings.MSBuildProjectTemplatePath);
MigrateProject(settings);
projectMigrationReports.Add(MigrateProject(settings));
}
@ -141,13 +141,28 @@ namespace Microsoft.DotNet.ProjectJsonMigration
{
var migrationRuleInputs = ComputeMigrationRuleInputs(migrationSettings);
var projectName = migrationRuleInputs.DefaultProjectContext.GetProjectName();
var outputProject = Path.Combine(migrationSettings.OutputDirectory, projectName + ".csproj");
try
{
if (IsMigrated(migrationSettings, migrationRuleInputs))
if (File.Exists(outputProject))
{
MigrationTrace.Instance.WriteLine(String.Format(LocalizableStrings.SkipMigrationAlreadyMigrated, nameof(ProjectMigrator), migrationSettings.ProjectDirectory));
return new ProjectMigrationReport(migrationSettings.ProjectDirectory, projectName, skipped: true);
if (_migratedProjects.Contains(outputProject))
{
MigrationTrace.Instance.WriteLine(String.Format(
LocalizableStrings.SkipMigrationAlreadyMigrated,
nameof(ProjectMigrator),
migrationSettings.ProjectDirectory));
return new ProjectMigrationReport(
migrationSettings.ProjectDirectory,
projectName,
skipped: true);
}
else
{
MigrationBackupPlan.RenameCsprojFromMigrationOutputNameToTempName(outputProject);
}
}
VerifyInputs(migrationRuleInputs, migrationSettings);
@ -185,7 +200,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration
}
}
var outputProject = Path.Combine(migrationSettings.OutputDirectory, projectName + ".csproj");
_migratedProjects.Add(outputProject);
return new ProjectMigrationReport(
migrationSettings.ProjectDirectory,
projectName,
@ -286,14 +302,5 @@ namespace Microsoft.DotNet.ProjectJsonMigration
File.Copy(sourceFilePath, destinationFilePath);
}
}
public bool IsMigrated(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
{
var outputName = migrationRuleInputs.DefaultProjectContext.GetProjectName();
var outputProject = Path.Combine(migrationSettings.OutputDirectory, outputName + ".csproj");
return File.Exists(outputProject);
}
}
}

View file

@ -346,7 +346,7 @@ namespace Microsoft.DotNet.TestFramework
file.Refresh();
if (!file.Exists)
{
throw new ArgumentException("Inventory file should exist.");
return Enumerable.Empty<FileInfo>();
}
var inventory = new List<FileInfo>();

View file

@ -30,7 +30,7 @@ namespace Microsoft.DotNet.TestFramework
var testDirectory = new DirectoryInfo(path);
var migrationBackupDirectory = new DirectoryInfo(
System.IO.Path.Combine(testDirectory.Parent.FullName, "backup"));
System.IO.Path.Combine(testDirectory.FullName, "backup"));
if (testDirectory.Exists)
{

View file

@ -10,34 +10,18 @@ namespace Microsoft.DotNet.Tools.Common
{
public static class SlnProjectCollectionExtensions
{
public static HashSet<string> GetReferencedSolutionFolders(this SlnProjectCollection projects)
public static IEnumerable<SlnProject> GetProjectsByType(
this SlnProjectCollection projects,
string typeGuid)
{
var referencedSolutionFolders = new HashSet<string>();
return projects.Where(p => p.TypeGuid == typeGuid);
}
var solutionFolderProjects = projects
.Where(p => p.TypeGuid == ProjectTypeGuids.SolutionFolderGuid)
.ToList();
if (solutionFolderProjects.Any())
{
var nonSolutionFolderProjects = projects
.Where(p => p.TypeGuid != ProjectTypeGuids.SolutionFolderGuid)
.ToList();
foreach (var project in nonSolutionFolderProjects)
{
var solutionFolders = project.GetSolutionFoldersFromProject();
foreach (var solutionFolder in solutionFolders)
{
if (!referencedSolutionFolders.Contains(solutionFolder))
{
referencedSolutionFolders.Add(solutionFolder);
}
}
}
}
return referencedSolutionFolders;
public static IEnumerable<SlnProject> GetProjectsNotOfType(
this SlnProjectCollection projects,
string typeGuid)
{
return projects.Where(p => p.TypeGuid != typeGuid);
}
}
}

View file

@ -12,17 +12,44 @@ namespace Microsoft.DotNet.Tools.Common
{
public static IList<string> GetSolutionFoldersFromProject(this SlnProject project)
{
var currentDirString = $".{Path.DirectorySeparatorChar}";
var solutionFolders = new List<string>();
var directoryPath = Path.GetDirectoryName(project.FilePath);
if (directoryPath.StartsWith(currentDirString))
var projectFilePath = project.FilePath;
if (IsPathInTreeRootedAtSolutionDirectory(projectFilePath))
{
directoryPath = directoryPath.Substring(currentDirString.Length);
var currentDirString = $".{Path.DirectorySeparatorChar}";
if (projectFilePath.StartsWith(currentDirString))
{
projectFilePath = projectFilePath.Substring(currentDirString.Length);
}
var projectDirectoryPath = TrimProject(projectFilePath);
if (!string.IsNullOrEmpty(projectDirectoryPath))
{
var solutionFoldersPath = TrimProjectDirectory(projectDirectoryPath);
if (!string.IsNullOrEmpty(solutionFoldersPath))
{
solutionFolders.AddRange(solutionFoldersPath.Split(Path.DirectorySeparatorChar));
}
}
}
return directoryPath.StartsWith("..")
? new List<string>()
: new List<string>(directoryPath.Split(Path.DirectorySeparatorChar));
return solutionFolders;
}
private static bool IsPathInTreeRootedAtSolutionDirectory(string path)
{
return !path.StartsWith("..");
}
private static string TrimProject(string path)
{
return Path.GetDirectoryName(path);
}
private static string TrimProjectDirectory(string path)
{
return Path.GetDirectoryName(path);
}
}
}

View file

@ -9,7 +9,7 @@ namespace Microsoft.DotNet.Tools.Add.PackageReference
public const string AppDescription = "Command to add package reference";
public const string AppHelpText = "Package references to add";
public const string CmdPackageDescription = "Package references to add";
public const string SpecifyExactlyOnePackageReference = "Please specify one package reference to add.";
@ -25,6 +25,8 @@ namespace Microsoft.DotNet.Tools.Add.PackageReference
public const string CmdDGFileException = "Unable to Create Dependency graph file for project '{0}'. Cannot add package reference.";
public const string CmdPackage = "PACKAGE_NAME";
public const string CmdVersion = "VERSION";
public const string CmdFramework = "FRAMEWORK";

View file

@ -1,12 +1,6 @@
// 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.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Build.Evaluation;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
@ -15,6 +9,12 @@ using Microsoft.DotNet.Tools.Common;
using Microsoft.DotNet.Tools.MSBuild;
using Microsoft.DotNet.Tools.NuGet;
using NuGet.Frameworks;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
namespace Microsoft.DotNet.Tools.Add.PackageReference
{
@ -25,6 +25,7 @@ namespace Microsoft.DotNet.Tools.Add.PackageReference
private CommandOption _noRestoreOption;
private CommandOption _sourceOption;
private CommandOption _packageDirectoryOption;
private CommandArgument _packageNameArgument;
public static DotNetSubCommandBase Create()
{
@ -33,12 +34,16 @@ namespace Microsoft.DotNet.Tools.Add.PackageReference
Name = "package",
FullName = LocalizableStrings.AppFullName,
Description = LocalizableStrings.AppDescription,
HandleRemainingArguments = true,
ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText,
HandleRemainingArguments = false
};
command.HelpOption("-h|--help");
command._packageNameArgument = command.Argument(
$"<{LocalizableStrings.CmdPackage}>",
LocalizableStrings.CmdPackageDescription,
multipleValues: false);
command._versionOption = command.Option(
$"-v|--version <{LocalizableStrings.CmdVersion}>",
LocalizableStrings.CmdVersionDescription,
@ -69,7 +74,7 @@ namespace Microsoft.DotNet.Tools.Add.PackageReference
public override int Run(string fileOrDirectory)
{
if (RemainingArguments.Count != 1)
if (_packageNameArgument.Values.Count != 1 || string.IsNullOrWhiteSpace(_packageNameArgument.Value) || RemainingArguments.Count > 0)
{
throw new GracefulException(LocalizableStrings.SpecifyExactlyOnePackageReference);
}
@ -94,7 +99,7 @@ namespace Microsoft.DotNet.Tools.Add.PackageReference
GetProjectDependencyGraph(projectFilePath, tempDgFilePath);
}
var result = NuGetCommand.Run(TransformArgs(RemainingArguments.First(), tempDgFilePath, projectFilePath));
var result = NuGetCommand.Run(TransformArgs(_packageNameArgument.Value, tempDgFilePath, projectFilePath));
DisposeTemporaryFile(tempDgFilePath);
return result;

View file

@ -113,22 +113,23 @@ namespace Microsoft.DotNet.Tools.Migrate
return;
}
List<string> csprojFilesToAdd = new List<string>();
var csprojFilesToAdd = new HashSet<string>();
var slnPathWithTrailingSlash = PathUtility.EnsureTrailingSlash(_slnFile.BaseDirectory);
foreach (var report in migrationReport.ProjectMigrationReports)
{
var reportPathWithTrailingSlash = PathUtility.EnsureTrailingSlash(report.ProjectDirectory);
var reportRelPath = Path.Combine(
PathUtility.GetRelativePath(slnPathWithTrailingSlash, reportPathWithTrailingSlash),
report.ProjectName + ".xproj");
var relativeReportPath = PathUtility.GetRelativePath(
slnPathWithTrailingSlash,
reportPathWithTrailingSlash);
var projects = _slnFile.Projects.Where(p => p.FilePath == reportRelPath);
var xprojPath = Path.Combine(relativeReportPath, report.ProjectName + ".xproj");
var xprojProjectsReferencedBySolution = _slnFile.Projects.Where(p => p.FilePath == xprojPath);
var migratedProjectName = report.ProjectName + ".csproj";
if (projects.Count() == 1)
if (xprojProjectsReferencedBySolution.Count() == 1)
{
var slnProject = projects.Single();
var slnProject = xprojProjectsReferencedBySolution.Single();
slnProject.FilePath = Path.Combine(
Path.GetDirectoryName(slnProject.FilePath),
migratedProjectName);
@ -136,7 +137,15 @@ namespace Microsoft.DotNet.Tools.Migrate
}
else
{
csprojFilesToAdd.Add(Path.Combine(report.ProjectDirectory, migratedProjectName));
var csprojPath = Path.Combine(relativeReportPath, migratedProjectName);
var solutionContainsCsprojPriorToMigration = _slnFile.Projects
.Where(p => p.FilePath == csprojPath)
.Any();
if (!solutionContainsCsprojPriorToMigration)
{
csprojFilesToAdd.Add(Path.Combine(report.ProjectDirectory, migratedProjectName));
}
}
foreach (var preExisting in report.PreExistingCsprojDependencies)
@ -211,14 +220,19 @@ namespace Microsoft.DotNet.Tools.Migrate
private void BackupProjects(MigrationReport migrationReport)
{
var projectDirectories = new List<DirectoryInfo>();
foreach (var report in migrationReport.ProjectMigrationReports)
{
var backupPlan = new MigrationBackupPlan(
new DirectoryInfo(report.ProjectDirectory),
_workspaceDirectory);
backupPlan.PerformBackup();
projectDirectories.Add(new DirectoryInfo(report.ProjectDirectory));
}
var backupPlan = new MigrationBackupPlan(
projectDirectories,
_workspaceDirectory);
backupPlan.PerformBackup();
Reporter.Output.WriteLine($"Files backed up to {backupPlan.RootBackupDirectory.FullName}");
}
private void WriteReport(MigrationReport migrationReport)
@ -310,7 +324,6 @@ namespace Microsoft.DotNet.Tools.Migrate
if (projectMigrationReport.Errors.Any())
{
sb.AppendLine(RedIfColored($"Project {projectMigrationReport.ProjectName} migration failed ({projectMigrationReport.ProjectDirectory})"));
foreach (var error in projectMigrationReport.Errors.Select(e => e.GetFormattedErrorMessage()))

View file

@ -163,28 +163,61 @@ namespace Microsoft.DotNet.Tools.Sln.Add
"NestedProjects",
SlnSectionType.PreProcess);
var pathToGuidMap = GetSolutionFolderPaths(slnFile, nestedProjectsSection.Properties);
string parentDirGuid = null;
var solutionFolderHierarchy = string.Empty;
foreach (var dir in solutionFolders)
{
var solutionFolder = new SlnProject
solutionFolderHierarchy = Path.Combine(solutionFolderHierarchy, dir);
if (pathToGuidMap.ContainsKey(solutionFolderHierarchy))
{
Id = Guid.NewGuid().ToString("B").ToUpper(),
TypeGuid = ProjectTypeGuids.SolutionFolderGuid,
Name = dir,
FilePath = dir
};
slnFile.Projects.Add(solutionFolder);
if (parentDirGuid != null)
{
nestedProjectsSection.Properties[solutionFolder.Id] = parentDirGuid;
parentDirGuid = pathToGuidMap[solutionFolderHierarchy];
}
else
{
var solutionFolder = new SlnProject
{
Id = Guid.NewGuid().ToString("B").ToUpper(),
TypeGuid = ProjectTypeGuids.SolutionFolderGuid,
Name = dir,
FilePath = dir
};
slnFile.Projects.Add(solutionFolder);
if (parentDirGuid != null)
{
nestedProjectsSection.Properties[solutionFolder.Id] = parentDirGuid;
}
parentDirGuid = solutionFolder.Id;
}
parentDirGuid = solutionFolder.Id;
}
nestedProjectsSection.Properties[slnProject.Id] = parentDirGuid;
}
}
private IDictionary<string, string> GetSolutionFolderPaths(SlnFile slnFile, SlnPropertySet nestedProjects)
{
var solutionFolderPaths = new Dictionary<string, string>();
var solutionFolderProjects = slnFile.Projects.GetProjectsByType(ProjectTypeGuids.SolutionFolderGuid);
foreach (var slnProject in solutionFolderProjects)
{
var path = slnProject.FilePath;
var id = slnProject.Id;
while (nestedProjects.ContainsKey(id))
{
id = nestedProjects[id];
var parentSlnProject = solutionFolderProjects.Where(p => p.Id == id).Single();
path = Path.Combine(parentSlnProject.FilePath, path);
}
solutionFolderPaths[path] = slnProject.Id;
}
return solutionFolderPaths;
}
}
}

View file

@ -126,10 +126,8 @@ namespace Microsoft.DotNet.Tools.Sln.Remove
private void RemoveEmptySolutionFolders(SlnFile slnFile)
{
var referencedSolutionFolders = slnFile.Projects.GetReferencedSolutionFolders();
var solutionFolderProjects = slnFile.Projects
.Where(p => p.TypeGuid == ProjectTypeGuids.SolutionFolderGuid)
.GetProjectsByType(ProjectTypeGuids.SolutionFolderGuid)
.ToList();
if (solutionFolderProjects.Any())
@ -138,9 +136,13 @@ namespace Microsoft.DotNet.Tools.Sln.Remove
"NestedProjects",
SlnSectionType.PreProcess);
var solutionFoldersInUse = GetSolutionFoldersThatContainProjectsInItsHierarchy(
slnFile,
nestedProjectsSection.Properties);
foreach (var solutionFolderProject in solutionFolderProjects)
{
if (!referencedSolutionFolders.Contains(solutionFolderProject.Name))
if (!solutionFoldersInUse.Contains(solutionFolderProject.Id))
{
slnFile.Projects.Remove(solutionFolderProject);
nestedProjectsSection.Properties.Remove(solutionFolderProject.Id);
@ -153,5 +155,27 @@ namespace Microsoft.DotNet.Tools.Sln.Remove
}
}
}
private HashSet<string> GetSolutionFoldersThatContainProjectsInItsHierarchy(
SlnFile slnFile,
SlnPropertySet nestedProjects)
{
var solutionFoldersInUse = new HashSet<string>();
var nonSolutionFolderProjects = slnFile.Projects.GetProjectsNotOfType(
ProjectTypeGuids.SolutionFolderGuid);
foreach (var nonSolutionFolderProject in nonSolutionFolderProjects)
{
var id = nonSolutionFolderProject.Id;
while (nestedProjects.ContainsKey(id))
{
id = nestedProjects[id];
solutionFoldersInUse.Add(id);
}
}
return solutionFoldersInUse;
}
}
}

View file

@ -55,5 +55,7 @@
public const string RunSettingsArgsHelpText = @"Any extra commandline runsettings arguments that should be passed to vstest. See 'dotnet vstest --help' for available options.
Example: -- RunConfiguration.ResultsDirectory=""C:\users\user\desktop\Results Directory"" MSTest.DeploymentEnabled=false";
public const string CmdResultsDirectoryDescription = @"Test results directory will be created in specified path if not exists.
Example: --results-directory <PATH_TO_RESULTS_DIRECTORY>";
}
}

View file

@ -83,6 +83,11 @@ namespace Microsoft.DotNet.Tools.Test
LocalizableStrings.CmdNoBuildDescription,
CommandOptionType.NoValue);
var resultsDirectoryOption = cmd.Option(
"-r|--results-directory",
LocalizableStrings.CmdResultsDirectoryDescription,
CommandOptionType.SingleValue);
CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(cmd);
cmd.OnExecute(() =>
@ -129,6 +134,11 @@ namespace Microsoft.DotNet.Tools.Test
msbuildArgs.Add($"/p:TargetFramework={frameworkOption.Value()}");
}
if (resultsDirectoryOption.HasValue())
{
msbuildArgs.Add($"/p:VSTestResultsDirectory={resultsDirectoryOption.Value()}");
}
if (outputOption.HasValue())
{
msbuildArgs.Add($"/p:OutputPath={outputOption.Value()}");

View file

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
@ -35,8 +35,4 @@
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
</PropertyGroup>
</Project>

View file

@ -1,48 +0,0 @@
using System.IO;
using Microsoft.DotNet.Tools.Test.Utilities;
using Xunit;
using Microsoft.DotNet.TestFramework;
namespace Microsoft.DotNet.Kestrel.Tests
{
public class DotnetBuildTest : TestBase
{
public static string KestrelPortableApp { get; } = "KestrelPortable";
[Fact]
public void BuildingKestrelPortableFatAppProducesExpectedArtifacts()
{
var testInstance = TestAssetsManager.CreateTestInstance("KestrelSample")
.WithLockFiles();
BuildAndTest(Path.Combine(testInstance.TestRoot, KestrelPortableApp));
}
private static void BuildAndTest(string testRoot)
{
string appName = Path.GetFileName(testRoot);
var result = new BuildCommand(
projectPath: testRoot)
.ExecuteWithCapturedOutput();
result.Should().Pass();
var outputBase = new DirectoryInfo(Path.Combine(testRoot, "bin", "Debug"));
var netcoreAppOutput = outputBase.Sub("netcoreapp1.0");
netcoreAppOutput.Should()
.Exist().And
.OnlyHaveFiles(new[]
{
$"{appName}.deps.json",
$"{appName}.dll",
$"{appName}.pdb",
$"{appName}.runtimeconfig.json",
$"{appName}.runtimeconfig.dev.json"
});
}
}
}

View file

@ -1,65 +0,0 @@
// 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.TestFramework;
using Microsoft.DotNet.Tools.Test.Utilities;
using Xunit;
using System.Net.Http;
using System.Threading.Tasks;
using FluentAssertions;
namespace Microsoft.DotNet.Kestrel.Tests
{
public class DotnetRunTest : TestBase
{
private const string KestrelSampleBase = "KestrelSample";
private const string KestrelPortable = "KestrelPortable";
private const string KestrelStandalone = "KestrelStandalone";
[Fact]
public void ItRunsKestrelPortableApp()
{
TestInstance instance = TestAssetsManager.CreateTestInstance(KestrelSampleBase)
.WithLockFiles();
var url = NetworkHelper.GetLocalhostUrlWithFreePort();
var args = $"{url} {Guid.NewGuid().ToString()}";
var runCommand = new RunCommand(Path.Combine(instance.TestRoot, KestrelPortable));
try
{
runCommand.ExecuteAsync(args);
NetworkHelper.IsServerUp(url).Should().BeTrue($"Unable to connect to kestrel server - {KestrelPortable} @ {url}");
NetworkHelper.TestGetRequest(url, args);
}
finally
{
runCommand.KillTree();
}
}
[Fact]
public void ItRunsKestrelStandaloneApp()
{
TestInstance instance = TestAssetsManager.CreateTestInstance(KestrelSampleBase)
.WithLockFiles();
var url = NetworkHelper.GetLocalhostUrlWithFreePort();
var args = $"{url} {Guid.NewGuid().ToString()}";
var runCommand = new RunCommand(Path.Combine(instance.TestRoot, KestrelStandalone));
try
{
runCommand.ExecuteAsync(args);
NetworkHelper.IsServerUp(url).Should().BeTrue($"Unable to connect to kestrel server - {KestrelStandalone} @ {url}");
NetworkHelper.TestGetRequest(url, args);
}
finally
{
runCommand.KillTree();
}
}
}
}

View file

@ -1,141 +0,0 @@
// 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.TestFramework;
using Microsoft.DotNet.Tools.Test.Utilities;
using Xunit;
using System.Threading.Tasks;
using FluentAssertions;
namespace Microsoft.DotNet.Kestrel.Tests
{
public class DotnetTest : TestBase
{
private const string KestrelSampleBase = "KestrelSample";
private const string KestrelPortable = "KestrelPortable";
private const string KestrelStandalone = "KestrelStandalone";
[Fact]
public void ItRunsKestrelPortableAfterBuild()
{
TestInstance instance = TestAssetsManager.CreateTestInstance(KestrelSampleBase)
.WithLockFiles();
var url = NetworkHelper.GetLocalhostUrlWithFreePort();
var args = $"{url} {Guid.NewGuid().ToString()}";
var dotnetCommand = new DotnetCommand();
var output = Build(Path.Combine(instance.TestRoot, KestrelPortable));
try
{
dotnetCommand.ExecuteAsync($"{output} {args}");
NetworkHelper.IsServerUp(url).Should().BeTrue($"Unable to connect to kestrel server - {KestrelPortable} @ {url}");
NetworkHelper.TestGetRequest(url, args);
}
finally
{
dotnetCommand.KillTree();
}
}
[Fact]
public void ItRunsKestrelStandaloneAfterBuild()
{
TestInstance instance = TestAssetsManager.CreateTestInstance(KestrelSampleBase)
.WithLockFiles();
var url = NetworkHelper.GetLocalhostUrlWithFreePort();
var args = $"{url} {Guid.NewGuid().ToString()}";
var dotnetCommand = new DotnetCommand();
var output = Build(Path.Combine(instance.TestRoot, KestrelStandalone));
try
{
dotnetCommand.ExecuteAsync($"{output} {args}");
NetworkHelper.IsServerUp(url).Should().BeTrue($"Unable to connect to kestrel server - {KestrelStandalone} @ {url}");
NetworkHelper.TestGetRequest(url, args);
}
finally
{
dotnetCommand.KillTree();
}
}
[Fact]
public void ItRunsKestrelPortableAfterPublish()
{
TestInstance instance = TestAssetsManager.CreateTestInstance(KestrelSampleBase)
.WithLockFiles();
var url = NetworkHelper.GetLocalhostUrlWithFreePort();
var args = $"{url} {Guid.NewGuid().ToString()}";
var dotnetCommand = new DotnetCommand();
var output = Publish(Path.Combine(instance.TestRoot, KestrelPortable), true);
try
{
dotnetCommand.ExecuteAsync($"{output} {args}");
NetworkHelper.IsServerUp(url).Should().BeTrue($"Unable to connect to kestrel server - {KestrelPortable} @ {url}");
NetworkHelper.TestGetRequest(url, args);
}
finally
{
dotnetCommand.KillTree();
}
}
[Fact]
public void ItRunsKestrelStandaloneAfterPublish()
{
TestInstance instance = TestAssetsManager.CreateTestInstance(KestrelSampleBase)
.WithLockFiles();
var url = NetworkHelper.GetLocalhostUrlWithFreePort();
var args = $"{url} {Guid.NewGuid().ToString()}";
var output = Publish(Path.Combine(instance.TestRoot, KestrelStandalone), false);
var command = new TestCommand(output);
try
{
command.ExecuteAsync($"{args}");
NetworkHelper.IsServerUp(url).Should().BeTrue($"Unable to connect to kestrel server - {KestrelStandalone} @ {url}");
NetworkHelper.TestGetRequest(url, args);
}
finally
{
command.KillTree();
}
}
private static string Build(string testRoot)
{
string appName = Path.GetFileName(testRoot);
var result = new BuildCommand(
projectPath: testRoot)
.ExecuteWithCapturedOutput();
result.Should().Pass();
// the correct build assembly is next to its deps.json file
var depsJsonFile = Directory.EnumerateFiles(testRoot, appName + FileNameSuffixes.DepsJson, SearchOption.AllDirectories).First();
return Path.Combine(Path.GetDirectoryName(depsJsonFile), appName + ".dll");
}
private static string Publish(string testRoot, bool isPortable)
{
string appName = Path.GetFileName(testRoot);
var publishCmd = new PublishCommand(projectPath: testRoot, output: Path.Combine(testRoot, "bin"));
var result = publishCmd.ExecuteWithCapturedOutput();
result.Should().Pass();
var publishDir = publishCmd.GetOutputDirectory(portable: isPortable).FullName;
return Path.Combine(publishDir, appName + (isPortable ? ".dll" : FileNameSuffixes.CurrentPlatform.Exe));
}
}
}

View file

@ -1,49 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AssemblyName>Kestrel.Tests</AssemblyName>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);dotnet5.4;portable-net451+win8</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj">
<FromP2P>true</FromP2P>
</ProjectReference>
<ProjectReference Include="..\..\src\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj">
<FromP2P>true</FromP2P>
</ProjectReference>
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
<Reference Include="System.Runtime">
<FromP2P>true</FromP2P>
</Reference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk">
<Version>15.0.0-preview-20161024-02</Version>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio">
<Version>2.2.0-beta4-build1194</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.App">
<Version>1.0.3</Version>
</PackageReference>
<PackageReference Include="System.Runtime.Serialization.Primitives">
<Version>4.1.1</Version>
</PackageReference>
<PackageReference Include="xunit">
<Version>2.2.0-beta4-build3444</Version>
</PackageReference>
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
</PropertyGroup>
</Project>

View file

@ -38,10 +38,6 @@ Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "crossgen.Tests", "crossgen.
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "binding-redirects.Tests", "binding-redirects.Tests\binding-redirects.Tests.csproj", "{18702FC5-7B1A-49B7-A335-A926064D577A}"
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "Microsoft.DotNet.Cli.Msi.Tests", "Installer\Microsoft.DotNet.Cli.Msi.Tests\Microsoft.DotNet.Cli.Msi.Tests.csproj", "{2867CE61-92A5-49EC-B9F5-424655257069}"
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "Kestrel.Tests", "Kestrel.Tests\Kestrel.Tests.csproj", "{642A0997-86E6-40E6-8E74-BFE2DC7C4A58}"
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "ArgumentForwardingTests", "ArgumentForwardingTests\ArgumentForwardingTests.csproj", "{67418187-0CF6-4213-87D0-5B9B841FD755}"
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "ArgumentsReflector", "ArgumentsReflector\ArgumentsReflector.csproj", "{8818FEBB-7243-4AB5-9E1C-179F5189FBD7}"
@ -62,8 +58,6 @@ Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "EndToEnd", "EndToEnd\EndToE
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "dotnet.Tests", "dotnet.Tests\dotnet.Tests.csproj", "{B4B5DA8E-E2EA-49CB-8B8C-4E157D42E710}"
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "Performance", "Performance\Performance.csproj", "{2CD55F27-3755-4E7D-8524-81B0BBCB93A4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dotnet-sln-add.Tests", "dotnet-sln-add.Tests", "{5FF48976-B083-4E3B-A8E7-6FCD225D5C8E}"
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "dotnet-sln-add.Tests", "dotnet-sln-add.Tests\dotnet-sln-add.Tests.csproj", "{FC849626-89C9-4F50-A2CA-53C4315A87F8}"
@ -76,6 +70,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dotnet-sln-remove.Tests", "
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "dotnet-sln-remove.Tests", "dotnet-sln-remove.Tests\dotnet-sln-remove.Tests.csproj", "{92BA9F90-E25B-4A1C-9598-2295D3DFC12F}"
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "dotnet-add-package.Tests", "dotnet-add-package.Tests\dotnet-add-package.Tests.csproj", "{3501AB72-3E05-45EE-9000-9515F5A139AC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -158,14 +154,6 @@ Global
{18702FC5-7B1A-49B7-A335-A926064D577A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18702FC5-7B1A-49B7-A335-A926064D577A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18702FC5-7B1A-49B7-A335-A926064D577A}.Release|Any CPU.Build.0 = Release|Any CPU
{2867CE61-92A5-49EC-B9F5-424655257069}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2867CE61-92A5-49EC-B9F5-424655257069}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2867CE61-92A5-49EC-B9F5-424655257069}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2867CE61-92A5-49EC-B9F5-424655257069}.Release|Any CPU.Build.0 = Release|Any CPU
{642A0997-86E6-40E6-8E74-BFE2DC7C4A58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{642A0997-86E6-40E6-8E74-BFE2DC7C4A58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{642A0997-86E6-40E6-8E74-BFE2DC7C4A58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{642A0997-86E6-40E6-8E74-BFE2DC7C4A58}.Release|Any CPU.Build.0 = Release|Any CPU
{67418187-0CF6-4213-87D0-5B9B841FD755}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67418187-0CF6-4213-87D0-5B9B841FD755}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67418187-0CF6-4213-87D0-5B9B841FD755}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -206,10 +194,6 @@ Global
{B4B5DA8E-E2EA-49CB-8B8C-4E157D42E710}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B4B5DA8E-E2EA-49CB-8B8C-4E157D42E710}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B4B5DA8E-E2EA-49CB-8B8C-4E157D42E710}.Release|Any CPU.Build.0 = Release|Any CPU
{2CD55F27-3755-4E7D-8524-81B0BBCB93A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2CD55F27-3755-4E7D-8524-81B0BBCB93A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2CD55F27-3755-4E7D-8524-81B0BBCB93A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2CD55F27-3755-4E7D-8524-81B0BBCB93A4}.Release|Any CPU.Build.0 = Release|Any CPU
{FC849626-89C9-4F50-A2CA-53C4315A87F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC849626-89C9-4F50-A2CA-53C4315A87F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC849626-89C9-4F50-A2CA-53C4315A87F8}.Debug|x64.ActiveCfg = Debug|x64
@ -246,6 +230,18 @@ Global
{92BA9F90-E25B-4A1C-9598-2295D3DFC12F}.Release|x64.Build.0 = Release|x64
{92BA9F90-E25B-4A1C-9598-2295D3DFC12F}.Release|x86.ActiveCfg = Release|x86
{92BA9F90-E25B-4A1C-9598-2295D3DFC12F}.Release|x86.Build.0 = Release|x86
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Debug|x64.ActiveCfg = Debug|x64
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Debug|x64.Build.0 = Debug|x64
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Debug|x86.ActiveCfg = Debug|x86
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Debug|x86.Build.0 = Debug|x86
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Release|Any CPU.Build.0 = Release|Any CPU
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Release|x64.ActiveCfg = Release|x64
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Release|x64.Build.0 = Release|x64
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Release|x86.ActiveCfg = Release|x86
{3501AB72-3E05-45EE-9000-9515F5A139AC}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -5,6 +5,7 @@ using FluentAssertions;
using Microsoft.DotNet.Internal.ProjectModel.Utilities;
using Microsoft.DotNet.ProjectJsonMigration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Xunit;
@ -14,81 +15,123 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
public partial class MigrationBackupPlanTests
{
[Fact]
public void TheRootBackupDirectoryIsASiblingOfTheRootProject()
public void TheBackupDirectoryIsASubfolderOfTheMigratedProject()
{
var dir = new DirectoryInfo(Path.Combine("src", "some-proj"));
var workspaceDirectory = Path.Combine("src", "root");
var projectDirectory = Path.Combine("src", "project1");
System.Console.WriteLine(dir.FullName);
WhenMigrating(
projectDirectory: dir.FullName,
workspaceDirectory: Path.Combine("src", "RootProject"))
.RootBackupDirectory
.FullName
.Should()
.Be(new DirectoryInfo(Path.Combine("src", "backup")).FullName.EnsureTrailingSlash());
WhenMigrating(projectDirectory, workspaceDirectory)
.RootBackupDirectory
.FullName
.Should()
.Be(new DirectoryInfo(Path.Combine("src", "project1", "backup")).FullName.EnsureTrailingSlash());
}
[Fact]
public void TheRootProjectsBackupDirectoryIsASubfolderOfTheRootBackupDirectory()
public void TheBackupDirectoryIsASubfolderOfTheMigratedProjectWhenInitiatedFromProjectFolder()
{
WhenMigrating(
projectDirectory: Path.Combine("src", "RootProject"),
workspaceDirectory: Path.Combine("src", "RootProject"))
.ProjectBackupDirectory
.FullName
.Should()
.Be(new DirectoryInfo(Path.Combine("src", "backup", "RootProject")).FullName.EnsureTrailingSlash());
var workspaceDirectory = Path.Combine("src", "root");
var projectDirectory = Path.Combine("src", "root");
WhenMigrating(projectDirectory, workspaceDirectory)
.ProjectBackupDirectories.Single()
.FullName
.Should()
.Be(new DirectoryInfo(Path.Combine("src", "root", "backup")).FullName.EnsureTrailingSlash());
}
[Fact]
public void ADependentProjectsMigrationBackupDirectoryIsASubfolderOfTheRootBackupDirectory()
public void TheBackupDirectoryIsInTheCommonRootOfTwoProjectFoldersWhenInitiatedFromProjectFolder()
{
WhenMigrating(
projectDirectory: Path.Combine("src", "Dependency"),
workspaceDirectory: Path.Combine("src", "RootProject"))
.ProjectBackupDirectory
.FullName
.Should()
.Be(new DirectoryInfo(Path.Combine("src", "backup", "Dependency")).FullName.EnsureTrailingSlash());
var projectDirectories = new []
{
Path.Combine("root", "project1"),
Path.Combine("root", "project2")
};
var workspaceDirectory = Path.Combine("root", "project1");
WhenMigrating(projectDirectories, workspaceDirectory)
.RootBackupDirectory
.FullName
.Should()
.Be(new DirectoryInfo(Path.Combine("root", "backup")).FullName.EnsureTrailingSlash());
}
[Fact]
public void FilesToBackUpAreIdentifiedInTheTheRootProjectDirectory()
public void TheBackupDirectoryIsInTheCommonRootOfTwoProjectFoldersWhenInitiatedFromCommonRoot()
{
var root = new DirectoryInfo(Path.Combine("src", "RootProject"));
var projectDirectories = new []
{
Path.Combine("root", "project1"),
Path.Combine("root", "project2")
};
WhenMigrating(
projectDirectory: root.FullName,
workspaceDirectory: root.FullName)
.FilesToMove
.Should()
.Contain(_ => _.FullName == Path.Combine(root.FullName, "project.json"));
var workspaceDirectory = Path.Combine("root");
WhenMigrating(projectDirectories, workspaceDirectory)
.RootBackupDirectory
.FullName
.Should()
.Be(new DirectoryInfo(Path.Combine("root", "backup")).FullName.EnsureTrailingSlash());
}
[Fact]
public void FilesToBackUpAreIdentifiedInTheTheDependencyProjectDirectory()
public void TheBackupDirectoryIsInTheCommonRootOfTwoProjectFoldersAtDifferentLevelsWhenInitiatedFromProjectFolder()
{
var root = new DirectoryInfo(Path.Combine("src", "RootProject"));
var dependency = new DirectoryInfo(Path.Combine("src", "RootProject"));
var projectDirectories = new []
{
Path.Combine("root", "tests", "inner", "project1"),
Path.Combine("root", "src", "project2")
};
WhenMigrating(
projectDirectory: dependency.FullName,
workspaceDirectory: root.FullName)
.FilesToMove
.Should()
.Contain(_ => _.FullName == Path.Combine(dependency.FullName, "project.json"));
var workspaceDirectory = Path.Combine("root", "tests", "inner");
WhenMigrating(projectDirectories, workspaceDirectory)
.RootBackupDirectory
.FullName
.Should()
.Be(new DirectoryInfo(Path.Combine("root", "backup")).FullName.EnsureTrailingSlash());
}
private MigrationBackupPlan WhenMigrating(
string projectDirectory,
string workspaceDirectory) =>
[Fact]
public void FilesToBackUpAreIdentifiedInTheRootProjectDirectory()
{
var workspaceDirectory = Path.Combine("src", "root");
var projectDirectory = Path.Combine("src", "root");
var whenMigrating = WhenMigrating(projectDirectory, workspaceDirectory);
whenMigrating
.FilesToMove(whenMigrating.ProjectBackupDirectories.Single())
.Should()
.Contain(_ => _.FullName == Path.Combine(new DirectoryInfo(workspaceDirectory).FullName, "project.json"));
}
[Fact]
public void FilesToBackUpAreIdentifiedInTheDependencyProjectDirectory()
{
var workspaceDirectory = Path.Combine("src", "root");
var projectDirectory = Path.Combine("src", "root");
var whenMigrating = WhenMigrating(projectDirectory, workspaceDirectory);
whenMigrating
.FilesToMove(whenMigrating.ProjectBackupDirectories.Single())
.Should()
.Contain(_ => _.FullName == Path.Combine(new DirectoryInfo(projectDirectory).FullName, "project.json"));
}
private MigrationBackupPlan WhenMigrating(string projectDirectory, string workspaceDirectory) =>
new MigrationBackupPlan(
new DirectoryInfo(projectDirectory),
new [] { new DirectoryInfo(projectDirectory) },
new DirectoryInfo(workspaceDirectory),
dir => new[] { new FileInfo(Path.Combine(dir.FullName, "project.json")) });
dir => new [] { new FileInfo(Path.Combine(dir.FullName, "project.json")) });
private MigrationBackupPlan WhenMigrating(string[] projectDirectories, string workspaceDirectory) =>
new MigrationBackupPlan(
projectDirectories.Select(p => new DirectoryInfo(p)),
new DirectoryInfo(workspaceDirectory),
dir => new [] { new FileInfo(Path.Combine(dir.FullName, "project.json")) });
}
}

View file

@ -3,7 +3,7 @@
<PropertyGroup>
<Description>Microsoft.DotNet.Tools.Tests.Utilities Class Library</Description>
<TargetFrameworks>netcoreapp1.0;net46</TargetFrameworks>
<TargetFrameworks>netcoreapp1.0</TargetFrameworks>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AssemblyName>Microsoft.DotNet.Tools.Tests.Utilities</AssemblyName>
<AssemblyOriginatorKeyFile>../../tools/Key.snk</AssemblyOriginatorKeyFile>

View file

@ -1,4 +0,0 @@
/*.html
/*.csv
/*.xml
/*.xml.bak

View file

@ -1,353 +0,0 @@
// 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.Linq;
using Microsoft.DotNet.Tools.Test.Utilities;
using Microsoft.Xunit.Performance;
using Microsoft.DotNet.TestFramework;
using System.IO;
using System.Runtime.CompilerServices;
using System;
using System.Collections.Generic;
namespace Microsoft.DotNet.Tools.Builder.Tests
{
public class BuildPerformanceTest : TestBase
{
private static string SingleTargetApp = "SingleTargetApp";
private static string TwoTargetApp = "TwoTargetApp";
private static string[] SingleTargetGraph = new[]
{
"SingleTargetGraph/SingleTargetP0",
"SingleTargetGraph/SingleTargetP1",
"SingleTargetGraph/SingleTargetP2"
};
private static string[] TwoTargetGraph = new[]
{
"TwoTargetGraph/TwoTargetP0",
"TwoTargetGraph/TwoTargetP1",
"TwoTargetGraph/TwoTargetP2"
};
private static string[] TwoTargetGraphLarge = new[]
{
"TwoTargetGraphLarge/TwoTargetLargeP0",
"TwoTargetGraphLarge/TwoTargetLargeP1",
"TwoTargetGraphLarge/TwoTargetLargeP2",
"TwoTargetGraphLarge/TwoTargetLargeP3",
"TwoTargetGraphLarge/TwoTargetLargeP4",
"TwoTargetGraphLarge/TwoTargetLargeP5",
"TwoTargetGraphLarge/TwoTargetLargeP6"
};
[Benchmark]
public void BuildSingleProject_SingleTargetApp() => BuildSingleProject(CreateTestInstance(SingleTargetApp));
[Benchmark]
public void BuildSingleProject_TwoTargetApp() => BuildSingleProject(CreateTestInstance(TwoTargetApp));
public void BuildSingleProject(TestAssetInstance instance)
{
foreach (var iteration in Benchmark.Iterations)
{
var buildCommand = new BuildCommand()
.WithProjectDirectory(instance.Root);
using (iteration.StartMeasurement())
{
buildCommand.Execute()
.Should().Pass();
}
TouchSource(instance.Root);
}
}
[Benchmark]
public void IncrementalSkipSingleProject_SingleTargetApp() => IncrementalSkipSingleProject(CreateTestInstance(SingleTargetApp));
[Benchmark]
public void IncrementalSkipSingleProject_TwoTargetApp() => IncrementalSkipSingleProject(CreateTestInstance(TwoTargetApp));
public void IncrementalSkipSingleProject(TestAssetInstance instance)
{
new BuildCommand()
.WithProjectDirectory(instance.Root)
.Execute()
.Should().Pass();
foreach (var iteration in Benchmark.Iterations)
{
var buildCommand = new BuildCommand()
.WithProjectDirectory(instance.Root);
using (iteration.StartMeasurement())
{
buildCommand
.Execute()
.Should().Pass();
}
}
}
[Benchmark]
public void BuildAllInGraph_SingleTargetGraph() => BuildAllInGraph(CreateTestInstances(SingleTargetGraph));
[Benchmark]
public void BuildAllInGraph_TwoTargetGraph() => BuildAllInGraph(CreateTestInstances(TwoTargetGraph));
[Benchmark]
public void BuildAllInGraph_TwoTargetGraphLarge() => BuildAllInGraph(CreateTestInstances(TwoTargetGraphLarge));
public void BuildAllInGraph(TestAssetInstance[] instances)
{
var instance = instances[0];
foreach (var iteration in Benchmark.Iterations)
{
var buildCommand = new BuildCommand()
.WithProjectDirectory(instance.Root);
using (iteration.StartMeasurement())
{
buildCommand
.Execute()
.Should().Pass();
}
foreach (var i in instances)
{
TouchSource(i.Root);
}
}
}
[Benchmark]
public void IncrementalSkipAllInGraph_SingleTargetGraph() =>
IncrementalSkipAllInGraph(CreateTestInstances(SingleTargetGraph));
[Benchmark]
public void IncrementalSkipAllInGraph_TwoTargetGraph() =>
IncrementalSkipAllInGraph(CreateTestInstances(TwoTargetGraph));
[Benchmark]
public void IncrementalSkipAllInGraphh_TwoTargetGraphLarge() =>
IncrementalSkipAllInGraph(CreateTestInstances(TwoTargetGraphLarge));
public void IncrementalSkipAllInGraph(TestAssetInstance[] instances)
{
var instance = instances[0];
new BuildCommand()
.WithProjectDirectory(instance.Root)
.Execute()
.Should().Pass();
foreach (var iteration in Benchmark.Iterations)
{
var buildCommand = new BuildCommand()
.WithProjectDirectory(instance.Root);
using (iteration.StartMeasurement())
{
buildCommand
.Execute()
.Should().Pass();
}
}
}
[Benchmark]
public void IncrementalRebuildWithRootChangedInGraph_SingleTargetGraph() =>
IncrementalRebuildWithRootChangedInGraph(CreateTestInstances(SingleTargetGraph));
[Benchmark]
public void IncrementalRebuildWithRootChangedInGraph_TwoTargetGraph() =>
IncrementalRebuildWithRootChangedInGraph(CreateTestInstances(TwoTargetGraph));
[Benchmark]
public void IncrementalRebuildWithRootChangedInGraph_TwoTargetGraphLarge() =>
IncrementalRebuildWithRootChangedInGraph(CreateTestInstances(TwoTargetGraphLarge));
public void IncrementalRebuildWithRootChangedInGraph(TestAssetInstance[] instances)
{
var instance = instances[0];
new BuildCommand()
.WithProjectDirectory(instance.Root)
.Execute()
.Should().Pass();
foreach (var iteration in Benchmark.Iterations)
{
var buildCommand = new BuildCommand()
.WithProjectDirectory(instance.Root);
using (iteration.StartMeasurement())
{
buildCommand
.Execute()
.Should().Pass();
}
TouchSource(instance.Root);
}
}
[Benchmark]
public void IncrementalRebuildWithLastChangedInGraph_SingleTargetGraph() =>
IncrementalRebuildWithLastChangedInGraph(CreateTestInstances(SingleTargetGraph));
[Benchmark]
public void IncrementalRebuildWithLastChangedInGraph_TwoTargetGraph() =>
IncrementalRebuildWithLastChangedInGraph(CreateTestInstances(TwoTargetGraph));
[Benchmark]
public void IncrementalRebuildWithLastChangedInGraph_TwoTargetGraphLarge() =>
IncrementalRebuildWithLastChangedInGraph(CreateTestInstances(TwoTargetGraphLarge));
public void IncrementalRebuildWithLastChangedInGraph(TestAssetInstance[] instances)
{
var instance = instances[0];
new BuildCommand()
.WithProjectDirectory(instance.Root)
.Execute()
.Should().Pass();
foreach (var iteration in Benchmark.Iterations)
{
var buildCommand = new BuildCommand()
.WithProjectDirectory(instance.Root);
using (iteration.StartMeasurement())
{
buildCommand
.Execute()
.Should().Pass();
}
TouchSource(instances.Last().Root);
}
}
[Benchmark]
public void IncrementalSkipAllNoDependenciesInGraph_SingleTargetGraph() =>
IncrementalSkipAllNoDependenciesInGraph(CreateTestInstances(SingleTargetGraph));
[Benchmark]
public void IncrementalSkipAllNoDependenciesInGraph_TwoTargetGraph() =>
IncrementalSkipAllNoDependenciesInGraph(CreateTestInstances(TwoTargetGraph));
[Benchmark]
public void IncrementalSkipAllNoDependenciesInGraph_TwoTargetGraphLarge() =>
IncrementalSkipAllNoDependenciesInGraph(CreateTestInstances(TwoTargetGraphLarge));
public void IncrementalSkipAllNoDependenciesInGraph(TestAssetInstance[] instances)
{
var instance = instances[0];
new BuildCommand()
.WithProjectDirectory(instance.Root)
.Execute()
.Should().Pass();
foreach (var iteration in Benchmark.Iterations)
{
var commands = new List<BuildCommand>();
foreach (var i in instances.Reverse())
{
var buildCommand = new BuildCommand()
.WithProjectDirectory(instance.Root)
.WithFramework(NuGet.Frameworks.FrameworkConstants.CommonFrameworks.NetCoreApp10)
.WithNoDependencies();
commands.Add(buildCommand);
}
using (iteration.StartMeasurement())
{
foreach (var buildCommand in commands)
{
buildCommand
.Execute()
.Should().Pass();
}
}
}
}
[Benchmark]
public void BuildAllNoDependenciesInGraph_SingleTargetGraph() =>
BuildAllNoDependenciesInGraph(CreateTestInstances(SingleTargetGraph));
[Benchmark]
public void BuildAllNoDependenciesInGraph_TwoTargetGraph() =>
BuildAllNoDependenciesInGraph(CreateTestInstances(TwoTargetGraph));
[Benchmark]
public void BuildAllNoDependenciesInGraph_TwoTargetGraphLarge() =>
BuildAllNoDependenciesInGraph(CreateTestInstances(TwoTargetGraphLarge));
public void BuildAllNoDependenciesInGraph(TestAssetInstance[] instances)
{
foreach (var iteration in Benchmark.Iterations)
{
var commands = new List<BuildCommand>();
foreach (var i in instances.Reverse())
{
var buildCommand = new BuildCommand()
.WithProjectDirectory(i.Root)
.WithFramework(NuGet.Frameworks.FrameworkConstants.CommonFrameworks.NetCoreApp10)
.WithNoDependencies();
commands.Add(buildCommand);
}
using (iteration.StartMeasurement())
{
foreach (var buildCommand in commands)
{
buildCommand.Execute().Should().Pass();
}
}
foreach (var instance in instances)
{
TouchSource(instance.Root);
}
}
}
protected void TouchSource(DirectoryInfo projectDir)
{
var sourceFile = projectDir.GetFiles("*.cs", SearchOption.AllDirectories).FirstOrDefault();
if (sourceFile == null)
{
throw new InvalidOperationException($"'.cs' files not found in {projectDir.FullName}");
}
sourceFile.LastWriteTime = DateTime.Now;
}
protected TestAssetInstance[] CreateTestInstances(string[] testProjectNames, [CallerMemberName] string callingMethod = "")
{
return testProjectNames.Select(testProjectName =>
{
return CreateTestInstance(testProjectName, callingMethod);
}).ToArray();
}
protected TestAssetInstance CreateTestInstance(string testProjectName, [CallerMemberName] string callingMethod = "")
{
return TestAssets.Get(Path.Combine("PerformanceTestProjects", testProjectName))
.CreateInstance(callingMethod)
.WithSourceFiles()
.WithRestoreFiles();
}
}
}

View file

@ -1,89 +0,0 @@
// 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 Microsoft.Xunit.Performance;
namespace Microsoft.DotNet.Tests.Performance
{
public class HelloWorld : TestBase
{
private static readonly string s_testdirName = "helloworldtestroot";
private static readonly string s_testProject = $"{s_testdirName}.csproj";
private static readonly string s_outputdirName = "test space/bin";
private static string AssetsRoot { get; set; }
private static string RestoredTestProjectDirectory { get; set; }
private string ProjectPath { get; set; }
private string TestDirectory { get; set; }
private string OutputDirectory { get; set; }
static HelloWorld()
{
HelloWorld.SetupStaticTestProject();
}
public HelloWorld()
{
}
[Benchmark]
public void MeasureDotNetBuild()
{
foreach (var iter in Benchmark.Iterations)
{
// Setup a new instance of the test project.
TestInstanceSetup();
// Setup the build command.
var buildCommand = new BuildCommand();
using (iter.StartMeasurement())
{
// Execute the build command.
buildCommand.Execute($"{ProjectPath} --output \"{OutputDirectory}\" --framework {DefaultFramework}");
}
}
}
private void TestInstanceSetup()
{
var root = Temp.CreateDirectory();
var testInstanceDir = root.CopyDirectory(RestoredTestProjectDirectory);
TestDirectory = testInstanceDir.Path;
OutputDirectory = Path.Combine(TestDirectory, s_outputdirName);
ProjectPath = Path.Combine(TestDirectory, s_testProject);
}
private static void SetupStaticTestProject()
{
AssetsRoot = Path.Combine(AppContext.BaseDirectory, "bin");
RestoredTestProjectDirectory = Path.Combine(AssetsRoot, s_testdirName);
// Ignore Delete Failure
try
{
Directory.Delete(RestoredTestProjectDirectory, true);
}
catch (Exception) { }
Directory.CreateDirectory(RestoredTestProjectDirectory);
// Todo: this is a hack until corefx is on nuget.org remove this After RC 2 Release
NuGetConfig.Write(RestoredTestProjectDirectory);
var newCommand = new NewCommand();
newCommand.WorkingDirectory = RestoredTestProjectDirectory;
newCommand.Execute().Should().Pass();
var restoreCommand = new RestoreCommand();
restoreCommand.WorkingDirectory = RestoredTestProjectDirectory;
restoreCommand.Execute("/p:SkipInvalidConfigurations=true")
.Should().Pass();
}
}
}

View file

@ -1,55 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AssemblyName>Performance</AssemblyName>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);dotnet5.4;portable-net451+win8</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj">
<FromP2P>true</FromP2P>
</ProjectReference>
<ProjectReference Include="..\..\src\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj">
<FromP2P>true</FromP2P>
</ProjectReference>
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
<Reference Include="System.Runtime">
<FromP2P>true</FromP2P>
</Reference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk">
<Version>15.0.0-preview-20161024-02</Version>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio">
<Version>2.2.0-beta4-build1194</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.App">
<Version>1.0.3</Version>
</PackageReference>
<PackageReference Include="System.Runtime.Serialization.Primitives">
<Version>4.1.1</Version>
</PackageReference>
<PackageReference Include="xunit">
<Version>2.2.0-beta4-build3444</Version>
</PackageReference>
<PackageReference Include="xunit.netcore.extensions">
<Version>1.0.0-prerelease-00206</Version>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.xunit.performance">
<Version>1.0.0-alpha-build0028</Version>
</PackageReference>
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
</PropertyGroup>
</Project>

View file

@ -1,54 +0,0 @@
Running Performance Tests
=========================
Pre-Requisites
--------------
* Python 2.7+ or 3.5+
* msbuild.exe (must be on `PATH`)
Single Perf Run
---------------
1. Build the CLI repo to get dotnet.exe, or otherwise source the CLI. For
meaningful perf results, be sure to use release mode.
2. `cd <cli_repo_root>/test/Performance`
3. `python run-perftests.py <dotnet_bin> --name <unique_run_name>
--xunit-perf-path <x_repo_path>`
where:
* `<dotnet_bin>` is the path to the dotnet binary whose perf you want to
measure.
* `<x_repo_path>` should point either to an non-existent directory, or to
the root of a local clone of xunit-performance. If a non-existent
directory is specified, the repo will automatically be cloned.
- NOTE: You can also set the environment variable
`XUNIT_PERFORMANCE_PATH` to avoid having to pass this variable every
time.
4. View the `*.csv` / `*.xml` results in the current directory.
Comparison Run
--------------
In general, follow the same steps as for a single perf run. The following
additional steps are required:
1. In addition to the dotnet.exe that you're testing, be sure to also build or
otherwise source the baseline dotnet.exe. This could be the "stage0" exe, or
the exe from the last nightly build, or the exe built from sources prior to
changes you made, etc.
2. When invoking `run-perftests.py`, add an additional parameter: `--base
<base_bin>`, which points to the baseline dotnet.exe mentioned in step 1.
3. View the `*.html` file generated for the perf comparison analysis.
Debugging Issues
----------------
The output of commands invoked by `run-perftests` is hidden by default. You can
see the output after an error by looking in the `logs/run-perftests` directory.
Alternatively, you can rerun `run-perftests` with `--verbose`, which will print
all output to the console instead of piping it to log files.

View file

@ -1,249 +0,0 @@
#!/usr/bin/env python
import argparse
import glob
import os
import re
import subprocess
import sys
SCRIPT_ROOT_PATH = os.path.dirname(os.path.realpath(__file__))
PERFTEST_JSON_PATH = os.path.join(SCRIPT_ROOT_PATH, 'project.json')
XUNITPERF_REPO_URL = 'https://github.com/microsoft/xunit-performance.git'
script_args = None
class FatalError(Exception):
def __init__(self, message):
self.message = message
def check_requirements():
try:
run_command('git', '--version', quiet = True)
except:
raise FatalError("git not found, please make sure that it's installed and on path.")
try:
run_command('msbuild', '-version', quiet = True)
except:
raise FatalError("msbuild not found, please make sure that it's installed and on path.")
if script_args.xunit_perf_path == None:
raise FatalError("Don't know where to clone xunit-performance. Please specify --xunit-perf-path <path>. " +
"You can also set/export XUNIT_PERFORMANCE_PATH to not have to set the value every time.")
def process_arguments():
parser = argparse.ArgumentParser(
description = "Runs CLI perf tests. Requires 'git' and 'msbuild' to be on the PATH.",
)
parser.add_argument(
'test_cli',
help = "full path to the dotnet.exe under test",
)
parser.add_argument(
'--runid', '--name', '-n',
help = "unique ID for this run",
required = True,
)
parser.add_argument(
'--base', '--baseline', '-b',
help = "full path to the baseline dotnet.exe",
metavar = 'baseline_cli',
dest = 'base_cli',
)
parser.add_argument(
'--xunit-perf-path', '-x',
help = """Path to local copy of the xunit-performance repository.
Required unless the environment variable XUNIT_PERFORMANCE_PATH is defined.""",
default = os.environ.get('XUNIT_PERFORMANCE_PATH'),
metavar = 'path',
)
parser.add_argument(
'--rebuild', '--rebuild-tools', '-r',
help = "Rebuilds the test tools from scratch.",
action = 'store_true',
)
parser.add_argument(
'--verbose', '-v',
help = "Shows the output of all commands run by this script",
action = 'store_true',
)
global script_args
script_args = parser.parse_args()
def run_command(*vargs, **kwargs):
title = kwargs['title'] if 'title' in kwargs else None
from_dir = kwargs['from_dir'] if 'from_dir' in kwargs else None
quiet = kwargs['quiet'] if 'quiet' in kwargs else False
quoted_args = map(lambda x: '"{x}"'.format(x=x) if ' ' in x else x, vargs)
cmd_line = ' '.join(quoted_args)
should_log = not script_args.verbose and title != None
redirect_args = { 'stderr': subprocess.STDOUT }
nullfile = None
logfile = None
cwd = None
try:
if should_log:
log_name = '-'.join(re.sub(r'\W', ' ', title).lower().split()) + '.log'
log_path = os.path.join(SCRIPT_ROOT_PATH, 'logs', 'run-perftests', log_name)
log_dir = os.path.dirname(log_path)
if not os.path.exists(log_dir):
os.makedirs(log_dir)
cmd_line += ' > "{log}"'.format(log = log_path)
logfile = open(log_path, 'w')
redirect_args['stdout'] = logfile
elif quiet or not script_args.verbose:
nullfile = open(os.devnull, 'w')
redirect_args['stdout'] = nullfile
prefix = ''
if not quiet and title != None:
print('# {msg}...'.format(msg = title))
prefix = ' $ '
if from_dir != None:
cwd = os.getcwd()
if not quiet: print('{pref}cd "{dir}"'.format(pref = prefix, dir = from_dir))
os.chdir(from_dir)
if not quiet: print(prefix + cmd_line)
returncode = subprocess.call(vargs, **redirect_args)
if returncode != 0:
logmsg = " See '{log}' for details.".format(log = log_path) if should_log else ''
raise FatalError("Command `{cmd}` returned with error code {e}.{log}".format(cmd = cmd_line, e = returncode, log = logmsg))
finally:
if logfile != None: logfile.close()
if nullfile != None: nullfile.close()
if cwd != None: os.chdir(cwd)
def clone_repo(repo_url, local_path):
if os.path.exists(local_path):
# For now, we just assume that if the path exists, it's already the correct repo
print("# xunit-performance repo was detected at '{path}', skipping git clone".format(path = local_path))
return
run_command(
'git', 'clone', repo_url, local_path,
title = "Clone the xunit-performance repo",
)
def get_xunitperf_dotnet_path(xunitperf_src_path):
return os.path.join(xunitperf_src_path, 'tools', 'bin', 'dotnet')
def get_xunitperf_runner_src_path(xunitperf_src_path):
return os.path.join(xunitperf_src_path, 'src', 'cli', 'Microsoft.DotNet.xunit.performance.runner.cli')
def get_xunitperf_analyzer_path(xunitperf_src_path):
return os.path.join(xunitperf_src_path, 'src', 'xunit.performance.analysis', 'bin', 'Release', 'xunit.performance.analysis')
def make_xunit_perf(xunitperf_src_path):
dotnet_path = get_xunitperf_dotnet_path(xunitperf_src_path)
dotnet_base_path = os.path.dirname(dotnet_path)
analyzer_base_path = os.path.dirname(get_xunitperf_analyzer_path(xunitperf_src_path))
runner_src_path = get_xunitperf_runner_src_path(xunitperf_src_path)
if script_args.rebuild or not os.path.exists(dotnet_base_path) or not os.path.exists(analyzer_base_path):
run_command(
'CiBuild.cmd', '/release',
title = "Build xunit-performance",
from_dir = xunitperf_src_path,
)
run_command(
dotnet_path, 'publish', '-c', 'Release', runner_src_path,
title = "Build Microsoft.DotNet.xunit.performance.runner.cli",
)
else:
print("# xunit-performance at '{path}' was already built, skipping CiBuild. Use --rebuild to force rebuild.".format(path = xunitperf_src_path))
def run_perf_test(runid, cli_path, xunitperf_src_path):
cli_path = os.path.realpath(cli_path)
dotnet_path = get_xunitperf_dotnet_path(xunitperf_src_path)
runner_src_path = get_xunitperf_runner_src_path(xunitperf_src_path)
result_xml_path = os.path.join(SCRIPT_ROOT_PATH, '{}.xml'.format(runid))
project_lock_path = os.path.join(SCRIPT_ROOT_PATH, 'project.lock.json')
saved_path = os.environ.get('PATH')
print("# Prepending {dir} to PATH".format(dir = os.path.dirname(cli_path)))
os.environ['PATH'] = os.path.dirname(cli_path) + ';' + os.environ.get('PATH')
try:
if os.path.exists(project_lock_path):
print("# Deleting {file}".format(file = project_lock_path))
os.remove(project_lock_path)
run_command(
cli_path, 'restore', '-f', 'https://dotnet.myget.org/f/dotnet-core',
title = "Dotnet restore using \"{cli}\"".format(cli = cli_path),
from_dir = SCRIPT_ROOT_PATH,
)
run_command(
dotnet_path, 'run', '-p', runner_src_path, '-c', 'Release', '--',
'-runner', cli_path, '-runid', runid,
'-runnerargs', 'test {json} -c Release'.format(json = PERFTEST_JSON_PATH),
title = "Run {id}".format(id = runid),
from_dir = SCRIPT_ROOT_PATH,
)
if not os.path.exists(result_xml_path):
raise FatalError("Running {id} seems to have failed: {xml} was not generated".format(
id = runid, xml = result_xml_path
))
finally:
print("# Reverting PATH")
os.environ['PATH'] = saved_path
def compare_results(base_id, test_id, out_html, xunitperf_src_path):
analyzer_path = get_xunitperf_analyzer_path(xunitperf_src_path)
# Make sure there aren't any stale XMLs in the target dir
for xml in glob.glob(os.path.join(SCRIPT_ROOT_PATH, '*.xml')):
if not os.path.basename(xml) in [base_id + '.xml', test_id + '.xml']:
os.rename(xml, xml + '.bak')
try:
run_command(
analyzer_path, SCRIPT_ROOT_PATH, '-compare', base_id, test_id, '-html', out_html,
title = "Generate comparison report",
from_dir = SCRIPT_ROOT_PATH,
)
if os.path.exists(out_html):
print("# Comparison finished, please see \"{report}\" for details.".format(report = out_html))
else:
raise FatalError("Failed to genererate comparison report: \"{report}\" not found.".format(report = out_html))
finally:
# Revert the renamed XMLs
for xml in glob.glob(os.path.join(SCRIPT_ROOT_PATH, '*.xml.bak')):
os.rename(xml, xml[0:-4])
def main():
try:
process_arguments()
check_requirements()
script_args.xunit_perf_path = os.path.realpath(script_args.xunit_perf_path)
clone_repo(XUNITPERF_REPO_URL, script_args.xunit_perf_path)
make_xunit_perf(script_args.xunit_perf_path)
base_runid = script_args.runid + '.base'
test_runid = script_args.runid + '.test'
out_html = os.path.join(SCRIPT_ROOT_PATH, script_args.runid + '.html')
run_perf_test(test_runid, script_args.test_cli, script_args.xunit_perf_path)
if script_args.base_cli != None:
run_perf_test(base_runid, script_args.base_cli, script_args.xunit_perf_path)
compare_results(base_runid, test_runid, out_html, script_args.xunit_perf_path)
return 0
except FatalError as error:
print("! ERROR: {msg}".format(msg = error.message))
return 1
if __name__ == "__main__":
sys.exit(main())

View file

@ -1,57 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<TargetFramework>net46</TargetFramework>
<TargetFramework>netcoreapp1.0</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AssemblyName>binding-redirects.Tests</AssemblyName>
<RuntimeIdentifiers>win7-x64;win7-x86</RuntimeIdentifiers>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);dotnet5.4;portable-net451+win8</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj">
<FromP2P>true</FromP2P>
</ProjectReference>
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj">
<FromP2P>true</FromP2P>
</ProjectReference>
<ProjectReference Include="..\..\src\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj">
<FromP2P>true</FromP2P>
</ProjectReference>
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
<Reference Include="System.Runtime">
<FromP2P>true</FromP2P>
</Reference>
<PackageReference Include="System.Console">
<Version>4.0.0</Version>
</PackageReference>
<Reference Include="System.Configuration" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk">
<Version>15.0.0-preview-20161024-02</Version>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio">
<Version>2.2.0-beta4-build1194</Version>
</PackageReference>
<PackageReference Include="xunit">
<Version>2.2.0-beta4-build3444</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.Platforms">
<Version>1.0.1</Version>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions">
<Version>1.0.1-beta-000933</Version>
</PackageReference>
<PackageReference Include="Microsoft.NetCore.App" Version="1.0.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(CLI_TestPlatform_Version)" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-beta4-build1194" />
<PackageReference Include="xunit" Version="2.2.0-beta4-build3444" />
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="1.0.1-beta-000933" />
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,119 @@
// 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 FluentAssertions;
using Microsoft.Build.Construction;
using Microsoft.DotNet.Cli.Sln.Internal;
using Microsoft.DotNet.Tools.Test.Utilities;
using System;
using System.IO;
using System.Linq;
using Xunit;
namespace Microsoft.DotNet.Cli.Package.Add.Tests
{
public class GivenDotnetPackageAdd : TestBase
{
[Fact]
public void WhenValidPackageIsPassedBeforeVersionItGetsAdded()
{
var testAsset = "TestAppSimple";
var projectDirectory = TestAssets
.Get(testAsset)
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var packageName = "Newtonsoft.Json";
var packageVersion = "9.0.1";
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"add package {packageName} --version {packageVersion}");
cmd.Should().Pass();
cmd.StdOut.Should().Contain($"PackageReference for package '{packageName}' version '{packageVersion}' " +
$"added to file '{projectDirectory + Path.DirectorySeparatorChar + testAsset}.csproj'.");
cmd.StdErr.Should().BeEmpty();
}
[Fact]
public void WhenValidPackageIsPassedAfterVersionItGetsAdded()
{
var testAsset = "TestAppSimple";
var projectDirectory = TestAssets
.Get(testAsset)
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var packageName = "Newtonsoft.Json";
var packageVersion = "9.0.1";
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"add package --version {packageVersion} {packageName}");
cmd.Should().Pass();
cmd.StdOut.Should().Contain($"PackageReference for package '{packageName}' version '{packageVersion}' " +
$"added to file '{projectDirectory + Path.DirectorySeparatorChar + testAsset}.csproj'.");
cmd.StdErr.Should().BeEmpty();
}
[Fact]
public void WhenValidPackageIsPassedWithFrameworkItGetsAdded()
{
var testAsset = "TestAppSimple";
var projectDirectory = TestAssets
.Get(testAsset)
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var packageName = "Newtonsoft.Json";
var packageVersion = "9.0.1";
var framework = "netcoreapp1.0";
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"add package {packageName} --version {packageVersion} --framework {framework}");
cmd.Should().Pass();
cmd.StdOut.Should().Contain($"PackageReference for package '{packageName}' version '{packageVersion}' " +
$"added to file '{projectDirectory + Path.DirectorySeparatorChar + testAsset}.csproj'.");
cmd.StdErr.Should().BeEmpty();
}
[Fact]
public void WhenMultiplePackagesArePassedCommandFails()
{
var projectDirectory = TestAssets
.Get("TestAppSimple")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"add package package1 package2 package3");
cmd.Should().Fail();
cmd.StdErr.Should().Contain("Please specify one package reference to add.");
}
[Fact]
public void WhenNoPackageisPassedCommandFails()
{
var projectDirectory = TestAssets
.Get("TestAppSimple")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"add package");
cmd.Should().Fail();
cmd.StdErr.Should().Contain("Please specify one package reference to add.");
}
}
}

View file

@ -0,0 +1 @@
https://github.com/Microsoft/msbuild/issues/927

View file

@ -0,0 +1 @@
https://github.com/Microsoft/msbuild/issues/927

View file

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AssemblyName>dotnet-add-package.Tests</AssemblyName>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);dotnet5.4;portable-net451+win8</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Sln.Internal\Microsoft.DotNet.Cli.Sln.Internal.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NetCore.App" Version="1.0.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(CLI_TestPlatform_Version)" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-beta4-build1194" />
<PackageReference Include="xunit" Version="2.2.0-beta4-build3444" />
<PackageReference Include="Microsoft.Build" Version="$(CLI_MSBuild_Version)" />
</ItemGroup>
</Project>

View file

@ -15,13 +15,13 @@ namespace Microsoft.DotNet.Migration.Tests
[InlineData("TestAppWithLibrary")]
public void WhenProjectMigrationSucceedsThenProjectJsonArtifactsGetMovedToBackup(string testProjectName)
{
var testRoot = TestAssetsManager
.CreateTestInstance(testProjectName)
.Path;
var testRoot = TestAssets
.GetProjectJson(testProjectName)
.CreateInstance()
.WithSourceFiles()
.Root;
var testRootParent = new DirectoryInfo(testRoot).Parent.FullName;
var backupRoot = Path.Combine(testRootParent, "backup");
var backupRoot = testRoot.GetDirectory("backup");
var migratableArtifacts = GetProjectJsonArtifacts(testRoot);
@ -34,22 +34,22 @@ namespace Microsoft.DotNet.Migration.Tests
backupArtifacts.Should().Equal(migratableArtifacts, "Because all of and only these artifacts should have been moved");
new DirectoryInfo(testRoot).Should().NotHaveFiles(backupArtifacts.Keys);
testRoot.Should().NotHaveFiles(backupArtifacts.Keys);
new DirectoryInfo(backupRoot).Should().HaveTextFiles(backupArtifacts);
backupRoot.Should().HaveTextFiles(backupArtifacts);
}
[Theory]
[InlineData("PJTestAppSimple")]
public void WhenFolderMigrationSucceedsThenProjectJsonArtifactsGetMovedToBackup(string testProjectName)
{
var testRoot = TestAssetsManager
.CreateTestInstance(testProjectName)
.Path;
var testRoot = TestAssets
.GetProjectJson(testProjectName)
.CreateInstance()
.WithSourceFiles()
.Root;
var testRootParent = new DirectoryInfo(testRoot).Parent.FullName;
var backupRoot = Path.Combine(testRootParent, "backup", testProjectName);
var backupRoot = testRoot.GetDirectory("backup");
var migratableArtifacts = GetProjectJsonArtifacts(testRoot);
@ -62,20 +62,22 @@ namespace Microsoft.DotNet.Migration.Tests
backupArtifacts.Should().Equal(migratableArtifacts, "Because all of and only these artifacts should have been moved");
new DirectoryInfo(testRoot).Should().NotHaveFiles(backupArtifacts.Keys);
testRoot.Should().NotHaveFiles(backupArtifacts.Keys);
new DirectoryInfo(backupRoot).Should().HaveTextFiles(backupArtifacts);
backupRoot.Should().HaveTextFiles(backupArtifacts);
}
[Theory]
[InlineData("TestAppWithLibraryAndMissingP2P")]
public void WhenMigrationFailsThenProjectJsonArtifactsDoNotGetMovedToBackup(string testProjectName)
{
var testRoot = new TestAssetsManager(Path.Combine(RepoRoot, "TestAssets", "NonRestoredTestProjects"))
.CreateTestInstance(testProjectName, identifier: testProjectName)
.Path;
var testRoot = TestAssets
.GetProjectJson(TestAssetKinds.NonRestoredTestProjects, testProjectName)
.CreateInstance(identifier: testProjectName)
.WithSourceFiles()
.Root;
var backupRoot = Path.Combine(testRoot, "backup");
var backupRoot = testRoot.GetDirectory("backup");
var migratableArtifacts = GetProjectJsonArtifacts(testRoot);
@ -84,19 +86,23 @@ namespace Microsoft.DotNet.Migration.Tests
.Execute()
.Should().Fail();
new DirectoryInfo(backupRoot).Should().NotExist("Because migration failed and therefore no backup is needed.");
backupRoot.Should().NotExist("Because migration failed and therefore no backup is needed.");
new DirectoryInfo(testRoot).Should().HaveTextFiles(migratableArtifacts, "Because migration failed so nothing was moved to backup.");
testRoot.Should().HaveTextFiles(migratableArtifacts, "Because migration failed so nothing was moved to backup.");
}
[Theory]
[InlineData("PJTestAppSimple")]
public void WhenSkipbackupSpecifiedThenProjectJsonArtifactsDoNotGetMovedToBackup(string testProjectName)
{
var testRoot = TestAssetsManager.CreateTestInstance(testProjectName, identifier: testProjectName).Path;
var backupRoot = Path.Combine(testRoot, "backup");
var testRoot = TestAssets
.GetProjectJson(testProjectName)
.CreateInstance(identifier: testProjectName)
.WithSourceFiles()
.Root;
var backupRoot = testRoot.GetDirectory("backup");
var migratableArtifacts = GetProjectJsonArtifacts(testRoot);
new MigrateCommand()
@ -104,12 +110,12 @@ namespace Microsoft.DotNet.Migration.Tests
.Execute("--skip-backup")
.Should().Pass();
new DirectoryInfo(backupRoot).Should().NotExist("Because --skip-backup was specified.");
backupRoot.Should().NotExist("Because --skip-backup was specified.");
new DirectoryInfo(testRoot).Should().HaveTextFiles(migratableArtifacts, "Because --skip-backup was specified.");
testRoot.Should().HaveTextFiles(migratableArtifacts, "Because --skip-backup was specified.");
}
private Dictionary<string, string> GetProjectJsonArtifacts(string rootPath)
private Dictionary<string, string> GetProjectJsonArtifacts(DirectoryInfo root)
{
var catalog = new Dictionary<string, string>();
@ -117,23 +123,19 @@ namespace Microsoft.DotNet.Migration.Tests
foreach (var pattern in patterns)
{
AddArtifactsToCatalog(catalog, rootPath, pattern);
AddArtifactsToCatalog(catalog, root, pattern);
}
return catalog;
}
private void AddArtifactsToCatalog(Dictionary<string, string> catalog, string basePath, string pattern)
private void AddArtifactsToCatalog(Dictionary<string, string> catalog, DirectoryInfo root, string pattern)
{
basePath = PathUtility.EnsureTrailingSlash(basePath);
var baseDirectory = new DirectoryInfo(basePath);
var files = baseDirectory.GetFiles(pattern, SearchOption.AllDirectories);
var files = root.GetFiles(pattern, SearchOption.AllDirectories);
foreach (var file in files)
{
var key = PathUtility.GetRelativePath(basePath, file.FullName);
var key = PathUtility.GetRelativePath(root, file);
catalog.Add(key, File.ReadAllText(file.FullName));
}
}

View file

@ -14,13 +14,17 @@ namespace Microsoft.DotNet.Migration.Tests
[Fact]
public void ItMigratesWhenBeingPassedAFullPathToGlobalJson()
{
var solutionDirectory =
TestAssetsManager.CreateTestInstance("AppWithPackageNamedAfterFolder").Path;
var globalJsonPath = Path.Combine(solutionDirectory, "global.json");
var solutionDirectory = TestAssets
.GetProjectJson("AppWithPackageNamedAfterFolder")
.CreateInstance()
.WithSourceFiles()
.Root;
var globalJsonPath = solutionDirectory.GetFile("global.json");
new TestCommand("dotnet")
.WithForwardingToConsole()
.Execute($"migrate {globalJsonPath}")
.Execute($"migrate {globalJsonPath.FullName}")
.Should()
.Pass();
}
@ -28,17 +32,21 @@ namespace Microsoft.DotNet.Migration.Tests
[Fact]
public void WhenUsingGlobalJsonItOnlyMigratesProjectsInTheGlobalJsonNode()
{
var solutionDirectory =
TestAssetsManager.CreateTestInstance("AppWithPackageNamedAfterFolder").Path;
var globalJsonPath = Path.Combine(solutionDirectory, "global.json");
var solutionDirectory = TestAssets
.GetProjectJson("AppWithPackageNamedAfterFolder")
.CreateInstance()
.WithSourceFiles()
.Root;
var globalJsonPath = solutionDirectory.GetFile("global.json");
new TestCommand("dotnet")
.WithForwardingToConsole()
.Execute($"migrate {globalJsonPath}")
.Execute($"migrate {globalJsonPath.FullName}")
.Should()
.Pass();
new DirectoryInfo(solutionDirectory)
solutionDirectory
.Should().HaveFiles(new []
{
Path.Combine("src", "App", "App.csproj"),
@ -46,15 +54,20 @@ namespace Microsoft.DotNet.Migration.Tests
Path.Combine("TestAssets", "TestAsset", "project.json")
});
new DirectoryInfo(solutionDirectory)
solutionDirectory
.Should().NotHaveFile(Path.Combine("TestAssets", "TestAsset", "TestAsset.csproj"));
}
[Fact]
public void ItMigratesWhenBeingPassedJustGlobalJson()
{
var solutionDirectory =
TestAssetsManager.CreateTestInstance("AppWithPackageNamedAfterFolder").Path;
var solutionDirectory = TestAssets
.GetProjectJson("AppWithPackageNamedAfterFolder")
.CreateInstance()
.WithSourceFiles()
.Root;
var globalJsonPath = solutionDirectory.GetFile("global.json");
new TestCommand("dotnet")
.WithWorkingDirectory(solutionDirectory)

View file

@ -102,8 +102,8 @@ EndGlobal
string minVisualStudioVersion)
{
var projectDirectory = TestAssets
.Get("NonRestoredTestProjects", projectName)
.CreateInstance()
.GetProjectJson(TestAssetKinds.NonRestoredTestProjects, projectName)
.CreateInstance(identifier: projectName)
.WithSourceFiles()
.Root;
@ -132,7 +132,7 @@ EndGlobal
public void ItOnlyMigratesProjectsInTheSlnFile()
{
var projectDirectory = TestAssets
.Get("NonRestoredTestProjects", "PJAppWithSlnAndXprojRefs")
.GetProjectJson(TestAssetKinds.NonRestoredTestProjects, "PJAppWithSlnAndXprojRefs")
.CreateInstance()
.WithSourceFiles()
.Root;
@ -144,7 +144,7 @@ EndGlobal
.Execute($"migrate \"{solutionRelPath}\"")
.Should().Pass();
new DirectoryInfo(projectDirectory.FullName)
projectDirectory
.Should().HaveFiles(new []
{
Path.Combine("TestApp", "TestApp.csproj"),
@ -153,7 +153,7 @@ EndGlobal
Path.Combine("TestApp", "TestAssets", "TestAsset", "project.json")
});
new DirectoryInfo(projectDirectory.FullName)
projectDirectory
.Should().NotHaveFile(Path.Combine("TestApp", "TestAssets", "TestAsset", "TestAsset.csproj"));
}
@ -173,6 +173,59 @@ EndGlobal
"PJAppWithSlnAndXprojRefThatRefsCsprojWhereSlnDoesNotRefCsproj");
}
[Fact]
public void WhenSolutionContainsACsprojFileItGetsMovedToBackup()
{
var projectDirectory = TestAssets
.GetProjectJson("NonRestoredTestProjects", "PJAppWithSlnAndOneAlreadyMigratedCsproj")
.CreateInstance()
.WithSourceFiles()
.Root;
var solutionRelPath = Path.Combine("TestApp", "TestApp.sln");
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"migrate \"{solutionRelPath}\"");
cmd.Should().Pass();
projectDirectory
.GetDirectory("TestLibrary")
.GetFile("TestLibrary.csproj")
.Should().Exist();
projectDirectory
.GetDirectory("TestLibrary")
.GetFile("TestLibrary.csproj.migration_in_place_backup")
.Should().NotExist();
projectDirectory
.GetDirectory("backup", "TestLibrary")
.GetFile("TestLibrary.csproj")
.Should().Exist();
}
[Fact]
public void WhenSolutionContainsACsprojFileItDoesNotTryToAddItAgain()
{
var projectDirectory = TestAssets
.GetProjectJson(TestAssetKinds.NonRestoredTestProjects, "PJAppWithSlnAndOneAlreadyMigratedCsproj")
.CreateInstance()
.WithSourceFiles()
.Root;
var solutionRelPath = Path.Combine("TestApp", "TestApp.sln");
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"migrate \"{solutionRelPath}\"");
cmd.Should().Pass();
cmd.StdOut.Should().NotContain("already contains project");
cmd.StdErr.Should().BeEmpty();
}
[Theory]
[InlineData("NoSolutionItemsAfterMigration.sln", ExpectedSlnFileAfterRemovingAllSolutionItems)]
[InlineData("ReadmeSolutionItemAfterMigration.sln", ExpectedSlnFileAfterRemovingAllSolutionItemsExceptReadme)]
@ -223,6 +276,7 @@ EndGlobal
// .Should().Pass();
SlnFile slnFile = SlnFile.Read(Path.Combine(projectDirectory.FullName, solutionRelPath));
var nonSolutionFolderProjects = slnFile.Projects
.Where(p => p.TypeGuid != ProjectTypeGuids.SolutionFolderGuid);

View file

@ -3,6 +3,7 @@
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;
@ -28,9 +29,12 @@ namespace Microsoft.DotNet.Migration.Tests
[InlineData("TestAppWithEmbeddedResources")]
public void ItMigratesApps(string projectName)
{
var projectDirectory = TestAssetsManager.CreateTestInstance(projectName, identifier: projectName)
.WithLockFiles()
.Path;
var projectDirectory = TestAssets
.GetProjectJson(projectName)
.CreateInstance(identifier: projectName)
.WithSourceFiles()
.WithRestoreFiles()
.Root;
CleanBinObj(projectDirectory);
@ -48,9 +52,10 @@ namespace Microsoft.DotNet.Migration.Tests
VerifyAllMSBuildOutputsRunnable(projectDirectory);
var outputCsProj = Path.Combine(projectDirectory, projectName + ".csproj");
var csproj = File.ReadAllText(outputCsProj);
csproj.EndsWith("\n").Should().Be(true);
var outputCsProj = projectDirectory.GetFile(projectName + ".csproj");
outputCsProj.ReadAllText()
.Should().EndWith("\n");
}
[WindowsOnlyTheory]
@ -58,13 +63,16 @@ namespace Microsoft.DotNet.Migration.Tests
[InlineData("TestAppWithMultipleFullFrameworksOnly", "net461")]
public void ItMigratesAppsWithFullFramework(string projectName, string framework)
{
var projectDirectory = TestAssetsManager.CreateTestInstance(
projectName,
identifier: projectName).WithLockFiles().Path;
var projectDirectory = TestAssets
.GetProjectJson(projectName)
.CreateInstance(identifier: projectName)
.WithSourceFiles()
.WithRestoreFiles()
.Root;
CleanBinObj(projectDirectory);
MigrateProject(new [] { projectDirectory });
MigrateProject(new [] { projectDirectory.FullName });
Restore(projectDirectory);
@ -74,7 +82,12 @@ namespace Microsoft.DotNet.Migration.Tests
[Fact]
public void ItMigratesSignedApps()
{
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppWithSigning").WithLockFiles().Path;
var projectDirectory = TestAssets
.GetProjectJson("TestAppWithSigning")
.CreateInstance()
.WithSourceFiles()
.WithRestoreFiles()
.Root;
CleanBinObj(projectDirectory);
@ -98,10 +111,11 @@ namespace Microsoft.DotNet.Migration.Tests
[Fact]
public void ItMigratesDotnetNewConsoleWithIdenticalOutputs()
{
var testInstance = TestAssetsManager
.CreateTestInstance("ProjectJsonConsoleTemplate");
var projectDirectory = testInstance.Path;
var projectDirectory = TestAssets
.GetProjectJson("ProjectJsonConsoleTemplate")
.CreateInstance()
.WithSourceFiles()
.Root;
var outputComparisonData = GetComparisonData(projectDirectory);
@ -121,14 +135,14 @@ namespace Microsoft.DotNet.Migration.Tests
[Fact]
public void ItMigratesOldDotnetNewWebWithoutToolsWithOutputsContainingProjectJsonOutputs()
{
var testInstance = TestAssetsManager
.CreateTestInstance("ProjectJsonWebTemplate")
.WithLockFiles();
var projectDirectory = TestAssets
.GetProjectJson("ProjectJsonWebTemplate")
.CreateInstance()
.WithSourceFiles()
.WithRestoreFiles()
.Root;
var projectDirectory = testInstance.Path;
var globalDirectory = Path.Combine(projectDirectory, "..");
var projectJsonFile = Path.Combine(projectDirectory, "project.json");
var globalDirectory = projectDirectory.Parent;
WriteGlobalJson(globalDirectory);
@ -148,16 +162,17 @@ namespace Microsoft.DotNet.Migration.Tests
[Fact]
public void ItMigratesAndPublishesWebApp()
{
const string projectName = "WebAppWithMissingFileInPublishOptions";
var testInstance = TestAssets.Get(projectName)
.CreateInstance()
.WithSourceFiles();
var projectName = "WebAppWithMissingFileInPublishOptions";
var projectDirectory = testInstance.Root.FullName;
var projectDirectory = TestAssets
.GetProjectJson(projectName)
.CreateInstance()
.WithSourceFiles()
.Root;
File.Copy("NuGet.tempaspnetpatch.config", Path.Combine(projectDirectory, "NuGet.Config"));
File.Copy("NuGet.tempaspnetpatch.config", projectDirectory.GetFile("NuGet.Config").FullName);
MigrateProject(new [] { projectDirectory });
MigrateProject(new [] { projectDirectory.FullName });
Restore(projectDirectory);
PublishMSBuild(projectDirectory, projectName);
@ -166,13 +181,20 @@ namespace Microsoft.DotNet.Migration.Tests
[Fact]
public void ItMigratesAPackageReferenceAsSuchEvenIfAFolderWithTheSameNameExistsInTheRepo()
{
var solutionDirectory =
TestAssetsManager.CreateTestInstance("AppWithPackageNamedAfterFolder").Path;
var appProject = Path.Combine(solutionDirectory, "src", "App", "App.csproj");
var solutionDirectory = TestAssets
.GetProjectJson("AppWithPackageNamedAfterFolder")
.CreateInstance()
.WithSourceFiles()
.Root;
MigrateProject(solutionDirectory);
var appProject = solutionDirectory
.GetDirectory("src", "App")
.GetFile("App.csproj");
MigrateProject(solutionDirectory.FullName);
var projectRootElement = ProjectRootElement.Open(appProject.FullName);
var projectRootElement = ProjectRootElement.Open(appProject);
projectRootElement.Items.Where(
i => i.Include == "EntityFramework" && i.ItemType == "PackageReference")
.Should().HaveCount(2);
@ -183,38 +205,47 @@ namespace Microsoft.DotNet.Migration.Tests
const string dependentProject = "ProjectA";
const string dependencyProject = "ProjectB";
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppDependencyGraph").Path;
var projectDirectory = TestAssets
.GetProjectJson("TestAppDependencyGraph")
.CreateInstance()
.WithSourceFiles()
.Root;
MigrateProject(Path.Combine(projectDirectory, dependencyProject));
MigrateProject(projectDirectory.GetDirectory(dependencyProject).FullName);
MigrateProject("--skip-project-references", Path.Combine(projectDirectory, dependentProject));
MigrateProject("--skip-project-references", projectDirectory.GetDirectory(dependentProject).FullName);
}
[Fact]
public void ItAddsMicrosoftNetWebSdkToTheSdkAttributeOfAWebApp()
{
var testInstance = TestAssetsManager
.CreateTestInstance("ProjectJsonWebTemplate")
.WithLockFiles();
var projectDirectory = TestAssets
.Get("ProjectJsonWebTemplate")
.CreateInstance()
.WithSourceFiles()
.WithRestoreFiles()
.Root;
var projectDirectory = testInstance.Path;
var globalDirectory = Path.Combine(projectDirectory, "..");
var projectJsonFile = Path.Combine(projectDirectory, "project.json");
var globalDirectory = projectDirectory.Parent;
var projectJsonFile = projectDirectory.GetFile("project.json");
MigrateProject(new [] { projectDirectory });
MigrateProject(new [] { projectDirectory.FullName });
var csProj = Path.Combine(projectDirectory, $"{new DirectoryInfo(projectDirectory).Name}.csproj");
var csProj = projectDirectory.GetFile($"{projectDirectory.Name}.csproj");
File.ReadAllText(csProj).Should().Contain(@"Sdk=""Microsoft.NET.Sdk.Web""");
csProj.ReadAllText().Should().Contain(@"Sdk=""Microsoft.NET.Sdk.Web""");
}
[Theory]
[InlineData("TestLibraryWithTwoFrameworks")]
public void ItMigratesProjectsWithMultipleTFMs(string projectName)
{
var projectDirectory =
TestAssetsManager.CreateTestInstance(projectName, identifier: projectName).WithLockFiles().Path;
var projectDirectory = TestAssets
.GetProjectJson(projectName)
.CreateInstance(identifier: projectName)
.WithSourceFiles()
.WithRestoreFiles()
.Root;
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory, projectName);
@ -233,8 +264,13 @@ namespace Microsoft.DotNet.Migration.Tests
public void ItMigratesLibraryWithMultipleTFMsAndFullFramework()
{
var projectName = "PJLibWithMultipleFrameworks";
var projectDirectory =
TestAssetsManager.CreateTestInstance(projectName, identifier: projectName).WithLockFiles().Path;
var projectDirectory = TestAssets
.GetProjectJson(projectName)
.CreateInstance(identifier: projectName)
.WithSourceFiles()
.WithRestoreFiles()
.Root;
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory, projectName);
@ -255,13 +291,20 @@ namespace Microsoft.DotNet.Migration.Tests
[InlineData("PJTestLibraryWithConfiguration")]
public void ItMigratesALibrary(string projectName)
{
var projectDirectory =
TestAssetsManager.CreateTestInstance(projectName, identifier: projectName).WithLockFiles().Path;
var projectDirectory = TestAssets
.GetProjectJson(projectName)
.CreateInstance(identifier: projectName)
.WithSourceFiles()
.WithRestoreFiles()
.Root;
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory, Path.GetFileNameWithoutExtension(projectName));
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(
projectDirectory,
Path.GetFileNameWithoutExtension(projectName));
var outputsIdentical =
outputComparisonData.ProjectJsonBuildOutputs.SetEquals(outputComparisonData.MSBuildBuildOutputs);
var outputsIdentical = outputComparisonData
.ProjectJsonBuildOutputs
.SetEquals(outputComparisonData.MSBuildBuildOutputs);
if (!outputsIdentical)
{
@ -279,12 +322,13 @@ namespace Microsoft.DotNet.Migration.Tests
[InlineData("ProjectE", "ProjectE")]
public void ItMigratesRootProjectAndReferences(string projectName, string expectedProjects)
{
var projectDirectory =
TestAssetsManager.CreateTestInstance(
"TestAppDependencyGraph",
identifier: $"{projectName}.RefsTest").Path;
var projectDirectory = TestAssets
.GetProjectJson("TestAppDependencyGraph")
.CreateInstance(identifier: $"{projectName}.RefsTest")
.WithSourceFiles()
.Root;
MigrateProject(new [] { Path.Combine(projectDirectory, projectName) });
MigrateProject(new [] { projectDirectory.GetDirectory(projectName).FullName });
string[] migratedProjects = expectedProjects.Split(new char[] { ',' });
@ -299,10 +343,13 @@ namespace Microsoft.DotNet.Migration.Tests
[InlineData("ProjectE")]
public void ItMigratesRootProjectAndSkipsReferences(string projectName)
{
var projectDirectory =
TestAssetsManager.CreateTestInstance("TestAppDependencyGraph", identifier: $"{projectName}.SkipRefsTest").Path;
MigrateProject(new [] { Path.Combine(projectDirectory, projectName), "--skip-project-references" });
var projectDirectory = TestAssets
.GetProjectJson("TestAppDependencyGraph")
.CreateInstance($"{projectName}.SkipRefsTest")
.WithSourceFiles()
.Root;
MigrateProject(new [] { projectDirectory.GetDirectory(projectName).FullName, "--skip-project-references" });
VerifyMigration(Enumerable.Repeat(projectName, 1), projectDirectory);
}
@ -312,15 +359,19 @@ namespace Microsoft.DotNet.Migration.Tests
[InlineData(false)]
public void ItMigratesAllProjectsInGivenDirectory(bool skipRefs)
{
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppDependencyGraph", callingMethod: $"MigrateDirectory.SkipRefs.{skipRefs}").Path;
var projectDirectory = TestAssets
.GetProjectJson("TestAppDependencyGraph")
.CreateInstance(callingMethod: $"MigrateDirectory.SkipRefs.{skipRefs}")
.WithSourceFiles()
.Root;
if (skipRefs)
{
MigrateProject(new [] { projectDirectory, "--skip-project-references" });
MigrateProject(new [] { projectDirectory.FullName, "--skip-project-references" });
}
else
{
MigrateProject(new [] { projectDirectory });
MigrateProject(new [] { projectDirectory.FullName });
}
string[] migratedProjects = new string[] { "ProjectA", "ProjectB", "ProjectC", "ProjectD", "ProjectE", "ProjectF", "ProjectG", "ProjectH", "ProjectI", "ProjectJ" };
@ -331,11 +382,17 @@ namespace Microsoft.DotNet.Migration.Tests
[Fact]
public void ItMigratesGivenProjectJson()
{
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppDependencyGraph").Path;
var projectDirectory = TestAssets
.GetProjectJson("TestAppDependencyGraph")
.CreateInstance()
.WithSourceFiles()
.Root;
var project = Path.Combine(projectDirectory, "ProjectA", "project.json");
var project = projectDirectory
.GetDirectory("ProjectA")
.GetFile("project.json");
MigrateProject(new [] { project });
MigrateProject(new [] { project.FullName });
string[] migratedProjects = new string[] { "ProjectA", "ProjectB", "ProjectC", "ProjectD", "ProjectE" };
@ -346,17 +403,22 @@ namespace Microsoft.DotNet.Migration.Tests
// regression test for https://github.com/dotnet/cli/issues/4269
public void ItMigratesAndBuildsP2PReferences()
{
var assetsDir = TestAssetsManager.CreateTestInstance("TestAppDependencyGraph").WithLockFiles().Path;
var assetsDir = TestAssets
.GetProjectJson("TestAppDependencyGraph")
.CreateInstance()
.WithSourceFiles()
.WithRestoreFiles()
.Root;
var projectDirectory = Path.Combine(assetsDir, "ProjectF");
var projectDirectory = assetsDir.GetDirectory("ProjectF");
var restoreDirectories = new string[]
var restoreDirectories = new DirectoryInfo[]
{
projectDirectory,
Path.Combine(assetsDir, "ProjectG")
assetsDir.GetDirectory("ProjectG")
};
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory, "ProjectF", new [] { projectDirectory }, restoreDirectories);
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory, "ProjectF", new [] { projectDirectory.FullName }, restoreDirectories);
var outputsIdentical = outputComparisonData.ProjectJsonBuildOutputs
.SetEquals(outputComparisonData.MSBuildBuildOutputs);
@ -372,27 +434,33 @@ namespace Microsoft.DotNet.Migration.Tests
}
[Theory]
[InlineData("src", "ProjectH")]
[InlineData("src with spaces", "ProjectJ")]
public void ItMigratesAndBuildsProjectsInGlobalJson(string path, string projectName)
[InlineData("src", "H")]
[InlineData("src with spaces", "J")]
public void ItMigratesAndBuildsProjectsInGlobalJson(string path, string projectNameSuffix)
{
var assetsDir = TestAssetsManager.CreateTestInstance(Path.Combine("TestAppDependencyGraph", "ProjectsWithGlobalJson"),
callingMethod: $"ProjectsWithGlobalJson.{projectName}")
.WithLockFiles().Path;
var globalJson = Path.Combine(assetsDir, "global.json");
var assetsDir = TestAssets
.GetProjectJson("ProjectsWithGlobalJson")
.CreateInstance(identifier: projectNameSuffix)
.WithSourceFiles()
.WithRestoreFiles()
.Root;
var restoreDirectories = new string[]
var projectName = $"Project{projectNameSuffix}";
var globalJson = assetsDir.GetFile("global.json");
var restoreDirectories = new DirectoryInfo[]
{
Path.Combine(assetsDir, "src", "ProjectH"),
Path.Combine(assetsDir, "src", "ProjectI"),
Path.Combine(assetsDir, "src with spaces", "ProjectJ")
assetsDir.GetDirectory("src", "ProjectH"),
assetsDir.GetDirectory("src", "ProjectI"),
assetsDir.GetDirectory("src with spaces", "ProjectJ")
};
var projectDirectory = Path.Combine(assetsDir, path, projectName);
var projectDirectory = assetsDir.GetDirectory(path, projectName);
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory,
projectName,
new [] { globalJson },
new [] { globalJson.FullName },
restoreDirectories);
var outputsIdentical = outputComparisonData.ProjectJsonBuildOutputs
@ -413,7 +481,7 @@ namespace Microsoft.DotNet.Migration.Tests
[InlineData(false)]
public void MigrationOutputsErrorWhenNoProjectsFound(bool useGlobalJson)
{
var projectDirectory = TestAssetsManager.CreateTestDirectory("Migration_outputs_error_when_no_projects_found");
var projectDirectory = TestAssets.CreateTestDirectory("Migration_outputs_error_when_no_projects_found");
string argstr = string.Empty;
@ -421,31 +489,28 @@ namespace Microsoft.DotNet.Migration.Tests
if (useGlobalJson)
{
var globalJsonPath = Path.Combine(projectDirectory.Path, "global.json");
var globalJson = projectDirectory.GetFile("global.json");
using (FileStream fs = File.Create(globalJsonPath))
using (StreamWriter sw = globalJson.CreateText())
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("{");
sw.WriteLine("\"projects\": [ \".\" ]");
sw.WriteLine("}");
}
sw.WriteLine("{");
sw.WriteLine("\"projects\": [ \".\" ]");
sw.WriteLine("}");
}
argstr = globalJsonPath;
argstr = globalJson.FullName;
errorMessage = "Unable to find any projects in global.json";
}
else
{
argstr = projectDirectory.Path;
argstr = projectDirectory.FullName;
errorMessage = $"No project.json file found in '{projectDirectory.Path}'";
errorMessage = $"No project.json file found in '{projectDirectory.FullName}'";
}
var result = new TestCommand("dotnet")
.WithWorkingDirectory(projectDirectory.Path)
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"migrate {argstr}");
// Expecting an error exit code.
@ -453,18 +518,21 @@ namespace Microsoft.DotNet.Migration.Tests
// 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);
result.StdErr.Should().Contain("Migration failed.");
result.StdErr
.Should().Contain(errorMessage)
.And.Contain("Migration failed.");
}
[Fact]
public void ItMigratesAndPublishesProjectsWithRuntimes()
{
var projectName = "PJTestAppSimple";
var projectDirectory = TestAssetsManager
.CreateTestInstance(projectName)
.WithLockFiles()
.Path;
var projectDirectory = TestAssets
.GetProjectJson(projectName)
.CreateInstance()
.WithSourceFiles()
.WithRestoreFiles()
.Root;
CleanBinObj(projectDirectory);
BuildProjectJsonMigrateBuildMSBuild(projectDirectory, projectName);
@ -477,11 +545,16 @@ namespace Microsoft.DotNet.Migration.Tests
public void ItAutoAddDesktopReferencesDuringMigrate(string testGroup, string projectName, bool isDesktopApp)
{
var runtime = DotnetLegacyRuntimeIdentifiers.InferLegacyRestoreRuntimeIdentifier();
var testAssetManager = GetTestGroupTestAssetsManager(testGroup);
var projectDirectory = testAssetManager.CreateTestInstance(projectName).WithLockFiles().Path;
var projectDirectory = TestAssets
.GetProjectJson(testGroup, projectName)
.CreateInstance()
.WithSourceFiles()
.WithRestoreFiles()
.Root;
CleanBinObj(projectDirectory);
MigrateProject(new string[] { projectDirectory });
MigrateProject(new string[] { projectDirectory.FullName });
Restore(projectDirectory, runtime: runtime);
BuildMSBuild(projectDirectory, projectName, runtime:runtime);
VerifyAutoInjectedDesktopReferences(projectDirectory, projectName, isDesktopApp);
@ -492,12 +565,19 @@ namespace Microsoft.DotNet.Migration.Tests
public void ItBuildsAMigratedAppWithAnIndirectDependency()
{
const string projectName = "ProjectA";
var solutionDirectory =
TestAssetsManager.CreateTestInstance("TestAppDependencyGraph").Path;
var projectDirectory = Path.Combine(solutionDirectory, projectName);
MigrateProject(new string[] { projectDirectory });
var solutionDirectory = TestAssets
.GetProjectJson("TestAppDependencyGraph")
.CreateInstance()
.WithSourceFiles()
.Root;
var projectDirectory = solutionDirectory.GetDirectory(projectName);
MigrateProject(new string[] { projectDirectory.FullName });
Restore(projectDirectory);
BuildMSBuild(projectDirectory, projectName);
VerifyAllMSBuildOutputsRunnable(projectDirectory);
@ -506,35 +586,42 @@ namespace Microsoft.DotNet.Migration.Tests
[Fact]
public void ItMigratesProjectWithOutputName()
{
string projectName = "AppWithOutputAssemblyName";
string expectedOutputName = "MyApp";
var projectName = "AppWithOutputAssemblyName";
var expectedOutputName = "MyApp";
var projectDirectory = TestAssetsManager.CreateTestInstance(projectName, callingMethod: $"It_migrates_{projectName}")
.WithLockFiles()
.Path;
string expectedCsprojPath = Path.Combine(projectDirectory, $"{projectName}.csproj");
if (File.Exists(expectedCsprojPath))
var projectDirectory = TestAssets
.GetProjectJson(projectName)
.CreateInstance()
.WithSourceFiles()
.WithRestoreFiles()
.Root;
var expectedCsprojPath = projectDirectory.GetFile($"{projectName}.csproj");
if (expectedCsprojPath.Exists)
{
File.Delete(expectedCsprojPath);
expectedCsprojPath.Delete();
}
CleanBinObj(projectDirectory);
MigrateProject(projectDirectory);
File.Exists(expectedCsprojPath).Should().BeTrue();
MigrateProject(projectDirectory.FullName);
expectedCsprojPath.Refresh();
expectedCsprojPath.Should().Exist();
Restore(projectDirectory, projectName);
BuildMSBuild(projectDirectory, projectName);
Directory.EnumerateFiles(
Path.Combine(projectDirectory, "bin"),
$"{expectedOutputName}.pdb",
SearchOption.AllDirectories)
projectDirectory
.GetDirectory("bin")
.EnumerateFiles($"{expectedOutputName}.pdb", SearchOption.AllDirectories)
.Count().Should().Be(1);
PackMSBuild(projectDirectory, projectName);
Directory.EnumerateFiles(
Path.Combine(projectDirectory, "bin"),
$"{projectName}.1.0.0.nupkg",
SearchOption.AllDirectories)
projectDirectory
.GetDirectory("bin")
.EnumerateFiles($"{projectName}.1.0.0.nupkg", SearchOption.AllDirectories)
.Count().Should().Be(1);
}
@ -543,24 +630,31 @@ namespace Microsoft.DotNet.Migration.Tests
[InlineData("LibraryWithNetStandardLibRef")]
public void ItMigratesAndBuildsLibrary(string projectName)
{
var projectDirectory = TestAssetsManager.CreateTestInstance(
projectName,
identifier: $"{projectName}").Path;
var projectDirectory = TestAssets
.GetProjectJson(projectName)
.CreateInstance(identifier: projectName)
.WithSourceFiles()
.Root;
MigrateProject(projectDirectory);
MigrateProject(projectDirectory.FullName);
Restore(projectDirectory, projectName);
BuildMSBuild(projectDirectory, projectName);
}
private void VerifyAutoInjectedDesktopReferences(string projectDirectory, string projectName, bool shouldBePresent)
private void VerifyAutoInjectedDesktopReferences(DirectoryInfo projectDirectory, string projectName, bool shouldBePresent)
{
if (projectName != null)
{
projectName = projectName + ".csproj";
}
var root = ProjectRootElement.Open(Path.Combine(projectDirectory, projectName));
var autoInjectedReferences = root.Items.Where(i => i.ItemType == "Reference" && (i.Include == "System" || i.Include == "Microsoft.CSharp"));
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);
@ -571,51 +665,56 @@ namespace Microsoft.DotNet.Migration.Tests
}
}
private void VerifyMigration(IEnumerable<string> expectedProjects, string rootDir)
private void VerifyMigration(IEnumerable<string> expectedProjects, DirectoryInfo rootDir)
{
var migratedProjects = Directory.EnumerateFiles(rootDir, "*.csproj", SearchOption.AllDirectories)
.Where(s => Directory.EnumerateFiles(Path.GetDirectoryName(s), "*.csproj").Count() == 1)
.Where(s => Path.GetFileName(Path.GetDirectoryName(s)).Contains("Project"))
.Select(s => Path.GetFileName(Path.GetDirectoryName(s)));
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(string projectDirectory)
private MigratedBuildComparisonData GetComparisonData(DirectoryInfo projectDirectory)
{
File.Copy("NuGet.tempaspnetpatch.config", Path.Combine(projectDirectory, "NuGet.Config"));
File.Copy("NuGet.tempaspnetpatch.config", projectDirectory.GetFile("NuGet.Config").FullName);
RestoreProjectJson(projectDirectory);
var outputComparisonData =
BuildProjectJsonMigrateBuildMSBuild(projectDirectory, Path.GetFileNameWithoutExtension(projectDirectory));
BuildProjectJsonMigrateBuildMSBuild(projectDirectory, Path.GetFileNameWithoutExtension(projectDirectory.FullName));
return outputComparisonData;
}
private void VerifyAllMSBuildOutputsRunnable(string projectDirectory)
private void VerifyAllMSBuildOutputsRunnable(DirectoryInfo projectDirectory)
{
var dllFileName = Path.GetFileName(projectDirectory) + ".dll";
var dllFileName = Path.GetFileName(projectDirectory.FullName) + ".dll";
var runnableDlls = Directory.EnumerateFiles(Path.Combine(projectDirectory, "bin"), dllFileName,
SearchOption.AllDirectories);
var runnableDlls = projectDirectory
.GetDirectory("bin")
.GetFiles(dllFileName, SearchOption.AllDirectories);
foreach (var dll in runnableDlls)
{
new TestCommand("dotnet").ExecuteWithCapturedOutput($"\"{dll}\"").Should().Pass();
new TestCommand("dotnet").ExecuteWithCapturedOutput($"\"{dll.FullName}\"").Should().Pass();
}
}
private void VerifyAllMSBuildOutputsAreSigned(string projectDirectory)
private void VerifyAllMSBuildOutputsAreSigned(DirectoryInfo projectDirectory)
{
var dllFileName = Path.GetFileName(projectDirectory) + ".dll";
var dllFileName = Path.GetFileName(projectDirectory.FullName) + ".dll";
var runnableDlls = Directory.EnumerateFiles(Path.Combine(projectDirectory, "bin"), dllFileName,
SearchOption.AllDirectories);
var runnableDlls = projectDirectory
.GetDirectory("bin")
.EnumerateFiles(dllFileName, SearchOption.AllDirectories);
foreach (var dll in runnableDlls)
{
var assemblyName = AssemblyLoadContext.GetAssemblyName(dll);
var assemblyName = AssemblyLoadContext.GetAssemblyName(dll.FullName);
var token = assemblyName.GetPublicKeyToken();
@ -623,30 +722,30 @@ namespace Microsoft.DotNet.Migration.Tests
}
}
private MigratedBuildComparisonData BuildProjectJsonMigrateBuildMSBuild(string projectDirectory,
private MigratedBuildComparisonData BuildProjectJsonMigrateBuildMSBuild(DirectoryInfo projectDirectory,
string projectName)
{
return BuildProjectJsonMigrateBuildMSBuild(projectDirectory,
projectName,
new [] { projectDirectory },
new [] { projectDirectory.FullName },
new [] { projectDirectory });
}
private MigratedBuildComparisonData BuildProjectJsonMigrateBuildMSBuild(string projectDirectory,
private MigratedBuildComparisonData BuildProjectJsonMigrateBuildMSBuild(DirectoryInfo projectDirectory,
string projectName,
string[] migrateArgs,
string[] restoreDirectories)
DirectoryInfo[] restoreDirectories)
{
BuildProjectJson(projectDirectory);
var projectJsonBuildOutputs = new HashSet<string>(CollectBuildOutputs(projectDirectory));
var projectJsonBuildOutputs = new HashSet<string>(CollectBuildOutputs(projectDirectory.FullName));
CleanBinObj(projectDirectory);
// Remove lock file for migration
foreach(var dir in restoreDirectories)
{
File.Delete(Path.Combine(dir, "project.lock.json"));
dir.GetFile("project.lock.json").Delete();
}
MigrateProject(migrateArgs);
@ -660,7 +759,7 @@ namespace Microsoft.DotNet.Migration.Tests
BuildMSBuild(projectDirectory, projectName);
var msbuildBuildOutputs = new HashSet<string>(CollectBuildOutputs(projectDirectory));
var msbuildBuildOutputs = new HashSet<string>(CollectBuildOutputs(projectDirectory.FullName));
return new MigratedBuildComparisonData(projectJsonBuildOutputs, msbuildBuildOutputs);
}
@ -673,41 +772,24 @@ namespace Microsoft.DotNet.Migration.Tests
.Select(p => Path.GetFullPath(p).Substring(fullBinPath.Length));
}
private static void DeleteDirectory(string dir)
private void CleanBinObj(DirectoryInfo projectDirectory)
{
foreach (string directory in Directory.EnumerateDirectories(dir))
{
DeleteDirectory(directory);
}
try
{
Directory.Delete(dir, true);
}
catch
{
// retry, if still doesn't delete then throw
Directory.Delete(dir, true);
}
}
private void CleanBinObj(string projectDirectory)
{
var dirs = new string[] { Path.Combine(projectDirectory, "bin"), Path.Combine(projectDirectory, "obj") };
var dirs = new DirectoryInfo[] { projectDirectory.GetDirectory("bin"), projectDirectory.GetDirectory("obj") };
foreach (var dir in dirs)
{
if(Directory.Exists(dir))
if(dir.Exists)
{
DeleteDirectory(dir);
dir.Delete(true);
}
}
}
private void BuildProjectJson(string projectDirectory)
private void BuildProjectJson(DirectoryInfo projectDirectory)
{
Console.WriteLine(projectDirectory);
var projectFile = "\"" + Path.Combine(projectDirectory, "project.json") + "\"";
var projectFile = $"\"{projectDirectory.GetFile("project.json").FullName}\"";
var result = new BuildPJCommand()
.WithCapturedOutput()
@ -726,15 +808,15 @@ namespace Microsoft.DotNet.Migration.Tests
.Pass();
}
private void RestoreProjectJson(string projectDirectory)
private void RestoreProjectJson(DirectoryInfo projectDirectory)
{
var projectFile = "\"" + Path.Combine(projectDirectory, "project.json") + "\"";
var projectFile = $"\"{projectDirectory.GetFile("project.json").FullName}\"";
new RestoreProjectJsonCommand()
.Execute(projectFile)
.Should().Pass();
}
private void Restore(string projectDirectory, string projectName=null, string runtime=null)
private void Restore(DirectoryInfo projectDirectory, string projectName=null, string runtime=null)
{
var command = new RestoreCommand()
.WithWorkingDirectory(projectDirectory)
@ -757,7 +839,7 @@ namespace Microsoft.DotNet.Migration.Tests
}
private string BuildMSBuild(
string projectDirectory,
DirectoryInfo projectDirectory,
string projectName,
string configuration="Debug",
string runtime=null,
@ -783,7 +865,7 @@ namespace Microsoft.DotNet.Migration.Tests
}
private string PublishMSBuild(
string projectDirectory,
DirectoryInfo projectDirectory,
string projectName,
string runtime = null,
string configuration = "Debug")
@ -805,7 +887,7 @@ namespace Microsoft.DotNet.Migration.Tests
return result.StdOut;
}
private string PackMSBuild(string projectDirectory, string projectName)
private string PackMSBuild(DirectoryInfo projectDirectory, string projectName)
{
if (projectName != null && !Path.HasExtension(projectName))
{
@ -821,13 +903,13 @@ namespace Microsoft.DotNet.Migration.Tests
return result.StdOut;
}
private void DeleteXproj(string projectDirectory)
private void DeleteXproj(DirectoryInfo projectDirectory)
{
var xprojFiles = Directory.EnumerateFiles(projectDirectory, "*.xproj");
var xprojFiles = projectDirectory.EnumerateFiles("*.xproj");
foreach (var xprojFile in xprojFiles)
{
File.Delete(xprojFile);
xprojFile.Delete();
}
}
@ -864,10 +946,11 @@ namespace Microsoft.DotNet.Migration.Tests
}
}
private void WriteGlobalJson(string globalDirectory)
private void WriteGlobalJson(DirectoryInfo globalDirectory)
{
var file = Path.Combine(globalDirectory, "global.json");
File.WriteAllText(file, @"
var file = globalDirectory.GetFile("global.json");
File.WriteAllText(file.FullName, @"
{
""projects"": [ ]
}");

View file

@ -35,8 +35,6 @@ VisualStudioVersion = 15.0.26006.2
MinimumVisualStudioVersion = 10.0.40219.1
Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""App"", ""App\App.csproj"", ""{7072A694-548F-4CAE-A58F-12D257D5F486}""
EndProject
Project(""{2150E333-8FDC-42A3-9474-1A3956D46DE8}"") = ""Lib"", ""Lib"", ""__LIB_FOLDER_GUID__""
EndProject
Project(""{13B669BE-BB05-4DDF-9536-439F39A36129}"") = ""Lib"", ""Lib\Lib.csproj"", ""__LIB_PROJECT_GUID__""
EndProject
Global
@ -77,9 +75,6 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
__LIB_PROJECT_GUID__ = __LIB_FOLDER_GUID__
EndGlobalSection
EndGlobal
";
@ -88,8 +83,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26006.2
MinimumVisualStudioVersion = 10.0.40219.1
Project(""{2150E333-8FDC-42A3-9474-1A3956D46DE8}"") = ""Lib"", ""Lib"", ""__LIB_FOLDER_GUID__""
EndProject
Project(""{13B669BE-BB05-4DDF-9536-439F39A36129}"") = ""Lib"", ""Lib\Lib.csproj"", ""__LIB_PROJECT_GUID__""
EndProject
Global
@ -115,9 +108,6 @@ Global
__LIB_PROJECT_GUID__.Release|x86.ActiveCfg = Release|x86
__LIB_PROJECT_GUID__.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
__LIB_PROJECT_GUID__ = __LIB_FOLDER_GUID__
EndGlobalSection
EndGlobal
";
@ -130,8 +120,6 @@ Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""App"", ""App.csproj"", "
EndProject
Project(""{2150E333-8FDC-42A3-9474-1A3956D46DE8}"") = ""src"", ""src"", ""__SRC_FOLDER_GUID__""
EndProject
Project(""{2150E333-8FDC-42A3-9474-1A3956D46DE8}"") = ""Lib"", ""Lib"", ""__LIB_FOLDER_GUID__""
EndProject
Project(""{13B669BE-BB05-4DDF-9536-439F39A36129}"") = ""Lib"", ""src\Lib\Lib.csproj"", ""__LIB_PROJECT_GUID__""
EndProject
Global
@ -173,8 +161,7 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
__LIB_FOLDER_GUID__ = __SRC_FOLDER_GUID__
__LIB_PROJECT_GUID__ = __LIB_FOLDER_GUID__
__LIB_PROJECT_GUID__ = __SRC_FOLDER_GUID__
EndGlobalSection
EndGlobal
";
@ -345,6 +332,70 @@ EndGlobal
.Should().BeVisuallyEquivalentTo(expectedSlnContents);
}
[Fact]
public void WhenProjectDirectoryIsAddedSolutionFoldersAreNotCreated()
{
var projectDirectory = TestAssets
.Get("TestAppWithSlnAndCsprojFiles")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var projectToAdd = Path.Combine("Lib", "Lib.csproj");
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"sln App.sln add {projectToAdd}");
cmd.Should().Pass();
var slnFile = SlnFile.Read(Path.Combine(projectDirectory, "App.sln"));
var solutionFolderProjects = slnFile.Projects.Where(
p => p.TypeGuid == ProjectTypeGuids.SolutionFolderGuid);
solutionFolderProjects.Count().Should().Be(0);
slnFile.Sections.GetSection("NestedProjects").Should().BeNull();
}
[Theory]
[InlineData(".")]
[InlineData("")]
public void WhenSolutionFolderExistsItDoesNotGetAdded(string firstComponent)
{
var projectDirectory = TestAssets
.Get("TestAppWithSlnAndSolutionFolders")
.CreateInstance()
.WithSourceFiles()
.Root
.FullName;
var projectToAdd = Path.Combine($"{firstComponent}", "src", "src", "Lib", "Lib.csproj");
var cmd = new DotnetCommand()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput($"sln App.sln add {projectToAdd}");
cmd.Should().Pass();
var slnFile = SlnFile.Read(Path.Combine(projectDirectory, "App.sln"));
slnFile.Projects.Count().Should().Be(4);
var solutionFolderProjects = slnFile.Projects.Where(
p => p.TypeGuid == ProjectTypeGuids.SolutionFolderGuid);
solutionFolderProjects.Count().Should().Be(2);
var solutionFolders = slnFile.Sections.GetSection("NestedProjects").Properties;
solutionFolders.Count.Should().Be(3);
solutionFolders["{DDF3765C-59FB-4AA6-BE83-779ED13AA64A}"]
.Should().Be("{72BFCA87-B033-4721-8712-4D12166B4A39}");
var newlyAddedSrcFolder = solutionFolderProjects.Where(
p => p.Id != "{72BFCA87-B033-4721-8712-4D12166B4A39}").Single();
solutionFolders[newlyAddedSrcFolder.Id]
.Should().Be("{72BFCA87-B033-4721-8712-4D12166B4A39}");
var libProject = slnFile.Projects.Where(p => p.Name == "Lib").Single();
solutionFolders[libProject.Id]
.Should().Be(newlyAddedSrcFolder.Id);
}
[Theory]
[InlineData("TestAppWithSlnAndCsprojFiles", ExpectedSlnFileAfterAddingLibProj, "")]
[InlineData("TestAppWithSlnAndCsprojProjectGuidFiles", ExpectedSlnFileAfterAddingLibProj, "{84A45D44-B677-492D-A6DA-B3A71135AB8E}")]
@ -574,12 +625,6 @@ EndGlobal
}
var slnContents = slnTemplate.Replace("__LIB_PROJECT_GUID__", expectedLibProjectGuid);
var matchingLibFolder = slnFile.Projects
.Where((p) => p.FilePath == "Lib")
.ToList();
matchingLibFolder.Count.Should().Be(1);
slnContents = slnContents.Replace("__LIB_FOLDER_GUID__", matchingLibFolder[0].Id);
var matchingSrcFolder = slnFile.Projects
.Where((p) => p.FilePath == "src")
.ToList();