| File: Workspaces\MSBuildWorkspaceFinder.cs | Web Access |
| Project: src\sdk\src\Dotnet.Format\dotnet-format\dotnet-format.csproj (dotnet-format) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // Original License: // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // See https://github.com/aspnet/DotNetTools/blob/261b27b70027871143540af10a5cba57ce07ff97/src/dotnet-watch/Internal/MsBuildProjectFinder.cs namespace Microsoft.CodeAnalysis.Tools.Workspaces { internal class MSBuildWorkspaceFinder { // Used to exclude dnx projects private const string DnxProjectExtension = ".xproj"; /// <summary> /// Finds a compatible MSBuild project or solution. /// <param name="searchDirectory">The base directory to search</param> /// <param name="workspacePath">A specific project or solution file to find</param> /// </summary> public static (bool isSolution, string workspacePath) FindWorkspace(string searchDirectory, string? workspacePath = null) { if (!string.IsNullOrEmpty(workspacePath)) { if (!Path.IsPathRooted(workspacePath)) { workspacePath = Path.GetFullPath(workspacePath, searchDirectory); } return Directory.Exists(workspacePath) ? FindWorkspace(workspacePath!) // IsNullOrEmpty is not annotated on .NET Core 2.1 : FindFile(workspacePath!); // IsNullOrEmpty is not annotated on .NET Core 2.1 } var foundSolution = FindMatchingFile(searchDirectory, FindSolutionFiles, Resources.Multiple_MSBuild_solution_files_found_in_0_Specify_which_to_use_with_the_workspace_argument); var foundProject = FindMatchingFile(searchDirectory, FindProjectFiles, Resources.Multiple_MSBuild_project_files_found_in_0_Specify_which_to_use_with_the_workspace_argument); if (!string.IsNullOrEmpty(foundSolution) && !string.IsNullOrEmpty(foundProject)) { throw new FileNotFoundException(string.Format(Resources.Both_a_MSBuild_project_file_and_solution_file_found_in_0_Specify_which_to_use_with_the_workspace_argument, searchDirectory)); } if (!string.IsNullOrEmpty(foundSolution)) { return (true, foundSolution!); // IsNullOrEmpty is not annotated on .NET Core 2.1 } if (!string.IsNullOrEmpty(foundProject)) { return (false, foundProject!); // IsNullOrEmpty is not annotated on .NET Core 2.1 } throw new FileNotFoundException(string.Format(Resources.Could_not_find_a_MSBuild_project_or_solution_file_in_0_Specify_which_to_use_with_the_workspace_argument, searchDirectory)); } private static (bool isSolution, string workspacePath) FindFile(string workspacePath) { var workspaceExtension = Path.GetExtension(workspacePath); var isSolution = workspaceExtension.Equals(".sln", StringComparison.OrdinalIgnoreCase) || workspaceExtension.Equals(".slnf", StringComparison.OrdinalIgnoreCase) || workspaceExtension.Equals(".slnx", StringComparison.OrdinalIgnoreCase); var isProject = !isSolution && workspaceExtension.EndsWith("proj", StringComparison.OrdinalIgnoreCase) && !workspaceExtension.Equals(DnxProjectExtension, StringComparison.OrdinalIgnoreCase); if (!isSolution && !isProject) { throw new FileNotFoundException(string.Format(Resources.The_file_0_does_not_appear_to_be_a_valid_project_or_solution_file, Path.GetFileName(workspacePath))); } if (!File.Exists(workspacePath)) { var message = isSolution ? Resources.The_solution_file_0_does_not_exist : Resources.The_project_file_0_does_not_exist; throw new FileNotFoundException(string.Format(message, workspacePath)); } return (isSolution, workspacePath); } private static IEnumerable<string> FindSolutionFiles(string basePath) => [ ..Directory.EnumerateFileSystemEntries(basePath, "*.sln", SearchOption.TopDirectoryOnly), ..Directory.EnumerateFileSystemEntries(basePath, "*.slnf", SearchOption.TopDirectoryOnly), ..Directory.EnumerateFileSystemEntries(basePath, "*.slnx", SearchOption.TopDirectoryOnly) ]; private static IEnumerable<string> FindProjectFiles(string basePath) => Directory.EnumerateFileSystemEntries(basePath, "*.*proj", SearchOption.TopDirectoryOnly) .Where(f => !DnxProjectExtension.Equals(Path.GetExtension(f), StringComparison.OrdinalIgnoreCase)); private static string? FindMatchingFile(string searchBase, Func<string, IEnumerable<string>> fileSelector, string multipleFilesFoundError) { if (!Directory.Exists(searchBase)) { return null; } var files = fileSelector(searchBase).ToList(); if (files.Count > 1) { throw new FileNotFoundException(string.Format(multipleFilesFoundError, searchBase)); } return files.Count == 1 ? files[0] : null; } } }