Skip to content

Commit

Permalink
Merge pull request #1161 from filipw/feature/globbing
Browse files Browse the repository at this point in the history
Added support for excluding search paths via globbing patterns
  • Loading branch information
david-driscoll authored Apr 24, 2018
2 parents f504b8e + 4f6b865 commit c53f211
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 7 deletions.
42 changes: 42 additions & 0 deletions src/OmniSharp.Abstractions/FileSystem/FileSystemHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Collections.Generic;
using System.Composition;
using System.Linq;
using Microsoft.Extensions.FileSystemGlobbing;
using OmniSharp.Options;

namespace OmniSharp.FileSystem
{
[Export, Shared]
public class FileSystemHelper
{
private readonly OmniSharpOptions _omniSharpOptions;
private readonly IOmniSharpEnvironment _omniSharpEnvironment;

[ImportingConstructor]
public FileSystemHelper(OmniSharpOptions omniSharpOptions, IOmniSharpEnvironment omniSharpEnvironment)
{
_omniSharpOptions = omniSharpOptions;
_omniSharpEnvironment = omniSharpEnvironment;
}

public IEnumerable<string> GetFiles(string includePattern) => GetFiles(includePattern, _omniSharpEnvironment.TargetDirectory);

public IEnumerable<string> GetFiles(string includePattern, string targetDirectory)
{
var matcher = new Matcher();
matcher.AddInclude(includePattern);

if (_omniSharpOptions.FileOptions.SystemExcludeSearchPatterns != null && _omniSharpOptions.FileOptions.SystemExcludeSearchPatterns.Any())
{
matcher.AddExcludePatterns(_omniSharpOptions.FileOptions.SystemExcludeSearchPatterns);
}

if (_omniSharpOptions.FileOptions.ExcludeSearchPatterns != null && _omniSharpOptions.FileOptions.ExcludeSearchPatterns.Any())
{
matcher.AddExcludePatterns(_omniSharpOptions.FileOptions.ExcludeSearchPatterns);
}

return matcher.GetResultsInFullPath(targetDirectory);
}
}
}
11 changes: 11 additions & 0 deletions src/OmniSharp.Abstractions/Options/FileOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace OmniSharp.Options
{
public class FileOptions
{
public string[] SystemExcludeSearchPatterns { get; set; } = new[] { "**/node_modules/**/*", "**/bin/**/*", "**/obj/**/*", "**/.git/**/*" };

public string[] ExcludeSearchPatterns { get; set; } = Array.Empty<string>();
}
}
2 changes: 2 additions & 0 deletions src/OmniSharp.Abstractions/Options/OmniSharpOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ public class OmniSharpOptions
public RoslynExtensionsOptions RoslynExtensionsOptions { get; } = new RoslynExtensionsOptions();

public FormattingOptions FormattingOptions { get; } = new FormattingOptions();

public FileOptions FileOptions { get; } = new FileOptions();
}
}
8 changes: 5 additions & 3 deletions src/OmniSharp.Cake/CakeProjectSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@
using Microsoft.CodeAnalysis.Scripting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using OmniSharp.Cake.Configuration;
using OmniSharp.Cake.Services;
using OmniSharp.FileSystem;
using OmniSharp.FileWatching;
using OmniSharp.Helpers;
using OmniSharp.Models.UpdateBuffer;
using OmniSharp.Models.WorkspaceInformation;
using OmniSharp.Roslyn.Utilities;
using OmniSharp.Services;
Expand All @@ -32,6 +31,7 @@ public class CakeProjectSystem : IProjectSystem
private readonly IAssemblyLoader _assemblyLoader;
private readonly ICakeScriptService _scriptService;
private readonly IFileSystemWatcher _fileSystemWatcher;
private readonly FileSystemHelper _fileSystemHelper;
private readonly ILogger<CakeProjectSystem> _logger;
private readonly ConcurrentDictionary<string, ProjectInfo> _projects;
private readonly Lazy<CSharpCompilationOptions> _compilationOptions;
Expand All @@ -50,6 +50,7 @@ public CakeProjectSystem(
IAssemblyLoader assemblyLoader,
ICakeScriptService scriptService,
IFileSystemWatcher fileSystemWatcher,
FileSystemHelper fileSystemHelper,
ILoggerFactory loggerFactory)
{
_workspace = workspace ?? throw new ArgumentNullException(nameof(workspace));
Expand All @@ -58,6 +59,7 @@ public CakeProjectSystem(
_assemblyLoader = assemblyLoader ?? throw new ArgumentNullException(nameof(assemblyLoader));
_scriptService = scriptService ?? throw new ArgumentNullException(nameof(scriptService));
_fileSystemWatcher = fileSystemWatcher ?? throw new ArgumentNullException(nameof(fileSystemWatcher));
_fileSystemHelper = fileSystemHelper;
_logger = loggerFactory?.CreateLogger<CakeProjectSystem>() ?? throw new ArgumentNullException(nameof(loggerFactory));

_projects = new ConcurrentDictionary<string, ProjectInfo>();
Expand All @@ -72,7 +74,7 @@ public void Initalize(IConfiguration configuration)
_logger.LogInformation($"Detecting Cake files in '{_environment.TargetDirectory}'.");

// Nothing to do if there are no Cake files
var allCakeFiles = Directory.GetFiles(_environment.TargetDirectory, "*.cake", SearchOption.AllDirectories);
var allCakeFiles = _fileSystemHelper.GetFiles("**/*.cake").ToArray();
if (allCakeFiles.Length == 0)
{
_logger.LogInformation("Could not find any Cake files");
Expand Down
6 changes: 5 additions & 1 deletion src/OmniSharp.MSBuild/ProjectSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using OmniSharp.Eventing;
using OmniSharp.FileSystem;
using OmniSharp.FileWatching;
using OmniSharp.Models.WorkspaceInformation;
using OmniSharp.MSBuild.Discovery;
Expand All @@ -30,6 +31,7 @@ public class ProjectSystem : IProjectSystem
private readonly MetadataFileReferenceCache _metadataFileReferenceCache;
private readonly IEventEmitter _eventEmitter;
private readonly IFileSystemWatcher _fileSystemWatcher;
private readonly FileSystemHelper _fileSystemHelper;
private readonly ILoggerFactory _loggerFactory;
private readonly ILogger _logger;

Expand All @@ -56,6 +58,7 @@ public ProjectSystem(
MetadataFileReferenceCache metadataFileReferenceCache,
IEventEmitter eventEmitter,
IFileSystemWatcher fileSystemWatcher,
FileSystemHelper fileSystemHelper,
ILoggerFactory loggerFactory)
{
_environment = environment;
Expand All @@ -66,6 +69,7 @@ public ProjectSystem(
_metadataFileReferenceCache = metadataFileReferenceCache;
_eventEmitter = eventEmitter;
_fileSystemWatcher = fileSystemWatcher;
_fileSystemHelper = fileSystemHelper;
_loggerFactory = loggerFactory;

_projectsToProcess = new Queue<ProjectFileInfo>();
Expand Down Expand Up @@ -121,7 +125,7 @@ private IEnumerable<string> GetInitialProjectPaths()
// Finally, if there isn't a single solution immediately available,
// Just process all of the projects beneath the root path.
_solutionFileOrRootPath = _environment.TargetDirectory;
return Directory.GetFiles(_environment.TargetDirectory, "*.csproj", SearchOption.AllDirectories);
return _fileSystemHelper.GetFiles("**/*.csproj");
}

private IEnumerable<string> GetProjectPathsFromSolution(string solutionFilePath)
Expand Down
8 changes: 5 additions & 3 deletions src/OmniSharp.Script/ScriptProjectSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.Logging;
using OmniSharp.FileSystem;
using OmniSharp.FileWatching;
using OmniSharp.Models.WorkspaceInformation;
using OmniSharp.Services;
Expand All @@ -36,7 +37,7 @@ public class ScriptProjectSystem : IProjectSystem
private readonly IOmniSharpEnvironment _env;
private readonly ILogger _logger;
private readonly IFileSystemWatcher _fileSystemWatcher;

private readonly FileSystemHelper _fileSystemHelper;
private readonly CompilationDependencyResolver _compilationDependencyResolver;

private ScriptOptions _scriptOptions;
Expand All @@ -45,12 +46,13 @@ public class ScriptProjectSystem : IProjectSystem

[ImportingConstructor]
public ScriptProjectSystem(OmniSharpWorkspace workspace, IOmniSharpEnvironment env, ILoggerFactory loggerFactory,
MetadataFileReferenceCache metadataFileReferenceCache, IFileSystemWatcher fileSystemWatcher)
MetadataFileReferenceCache metadataFileReferenceCache, IFileSystemWatcher fileSystemWatcher, FileSystemHelper fileSystemHelper)
{
_metadataFileReferenceCache = metadataFileReferenceCache;
_workspace = workspace;
_env = env;
_fileSystemWatcher = fileSystemWatcher;
_fileSystemHelper = fileSystemHelper;
_logger = loggerFactory.CreateLogger<ScriptProjectSystem>();
_projects = new ConcurrentDictionary<string, ProjectInfo>();

Expand Down Expand Up @@ -86,7 +88,7 @@ public void Initalize(IConfiguration configuration)
_logger.LogInformation($"Detecting CSX files in '{_env.TargetDirectory}'.");

// Nothing to do if there are no CSX files
var allCsxFiles = Directory.GetFiles(_env.TargetDirectory, "*.csx", SearchOption.AllDirectories);
var allCsxFiles = _fileSystemHelper.GetFiles("**/*.csx").ToArray();
if (allCsxFiles.Length == 0)
{
_logger.LogInformation("Could not find any CSX files");
Expand Down
114 changes: 114 additions & 0 deletions tests/OmniSharp.Tests/FileSystemHelperFacts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using Microsoft.Extensions.Logging;
using OmniSharp.FileSystem;
using OmniSharp.Options;
using OmniSharp.Services;
using System.Linq;
using TestUtility;
using Xunit;

namespace OmniSharp.Tests
{
public class FileSystemHelperFacts
{
[Fact]
public void FileSystemHelperFacts_CanExcludeSearchPath_File()
{
var helper = CreateFileSystemHelper("**/ProjectWithSdkProperty.csproj");

var msbuildProjectFiles = helper.GetFiles("**/*.csproj");
Assert.NotEmpty(msbuildProjectFiles);

var projectWithSdkProperty = msbuildProjectFiles.FirstOrDefault(p => p.Contains("ProjectWithSdkProperty"));
Assert.Null(projectWithSdkProperty);
}

[Fact]
public void FileSystemHelperFacts_CanExcludeSearchPath_MultipleFiles()
{
var helper = CreateFileSystemHelper("**/MSTestProject.csproj", "**/NUnitTestProject.csproj");

var msbuildProjectFiles = helper.GetFiles("**/*.csproj");
Assert.NotEmpty(msbuildProjectFiles);

var msTestProject = msbuildProjectFiles.FirstOrDefault(p => p.Contains("MSTestProject"));
Assert.Null(msTestProject);

var nunitTestProject = msbuildProjectFiles.FirstOrDefault(p => p.Contains("NUnitTestProject"));
Assert.Null(nunitTestProject);
}

[Fact]
public void FileSystemHelperFacts_CanExcludeSearchPath_Folder()
{
var helper = CreateFileSystemHelper("**/ProjectWithSdkProperty/**/*");

var msbuildProjectFiles = helper.GetFiles("**/*.csproj");
Assert.NotEmpty(msbuildProjectFiles);

var projectWithSdkProperty = msbuildProjectFiles.FirstOrDefault(p => p.Contains("ProjectWithSdkProperty"));
Assert.Null(projectWithSdkProperty);
}

[Fact]
public void FileSystemHelperFacts_CanExcludeSearchPath_MultipleFolders()
{
var helper = CreateFileSystemHelper("**/MSTestProject/**/*", "**/NUnitTestProject/**/*");

var msbuildProjectFiles = helper.GetFiles("**/*.csproj");
Assert.NotEmpty(msbuildProjectFiles);

var msTestProject = msbuildProjectFiles.FirstOrDefault(p => p.Contains("MSTestProject"));
Assert.Null(msTestProject);

var nunitTestProject = msbuildProjectFiles.FirstOrDefault(p => p.Contains("NUnitTestProject"));
Assert.Null(nunitTestProject);
}

[Fact]
public void FileSystemHelperFacts_CanExcludeSearchPath_MultipleFolders_BothSystemAndUserPaths()
{
var helper = CreateFileSystemHelper(new[] { "**/MSTestProject/**/*", "**/NUnitTestProject/**/*" }, systemExcludePatterns: new[] { "**/ProjectWithSdkProperty/**/*" });

var msbuildProjectFiles = helper.GetFiles("**/*.csproj");
Assert.NotEmpty(msbuildProjectFiles);

var msTestProject = msbuildProjectFiles.FirstOrDefault(p => p.Contains("MSTestProject"));
Assert.Null(msTestProject);

var nunitTestProject = msbuildProjectFiles.FirstOrDefault(p => p.Contains("NUnitTestProject"));
Assert.Null(nunitTestProject);

var projectWithSdkProperty = msbuildProjectFiles.FirstOrDefault(p => p.Contains("ProjectWithSdkProperty"));
Assert.Null(projectWithSdkProperty);
}

[Fact]
public void FileSystemHelperFacts_CanHandleInvalidPath()
{
var helper = CreateFileSystemHelper("!@@#$$@%&&*()_+");

var ex = Record.Exception(() => helper.GetFiles("**/*.csproj"));
Assert.Null(ex);
}

private FileSystemHelper CreateFileSystemHelper(params string[] excludePatterns)
{
var environment = new OmniSharpEnvironment(TestAssets.Instance.TestAssetsFolder, 1000, LogLevel.Information, null);
var options = new OmniSharpOptions();
options.FileOptions.ExcludeSearchPatterns = excludePatterns;
var helper = new FileSystemHelper(options, environment);
return helper;
}

private FileSystemHelper CreateFileSystemHelper(string[] excludePatterns, string[] systemExcludePatterns)
{
var environment = new OmniSharpEnvironment(TestAssets.Instance.TestAssetsFolder, 1000, LogLevel.Information, null);
var options = new OmniSharpOptions();
options.FileOptions.ExcludeSearchPatterns = excludePatterns;
options.FileOptions.SystemExcludeSearchPatterns = systemExcludePatterns;

var helper = new FileSystemHelper(options, environment);
return helper;
}
}
}

0 comments on commit c53f211

Please sign in to comment.