post migration cleanup (#4449)
* Create tests * Basic scenario working & tested * Feature Complete * prevent build of intentionally broken test asset * Update migrate command backup * PR Feedback * Move negative test to negative test directory * Fix tests * make test output directories unique * Merge Conflict * make backup the default behavior * Pass2Fail * Remove tests' PJ dependency
This commit is contained in:
parent
a4776a2b2c
commit
5ede3b6367
14 changed files with 376 additions and 19 deletions
|
@ -0,0 +1,17 @@
|
|||
// 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(TestLibrary.Helper.GetMessage());
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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": {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// 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
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the message from the helper. This comment is here to help test XML documentation file generation, please do not remove it.
|
||||
/// </summary>
|
||||
/// <returns>A message</returns>
|
||||
public static string GetMessage()
|
||||
{
|
||||
return "This string came from the test library!";
|
||||
}
|
||||
|
||||
public static void SayHi()
|
||||
{
|
||||
Console.WriteLine("Hello there!");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"buildOptions": {
|
||||
"nowarn": [
|
||||
"CS1591"
|
||||
],
|
||||
"xmlDoc": true,
|
||||
"additionalArguments": [
|
||||
"-highentropyva+"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"MissingP2PDependency": {
|
||||
"target": "project",
|
||||
"version": "1.0.0-*"
|
||||
},
|
||||
"NETStandard.Library": "1.6.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"netstandard1.5": {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"projects": [ "."]
|
||||
}
|
|
@ -11,12 +11,15 @@ using Microsoft.Build.Evaluation;
|
|||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.ProjectJsonMigration;
|
||||
using Microsoft.DotNet.Internal.ProjectModel;
|
||||
using ProjectModel = Microsoft.DotNet.Internal.ProjectModel.Project;
|
||||
using Project = Microsoft.DotNet.Internal.ProjectModel.Project;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Migrate
|
||||
{
|
||||
public partial class MigrateCommand
|
||||
{
|
||||
private readonly DirectoryInfo _workspaceDirectory;
|
||||
private readonly DirectoryInfo _backupDirectory;
|
||||
private readonly string _templateFile;
|
||||
private readonly string _projectArg;
|
||||
private readonly string _sdkVersion;
|
||||
|
@ -24,6 +27,7 @@ namespace Microsoft.DotNet.Tools.Migrate
|
|||
private readonly bool _skipProjectReferences;
|
||||
private readonly string _reportFile;
|
||||
private readonly bool _reportFormatJson;
|
||||
private readonly bool _skipBackup;
|
||||
|
||||
public MigrateCommand(
|
||||
string templateFile,
|
||||
|
@ -32,15 +36,21 @@ namespace Microsoft.DotNet.Tools.Migrate
|
|||
string xprojFilePath,
|
||||
string reportFile,
|
||||
bool skipProjectReferences,
|
||||
bool reportFormatJson)
|
||||
bool reportFormatJson,
|
||||
bool skipBackup)
|
||||
{
|
||||
_templateFile = templateFile;
|
||||
_projectArg = projectArg ?? Directory.GetCurrentDirectory();
|
||||
_workspaceDirectory = File.Exists(_projectArg)
|
||||
? new FileInfo(_projectArg).Directory
|
||||
: new DirectoryInfo(_projectArg);
|
||||
_backupDirectory = new DirectoryInfo(Path.Combine(_workspaceDirectory.FullName, "backup"));
|
||||
_sdkVersion = sdkVersion;
|
||||
_xprojFilePath = xprojFilePath;
|
||||
_skipProjectReferences = skipProjectReferences;
|
||||
_reportFile = reportFile;
|
||||
_reportFormatJson = reportFormatJson;
|
||||
_skipBackup = skipBackup;
|
||||
}
|
||||
|
||||
public int Execute()
|
||||
|
@ -82,12 +92,73 @@ namespace Microsoft.DotNet.Tools.Migrate
|
|||
|
||||
temporaryDotnetNewProject.Clean();
|
||||
|
||||
MoveProjectJsonArtifactsToBackup(migrationReport);
|
||||
|
||||
return migrationReport.FailedProjectsCount;
|
||||
}
|
||||
|
||||
private void MoveProjectJsonArtifactsToBackup(MigrationReport migrationReport)
|
||||
{
|
||||
if (_skipBackup)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (migrationReport.FailedProjectsCount > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BackupGlobalJson();
|
||||
|
||||
BackupProjects(migrationReport);
|
||||
|
||||
}
|
||||
|
||||
private void BackupGlobalJson()
|
||||
{
|
||||
_backupDirectory.Create();
|
||||
|
||||
var globalJson = Path.Combine(_workspaceDirectory.FullName, GlobalSettings.FileName);
|
||||
|
||||
if (File.Exists(globalJson))
|
||||
{
|
||||
File.Move(globalJson, Path.Combine(_backupDirectory.FullName, GlobalSettings.FileName));
|
||||
}
|
||||
}
|
||||
|
||||
private void BackupProjects(MigrationReport migrationReport)
|
||||
{
|
||||
foreach (var report in migrationReport.ProjectMigrationReports)
|
||||
{
|
||||
MigrateProject(report);
|
||||
}
|
||||
}
|
||||
|
||||
private void MigrateProject(ProjectMigrationReport report)
|
||||
{
|
||||
var projectDirectory = PathUtility.EnsureTrailingSlash(report.ProjectDirectory);
|
||||
|
||||
var relativeDirectory = PathUtility.GetRelativePath(PathUtility.EnsureTrailingSlash(_workspaceDirectory.FullName), projectDirectory);
|
||||
|
||||
var targetDirectory = String.IsNullOrEmpty(relativeDirectory)
|
||||
? _backupDirectory.FullName
|
||||
: Path.Combine(_backupDirectory.FullName, relativeDirectory);
|
||||
|
||||
PathUtility.EnsureDirectory(PathUtility.EnsureTrailingSlash(targetDirectory));
|
||||
|
||||
var movableFiles = new DirectoryInfo(projectDirectory)
|
||||
.EnumerateFiles()
|
||||
.Where(f => f.Name == Project.FileName || f.Extension == ".xproj");
|
||||
|
||||
foreach (var movableFile in movableFiles)
|
||||
{
|
||||
movableFile.MoveTo(Path.Combine(targetDirectory, movableFile.Name));
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteReport(MigrationReport migrationReport)
|
||||
{
|
||||
|
||||
if (!string.IsNullOrEmpty(_reportFile))
|
||||
{
|
||||
using (var outputTextWriter = GetReportFileOutputTextWriter())
|
||||
|
@ -194,13 +265,14 @@ namespace Microsoft.DotNet.Tools.Migrate
|
|||
{
|
||||
IEnumerable<string> projects = null;
|
||||
|
||||
if (projectArg.EndsWith(ProjectModel.FileName, StringComparison.OrdinalIgnoreCase))
|
||||
if (projectArg.EndsWith(Project.FileName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
projects = Enumerable.Repeat(projectArg, 1);
|
||||
}
|
||||
else if (projectArg.EndsWith(GlobalSettings.FileName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
projects = GetProjectsFromGlobalJson(projectArg);
|
||||
|
||||
if (!projects.Any())
|
||||
{
|
||||
throw new Exception("Unable to find any projects in global.json");
|
||||
|
@ -208,8 +280,8 @@ namespace Microsoft.DotNet.Tools.Migrate
|
|||
}
|
||||
else if (Directory.Exists(projectArg))
|
||||
{
|
||||
projects =
|
||||
Directory.EnumerateFiles(projectArg, ProjectModel.FileName, SearchOption.AllDirectories);
|
||||
projects = Directory.EnumerateFiles(projectArg, Project.FileName, SearchOption.AllDirectories);
|
||||
|
||||
if (!projects.Any())
|
||||
{
|
||||
throw new Exception($"No project.json file found in '{projectArg}'");
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace Microsoft.DotNet.Tools.Migrate
|
|||
|
||||
CommandOption reportFile = app.Option("-r|--report-file", "Output migration report to a file in addition to the console.", CommandOptionType.SingleValue);
|
||||
CommandOption structuredReportOutput = app.Option("--format-report-file-json", "Output migration report file as json rather than user messages", CommandOptionType.BoolValue);
|
||||
CommandOption skipBackup = app.Option("--skip-backup", "Skip moving project.json, global.json, and *.xproj to a `backup` directory after successful migration.", CommandOptionType.BoolValue);
|
||||
|
||||
app.OnExecute(() =>
|
||||
{
|
||||
|
@ -53,7 +54,8 @@ namespace Microsoft.DotNet.Tools.Migrate
|
|||
xprojFile.Value(),
|
||||
reportFile.Value(),
|
||||
skipProjectReferences.BoolValue.HasValue ? skipProjectReferences.BoolValue.Value : false,
|
||||
structuredReportOutput.BoolValue.HasValue ? structuredReportOutput.BoolValue.Value : false);
|
||||
structuredReportOutput.BoolValue.HasValue ? structuredReportOutput.BoolValue.Value : false,
|
||||
skipBackup.BoolValue.HasValue ? skipBackup.BoolValue.Value : false);
|
||||
|
||||
return migrateCommand.Execute();
|
||||
});
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
|
|||
public GivenThatIWantToMigrateAssemblyInfo()
|
||||
{
|
||||
var projectDirectory =
|
||||
TestAssetsManager.CreateTestInstance("AppWithAssemblyInfo", callingMethod: "i").Path;
|
||||
TestAssetsManager.CreateTestInstance("AppWithAssemblyInfo").Path;
|
||||
var projectContext =
|
||||
ProjectContext.Create(projectDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10);
|
||||
_mockProject = ProjectRootElement.Create();
|
||||
|
|
|
@ -30,11 +30,31 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
|
|||
return new AndConstraint<DirectoryInfoAssertions>(this);
|
||||
}
|
||||
|
||||
public AndConstraint<DirectoryInfoAssertions> HaveFile(string expectedFile)
|
||||
public AndConstraint<DirectoryInfoAssertions> HaveFile(string expectedFile, string because = "", params object[] reasonArgs)
|
||||
{
|
||||
var file = _dirInfo.EnumerateFiles(expectedFile, SearchOption.TopDirectoryOnly).SingleOrDefault();
|
||||
Execute.Assertion.ForCondition(file != null)
|
||||
.FailWith("Expected File {0} cannot be found in directory {1}.", expectedFile, _dirInfo.FullName);
|
||||
|
||||
Execute.Assertion
|
||||
.ForCondition(file != null)
|
||||
.BecauseOf(because, reasonArgs)
|
||||
.FailWith($"Expected File {expectedFile} cannot be found in directory {_dirInfo.FullName}.");
|
||||
|
||||
return new AndConstraint<DirectoryInfoAssertions>(this);
|
||||
}
|
||||
|
||||
public AndConstraint<DirectoryInfoAssertions> HaveTextFile(string expectedFile, string expectedContents, string because = "", params object[] reasonArgs)
|
||||
{
|
||||
this.HaveFile(expectedFile, because, reasonArgs);
|
||||
|
||||
var file = _dirInfo.EnumerateFiles(expectedFile, SearchOption.TopDirectoryOnly).SingleOrDefault();
|
||||
|
||||
var contents = File.ReadAllText(file.FullName);
|
||||
|
||||
Execute.Assertion
|
||||
.ForCondition(contents.Equals(expectedContents))
|
||||
.BecauseOf(because, reasonArgs)
|
||||
.FailWith($"Expected file {expectedFile} to contain \n\n{expectedContents}\n\nbut it contains\n\n{contents}\n");
|
||||
|
||||
return new AndConstraint<DirectoryInfoAssertions>(this);
|
||||
}
|
||||
|
||||
|
@ -56,12 +76,26 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
|
|||
return new AndConstraint<DirectoryInfoAssertions>(this);
|
||||
}
|
||||
|
||||
public AndConstraint<DirectoryInfoAssertions> HaveFilesMatching(string expectedFilesSearchPattern, SearchOption searchOption)
|
||||
public AndConstraint<DirectoryInfoAssertions> HaveTextFiles(IDictionary<string, string> expectedFiles, string because = "", params object[] reasonArgs)
|
||||
{
|
||||
foreach (var expectedFile in expectedFiles)
|
||||
{
|
||||
HaveTextFile(expectedFile.Key, expectedFile.Value, because, reasonArgs);
|
||||
}
|
||||
|
||||
return new AndConstraint<DirectoryInfoAssertions>(this);
|
||||
}
|
||||
|
||||
public AndConstraint<DirectoryInfoAssertions> HaveFilesMatching(string expectedFilesSearchPattern, SearchOption searchOption, string because = "", params object[] reasonArgs)
|
||||
{
|
||||
var matchingFileExists = _dirInfo.EnumerateFiles(expectedFilesSearchPattern, searchOption).Any();
|
||||
Execute.Assertion.ForCondition(matchingFileExists == true)
|
||||
|
||||
Execute.Assertion
|
||||
.ForCondition(matchingFileExists == true)
|
||||
.BecauseOf(because, reasonArgs)
|
||||
.FailWith("Expected directory {0} to contain files matching {1}, but no matching file exists.",
|
||||
_dirInfo.FullName, expectedFilesSearchPattern);
|
||||
|
||||
return new AndConstraint<DirectoryInfoAssertions>(this);
|
||||
}
|
||||
|
||||
|
@ -108,5 +142,15 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
|
|||
|
||||
return new AndConstraint<DirectoryInfoAssertions>(this);
|
||||
}
|
||||
|
||||
public AndConstraint<DirectoryInfoAssertions> NotExist(string because = "", params object[] reasonArgs)
|
||||
{
|
||||
Execute.Assertion
|
||||
.ForCondition(_dirInfo.Exists == false)
|
||||
.BecauseOf(because, reasonArgs)
|
||||
.FailWith($"Expected directory {_dirInfo.FullName} to not exist, but it does.");
|
||||
|
||||
return new AndConstraint<DirectoryInfoAssertions>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Test.Utilities
|
||||
{
|
||||
public sealed class MigrateCommand : TestCommand
|
||||
{
|
||||
public MigrateCommand()
|
||||
: base("dotnet")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override CommandResult Execute(string args="")
|
||||
{
|
||||
args = $"migrate {args}";
|
||||
|
||||
return base.Execute(args);
|
||||
}
|
||||
|
||||
public override CommandResult ExecuteWithCapturedOutput(string args = "")
|
||||
{
|
||||
args = $"migrate {args}";
|
||||
return base.ExecuteWithCapturedOutput(args);
|
||||
}
|
||||
}
|
||||
}
|
111
test/dotnet-migrate.Tests/GivenThatAnAppWasMigrated.cs
Normal file
111
test/dotnet-migrate.Tests/GivenThatAnAppWasMigrated.cs
Normal file
|
@ -0,0 +1,111 @@
|
|||
using FluentAssertions;
|
||||
using Microsoft.DotNet.TestFramework;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.DotNet.Migration.Tests
|
||||
{
|
||||
public class GivenThatAnAppWasMigrated : TestBase
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("PJTestAppSimple")]
|
||||
[InlineData("TestAppWithLibrary")]
|
||||
public void When_migration_succeeds_Then_project_json_artifacts_get_moved_to_backup(string testProjectName)
|
||||
{
|
||||
var testRoot = TestAssetsManager
|
||||
.CreateTestInstance(testProjectName, identifier: testProjectName)
|
||||
.Path;
|
||||
|
||||
var backupRoot = Path.Combine(testRoot, "backup");
|
||||
|
||||
var migratableArtifacts = GetProjectJsonArtifacts(testRoot);
|
||||
|
||||
new MigrateCommand()
|
||||
.WithWorkingDirectory(testRoot)
|
||||
.Execute()
|
||||
.Should().Pass();
|
||||
|
||||
var backupArtifacts = GetProjectJsonArtifacts(backupRoot);
|
||||
|
||||
backupArtifacts.Should().Equal(migratableArtifacts, "Because all of and only these artifacts should have been moved");
|
||||
|
||||
new DirectoryInfo(testRoot).Should().NotHaveFiles(backupArtifacts.Keys);
|
||||
|
||||
new DirectoryInfo(backupRoot).Should().HaveTextFiles(backupArtifacts);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("TestAppWithLibraryAndMissingP2P")]
|
||||
public void When_migration_fails_Then_project_json_artifacts_do_not_get_moved_to_backup(string testProjectName)
|
||||
{
|
||||
var testRoot = new TestAssetsManager(Path.Combine(RepoRoot, "TestAssets", "NonRestoredTestProjects"))
|
||||
.CreateTestInstance(testProjectName, identifier: testProjectName)
|
||||
.Path;
|
||||
|
||||
var backupRoot = Path.Combine(testRoot, "backup");
|
||||
|
||||
var migratableArtifacts = GetProjectJsonArtifacts(testRoot);
|
||||
|
||||
new MigrateCommand()
|
||||
.WithWorkingDirectory(testRoot)
|
||||
.Execute()
|
||||
.Should().Fail();
|
||||
|
||||
new DirectoryInfo(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.");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("PJTestAppSimple")]
|
||||
public void When_skipbackup_specified_Then_project_json_artifacts_do_not_get_moved_to_backup(string testProjectName)
|
||||
{
|
||||
var testRoot = TestAssetsManager.CreateTestInstance(testProjectName, identifier: testProjectName).Path;
|
||||
|
||||
var backupRoot = Path.Combine(testRoot, "backup");
|
||||
|
||||
var migratableArtifacts = GetProjectJsonArtifacts(testRoot);
|
||||
|
||||
new MigrateCommand()
|
||||
.WithWorkingDirectory(testRoot)
|
||||
.Execute("--skip-backup")
|
||||
.Should().Pass();
|
||||
|
||||
new DirectoryInfo(backupRoot).Should().NotExist("Because --skip-backup was specified.");
|
||||
|
||||
new DirectoryInfo(testRoot).Should().HaveTextFiles(migratableArtifacts, "Because --skip-backup was specified.");
|
||||
}
|
||||
|
||||
private Dictionary<string, string> GetProjectJsonArtifacts(string rootPath)
|
||||
{
|
||||
var catalog = new Dictionary<string, string>();
|
||||
|
||||
var patterns = new [] { "global.json", "project.json", "*.xproj" };
|
||||
|
||||
foreach (var pattern in patterns)
|
||||
{
|
||||
AddArtifactsToCatalog(catalog, rootPath, pattern);
|
||||
}
|
||||
|
||||
return catalog;
|
||||
}
|
||||
|
||||
private void AddArtifactsToCatalog(Dictionary<string, string> catalog, string basePath, string pattern)
|
||||
{
|
||||
basePath = PathUtility.EnsureTrailingSlash(basePath);
|
||||
|
||||
var baseDirectory = new DirectoryInfo(basePath);
|
||||
|
||||
var files = baseDirectory.GetFiles(pattern, SearchOption.AllDirectories);
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
catalog.Add(PathUtility.GetRelativePath(basePath, file.FullName), File.ReadAllText(file.FullName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,8 @@ using BuildCommand = Microsoft.DotNet.Tools.Test.Utilities.BuildCommand;
|
|||
using System.Runtime.Loader;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using MigrateCommand = Microsoft.DotNet.Tools.Migrate.MigrateCommand;
|
||||
|
||||
namespace Microsoft.DotNet.Migration.Tests
|
||||
{
|
||||
public class GivenThatIWantToMigrateTestApps : TestBase
|
||||
|
@ -354,7 +356,8 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
public void It_migrates_and_publishes_projects_with_runtimes()
|
||||
{
|
||||
var projectName = "PJTestAppSimple";
|
||||
var projectDirectory = TestAssetsManager.CreateTestInstance(projectName, callingMethod: "i")
|
||||
var projectDirectory = TestAssetsManager
|
||||
.CreateTestInstance(projectName)
|
||||
.WithLockFiles()
|
||||
.Path;
|
||||
|
||||
|
@ -440,7 +443,7 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
|
||||
private void VerifyMigration(IEnumerable<string> expectedProjects, string rootDir)
|
||||
{
|
||||
var migratedProjects = Directory.EnumerateFiles(rootDir, "project.json", SearchOption.AllDirectories)
|
||||
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)));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue