diff --git a/src/Grr.App/Grr.App.csproj b/src/Grr.App/Grr.App.csproj index da66753c..9175184f 100644 --- a/src/Grr.App/Grr.App.csproj +++ b/src/Grr.App/Grr.App.csproj @@ -12,6 +12,7 @@ + diff --git a/src/GrrUi.App/GrrUi.App.csproj b/src/GrrUi.App/GrrUi.App.csproj index 700fb0c5..3b0cdf68 100644 --- a/src/GrrUi.App/GrrUi.App.csproj +++ b/src/GrrUi.App/GrrUi.App.csproj @@ -11,6 +11,7 @@ + diff --git a/src/RepoM.Api/Common/HardcodededMiniHumanizer.cs b/src/RepoM.Api/Common/HardcodededMiniHumanizer.cs index 0fced3af..ac358df1 100644 --- a/src/RepoM.Api/Common/HardcodededMiniHumanizer.cs +++ b/src/RepoM.Api/Common/HardcodededMiniHumanizer.cs @@ -7,7 +7,9 @@ public class HardcodededMiniHumanizer : IHumanizer private readonly IClock _clock; public HardcodededMiniHumanizer() - : this(new SystemClock()) { } + : this(new SystemClock()) + { + } public HardcodededMiniHumanizer(IClock clock) { diff --git a/src/RepoM.Api/Git/DefaultRepositoryIgnoreStore.cs b/src/RepoM.Api/Git/DefaultRepositoryIgnoreStore.cs index 207efe49..303659cb 100644 --- a/src/RepoM.Api/Git/DefaultRepositoryIgnoreStore.cs +++ b/src/RepoM.Api/Git/DefaultRepositoryIgnoreStore.cs @@ -5,7 +5,6 @@ namespace RepoM.Api.Git; using System.IO; using System.IO.Abstractions; using System.Linq; -using RepoM.Api.Common; using RepoM.Api.IO; public class DefaultRepositoryIgnoreStore : FileRepositoryStore, IRepositoryIgnoreStore @@ -20,8 +19,8 @@ public DefaultRepositoryIgnoreStore( IFileSystem fileSystem) : base(fileSystem) { - AppDataPathProvider = appDataPathProvider ?? throw new ArgumentNullException(nameof(appDataPathProvider)); - _fullFilename = Path.Combine(AppDataPathProvider.GetAppDataPath(), "Repositories.ignore"); + _ = appDataPathProvider ?? throw new ArgumentNullException(nameof(appDataPathProvider)); + _fullFilename = Path.Combine(appDataPathProvider.GetAppDataPath(), "Repositories.ignore"); } public override string GetFileName() @@ -71,7 +70,7 @@ private List Ignores return _ignores; } - _ignores = Get()?.ToList() ?? new List(); + _ignores = Get().ToList(); UpdateRules(); } @@ -83,6 +82,4 @@ private void UpdateRules() { _rules = Ignores.Select(i => new IgnoreRule(i)); } - - public IAppDataPathProvider AppDataPathProvider { get; } } \ No newline at end of file diff --git a/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs b/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs index 7c5234cf..3ca4cf5d 100644 --- a/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs +++ b/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs @@ -51,10 +51,8 @@ public DefaultRepositoryMonitor( _repositoryObservers = new Dictionary(); _repositoryIgnoreStore = repositoryIgnoreStore; _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); - - _storeFlushTimer = new Timer(RepositoryStoreFlushTimerCallback, null, Timeout.Infinite, Timeout.Infinite); - _autoFetchHandler = autoFetchHandler ?? throw new ArgumentNullException(nameof(autoFetchHandler)); + _storeFlushTimer = new Timer(RepositoryStoreFlushTimerCallback, null, Timeout.Infinite, Timeout.Infinite); } public Task ScanForLocalRepositoriesAsync() diff --git a/src/RepoM.Api/Git/DefaultRepositoryReader.cs b/src/RepoM.Api/Git/DefaultRepositoryReader.cs index 8cc78084..b7c71e2e 100644 --- a/src/RepoM.Api/Git/DefaultRepositoryReader.cs +++ b/src/RepoM.Api/Git/DefaultRepositoryReader.cs @@ -4,15 +4,18 @@ namespace RepoM.Api.Git; using System.IO; using System.Linq; using LibGit2Sharp; +using Microsoft.Extensions.Logging; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider; public class DefaultRepositoryReader : IRepositoryReader { private readonly IRepositoryTagsFactory _resolver; + private readonly ILogger _logger; - public DefaultRepositoryReader(IRepositoryTagsFactory resolver) + public DefaultRepositoryReader(IRepositoryTagsFactory resolver, ILogger logger) { - _resolver = resolver; + _resolver = resolver ?? throw new ArgumentNullException(nameof(resolver)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public Git.Repository? ReadRepository(string path) @@ -26,6 +29,7 @@ public DefaultRepositoryReader(IRepositoryTagsFactory resolver) var repoPath = LibGit2Sharp.Repository.Discover(path); if (string.IsNullOrEmpty(repoPath)) { + _logger.LogWarning("Could not Discover git repo in path {path}", path); return null; // return Api.Git.Repository.Empty; } @@ -35,6 +39,11 @@ public DefaultRepositoryReader(IRepositoryTagsFactory resolver) { result.Tags = _resolver.GetTags(result).ToArray(); } + else + { + _logger.LogWarning("Could not read git repo in path {path}", repoPath); + } + return result; } @@ -51,14 +60,14 @@ public DefaultRepositoryReader(IRepositoryTagsFactory resolver) } catch (LockedFileException) { + _logger.LogWarning("LockedFileException {path}", repoPath); + if (currentTry >= maxRetries) { throw; } - else - { - System.Threading.Thread.Sleep(500); - } + + System.Threading.Thread.Sleep(500); } currentTry++; @@ -67,7 +76,7 @@ public DefaultRepositoryReader(IRepositoryTagsFactory resolver) return repository; } - private static Git.Repository? ReadRepositoryInternal(string repoPath) + private Git.Repository? ReadRepositoryInternal(string repoPath) { try { @@ -78,7 +87,7 @@ public DefaultRepositoryReader(IRepositoryTagsFactory resolver) HeadDetails headDetails = GetHeadDetails(repo); - var repository = new Git.Repository() + var repository = new Git.Repository { Name = workingDirectory.Name, Path = workingDirectory.FullName, @@ -114,8 +123,9 @@ public DefaultRepositoryReader(IRepositoryTagsFactory resolver) return repository; } - catch (Exception) + catch (Exception e) { + _logger.LogError(e, "Could not read (LibGit2Sharp) repo in {path}.", repoPath); return null; // return Api.Git.Repository.Empty; } diff --git a/src/RepoM.Api/Git/DefaultRepositoryStore.cs b/src/RepoM.Api/Git/DefaultRepositoryStore.cs index 95666417..3ae39a8f 100644 --- a/src/RepoM.Api/Git/DefaultRepositoryStore.cs +++ b/src/RepoM.Api/Git/DefaultRepositoryStore.cs @@ -3,7 +3,6 @@ namespace RepoM.Api.Git; using System; using System.IO; using System.IO.Abstractions; -using RepoM.Api.Common; using RepoM.Api.IO; public class DefaultRepositoryStore : FileRepositoryStore diff --git a/src/RepoM.Api/Git/FileRepositoryStore.cs b/src/RepoM.Api/Git/FileRepositoryStore.cs index c5728a5b..a55cf8eb 100644 --- a/src/RepoM.Api/Git/FileRepositoryStore.cs +++ b/src/RepoM.Api/Git/FileRepositoryStore.cs @@ -4,15 +4,14 @@ namespace RepoM.Api.Git; using System.Collections.Generic; using System.IO.Abstractions; using System.Linq; -using RepoM.Api.Common; public abstract class FileRepositoryStore : IRepositoryStore { - private protected readonly IFileSystem FileSystem; + private readonly IFileSystem _fileSystem; protected FileRepositoryStore(IFileSystem fileSystem) { - FileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); + _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); } public abstract string GetFileName(); @@ -24,11 +23,11 @@ public IEnumerable Get(string file) return Array.Empty(); } - if (FileSystem.File.Exists(file)) + if (_fileSystem.File.Exists(file)) { try { - return FileSystem.File.ReadAllLines(file); + return _fileSystem.File.ReadAllLines(file); } catch (Exception) { @@ -53,16 +52,16 @@ public void Set(IEnumerable paths) } var file = GetFileName(); - var path = FileSystem.Directory.GetParent(file).FullName; + var path = _fileSystem.Directory.GetParent(file).FullName; - if (!FileSystem.Directory.Exists(path)) + if (!_fileSystem.Directory.Exists(path)) { - FileSystem.Directory.CreateDirectory(path); + _fileSystem.Directory.CreateDirectory(path); } try { - FileSystem.File.WriteAllLines(GetFileName(), paths.ToArray()); + _fileSystem.File.WriteAllLines(GetFileName(), paths.ToArray()); } catch (Exception) { @@ -70,5 +69,6 @@ public void Set(IEnumerable paths) } } + // todo remove public bool UseFilePersistence { get; set; } = true; } \ No newline at end of file diff --git a/src/RepoM.Api/Git/Remote.cs b/src/RepoM.Api/Git/Remote.cs index 3fb4e2d6..c10ddaf9 100644 --- a/src/RepoM.Api/Git/Remote.cs +++ b/src/RepoM.Api/Git/Remote.cs @@ -3,7 +3,6 @@ namespace RepoM.Api.Git; using System; using System.Diagnostics; using System.IO; -using System.Xml.Linq; [DebuggerDisplay("{Key}/{Name}")] public class Remote diff --git a/src/RepoM.Api/Git/Repository.cs b/src/RepoM.Api/Git/Repository.cs index f182a9ea..bd7a0f38 100644 --- a/src/RepoM.Api/Git/Repository.cs +++ b/src/RepoM.Api/Git/Repository.cs @@ -34,8 +34,8 @@ public override bool Equals(object obj) private static string? Normalize(string path) { - // yeah not that beautiful but we have to add a blackslash - // or slash (depending on the OS) and on Mono, I dont have Path.PathSeparator. + // yeah not that beautiful but we have to add a backslash + // or slash (depending on the OS) and on Mono, I don't have Path.PathSeparator. // so we add a random char with Path.Combine() and remove it again path = System.IO.Path.Combine(path, "_"); path = path.Substring(0, path.Length - 1); diff --git a/src/RepoM.Api/IO/DefaultAppDataPathProvider.cs b/src/RepoM.Api/IO/DefaultAppDataPathProvider.cs index 907bef3e..62c5884e 100644 --- a/src/RepoM.Api/IO/DefaultAppDataPathProvider.cs +++ b/src/RepoM.Api/IO/DefaultAppDataPathProvider.cs @@ -4,14 +4,21 @@ namespace RepoM.Api.IO; using System.IO; public class DefaultAppDataPathProvider : IAppDataPathProvider -{ +{ private static readonly string _applicationDataRepoM = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "RepoM"); + private DefaultAppDataPathProvider() + { + } + + public static DefaultAppDataPathProvider Instance { get; } = new(); + public string GetAppDataPath() { return _applicationDataRepoM ; } + [Obsolete("Not used.")] public string GetAppResourcesPath() { return Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location); diff --git a/src/RepoM.Api/IO/DefaultRepositoryActionProvider.cs b/src/RepoM.Api/IO/DefaultRepositoryActionProvider.cs index 20b6f540..c265bcde 100644 --- a/src/RepoM.Api/IO/DefaultRepositoryActionProvider.cs +++ b/src/RepoM.Api/IO/DefaultRepositoryActionProvider.cs @@ -4,6 +4,7 @@ namespace RepoM.Api.IO; using System.Collections.Generic; using System.IO.Abstractions; using System.Linq; +using Microsoft.Extensions.Logging; using RepoM.Api.Git; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider; @@ -11,13 +12,16 @@ public class DefaultRepositoryActionProvider : IRepositoryActionProvider { private readonly IFileSystem _fileSystem; private readonly RepositorySpecificConfiguration _repoSpecificConfig; + private readonly ILogger _logger; public DefaultRepositoryActionProvider( IFileSystem fileSystem, - RepositorySpecificConfiguration repoSpecificConfig) + RepositorySpecificConfiguration repoSpecificConfig, + ILogger logger) { _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); _repoSpecificConfig = repoSpecificConfig ?? throw new ArgumentNullException(nameof(repoSpecificConfig)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public RepositoryActionBase? GetPrimaryAction(Repository repository) @@ -27,8 +31,8 @@ public DefaultRepositoryActionProvider( public RepositoryActionBase? GetSecondaryAction(Repository repository) { - IEnumerable actions = GetContextMenuActions(new[] { repository, }).Take(2); - return actions.Count() > 1 ? actions.ElementAt(1) : null; + RepositoryActionBase[] actions = GetContextMenuActions(new[] { repository, }).Take(2).ToArray(); + return actions.Length > 1 ? actions.ElementAt(1) : null; } public IEnumerable GetContextMenuActions(IEnumerable repositories) @@ -46,147 +50,8 @@ private IEnumerable GetContextMenuActionsInternal(IEnumera } catch (Exception ex) { - Console.WriteLine(ex.Message); + _logger.LogError(ex, "Could not create action menu."); throw; } } - - // //todo, remove - // private RepositoryAction CreateProcessRunnerAction(RepositoryActionConfiguration.RepositoryAction action, Repository repository) - // { - // var type = action.Type; - // var name = NameHelper.ReplaceTranslatables(NameHelper.ReplaceVariables(_translationService.Translate(action.Name), repository), _translationService); - // var command = NameHelper.ReplaceVariables(action.Command, repository); - // var executables = action.Executables.Select(e => NameHelper.ReplaceVariables(e, repository)); - // - // // var arguments = ReplaceVariables(action.Arguments, repository); - // var arguments = _expressionEvaluator.EvaluateStringExpression(action.Arguments, repository); - // - // if ("external commandline provider".Equals(type, StringComparison.CurrentCultureIgnoreCase)) - // { - // return new RepositoryAction() - // { - // Name = name, - // ExecutionCausesSynchronizing = true, - // DeferredSubActionsEnumerator = () => - // { - // try - // { - // var repomEnvFile = Path.Combine(repository.Path, ".git", "repom.env"); - // - // var psi = new ProcessStartInfo(command, arguments) - // { - // WorkingDirectory = new FileInfo(command).DirectoryName, - // CreateNoWindow = true, - // UseShellExecute = false, - // WindowStyle = ProcessWindowStyle.Hidden, - // RedirectStandardOutput = true, - // RedirectStandardError = true, - // }; - // - // if (_fileSystem.File.Exists(repomEnvFile)) - // { - // foreach (KeyValuePair item in DotNetEnv.Env.Load(repomEnvFile, new DotNetEnv.LoadOptions(setEnvVars: false))) - // { - // psi.EnvironmentVariables.Add(item.Key, item.Value); - // } - // } - // - // var proc = Process.Start(psi); - // if (proc == null) - // { - // return new RepositoryAction[] - // { - // new RepositoryAction() { Name = _translationService.Translate("Could not start process"), CanExecute = false, }, - // }; - // } - // else - // { - // proc.WaitForExit(7500); - // if (proc.HasExited) - // { - // if (proc.ExitCode == 0) - // { - // var json = proc.StandardOutput.ReadToEnd(); - // - // RepositoryActionConfiguration actionMenu = _repositoryActionConfigurationStore.LoadRepositoryActionConfigurationFromJson(json); - // if (actionMenu.State == RepositoryActionConfiguration.LoadState.Error) - // { - // return new RepositoryAction[] - // { - // new RepositoryAction() { Name = _translationService.Translate("Could not read repository actions"), CanExecute = false, }, - // }; - // } - // - // if (actionMenu.RepositoryActions.Count > 0) - // { - // return actionMenu.RepositoryActions - // .Where(x => _expressionEvaluator.EvaluateBooleanExpression(x.Active, repository)) - // .Select(x => CreateProcessRunnerAction(x, repository)) - // .Concat( - // new RepositoryAction[] - // { - // new RepositoryAction() { Name = $"Last update: {DateTime.Now:HH:mm:ss}", CanExecute = false, }, - // }) - // .ToArray(); - // } - // else - // { - // return new RepositoryAction[] - // { - // new RepositoryAction() { Name = $"No entries found.", CanExecute = false, }, - // new RepositoryAction() { Name = $"Last update: {DateTime.Now:HH:mm:ss}", CanExecute = false, }, - // }; - // } - // } - // else - // { - // var error = proc.StandardError.ReadToEnd(); - // - // return new RepositoryAction[] - // { - // new RepositoryAction() { Name = "No data found.", CanExecute = false, }, - // new RepositoryAction() { Name = $"Exit code {proc.ExitCode}", CanExecute = false, }, - // new RepositoryAction() { Name = string.IsNullOrEmpty(error) ? "Unknown error" : error, CanExecute = false, }, - // new RepositoryAction() { Name = $"Last update: {DateTime.Now:HH:mm:ss}", CanExecute = false, }, - // }; - // } - // } - // else - // { - // try - // { - // proc.Kill(); - // - // return new RepositoryAction[] - // { - // new RepositoryAction() { Name = _translationService.Translate("Could not read repository actions. Process killed successfully"), CanExecute = false, }, - // }; - // } - // catch (Exception e) - // { - // return new RepositoryAction[] - // { - // new RepositoryAction() { Name = _translationService.Translate("Could not read repository actions. Process didn't finish. Could not kill process"), CanExecute = false, }, - // new RepositoryAction() { Name = e.Message, CanExecute = false, }, - // }; - // } - // } - // } - // } - // catch (Exception e) - // { - // return new RepositoryAction[] - // { - // new RepositoryAction() { Name = _translationService.Translate("Could not read repository actions"), CanExecute = false }, - // new RepositoryAction() { Name = e.Message, CanExecute = false } - // }; - // } - // } - // }; - // } - // - // - // return null; - // } } \ No newline at end of file diff --git a/src/RepoM.Api/IO/IAppDataPathProvider.cs b/src/RepoM.Api/IO/IAppDataPathProvider.cs index b62e6fa1..eb2df89d 100644 --- a/src/RepoM.Api/IO/IAppDataPathProvider.cs +++ b/src/RepoM.Api/IO/IAppDataPathProvider.cs @@ -1,8 +1,11 @@ namespace RepoM.Api.IO; +using System; + public interface IAppDataPathProvider { string GetAppDataPath(); + [Obsolete("Not used.")] // todo string GetAppResourcesPath(); } \ No newline at end of file diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Deserialization/YamlDynamicRepositoryActionDeserializer.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Deserialization/YamlDynamicRepositoryActionDeserializer.cs index f6bb71de..4a5a2ee0 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Deserialization/YamlDynamicRepositoryActionDeserializer.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Deserialization/YamlDynamicRepositoryActionDeserializer.cs @@ -28,5 +28,5 @@ public RepositoryActionConfiguration Deserialize(string rawContent) var json = _serializer.Serialize(yamlObject); return _jsonDynamicRepositoryActionDeserializer.Deserialize(json); - } + } } \ No newline at end of file diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs index 23612d16..e6dea49a 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs @@ -32,23 +32,23 @@ public class RepositoryConfigurationReader public RepositoryConfigurationReader( IAppDataPathProvider appDataPathProvider, IFileSystem fileSystem, - JsonDynamicRepositoryActionDeserializer jsonAppsettingsDeserializer, + JsonDynamicRepositoryActionDeserializer jsonAppSettingsDeserializer, YamlDynamicRepositoryActionDeserializer yamlAppSettingsDeserializer, RepositoryExpressionEvaluator repoExpressionEvaluator) { _appDataPathProvider = appDataPathProvider ?? throw new ArgumentNullException(nameof(appDataPathProvider)); _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); - _jsonAppSettingsDeserializer = jsonAppsettingsDeserializer ?? throw new ArgumentNullException(nameof(jsonAppsettingsDeserializer)); + _jsonAppSettingsDeserializer = jsonAppSettingsDeserializer ?? throw new ArgumentNullException(nameof(jsonAppSettingsDeserializer)); _yamlAppSettingsDeserializer = yamlAppSettingsDeserializer ?? throw new ArgumentNullException(nameof(yamlAppSettingsDeserializer)); _repoExpressionEvaluator = repoExpressionEvaluator ?? throw new ArgumentNullException(nameof(repoExpressionEvaluator)); } private string GetRepositoryActionsFilename(string basePath) { - var exts = new [] { "yml", "yaml", "json", }; + var extensions = new [] { "yml", "yaml", "json", }; var path = Path.Combine(basePath, FILENAME); - foreach (var ext in exts) + foreach (var ext in extensions) { var filename = path + ext; if (_fileSystem.File.Exists(filename)) @@ -57,9 +57,8 @@ private string GetRepositoryActionsFilename(string basePath) } } - var f = path + "{" + string.Join(",",exts)+ "}"; - - throw new ConfigurationFileNotFoundException(f); + var failingFilename = path + "{" + string.Join(",",extensions) + "}"; + throw new ConfigurationFileNotFoundException(failingFilename); } public (Dictionary? envVars, List? Variables, List? actions, List? tags) Get(params Repository[] repositories) @@ -102,7 +101,7 @@ private string GetRepositoryActionsFilename(string basePath) throw new InvalidConfigurationException(filename, e.Message, e); } - Redirect? redirect = rootFile?.Redirect; + Redirect? redirect = rootFile.Redirect; if (!string.IsNullOrWhiteSpace(redirect?.Filename)) { if (IsEnabled(redirect?.Enabled, true, null)) @@ -123,11 +122,6 @@ private string GetRepositoryActionsFilename(string basePath) } } - if (rootFile == null) - { - return (null, null, null, null); - } - List EvaluateVariables(IEnumerable? vars) { if (vars == null) @@ -137,12 +131,12 @@ List EvaluateVariables(IEnumerable? vars) return vars .Where(v => IsEnabled(v.Enabled, true, repository)) - .Select(v => new EvaluatedVariable() - { - Name = v.Name, - Enabled = true, - Value = Evaluate(v.Value, repository), - }) + .Select(v => new EvaluatedVariable + { + Name = v.Name, + Enabled = true, + Value = Evaluate(v.Value, repository), + }) .ToList(); } @@ -223,7 +217,7 @@ List EvaluateVariables(IEnumerable? vars) List list2 = EvaluateVariables(repoSpecificConfig?.Variables); variables.AddRange(list2); - using IDisposable repoSepecificVariables = RepoMVariableProviderStore.Push(list2); + using IDisposable repoSpecificVariables = RepoMVariableProviderStore.Push(list2); actions.Add(rootFile.ActionsCollection); if (repoSpecificConfig?.ActionsCollection != null) @@ -247,14 +241,13 @@ private CombinedTypeContainer Evaluate(string? input, Repository? repository) return new CombinedTypeContainer(string.Empty); } - Repository[] repositories = repository == null ? Array.Empty() : new Repository[] { repository, }; + Repository[] repositories = repository == null ? Array.Empty() : new[] { repository, }; return _repoExpressionEvaluator.EvaluateValueExpression(input!, repositories); } - private string EvaluateString(string? input, Repository? repository) { - var v = Evaluate(input, repository); + CombinedTypeContainer v = Evaluate(input, repository); if (v == CombinedTypeContainer.NullInstance) { return string.Empty; @@ -320,7 +313,7 @@ List EvaluateVariables(IEnumerable? vars) return vars .Where(v => IsEnabled(v.Enabled, true, repository)) - .Select(v => new EvaluatedVariable() + .Select(v => new EvaluatedVariable { Name = v.Name, Enabled = true, @@ -492,7 +485,7 @@ private List EvaluateVariables(IEnumerable? vars, R return vars .Where(v => IsEnabled(v.Enabled, true, repository)) - .Select(v => new EvaluatedVariable() + .Select(v => new EvaluatedVariable { Name = v.Name, Enabled = true, diff --git a/src/RepoM.Api/IO/ProcessHelper.cs b/src/RepoM.Api/IO/ProcessHelper.cs index 42ec8bf7..31f5f45a 100644 --- a/src/RepoM.Api/IO/ProcessHelper.cs +++ b/src/RepoM.Api/IO/ProcessHelper.cs @@ -2,7 +2,6 @@ namespace RepoM.Api.IO; using System; using System.Diagnostics; -using RepoM.Api.Common; public static class ProcessHelper { diff --git a/src/RepoM.Api/RepoM.Api.csproj b/src/RepoM.Api/RepoM.Api.csproj index d818eecb..66b7c86f 100644 --- a/src/RepoM.Api/RepoM.Api.csproj +++ b/src/RepoM.Api/RepoM.Api.csproj @@ -5,6 +5,7 @@ + diff --git a/src/RepoM.App/App.xaml.cs b/src/RepoM.App/App.xaml.cs index 70356d90..d941f9ff 100644 --- a/src/RepoM.App/App.xaml.cs +++ b/src/RepoM.App/App.xaml.cs @@ -29,6 +29,11 @@ namespace RepoM.App; using RepoM.Core.Plugin; using RepoM.Ipc; using SimpleInjector; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Serilog; +using Serilog.Core; +using ILogger = Microsoft.Extensions.Logging.ILogger; /// /// Interaction logic for App.xaml @@ -66,8 +71,16 @@ protected override void OnStartup(StartupEventArgs e) _notifyIcon = FindResource("NotifyIcon") as TaskbarIcon; - RegisterServices(_container); + var fileSystem = new FileSystem(); + + IConfiguration config = SetupConfiguration(fileSystem); + ILoggerFactory loggerFactory = CreateLoggerFactory(config); + ILogger logger = loggerFactory.CreateLogger(nameof(App)); + logger.LogInformation("Started"); + RegisterLogging(loggerFactory); + RegisterServices(_container, fileSystem); UseRepositoryMonitor(_container); + _container.Verify(VerificationOption.VerifyAndDiagnose); _updateTimer = new Timer(async _ => await CheckForUpdatesAsync(), null, 5000, Timeout.Infinite); @@ -128,7 +141,53 @@ protected override void OnExit(ExitEventArgs e) base.OnExit(e); } - private static void RegisterServices(Container container) + private static IConfiguration SetupConfiguration(IFileSystem fileSystem) + { + const string FILENAME = "appsettings.serilog.json"; + var fullFilename = Path.Combine(DefaultAppDataPathProvider.Instance.GetAppDataPath(), FILENAME); + if (!fileSystem.File.Exists(fullFilename)) + { + fullFilename = FILENAME; + } + + IConfigurationBuilder builder = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile(fullFilename, optional: true, reloadOnChange: false) + .AddEnvironmentVariables(); + return builder.Build(); + } + + private static ILoggerFactory CreateLoggerFactory(IConfiguration config) + { + ILoggerFactory loggerFactory = new LoggerFactory(); + + LoggerConfiguration loggerConfiguration = new LoggerConfiguration() + .ReadFrom.Configuration(config); + + Logger logger = loggerConfiguration.CreateLogger(); + + _ = loggerFactory.AddSerilog(logger); + + return loggerFactory; + } + + private static void RegisterLogging(ILoggerFactory loggerFactory) + { + // https://stackoverflow.com/questions/41243485/simple-injector-register-iloggert-by-using-iloggerfactory-createloggert + + _container.RegisterInstance(loggerFactory); + _container.RegisterSingleton(typeof(ILogger<>), typeof(Logger<>)); + + _container.RegisterConditional( + typeof(ILogger), + c => c.Consumer == null + ? typeof(Logger) + : typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType), + Lifestyle.Singleton, + _ => true); + } + + private static void RegisterServices(Container container, IFileSystem fileSystem) { container.Register(Lifestyle.Singleton); @@ -140,7 +199,7 @@ private static void RegisterServices(Container container) container.Register(Lifestyle.Singleton); container.Register(Lifestyle.Singleton); container.Register(Lifestyle.Singleton); - container.Register(Lifestyle.Singleton); + container.RegisterInstance(DefaultAppDataPathProvider.Instance); container.Register(Lifestyle.Singleton); container.Register(Lifestyle.Singleton); container.Register(Lifestyle.Singleton); @@ -158,11 +217,10 @@ private static void RegisterServices(Container container) container.Register(Lifestyle.Singleton); container.Collection.Append(Lifestyle.Singleton); - var fileSystem = new FileSystem(); container.RegisterInstance(fileSystem); container.Register(Lifestyle.Singleton); - Assembly[] repoExpressionEvaluators = new[] + Assembly[] repoExpressionEvaluators = { typeof(IVariableProvider).Assembly, typeof(RepositoryExpressionEvaluator).Assembly, @@ -179,15 +237,15 @@ private static void RegisterServices(Container container) container.Collection.Append(Lifestyle.Singleton); container.Collection.Register(typeof(IMethod), repoExpressionEvaluators, Lifestyle.Singleton); - container.RegisterInstance(new DateTimeVariableProviderOptions() + container.RegisterInstance(new DateTimeVariableProviderOptions { DateTimeProvider = () => DateTime.Now, }); - container.RegisterInstance(new DateTimeNowVariableProviderOptions() + container.RegisterInstance(new DateTimeNowVariableProviderOptions { DateTimeProvider = () => DateTime.Now, }); - container.RegisterInstance(new DateTimeDateVariableProviderOptions() + container.RegisterInstance(new DateTimeDateVariableProviderOptions { DateTimeProvider = () => DateTime.Now, }); @@ -201,13 +259,11 @@ private static void RegisterServices(Container container) container.Collection.Register( new[] { typeof(IActionToRepositoryActionMapper).Assembly, }, Lifestyle.Singleton); - - + container.Register(Lifestyle.Singleton); container.Register(Lifestyle.Singleton); container.Register(Lifestyle.Singleton); - IEnumerable pluginDlls = PluginFinder.FindPluginAssemblies(Path.Combine(AppDomain.CurrentDomain.BaseDirectory), fileSystem); IEnumerable assemblies = pluginDlls.Select(plugin => Assembly.Load(AssemblyName.GetAssemblyName(plugin.FullName))); container.RegisterPackages(assemblies); diff --git a/src/RepoM.App/MainWindow.xaml.cs b/src/RepoM.App/MainWindow.xaml.cs index 8c423c84..d5af1bda 100644 --- a/src/RepoM.App/MainWindow.xaml.cs +++ b/src/RepoM.App/MainWindow.xaml.cs @@ -18,7 +18,6 @@ namespace RepoM.App; using RepoM.Api.Git; using RepoM.Api.IO; using RepoM.App.Controls; -using RepoM.Core.Plugin; using SourceChord.FluentWPF; /// @@ -77,11 +76,11 @@ public MainWindow( view.Filter = FilterRepositories; view.CustomSort = new CustomRepositoryViewSortBehavior(); - AssemblyName? appName = System.Reflection.Assembly.GetEntryAssembly()?.GetName(); + AssemblyName? appName = Assembly.GetEntryAssembly()?.GetName(); txtHelpCaption.Text = appName?.Name + " " + appName?.Version?.ToString(2); txtHelp.Text = GetHelp(statusCharacterMap); - PlaceFormByTaskbarLocation(); + PlaceFormByTaskBarLocation(); } private void View_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) @@ -135,7 +134,7 @@ public void ShowAndActivate() { Dispatcher.Invoke(() => { - PlaceFormByTaskbarLocation(); + PlaceFormByTaskBarLocation(); if (!IsShown) { @@ -340,28 +339,28 @@ private static void Navigate(string url) }); } - private void PlaceFormByTaskbarLocation() + private void PlaceFormByTaskBarLocation() { var topY = SystemParameters.WorkArea.Top; var bottomY = SystemParameters.WorkArea.Height - Height; var leftX = SystemParameters.WorkArea.Left; var rightX = SystemParameters.WorkArea.Width - Width; - switch (TaskbarLocator.GetTaskBarLocation()) + switch (TaskBarLocator.GetTaskBarLocation()) { - case TaskbarLocator.TaskBarLocation.Top: + case TaskBarLocator.TaskBarLocation.Top: Top = topY; Left = rightX; break; - case TaskbarLocator.TaskBarLocation.Bottom: + case TaskBarLocator.TaskBarLocation.Bottom: Top = bottomY; Left = rightX; break; - case TaskbarLocator.TaskBarLocation.Left: + case TaskBarLocator.TaskBarLocation.Left: Top = bottomY; Left = leftX; break; - case TaskbarLocator.TaskBarLocation.Right: + case TaskBarLocator.TaskBarLocation.Right: Top = bottomY; Left = rightX; break; diff --git a/src/RepoM.App/RepoM.App.csproj b/src/RepoM.App/RepoM.App.csproj index ba66f3a8..25f55e42 100644 --- a/src/RepoM.App/RepoM.App.csproj +++ b/src/RepoM.App/RepoM.App.csproj @@ -33,6 +33,16 @@ + + + + + + + + + + @@ -54,6 +64,9 @@ + + PreserveNewest + SettingsSingleFileGenerator Settings.Designer.cs diff --git a/src/RepoM.App/TaskbarLocator.cs b/src/RepoM.App/TaskBarLocator.cs similarity index 95% rename from src/RepoM.App/TaskbarLocator.cs rename to src/RepoM.App/TaskBarLocator.cs index 21ee2203..f7f27cd9 100644 --- a/src/RepoM.App/TaskbarLocator.cs +++ b/src/RepoM.App/TaskBarLocator.cs @@ -2,7 +2,7 @@ namespace RepoM.App; using System.Windows.Forms; -public static class TaskbarLocator +public static class TaskBarLocator { public enum TaskBarLocation { diff --git a/src/RepoM.App/appsettings.serilog.json b/src/RepoM.App/appsettings.serilog.json new file mode 100644 index 00000000..86fbd0db --- /dev/null +++ b/src/RepoM.App/appsettings.serilog.json @@ -0,0 +1,17 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.File" ], + "MinimumLevel": "Debug", + "WriteTo": [ + { + "Name": "File", + "Args": + { + "path": "%APPDATA%/RepoM/Logs/repom.txt", + "rollingInterval": "Day" + } + } + ], + "Enrich": [ "WithThreadId" ] + } +} \ No newline at end of file diff --git a/src/RepoM.Core.Plugin/RepoM.Core.Plugin.csproj b/src/RepoM.Core.Plugin/RepoM.Core.Plugin.csproj index 9f5c4f4a..21feb56d 100644 --- a/src/RepoM.Core.Plugin/RepoM.Core.Plugin.csproj +++ b/src/RepoM.Core.Plugin/RepoM.Core.Plugin.csproj @@ -4,4 +4,8 @@ netstandard2.0 + + + + diff --git a/src/RepoM.Ipc/RepoM.Ipc.csproj b/src/RepoM.Ipc/RepoM.Ipc.csproj index a94109f3..1fe013c2 100644 --- a/src/RepoM.Ipc/RepoM.Ipc.csproj +++ b/src/RepoM.Ipc/RepoM.Ipc.csproj @@ -4,6 +4,7 @@ + diff --git a/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs b/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs index 8618d18e..e084c108 100644 --- a/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs +++ b/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs @@ -3,7 +3,6 @@ namespace RepoM.Plugin.AzureDevOps; using System; using System.Threading.Tasks; using JetBrains.Annotations; -using RepoM.Api; using RepoM.Core.Plugin; [UsedImplicitly] diff --git a/src/RepoM.Plugin.AzureDevOps/AzureDevOpsPackage.cs b/src/RepoM.Plugin.AzureDevOps/AzureDevOpsPackage.cs index f9921986..aa48fafc 100644 --- a/src/RepoM.Plugin.AzureDevOps/AzureDevOpsPackage.cs +++ b/src/RepoM.Plugin.AzureDevOps/AzureDevOpsPackage.cs @@ -1,8 +1,6 @@ namespace RepoM.Plugin.AzureDevOps; -using ExpressionStringEvaluator.Methods; using JetBrains.Annotations; -using RepoM.Api; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider; using RepoM.Core.Plugin; using SimpleInjector; diff --git a/src/RepoM.Plugin.AzureDevOps/AzureDevOpsPullRequestService.cs b/src/RepoM.Plugin.AzureDevOps/AzureDevOpsPullRequestService.cs index 0ac4ca12..27695910 100644 --- a/src/RepoM.Plugin.AzureDevOps/AzureDevOpsPullRequestService.cs +++ b/src/RepoM.Plugin.AzureDevOps/AzureDevOpsPullRequestService.cs @@ -4,6 +4,7 @@ namespace RepoM.Plugin.AzureDevOps; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using Microsoft.TeamFoundation.SourceControl.WebApi; using Microsoft.VisualStudio.Services.Common; using Microsoft.VisualStudio.Services.WebApi; @@ -13,23 +14,29 @@ namespace RepoM.Plugin.AzureDevOps; internal class AzureDevOpsPullRequestService : IDisposable { private readonly IAppSettingsService _appSettingsService; + private readonly ILogger _logger; private readonly VssConnection? _connection; private GitHttpClient? _gitClient; private readonly List _emptyList = new(0); - public AzureDevOpsPullRequestService(IAppSettingsService appSettingsService) + public AzureDevOpsPullRequestService( + IAppSettingsService appSettingsService, + ILogger logger) { - _appSettingsService = appSettingsService; + _appSettingsService = appSettingsService ?? throw new ArgumentNullException(nameof(appSettingsService)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); var token = _appSettingsService.AzureDevOpsPersonalAccessToken; try { - _connection = new VssConnection(new Uri(_appSettingsService.AzureDevOpsBaseUrl), new VssBasicCredential(string.Empty, token)); + _connection = new VssConnection( + new Uri(_appSettingsService.AzureDevOpsBaseUrl), + new VssBasicCredential(string.Empty, token)); } - catch (Exception) + catch (Exception e) { - // swallow for now; + _logger.LogError(e, "Could not connect to Vss. Module will not be enabled."); } } @@ -43,6 +50,7 @@ public Task InitializeAsync() var key = _appSettingsService.AzureDevOpsPersonalAccessToken; if (string.IsNullOrWhiteSpace(key)) { + _logger.LogInformation($"'{nameof(_appSettingsService.AzureDevOpsPersonalAccessToken)}' was null or empty. Module will not be enabled."); return Task.CompletedTask; } @@ -52,7 +60,7 @@ public Task InitializeAsync() } catch (Exception e) { - throw new ApplicationException("Could not open GitClient from connection.", e); + _logger.LogError(e, "Could not retrieve GitHttpClient from connection."); } return Task.CompletedTask; @@ -99,10 +107,12 @@ private async Task> GetPullRequestsTask(Repository repository, } catch (Microsoft.TeamFoundation.Core.WebApi.ProjectDoesNotExistException e) { + _logger.LogWarning(e, "Project does not exist (repository: {repository.Name} projectId {projectId})", repository.Name, projectId); throw new ApplicationException(e.Message, e); } catch (Exception e) { + _logger.LogWarning(e, "Unable to Get repositories from client ({projectId}).", projectId); throw new ApplicationException("Could retrieve repositories Check your PAT", e); } @@ -114,13 +124,16 @@ private async Task> GetPullRequestsTask(Repository repository, if (selectedRepos.Length == 0) { + _logger.LogWarning("No repository found for url {searchRepoUrl}", searchRepoUrl); throw new ApplicationException($"No repositories found for url {searchRepoUrl}"); } - else if (selectedRepos.Length > 1) + + if (selectedRepos.Length > 1) { + _logger.LogWarning("Multiple repositories found for url {searchRepoUrl}", searchRepoUrl); throw new ApplicationException($"Multiple repositories found for url {searchRepoUrl}"); } - else + { GitRepository repo = selectedRepos.Single(); List prs = await GetPullRequests(_gitClient, repo.Id); @@ -137,7 +150,7 @@ private static Task> GetPullRequests(GitHttpClientBase gitC { return gitClient.GetPullRequestsAsync( repoId, - new GitPullRequestSearchCriteria() + new GitPullRequestSearchCriteria { Status = PullRequestStatus.Active, }); diff --git a/src/RepoM.Plugin.AzureDevOps/RepoM.Plugin.AzureDevOps.csproj b/src/RepoM.Plugin.AzureDevOps/RepoM.Plugin.AzureDevOps.csproj index 3828583f..9a903f12 100644 --- a/src/RepoM.Plugin.AzureDevOps/RepoM.Plugin.AzureDevOps.csproj +++ b/src/RepoM.Plugin.AzureDevOps/RepoM.Plugin.AzureDevOps.csproj @@ -6,6 +6,7 @@ + diff --git a/src/RepoM.Plugin.EverythingFileSearch/Internal/Everything64Api.cs b/src/RepoM.Plugin.EverythingFileSearch/Internal/Everything64Api.cs index 8007a793..a7a4688c 100644 --- a/src/RepoM.Plugin.EverythingFileSearch/Internal/Everything64Api.cs +++ b/src/RepoM.Plugin.EverythingFileSearch/Internal/Everything64Api.cs @@ -63,14 +63,14 @@ public static IEnumerable Search(string query) return Enumerable.Empty(); } - var buf = new StringBuilder(BUFFER_SIZE); + var buffer = new StringBuilder(BUFFER_SIZE); var result = new List((int)nrResults); for (uint i = 0; i < nrResults; i++) { - buf.Clear(); - Everything_GetResultFullPathName(i, buf, BUFFER_SIZE); - result.Add(buf.ToString()); + buffer.Clear(); + Everything_GetResultFullPathName(i, buffer, BUFFER_SIZE); + result.Add(buffer.ToString()); } return result; diff --git a/src/RepoM.Plugin.EverythingFileSearch/RepoM.Plugin.EverythingFileSearch.csproj b/src/RepoM.Plugin.EverythingFileSearch/RepoM.Plugin.EverythingFileSearch.csproj index a76d6fd3..b259dfc5 100644 --- a/src/RepoM.Plugin.EverythingFileSearch/RepoM.Plugin.EverythingFileSearch.csproj +++ b/src/RepoM.Plugin.EverythingFileSearch/RepoM.Plugin.EverythingFileSearch.csproj @@ -5,6 +5,7 @@ + diff --git a/src/RepoM.Plugin.IpcService/IpcServerModule.cs b/src/RepoM.Plugin.IpcService/IpcServerModule.cs index 4d6c90aa..145c9085 100644 --- a/src/RepoM.Plugin.IpcService/IpcServerModule.cs +++ b/src/RepoM.Plugin.IpcService/IpcServerModule.cs @@ -3,7 +3,6 @@ namespace RepoM.Plugin.IpcService; using System; using System.Threading.Tasks; using JetBrains.Annotations; -using RepoM.Api; using RepoM.Core.Plugin; [UsedImplicitly] diff --git a/src/RepoM.Plugin.IpcService/IpcServicePackage.cs b/src/RepoM.Plugin.IpcService/IpcServicePackage.cs index 68e6bea0..1bf9b8a0 100644 --- a/src/RepoM.Plugin.IpcService/IpcServicePackage.cs +++ b/src/RepoM.Plugin.IpcService/IpcServicePackage.cs @@ -1,7 +1,6 @@ namespace RepoM.Plugin.IpcService; using JetBrains.Annotations; -using RepoM.Api; using RepoM.Core.Plugin; using RepoM.Ipc; using SimpleInjector; diff --git a/src/RepoM.Plugin.IpcService/RepoM.Plugin.IpcService.csproj b/src/RepoM.Plugin.IpcService/RepoM.Plugin.IpcService.csproj index 4127ceb0..7df518c8 100644 --- a/src/RepoM.Plugin.IpcService/RepoM.Plugin.IpcService.csproj +++ b/src/RepoM.Plugin.IpcService/RepoM.Plugin.IpcService.csproj @@ -5,6 +5,7 @@ + diff --git a/src/RepoM.Plugin.LuceneSearch/EventToLuceneHandler.cs b/src/RepoM.Plugin.LuceneSearch/EventToLuceneHandler.cs index d071594e..ecf141f2 100644 --- a/src/RepoM.Plugin.LuceneSearch/EventToLuceneHandler.cs +++ b/src/RepoM.Plugin.LuceneSearch/EventToLuceneHandler.cs @@ -17,9 +17,9 @@ internal class EventToLuceneHandler : IModule, IDisposable public EventToLuceneHandler(IRepositoryMonitor monitor, IRepositoryIndex index, IRepositorySearch search) { - _monitor = monitor; - _index = index; - _search = search; + _monitor = monitor ?? throw new ArgumentNullException(nameof(monitor)); + _index = index ?? throw new ArgumentNullException(nameof(index)); + _search = search ?? throw new ArgumentNullException(nameof(search)); } public Task StartAsync() diff --git a/src/RepoM.Plugin.LuceneSearch/RepoM.Plugin.LuceneSearch.csproj b/src/RepoM.Plugin.LuceneSearch/RepoM.Plugin.LuceneSearch.csproj index f940c4b8..db1aafd1 100644 --- a/src/RepoM.Plugin.LuceneSearch/RepoM.Plugin.LuceneSearch.csproj +++ b/src/RepoM.Plugin.LuceneSearch/RepoM.Plugin.LuceneSearch.csproj @@ -14,6 +14,7 @@ + diff --git a/src/RepoM.Plugin.LuceneSearch/SearchAdapter.cs b/src/RepoM.Plugin.LuceneSearch/SearchAdapter.cs index 7be9aef6..a03dd99a 100644 --- a/src/RepoM.Plugin.LuceneSearch/SearchAdapter.cs +++ b/src/RepoM.Plugin.LuceneSearch/SearchAdapter.cs @@ -4,7 +4,6 @@ namespace RepoM.Plugin.LuceneSearch; using System.Collections.Generic; using System.Linq; using RepoM.Api; -using RepoM.Core.Plugin; internal class SearchAdapter : IRepositorySearch { @@ -12,31 +11,25 @@ internal class SearchAdapter : IRepositorySearch private List _cache = new(); private string _query = string.Empty; private DateTime _now = DateTime.MinValue; - private readonly object _l = new(); + private readonly object _lock = new(); public SearchAdapter(IRepositoryIndex index) { - _index = index; + _index = index ?? throw new ArgumentNullException(nameof(index)); } public IEnumerable Search(string query) { - if (_now > DateTime.UtcNow) + if (_now > DateTime.UtcNow && _query.Equals(query)) { - if (_query.Equals(query)) - { - return _cache.Select(x => x.Path); - } + return _cache.Select(x => x.Path); } - lock (_l) + lock (_lock) { - if (_now > DateTime.UtcNow) + if (_now > DateTime.UtcNow && _query.Equals(query)) { - if (_query.Equals(query)) - { - return _cache.Select(x => x.Path); - } + return _cache.Select(x => x.Path); } List results = _index.Search(query, SearchOperator.And, out var _); diff --git a/src/RepoM.Plugin.SonarCloud/ActionSonarCloudSetFavoriteV1Deserializer.cs b/src/RepoM.Plugin.SonarCloud/ActionSonarCloudSetFavoriteV1Deserializer.cs index e8881507..7dd62f28 100644 --- a/src/RepoM.Plugin.SonarCloud/ActionSonarCloudSetFavoriteV1Deserializer.cs +++ b/src/RepoM.Plugin.SonarCloud/ActionSonarCloudSetFavoriteV1Deserializer.cs @@ -4,7 +4,6 @@ namespace RepoM.Plugin.SonarCloud; using JetBrains.Annotations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using RepoM.Api.Git; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.ActionDeserializers; using RepositoryAction = RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.RepositoryAction; diff --git a/src/RepoM.Plugin.SonarCloud/RepoM.Plugin.SonarCloud.csproj b/src/RepoM.Plugin.SonarCloud/RepoM.Plugin.SonarCloud.csproj index cbaea84c..609172ba 100644 --- a/src/RepoM.Plugin.SonarCloud/RepoM.Plugin.SonarCloud.csproj +++ b/src/RepoM.Plugin.SonarCloud/RepoM.Plugin.SonarCloud.csproj @@ -6,6 +6,7 @@ + diff --git a/src/RepoM.Plugin.SonarCloud/SonarCloudFavoriteService.cs b/src/RepoM.Plugin.SonarCloud/SonarCloudFavoriteService.cs index 2bc5303a..5afb3025 100644 --- a/src/RepoM.Plugin.SonarCloud/SonarCloudFavoriteService.cs +++ b/src/RepoM.Plugin.SonarCloud/SonarCloudFavoriteService.cs @@ -18,7 +18,7 @@ internal class SonarCloudFavoriteService public SonarCloudFavoriteService(IAppSettingsService appSettingsService) { - _appSettingsService = appSettingsService; + _appSettingsService = appSettingsService ?? throw new ArgumentNullException(nameof(appSettingsService)); } public Task InitializeAsync() @@ -28,6 +28,7 @@ public Task InitializeAsync() { return Task.CompletedTask; } + _client = new SonarQubeClient( "https://sonarcloud.io", new BasicAuthentication(key, string.Empty)); diff --git a/src/RepoM.Plugin.SonarCloud/SonarCloudPackage.cs b/src/RepoM.Plugin.SonarCloud/SonarCloudPackage.cs index 7983240b..ff47c1e8 100644 --- a/src/RepoM.Plugin.SonarCloud/SonarCloudPackage.cs +++ b/src/RepoM.Plugin.SonarCloud/SonarCloudPackage.cs @@ -2,7 +2,6 @@ namespace RepoM.Plugin.SonarCloud; using ExpressionStringEvaluator.Methods; using JetBrains.Annotations; -using RepoM.Api; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider; using RepoM.Core.Plugin; using SimpleInjector; diff --git a/src/RepoM.Plugin.WindowsExplorerGitInfo/PInvoke/Explorer/CleanWindowTitleActor.cs b/src/RepoM.Plugin.WindowsExplorerGitInfo/PInvoke/Explorer/CleanWindowTitleActor.cs index e4a2975f..18a01262 100644 --- a/src/RepoM.Plugin.WindowsExplorerGitInfo/PInvoke/Explorer/CleanWindowTitleActor.cs +++ b/src/RepoM.Plugin.WindowsExplorerGitInfo/PInvoke/Explorer/CleanWindowTitleActor.cs @@ -6,7 +6,6 @@ internal class CleanWindowTitleActor : ExplorerWindowActor { protected override void Act(IntPtr hwnd, string? explorerLocationUrl) { - Console.WriteLine("Clean " + explorerLocationUrl ?? string.Empty); const string SEPARATOR = " ["; WindowHelper.RemoveAppendedWindowText(hwnd, SEPARATOR); } diff --git a/src/RepoM.Plugin.WindowsExplorerGitInfo/PInvoke/Explorer/ExplorerWindowActor.cs b/src/RepoM.Plugin.WindowsExplorerGitInfo/PInvoke/Explorer/ExplorerWindowActor.cs index 93e0d4c6..780d0fed 100644 --- a/src/RepoM.Plugin.WindowsExplorerGitInfo/PInvoke/Explorer/ExplorerWindowActor.cs +++ b/src/RepoM.Plugin.WindowsExplorerGitInfo/PInvoke/Explorer/ExplorerWindowActor.cs @@ -42,6 +42,7 @@ public void Pulse() using var window = new ComBridge(comWindow); var fullName = window.GetPropertyValue("FullName"); var executable = Path.GetFileName(fullName); + if (string.Equals(executable, "explorer.exe", StringComparison.OrdinalIgnoreCase)) { // thanks http://docwiki.embarcadero.com/Libraries/Seattle/en/SHDocVw.IWebBrowser2_Properties diff --git a/src/RepoM.Plugin.WindowsExplorerGitInfo/RepoM.Plugin.WindowsExplorerGitInfo.csproj b/src/RepoM.Plugin.WindowsExplorerGitInfo/RepoM.Plugin.WindowsExplorerGitInfo.csproj index a49fb3f2..29a1fa54 100644 --- a/src/RepoM.Plugin.WindowsExplorerGitInfo/RepoM.Plugin.WindowsExplorerGitInfo.csproj +++ b/src/RepoM.Plugin.WindowsExplorerGitInfo/RepoM.Plugin.WindowsExplorerGitInfo.csproj @@ -5,6 +5,7 @@ + diff --git a/src/RepoM.Plugin.WindowsExplorerGitInfo/WindowExplorerBarGitInfoModule.cs b/src/RepoM.Plugin.WindowsExplorerGitInfo/WindowExplorerBarGitInfoModule.cs index cc54d790..404aab45 100644 --- a/src/RepoM.Plugin.WindowsExplorerGitInfo/WindowExplorerBarGitInfoModule.cs +++ b/src/RepoM.Plugin.WindowsExplorerGitInfo/WindowExplorerBarGitInfoModule.cs @@ -4,7 +4,6 @@ namespace RepoM.Plugin.WindowsExplorerGitInfo; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; -using RepoM.Api; using RepoM.Core.Plugin; using RepoM.Plugin.WindowsExplorerGitInfo.PInvoke.Explorer; diff --git a/src/RepoM.Plugin.WindowsExplorerGitInfo/WindowsExplorerGitInfoModule.cs b/src/RepoM.Plugin.WindowsExplorerGitInfo/WindowsExplorerGitInfoModule.cs index af6fd546..d46628bf 100644 --- a/src/RepoM.Plugin.WindowsExplorerGitInfo/WindowsExplorerGitInfoModule.cs +++ b/src/RepoM.Plugin.WindowsExplorerGitInfo/WindowsExplorerGitInfoModule.cs @@ -1,7 +1,6 @@ namespace RepoM.Plugin.WindowsExplorerGitInfo; using JetBrains.Annotations; -using RepoM.Api; using RepoM.Core.Plugin; using RepoM.Plugin.WindowsExplorerGitInfo.PInvoke.Explorer; using SimpleInjector; diff --git a/tests/RepoM.Api.Tests/IO/DefaultRepositoryActionProviderTest.cs b/tests/RepoM.Api.Tests/IO/DefaultRepositoryActionProviderTest.cs index 5cf3d2b1..f4a57f5e 100644 --- a/tests/RepoM.Api.Tests/IO/DefaultRepositoryActionProviderTest.cs +++ b/tests/RepoM.Api.Tests/IO/DefaultRepositoryActionProviderTest.cs @@ -3,7 +3,6 @@ namespace RepoM.Api.Common.Tests.IO; using System; using System.Collections.Generic; using System.IO.Abstractions.TestingHelpers; -using System.Threading.Tasks; using EasyTestFileXunit; using ExpressionStringEvaluator.Methods.BooleanToBoolean; using ExpressionStringEvaluator.Methods.Flow; @@ -18,7 +17,6 @@ namespace RepoM.Api.Common.Tests.IO; using RepoM.Api.Git; using RepoM.Api.IO; using VerifyXunit; -using Xunit; [UsesEasyTestFile] [UsesVerify] diff --git a/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj b/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj index c4b74144..95334b02 100644 --- a/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj +++ b/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj @@ -15,6 +15,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/tests/RepoM.Ipc.Tests/RepoM.Ipc.Tests.csproj b/tests/RepoM.Ipc.Tests/RepoM.Ipc.Tests.csproj index 00510013..2d06d7d3 100644 --- a/tests/RepoM.Ipc.Tests/RepoM.Ipc.Tests.csproj +++ b/tests/RepoM.Ipc.Tests/RepoM.Ipc.Tests.csproj @@ -7,6 +7,7 @@ + diff --git a/tests/RepoM.Ipc.Tests/RepoMIpcClientTests.cs b/tests/RepoM.Ipc.Tests/RepoMIpcClientTests.cs index c833c1f0..6edb4bb7 100644 --- a/tests/RepoM.Ipc.Tests/RepoMIpcClientTests.cs +++ b/tests/RepoM.Ipc.Tests/RepoMIpcClientTests.cs @@ -8,7 +8,6 @@ namespace RepoM.Ipc.Tests; using RepoM.Ipc; using RepoM.Ipc.Tests.Internals; using RepoM.Plugin.IpcService; -using VerifyTests; using VerifyXunit; using Xunit; diff --git a/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj b/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj index ffac47d2..a8c4c7a3 100644 --- a/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj +++ b/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj @@ -17,6 +17,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/tests/RepoM.Plugin.LuceneSearch.Tests/RepoM.Plugin.LuceneSearch.Tests.csproj b/tests/RepoM.Plugin.LuceneSearch.Tests/RepoM.Plugin.LuceneSearch.Tests.csproj index d275168d..28068122 100644 --- a/tests/RepoM.Plugin.LuceneSearch.Tests/RepoM.Plugin.LuceneSearch.Tests.csproj +++ b/tests/RepoM.Plugin.LuceneSearch.Tests/RepoM.Plugin.LuceneSearch.Tests.csproj @@ -11,6 +11,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj b/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj index fe10865f..7dea6cf7 100644 --- a/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj +++ b/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj @@ -17,6 +17,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/tests/Specs/DefaultRepositoryMonitorTests.cs b/tests/Specs/DefaultRepositoryMonitorTests.cs index 36a7e623..c5022876 100644 --- a/tests/Specs/DefaultRepositoryMonitorTests.cs +++ b/tests/Specs/DefaultRepositoryMonitorTests.cs @@ -16,6 +16,7 @@ namespace Specs; using ExpressionStringEvaluator.VariableProviders.DateTime; using ExpressionStringEvaluator.VariableProviders; using FluentAssertions; +using Microsoft.Extensions.Logging.Abstractions; using Moq; using NUnit.Framework; using RepoM.Api.Common; @@ -101,7 +102,7 @@ public void OneTimeSetUp() new SubstringMethod(), }; - var defaultRepositoryReader = new DefaultRepositoryReader(new Mock().Object); + var defaultRepositoryReader = new DefaultRepositoryReader(new Mock().Object, NullLogger.Instance); _monitor = new DefaultRepositoryMonitor( new GivenPathProvider(new string[] { repoPath, }), defaultRepositoryReader, diff --git a/tests/Specs/Specs.csproj b/tests/Specs/Specs.csproj index 461a9899..b7c708ae 100644 --- a/tests/Specs/Specs.csproj +++ b/tests/Specs/Specs.csproj @@ -14,6 +14,7 @@ + diff --git a/tests/Tests/Tests.csproj b/tests/Tests/Tests.csproj index b4065e8f..2fae6473 100644 --- a/tests/Tests/Tests.csproj +++ b/tests/Tests/Tests.csproj @@ -14,6 +14,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive +