diff --git a/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs b/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs index 341a636a..7e30207e 100644 --- a/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs +++ b/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs @@ -11,6 +11,7 @@ namespace RepoM.Api.Git; using RepoM.Api.Git.AutoFetch; using RepoM.Api.IO; using RepoM.Core.Plugin.Repository; +using RepoM.Core.Plugin.RepositoryFinder; public class DefaultRepositoryMonitor : IRepositoryMonitor { @@ -55,11 +56,11 @@ public DefaultRepositoryMonitor( _pathProvider = pathProvider ?? throw new ArgumentNullException(nameof(pathProvider)); _repositoryStore = repositoryStore ?? throw new ArgumentNullException(nameof(repositoryStore)); _repositoryInformationAggregator = repositoryInformationAggregator ?? throw new ArgumentNullException(nameof(repositoryInformationAggregator)); - _repositoryObservers = new Dictionary(); - _repositoryIgnoreStore = repositoryIgnoreStore; + _repositoryIgnoreStore = repositoryIgnoreStore ?? throw new ArgumentNullException(nameof(repositoryIgnoreStore)); _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _autoFetchHandler = autoFetchHandler ?? throw new ArgumentNullException(nameof(autoFetchHandler)); + _repositoryObservers = new Dictionary(); _storeFlushTimer = new Timer(RepositoryStoreFlushTimerCallback, null, Timeout.Infinite, Timeout.Infinite); } @@ -72,8 +73,9 @@ public Task ScanForLocalRepositoriesAsync() var scannedPaths = 0; var paths = _pathProvider.GetPaths(); + IGitRepositoryFinder gitRepositoryFinder = _gitRepositoryFinderFactory.Create(); - IEnumerable tasks = paths.Select(path => Task.Run(() => _gitRepositoryFinderFactory.Create().Find(path, OnFoundNewRepository)) + IEnumerable tasks = paths.Select(path => Task.Run(() => gitRepositoryFinder.Find(path, OnFoundNewRepository)) .ContinueWith(_ => { if (Interlocked.Increment(ref scannedPaths) != paths.Length) diff --git a/src/RepoM.Plugin.EverythingFileSearch/Internal/Everything64Api.cs b/src/RepoM.Plugin.EverythingFileSearch/Internal/Everything64Api.cs index a7a4688c..00186a91 100644 --- a/src/RepoM.Plugin.EverythingFileSearch/Internal/Everything64Api.cs +++ b/src/RepoM.Plugin.EverythingFileSearch/Internal/Everything64Api.cs @@ -8,36 +8,37 @@ namespace RepoM.Plugin.EverythingFileSearch.Internal; /// Wrapper for Everything. /// See for the SDK. -internal static class Everything64Api +internal static partial class Everything64Api { private static readonly object _lock = new(); private const int EVERYTHING_REQUEST_FILE_NAME = 0x00000001; private const int EVERYTHING_REQUEST_PATH = 0x00000002; - [DllImport("Everything64.dll", CharSet = CharSet.Unicode)] - public static extern void Everything_SetSearch(string lpSearchString); + [LibraryImport("Everything64.dll", EntryPoint = "Everything_SetSearchW", StringMarshalling = StringMarshalling.Utf16)] + private static partial void Everything_SetSearch(string lpSearchString); - [DllImport("Everything64.dll")] - public static extern void Everything_SetMatchCase(bool bEnable); + [LibraryImport("Everything64.dll", EntryPoint = "Everything_SetMatchCase")] + private static partial void Everything_SetMatchCase([MarshalAs(UnmanagedType.Bool)] bool bEnable); - [DllImport("Everything64.dll", CharSet = CharSet.Unicode)] - public static extern bool Everything_Query(bool bWait); + [LibraryImport("Everything64.dll", EntryPoint = "Everything_QueryW")] + [return: MarshalAs(UnmanagedType.Bool)] + private static partial bool Everything_Query([MarshalAs(UnmanagedType.Bool)] bool bWait); - [DllImport("Everything64.dll")] - public static extern uint Everything_GetNumResults(); + [LibraryImport("Everything64.dll", EntryPoint = "Everything_GetNumResults")] + private static partial uint Everything_GetNumResults(); [DllImport("Everything64.dll", CharSet = CharSet.Unicode)] - public static extern void Everything_GetResultFullPathName(uint nIndex, StringBuilder lpString, uint nMaxCount); + private static extern void Everything_GetResultFullPathName(uint nIndex, StringBuilder lpString, uint nMaxCount); - [DllImport("Everything64.dll")] - public static extern void Everything_CleanUp(); + [LibraryImport("Everything64.dll", EntryPoint = "Everything_CleanUp")] + private static partial void Everything_CleanUp(); - [DllImport("Everything64.dll")] - public static extern uint Everything_GetMajorVersion(); + [LibraryImport("Everything64.dll", EntryPoint = "Everything_GetMajorVersion")] + private static partial uint Everything_GetMajorVersion(); // Everything 1.4 - [DllImport("Everything64.dll")] - public static extern void Everything_SetRequestFlags(uint dwRequestFlags); + [LibraryImport("Everything64.dll", EntryPoint = "Everything_SetRequestFlags")] + private static partial void Everything_SetRequestFlags(uint dwRequestFlags); public static IEnumerable Search(string query) { @@ -88,8 +89,7 @@ public static bool IsInstalled() { try { - Everything_GetMajorVersion(); - return true; + return Everything_GetMajorVersion() > 0; } catch (Exception) { diff --git a/src/RepoM.Plugin.EverythingFileSearch/RepoM.Plugin.EverythingFileSearch.csproj b/src/RepoM.Plugin.EverythingFileSearch/RepoM.Plugin.EverythingFileSearch.csproj index d7c3e13d..26b1d509 100644 --- a/src/RepoM.Plugin.EverythingFileSearch/RepoM.Plugin.EverythingFileSearch.csproj +++ b/src/RepoM.Plugin.EverythingFileSearch/RepoM.Plugin.EverythingFileSearch.csproj @@ -2,6 +2,7 @@ net7.0 + true diff --git a/tests/RepoM.Api.Tests/Git/DefaultRepositoryMonitorTests.cs b/tests/RepoM.Api.Tests/Git/DefaultRepositoryMonitorTests.cs new file mode 100644 index 00000000..e3978125 --- /dev/null +++ b/tests/RepoM.Api.Tests/Git/DefaultRepositoryMonitorTests.cs @@ -0,0 +1,73 @@ +namespace RepoM.Api.Tests.Git; + +using System; +using System.IO.Abstractions; +using System.Linq; +using System.Reflection; +using FakeItEasy; +using FluentAssertions; +using Microsoft.Extensions.Logging; +using RepoM.Api.Git; +using RepoM.Api.Git.AutoFetch; +using RepoM.Api.IO; +using Xunit; + +public class DefaultRepositoryMonitorTests +{ + [Fact] + public void Ctor_ShouldThrow_WhenArgumentNull() + { + // arrange + IPathProvider pathProvider = A.Dummy(); + IRepositoryReader repositoryReader = A.Dummy(); + IRepositoryDetectorFactory repositoryDetectorFactory = A.Dummy(); + IRepositoryObserverFactory repositoryObserverFactory = A.Dummy(); + IGitRepositoryFinderFactory gitRepositoryFinderFactory = A.Dummy(); + IRepositoryStore repositoryStore = A.Dummy(); + IRepositoryInformationAggregator repositoryInformationAggregator = A.Dummy(); + IAutoFetchHandler autoFetchHandler = A.Dummy(); + IRepositoryIgnoreStore repositoryIgnoreStore = A.Dummy(); + IFileSystem fileSystem = A.Dummy(); + ILogger logger = A.Dummy(); + + ConstructorInfo ctor = typeof(DefaultRepositoryMonitor).GetConstructors().Single(); + + var parameters = new object[] + { + pathProvider, + repositoryReader, + repositoryDetectorFactory, + repositoryObserverFactory, + gitRepositoryFinderFactory, + repositoryStore, + repositoryInformationAggregator, + autoFetchHandler, + repositoryIgnoreStore, + fileSystem, + logger, + }; + + var result = ctor.Invoke(parameters) as DefaultRepositoryMonitor; + result.Should().NotBeNull(); + + // act + for (int i = 0; i < parameters.Length; i++) + { + parameters[i] = null!; + Action act = () => + { + try + { + ctor.Invoke(parameters); + } + catch (TargetInvocationException e) + { + throw e.InnerException ?? e; + } + }; + + // assert + act.Should().Throw(); + } + } +} \ No newline at end of file