-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Support --solution and --directory options in dotnet test #45859
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
mariam-abdulla
merged 48 commits into
main
from
dev/mabdullah/support-solution-option-in-dotnet-test
Jan 13, 2025
Merged
Changes from all commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
e9c2a23
Use msbuild APIs to load projects
mariam-abdulla e7bcc8a
Add space
mariam-abdulla 8d747c7
Fix formatting
mariam-abdulla 2b02833
Add comments
mariam-abdulla f4cce4e
Update src/Cli/dotnet/commands/dotnet-test/TestingPlatformCommand.cs
mariam-abdulla f078060
Replace 0 and 1 with constants
mariam-abdulla 4c9add2
Merge branch 'dev/mabdullah/use-msbuild-apis-to-retrieve-project-prop…
mariam-abdulla 771c1f1
Return from InitializeTestApplications() if _areTestingPlatformApplic…
mariam-abdulla def3cb8
Update method name
mariam-abdulla 3b75ca8
Use aggregator overload in ProcessProjectsInParallel()
mariam-abdulla 8e3b723
Apply some comments
mariam-abdulla b7b79ef
Remove ?
mariam-abdulla 5349e6c
Update GetSolutionFilePaths
mariam-abdulla cbc3389
Use Microsoft.VisualStudio.SolutionPersistence namespace to parse sol…
mariam-abdulla 9284893
Add GetSlnFileFullPath and GetProjectFileFullPath methods in Extensio…
mariam-abdulla 6b42f48
Refactor
mariam-abdulla 51c7424
Update ParseSolution to use GetSerializerByMoniker
mariam-abdulla 3855845
Merge branch 'main' into dev/mabdullah/use-msbuild-apis-to-retrieve-p…
mariam-abdulla 082f260
Update src/Cli/dotnet/commands/dotnet-test/TestingPlatformCommand.cs
mariam-abdulla ae87351
Update src/Cli/dotnet/commands/dotnet-test/SolutionAndProjectUtility.cs
mariam-abdulla 3e26cd3
Update src/Cli/dotnet/commands/dotnet-test/SolutionAndProjectUtility.cs
mariam-abdulla 31593b0
Update src/Cli/dotnet/commands/dotnet-test/SolutionAndProjectUtility.cs
mariam-abdulla f781164
Update src/Cli/dotnet/commands/dotnet-test/SolutionAndProjectUtility.cs
mariam-abdulla 7e359d1
Merge branch 'main' into dev/mabdullah/use-msbuild-apis-to-retrieve-p…
mariam-abdulla 3c3d56b
Update src/Cli/dotnet/commands/dotnet-test/SolutionAndProjectUtility.cs
mariam-abdulla 55d247d
Apply comments
mariam-abdulla d3b11c5
merge
mariam-abdulla 41323d4
Update src/Cli/dotnet/commands/dotnet-test/SolutionAndProjectUtility.cs
mariam-abdulla a774524
Use Lock
mariam-abdulla 9d17be2
Merge branch 'dev/mabdullah/use-msbuild-apis-to-retrieve-project-prop…
mariam-abdulla 3f66a69
Update -bl logic
mariam-abdulla 97b5ae9
Merge branch 'main' into dev/mabdullah/use-msbuild-apis-to-retrieve-p…
mariam-abdulla 4f2b769
Remove unused var
mariam-abdulla 6504a67
Merge branch 'dev/mabdullah/use-msbuild-apis-to-retrieve-project-prop…
mariam-abdulla c3dc4f2
Support --solution
mariam-abdulla d96f016
merge
mariam-abdulla 517c20a
refactor code
mariam-abdulla 5d05184
Fix bug
mariam-abdulla 2341d1a
merge
mariam-abdulla 3bf45f4
Remove @
mariam-abdulla 223b072
Fixes
mariam-abdulla 542560a
Merge branch 'main' into dev/mabdullah/support-solution-option-in-dot…
ViktorHofer efa4fb4
Apply comments
mariam-abdulla 6765a26
Merge branch 'dev/mabdullah/support-solution-option-in-dotnet-test' o…
mariam-abdulla a36f471
Apply comments
mariam-abdulla 47bced1
remove unused vars
mariam-abdulla 9712e05
Support --directory
mariam-abdulla e1969ee
Merge branch 'main' into dev/mabdullah/support-solution-option-in-dot…
mariam-abdulla File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
| using Microsoft.Build.Execution; | ||
| using Microsoft.Build.Framework; | ||
| using Microsoft.Build.Logging; | ||
| using Microsoft.DotNet.Tools.Test; | ||
|
|
||
| namespace Microsoft.DotNet.Cli | ||
| { | ||
|
|
@@ -18,8 +19,6 @@ internal sealed class MSBuildHandler : IDisposable | |
| private readonly ConcurrentBag<TestApplication> _testApplications = new(); | ||
| private bool _areTestingPlatformApplications = true; | ||
|
|
||
| private const string BinLogFileName = "msbuild.binlog"; | ||
| private const string Separator = ";"; | ||
| private static readonly Lock buildLock = new(); | ||
|
|
||
| public MSBuildHandler(List<string> args, TestApplicationActionQueue actionQueue, int degreeOfParallelism) | ||
|
|
@@ -29,9 +28,86 @@ public MSBuildHandler(List<string> args, TestApplicationActionQueue actionQueue, | |
| _degreeOfParallelism = degreeOfParallelism; | ||
| } | ||
|
|
||
| public async Task<int> RunWithMSBuild() | ||
| public async Task<bool> RunMSBuild(BuildPathsOptions buildPathOptions) | ||
| { | ||
| bool solutionOrProjectFileFound = SolutionAndProjectUtility.TryGetProjectOrSolutionFilePath(Directory.GetCurrentDirectory(), out string projectOrSolutionFilePath, out bool isSolution); | ||
| if (!ValidateBuildPathOptions(buildPathOptions)) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| int msbuildExitCode; | ||
|
|
||
| if (!string.IsNullOrEmpty(buildPathOptions.ProjectPath)) | ||
| { | ||
| msbuildExitCode = await RunBuild(buildPathOptions.ProjectPath, isSolution: false); | ||
| } | ||
| else if (!string.IsNullOrEmpty(buildPathOptions.SolutionPath)) | ||
| { | ||
| msbuildExitCode = await RunBuild(buildPathOptions.SolutionPath, isSolution: true); | ||
| } | ||
| else | ||
| { | ||
| msbuildExitCode = await RunBuild(buildPathOptions.DirectoryPath ?? Directory.GetCurrentDirectory()); | ||
| } | ||
|
|
||
| if (msbuildExitCode != ExitCodes.Success) | ||
| { | ||
| VSTestTrace.SafeWriteTrace(() => string.Format(LocalizableStrings.CmdMSBuildProjectsPropertiesErrorDescription, msbuildExitCode)); | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| private bool ValidateBuildPathOptions(BuildPathsOptions buildPathOptions) | ||
| { | ||
| if ((!string.IsNullOrEmpty(buildPathOptions.ProjectPath) && !string.IsNullOrEmpty(buildPathOptions.SolutionPath)) || | ||
| (!string.IsNullOrEmpty(buildPathOptions.ProjectPath) && !string.IsNullOrEmpty(buildPathOptions.DirectoryPath)) || | ||
| (!string.IsNullOrEmpty(buildPathOptions.SolutionPath) && !string.IsNullOrEmpty(buildPathOptions.DirectoryPath))) | ||
| { | ||
| VSTestTrace.SafeWriteTrace(() => LocalizableStrings.CmdMultipleBuildPathOptionsErrorDescription); | ||
| return false; | ||
| } | ||
|
|
||
| if (!string.IsNullOrEmpty(buildPathOptions.ProjectPath)) | ||
| { | ||
| return ValidateFilePath(buildPathOptions.ProjectPath, CliConstants.ProjectExtensions, LocalizableStrings.CmdInvalidProjectFileExtensionErrorDescription); | ||
| } | ||
|
|
||
| if (!string.IsNullOrEmpty(buildPathOptions.SolutionPath)) | ||
| { | ||
| return ValidateFilePath(buildPathOptions.SolutionPath, CliConstants.SolutionExtensions, LocalizableStrings.CmdInvalidSolutionFileExtensionErrorDescription); | ||
| } | ||
|
|
||
| if (!string.IsNullOrEmpty(buildPathOptions.DirectoryPath) && !Directory.Exists(buildPathOptions.DirectoryPath)) | ||
| { | ||
| VSTestTrace.SafeWriteTrace(() => string.Format(LocalizableStrings.CmdNonExistentDirectoryErrorDescription, Path.GetFullPath(buildPathOptions.DirectoryPath))); | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| private static bool ValidateFilePath(string filePath, string[] validExtensions, string errorMessage) | ||
| { | ||
| if (!validExtensions.Contains(Path.GetExtension(filePath))) | ||
| { | ||
| VSTestTrace.SafeWriteTrace(() => string.Format(errorMessage, filePath)); | ||
| return false; | ||
| } | ||
|
|
||
| if (!File.Exists(filePath)) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @baronfel do you have some helper around filesystem for mocking and more or is it fine to use this check directly? |
||
| { | ||
| VSTestTrace.SafeWriteTrace(() => string.Format(LocalizableStrings.CmdNonExistentFileErrorDescription, Path.GetFullPath(filePath))); | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| private async Task<int> RunBuild(string directoryPath) | ||
| { | ||
| bool solutionOrProjectFileFound = SolutionAndProjectUtility.TryGetProjectOrSolutionFilePath(directoryPath, out string projectOrSolutionFilePath, out bool isSolution); | ||
|
|
||
| if (!solutionOrProjectFileFound) | ||
| { | ||
|
|
@@ -45,9 +121,9 @@ public async Task<int> RunWithMSBuild() | |
| return restored ? ExitCodes.Success : ExitCodes.GenericFailure; | ||
| } | ||
|
|
||
| public async Task<int> RunWithMSBuild(string filePath) | ||
| private async Task<int> RunBuild(string filePath, bool isSolution) | ||
| { | ||
| (IEnumerable<Module> modules, bool restored) = await GetProjectsProperties(filePath, false); | ||
| (IEnumerable<Module> modules, bool restored) = await GetProjectsProperties(filePath, isSolution); | ||
|
|
||
| InitializeTestApplications(modules); | ||
|
|
||
|
|
@@ -92,7 +168,12 @@ public bool EnqueueTestApplications() | |
|
|
||
| if (isSolution) | ||
| { | ||
| var projects = await SolutionAndProjectUtility.ParseSolution(solutionOrProjectFilePath); | ||
| string fileDirectory = Path.GetDirectoryName(solutionOrProjectFilePath); | ||
| string rootDirectory = string.IsNullOrEmpty(fileDirectory) | ||
| ? Directory.GetCurrentDirectory() | ||
| : fileDirectory; | ||
|
|
||
| var projects = await SolutionAndProjectUtility.ParseSolution(solutionOrProjectFilePath, rootDirectory); | ||
| ProcessProjectsInParallel(projects, allProjects, ref restored); | ||
| } | ||
| else | ||
|
|
@@ -178,7 +259,7 @@ private static IEnumerable<Module> ExtractModulesFromProject(Project project) | |
| } | ||
| else | ||
| { | ||
| var frameworks = targetFrameworks.Split(Separator, StringSplitOptions.RemoveEmptyEntries); | ||
| var frameworks = targetFrameworks.Split(CliConstants.SemiColon, StringSplitOptions.RemoveEmptyEntries); | ||
| foreach (var framework in frameworks) | ||
| { | ||
| project.SetProperty(ProjectProperties.TargetFramework, framework); | ||
|
|
@@ -225,8 +306,7 @@ private static BuildResult RestoreProject(string projectFilePath, ProjectCollect | |
|
|
||
| private static bool IsBinaryLoggerEnabled(List<string> args, out string binLogFileName) | ||
| { | ||
| binLogFileName = BinLogFileName; | ||
|
|
||
| binLogFileName = string.Empty; | ||
| var binLogArgs = new List<string>(); | ||
|
|
||
| foreach (var arg in args) | ||
|
|
@@ -248,10 +328,16 @@ private static bool IsBinaryLoggerEnabled(List<string> args, out string binLogFi | |
| // Get BinLog filename | ||
| var binLogArg = binLogArgs.LastOrDefault(); | ||
|
|
||
| if (binLogArg.Contains(':')) | ||
| if (binLogArg.Contains(CliConstants.Colon)) | ||
| { | ||
| binLogFileName = binLogArg.Split(':')[1]; | ||
| var parts = binLogArg.Split(CliConstants.Colon, 2); | ||
| binLogFileName = !string.IsNullOrEmpty(parts[1]) ? parts[1] : CliConstants.BinLogFileName; | ||
| } | ||
| else | ||
| { | ||
| binLogFileName = CliConstants.BinLogFileName; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| namespace Microsoft.DotNet.Cli | ||
| { | ||
| internal record BuildConfigurationOptions(bool HasNoRestore, bool HasNoBuild, string Configuration, string Architecture); | ||
|
|
||
| internal record BuildPathsOptions(string ProjectPath, string SolutionPath, string DirectoryPath); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.