public static bool TryRead(string filterFilename, PathResolver pathResolver, [NotNullWhen(true)] out string?solutionFilename, out ImmutableHashSet <string> projectFilter) { try { using var document = JsonDocument.Parse(File.ReadAllText(filterFilename)); var solution = document.RootElement.GetProperty("solution"); // Convert directory separators to the platform's default, since that is what MSBuild provide us. var solutionPath = solution.GetProperty("path").GetString()?.Replace('\\', Path.DirectorySeparatorChar); if (solutionPath is null || Path.GetDirectoryName(filterFilename) is not string baseDirectory) { solutionFilename = string.Empty; projectFilter = ImmutableHashSet <string> .Empty; return(false); } if (!pathResolver.TryGetAbsoluteSolutionPath(solutionPath, baseDirectory, DiagnosticReportingMode.Throw, out solutionFilename)) { // TryGetAbsoluteSolutionPath should throw before we get here. solutionFilename = string.Empty; projectFilter = ImmutableHashSet <string> .Empty; return(false); } if (!File.Exists(solutionFilename)) { projectFilter = ImmutableHashSet <string> .Empty; return(false); } // The base directory for projects is the solution folder. baseDirectory = Path.GetDirectoryName(solutionFilename) !; RoslynDebug.AssertNotNull(baseDirectory); var filterProjects = ImmutableHashSet.CreateBuilder <string>(StringComparer.OrdinalIgnoreCase); foreach (var project in solution.GetProperty("projects").EnumerateArray()) { // Convert directory separators to the platform's default, since that is what MSBuild provide us. var projectPath = project.GetString()?.Replace('\\', Path.DirectorySeparatorChar); if (projectPath is null) { continue; } // Fill the filter with the absolute project paths. if (pathResolver.TryGetAbsoluteProjectPath(projectPath, baseDirectory, DiagnosticReportingMode.Throw, out var absoluteProjectPath)) { filterProjects.Add(absoluteProjectPath); } } projectFilter = filterProjects.ToImmutable(); return(true); } catch { solutionFilename = string.Empty; projectFilter = ImmutableHashSet <string> .Empty; return(false); } }
public static bool TryRead(string filterFilename, PathResolver pathResolver, out string solutionFilename, out ImmutableHashSet <string> projectFilter) { try { using var document = JsonDocument.Parse(File.ReadAllText(filterFilename)); var solution = document.RootElement.GetProperty("solution"); var solutionPath = solution.GetProperty("path").GetString(); if (!pathResolver.TryGetAbsoluteSolutionPath(solutionPath, baseDirectory: Path.GetDirectoryName(filterFilename), DiagnosticReportingMode.Throw, out solutionFilename)) { // TryGetAbsoluteSolutionPath should throw before we get here. solutionFilename = string.Empty; projectFilter = ImmutableHashSet <string> .Empty; return(false); } if (!File.Exists(solutionFilename)) { projectFilter = ImmutableHashSet <string> .Empty; return(false); } var filterProjects = ImmutableHashSet.CreateBuilder <string>(StringComparer.OrdinalIgnoreCase); foreach (var project in solution.GetProperty("projects").EnumerateArray()) { var projectPath = project.GetString(); if (projectPath is null) { continue; } filterProjects.Add(projectPath); } projectFilter = filterProjects.ToImmutable(); return(true); } catch { solutionFilename = string.Empty; projectFilter = ImmutableHashSet <string> .Empty; return(false); } }
/// <summary> /// Loads the <see cref="SolutionInfo"/> for the specified solution file, including all projects referenced by the solution file and /// all the projects referenced by the project files. /// </summary> /// <param name="solutionFilePath">The path to the solution file to be loaded. This may be an absolute path or a path relative to the /// current working directory.</param> /// <param name="progress">An optional <see cref="IProgress{T}"/> that will receive updates as the solution is loaded.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> to allow cancellation of this operation.</param> public async Task <SolutionInfo> LoadSolutionInfoAsync( string solutionFilePath, IProgress <ProjectLoadProgress> progress = null, CancellationToken cancellationToken = default) { if (solutionFilePath == null) { throw new ArgumentNullException(nameof(solutionFilePath)); } if (!_pathResolver.TryGetAbsoluteSolutionPath(solutionFilePath, baseDirectory: Directory.GetCurrentDirectory(), DiagnosticReportingMode.Throw, out var absoluteSolutionPath)) { // TryGetAbsoluteSolutionPath should throw before we get here. return(null); } using (_dataGuard.DisposableWait(cancellationToken)) { this.SetSolutionProperties(absoluteSolutionPath); } var solutionFile = MSB.Construction.SolutionFile.Parse(absoluteSolutionPath); var reportingMode = GetReportingModeForUnrecognizedProjects(); var reportingOptions = new DiagnosticReportingOptions( onPathFailure: reportingMode, onLoaderFailure: reportingMode); var projectPaths = ImmutableArray.CreateBuilder <string>(); // load all the projects foreach (var project in solutionFile.ProjectsInOrder) { cancellationToken.ThrowIfCancellationRequested(); if (project.ProjectType != MSB.Construction.SolutionProjectType.SolutionFolder) { projectPaths.Add(project.RelativePath); } } var buildManager = new ProjectBuildManager(_properties); var worker = new Worker( _workspaceServices, _diagnosticReporter, _pathResolver, _projectFileLoaderRegistry, buildManager, projectPaths.ToImmutable(), baseDirectory: Path.GetDirectoryName(absoluteSolutionPath), _properties, projectMap: null, progress, requestedProjectOptions: reportingOptions, discoveredProjectOptions: reportingOptions, preferMetadataForReferencesOfDiscoveredProjects: false); var projects = await worker.LoadAsync(cancellationToken).ConfigureAwait(false); // construct workspace from loaded project infos return(SolutionInfo.Create( SolutionId.CreateNewId(debugName: absoluteSolutionPath), version: default,