-
Notifications
You must be signed in to change notification settings - Fork 418
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
Fix project.json search in DotNetProjectSystem #673
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,86 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using Microsoft.DotNet.ProjectModel; | ||
|
||
namespace OmniSharp.DotNet.Projects | ||
{ | ||
public class ProjectSearcher | ||
{ | ||
public static IEnumerable<string> Search(string solutionRoot) | ||
public static IEnumerable<string> Search(string directory) | ||
{ | ||
return Search(solutionRoot, maxDepth: 5); | ||
return Search(directory, maxDepth: 5); | ||
} | ||
|
||
public static IEnumerable<string> Search(string solutionRoot, int maxDepth) | ||
public static IEnumerable<string> Search(string directory, int maxDepth) | ||
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. Note that this function was inconsistent before my changes. Sometimes it would return a directory path to a project.json files, and sometimes it would return multiple file paths to project.json files. Now, it just returns file paths to project.json files. |
||
{ | ||
var dir = new DirectoryInfo(solutionRoot); | ||
if (!dir.Exists) | ||
if (!Directory.Exists(directory)) | ||
{ | ||
return Enumerable.Empty<string>(); | ||
return Array.Empty<string>(); | ||
} | ||
|
||
if (File.Exists(Path.Combine(solutionRoot, Project.FileName))) | ||
// Is there a project.json file in this directory? If so, return it. | ||
var projectFilePath = Path.Combine(directory, Project.FileName); | ||
if (File.Exists(projectFilePath)) | ||
{ | ||
return new string[] { solutionRoot }; | ||
return new string[] { projectFilePath }; | ||
} | ||
else if (File.Exists(Path.Combine(solutionRoot, GlobalSettings.FileName))) | ||
|
||
// Is there a global.json file in this directory? If so, use that to search. | ||
if (File.Exists(Path.Combine(directory, GlobalSettings.FileName))) | ||
{ | ||
return FindProjectsThroughGlobalJson(solutionRoot); | ||
return FindProjectsThroughGlobalJson(directory); | ||
} | ||
else | ||
|
||
// Otherwise, perform a general search through the file system. | ||
return FindProjects(directory, maxDepth); | ||
} | ||
|
||
// TODO: Replace with proper tuple when we move to C# 7 | ||
private struct DirectoryAndDepth | ||
{ | ||
public readonly string Directory; | ||
public readonly int Depth; | ||
|
||
private DirectoryAndDepth(string directory, int depth) | ||
{ | ||
return FindProjects(solutionRoot, maxDepth); | ||
this.Directory = directory; | ||
this.Depth = depth; | ||
} | ||
|
||
public static DirectoryAndDepth Create(string directory, int depth) | ||
=> new DirectoryAndDepth(directory, depth); | ||
} | ||
|
||
private static IEnumerable<string> FindProjects(string root, int maxDepth) | ||
private static IEnumerable<string> FindProjects(string rootDirectory, int maxDepth) | ||
{ | ||
var result = new List<string>(); | ||
var stack = new Stack<Tuple<DirectoryInfo, int>>(); | ||
var result = new SortedSet<string>(StringComparer.OrdinalIgnoreCase); | ||
var stack = new Stack<DirectoryAndDepth>(); | ||
|
||
stack.Push(Tuple.Create(new DirectoryInfo(root), 0)); | ||
stack.Push(DirectoryAndDepth.Create(rootDirectory, 0)); | ||
|
||
while (stack.Any()) | ||
while (stack.Count > 0) | ||
{ | ||
var next = stack.Pop(); | ||
var currentFolder = next.Item1; | ||
var depth = next.Item2; | ||
var current = stack.Pop(); | ||
|
||
if (!currentFolder.Exists) | ||
if (!Directory.Exists(current.Directory)) | ||
{ | ||
continue; | ||
} | ||
else if (currentFolder.GetFiles(Project.FileName).Any()) | ||
|
||
// Did we find a project.json? | ||
var projectFilePath = Path.Combine(current.Directory, Project.FileName); | ||
if (File.Exists(projectFilePath)) | ||
{ | ||
result.Add(Path.Combine(currentFolder.FullName, Project.FileName)); | ||
result.Add(projectFilePath); | ||
} | ||
else if (depth < maxDepth) | ||
|
||
// If we're not already at maximum depth, go ahead and search child directories. | ||
if (current.Depth < maxDepth) | ||
{ | ||
foreach (var sub in currentFolder.GetDirectories()) | ||
foreach (var childDirectory in Directory.GetDirectories(current.Directory)) | ||
{ | ||
stack.Push(Tuple.Create(sub, depth + 1)); | ||
stack.Push(DirectoryAndDepth.Create(childDirectory, current.Depth + 1)); | ||
} | ||
} | ||
} | ||
|
@@ -73,19 +93,38 @@ private static IEnumerable<string> FindProjectsThroughGlobalJson(string root) | |
GlobalSettings globalSettings; | ||
if (GlobalSettings.TryGetGlobalSettings(root, out globalSettings)) | ||
{ | ||
return globalSettings.ProjectSearchPaths | ||
.Select(searchPath => Path.Combine(globalSettings.DirectoryPath, searchPath)) | ||
.Where(actualPath => Directory.Exists(actualPath)) | ||
.SelectMany(actualPath => Directory.GetDirectories(actualPath)) | ||
.Where(actualPath => File.Exists(Path.Combine(actualPath, Project.FileName))) | ||
.Select(path => Path.GetFullPath(path)) | ||
.Distinct(StringComparer.OrdinalIgnoreCase) | ||
.ToList(); | ||
} | ||
else | ||
{ | ||
return Enumerable.Empty<string>(); | ||
var projectPaths = new SortedSet<string>(StringComparer.OrdinalIgnoreCase); | ||
var searchDirectories = new Queue<string>(); | ||
|
||
// Look in global.json 'projects' search paths and their immediate children | ||
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. For my sanity (because project.json is starting to fade with csproj out soon 😜).
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. Were you looking for a change here? |
||
foreach (var searchPath in globalSettings.ProjectSearchPaths) | ||
{ | ||
var searchDirectory = Path.Combine(globalSettings.DirectoryPath, searchPath); | ||
if (Directory.Exists(searchDirectory)) | ||
{ | ||
searchDirectories.Enqueue(searchDirectory); | ||
|
||
foreach (var childDirectory in Directory.GetDirectories(searchDirectory)) | ||
{ | ||
searchDirectories.Enqueue(childDirectory); | ||
} | ||
} | ||
} | ||
|
||
while (searchDirectories.Count > 0) | ||
{ | ||
var searchDirectory = searchDirectories.Dequeue(); | ||
var projectFilePath = Path.Combine(searchDirectory, Project.FileName); | ||
if (File.Exists(projectFilePath)) | ||
{ | ||
projectPaths.Add(Path.GetFullPath(projectFilePath)); | ||
} | ||
} | ||
|
||
return projectPaths; | ||
} | ||
|
||
return Array.Empty<string>(); | ||
} | ||
} | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol